1 /* $OpenBSD: fins.c,v 1.1 2008/03/19 19:33:09 deraadt Exp $ */ 2 /* $NetBSD: finsio_isa.c,v 1.4 2008/04/22 13:33:38 xtraeme Exp $ */ 3 4 /* 5 * Copyright (c) 2008 Juan Romero Pardines 6 * Copyright (c) 2007, 2008 Geoff Steckel 7 * Copyright (c) 2005, 2006 Mark Kettenis 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 #include <sys/cdefs.h> 22 __KERNEL_RCSID(0, "$NetBSD: finsio_isa.c,v 1.4 2008/04/22 13:33:38 xtraeme Exp $"); 23 24 #include <sys/param.h> 25 #include <sys/systm.h> 26 #include <sys/device.h> 27 #include <sys/bus.h> 28 29 #include <dev/isa/isareg.h> 30 #include <dev/isa/isavar.h> 31 32 #include <dev/sysmon/sysmonvar.h> 33 34 /* Derived from LM78 code. Only handles chips attached to ISA bus */ 35 36 /* 37 * Fintek F71805/F71883 Super I/O datasheets: 38 * http://www.fintek.com.tw/files/productfiles/F71805F_V025.pdf 39 * http://www.fintek.com.tw/files/productfiles/F71883_V026P.pdf 40 * 41 * This chip is a multi-io chip with many functions. 42 * Each function may be relocated in I/O space by the BIOS. 43 * The base address (2E or 4E) accesses a configuration space which 44 * has pointers to the individual functions. The config space must be 45 * unlocked with a cookie and relocked afterwards. The chip ID is stored 46 * in config space so it is not normally visible. 47 * 48 * The voltage dividers specified are from reading the chips on one board. 49 * There is no way to determine what they are in the general case. 50 */ 51 52 #define FINSIO_UNLOCK 0x87 /* magic constant - write 2x to select chip */ 53 #define FINSIO_LOCK 0xaa /* magic constant - write 1x to deselect reg */ 54 55 #define FINSIO_FUNC_SEL 0x07 /* select which subchip to access */ 56 # define FINSIO_FUNC_HWMON 0x4 57 58 /* ISA registers index to an internal register space on chip */ 59 #define FINSIO_ADDR 0 /* global configuration index registers */ 60 #define FINSIO_DATA 1 61 62 /* 63 * The F71882/F71883 chips use a different Hardware Monitor 64 * address offset. 65 */ 66 #define FINSIO_F71882_HWM_OFFSET 5 67 68 /* Global configuration registers */ 69 #define FINSIO_MANUF 0x23 /* manufacturer ID */ 70 # define FINTEK_ID 0x1934 71 #define FINSIO_CHIP 0x20 /* chip ID */ 72 # define FINSIO_IDF71805 0x0406 73 # define FINSIO_IDF71806 0x0341 /* F71872 and F1806 F/FG */ 74 # define FINSIO_IDF71883 0x0541 /* F71882 and F1883 */ 75 # define FINSIO_IDF71862 0x0601 /* F71862FG */ 76 77 /* in bank sensors of config space */ 78 #define FINSIO_SENSADDR 0x60 /* sensors assigned I/O address (2 bytes) */ 79 80 #define FINSIO_HWMON_CONF 0x01 /* Hardware Monitor Config. Register */ 81 82 /* in sensors space */ 83 #define FINSIO_TMODE 0x01 /* temperature mode reg */ 84 85 #define FINSIO_MAX_SENSORS 20 86 /* 87 * Fintek chips typically measure voltages using 8mv steps. 88 * To measure higher voltages the input is attenuated with (external) 89 * resistors. Negative voltages are measured using inverting op amps 90 * and resistors. So we have to convert the sensor values back to 91 * real voltages by applying the appropriate resistor factor. 92 */ 93 #define FRFACT_NONE 8000 94 #define FRFACT(x, y) (FRFACT_NONE * ((x) + (y)) / (y)) 95 #define FNRFACT(x, y) (-FRFACT_NONE * (x) / (y)) 96 97 #if defined(FINSIODEBUG) 98 #define DPRINTF(x) do { printf x; } while (0) 99 #else 100 #define DPRINTF(x) 101 #endif 102 103 struct finsio_softc { 104 bus_space_tag_t sc_iot; 105 bus_space_handle_t sc_ioh; 106 107 struct sysmon_envsys *sc_sme; 108 envsys_data_t sc_sensor[FINSIO_MAX_SENSORS]; 109 struct finsio_sensor *sc_finsio_sensors; 110 111 u_int sc_tempsel; 112 }; 113 114 struct finsio_sensor { 115 const char *fs_desc; 116 u_int fs_type; 117 uint8_t fs_aux; 118 uint8_t fs_reg; 119 void (*fs_refresh)(struct finsio_softc *, envsys_data_t *); 120 int fs_rfact; 121 }; 122 123 static int finsio_isa_match(device_t, cfdata_t, void *); 124 static void finsio_isa_attach(device_t, device_t, void *); 125 static int finsio_isa_detach(device_t, int); 126 127 static void finsio_enter(bus_space_tag_t, bus_space_handle_t); 128 static void finsio_exit(bus_space_tag_t, bus_space_handle_t); 129 static uint8_t finsio_readreg(bus_space_tag_t, bus_space_handle_t, int); 130 static void finsio_writereg(bus_space_tag_t, bus_space_handle_t, int, int); 131 132 static void finsio_refresh(struct sysmon_envsys *, envsys_data_t *); 133 static void finsio_refresh_volt(struct finsio_softc *, envsys_data_t *); 134 static void finsio_refresh_temp(struct finsio_softc *, envsys_data_t *); 135 static void finsio_refresh_fanrpm(struct finsio_softc *, envsys_data_t *); 136 137 CFATTACH_DECL_NEW(finsio, sizeof(struct finsio_softc), 138 finsio_isa_match, finsio_isa_attach, finsio_isa_detach, NULL); 139 140 /* Sensors available in F71805/F71806 */ 141 static struct finsio_sensor f71805_sensors[] = { 142 /* Voltage */ 143 { 144 .fs_desc = "+3.3V", 145 .fs_type = ENVSYS_SVOLTS_DC, 146 .fs_aux = 0, 147 .fs_reg = 0x10, 148 .fs_refresh = finsio_refresh_volt, 149 .fs_rfact = FRFACT(100, 100) 150 }, 151 { 152 .fs_desc = "Vtt", 153 .fs_type = ENVSYS_SVOLTS_DC, 154 .fs_aux = 0, 155 .fs_reg = 0x11, 156 .fs_refresh = finsio_refresh_volt, 157 .fs_rfact = FRFACT_NONE 158 }, 159 { 160 .fs_desc = "Vram", 161 .fs_type = ENVSYS_SVOLTS_DC, 162 .fs_aux = 0, 163 .fs_reg = 0x12, 164 .fs_refresh = finsio_refresh_volt, 165 .fs_rfact = FRFACT(100, 100) 166 }, 167 { 168 .fs_desc = "Vchips", 169 .fs_type = ENVSYS_SVOLTS_DC, 170 .fs_aux = 0, 171 .fs_reg = 0x13, 172 .fs_refresh = finsio_refresh_volt, 173 .fs_rfact = FRFACT(47, 100) 174 }, 175 { 176 .fs_desc = "+5V", 177 .fs_type = ENVSYS_SVOLTS_DC, 178 .fs_aux = 0, 179 .fs_reg = 0x14, 180 .fs_refresh = finsio_refresh_volt, 181 .fs_rfact = FRFACT(200, 47) 182 }, 183 { 184 .fs_desc = "+12V", 185 .fs_type = ENVSYS_SVOLTS_DC, 186 .fs_aux = 0, 187 .fs_reg = 0x15, 188 .fs_refresh = finsio_refresh_volt, 189 .fs_rfact = FRFACT(200, 20) 190 }, 191 { 192 .fs_desc = "Vcc 1.5V", 193 .fs_type = ENVSYS_SVOLTS_DC, 194 .fs_aux = 0, 195 .fs_reg = 0x16, 196 .fs_refresh = finsio_refresh_volt, 197 .fs_rfact = FRFACT_NONE 198 }, 199 { 200 .fs_desc = "VCore", 201 .fs_type = ENVSYS_SVOLTS_DC, 202 .fs_aux = 0, 203 .fs_reg = 0x17, 204 .fs_refresh = finsio_refresh_volt, 205 .fs_rfact = FRFACT_NONE 206 }, 207 { 208 .fs_desc = "Vsb", 209 .fs_type = ENVSYS_SVOLTS_DC, 210 .fs_aux = 0, 211 .fs_reg = 0x18, 212 .fs_refresh = finsio_refresh_volt, 213 .fs_rfact = FRFACT(200, 47) 214 }, 215 { 216 .fs_desc = "Vsbint", 217 .fs_type = ENVSYS_SVOLTS_DC, 218 .fs_aux = 0, 219 .fs_reg = 0x19, 220 .fs_refresh = finsio_refresh_volt, 221 .fs_rfact = FRFACT(200, 47) 222 }, 223 { 224 .fs_desc = "Vbat", 225 .fs_type = ENVSYS_SVOLTS_DC, 226 .fs_aux = 0, 227 .fs_reg = 0x1a, 228 .fs_refresh = finsio_refresh_volt, 229 .fs_rfact = FRFACT(200, 47) 230 }, 231 /* Temperature */ 232 { 233 .fs_desc = "Temp1", 234 .fs_type = ENVSYS_STEMP, 235 .fs_aux = 0x01, 236 .fs_reg = 0x1b, 237 .fs_refresh = finsio_refresh_temp, 238 .fs_rfact = 0 239 }, 240 { 241 .fs_desc = "Temp2", 242 .fs_type = ENVSYS_STEMP, 243 .fs_aux = 0x02, 244 .fs_reg = 0x1c, 245 .fs_refresh = finsio_refresh_temp, 246 .fs_rfact = 0 247 }, 248 { 249 .fs_desc = "Temp3", 250 .fs_type = ENVSYS_STEMP, 251 .fs_aux = 0x04, 252 .fs_reg = 0x1d, 253 .fs_refresh = finsio_refresh_temp, 254 .fs_rfact = 0 255 }, 256 /* Fans */ 257 { 258 .fs_desc = "Fan1", 259 .fs_type = ENVSYS_SFANRPM, 260 .fs_aux = 0, 261 .fs_reg = 0x20, 262 .fs_refresh = finsio_refresh_fanrpm, 263 .fs_rfact = 0 264 }, 265 { 266 .fs_desc = "Fan2", 267 .fs_type = ENVSYS_SFANRPM, 268 .fs_aux = 0, 269 .fs_reg = 0x22, 270 .fs_refresh = finsio_refresh_fanrpm, 271 .fs_rfact = 0 272 }, 273 { 274 .fs_desc = "Fan3", 275 .fs_type = ENVSYS_SFANRPM, 276 .fs_aux = 0, 277 .fs_reg = 0x24, 278 .fs_refresh = finsio_refresh_fanrpm, 279 .fs_rfact = 0 280 }, 281 282 { .fs_desc = NULL } 283 }; 284 285 /* Sensors available in F71862/F71882/F71883 */ 286 static struct finsio_sensor f71883_sensors[] = { 287 /* Voltage */ 288 { 289 .fs_desc = "+3.3V", 290 .fs_type = ENVSYS_SVOLTS_DC, 291 .fs_aux = 0, 292 .fs_reg = 0x20, 293 .fs_refresh = finsio_refresh_volt, 294 .fs_rfact = FRFACT(100, 100) 295 }, 296 { 297 .fs_desc = "Vcore", 298 .fs_type = ENVSYS_SVOLTS_DC, 299 .fs_aux = 0, 300 .fs_reg = 0x21, 301 .fs_refresh = finsio_refresh_volt, 302 .fs_rfact = FRFACT_NONE 303 }, 304 { 305 .fs_desc = "VIN2", 306 .fs_type = ENVSYS_SVOLTS_DC, 307 .fs_aux = 0, 308 .fs_reg = 0x22, 309 .fs_refresh = finsio_refresh_volt, 310 .fs_rfact = FRFACT(100, 100) 311 }, 312 { 313 .fs_desc = "VIN3", 314 .fs_type = ENVSYS_SVOLTS_DC, 315 .fs_aux = 0, 316 .fs_reg = 0x23, 317 .fs_refresh = finsio_refresh_volt, 318 .fs_rfact = FRFACT(47, 100) 319 }, 320 { 321 .fs_desc = "VIN4", 322 .fs_type = ENVSYS_SVOLTS_DC, 323 .fs_aux = 0, 324 .fs_reg = 0x24, 325 .fs_refresh = finsio_refresh_volt, 326 .fs_rfact = FRFACT(200, 47) 327 }, 328 { 329 .fs_desc = "VIN5", 330 .fs_type = ENVSYS_SVOLTS_DC, 331 .fs_aux = 0, 332 .fs_reg = 0x25, 333 .fs_refresh = finsio_refresh_volt, 334 .fs_rfact = FRFACT(200, 20) 335 }, 336 { 337 .fs_desc = "VIN6", 338 .fs_type = ENVSYS_SVOLTS_DC, 339 .fs_aux = 0, 340 .fs_reg = 0x26, 341 .fs_refresh = finsio_refresh_volt, 342 .fs_rfact = FRFACT(100, 100) 343 }, 344 { 345 .fs_desc = "VSB +3.3V", 346 .fs_type = ENVSYS_SVOLTS_DC, 347 .fs_aux = 0, 348 .fs_reg = 0x27, 349 .fs_refresh = finsio_refresh_volt, 350 .fs_rfact = FRFACT(200, 47) 351 }, 352 { 353 .fs_desc = "VBAT", 354 .fs_type = ENVSYS_SVOLTS_DC, 355 .fs_aux = 0, 356 .fs_reg = 0x28, 357 .fs_refresh = finsio_refresh_volt, 358 .fs_rfact = FRFACT(200, 47) 359 }, 360 /* Temperature */ 361 { 362 .fs_desc = "Temp1", 363 .fs_type = ENVSYS_STEMP, 364 .fs_aux = 0x1, 365 .fs_reg = 0x72, 366 .fs_refresh = finsio_refresh_temp, 367 .fs_rfact = 0 368 }, 369 { 370 .fs_desc = "Temp2", 371 .fs_type = ENVSYS_STEMP, 372 .fs_aux = 0x2, 373 .fs_reg = 0x74, 374 .fs_refresh = finsio_refresh_temp, 375 .fs_rfact = 0 376 }, 377 { 378 .fs_desc = "Temp3", 379 .fs_type = ENVSYS_STEMP, 380 .fs_aux = 0x4, 381 .fs_reg = 0x76, 382 .fs_refresh = finsio_refresh_temp, 383 .fs_rfact = 0 384 }, 385 /* Fan */ 386 { 387 .fs_desc = "Fan1", 388 .fs_type = ENVSYS_SFANRPM, 389 .fs_aux = 0, 390 .fs_reg = 0xa0, 391 .fs_refresh = finsio_refresh_fanrpm, 392 .fs_rfact = 0 393 }, 394 { 395 .fs_desc = "Fan2", 396 .fs_type = ENVSYS_SFANRPM, 397 .fs_aux = 0, 398 .fs_reg = 0xb0, 399 .fs_refresh = finsio_refresh_fanrpm, 400 .fs_rfact = 0 401 }, 402 { 403 .fs_desc = "Fan3", 404 .fs_type = ENVSYS_SFANRPM, 405 .fs_aux = 0, 406 .fs_reg = 0xc0, 407 .fs_refresh = finsio_refresh_fanrpm, 408 .fs_rfact = 0 409 }, 410 { 411 .fs_desc = "Fan4", 412 .fs_type = ENVSYS_SFANRPM, 413 .fs_aux = 0, 414 .fs_reg = 0xd0, 415 .fs_refresh = finsio_refresh_fanrpm, 416 .fs_rfact = 0 417 }, 418 419 { .fs_desc = NULL } 420 }; 421 422 static int 423 finsio_isa_match(device_t parent, cfdata_t match, void *aux) 424 { 425 struct isa_attach_args *ia = aux; 426 bus_space_handle_t ioh; 427 uint16_t val; 428 429 /* Must supply an address */ 430 if (ia->ia_nio < 1) 431 return 0; 432 433 if (ISA_DIRECT_CONFIG(ia)) 434 return 0; 435 436 if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) 437 return 0; 438 439 if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, 2, 0, &ioh)) 440 return 0; 441 442 finsio_enter(ia->ia_iot, ioh); 443 /* Find out Manufacturer ID */ 444 val = finsio_readreg(ia->ia_iot, ioh, FINSIO_MANUF) << 8; 445 val |= finsio_readreg(ia->ia_iot, ioh, FINSIO_MANUF + 1); 446 finsio_exit(ia->ia_iot, ioh); 447 bus_space_unmap(ia->ia_iot, ioh, 2); 448 449 if (val != FINTEK_ID) 450 return 0; 451 452 ia->ia_nio = 1; 453 ia->ia_io[0].ir_size = 2; 454 ia->ia_niomem = 0; 455 ia->ia_nirq = 0; 456 ia->ia_ndrq = 0; 457 458 return 1; 459 } 460 461 static void 462 finsio_isa_attach(device_t parent, device_t self, void *aux) 463 { 464 struct finsio_softc *sc = device_private(self); 465 struct isa_attach_args *ia = aux; 466 bus_space_handle_t ioh; 467 uint16_t hwmon_baddr, chipid, cr; 468 int i, rv = 0; 469 470 aprint_naive("\n"); 471 472 sc->sc_iot = ia->ia_iot; 473 474 /* Map Super I/O configuration space */ 475 if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 2, 0, &ioh)) { 476 aprint_error(": can't map configuration I/O space\n"); 477 return; 478 } 479 480 finsio_enter(sc->sc_iot, ioh); 481 /* Get the Chip ID */ 482 chipid = finsio_readreg(sc->sc_iot, ioh, FINSIO_CHIP) << 8; 483 chipid |= finsio_readreg(sc->sc_iot, ioh, FINSIO_CHIP + 1); 484 /* 485 * Select the Hardware Monitor LDN to find out the I/O 486 * address space. 487 */ 488 finsio_writereg(sc->sc_iot, ioh, FINSIO_FUNC_SEL, FINSIO_FUNC_HWMON); 489 hwmon_baddr = finsio_readreg(sc->sc_iot, ioh, FINSIO_SENSADDR) << 8; 490 hwmon_baddr |= finsio_readreg(sc->sc_iot, ioh, FINSIO_SENSADDR + 1); 491 finsio_exit(sc->sc_iot, ioh); 492 bus_space_unmap(sc->sc_iot, ioh, 2); 493 494 switch (chipid) { 495 case FINSIO_IDF71805: 496 sc->sc_finsio_sensors = f71805_sensors; 497 aprint_normal(": Fintek F71805 Super I/O\n"); 498 break; 499 case FINSIO_IDF71806: 500 sc->sc_finsio_sensors = f71805_sensors; 501 aprint_normal(": Fintek F71806/F71872 Super I/O\n"); 502 break; 503 case FINSIO_IDF71862: 504 hwmon_baddr += FINSIO_F71882_HWM_OFFSET; 505 sc->sc_finsio_sensors = f71883_sensors; 506 aprint_normal(": Fintek F71862 Super I/O\n"); 507 break; 508 case FINSIO_IDF71883: 509 hwmon_baddr += FINSIO_F71882_HWM_OFFSET; 510 sc->sc_finsio_sensors = f71883_sensors; 511 aprint_normal(": Fintek F71882/F71883 Super I/O\n"); 512 break; 513 default: 514 /* 515 * Unknown Chip ID, assume the same register layout 516 * than F71805 for now. 517 */ 518 sc->sc_finsio_sensors = f71805_sensors; 519 aprint_normal(": Fintek Super I/O (unknown chip ID %x)\n", 520 chipid); 521 break; 522 } 523 524 /* Map Hardware Monitor I/O space */ 525 if (bus_space_map(sc->sc_iot, hwmon_baddr, 2, 0, &sc->sc_ioh)) { 526 aprint_error(": can't map hwmon I/O space\n"); 527 return; 528 } 529 530 /* 531 * Enable Hardware monitoring for fan/temperature and 532 * voltage sensors. 533 */ 534 cr = finsio_readreg(sc->sc_iot, sc->sc_ioh, FINSIO_HWMON_CONF); 535 finsio_writereg(sc->sc_iot, sc->sc_ioh, FINSIO_HWMON_CONF, cr | 0x3); 536 537 /* Find out the temperature mode */ 538 sc->sc_tempsel = finsio_readreg(sc->sc_iot, sc->sc_ioh, FINSIO_TMODE); 539 540 /* 541 * Initialize and attach sensors with sysmon_envsys(9). 542 */ 543 sc->sc_sme = sysmon_envsys_create(); 544 for (i = 0; sc->sc_finsio_sensors[i].fs_desc; i++) { 545 sc->sc_sensor[i].units = sc->sc_finsio_sensors[i].fs_type; 546 if (sc->sc_sensor[i].units == ENVSYS_SVOLTS_DC) 547 sc->sc_sensor[i].flags = ENVSYS_FCHANGERFACT; 548 strlcpy(sc->sc_sensor[i].desc, sc->sc_finsio_sensors[i].fs_desc, 549 sizeof(sc->sc_sensor[i].desc)); 550 if (sysmon_envsys_sensor_attach(sc->sc_sme, 551 &sc->sc_sensor[i])) 552 goto fail; 553 } 554 555 sc->sc_sme->sme_name = device_xname(self); 556 sc->sc_sme->sme_cookie = sc; 557 sc->sc_sme->sme_refresh = finsio_refresh; 558 if ((rv = sysmon_envsys_register(sc->sc_sme))) { 559 aprint_error(": unable to register with sysmon (%d)\n", rv); 560 goto fail; 561 } 562 563 aprint_normal_dev(self, 564 "Hardware Monitor registers at 0x%x\n", hwmon_baddr); 565 return; 566 567 fail: 568 sysmon_envsys_destroy(sc->sc_sme); 569 bus_space_unmap(sc->sc_iot, sc->sc_ioh, 2); 570 } 571 572 static int 573 finsio_isa_detach(device_t self, int flags) 574 { 575 struct finsio_softc *sc = device_private(self); 576 577 sysmon_envsys_unregister(sc->sc_sme); 578 bus_space_unmap(sc->sc_iot, sc->sc_ioh, 2); 579 return 0; 580 } 581 582 /* Enter Super I/O configuration mode */ 583 static void 584 finsio_enter(bus_space_tag_t iot, bus_space_handle_t ioh) 585 { 586 bus_space_write_1(iot, ioh, FINSIO_ADDR, FINSIO_UNLOCK); 587 bus_space_write_1(iot, ioh, FINSIO_ADDR, FINSIO_UNLOCK); 588 } 589 590 /* Exit Super I/O configuration mode */ 591 static void 592 finsio_exit(bus_space_tag_t iot, bus_space_handle_t ioh) 593 { 594 bus_space_write_1(iot, ioh, FINSIO_ADDR, FINSIO_LOCK); 595 } 596 597 static uint8_t 598 finsio_readreg(bus_space_tag_t iot, bus_space_handle_t ioh, int reg) 599 { 600 bus_space_write_1(iot, ioh, FINSIO_ADDR, reg); 601 return bus_space_read_1(iot, ioh, FINSIO_DATA); 602 } 603 604 static void 605 finsio_writereg(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, int val) 606 { 607 bus_space_write_1(iot, ioh, FINSIO_ADDR, reg); 608 bus_space_write_1(iot, ioh, FINSIO_DATA, val); 609 } 610 611 static void 612 finsio_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 613 { 614 struct finsio_softc *sc = sme->sme_cookie; 615 int i = edata->sensor; 616 617 sc->sc_finsio_sensors[i].fs_refresh(sc, edata); 618 } 619 620 static void 621 finsio_refresh_volt(struct finsio_softc *sc, envsys_data_t *edata) 622 { 623 struct finsio_sensor *fs = &sc->sc_finsio_sensors[edata->sensor]; 624 int data; 625 626 data = finsio_readreg(sc->sc_iot, sc->sc_ioh, fs->fs_reg); 627 DPRINTF(("%s: data 0x%x\n", __func__, data)); 628 629 if (data == 0xff || data == 0) 630 edata->state = ENVSYS_SINVALID; 631 else { 632 edata->state = ENVSYS_SVALID; 633 if (edata->rfact) 634 edata->value_cur = data * edata->rfact; 635 else 636 edata->value_cur = data * fs->fs_rfact; 637 } 638 } 639 640 /* The BIOS seems to add a fudge factor to the CPU temp of +5C */ 641 static void 642 finsio_refresh_temp(struct finsio_softc *sc, envsys_data_t *edata) 643 { 644 struct finsio_sensor *fs = &sc->sc_finsio_sensors[edata->sensor]; 645 u_int data; 646 u_int llmax; 647 648 /* 649 * The data sheet says that the range of the temperature 650 * sensor is between 0 and 127 or 140 degrees C depending on 651 * what kind of sensor is used. 652 * A disconnected sensor seems to read over 110 or so. 653 */ 654 data = finsio_readreg(sc->sc_iot, sc->sc_ioh, fs->fs_reg) & 0xFF; 655 DPRINTF(("%s: data 0x%x\n", __func__, data)); 656 657 llmax = (sc->sc_tempsel & fs->fs_aux) ? 111 : 128; 658 if (data == 0 || data >= llmax) /* disconnected? */ 659 edata->state = ENVSYS_SINVALID; 660 else { 661 edata->state = ENVSYS_SVALID; 662 edata->value_cur = data * 1000000 + 273150000; 663 } 664 } 665 666 /* fan speed appears to be a 12-bit number */ 667 static void 668 finsio_refresh_fanrpm(struct finsio_softc *sc, envsys_data_t *edata) 669 { 670 struct finsio_sensor *fs = &sc->sc_finsio_sensors[edata->sensor]; 671 int data; 672 673 data = finsio_readreg(sc->sc_iot, sc->sc_ioh, fs->fs_reg) << 8; 674 data |= finsio_readreg(sc->sc_iot, sc->sc_ioh, fs->fs_reg + 1); 675 DPRINTF(("%s: data 0x%x\n", __func__, data)); 676 677 if (data >= 0xfff) 678 edata->state = ENVSYS_SINVALID; 679 else { 680 edata->value_cur = 1500000 / data; 681 edata->state = ENVSYS_SVALID; 682 } 683 } 684