1 1.34 jdolecek /* $NetBSD: viaenv.c,v 1.34 2018/03/04 13:24:17 jdolecek Exp $ */ 2 1.1 joda 3 1.1 joda /* 4 1.1 joda * Copyright (c) 2000 Johan Danielsson 5 1.1 joda * All rights reserved. 6 1.1 joda * 7 1.2 thorpej * Redistribution and use in source and binary forms, with or without 8 1.2 thorpej * modification, are permitted provided that the following conditions 9 1.2 thorpej * are met: 10 1.1 joda * 11 1.2 thorpej * 1. Redistributions of source code must retain the above copyright 12 1.2 thorpej * notice, this list of conditions and the following disclaimer. 13 1.1 joda * 14 1.2 thorpej * 2. Redistributions in binary form must reproduce the above copyright 15 1.2 thorpej * notice, this list of conditions and the following disclaimer in the 16 1.2 thorpej * documentation and/or other materials provided with the distribution. 17 1.1 joda * 18 1.1 joda * 3. Neither the name of author nor the names of any contributors may 19 1.1 joda * be used to endorse or promote products derived from this 20 1.1 joda * software without specific prior written permission. 21 1.1 joda * 22 1.1 joda * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 23 1.1 joda * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 1.1 joda * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 1.1 joda * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26 1.1 joda * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 1.1 joda * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 1.1 joda * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 1.1 joda * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 1.1 joda * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 1.1 joda * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 1.1 joda * POSSIBILITY OF SUCH DAMAGE. 33 1.1 joda */ 34 1.1 joda 35 1.18 xtraeme /* 36 1.18 xtraeme * Driver for the hardware monitoring and power management timer 37 1.18 xtraeme * in the VIA VT82C686A and VT8231 South Bridges. 38 1.18 xtraeme */ 39 1.5 lukem 40 1.5 lukem #include <sys/cdefs.h> 41 1.34 jdolecek __KERNEL_RCSID(0, "$NetBSD: viaenv.c,v 1.34 2018/03/04 13:24:17 jdolecek Exp $"); 42 1.1 joda 43 1.1 joda #include <sys/param.h> 44 1.1 joda #include <sys/systm.h> 45 1.1 joda #include <sys/kernel.h> 46 1.1 joda #include <sys/device.h> 47 1.1 joda 48 1.24 ad #include <sys/bus.h> 49 1.18 xtraeme #include <dev/ic/acpipmtimer.h> 50 1.18 xtraeme 51 1.1 joda #include <dev/pci/pcivar.h> 52 1.1 joda #include <dev/pci/pcireg.h> 53 1.18 xtraeme #include <dev/pci/pcidevs.h> 54 1.1 joda 55 1.3 thorpej #include <dev/sysmon/sysmonvar.h> 56 1.3 thorpej 57 1.1 joda #ifdef VIAENV_DEBUG 58 1.1 joda unsigned int viaenv_debug = 0; 59 1.18 xtraeme #define DPRINTF(X) do { if (viaenv_debug) printf X ; } while(0) 60 1.1 joda #else 61 1.1 joda #define DPRINTF(X) 62 1.1 joda #endif 63 1.1 joda 64 1.2 thorpej #define VIANUMSENSORS 10 /* three temp, two fan, five voltage */ 65 1.1 joda 66 1.1 joda struct viaenv_softc { 67 1.2 thorpej bus_space_tag_t sc_iot; 68 1.2 thorpej bus_space_handle_t sc_ioh; 69 1.18 xtraeme bus_space_handle_t sc_pm_ioh; 70 1.1 joda 71 1.2 thorpej int sc_fan_div[2]; /* fan RPM divisor */ 72 1.1 joda 73 1.25 xtraeme struct sysmon_envsys *sc_sme; 74 1.25 xtraeme envsys_data_t sc_sensor[VIANUMSENSORS]; 75 1.1 joda 76 1.6 thorpej struct timeval sc_lastread; 77 1.1 joda }; 78 1.3 thorpej 79 1.18 xtraeme /* autoconf(9) glue */ 80 1.27 xtraeme static int viaenv_match(device_t, cfdata_t, void *); 81 1.27 xtraeme static void viaenv_attach(device_t, device_t, void *); 82 1.18 xtraeme 83 1.27 xtraeme CFATTACH_DECL_NEW(viaenv, sizeof(struct viaenv_softc), 84 1.18 xtraeme viaenv_match, viaenv_attach, NULL, NULL); 85 1.18 xtraeme 86 1.18 xtraeme /* envsys(4) glue */ 87 1.25 xtraeme static void viaenv_refresh(struct sysmon_envsys *, envsys_data_t *); 88 1.18 xtraeme 89 1.18 xtraeme static int val_to_uK(unsigned int); 90 1.18 xtraeme static int val_to_rpm(unsigned int, int); 91 1.18 xtraeme static long val_to_uV(unsigned int, int); 92 1.1 joda 93 1.1 joda static int 94 1.27 xtraeme viaenv_match(device_t parent, cfdata_t match, void *aux) 95 1.1 joda { 96 1.27 xtraeme struct pci_attach_args *pa = aux; 97 1.2 thorpej 98 1.18 xtraeme if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_VIATECH) 99 1.18 xtraeme return 0; 100 1.18 xtraeme 101 1.18 xtraeme switch (PCI_PRODUCT(pa->pa_id)) { 102 1.34 jdolecek case PCI_PRODUCT_VIATECH_VT82C686A_PWR: 103 1.18 xtraeme case PCI_PRODUCT_VIATECH_VT8231_PWR: 104 1.2 thorpej return 1; 105 1.18 xtraeme default: 106 1.18 xtraeme return 0; 107 1.18 xtraeme } 108 1.1 joda } 109 1.1 joda 110 1.2 thorpej /* 111 1.2 thorpej * XXX there doesn't seem to exist much hard documentation on how to 112 1.2 thorpej * convert the raw values to usable units, this code is more or less 113 1.2 thorpej * stolen from the Linux driver, but changed to suit our conditions 114 1.2 thorpej */ 115 1.2 thorpej 116 1.2 thorpej /* 117 1.2 thorpej * lookup-table to translate raw values to uK, this is the same table 118 1.2 thorpej * used by the Linux driver (modulo units); there is a fifth degree 119 1.2 thorpej * polynomial that supposedly been used to generate this table, but I 120 1.2 thorpej * haven't been able to figure out how -- it doesn't give the same values 121 1.2 thorpej */ 122 1.2 thorpej 123 1.3 thorpej static const long val_to_temp[] = { 124 1.2 thorpej 20225, 20435, 20645, 20855, 21045, 21245, 21425, 21615, 21785, 21955, 125 1.2 thorpej 22125, 22285, 22445, 22605, 22755, 22895, 23035, 23175, 23315, 23445, 126 1.2 thorpej 23565, 23695, 23815, 23925, 24045, 24155, 24265, 24365, 24465, 24565, 127 1.2 thorpej 24665, 24765, 24855, 24945, 25025, 25115, 25195, 25275, 25355, 25435, 128 1.2 thorpej 25515, 25585, 25655, 25725, 25795, 25865, 25925, 25995, 26055, 26115, 129 1.2 thorpej 26175, 26235, 26295, 26355, 26405, 26465, 26515, 26575, 26625, 26675, 130 1.2 thorpej 26725, 26775, 26825, 26875, 26925, 26975, 27025, 27065, 27115, 27165, 131 1.2 thorpej 27205, 27255, 27295, 27345, 27385, 27435, 27475, 27515, 27565, 27605, 132 1.2 thorpej 27645, 27685, 27735, 27775, 27815, 27855, 27905, 27945, 27985, 28025, 133 1.2 thorpej 28065, 28105, 28155, 28195, 28235, 28275, 28315, 28355, 28405, 28445, 134 1.2 thorpej 28485, 28525, 28565, 28615, 28655, 28695, 28735, 28775, 28825, 28865, 135 1.2 thorpej 28905, 28945, 28995, 29035, 29075, 29125, 29165, 29205, 29245, 29295, 136 1.2 thorpej 29335, 29375, 29425, 29465, 29505, 29555, 29595, 29635, 29685, 29725, 137 1.2 thorpej 29765, 29815, 29855, 29905, 29945, 29985, 30035, 30075, 30125, 30165, 138 1.2 thorpej 30215, 30255, 30305, 30345, 30385, 30435, 30475, 30525, 30565, 30615, 139 1.2 thorpej 30655, 30705, 30755, 30795, 30845, 30885, 30935, 30975, 31025, 31075, 140 1.2 thorpej 31115, 31165, 31215, 31265, 31305, 31355, 31405, 31455, 31505, 31545, 141 1.2 thorpej 31595, 31645, 31695, 31745, 31805, 31855, 31905, 31955, 32005, 32065, 142 1.2 thorpej 32115, 32175, 32225, 32285, 32335, 32395, 32455, 32515, 32575, 32635, 143 1.2 thorpej 32695, 32755, 32825, 32885, 32955, 33025, 33095, 33155, 33235, 33305, 144 1.2 thorpej 33375, 33455, 33525, 33605, 33685, 33765, 33855, 33935, 34025, 34115, 145 1.2 thorpej 34205, 34295, 34395, 34495, 34595, 34695, 34805, 34905, 35015, 35135, 146 1.2 thorpej 35245, 35365, 35495, 35615, 35745, 35875, 36015, 36145, 36295, 36435, 147 1.2 thorpej 36585, 36745, 36895, 37065, 37225, 37395, 37575, 37755, 37935, 38125, 148 1.2 thorpej 38325, 38525, 38725, 38935, 39155, 39375, 39605, 39835, 40075, 40325, 149 1.2 thorpej 40575, 40835, 41095, 41375, 41655, 41935, 150 1.1 joda }; 151 1.1 joda 152 1.1 joda /* use above table to convert values to temperatures in micro-Kelvins */ 153 1.1 joda static int 154 1.1 joda val_to_uK(unsigned int val) 155 1.1 joda { 156 1.2 thorpej int i = val / 4; 157 1.2 thorpej int j = val % 4; 158 1.2 thorpej 159 1.2 thorpej assert(i >= 0 && i <= 255); 160 1.2 thorpej 161 1.2 thorpej if (j == 0 || i == 255) 162 1.2 thorpej return val_to_temp[i] * 10000; 163 1.2 thorpej 164 1.2 thorpej /* is linear interpolation ok? */ 165 1.2 thorpej return (val_to_temp[i] * (4 - j) + 166 1.2 thorpej val_to_temp[i + 1] * j) * 2500 /* really: / 4 * 10000 */ ; 167 1.1 joda } 168 1.1 joda 169 1.1 joda static int 170 1.1 joda val_to_rpm(unsigned int val, int div) 171 1.1 joda { 172 1.2 thorpej 173 1.2 thorpej if (val == 0) 174 1.2 thorpej return 0; 175 1.2 thorpej 176 1.2 thorpej return 1350000 / val / div; 177 1.1 joda } 178 1.1 joda 179 1.1 joda static long 180 1.1 joda val_to_uV(unsigned int val, int index) 181 1.1 joda { 182 1.3 thorpej static const long mult[] = 183 1.3 thorpej {1250000, 1250000, 1670000, 2600000, 6300000}; 184 1.2 thorpej 185 1.2 thorpej assert(index >= 0 && index <= 4); 186 1.2 thorpej 187 1.2 thorpej return (25LL * val + 133) * mult[index] / 2628; 188 1.1 joda } 189 1.1 joda 190 1.1 joda #define VIAENV_TSENS3 0x1f 191 1.1 joda #define VIAENV_TSENS1 0x20 192 1.1 joda #define VIAENV_TSENS2 0x21 193 1.1 joda #define VIAENV_VSENS1 0x22 194 1.1 joda #define VIAENV_VSENS2 0x23 195 1.1 joda #define VIAENV_VCORE 0x24 196 1.1 joda #define VIAENV_VSENS3 0x25 197 1.1 joda #define VIAENV_VSENS4 0x26 198 1.1 joda #define VIAENV_FAN1 0x29 199 1.1 joda #define VIAENV_FAN2 0x2a 200 1.1 joda #define VIAENV_FANCONF 0x47 /* fan configuration */ 201 1.1 joda #define VIAENV_TLOW 0x49 /* temperature low order value */ 202 1.1 joda #define VIAENV_TIRQ 0x4b /* temperature interrupt configuration */ 203 1.1 joda 204 1.18 xtraeme #define VIAENV_GENCFG 0x40 /* general configuration */ 205 1.18 xtraeme #define VIAENV_GENCFG_TMR32 (1 << 11) /* 32-bit PM timer */ 206 1.18 xtraeme #define VIAENV_GENCFG_PMEN (1 << 15) /* enable PM I/O space */ 207 1.18 xtraeme #define VIAENV_PMBASE 0x48 /* power management I/O space base */ 208 1.18 xtraeme #define VIAENV_PMSIZE 128 /* HWM and power management I/O space size */ 209 1.18 xtraeme #define VIAENV_PM_TMR 0x08 /* PM timer */ 210 1.18 xtraeme #define VIAENV_HWMON_CONF 0x70 /* HWMon I/O base */ 211 1.18 xtraeme #define VIAENV_HWMON_CTL 0x74 /* HWMon control register */ 212 1.1 joda 213 1.1 joda static void 214 1.21 xtraeme viaenv_refresh_sensor_data(struct viaenv_softc *sc, envsys_data_t *edata) 215 1.1 joda { 216 1.6 thorpej static const struct timeval onepointfive = { 1, 500000 }; 217 1.21 xtraeme static int old_sensor = -1; 218 1.14 kardel struct timeval t, utv; 219 1.18 xtraeme uint8_t v, v2; 220 1.14 kardel int i; 221 1.6 thorpej 222 1.6 thorpej /* Read new values at most once every 1.5 seconds. */ 223 1.6 thorpej timeradd(&sc->sc_lastread, &onepointfive, &t); 224 1.14 kardel getmicrouptime(&utv); 225 1.14 kardel i = timercmp(&utv, &t, >); 226 1.6 thorpej if (i) 227 1.14 kardel sc->sc_lastread = utv; 228 1.6 thorpej 229 1.21 xtraeme if (i == 0 && old_sensor == edata->sensor) 230 1.6 thorpej return; 231 1.6 thorpej 232 1.21 xtraeme old_sensor = edata->sensor; 233 1.21 xtraeme 234 1.6 thorpej /* temperature */ 235 1.21 xtraeme if (edata->sensor == 0) { 236 1.21 xtraeme v = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TIRQ); 237 1.21 xtraeme v2 = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TSENS1); 238 1.21 xtraeme DPRINTF(("TSENS1 = %d\n", (v2 << 2) | (v >> 6))); 239 1.22 xtraeme edata->value_cur = val_to_uK((v2 << 2) | (v >> 6)); 240 1.22 xtraeme edata->state = ENVSYS_SVALID; 241 1.21 xtraeme } else if (edata->sensor == 1) { 242 1.21 xtraeme v = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TLOW); 243 1.21 xtraeme v2 = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TSENS2); 244 1.21 xtraeme DPRINTF(("TSENS2 = %d\n", (v2 << 2) | ((v >> 4) & 0x3))); 245 1.22 xtraeme edata->value_cur = val_to_uK((v2 << 2) | ((v >> 4) & 0x3)); 246 1.22 xtraeme edata->state = ENVSYS_SVALID; 247 1.21 xtraeme } else if (edata->sensor == 2) { 248 1.21 xtraeme v = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TLOW); 249 1.21 xtraeme v2 = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TSENS3); 250 1.21 xtraeme DPRINTF(("TSENS3 = %d\n", (v2 << 2) | (v >> 6))); 251 1.22 xtraeme edata->value_cur = val_to_uK((v2 << 2) | (v >> 6)); 252 1.22 xtraeme edata->state = ENVSYS_SVALID; 253 1.21 xtraeme } else if (edata->sensor > 2 && edata->sensor < 5) { 254 1.21 xtraeme /* fans */ 255 1.21 xtraeme v = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_FANCONF); 256 1.2 thorpej 257 1.21 xtraeme sc->sc_fan_div[0] = 1 << ((v >> 4) & 0x3); 258 1.21 xtraeme sc->sc_fan_div[1] = 1 << ((v >> 6) & 0x3); 259 1.1 joda 260 1.6 thorpej v = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 261 1.21 xtraeme VIAENV_FAN1 + edata->sensor - 3); 262 1.21 xtraeme DPRINTF(("FAN%d = %d / %d\n", edata->sensor - 3, v, 263 1.21 xtraeme sc->sc_fan_div[edata->sensor - 3])); 264 1.22 xtraeme edata->value_cur = val_to_rpm(v, 265 1.21 xtraeme sc->sc_fan_div[edata->sensor - 3]); 266 1.22 xtraeme edata->state = ENVSYS_SVALID; 267 1.21 xtraeme } else { 268 1.6 thorpej v = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 269 1.21 xtraeme VIAENV_VSENS1 + edata->sensor - 5); 270 1.21 xtraeme DPRINTF(("V%d = %d\n", edata->sensor - 5, v)); 271 1.22 xtraeme edata->value_cur = val_to_uV(v, edata->sensor - 5); 272 1.22 xtraeme edata->state = ENVSYS_SVALID; 273 1.2 thorpej } 274 1.1 joda } 275 1.1 joda 276 1.1 joda static void 277 1.27 xtraeme viaenv_attach(device_t parent, device_t self, void *aux) 278 1.1 joda { 279 1.27 xtraeme struct viaenv_softc *sc = device_private(self); 280 1.27 xtraeme struct pci_attach_args *pa = aux; 281 1.2 thorpej pcireg_t iobase, control; 282 1.2 thorpej int i; 283 1.2 thorpej 284 1.18 xtraeme aprint_naive("\n"); 285 1.18 xtraeme aprint_normal(": VIA Technologies "); 286 1.18 xtraeme switch (PCI_PRODUCT(pa->pa_id)) { 287 1.34 jdolecek case PCI_PRODUCT_VIATECH_VT82C686A_PWR: 288 1.18 xtraeme aprint_normal("VT82C686A Hardware Monitor\n"); 289 1.18 xtraeme break; 290 1.18 xtraeme case PCI_PRODUCT_VIATECH_VT8231_PWR: 291 1.18 xtraeme aprint_normal("VT8231 Hardware Monitor\n"); 292 1.18 xtraeme break; 293 1.18 xtraeme default: 294 1.18 xtraeme aprint_normal("Unknown Hardware Monitor\n"); 295 1.18 xtraeme break; 296 1.2 thorpej } 297 1.18 xtraeme 298 1.30 phx sc->sc_iot = pa->pa_iot; 299 1.30 phx 300 1.18 xtraeme iobase = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_HWMON_CONF); 301 1.29 ad DPRINTF(("%s: iobase 0x%x\n", device_xname(self), iobase)); 302 1.18 xtraeme control = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_HWMON_CTL); 303 1.18 xtraeme 304 1.18 xtraeme /* Check if the Hardware Monitor enable bit is set */ 305 1.18 xtraeme if ((control & 1) == 0) { 306 1.27 xtraeme aprint_normal_dev(self, "Hardware Monitor disabled\n"); 307 1.18 xtraeme goto nohwm; 308 1.2 thorpej } 309 1.2 thorpej 310 1.18 xtraeme /* Map Hardware Monitor I/O space */ 311 1.18 xtraeme if (bus_space_map(sc->sc_iot, iobase & 0xff80, 312 1.18 xtraeme VIAENV_PMSIZE, 0, &sc->sc_ioh)) { 313 1.27 xtraeme aprint_error_dev(self, "failed to map I/O space\n"); 314 1.18 xtraeme goto nohwm; 315 1.18 xtraeme } 316 1.2 thorpej 317 1.21 xtraeme for (i = 0; i < 3; i++) 318 1.25 xtraeme sc->sc_sensor[i].units = ENVSYS_STEMP; 319 1.2 thorpej 320 1.18 xtraeme #define COPYDESCR(x, y) \ 321 1.18 xtraeme do { \ 322 1.18 xtraeme strlcpy((x), (y), sizeof(x)); \ 323 1.18 xtraeme } while (0) 324 1.18 xtraeme 325 1.25 xtraeme COPYDESCR(sc->sc_sensor[0].desc, "TSENS1"); 326 1.25 xtraeme COPYDESCR(sc->sc_sensor[1].desc, "TSENS2"); 327 1.25 xtraeme COPYDESCR(sc->sc_sensor[2].desc, "TSENS3"); 328 1.18 xtraeme 329 1.21 xtraeme for (i = 3; i < 5; i++) 330 1.25 xtraeme sc->sc_sensor[i].units = ENVSYS_SFANRPM; 331 1.18 xtraeme 332 1.25 xtraeme COPYDESCR(sc->sc_sensor[3].desc, "FAN1"); 333 1.25 xtraeme COPYDESCR(sc->sc_sensor[4].desc, "FAN2"); 334 1.18 xtraeme 335 1.21 xtraeme for (i = 5; i < 10; i++) 336 1.25 xtraeme sc->sc_sensor[i].units = ENVSYS_SVOLTS_DC; 337 1.18 xtraeme 338 1.25 xtraeme COPYDESCR(sc->sc_sensor[5].desc, "VSENS1"); /* CPU core (2V) */ 339 1.25 xtraeme COPYDESCR(sc->sc_sensor[6].desc, "VSENS2"); /* NB core? (2.5V) */ 340 1.25 xtraeme COPYDESCR(sc->sc_sensor[7].desc, "Vcore"); /* Vcore (3.3V) */ 341 1.25 xtraeme COPYDESCR(sc->sc_sensor[8].desc, "VSENS3"); /* VSENS3 (5V) */ 342 1.25 xtraeme COPYDESCR(sc->sc_sensor[9].desc, "VSENS4"); /* VSENS4 (12V) */ 343 1.1 joda 344 1.18 xtraeme #undef COPYDESCR 345 1.18 xtraeme 346 1.33 ozaki for (i = 0; i < 10; i++) { 347 1.31 pgoyette sc->sc_sensor[i].state = ENVSYS_SINVALID; 348 1.32 tls sc->sc_sensor[i].flags |= ENVSYS_FHAS_ENTROPY; 349 1.33 ozaki } 350 1.31 pgoyette 351 1.26 njoly sc->sc_sme = sysmon_envsys_create(); 352 1.26 njoly 353 1.26 njoly /* Initialize sensors */ 354 1.26 njoly for (i = 0; i < VIANUMSENSORS; i++) { 355 1.26 njoly if (sysmon_envsys_sensor_attach(sc->sc_sme, 356 1.26 njoly &sc->sc_sensor[i])) { 357 1.26 njoly sysmon_envsys_destroy(sc->sc_sme); 358 1.26 njoly return; 359 1.26 njoly } 360 1.26 njoly } 361 1.26 njoly 362 1.3 thorpej /* 363 1.3 thorpej * Hook into the System Monitor. 364 1.3 thorpej */ 365 1.27 xtraeme sc->sc_sme->sme_name = device_xname(self); 366 1.25 xtraeme sc->sc_sme->sme_cookie = sc; 367 1.25 xtraeme sc->sc_sme->sme_refresh = viaenv_refresh; 368 1.3 thorpej 369 1.25 xtraeme if (sysmon_envsys_register(sc->sc_sme)) { 370 1.27 xtraeme aprint_error_dev(self, "unable to register with sysmon\n"); 371 1.25 xtraeme sysmon_envsys_destroy(sc->sc_sme); 372 1.25 xtraeme return; 373 1.25 xtraeme } 374 1.18 xtraeme 375 1.18 xtraeme nohwm: 376 1.18 xtraeme /* Check if power management I/O space is enabled */ 377 1.18 xtraeme control = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_GENCFG); 378 1.18 xtraeme if ((control & VIAENV_GENCFG_PMEN) == 0) { 379 1.27 xtraeme aprint_normal_dev(self, 380 1.27 xtraeme "Power Managament controller disabled\n"); 381 1.18 xtraeme goto nopm; 382 1.18 xtraeme } 383 1.18 xtraeme 384 1.18 xtraeme /* Map power management I/O space */ 385 1.18 xtraeme iobase = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_PMBASE); 386 1.18 xtraeme if (bus_space_map(sc->sc_iot, PCI_MAPREG_IO_ADDR(iobase), 387 1.18 xtraeme VIAENV_PMSIZE, 0, &sc->sc_pm_ioh)) { 388 1.27 xtraeme aprint_error_dev(self, "failed to map PM I/O space\n"); 389 1.18 xtraeme goto nopm; 390 1.18 xtraeme } 391 1.18 xtraeme 392 1.18 xtraeme /* Attach our PM timer with the generic acpipmtimer function */ 393 1.27 xtraeme acpipmtimer_attach(self, sc->sc_iot, sc->sc_pm_ioh, 394 1.18 xtraeme VIAENV_PM_TMR, 395 1.18 xtraeme ((control & VIAENV_GENCFG_TMR32) ? ACPIPMT_32BIT : 0)); 396 1.18 xtraeme 397 1.18 xtraeme nopm: 398 1.18 xtraeme return; 399 1.1 joda } 400 1.1 joda 401 1.25 xtraeme static void 402 1.25 xtraeme viaenv_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 403 1.1 joda { 404 1.3 thorpej struct viaenv_softc *sc = sme->sme_cookie; 405 1.1 joda 406 1.21 xtraeme viaenv_refresh_sensor_data(sc, edata); 407 1.1 joda } 408