1 /* $NetBSD: nslm7x.c,v 1.78 2022/10/01 07:22:56 msaitoh Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Bill Squier. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1.78 2022/10/01 07:22:56 msaitoh Exp $"); 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/proc.h> 39 #include <sys/device.h> 40 #include <sys/module.h> 41 #include <sys/conf.h> 42 #include <sys/time.h> 43 44 #include <sys/bus.h> 45 46 #include <dev/isa/isareg.h> 47 #include <dev/isa/isavar.h> 48 #include <dev/isa/wbsioreg.h> 49 50 #include <dev/sysmon/sysmonvar.h> 51 52 #include <dev/ic/nslm7xvar.h> 53 54 #include <sys/intr.h> 55 56 #if defined(LMDEBUG) 57 #define DPRINTF(x) do { printf x; } while (0) 58 #else 59 #define DPRINTF(x) 60 #endif 61 62 /* 63 * LM78-compatible chips can typically measure voltages up to 4.096 V. 64 * To measure higher voltages the input is attenuated with (external) 65 * resistors. Negative voltages are measured using inverting op amps 66 * and resistors. So we have to convert the sensor values back to 67 * real voltages by applying the appropriate resistor factor. 68 */ 69 #define RFACT_NONE 10000 70 #define RFACT(x, y) (RFACT_NONE * ((x) + (y)) / (y)) 71 #define NRFACT(x, y) (-RFACT_NONE * (x) / (y)) 72 73 #define LM_REFRESH_TIMO (2 * hz) /* 2 seconds */ 74 75 static const struct wb_product *wb_lookup(struct lm_softc *, 76 const struct wb_product *, uint16_t); 77 static int wb_match(struct lm_softc *); 78 static int wb_attach(struct lm_softc *); 79 static int nslm_match(struct lm_softc *); 80 static int nslm_attach(struct lm_softc *); 81 static int def_match(struct lm_softc *); 82 static int def_attach(struct lm_softc *); 83 static void wb_temp_diode_type(struct lm_softc *, int); 84 static uint16_t wb_read_vendorid(struct lm_softc *); 85 86 static void lm_refresh(void *); 87 88 static void lm_generic_banksel(struct lm_softc *, uint8_t); 89 static void lm_setup_sensors(struct lm_softc *, const struct lm_sensor *); 90 static void lm_refresh_sensor_data(struct lm_softc *); 91 static void lm_refresh_volt(struct lm_softc *, int); 92 static void lm_refresh_temp(struct lm_softc *, int); 93 static void lm_refresh_fanrpm(struct lm_softc *, int); 94 95 static void wb_refresh_sensor_data(struct lm_softc *); 96 static void wb_w83637hf_refresh_vcore(struct lm_softc *, int); 97 static void wb_refresh_nvolt(struct lm_softc *, int); 98 static void wb_w83627ehf_refresh_nvolt(struct lm_softc *, int); 99 static void wb_refresh_temp(struct lm_softc *, int); 100 static void wb_refresh_fanrpm(struct lm_softc *, int); 101 static void wb_w83792d_refresh_fanrpm(struct lm_softc *, int); 102 static void wb_nct6776f_refresh_fanrpm(struct lm_softc *, int); 103 104 static void as_refresh_temp(struct lm_softc *, int); 105 106 struct lm_chip { 107 int (*chip_match)(struct lm_softc *); 108 int (*chip_attach)(struct lm_softc *); 109 }; 110 111 static struct lm_chip lm_chips[] = { 112 { wb_match, wb_attach }, 113 { nslm_match, nslm_attach }, 114 { def_match, def_attach } /* Must be last */ 115 }; 116 117 /* LM78/78J/79/81 */ 118 static const struct lm_sensor lm78_sensors[] = { 119 /* Voltage */ 120 { 121 .desc = "VCore A", 122 .type = ENVSYS_SVOLTS_DC, 123 .bank = 0, 124 .reg = 0x20, 125 .refresh = lm_refresh_volt, 126 .rfact = RFACT_NONE 127 }, 128 { 129 .desc = "VCore B", 130 .type = ENVSYS_SVOLTS_DC, 131 .bank = 0, 132 .reg = 0x21, 133 .refresh = lm_refresh_volt, 134 .rfact = RFACT_NONE 135 }, 136 { 137 .desc = "+3.3V", 138 .type = ENVSYS_SVOLTS_DC, 139 .bank = 0, 140 .reg = 0x22, 141 .refresh = lm_refresh_volt, 142 .rfact = RFACT_NONE 143 }, 144 { 145 .desc = "+5V", 146 .type = ENVSYS_SVOLTS_DC, 147 .bank = 0, 148 .reg = 0x23, 149 .refresh = lm_refresh_volt, 150 .rfact = RFACT(68, 100) 151 }, 152 { 153 .desc = "+12V", 154 .type = ENVSYS_SVOLTS_DC, 155 .bank = 0, 156 .reg = 0x24, 157 .refresh = lm_refresh_volt, 158 .rfact = RFACT(30, 10) 159 }, 160 { 161 .desc = "-12V", 162 .type = ENVSYS_SVOLTS_DC, 163 .bank = 0, 164 .reg = 0x25, 165 .refresh = lm_refresh_volt, 166 .rfact = NRFACT(240, 60) 167 }, 168 { 169 .desc = "-5V", 170 .type = ENVSYS_SVOLTS_DC, 171 .bank = 0, 172 .reg = 0x26, 173 .refresh = lm_refresh_volt, 174 .rfact = NRFACT(100, 60) 175 }, 176 177 /* Temperature */ 178 { 179 .desc = "Temp0", 180 .type = ENVSYS_STEMP, 181 .bank = 0, 182 .reg = 0x27, 183 .refresh = lm_refresh_temp, 184 .rfact = 0 185 }, 186 187 /* Fans */ 188 { 189 .desc = "Fan0", 190 .type = ENVSYS_SFANRPM, 191 .bank = 0, 192 .reg = 0x28, 193 .refresh = lm_refresh_fanrpm, 194 .rfact = 0 195 }, 196 { 197 .desc = "Fan1", 198 .type = ENVSYS_SFANRPM, 199 .bank = 0, 200 .reg = 0x29, 201 .refresh = lm_refresh_fanrpm, 202 .rfact = 0 203 }, 204 { 205 .desc = "Fan2", 206 .type = ENVSYS_SFANRPM, 207 .bank = 0, 208 .reg = 0x2a, 209 .refresh = lm_refresh_fanrpm, 210 .rfact = 0 211 }, 212 213 { .desc = NULL } 214 }; 215 216 /* W83627HF */ 217 static const struct lm_sensor w83627hf_sensors[] = { 218 /* Voltage */ 219 { 220 .desc = "VCore A", 221 .type = ENVSYS_SVOLTS_DC, 222 .bank = 0, 223 .reg = 0x20, 224 .refresh = lm_refresh_volt, 225 .rfact = RFACT_NONE 226 }, 227 { 228 .desc = "VCore B", 229 .type = ENVSYS_SVOLTS_DC, 230 .bank = 0, 231 .reg = 0x21, 232 .refresh = lm_refresh_volt, 233 .rfact = RFACT_NONE 234 }, 235 { 236 .desc = "+3.3V", 237 .type = ENVSYS_SVOLTS_DC, 238 .bank = 0, 239 .reg = 0x22, 240 .refresh = lm_refresh_volt, 241 .rfact = RFACT_NONE 242 }, 243 { 244 .desc = "+5V", 245 .type = ENVSYS_SVOLTS_DC, 246 .bank = 0, 247 .reg = 0x23, 248 .refresh = lm_refresh_volt, 249 .rfact = RFACT(34, 50) 250 }, 251 { 252 .desc = "+12V", 253 .type = ENVSYS_SVOLTS_DC, 254 .bank = 0, 255 .reg = 0x24, 256 .refresh = lm_refresh_volt, 257 .rfact = RFACT(28, 10) 258 }, 259 { 260 .desc = "-12V", 261 .type = ENVSYS_SVOLTS_DC, 262 .bank = 0, 263 .reg = 0x25, 264 .refresh = wb_refresh_nvolt, 265 .rfact = RFACT(232, 56) 266 }, 267 { 268 .desc = "-5V", 269 .type = ENVSYS_SVOLTS_DC, 270 .bank = 0, 271 .reg = 0x26, 272 .refresh = wb_refresh_nvolt, 273 .rfact = RFACT(120, 56) 274 }, 275 { 276 .desc = "5VSB", 277 .type = ENVSYS_SVOLTS_DC, 278 .bank = 5, 279 .reg = 0x50, 280 .refresh = lm_refresh_volt, 281 .rfact = RFACT(17, 33) 282 }, 283 { 284 .desc = "VBAT", 285 .type = ENVSYS_SVOLTS_DC, 286 .bank = 5, 287 .reg = 0x51, 288 .refresh = lm_refresh_volt, 289 .rfact = RFACT_NONE 290 }, 291 292 /* Temperature */ 293 { 294 .desc = "Temp0", 295 .type = ENVSYS_STEMP, 296 .bank = 0, 297 .reg = 0x27, 298 .refresh = lm_refresh_temp, 299 .rfact = 0 300 }, 301 { 302 .desc = "Temp1", 303 .type = ENVSYS_STEMP, 304 .bank = 1, 305 .reg = 0x50, 306 .refresh = wb_refresh_temp, 307 .rfact = 0 308 }, 309 { 310 .desc = "Temp2", 311 .type = ENVSYS_STEMP, 312 .bank = 2, 313 .reg = 0x50, 314 .refresh = wb_refresh_temp, 315 .rfact = 0 316 }, 317 318 /* Fans */ 319 { 320 .desc = "Fan0", 321 .type = ENVSYS_SFANRPM, 322 .bank = 0, 323 .reg = 0x28, 324 .refresh = wb_refresh_fanrpm, 325 .rfact = 0 326 }, 327 { 328 .desc = "Fan1", 329 .type = ENVSYS_SFANRPM, 330 .bank = 0, 331 .reg = 0x29, 332 .refresh = wb_refresh_fanrpm, 333 .rfact = 0 334 }, 335 { 336 .desc = "Fan2", 337 .type = ENVSYS_SFANRPM, 338 .bank = 0, 339 .reg = 0x2a, 340 .refresh = wb_refresh_fanrpm, 341 .rfact = 0 342 }, 343 344 { .desc = NULL } 345 }; 346 347 /* W8627EHF */ 348 349 /* 350 * The W83627EHF can measure voltages up to 2.048 V instead of the 351 * traditional 4.096 V. For measuring positive voltages, this can be 352 * accounted for by halving the resistor factor. Negative voltages 353 * need special treatment, also because the reference voltage is 2.048 V 354 * instead of the traditional 3.6 V. 355 */ 356 static const struct lm_sensor w83627ehf_sensors[] = { 357 /* Voltage */ 358 { 359 .desc = "VCore", 360 .type = ENVSYS_SVOLTS_DC, 361 .bank = 0, 362 .reg = 0x20, 363 .refresh = lm_refresh_volt, 364 .rfact = RFACT_NONE / 2 365 }, 366 { 367 .desc = "+12V", 368 .type = ENVSYS_SVOLTS_DC, 369 .bank = 0, 370 .reg = 0x21, 371 .refresh = lm_refresh_volt, 372 .rfact = RFACT(56, 10) / 2 373 }, 374 { 375 .desc = "+3.3V", 376 .type = ENVSYS_SVOLTS_DC, 377 .bank = 0, 378 .reg = 0x22, 379 .refresh = lm_refresh_volt, 380 .rfact = RFACT(34, 34) / 2 381 }, 382 { 383 .desc = "VIN3", 384 .type = ENVSYS_SVOLTS_DC, 385 .bank = 0, 386 .reg = 0x23, 387 .refresh = lm_refresh_volt, 388 .rfact = RFACT(34, 34) / 2 389 }, 390 { 391 .desc = "-12V", 392 .type = ENVSYS_SVOLTS_DC, 393 .bank = 0, 394 .reg = 0x24, 395 .refresh = wb_w83627ehf_refresh_nvolt, 396 .rfact = 0 397 }, 398 { 399 .desc = "VIN5", 400 .type = ENVSYS_SVOLTS_DC, 401 .bank = 0, 402 .reg = 0x25, 403 .refresh = lm_refresh_volt, 404 .rfact = RFACT_NONE / 2 405 }, 406 { 407 .desc = "VIN6", 408 .type = ENVSYS_SVOLTS_DC, 409 .bank = 0, 410 .reg = 0x26, 411 .refresh = lm_refresh_volt, 412 .rfact = RFACT_NONE / 2 413 }, 414 { 415 .desc = "3.3VSB", 416 .type = ENVSYS_SVOLTS_DC, 417 .bank = 5, 418 .reg = 0x50, 419 .refresh = lm_refresh_volt, 420 .rfact = RFACT(34, 34) / 2 421 }, 422 { 423 .desc = "VBAT", 424 .type = ENVSYS_SVOLTS_DC, 425 .bank = 5, 426 .reg = 0x51, 427 .refresh = lm_refresh_volt, 428 .rfact = RFACT_NONE / 2 429 }, 430 { 431 .desc = "VIN8", 432 .type = ENVSYS_SVOLTS_DC, 433 .bank = 5, 434 .reg = 0x52, 435 .refresh = lm_refresh_volt, 436 .rfact = RFACT_NONE / 2 437 }, 438 439 /* Temperature */ 440 { 441 .desc = "Temp0", 442 .type = ENVSYS_STEMP, 443 .bank = 0, 444 .reg = 0x27, 445 .refresh = lm_refresh_temp, 446 .rfact = 0 447 }, 448 { 449 .desc = "Temp1", 450 .type = ENVSYS_STEMP, 451 .bank = 1, 452 .reg = 0x50, 453 .refresh = wb_refresh_temp, 454 .rfact = 0 455 }, 456 { 457 .desc = "Temp2", 458 .type = ENVSYS_STEMP, 459 .bank = 2, 460 .reg = 0x50, 461 .refresh = wb_refresh_temp, 462 .rfact = 0 463 }, 464 465 /* Fans */ 466 { 467 .desc = "Fan0", 468 .type = ENVSYS_SFANRPM, 469 .bank = 0, 470 .reg = 0x28, 471 .refresh = wb_refresh_fanrpm, 472 .rfact = 0 473 }, 474 { 475 .desc = "Fan1", 476 .type = ENVSYS_SFANRPM, 477 .bank = 0, 478 .reg = 0x29, 479 .refresh = wb_refresh_fanrpm, 480 .rfact = 0 481 }, 482 { 483 .desc = "Fan2", 484 .type = ENVSYS_SFANRPM, 485 .bank = 0, 486 .reg = 0x2a, 487 .refresh = wb_refresh_fanrpm, 488 .rfact = 0 489 }, 490 491 { .desc = NULL } 492 }; 493 494 /* W83627DHG */ 495 static const struct lm_sensor w83627dhg_sensors[] = { 496 /* Voltage */ 497 { 498 .desc = "VCore", 499 .type = ENVSYS_SVOLTS_DC, 500 .bank = 0, 501 .reg = 0x20, 502 .refresh = lm_refresh_volt, 503 .rfact = RFACT_NONE / 2 504 }, 505 { 506 .desc = "+12V", 507 .type = ENVSYS_SVOLTS_DC, 508 .bank = 0, 509 .reg = 0x21, 510 .refresh = lm_refresh_volt, 511 .rfact = RFACT(56, 10) / 2 512 }, 513 { 514 .desc = "AVCC", 515 .type = ENVSYS_SVOLTS_DC, 516 .bank = 0, 517 .reg = 0x22, 518 .refresh = lm_refresh_volt, 519 .rfact = RFACT(34, 34) / 2 520 }, 521 { 522 .desc = "+3.3V", 523 .type = ENVSYS_SVOLTS_DC, 524 .bank = 0, 525 .reg = 0x23, 526 .refresh = lm_refresh_volt, 527 .rfact = RFACT(34, 34) / 2 528 }, 529 { 530 .desc = "-12V", 531 .type = ENVSYS_SVOLTS_DC, 532 .bank = 0, 533 .reg = 0x24, 534 .refresh = wb_w83627ehf_refresh_nvolt, 535 .rfact = 0 536 }, 537 { 538 .desc = "+5V", 539 .type = ENVSYS_SVOLTS_DC, 540 .bank = 0, 541 .reg = 0x25, 542 .refresh = lm_refresh_volt, 543 .rfact = 16000 544 }, 545 { 546 .desc = "VIN3", 547 .type = ENVSYS_SVOLTS_DC, 548 .bank = 0, 549 .reg = 0x26, 550 .refresh = lm_refresh_volt, 551 .rfact = RFACT_NONE 552 }, 553 { 554 .desc = "+3.3VSB", 555 .type = ENVSYS_SVOLTS_DC, 556 .bank = 5, 557 .reg = 0x50, 558 .refresh = lm_refresh_volt, 559 .rfact = RFACT(34, 34) / 2 560 }, 561 { 562 .desc = "VBAT", 563 .type = ENVSYS_SVOLTS_DC, 564 .bank = 5, 565 .reg = 0x51, 566 .refresh = lm_refresh_volt, 567 .rfact = RFACT(34, 34) / 2 568 }, 569 570 /* Temperature */ 571 { 572 .desc = "MB Temperature", 573 .type = ENVSYS_STEMP, 574 .bank = 0, 575 .reg = 0x27, 576 .refresh = lm_refresh_temp, 577 .rfact = 0 578 }, 579 { 580 .desc = "CPU Temperature", 581 .type = ENVSYS_STEMP, 582 .bank = 1, 583 .reg = 0x50, 584 .refresh = lm_refresh_temp, 585 .rfact = 0 586 }, 587 { 588 .desc = "Aux Temp", 589 .type = ENVSYS_STEMP, 590 .bank = 2, 591 .reg = 0x50, 592 .refresh = lm_refresh_temp, 593 .rfact = 0 594 }, 595 596 /* Fans */ 597 { 598 .desc = "System Fan", 599 .type = ENVSYS_SFANRPM, 600 .bank = 0, 601 .reg = 0x28, 602 .refresh = wb_refresh_fanrpm, 603 .rfact = 0 604 }, 605 { 606 .desc = "CPU Fan", 607 .type = ENVSYS_SFANRPM, 608 .bank = 0, 609 .reg = 0x29, 610 .refresh = wb_refresh_fanrpm, 611 .rfact = 0 612 }, 613 { 614 .desc = "Aux Fan", 615 .type = ENVSYS_SFANRPM, 616 .bank = 0, 617 .reg = 0x2a, 618 .refresh = wb_refresh_fanrpm, 619 .rfact = 0 620 }, 621 622 { .desc = NULL } 623 }; 624 625 /* W83637HF */ 626 static const struct lm_sensor w83637hf_sensors[] = { 627 /* Voltage */ 628 { 629 .desc = "VCore", 630 .type = ENVSYS_SVOLTS_DC, 631 .bank = 0, 632 .reg = 0x20, 633 .refresh = wb_w83637hf_refresh_vcore, 634 .rfact = 0 635 }, 636 { 637 .desc = "+12V", 638 .type = ENVSYS_SVOLTS_DC, 639 .bank = 0, 640 .reg = 0x21, 641 .refresh = lm_refresh_volt, 642 .rfact = RFACT(28, 10) 643 }, 644 { 645 .desc = "+3.3V", 646 .type = ENVSYS_SVOLTS_DC, 647 .bank = 0, 648 .reg = 0x22, 649 .refresh = lm_refresh_volt, 650 .rfact = RFACT_NONE 651 }, 652 { 653 .desc = "+5V", 654 .type = ENVSYS_SVOLTS_DC, 655 .bank = 0, 656 .reg = 0x23, 657 .refresh = lm_refresh_volt, 658 .rfact = RFACT(34, 51) 659 }, 660 { 661 .desc = "-12V", 662 .type = ENVSYS_SVOLTS_DC, 663 .bank = 0, 664 .reg = 0x24, 665 .refresh = wb_refresh_nvolt, 666 .rfact = RFACT(232, 56) 667 }, 668 { 669 .desc = "5VSB", 670 .type = ENVSYS_SVOLTS_DC, 671 .bank = 5, 672 .reg = 0x50, 673 .refresh = lm_refresh_volt, 674 .rfact = RFACT(34, 51) 675 }, 676 { 677 .desc = "VBAT", 678 .type = ENVSYS_SVOLTS_DC, 679 .bank = 5, 680 .reg = 0x51, 681 .refresh = lm_refresh_volt, 682 .rfact = RFACT_NONE 683 }, 684 685 /* Temperature */ 686 { 687 .desc = "Temp0", 688 .type = ENVSYS_STEMP, 689 .bank = 0, 690 .reg = 0x27, 691 .refresh = lm_refresh_temp, 692 .rfact = 0 693 }, 694 { 695 .desc = "Temp1", 696 .type = ENVSYS_STEMP, 697 .bank = 1, 698 .reg = 0x50, 699 .refresh = wb_refresh_temp, 700 .rfact = 0 701 }, 702 { 703 .desc = "Temp2", 704 .type = ENVSYS_STEMP, 705 .bank = 2, 706 .reg = 0x50, 707 .refresh = wb_refresh_temp, 708 .rfact = 0 709 }, 710 711 /* Fans */ 712 { 713 .desc = "Fan0", 714 .type = ENVSYS_SFANRPM, 715 .bank = 0, 716 .reg = 0x28, 717 .refresh = wb_refresh_fanrpm, 718 .rfact = 0 719 }, 720 { 721 .desc = "Fan1", 722 .type = ENVSYS_SFANRPM, 723 .bank = 0, 724 .reg = 0x29, 725 .refresh = wb_refresh_fanrpm, 726 .rfact = 0 727 }, 728 { 729 .desc = "Fan2", 730 .type = ENVSYS_SFANRPM, 731 .bank = 0, 732 .reg = 0x2a, 733 .refresh = wb_refresh_fanrpm, 734 .rfact = 0 735 }, 736 737 { .desc = NULL } 738 }; 739 740 /* W83697HF */ 741 static const struct lm_sensor w83697hf_sensors[] = { 742 /* Voltage */ 743 { 744 .desc = "VCore", 745 .type = ENVSYS_SVOLTS_DC, 746 .bank = 0, 747 .reg = 0x20, 748 .refresh = lm_refresh_volt, 749 .rfact = RFACT_NONE 750 }, 751 { 752 .desc = "+3.3V", 753 .type = ENVSYS_SVOLTS_DC, 754 .bank = 0, 755 .reg = 0x22, 756 .refresh = lm_refresh_volt, 757 .rfact = RFACT_NONE 758 }, 759 { 760 .desc = "+5V", 761 .type = ENVSYS_SVOLTS_DC, 762 .bank = 0, 763 .reg = 0x23, 764 .refresh = lm_refresh_volt, 765 .rfact = RFACT(34, 50) 766 }, 767 { 768 .desc = "+12V", 769 .type = ENVSYS_SVOLTS_DC, 770 .bank = 0, 771 .reg = 0x24, 772 .refresh = lm_refresh_volt, 773 .rfact = RFACT(28, 10) 774 }, 775 { 776 .desc = "-12V", 777 .type = ENVSYS_SVOLTS_DC, 778 .bank = 0, 779 .reg = 0x25, 780 .refresh = wb_refresh_nvolt, 781 .rfact = RFACT(232, 56) 782 }, 783 { 784 .desc = "-5V", 785 .type = ENVSYS_SVOLTS_DC, 786 .bank = 0, 787 .reg = 0x26, 788 .refresh = wb_refresh_nvolt, 789 .rfact = RFACT(120, 56) 790 }, 791 { 792 .desc = "5VSB", 793 .type = ENVSYS_SVOLTS_DC, 794 .bank = 5, 795 .reg = 0x50, 796 .refresh = lm_refresh_volt, 797 .rfact = RFACT(17, 33) 798 }, 799 { 800 .desc = "VBAT", 801 .type = ENVSYS_SVOLTS_DC, 802 .bank = 5, 803 .reg = 0x51, 804 .refresh = lm_refresh_volt, 805 .rfact = RFACT_NONE 806 }, 807 808 /* Temperature */ 809 { 810 .desc = "Temp0", 811 .type = ENVSYS_STEMP, 812 .bank = 0, 813 .reg = 0x27, 814 .refresh = lm_refresh_temp, 815 .rfact = 0 816 }, 817 { 818 .desc = "Temp1", 819 .type = ENVSYS_STEMP, 820 .bank = 1, 821 .reg = 0x50, 822 .refresh = wb_refresh_temp, 823 .rfact = 0 824 }, 825 826 /* Fans */ 827 { 828 .desc = "Fan0", 829 .type = ENVSYS_SFANRPM, 830 .bank = 0, 831 .reg = 0x28, 832 .refresh = wb_refresh_fanrpm, 833 .rfact = 0 834 }, 835 { 836 .desc = "Fan1", 837 .type = ENVSYS_SFANRPM, 838 .bank = 0, 839 .reg = 0x29, 840 .refresh = wb_refresh_fanrpm, 841 .rfact = 0 842 }, 843 844 { .desc = NULL } 845 }; 846 847 /* W83781D */ 848 849 /* 850 * The datasheet doesn't mention the (internal) resistors used for the 851 * +5V, but using the values from the W83782D datasheets seems to 852 * provide sensible results. 853 */ 854 static const struct lm_sensor w83781d_sensors[] = { 855 /* Voltage */ 856 { 857 .desc = "VCore A", 858 .type = ENVSYS_SVOLTS_DC, 859 .bank = 0, 860 .reg = 0x20, 861 .refresh = lm_refresh_volt, 862 .rfact = RFACT_NONE 863 }, 864 { 865 .desc = "VCore B", 866 .type = ENVSYS_SVOLTS_DC, 867 .bank = 0, 868 .reg = 0x21, 869 .refresh = lm_refresh_volt, 870 .rfact = RFACT_NONE 871 }, 872 { 873 .desc = "+3.3V", 874 .type = ENVSYS_SVOLTS_DC, 875 .bank = 0, 876 .reg = 0x22, 877 .refresh = lm_refresh_volt, 878 .rfact = RFACT_NONE 879 }, 880 { 881 .desc = "+5V", 882 .type = ENVSYS_SVOLTS_DC, 883 .bank = 0, 884 .reg = 0x23, 885 .refresh = lm_refresh_volt, 886 .rfact = RFACT(34, 50) 887 }, 888 { 889 .desc = "+12V", 890 .type = ENVSYS_SVOLTS_DC, 891 .bank = 0, 892 .reg = 0x24, 893 .refresh = lm_refresh_volt, 894 .rfact = RFACT(28, 10) 895 }, 896 { 897 .desc = "-12V", 898 .type = ENVSYS_SVOLTS_DC, 899 .bank = 0, 900 .reg = 0x25, 901 .refresh = lm_refresh_volt, 902 .rfact = NRFACT(2100, 604) 903 }, 904 { 905 .desc = "-5V", 906 .type = ENVSYS_SVOLTS_DC, 907 .bank = 0, 908 .reg = 0x26, 909 .refresh = lm_refresh_volt, 910 .rfact = NRFACT(909, 604) 911 }, 912 913 /* Temperature */ 914 { 915 .desc = "Temp0", 916 .type = ENVSYS_STEMP, 917 .bank = 0, 918 .reg = 0x27, 919 .refresh = lm_refresh_temp, 920 .rfact = 0 921 }, 922 { 923 .desc = "Temp1", 924 .type = ENVSYS_STEMP, 925 .bank = 1, 926 .reg = 0x50, 927 .refresh = wb_refresh_temp, 928 .rfact = 0 929 }, 930 { 931 .desc = "Temp2", 932 .type = ENVSYS_STEMP, 933 .bank = 2, 934 .reg = 0x50, 935 .refresh = wb_refresh_temp, 936 .rfact = 0 937 }, 938 939 /* Fans */ 940 { 941 .desc = "Fan0", 942 .type = ENVSYS_SFANRPM, 943 .bank = 0, 944 .reg = 0x28, 945 .refresh = lm_refresh_fanrpm, 946 .rfact = 0 947 }, 948 { 949 .desc = "Fan1", 950 .type = ENVSYS_SFANRPM, 951 .bank = 0, 952 .reg = 0x29, 953 .refresh = lm_refresh_fanrpm, 954 .rfact = 0 955 }, 956 { 957 .desc = "Fan2", 958 .type = ENVSYS_SFANRPM, 959 .bank = 0, 960 .reg = 0x2a, 961 .refresh = lm_refresh_fanrpm, 962 .rfact = 0 963 }, 964 965 { .desc = NULL } 966 }; 967 968 /* W83782D */ 969 static const struct lm_sensor w83782d_sensors[] = { 970 /* Voltage */ 971 { 972 .desc = "VCore", 973 .type = ENVSYS_SVOLTS_DC, 974 .bank = 0, 975 .reg = 0x20, 976 .refresh = lm_refresh_volt, 977 .rfact = RFACT_NONE 978 }, 979 { 980 .desc = "VINR0", 981 .type = ENVSYS_SVOLTS_DC, 982 .bank = 0, 983 .reg = 0x21, 984 .refresh = lm_refresh_volt, 985 .rfact = RFACT_NONE 986 }, 987 { 988 .desc = "+3.3V", 989 .type = ENVSYS_SVOLTS_DC, 990 .bank = 0, 991 .reg = 0x22, 992 .refresh = lm_refresh_volt, 993 .rfact = RFACT_NONE 994 }, 995 { 996 .desc = "+5V", 997 .type = ENVSYS_SVOLTS_DC, 998 .bank = 0, 999 .reg = 0x23, 1000 .refresh = lm_refresh_volt, 1001 .rfact = RFACT(34, 50) 1002 }, 1003 { 1004 .desc = "+12V", 1005 .type = ENVSYS_SVOLTS_DC, 1006 .bank = 0, 1007 .reg = 0x24, 1008 .refresh = lm_refresh_volt, 1009 .rfact = RFACT(28, 10) 1010 }, 1011 { 1012 .desc = "-12V", 1013 .type = ENVSYS_SVOLTS_DC, 1014 .bank = 0, 1015 .reg = 0x25, 1016 .refresh = wb_refresh_nvolt, 1017 .rfact = RFACT(232, 56) 1018 }, 1019 { 1020 .desc = "-5V", 1021 .type = ENVSYS_SVOLTS_DC, 1022 .bank = 0, 1023 .reg = 0x26, 1024 .refresh = wb_refresh_nvolt, 1025 .rfact = RFACT(120, 56) 1026 }, 1027 { 1028 .desc = "5VSB", 1029 .type = ENVSYS_SVOLTS_DC, 1030 .bank = 5, 1031 .reg = 0x50, 1032 .refresh = lm_refresh_volt, 1033 .rfact = RFACT(17, 33) 1034 }, 1035 { 1036 .desc = "VBAT", 1037 .type = ENVSYS_SVOLTS_DC, 1038 .bank = 5, 1039 .reg = 0x51, 1040 .refresh = lm_refresh_volt, 1041 .rfact = RFACT_NONE 1042 }, 1043 1044 /* Temperature */ 1045 { 1046 .desc = "Temp0", 1047 .type = ENVSYS_STEMP, 1048 .bank = 0, 1049 .reg = 0x27, 1050 .refresh = lm_refresh_temp, 1051 .rfact = 0 1052 }, 1053 { 1054 .desc = "Temp1", 1055 .type = ENVSYS_STEMP, 1056 .bank = 1, 1057 .reg = 0x50, 1058 .refresh = wb_refresh_temp, 1059 .rfact = 0 1060 }, 1061 { 1062 .desc = "Temp2", 1063 .type = ENVSYS_STEMP, 1064 .bank = 2, 1065 .reg = 0x50, 1066 .refresh = wb_refresh_temp, 1067 .rfact = 0 1068 }, 1069 1070 /* Fans */ 1071 { 1072 .desc = "Fan0", 1073 .type = ENVSYS_SFANRPM, 1074 .bank = 0, 1075 .reg = 0x28, 1076 .refresh = wb_refresh_fanrpm, 1077 .rfact = 0 1078 }, 1079 { 1080 .desc = "Fan1", 1081 .type = ENVSYS_SFANRPM, 1082 .bank = 0, 1083 .reg = 0x29, 1084 .refresh = wb_refresh_fanrpm, 1085 .rfact = 0 1086 }, 1087 { 1088 .desc = "Fan2", 1089 .type = ENVSYS_SFANRPM, 1090 .bank = 0, 1091 .reg = 0x2a, 1092 .refresh = wb_refresh_fanrpm, 1093 .rfact = 0 1094 }, 1095 1096 { .desc = NULL } 1097 }; 1098 1099 /* W83783S */ 1100 static const struct lm_sensor w83783s_sensors[] = { 1101 /* Voltage */ 1102 { 1103 .desc = "VCore", 1104 .type = ENVSYS_SVOLTS_DC, 1105 .bank = 0, 1106 .reg = 0x20, 1107 .refresh = lm_refresh_volt, 1108 .rfact = RFACT_NONE 1109 }, 1110 { 1111 .desc = "+3.3V", 1112 .type = ENVSYS_SVOLTS_DC, 1113 .bank = 0, 1114 .reg = 0x22, 1115 .refresh = lm_refresh_volt, 1116 .rfact = RFACT_NONE 1117 }, 1118 { 1119 .desc = "+5V", 1120 .type = ENVSYS_SVOLTS_DC, 1121 .bank = 0, 1122 .reg = 0x23, 1123 .refresh = lm_refresh_volt, 1124 .rfact = RFACT(34, 50) 1125 }, 1126 { 1127 .desc = "+12V", 1128 .type = ENVSYS_SVOLTS_DC, 1129 .bank = 0, 1130 .reg = 0x24, 1131 .refresh = lm_refresh_volt, 1132 .rfact = RFACT(28, 10) 1133 }, 1134 { 1135 .desc = "-12V", 1136 .type = ENVSYS_SVOLTS_DC, 1137 .bank = 0, 1138 .reg = 0x25, 1139 .refresh = wb_refresh_nvolt, 1140 .rfact = RFACT(232, 56) 1141 }, 1142 { 1143 .desc = "-5V", 1144 .type = ENVSYS_SVOLTS_DC, 1145 .bank = 0, 1146 .reg = 0x26, 1147 .refresh = wb_refresh_nvolt, 1148 .rfact = RFACT(120, 56) 1149 }, 1150 1151 /* Temperature */ 1152 { 1153 .desc = "Temp0", 1154 .type = ENVSYS_STEMP, 1155 .bank = 0, 1156 .reg = 0x27, 1157 .refresh = lm_refresh_temp, 1158 .rfact = 0 1159 }, 1160 { 1161 .desc = "Temp1", 1162 .type = ENVSYS_STEMP, 1163 .bank = 1, 1164 .reg = 0x50, 1165 .refresh = wb_refresh_temp, 1166 .rfact = 0 1167 }, 1168 1169 /* Fans */ 1170 { 1171 .desc = "Fan0", 1172 .type = ENVSYS_SFANRPM, 1173 .bank = 0, 1174 .reg = 0x28, 1175 .refresh = wb_refresh_fanrpm, 1176 .rfact = 0 1177 }, 1178 { 1179 .desc = "Fan1", 1180 .type = ENVSYS_SFANRPM, 1181 .bank = 0, 1182 .reg = 0x29, 1183 .refresh = wb_refresh_fanrpm, 1184 .rfact = 0 1185 }, 1186 { 1187 .desc = "Fan2", 1188 .type = ENVSYS_SFANRPM, 1189 .bank = 0, 1190 .reg = 0x2a, 1191 .refresh = wb_refresh_fanrpm, 1192 .rfact = 0 1193 }, 1194 1195 { .desc = NULL } 1196 }; 1197 1198 /* W83791D */ 1199 static const struct lm_sensor w83791d_sensors[] = { 1200 /* Voltage */ 1201 { 1202 .desc = "VCore", 1203 .type = ENVSYS_SVOLTS_DC, 1204 .bank = 0, 1205 .reg = 0x20, 1206 .refresh = lm_refresh_volt, 1207 .rfact = 10000 1208 }, 1209 { 1210 .desc = "VINR0", 1211 .type = ENVSYS_SVOLTS_DC, 1212 .bank = 0, 1213 .reg = 0x21, 1214 .refresh = lm_refresh_volt, 1215 .rfact = 10000 1216 }, 1217 { 1218 .desc = "+3.3V", 1219 .type = ENVSYS_SVOLTS_DC, 1220 .bank = 0, 1221 .reg = 0x22, 1222 .refresh = lm_refresh_volt, 1223 .rfact = 10000 1224 }, 1225 { 1226 .desc = "+5V", 1227 .type = ENVSYS_SVOLTS_DC, 1228 .bank = 0, 1229 .reg = 0x23, 1230 .refresh = lm_refresh_volt, 1231 .rfact = RFACT(34, 50) 1232 }, 1233 { 1234 .desc = "+12V", 1235 .type = ENVSYS_SVOLTS_DC, 1236 .bank = 0, 1237 .reg = 0x24, 1238 .refresh = lm_refresh_volt, 1239 .rfact = RFACT(28, 10) 1240 }, 1241 { 1242 .desc = "-12V", 1243 .type = ENVSYS_SVOLTS_DC, 1244 .bank = 0, 1245 .reg = 0x25, 1246 .refresh = wb_refresh_nvolt, 1247 .rfact = RFACT(232, 56) 1248 }, 1249 { 1250 .desc = "-5V", 1251 .type = ENVSYS_SVOLTS_DC, 1252 .bank = 0, 1253 .reg = 0x26, 1254 .refresh = wb_refresh_nvolt, 1255 .rfact = RFACT(120, 56) 1256 }, 1257 { 1258 .desc = "5VSB", 1259 .type = ENVSYS_SVOLTS_DC, 1260 .bank = 0, 1261 .reg = 0xb0, 1262 .refresh = lm_refresh_volt, 1263 .rfact = RFACT(17, 33) 1264 }, 1265 { 1266 .desc = "VBAT", 1267 .type = ENVSYS_SVOLTS_DC, 1268 .bank = 0, 1269 .reg = 0xb1, 1270 .refresh = lm_refresh_volt, 1271 .rfact = RFACT_NONE 1272 }, 1273 { 1274 .desc = "VINR1", 1275 .type = ENVSYS_SVOLTS_DC, 1276 .bank = 0, 1277 .reg = 0xb2, 1278 .refresh = lm_refresh_volt, 1279 .rfact = RFACT_NONE 1280 }, 1281 1282 /* Temperature */ 1283 { 1284 .desc = "Temp0", 1285 .type = ENVSYS_STEMP, 1286 .bank = 0, 1287 .reg = 0x27, 1288 .refresh = lm_refresh_temp, 1289 .rfact = 0 1290 }, 1291 { 1292 .desc = "Temp1", 1293 .type = ENVSYS_STEMP, 1294 .bank = 0, 1295 .reg = 0xc0, 1296 .refresh = wb_refresh_temp, 1297 .rfact = 0 1298 }, 1299 { 1300 .desc = "Temp2", 1301 .type = ENVSYS_STEMP, 1302 .bank = 0, 1303 .reg = 0xc8, 1304 .refresh = wb_refresh_temp, 1305 .rfact = 0 1306 }, 1307 1308 /* Fans */ 1309 { 1310 .desc = "Fan0", 1311 .type = ENVSYS_SFANRPM, 1312 .bank = 0, 1313 .reg = 0x28, 1314 .refresh = wb_refresh_fanrpm, 1315 .rfact = 0 1316 }, 1317 { 1318 .desc = "Fan1", 1319 .type = ENVSYS_SFANRPM, 1320 .bank = 0, 1321 .reg = 0x29, 1322 .refresh = wb_refresh_fanrpm, 1323 .rfact = 0 1324 }, 1325 { 1326 .desc = "Fan2", 1327 .type = ENVSYS_SFANRPM, 1328 .bank = 0, 1329 .reg = 0x2a, 1330 .refresh = wb_refresh_fanrpm, 1331 .rfact = 0 1332 }, 1333 { 1334 .desc = "Fan3", 1335 .type = ENVSYS_SFANRPM, 1336 .bank = 0, 1337 .reg = 0xba, 1338 .refresh = wb_refresh_fanrpm, 1339 .rfact = 0 1340 }, 1341 { 1342 .desc = "Fan4", 1343 .type = ENVSYS_SFANRPM, 1344 .bank = 0, 1345 .reg = 0xbb, 1346 .refresh = wb_refresh_fanrpm, 1347 .rfact = 0 1348 }, 1349 1350 { .desc = NULL } 1351 }; 1352 1353 /* W83792D */ 1354 static const struct lm_sensor w83792d_sensors[] = { 1355 /* Voltage */ 1356 { 1357 .desc = "VCore A", 1358 .type = ENVSYS_SVOLTS_DC, 1359 .bank = 0, 1360 .reg = 0x20, 1361 .refresh = lm_refresh_volt, 1362 .rfact = RFACT_NONE 1363 }, 1364 { 1365 .desc = "VCore B", 1366 .type = ENVSYS_SVOLTS_DC, 1367 .bank = 0, 1368 .reg = 0x21, 1369 .refresh = lm_refresh_volt, 1370 .rfact = RFACT_NONE 1371 }, 1372 { 1373 .desc = "+3.3V", 1374 .type = ENVSYS_SVOLTS_DC, 1375 .bank = 0, 1376 .reg = 0x22, 1377 .refresh = lm_refresh_volt, 1378 .rfact = RFACT_NONE 1379 }, 1380 { 1381 .desc = "-5V", 1382 .type = ENVSYS_SVOLTS_DC, 1383 .bank = 0, 1384 .reg = 0x23, 1385 .refresh = wb_refresh_nvolt, 1386 .rfact = RFACT(120, 56) 1387 }, 1388 { 1389 .desc = "+12V", 1390 .type = ENVSYS_SVOLTS_DC, 1391 .bank = 0, 1392 .reg = 0x24, 1393 .refresh = lm_refresh_volt, 1394 .rfact = RFACT(28, 10) 1395 }, 1396 { 1397 .desc = "-12V", 1398 .type = ENVSYS_SVOLTS_DC, 1399 .bank = 0, 1400 .reg = 0x25, 1401 .refresh = wb_refresh_nvolt, 1402 .rfact = RFACT(232, 56) 1403 }, 1404 { 1405 .desc = "+5V", 1406 .type = ENVSYS_SVOLTS_DC, 1407 .bank = 0, 1408 .reg = 0x26, 1409 .refresh = lm_refresh_volt, 1410 .rfact = RFACT(34, 50) 1411 }, 1412 { 1413 .desc = "5VSB", 1414 .type = ENVSYS_SVOLTS_DC, 1415 .bank = 0, 1416 .reg = 0xb0, 1417 .refresh = lm_refresh_volt, 1418 .rfact = RFACT(17, 33) 1419 }, 1420 { 1421 .desc = "VBAT", 1422 .type = ENVSYS_SVOLTS_DC, 1423 .bank = 0, 1424 .reg = 0xb1, 1425 .refresh = lm_refresh_volt, 1426 .rfact = RFACT_NONE 1427 }, 1428 1429 /* Temperature */ 1430 { 1431 .desc = "Temp0", 1432 .type = ENVSYS_STEMP, 1433 .bank = 0, 1434 .reg = 0x27, 1435 .refresh = lm_refresh_temp, 1436 .rfact = 0 1437 }, 1438 { 1439 .desc = "Temp1", 1440 .type = ENVSYS_STEMP, 1441 .bank = 0, 1442 .reg = 0xc0, 1443 .refresh = wb_refresh_temp, 1444 .rfact = 0 1445 }, 1446 { 1447 .desc = "Temp2", 1448 .type = ENVSYS_STEMP, 1449 .bank = 0, 1450 .reg = 0xc8, 1451 .refresh = wb_refresh_temp, 1452 .rfact = 0 1453 }, 1454 1455 /* Fans */ 1456 { 1457 .desc = "Fan0", 1458 .type = ENVSYS_SFANRPM, 1459 .bank = 0, 1460 .reg = 0x28, 1461 .refresh = wb_w83792d_refresh_fanrpm, 1462 .rfact = 0 1463 }, 1464 { 1465 .desc = "Fan1", 1466 .type = ENVSYS_SFANRPM, 1467 .bank = 0, 1468 .reg = 0x29, 1469 .refresh = wb_w83792d_refresh_fanrpm, 1470 .rfact = 0 1471 }, 1472 { 1473 .desc = "Fan2", 1474 .type = ENVSYS_SFANRPM, 1475 .bank = 0, 1476 .reg = 0x2a, 1477 .refresh = wb_w83792d_refresh_fanrpm, 1478 .rfact = 0 1479 }, 1480 { 1481 .desc = "Fan3", 1482 .type = ENVSYS_SFANRPM, 1483 .bank = 0, 1484 .reg = 0xb8, 1485 .refresh = wb_w83792d_refresh_fanrpm, 1486 .rfact = 0 1487 }, 1488 { 1489 .desc = "Fan4", 1490 .type = ENVSYS_SFANRPM, 1491 .bank = 0, 1492 .reg = 0xb9, 1493 .refresh = wb_w83792d_refresh_fanrpm, 1494 .rfact = 0 1495 }, 1496 { 1497 .desc = "Fan5", 1498 .type = ENVSYS_SFANRPM, 1499 .bank = 0, 1500 .reg = 0xba, 1501 .refresh = wb_w83792d_refresh_fanrpm, 1502 .rfact = 0 1503 }, 1504 { 1505 .desc = "Fan6", 1506 .type = ENVSYS_SFANRPM, 1507 .bank = 0, 1508 .reg = 0xbe, 1509 .refresh = wb_w83792d_refresh_fanrpm, 1510 .rfact = 0 1511 }, 1512 1513 { .desc = NULL } 1514 }; 1515 1516 /* AS99127F */ 1517 static const struct lm_sensor as99127f_sensors[] = { 1518 /* Voltage */ 1519 { 1520 .desc = "VCore A", 1521 .type = ENVSYS_SVOLTS_DC, 1522 .bank = 0, 1523 .reg = 0x20, 1524 .refresh = lm_refresh_volt, 1525 .rfact = RFACT_NONE 1526 }, 1527 { 1528 .desc = "VCore B", 1529 .type = ENVSYS_SVOLTS_DC, 1530 .bank = 0, 1531 .reg = 0x21, 1532 .refresh = lm_refresh_volt, 1533 .rfact = RFACT_NONE 1534 }, 1535 { 1536 .desc = "+3.3V", 1537 .type = ENVSYS_SVOLTS_DC, 1538 .bank = 0, 1539 .reg = 0x22, 1540 .refresh = lm_refresh_volt, 1541 .rfact = RFACT_NONE 1542 }, 1543 { 1544 .desc = "+5V", 1545 .type = ENVSYS_SVOLTS_DC, 1546 .bank = 0, 1547 .reg = 0x23, 1548 .refresh = lm_refresh_volt, 1549 .rfact = RFACT(34, 50) 1550 }, 1551 { 1552 .desc = "+12V", 1553 .type = ENVSYS_SVOLTS_DC, 1554 .bank = 0, 1555 .reg = 0x24, 1556 .refresh = lm_refresh_volt, 1557 .rfact = RFACT(28, 10) 1558 }, 1559 { 1560 .desc = "-12V", 1561 .type = ENVSYS_SVOLTS_DC, 1562 .bank = 0, 1563 .reg = 0x25, 1564 .refresh = wb_refresh_nvolt, 1565 .rfact = RFACT(232, 56) 1566 }, 1567 { 1568 .desc = "-5V", 1569 .type = ENVSYS_SVOLTS_DC, 1570 .bank = 0, 1571 .reg = 0x26, 1572 .refresh = wb_refresh_nvolt, 1573 .rfact = RFACT(120, 56) 1574 }, 1575 1576 /* Temperature */ 1577 { 1578 .desc = "Temp0", 1579 .type = ENVSYS_STEMP, 1580 .bank = 0, 1581 .reg = 0x27, 1582 .refresh = lm_refresh_temp, 1583 .rfact = 0 1584 }, 1585 { 1586 .desc = "Temp1", 1587 .type = ENVSYS_STEMP, 1588 .bank = 1, 1589 .reg = 0x50, 1590 .refresh = as_refresh_temp, 1591 .rfact = 0 1592 }, 1593 { 1594 .desc = "Temp2", 1595 .type = ENVSYS_STEMP, 1596 .bank = 2, 1597 .reg = 0x50, 1598 .refresh = as_refresh_temp, 1599 .rfact = 0 1600 }, 1601 1602 /* Fans */ 1603 { 1604 .desc = "Fan0", 1605 .type = ENVSYS_SFANRPM, 1606 .bank = 0, 1607 .reg = 0x28, 1608 .refresh = lm_refresh_fanrpm, 1609 .rfact = 0 1610 }, 1611 { 1612 .desc = "Fan1", 1613 .type = ENVSYS_SFANRPM, 1614 .bank = 0, 1615 .reg = 0x29, 1616 .refresh = lm_refresh_fanrpm, 1617 .rfact = 0 1618 }, 1619 { 1620 .desc = "Fan2", 1621 .type = ENVSYS_SFANRPM, 1622 .bank = 0, 1623 .reg = 0x2a, 1624 .refresh = lm_refresh_fanrpm, 1625 .rfact = 0 1626 }, 1627 1628 { .desc = NULL } 1629 }; 1630 1631 /* NCT6776F */ 1632 static const struct lm_sensor nct6776f_sensors[] = { 1633 /* Voltage */ 1634 { 1635 .desc = "VCore", 1636 .type = ENVSYS_SVOLTS_DC, 1637 .bank = 0, 1638 .reg = 0x20, 1639 .refresh = lm_refresh_volt, 1640 .rfact = RFACT_NONE / 2 1641 }, 1642 { 1643 .desc = "+12V", 1644 .type = ENVSYS_SVOLTS_DC, 1645 .bank = 0, 1646 .reg = 0x21, 1647 .refresh = lm_refresh_volt, 1648 .rfact = RFACT(56, 10) / 2 1649 }, 1650 { 1651 .desc = "AVCC", 1652 .type = ENVSYS_SVOLTS_DC, 1653 .bank = 0, 1654 .reg = 0x22, 1655 .refresh = lm_refresh_volt, 1656 .rfact = RFACT(34, 34) / 2 1657 }, 1658 { 1659 .desc = "+3.3V", 1660 .type = ENVSYS_SVOLTS_DC, 1661 .bank = 0, 1662 .reg = 0x23, 1663 .refresh = lm_refresh_volt, 1664 .rfact = RFACT(34, 34) / 2 1665 }, 1666 { 1667 .desc = "-12V", 1668 .type = ENVSYS_SVOLTS_DC, 1669 .bank = 0, 1670 .reg = 0x24, 1671 .refresh = wb_w83627ehf_refresh_nvolt, 1672 .rfact = 0 1673 }, 1674 { 1675 .desc = "+5V", 1676 .type = ENVSYS_SVOLTS_DC, 1677 .bank = 0, 1678 .reg = 0x25, 1679 .refresh = lm_refresh_volt, 1680 .rfact = 16000 1681 }, 1682 { 1683 .desc = "VIN3", 1684 .type = ENVSYS_SVOLTS_DC, 1685 .bank = 0, 1686 .reg = 0x26, 1687 .refresh = lm_refresh_volt, 1688 .rfact = RFACT_NONE 1689 }, 1690 { 1691 .desc = "+3.3VSB", 1692 .type = ENVSYS_SVOLTS_DC, 1693 .bank = 5, 1694 .reg = 0x50, 1695 .refresh = lm_refresh_volt, 1696 .rfact = RFACT(34, 34) / 2 1697 }, 1698 { 1699 .desc = "VBAT", 1700 .type = ENVSYS_SVOLTS_DC, 1701 .bank = 5, 1702 .reg = 0x51, 1703 .refresh = lm_refresh_volt, 1704 .rfact = RFACT(34, 34) / 2 1705 }, 1706 1707 /* Temperature */ 1708 { 1709 .desc = "MB Temperature", 1710 .type = ENVSYS_STEMP, 1711 .bank = 0, 1712 .reg = 0x27, 1713 .refresh = lm_refresh_temp, 1714 .rfact = 0 1715 }, 1716 { 1717 .desc = "CPU Temperature", 1718 .type = ENVSYS_STEMP, 1719 .bank = 1, 1720 .reg = 0x50, 1721 .refresh = wb_refresh_temp, 1722 .rfact = 0 1723 }, 1724 { 1725 .desc = "Aux Temp", 1726 .type = ENVSYS_STEMP, 1727 .bank = 2, 1728 .reg = 0x50, 1729 .refresh = wb_refresh_temp, 1730 .rfact = 0 1731 }, 1732 1733 /* Fans */ 1734 { 1735 .desc = "System Fan", 1736 .type = ENVSYS_SFANRPM, 1737 .bank = 6, 1738 .reg = 0x56, 1739 .refresh = wb_nct6776f_refresh_fanrpm, 1740 .rfact = 0 1741 }, 1742 { 1743 .desc = "CPU Fan", 1744 .type = ENVSYS_SFANRPM, 1745 .bank = 6, 1746 .reg = 0x58, 1747 .refresh = wb_nct6776f_refresh_fanrpm, 1748 .rfact = 0 1749 }, 1750 { 1751 .desc = "Aux Fan0", 1752 .type = ENVSYS_SFANRPM, 1753 .bank = 6, 1754 .reg = 0x5a, 1755 .refresh = wb_nct6776f_refresh_fanrpm, 1756 .rfact = 0 1757 }, 1758 { 1759 .desc = "Aux Fan1", 1760 .type = ENVSYS_SFANRPM, 1761 .bank = 6, 1762 .reg = 0x5c, 1763 .refresh = wb_nct6776f_refresh_fanrpm, 1764 .rfact = 0 1765 }, 1766 1767 { 1768 .desc = "Aux Fan2", 1769 .type = ENVSYS_SFANRPM, 1770 .bank = 6, 1771 .reg = 0x5e, 1772 .refresh = wb_nct6776f_refresh_fanrpm, 1773 .rfact = 0 1774 }, 1775 1776 { .desc = NULL } 1777 }; 1778 1779 /* NCT610[246]D */ 1780 static const struct lm_sensor nct6102d_sensors[] = { 1781 /* Voltage */ 1782 { 1783 .desc = "VCore", 1784 .type = ENVSYS_SVOLTS_DC, 1785 .bank = 0, 1786 .reg = 0x00, 1787 .refresh = lm_refresh_volt, 1788 .rfact = RFACT_NONE 1789 }, 1790 { 1791 .desc = "VIN0", 1792 .type = ENVSYS_SVOLTS_DC, 1793 .bank = 0, 1794 .reg = 0x01, 1795 .refresh = lm_refresh_volt, 1796 .rfact = RFACT_NONE 1797 }, 1798 { 1799 .desc = "AVCC", 1800 .type = ENVSYS_SVOLTS_DC, 1801 .bank = 0, 1802 .reg = 0x02, 1803 .refresh = lm_refresh_volt, 1804 .rfact = RFACT(34, 34) / 2 1805 }, 1806 { 1807 .desc = "3VCC", 1808 .type = ENVSYS_SVOLTS_DC, 1809 .bank = 0, 1810 .reg = 0x03, 1811 .refresh = lm_refresh_volt, 1812 .rfact = RFACT(34, 34) / 2 1813 }, 1814 { 1815 .desc = "VIN1", 1816 .type = ENVSYS_SVOLTS_DC, 1817 .bank = 0, 1818 .reg = 0x04, 1819 .refresh = lm_refresh_volt, 1820 .rfact = RFACT_NONE 1821 }, 1822 { 1823 .desc = "VIN2", 1824 .type = ENVSYS_SVOLTS_DC, 1825 .bank = 0, 1826 .reg = 0x05, 1827 .refresh = lm_refresh_volt, 1828 .rfact = RFACT(34, 34) / 2 1829 }, 1830 { 1831 .desc = "+3.3VSB", 1832 .type = ENVSYS_SVOLTS_DC, 1833 .bank = 0, 1834 .reg = 0x07, 1835 .refresh = lm_refresh_volt, 1836 .rfact = RFACT(34, 34) / 2 1837 }, 1838 { 1839 .desc = "VBAT", 1840 .type = ENVSYS_SVOLTS_DC, 1841 .bank = 0, 1842 .reg = 0x08, 1843 .refresh = lm_refresh_volt, 1844 .rfact = RFACT(34, 34) / 2 1845 }, 1846 { 1847 .desc = "VTT", 1848 .type = ENVSYS_SVOLTS_DC, 1849 .bank = 0, 1850 .reg = 0x09, 1851 .refresh = lm_refresh_volt, 1852 .rfact = RFACT_NONE 1853 }, 1854 1855 /* Temperature */ 1856 { 1857 .desc = "MB Temperature", 1858 .type = ENVSYS_STEMP, 1859 .bank = 0, 1860 .reg = 0x18, 1861 .refresh = lm_refresh_temp, 1862 .rfact = 0 1863 }, 1864 { 1865 .desc = "CPU Temperature", 1866 .type = ENVSYS_STEMP, 1867 .bank = 0, 1868 .reg = 0x19, 1869 .refresh = lm_refresh_temp, 1870 .rfact = 0 1871 }, 1872 { 1873 .desc = "Aux Temp", 1874 .type = ENVSYS_STEMP, 1875 .bank = 0, 1876 .reg = 0x1a, 1877 .refresh = lm_refresh_temp, 1878 .rfact = 0 1879 }, 1880 1881 /* Fans */ 1882 { 1883 .desc = "System Fan", 1884 .type = ENVSYS_SFANRPM, 1885 .bank = 0, 1886 .reg = 0x30, 1887 .refresh = wb_nct6776f_refresh_fanrpm, 1888 .rfact = 0 1889 }, 1890 { 1891 .desc = "CPU Fan", 1892 .type = ENVSYS_SFANRPM, 1893 .bank = 0, 1894 .reg = 0x32, 1895 .refresh = wb_nct6776f_refresh_fanrpm, 1896 .rfact = 0 1897 }, 1898 { 1899 .desc = "Aux Fan", 1900 .type = ENVSYS_SFANRPM, 1901 .bank = 0, 1902 .reg = 0x34, 1903 .refresh = wb_nct6776f_refresh_fanrpm, 1904 .rfact = 0 1905 }, 1906 1907 { .desc = NULL } 1908 }; 1909 1910 /* NCT6779D */ 1911 static const struct lm_sensor nct6779d_sensors[] = { 1912 /* Voltage */ 1913 { 1914 .desc = "VCore", 1915 .type = ENVSYS_SVOLTS_DC, 1916 .bank = 4, 1917 .reg = 0x80, 1918 .refresh = lm_refresh_volt, 1919 .rfact = RFACT_NONE / 2 1920 }, 1921 { 1922 .desc = "VIN1", 1923 .type = ENVSYS_SVOLTS_DC, 1924 .bank = 4, 1925 .reg = 0x81, 1926 .refresh = lm_refresh_volt, 1927 .rfact = RFACT(56, 10) / 2 1928 }, 1929 { 1930 .desc = "AVCC", 1931 .type = ENVSYS_SVOLTS_DC, 1932 .bank = 4, 1933 .reg = 0x82, 1934 .refresh = lm_refresh_volt, 1935 .rfact = RFACT(34, 34) / 2 1936 }, 1937 { 1938 .desc = "+3.3V", 1939 .type = ENVSYS_SVOLTS_DC, 1940 .bank = 4, 1941 .reg = 0x83, 1942 .refresh = lm_refresh_volt, 1943 .rfact = RFACT(34, 34) / 2 1944 }, 1945 { 1946 .desc = "VIN0", 1947 .type = ENVSYS_SVOLTS_DC, 1948 .bank = 4, 1949 .reg = 0x84, 1950 .refresh = lm_refresh_volt, 1951 .rfact = RFACT(48600, 10000) 1952 }, 1953 { 1954 .desc = "VIN8", 1955 .type = ENVSYS_SVOLTS_DC, 1956 .bank = 4, 1957 .reg = 0x85, 1958 .refresh = lm_refresh_volt, 1959 .rfact = RFACT_NONE / 2 1960 }, 1961 { 1962 .desc = "VIN4", 1963 .type = ENVSYS_SVOLTS_DC, 1964 .bank = 4, 1965 .reg = 0x86, 1966 .refresh = lm_refresh_volt, 1967 .rfact = RFACT_NONE 1968 }, 1969 { 1970 .desc = "+3.3VSB", 1971 .type = ENVSYS_SVOLTS_DC, 1972 .bank = 4, 1973 .reg = 0x87, 1974 .refresh = lm_refresh_volt, 1975 .rfact = RFACT(34, 34) / 2 1976 }, 1977 { 1978 .desc = "VBAT", 1979 .type = ENVSYS_SVOLTS_DC, 1980 .bank = 4, 1981 .reg = 0x88, 1982 .refresh = lm_refresh_volt, 1983 .rfact = RFACT_NONE 1984 }, 1985 { 1986 .desc = "VTT", 1987 .type = ENVSYS_SVOLTS_DC, 1988 .bank = 4, 1989 .reg = 0x89, 1990 .refresh = lm_refresh_volt, 1991 .rfact = RFACT_NONE 1992 }, 1993 { 1994 .desc = "VIN5", 1995 .type = ENVSYS_SVOLTS_DC, 1996 .bank = 4, 1997 .reg = 0x8a, 1998 .refresh = lm_refresh_volt, 1999 .rfact = RFACT_NONE 2000 }, 2001 { 2002 .desc = "VIN6", 2003 .type = ENVSYS_SVOLTS_DC, 2004 .bank = 4, 2005 .reg = 0x8b, 2006 .refresh = lm_refresh_volt, 2007 .rfact = RFACT_NONE 2008 }, 2009 { 2010 .desc = "VIN2", 2011 .type = ENVSYS_SVOLTS_DC, 2012 .bank = 4, 2013 .reg = 0x8c, 2014 .refresh = lm_refresh_volt, 2015 .rfact = RFACT_NONE 2016 }, 2017 { 2018 .desc = "VIN3", 2019 .type = ENVSYS_SVOLTS_DC, 2020 .bank = 4, 2021 .reg = 0x8d, 2022 .refresh = lm_refresh_volt, 2023 .rfact = RFACT(14414, 10000) 2024 }, 2025 { 2026 .desc = "VIN7", 2027 .type = ENVSYS_SVOLTS_DC, 2028 .bank = 4, 2029 .reg = 0x8e, 2030 .refresh = lm_refresh_volt, 2031 .rfact = RFACT_NONE / 2 2032 }, 2033 2034 /* Temperature */ 2035 { 2036 .desc = "MB Temperature", 2037 .type = ENVSYS_STEMP, 2038 .bank = 4, 2039 .reg = 0x90, 2040 .refresh = lm_refresh_temp, 2041 .rfact = 0 2042 }, 2043 { 2044 .desc = "CPU Temperature", 2045 .type = ENVSYS_STEMP, 2046 .bank = 4, 2047 .reg = 0x91, 2048 .refresh = wb_refresh_temp, 2049 .rfact = 0 2050 }, 2051 { 2052 .desc = "Aux Temp0", 2053 .type = ENVSYS_STEMP, 2054 .bank = 4, 2055 .reg = 0x92, 2056 .refresh = wb_refresh_temp, 2057 .rfact = 0 2058 }, 2059 { 2060 .desc = "Aux Temp1", 2061 .type = ENVSYS_STEMP, 2062 .bank = 4, 2063 .reg = 0x93, 2064 .refresh = wb_refresh_temp, 2065 .rfact = 0 2066 }, 2067 { 2068 .desc = "Aux Temp2", 2069 .type = ENVSYS_STEMP, 2070 .bank = 4, 2071 .reg = 0x94, 2072 .refresh = wb_refresh_temp, 2073 .rfact = 0 2074 }, 2075 { 2076 .desc = "Aux Temp3", 2077 .type = ENVSYS_STEMP, 2078 .bank = 4, 2079 .reg = 0x95, 2080 .refresh = wb_refresh_temp, 2081 .rfact = 0 2082 }, 2083 2084 /* Fans */ 2085 { 2086 .desc = "System Fan", 2087 .type = ENVSYS_SFANRPM, 2088 .bank = 4, 2089 .reg = 0xc0, 2090 .refresh = wb_nct6776f_refresh_fanrpm, 2091 .rfact = 0 2092 }, 2093 { 2094 .desc = "CPU Fan", 2095 .type = ENVSYS_SFANRPM, 2096 .bank = 4, 2097 .reg = 0xc2, 2098 .refresh = wb_nct6776f_refresh_fanrpm, 2099 .rfact = 0 2100 }, 2101 { 2102 .desc = "Aux Fan0", 2103 .type = ENVSYS_SFANRPM, 2104 .bank = 4, 2105 .reg = 0xc4, 2106 .refresh = wb_nct6776f_refresh_fanrpm, 2107 .rfact = 0 2108 }, 2109 { 2110 .desc = "Aux Fan1", 2111 .type = ENVSYS_SFANRPM, 2112 .bank = 4, 2113 .reg = 0xc6, 2114 .refresh = wb_nct6776f_refresh_fanrpm, 2115 .rfact = 0 2116 }, 2117 { 2118 .desc = "Aux Fan2", 2119 .type = ENVSYS_SFANRPM, 2120 .bank = 4, 2121 .reg = 0xc8, 2122 .refresh = wb_nct6776f_refresh_fanrpm, 2123 .rfact = 0 2124 }, 2125 2126 { .desc = NULL } 2127 }; 2128 2129 static const struct wb_product wb_products[] = { 2130 { WB_CHIPID_W83627HF, "W83627HF", w83627hf_sensors, NULL }, 2131 { WB_CHIPID_W83627THF, "W83627THF",w83637hf_sensors, NULL }, 2132 { WB_CHIPID_W83627EHF_A,"W83627EHF-A",w83627ehf_sensors,NULL }, 2133 { WB_CHIPID_W83627EHF, "W83627EHF",w83627ehf_sensors,NULL }, 2134 { WB_CHIPID_W83627DHG, NULL, NULL, NULL }, 2135 { WB_CHIPID_W83637HF, "W83637HF", w83637hf_sensors, NULL }, 2136 { WB_CHIPID_W83697HF, "W83697HF", w83697hf_sensors, NULL }, 2137 { WB_CHIPID_W83781D, "W83781D", w83781d_sensors, NULL }, 2138 { WB_CHIPID_W83781D_2, "W83781D", w83781d_sensors, NULL }, 2139 { WB_CHIPID_W83782D, "W83782D", w83782d_sensors, NULL }, 2140 { WB_CHIPID_W83783S, "W83783S", w83783s_sensors, NULL }, 2141 { WB_CHIPID_W83791D, "W83791D", w83791d_sensors, NULL }, 2142 { WB_CHIPID_W83791SD, "W83791SD", NULL, NULL }, 2143 { WB_CHIPID_W83792D, "W83792D", w83792d_sensors, NULL }, 2144 { WB_CHIPID_AS99127F, NULL, NULL, NULL }, 2145 { 0, NULL, NULL, NULL } 2146 }; 2147 2148 static const struct wb_product wbsio_products[] = { 2149 { WBSIO_ID_W83627DHG, "W83627DHG",w83627dhg_sensors,NULL }, 2150 { WBSIO_ID_NCT6775F, "NCT6775F", nct6776f_sensors, NULL }, 2151 { WBSIO_ID_NCT6776F, "NCT6776F", nct6776f_sensors, NULL }, 2152 { WBSIO_ID_NCT5104D, "NCT5104D or 610[246]D",nct6102d_sensors,NULL }, 2153 { WBSIO_ID_NCT6779D, "NCT6779D", nct6779d_sensors, NULL }, 2154 { WBSIO_ID_NCT6791D, "NCT6791D", nct6779d_sensors, NULL }, 2155 { WBSIO_ID_NCT6792D, "NCT6792D", nct6779d_sensors, NULL }, 2156 { WBSIO_ID_NCT6793D, "NCT6793D", nct6779d_sensors, NULL }, 2157 { WBSIO_ID_NCT6795D, "NCT6795D", nct6779d_sensors, NULL }, 2158 { WBSIO_ID_NCT6796D, "NCT6796D", nct6779d_sensors, NULL }, 2159 { WBSIO_ID_NCT6798D, "NCT6798D", nct6779d_sensors, NULL }, 2160 { WBSIO_ID_NCT6799D, "NCT6799D", nct6779d_sensors, NULL }, 2161 { 0, NULL, NULL, NULL } 2162 }; 2163 2164 static const struct wb_product as99127f_products[] = { 2165 { WB_VENDID_ASUS, "AS99127F", w83781d_sensors, NULL }, 2166 { WB_VENDID_WINBOND, "AS99127F rev 2",as99127f_sensors,NULL }, 2167 { 0, NULL, NULL, NULL } 2168 }; 2169 2170 static void 2171 lm_generic_banksel(struct lm_softc *lmsc, uint8_t bank) 2172 { 2173 (*lmsc->lm_writereg)(lmsc, WB_BANKSEL, bank); 2174 } 2175 2176 /* 2177 * bus independent match 2178 * 2179 * prerequisites: lmsc contains valid lm_{read,write}reg() routines 2180 * and associated bus access data is present in attachment's softc 2181 */ 2182 int 2183 lm_match(struct lm_softc *lmsc) 2184 { 2185 uint8_t cr; 2186 int i, rv; 2187 2188 /* Perform LM78 reset */ 2189 /*(*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x80); */ 2190 2191 cr = (*lmsc->lm_readreg)(lmsc, LMD_CONFIG); 2192 2193 /* XXX - spec says *only* 0x08! */ 2194 if ((cr != 0x08) && (cr != 0x01) && (cr != 0x03) && (cr != 0x06)) 2195 return 0; 2196 2197 DPRINTF(("%s: 0x80 check: cr = %x\n", __func__, cr)); 2198 2199 for (i = 0; i < __arraycount(lm_chips); i++) 2200 if ((rv = lm_chips[i].chip_match(lmsc)) != 0) 2201 return rv; 2202 2203 return 0; 2204 } 2205 2206 int 2207 nslm_match(struct lm_softc *sc) 2208 { 2209 uint8_t chipid; 2210 2211 /* See if we have an LM78/LM78J/LM79 or LM81 */ 2212 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 2213 switch(chipid) { 2214 case LM_ID_LM78: 2215 case LM_ID_LM78J: 2216 case LM_ID_LM79: 2217 case LM_ID_LM81: 2218 break; 2219 default: 2220 return 0; 2221 } 2222 DPRINTF(("%s: chipid %x\n", __func__, chipid)); 2223 return 1; 2224 } 2225 2226 void 2227 lm_attach(struct lm_softc *lmsc) 2228 { 2229 uint32_t i; 2230 int rv; 2231 2232 for (i = 0; i < __arraycount(lm_chips); i++) { 2233 if (lm_chips[i].chip_match(lmsc) != 0) { 2234 if (lm_chips[i].chip_attach(lmsc) == 0) 2235 break; 2236 else 2237 return; 2238 } 2239 } 2240 2241 /* Start the monitoring loop */ 2242 (*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x01); 2243 2244 lmsc->sc_sme = sysmon_envsys_create(); 2245 /* Initialize sensors */ 2246 for (i = 0; i < lmsc->numsensors; i++) { 2247 lmsc->sensors[i].state = ENVSYS_SINVALID; 2248 if ((rv = sysmon_envsys_sensor_attach(lmsc->sc_sme, 2249 &lmsc->sensors[i])) != 0) { 2250 sysmon_envsys_destroy(lmsc->sc_sme); 2251 lmsc->sc_sme = NULL; 2252 aprint_error_dev(lmsc->sc_dev, 2253 "sysmon_envsys_sensor_attach() returned %d\n", rv); 2254 return; 2255 } 2256 } 2257 2258 /* 2259 * Setup the callout to refresh sensor data every 2 seconds. 2260 */ 2261 callout_init(&lmsc->sc_callout, 0); 2262 callout_setfunc(&lmsc->sc_callout, lm_refresh, lmsc); 2263 callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO); 2264 2265 /* 2266 * Hook into the System Monitor. 2267 */ 2268 lmsc->sc_sme->sme_name = device_xname(lmsc->sc_dev); 2269 lmsc->sc_sme->sme_flags = SME_DISABLE_REFRESH; 2270 2271 if (sysmon_envsys_register(lmsc->sc_sme)) { 2272 aprint_error_dev(lmsc->sc_dev, 2273 "unable to register with sysmon\n"); 2274 sysmon_envsys_destroy(lmsc->sc_sme); 2275 lmsc->sc_sme = NULL; 2276 } 2277 if (!pmf_device_register(lmsc->sc_dev, NULL, NULL)) 2278 aprint_error_dev(lmsc->sc_dev, 2279 "couldn't establish power handler\n"); 2280 } 2281 2282 /* 2283 * Stop, destroy the callout and unregister the driver with the 2284 * sysmon_envsys(9) framework. 2285 */ 2286 void 2287 lm_detach(struct lm_softc *lmsc) 2288 { 2289 callout_halt(&lmsc->sc_callout, NULL); 2290 callout_destroy(&lmsc->sc_callout); 2291 2292 if (lmsc->sc_sme != NULL) 2293 sysmon_envsys_unregister(lmsc->sc_sme); 2294 pmf_device_deregister(lmsc->sc_dev); 2295 } 2296 2297 static void 2298 lm_refresh(void *arg) 2299 { 2300 struct lm_softc *lmsc = arg; 2301 2302 lmsc->refresh_sensor_data(lmsc); 2303 callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO); 2304 } 2305 2306 static int 2307 nslm_attach(struct lm_softc *sc) 2308 { 2309 const char *model = NULL; 2310 uint8_t chipid; 2311 2312 /* See if we have an LM78/LM78J/LM79 or LM81 */ 2313 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 2314 switch(chipid) { 2315 case LM_ID_LM78: 2316 model = "LM78"; 2317 break; 2318 case LM_ID_LM78J: 2319 model = "LM78J"; 2320 break; 2321 case LM_ID_LM79: 2322 model = "LM79"; 2323 break; 2324 case LM_ID_LM81: 2325 model = "LM81"; 2326 break; 2327 default: 2328 return -1; 2329 } 2330 2331 aprint_naive("\n"); 2332 aprint_normal("\n"); 2333 aprint_normal_dev(sc->sc_dev, 2334 "National Semiconductor %s Hardware monitor\n", model); 2335 2336 lm_setup_sensors(sc, lm78_sensors); 2337 sc->refresh_sensor_data = lm_refresh_sensor_data; 2338 return 0; 2339 } 2340 2341 static int 2342 def_match(struct lm_softc *sc) 2343 { 2344 2345 return 1; 2346 } 2347 2348 static int 2349 def_attach(struct lm_softc *sc) 2350 { 2351 uint8_t chipid; 2352 2353 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 2354 aprint_naive("\n"); 2355 aprint_normal("\n"); 2356 aprint_error_dev(sc->sc_dev, "Unknown chip (ID 0x%02x)\n", chipid); 2357 2358 lm_setup_sensors(sc, lm78_sensors); 2359 sc->refresh_sensor_data = lm_refresh_sensor_data; 2360 return 0; 2361 } 2362 2363 static void 2364 wb_temp_diode_type(struct lm_softc *sc, int diode_type) 2365 { 2366 uint8_t regval, banksel; 2367 2368 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2369 switch (diode_type) { 2370 case 1: /* Switch to Pentium-II diode mode */ 2371 lm_generic_banksel(sc, WB_BANKSEL_B0); 2372 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2373 regval |= 0x0e; 2374 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval); 2375 regval = (*sc->lm_readreg)(sc, WB_BANK0_RESVD1); 2376 regval |= 0x70; 2377 (*sc->lm_writereg)(sc, WB_BANK0_RESVD1, 0x0); 2378 lm_generic_banksel(sc, banksel); 2379 aprint_verbose_dev(sc->sc_dev, "Pentium-II diode temp sensors\n"); 2380 break; 2381 case 2: /* Switch to 2N3904 mode */ 2382 lm_generic_banksel(sc, WB_BANKSEL_B0); 2383 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2384 regval |= 0xe; 2385 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval); 2386 regval = (*sc->lm_readreg)(sc, WB_BANK0_RESVD1); 2387 regval &= ~0x70; 2388 (*sc->lm_writereg)(sc, WB_BANK0_RESVD1, 0x0); 2389 lm_generic_banksel(sc, banksel); 2390 aprint_verbose_dev(sc->sc_dev, "2N3904 bipolar temp sensors\n"); 2391 break; 2392 case 4: /* Switch to generic thermistor mode */ 2393 lm_generic_banksel(sc, WB_BANKSEL_B0); 2394 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2395 regval &= ~0xe; 2396 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval); 2397 lm_generic_banksel(sc, banksel); 2398 aprint_verbose_dev(sc->sc_dev, "Thermistor temp sensors\n"); 2399 break; 2400 case 0: /* Unspecified - use default */ 2401 aprint_verbose_dev(sc->sc_dev, "Using default temp sensors\n"); 2402 break; 2403 default: 2404 aprint_error_dev(sc->sc_dev, 2405 "Ignoring invalid temp sensor mode %d\n", 2406 diode_type); 2407 break; 2408 } 2409 } 2410 2411 static const struct wb_product * 2412 wb_lookup(struct lm_softc *sc, const struct wb_product *products, uint16_t id) 2413 { 2414 const struct wb_product *prod = products; 2415 int i = 0; 2416 2417 while (prod[i].id != 0) { 2418 if (prod[i].id != id) { 2419 i++; 2420 continue; 2421 } 2422 if (prod[i].str == NULL) { 2423 if (products == wb_products) { 2424 if (id == WB_CHIPID_W83627DHG) { 2425 /* 2426 * Lookup wbsio_products 2427 * with WBSIO_ID. 2428 */ 2429 return wb_lookup(sc, wbsio_products, 2430 sc->sioid); 2431 } else if (id == WB_CHIPID_AS99127F) { 2432 /* 2433 * Lookup as99127f_products 2434 * with WB_VENDID. 2435 */ 2436 return wb_lookup(sc, as99127f_products, 2437 wb_read_vendorid(sc)); 2438 } else 2439 return NULL; /* not occur */ 2440 } 2441 return NULL; /* not occur */ 2442 } 2443 return &prod[i]; 2444 } 2445 2446 /* Not found */ 2447 return NULL; 2448 } 2449 2450 static uint16_t 2451 wb_read_vendorid(struct lm_softc *sc) 2452 { 2453 uint16_t vendid; 2454 uint8_t vendidreg; 2455 uint8_t banksel; 2456 2457 /* Save bank */ 2458 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2459 2460 /* Check default vendor ID register first */ 2461 vendidreg = WB_VENDID; 2462 2463 retry: 2464 /* Read vendor ID */ 2465 lm_generic_banksel(sc, WB_BANKSEL_HBAC); 2466 vendid = (*sc->lm_readreg)(sc, vendidreg) << 8; 2467 lm_generic_banksel(sc, 0); 2468 vendid |= (*sc->lm_readreg)(sc, vendidreg); 2469 2470 if ((vendidreg == WB_VENDID) 2471 && (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)) { 2472 /* If it failed, try NCT6102 vendor ID register */ 2473 vendidreg = WB_NCT6102_VENDID; 2474 goto retry; 2475 } else if ((vendidreg == WB_NCT6102_VENDID) 2476 && (vendid != WB_VENDID_WINBOND)) 2477 vendid = 0; /* XXX */ 2478 2479 /* Restore bank */ 2480 lm_generic_banksel(sc, banksel); 2481 2482 return vendid; 2483 } 2484 2485 static uint8_t 2486 wb_read_chipid(struct lm_softc *sc) 2487 { 2488 const struct wb_product *prod; 2489 uint8_t chipidreg, chipid, banksel; 2490 2491 /* Save bank */ 2492 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2493 2494 /* Check default vendor ID register first */ 2495 chipidreg = WB_BANK0_CHIPID; 2496 lm_generic_banksel(sc, WB_BANKSEL_B0); 2497 2498 retry: 2499 (void)(*sc->lm_readreg)(sc, LMD_CHIPID); 2500 chipid = (*sc->lm_readreg)(sc, chipidreg); 2501 prod = wb_lookup(sc, wb_products, chipid); 2502 if (prod == NULL) { 2503 if (chipidreg == WB_BANK0_CHIPID) { 2504 chipidreg = WB_BANK0_NCT6102_CHIPID; 2505 goto retry; 2506 } else 2507 chipid = 0; 2508 } 2509 /* Restore bank */ 2510 lm_generic_banksel(sc, banksel); 2511 2512 return chipid; 2513 } 2514 2515 static int 2516 wb_match(struct lm_softc *sc) 2517 { 2518 const struct wb_product *prod; 2519 uint16_t vendid; 2520 uint8_t chipid; 2521 2522 /* Read vendor ID */ 2523 vendid = wb_read_vendorid(sc); 2524 DPRINTF(("%s: winbond vend id 0x%x\n", __func__, vendid)); 2525 if ((vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)) 2526 return 0; 2527 2528 /* Read device/chip ID */ 2529 chipid = wb_read_chipid(sc); 2530 DPRINTF(("%s: winbond chip id 0x%x\n", __func__, chipid)); 2531 prod = wb_lookup(sc, wb_products, chipid); 2532 2533 if (prod == NULL) { 2534 if (vendid == WB_VENDID_WINBOND) 2535 return 1; /* Generic match */ 2536 else 2537 return 0; 2538 } 2539 DPRINTF(("%s: chipid %02x, sioid = %04x\n", __func__, chipid, 2540 sc->sioid)); 2541 2542 return 10; /* found */ 2543 } 2544 2545 static int 2546 wb_attach(struct lm_softc *sc) 2547 { 2548 device_t dev = sc->sc_dev; 2549 const struct wb_product *prod; 2550 const char *model = NULL; 2551 const char *vendor = "Winbond"; 2552 const struct lm_sensor *sensors; 2553 uint16_t vendid; 2554 uint8_t banksel; 2555 int cf_flags; 2556 2557 aprint_naive("\n"); 2558 aprint_normal("\n"); 2559 /* Read device/chip ID */ 2560 sc->chipid = wb_read_chipid(sc); 2561 DPRINTF(("%s: winbond chip id 0x%x\n", __func__, sc->chipid)); 2562 2563 if ((prod = wb_lookup(sc, wb_products, sc->chipid)) != NULL) { 2564 model = prod->str; 2565 switch (model[0]) { 2566 case 'W': 2567 vendor = "Winbond"; 2568 break; 2569 case 'A': 2570 vendor = "ASUS"; 2571 break; 2572 case 'N': 2573 vendor = "Nuvoton"; 2574 break; 2575 default: 2576 aprint_error_dev(dev, "Unknown model (%s)\n", model); 2577 return -1; 2578 } 2579 sensors = prod->sensors; 2580 sc->refresh_sensor_data = wb_refresh_sensor_data; 2581 if (prod->extattach != NULL) 2582 prod->extattach(sc); 2583 } else { 2584 vendid = wb_read_vendorid(sc); 2585 if (vendid == WB_VENDID_WINBOND) { 2586 vendor = "Winbond"; 2587 model = "unknown-model"; 2588 2589 /* Handle as a standard LM78. */ 2590 sensors = lm78_sensors; 2591 sc->refresh_sensor_data = lm_refresh_sensor_data; 2592 } else { 2593 aprint_error_dev(dev, "Unknown chip (ID %02x)\n", 2594 sc->chipid); 2595 return -1; 2596 } 2597 } 2598 2599 cf_flags = device_cfdata(dev)->cf_flags; 2600 2601 if (sensors != NULL) { 2602 lm_setup_sensors(sc, sensors); 2603 2604 /* XXX Is this correct? Check all datasheets. */ 2605 switch (sc->chipid) { 2606 case WB_CHIPID_W83627EHF_A: 2607 case WB_CHIPID_W83781D: 2608 case WB_CHIPID_W83781D_2: 2609 case WB_CHIPID_W83791SD: 2610 case WB_CHIPID_W83792D: 2611 case WB_CHIPID_AS99127F: 2612 break; 2613 default: 2614 wb_temp_diode_type(sc, cf_flags); 2615 break; 2616 } 2617 } 2618 2619 /* XXX Is this correct? Check all datasheets. */ 2620 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2621 switch(sc->chipid) { 2622 case WB_CHIPID_W83627THF: 2623 lm_generic_banksel(sc, WB_BANKSEL_B0); 2624 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9) 2625 sc->vrm9 = 1; 2626 lm_generic_banksel(sc, banksel); 2627 break; 2628 case WB_CHIPID_W83637HF: 2629 lm_generic_banksel(sc, WB_BANKSEL_B0); 2630 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9) 2631 sc->vrm9 = 1; 2632 lm_generic_banksel(sc, banksel); 2633 break; 2634 default: 2635 break; 2636 } 2637 2638 aprint_normal_dev(dev, "%s %s Hardware monitor\n", vendor, model); 2639 2640 return 0; 2641 } 2642 2643 static void 2644 lm_setup_sensors(struct lm_softc *sc, const struct lm_sensor *sensors) 2645 { 2646 int i; 2647 2648 for (i = 0; sensors[i].desc; i++) { 2649 sc->sensors[i].units = sensors[i].type; 2650 if (sc->sensors[i].units == ENVSYS_SVOLTS_DC) 2651 sc->sensors[i].flags = ENVSYS_FCHANGERFACT; 2652 strlcpy(sc->sensors[i].desc, sensors[i].desc, 2653 sizeof(sc->sensors[i].desc)); 2654 sc->numsensors++; 2655 } 2656 sc->lm_sensors = sensors; 2657 } 2658 2659 static void 2660 lm_refresh_sensor_data(struct lm_softc *sc) 2661 { 2662 int i; 2663 2664 for (i = 0; i < sc->numsensors; i++) 2665 sc->lm_sensors[i].refresh(sc, i); 2666 } 2667 2668 static void 2669 lm_refresh_volt(struct lm_softc *sc, int n) 2670 { 2671 int data; 2672 2673 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2674 if (data == 0xff) { 2675 sc->sensors[n].state = ENVSYS_SINVALID; 2676 } else { 2677 sc->sensors[n].value_cur = (data << 4); 2678 if (sc->sensors[n].rfact) { 2679 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2680 sc->sensors[n].value_cur /= 10; 2681 } else { 2682 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact; 2683 sc->sensors[n].value_cur /= 10; 2684 sc->sensors[n].rfact = sc->lm_sensors[n].rfact; 2685 } 2686 sc->sensors[n].state = ENVSYS_SVALID; 2687 } 2688 2689 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2690 __func__, n, data, sc->sensors[n].value_cur)); 2691 } 2692 2693 static void 2694 lm_refresh_temp(struct lm_softc *sc, int n) 2695 { 2696 int data; 2697 2698 /* 2699 * The data sheet suggests that the range of the temperature 2700 * sensor is between -55 degC and +125 degC. 2701 */ 2702 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2703 if (data > 0x7d && data < 0xc9) 2704 sc->sensors[n].state = ENVSYS_SINVALID; 2705 else { 2706 if (data & 0x80) 2707 data -= 0x100; 2708 sc->sensors[n].state = ENVSYS_SVALID; 2709 sc->sensors[n].value_cur = data * 1000000 + 273150000; 2710 } 2711 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2712 __func__, n, data, sc->sensors[n].value_cur)); 2713 } 2714 2715 static void 2716 lm_refresh_fanrpm(struct lm_softc *sc, int n) 2717 { 2718 int data, divisor = 1; 2719 2720 /* 2721 * We might get more accurate fan readings by adjusting the 2722 * divisor, but that might interfere with APM or other SMM 2723 * BIOS code reading the fan speeds. 2724 */ 2725 2726 /* FAN3 has a fixed fan divisor. */ 2727 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2728 sc->lm_sensors[n].reg == LMD_FAN2) { 2729 data = (*sc->lm_readreg)(sc, LMD_VIDFAN); 2730 if (sc->lm_sensors[n].reg == LMD_FAN1) 2731 divisor = (data >> 4) & 0x03; 2732 else 2733 divisor = (data >> 6) & 0x03; 2734 } 2735 2736 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2737 if (data == 0xff || data == 0x00) 2738 sc->sensors[n].state = ENVSYS_SINVALID; 2739 else { 2740 sc->sensors[n].state = ENVSYS_SVALID; 2741 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2742 } 2743 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2744 __func__, n, data, sc->sensors[n].value_cur)); 2745 } 2746 2747 static void 2748 wb_refresh_sensor_data(struct lm_softc *sc) 2749 { 2750 uint8_t banksel, bank; 2751 int i; 2752 2753 /* 2754 * Properly save and restore bank selection register. 2755 */ 2756 banksel = bank = sc->lm_readreg(sc, WB_BANKSEL); 2757 for (i = 0; i < sc->numsensors; i++) { 2758 if (bank != sc->lm_sensors[i].bank) { 2759 bank = sc->lm_sensors[i].bank; 2760 lm_generic_banksel(sc, bank); 2761 } 2762 sc->lm_sensors[i].refresh(sc, i); 2763 } 2764 lm_generic_banksel(sc, banksel); 2765 } 2766 2767 static void 2768 wb_w83637hf_refresh_vcore(struct lm_softc *sc, int n) 2769 { 2770 int data; 2771 2772 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2773 /* 2774 * Depending on the voltage detection method, 2775 * one of the following formulas is used: 2776 * VRM8 method: value = raw * 0.016V 2777 * VRM9 method: value = raw * 0.00488V + 0.70V 2778 */ 2779 if (sc->vrm9) 2780 sc->sensors[n].value_cur = (data * 4880) + 700000; 2781 else 2782 sc->sensors[n].value_cur = (data * 16000); 2783 sc->sensors[n].state = ENVSYS_SVALID; 2784 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2785 __func__, n, data, sc->sensors[n].value_cur)); 2786 } 2787 2788 static void 2789 wb_refresh_nvolt(struct lm_softc *sc, int n) 2790 { 2791 int data; 2792 2793 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2794 sc->sensors[n].value_cur = ((data << 4) - WB_VREF); 2795 if (sc->sensors[n].rfact) 2796 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2797 else 2798 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact; 2799 2800 sc->sensors[n].value_cur /= 10; 2801 sc->sensors[n].value_cur += WB_VREF * 1000; 2802 sc->sensors[n].state = ENVSYS_SVALID; 2803 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2804 __func__, n , data, sc->sensors[n].value_cur)); 2805 } 2806 2807 static void 2808 wb_w83627ehf_refresh_nvolt(struct lm_softc *sc, int n) 2809 { 2810 int data; 2811 2812 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2813 sc->sensors[n].value_cur = ((data << 3) - WB_W83627EHF_VREF); 2814 if (sc->sensors[n].rfact) 2815 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2816 else 2817 sc->sensors[n].value_cur *= RFACT(232, 10); 2818 2819 sc->sensors[n].value_cur /= 10; 2820 sc->sensors[n].value_cur += WB_W83627EHF_VREF * 1000; 2821 sc->sensors[n].state = ENVSYS_SVALID; 2822 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2823 __func__, n , data, sc->sensors[n].value_cur)); 2824 } 2825 2826 static void 2827 wb_refresh_temp(struct lm_softc *sc, int n) 2828 { 2829 int data; 2830 2831 /* 2832 * The data sheet suggests that the range of the temperature 2833 * sensor is between -55 degC and +125 degC. However, values 2834 * around -48 degC seem to be a very common bogus values. 2835 * Since such values are unreasonably low, we use -45 degC for 2836 * the lower limit instead. 2837 */ 2838 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1; 2839 data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7; 2840 if (data > 0xfffffff || (data > 0x0fa && data < 0x1a6)) { 2841 sc->sensors[n].state = ENVSYS_SINVALID; 2842 } else { 2843 if (data & 0x100) 2844 data -= 0x200; 2845 sc->sensors[n].state = ENVSYS_SVALID; 2846 sc->sensors[n].value_cur = data * 500000 + 273150000; 2847 } 2848 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2849 __func__, n , data, sc->sensors[n].value_cur)); 2850 } 2851 2852 static void 2853 wb_refresh_fanrpm(struct lm_softc *sc, int n) 2854 { 2855 int fan, data, divisor = 0; 2856 2857 /* 2858 * This is madness; the fan divisor bits are scattered all 2859 * over the place. 2860 */ 2861 2862 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2863 sc->lm_sensors[n].reg == LMD_FAN2 || 2864 sc->lm_sensors[n].reg == LMD_FAN3) { 2865 data = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2866 fan = (sc->lm_sensors[n].reg - LMD_FAN1); 2867 if ((data >> 5) & (1 << fan)) 2868 divisor |= 0x04; 2869 } 2870 2871 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2872 sc->lm_sensors[n].reg == LMD_FAN2) { 2873 data = (*sc->lm_readreg)(sc, LMD_VIDFAN); 2874 if (sc->lm_sensors[n].reg == LMD_FAN1) 2875 divisor |= (data >> 4) & 0x03; 2876 else 2877 divisor |= (data >> 6) & 0x03; 2878 } else if (sc->lm_sensors[n].reg == LMD_FAN3) { 2879 data = (*sc->lm_readreg)(sc, WB_PIN); 2880 divisor |= (data >> 6) & 0x03; 2881 } else if (sc->lm_sensors[n].reg == WB_BANK0_FAN4 || 2882 sc->lm_sensors[n].reg == WB_BANK0_FAN5) { 2883 data = (*sc->lm_readreg)(sc, WB_BANK0_FAN45); 2884 if (sc->lm_sensors[n].reg == WB_BANK0_FAN4) 2885 divisor |= (data >> 0) & 0x07; 2886 else 2887 divisor |= (data >> 4) & 0x07; 2888 } 2889 2890 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2891 if (data >= 0xff || data == 0x00) 2892 sc->sensors[n].state = ENVSYS_SINVALID; 2893 else { 2894 sc->sensors[n].state = ENVSYS_SVALID; 2895 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2896 } 2897 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2898 __func__, n , data, sc->sensors[n].value_cur)); 2899 } 2900 2901 static void 2902 wb_nct6776f_refresh_fanrpm(struct lm_softc *sc, int n) 2903 { 2904 int datah, datal; 2905 2906 datah = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2907 datal = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1); 2908 2909 if ((datah == 0xff) || (datah == 0)) { 2910 sc->sensors[n].state = ENVSYS_SINVALID; 2911 } else { 2912 sc->sensors[n].state = ENVSYS_SVALID; 2913 sc->sensors[n].value_cur = (datah << 8) | datal; 2914 } 2915 } 2916 2917 static void 2918 wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n) 2919 { 2920 int shift, data, divisor = 1; 2921 uint8_t reg; 2922 2923 shift = 0; 2924 2925 switch (sc->lm_sensors[n].reg) { 2926 case 0x28: 2927 reg = 0x47; shift = 0; 2928 break; 2929 case 0x29: 2930 reg = 0x47; shift = 4; 2931 break; 2932 case 0x2a: 2933 reg = 0x5b; shift = 0; 2934 break; 2935 case 0xb8: 2936 reg = 0x5b; shift = 4; 2937 break; 2938 case 0xb9: 2939 reg = 0x5c; shift = 0; 2940 break; 2941 case 0xba: 2942 reg = 0x5c; shift = 4; 2943 break; 2944 case 0xbe: 2945 reg = 0x9e; shift = 0; 2946 break; 2947 default: 2948 reg = 0; 2949 break; 2950 } 2951 2952 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2953 if (data == 0xff || data == 0x00) 2954 sc->sensors[n].state = ENVSYS_SINVALID; 2955 else { 2956 if (reg != 0) 2957 divisor = ((*sc->lm_readreg)(sc, reg) >> shift) & 0x7; 2958 sc->sensors[n].state = ENVSYS_SVALID; 2959 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2960 } 2961 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2962 __func__, n , data, sc->sensors[n].value_cur)); 2963 } 2964 2965 static void 2966 as_refresh_temp(struct lm_softc *sc, int n) 2967 { 2968 int data; 2969 2970 /* 2971 * It seems a shorted temperature diode produces an all-ones 2972 * bit pattern. 2973 */ 2974 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1; 2975 data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7; 2976 if (data == 0x1ff) 2977 sc->sensors[n].state = ENVSYS_SINVALID; 2978 else { 2979 if (data & 0x100) 2980 data -= 0x200; 2981 sc->sensors[n].state = ENVSYS_SVALID; 2982 sc->sensors[n].value_cur = data * 500000 + 273150000; 2983 } 2984 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2985 __func__, n, data, sc->sensors[n].value_cur)); 2986 } 2987 2988 MODULE(MODULE_CLASS_DRIVER, lm, "sysmon_envsys"); 2989 2990 static int 2991 lm_modcmd(modcmd_t cmd, void *opaque) 2992 { 2993 switch (cmd) { 2994 case MODULE_CMD_INIT: 2995 case MODULE_CMD_FINI: 2996 return 0; 2997 default: 2998 return ENOTTY; 2999 } 3000 } 3001