1 /* $NetBSD: nslm7x.c,v 1.73 2019/07/10 16:23:55 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.73 2019/07/10 16:23:55 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 { 0, NULL, NULL, NULL } 2161 }; 2162 2163 static const struct wb_product as99127f_products[] = { 2164 { WB_VENDID_ASUS, "AS99127F", w83781d_sensors, NULL }, 2165 { WB_VENDID_WINBOND, "AS99127F rev 2",as99127f_sensors,NULL }, 2166 { 0, NULL, NULL, NULL } 2167 }; 2168 2169 static void 2170 lm_generic_banksel(struct lm_softc *lmsc, uint8_t bank) 2171 { 2172 (*lmsc->lm_writereg)(lmsc, WB_BANKSEL, bank); 2173 } 2174 2175 /* 2176 * bus independent match 2177 * 2178 * prerequisites: lmsc contains valid lm_{read,write}reg() routines 2179 * and associated bus access data is present in attachment's softc 2180 */ 2181 int 2182 lm_match(struct lm_softc *lmsc) 2183 { 2184 uint8_t cr; 2185 int i, rv; 2186 2187 /* Perform LM78 reset */ 2188 /*(*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x80); */ 2189 2190 cr = (*lmsc->lm_readreg)(lmsc, LMD_CONFIG); 2191 2192 /* XXX - spec says *only* 0x08! */ 2193 if ((cr != 0x08) && (cr != 0x01) && (cr != 0x03) && (cr != 0x06)) 2194 return 0; 2195 2196 DPRINTF(("%s: 0x80 check: cr = %x\n", __func__, cr)); 2197 2198 for (i = 0; i < __arraycount(lm_chips); i++) 2199 if ((rv = lm_chips[i].chip_match(lmsc)) != 0) 2200 return rv; 2201 2202 return 0; 2203 } 2204 2205 int 2206 nslm_match(struct lm_softc *sc) 2207 { 2208 uint8_t chipid; 2209 2210 /* See if we have an LM78/LM78J/LM79 or LM81 */ 2211 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 2212 switch(chipid) { 2213 case LM_ID_LM78: 2214 case LM_ID_LM78J: 2215 case LM_ID_LM79: 2216 case LM_ID_LM81: 2217 break; 2218 default: 2219 return 0; 2220 } 2221 DPRINTF(("%s: chipid %x\n", __func__, chipid)); 2222 return 1; 2223 } 2224 2225 void 2226 lm_attach(struct lm_softc *lmsc) 2227 { 2228 uint32_t i; 2229 int rv; 2230 2231 for (i = 0; i < __arraycount(lm_chips); i++) { 2232 if (lm_chips[i].chip_match(lmsc) != 0) { 2233 if (lm_chips[i].chip_attach(lmsc) == 0) 2234 break; 2235 else 2236 return; 2237 } 2238 } 2239 2240 /* Start the monitoring loop */ 2241 (*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x01); 2242 2243 lmsc->sc_sme = sysmon_envsys_create(); 2244 /* Initialize sensors */ 2245 for (i = 0; i < lmsc->numsensors; i++) { 2246 lmsc->sensors[i].state = ENVSYS_SINVALID; 2247 if ((rv = sysmon_envsys_sensor_attach(lmsc->sc_sme, 2248 &lmsc->sensors[i])) != 0) { 2249 sysmon_envsys_destroy(lmsc->sc_sme); 2250 aprint_error_dev(lmsc->sc_dev, 2251 "sysmon_envsys_sensor_attach() returned %d\n", rv); 2252 return; 2253 } 2254 } 2255 2256 /* 2257 * Setup the callout to refresh sensor data every 2 seconds. 2258 */ 2259 callout_init(&lmsc->sc_callout, 0); 2260 callout_setfunc(&lmsc->sc_callout, lm_refresh, lmsc); 2261 callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO); 2262 2263 /* 2264 * Hook into the System Monitor. 2265 */ 2266 lmsc->sc_sme->sme_name = device_xname(lmsc->sc_dev); 2267 lmsc->sc_sme->sme_flags = SME_DISABLE_REFRESH; 2268 2269 if (sysmon_envsys_register(lmsc->sc_sme)) { 2270 aprint_error_dev(lmsc->sc_dev, 2271 "unable to register with sysmon\n"); 2272 sysmon_envsys_destroy(lmsc->sc_sme); 2273 } 2274 if (!pmf_device_register(lmsc->sc_dev, NULL, NULL)) 2275 aprint_error_dev(lmsc->sc_dev, 2276 "couldn't establish power handler\n"); 2277 } 2278 2279 /* 2280 * Stop, destroy the callout and unregister the driver with the 2281 * sysmon_envsys(9) framework. 2282 */ 2283 void 2284 lm_detach(struct lm_softc *lmsc) 2285 { 2286 callout_halt(&lmsc->sc_callout, NULL); 2287 callout_destroy(&lmsc->sc_callout); 2288 sysmon_envsys_unregister(lmsc->sc_sme); 2289 pmf_device_deregister(lmsc->sc_dev); 2290 } 2291 2292 static void 2293 lm_refresh(void *arg) 2294 { 2295 struct lm_softc *lmsc = arg; 2296 2297 lmsc->refresh_sensor_data(lmsc); 2298 callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO); 2299 } 2300 2301 static int 2302 nslm_attach(struct lm_softc *sc) 2303 { 2304 const char *model = NULL; 2305 uint8_t chipid; 2306 2307 /* See if we have an LM78/LM78J/LM79 or LM81 */ 2308 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 2309 switch(chipid) { 2310 case LM_ID_LM78: 2311 model = "LM78"; 2312 break; 2313 case LM_ID_LM78J: 2314 model = "LM78J"; 2315 break; 2316 case LM_ID_LM79: 2317 model = "LM79"; 2318 break; 2319 case LM_ID_LM81: 2320 model = "LM81"; 2321 break; 2322 default: 2323 return -1; 2324 } 2325 2326 aprint_naive("\n"); 2327 aprint_normal("\n"); 2328 aprint_normal_dev(sc->sc_dev, 2329 "National Semiconductor %s Hardware monitor\n", model); 2330 2331 lm_setup_sensors(sc, lm78_sensors); 2332 sc->refresh_sensor_data = lm_refresh_sensor_data; 2333 return 0; 2334 } 2335 2336 static int 2337 def_match(struct lm_softc *sc) 2338 { 2339 2340 return 1; 2341 } 2342 2343 static int 2344 def_attach(struct lm_softc *sc) 2345 { 2346 uint8_t chipid; 2347 2348 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 2349 aprint_naive("\n"); 2350 aprint_normal("\n"); 2351 aprint_error_dev(sc->sc_dev, "Unknown chip (ID 0x%02x)\n", chipid); 2352 2353 lm_setup_sensors(sc, lm78_sensors); 2354 sc->refresh_sensor_data = lm_refresh_sensor_data; 2355 return 0; 2356 } 2357 2358 static void 2359 wb_temp_diode_type(struct lm_softc *sc, int diode_type) 2360 { 2361 uint8_t regval, banksel; 2362 2363 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2364 switch (diode_type) { 2365 case 1: /* Switch to Pentium-II diode mode */ 2366 lm_generic_banksel(sc, WB_BANKSEL_B0); 2367 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2368 regval |= 0x0e; 2369 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval); 2370 regval = (*sc->lm_readreg)(sc, WB_BANK0_RESVD1); 2371 regval |= 0x70; 2372 (*sc->lm_writereg)(sc, WB_BANK0_RESVD1, 0x0); 2373 lm_generic_banksel(sc, banksel); 2374 aprint_verbose_dev(sc->sc_dev, "Pentium-II diode temp sensors\n"); 2375 break; 2376 case 2: /* Switch to 2N3904 mode */ 2377 lm_generic_banksel(sc, WB_BANKSEL_B0); 2378 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2379 regval |= 0xe; 2380 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval); 2381 regval = (*sc->lm_readreg)(sc, WB_BANK0_RESVD1); 2382 regval &= ~0x70; 2383 (*sc->lm_writereg)(sc, WB_BANK0_RESVD1, 0x0); 2384 lm_generic_banksel(sc, banksel); 2385 aprint_verbose_dev(sc->sc_dev, "2N3904 bipolar temp sensors\n"); 2386 break; 2387 case 4: /* Switch to generic thermistor mode */ 2388 lm_generic_banksel(sc, WB_BANKSEL_B0); 2389 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2390 regval &= ~0xe; 2391 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval); 2392 lm_generic_banksel(sc, banksel); 2393 aprint_verbose_dev(sc->sc_dev, "Thermistor temp sensors\n"); 2394 break; 2395 case 0: /* Unspecified - use default */ 2396 aprint_verbose_dev(sc->sc_dev, "Using default temp sensors\n"); 2397 break; 2398 default: 2399 aprint_error_dev(sc->sc_dev, 2400 "Ignoring invalid temp sensor mode %d\n", 2401 diode_type); 2402 break; 2403 } 2404 } 2405 2406 static const struct wb_product * 2407 wb_lookup(struct lm_softc *sc, const struct wb_product *products, uint16_t id) 2408 { 2409 const struct wb_product *prod = products; 2410 int i = 0; 2411 2412 while (prod[i].id != 0) { 2413 if (prod[i].id != id) { 2414 i++; 2415 continue; 2416 } 2417 if (prod[i].str == NULL) { 2418 if (products == wb_products) { 2419 if (id == WB_CHIPID_W83627DHG) { 2420 /* 2421 * Lookup wbsio_products 2422 * with WBSIO_ID. 2423 */ 2424 return wb_lookup(sc, wbsio_products, 2425 sc->sioid); 2426 } else if (id == WB_CHIPID_AS99127F) { 2427 /* 2428 * Lookup as99127f_products 2429 * with WB_VENDID. 2430 */ 2431 return wb_lookup(sc, as99127f_products, 2432 wb_read_vendorid(sc)); 2433 } else 2434 return NULL; /* not occur */ 2435 } 2436 return NULL; /* not occur */ 2437 } 2438 return &prod[i]; 2439 } 2440 2441 /* Not found */ 2442 return NULL; 2443 } 2444 2445 static uint16_t 2446 wb_read_vendorid(struct lm_softc *sc) 2447 { 2448 uint16_t vendid; 2449 uint8_t vendidreg; 2450 uint8_t banksel; 2451 2452 /* Save bank */ 2453 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2454 2455 /* Check default vendor ID register first */ 2456 vendidreg = WB_VENDID; 2457 2458 retry: 2459 /* Read vendor ID */ 2460 lm_generic_banksel(sc, WB_BANKSEL_HBAC); 2461 vendid = (*sc->lm_readreg)(sc, vendidreg) << 8; 2462 lm_generic_banksel(sc, 0); 2463 vendid |= (*sc->lm_readreg)(sc, vendidreg); 2464 2465 if ((vendidreg == WB_VENDID) 2466 && (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)) { 2467 /* If it failed, try NCT6102 vendor ID register */ 2468 vendidreg = WB_NCT6102_VENDID; 2469 goto retry; 2470 } else if ((vendidreg == WB_NCT6102_VENDID) 2471 && (vendid != WB_VENDID_WINBOND)) 2472 vendid = 0; /* XXX */ 2473 2474 /* Restore bank */ 2475 lm_generic_banksel(sc, banksel); 2476 2477 return vendid; 2478 } 2479 2480 static uint8_t 2481 wb_read_chipid(struct lm_softc *sc) 2482 { 2483 const struct wb_product *prod; 2484 uint8_t chipidreg, chipid, banksel; 2485 2486 /* Save bank */ 2487 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2488 2489 /* Check default vendor ID register first */ 2490 chipidreg = WB_BANK0_CHIPID; 2491 lm_generic_banksel(sc, WB_BANKSEL_B0); 2492 2493 retry: 2494 (void)(*sc->lm_readreg)(sc, LMD_CHIPID); 2495 chipid = (*sc->lm_readreg)(sc, chipidreg); 2496 prod = wb_lookup(sc, wb_products, chipid); 2497 if (prod == NULL) { 2498 if (chipidreg == WB_BANK0_CHIPID) { 2499 chipidreg = WB_BANK0_NCT6102_CHIPID; 2500 goto retry; 2501 } else 2502 chipid = 0; 2503 } 2504 /* Restore bank */ 2505 lm_generic_banksel(sc, banksel); 2506 2507 return chipid; 2508 } 2509 2510 static int 2511 wb_match(struct lm_softc *sc) 2512 { 2513 const struct wb_product *prod; 2514 uint16_t vendid; 2515 uint8_t chipid; 2516 2517 /* Read vendor ID */ 2518 vendid = wb_read_vendorid(sc); 2519 DPRINTF(("%s: winbond vend id 0x%x\n", __func__, vendid)); 2520 if ((vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)) 2521 return 0; 2522 2523 /* Read device/chip ID */ 2524 chipid = wb_read_chipid(sc); 2525 DPRINTF(("%s: winbond chip id 0x%x\n", __func__, chipid)); 2526 prod = wb_lookup(sc, wb_products, chipid); 2527 2528 if (prod == NULL) { 2529 if (vendid == WB_VENDID_WINBOND) 2530 return 1; /* Generic match */ 2531 else 2532 return 0; 2533 } 2534 DPRINTF(("%s: chipid %02x, sioid = %04x\n", __func__, chipid, 2535 sc->sioid)); 2536 2537 return 10; /* found */ 2538 } 2539 2540 static int 2541 wb_attach(struct lm_softc *sc) 2542 { 2543 device_t dev = sc->sc_dev; 2544 const struct wb_product *prod; 2545 const char *model = NULL; 2546 const char *vendor = "Winbond"; 2547 const struct lm_sensor *sensors; 2548 uint16_t vendid; 2549 uint8_t banksel; 2550 int cf_flags; 2551 2552 aprint_naive("\n"); 2553 aprint_normal("\n"); 2554 /* Read device/chip ID */ 2555 sc->chipid = wb_read_chipid(sc); 2556 DPRINTF(("%s: winbond chip id 0x%x\n", __func__, sc->chipid)); 2557 2558 if ((prod = wb_lookup(sc, wb_products, sc->chipid)) != NULL) { 2559 switch (prod->str[0]) { 2560 case 'W': 2561 vendor = "Winbond"; 2562 break; 2563 case 'A': 2564 vendor = "ASUS"; 2565 break; 2566 case 'N': 2567 vendor = "Nuvoton"; 2568 break; 2569 default: 2570 aprint_error_dev(dev, "Unknown model (%s)\n", model); 2571 return -1; 2572 } 2573 model = prod->str; 2574 sensors = prod->sensors; 2575 sc->refresh_sensor_data = wb_refresh_sensor_data; 2576 if (prod->extattach != NULL) 2577 prod->extattach(sc); 2578 } else { 2579 vendid = wb_read_vendorid(sc); 2580 if (vendid == WB_VENDID_WINBOND) { 2581 vendor = "Winbond"; 2582 model = "unknown-model"; 2583 2584 /* Handle as a standard LM78. */ 2585 sensors = lm78_sensors; 2586 sc->refresh_sensor_data = lm_refresh_sensor_data; 2587 } else { 2588 aprint_error_dev(dev, "Unknown chip (ID %02x)\n", 2589 sc->chipid); 2590 return -1; 2591 } 2592 } 2593 2594 cf_flags = device_cfdata(dev)->cf_flags; 2595 2596 if (sensors != NULL) { 2597 lm_setup_sensors(sc, sensors); 2598 2599 /* XXX Is this correct? Check all datasheets. */ 2600 switch (sc->chipid) { 2601 case WB_CHIPID_W83627EHF_A: 2602 case WB_CHIPID_W83781D: 2603 case WB_CHIPID_W83781D_2: 2604 case WB_CHIPID_W83791SD: 2605 case WB_CHIPID_W83792D: 2606 case WB_CHIPID_AS99127F: 2607 break; 2608 default: 2609 wb_temp_diode_type(sc, cf_flags); 2610 break; 2611 } 2612 } 2613 2614 /* XXX Is this correct? Check all datasheets. */ 2615 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2616 switch(sc->chipid) { 2617 case WB_CHIPID_W83627THF: 2618 lm_generic_banksel(sc, WB_BANKSEL_B0); 2619 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9) 2620 sc->vrm9 = 1; 2621 lm_generic_banksel(sc, banksel); 2622 break; 2623 case WB_CHIPID_W83637HF: 2624 lm_generic_banksel(sc, WB_BANKSEL_B0); 2625 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9) 2626 sc->vrm9 = 1; 2627 lm_generic_banksel(sc, banksel); 2628 break; 2629 default: 2630 break; 2631 } 2632 2633 aprint_normal_dev(dev, "%s %s Hardware monitor\n", vendor, model); 2634 2635 return 0; 2636 } 2637 2638 static void 2639 lm_setup_sensors(struct lm_softc *sc, const struct lm_sensor *sensors) 2640 { 2641 int i; 2642 2643 for (i = 0; sensors[i].desc; i++) { 2644 sc->sensors[i].units = sensors[i].type; 2645 if (sc->sensors[i].units == ENVSYS_SVOLTS_DC) 2646 sc->sensors[i].flags = ENVSYS_FCHANGERFACT; 2647 strlcpy(sc->sensors[i].desc, sensors[i].desc, 2648 sizeof(sc->sensors[i].desc)); 2649 sc->numsensors++; 2650 } 2651 sc->lm_sensors = sensors; 2652 } 2653 2654 static void 2655 lm_refresh_sensor_data(struct lm_softc *sc) 2656 { 2657 int i; 2658 2659 for (i = 0; i < sc->numsensors; i++) 2660 sc->lm_sensors[i].refresh(sc, i); 2661 } 2662 2663 static void 2664 lm_refresh_volt(struct lm_softc *sc, int n) 2665 { 2666 int data; 2667 2668 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2669 if (data == 0xff) { 2670 sc->sensors[n].state = ENVSYS_SINVALID; 2671 } else { 2672 sc->sensors[n].value_cur = (data << 4); 2673 if (sc->sensors[n].rfact) { 2674 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2675 sc->sensors[n].value_cur /= 10; 2676 } else { 2677 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact; 2678 sc->sensors[n].value_cur /= 10; 2679 sc->sensors[n].rfact = sc->lm_sensors[n].rfact; 2680 } 2681 sc->sensors[n].state = ENVSYS_SVALID; 2682 } 2683 2684 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2685 __func__, n, data, sc->sensors[n].value_cur)); 2686 } 2687 2688 static void 2689 lm_refresh_temp(struct lm_softc *sc, int n) 2690 { 2691 int data; 2692 2693 /* 2694 * The data sheet suggests that the range of the temperature 2695 * sensor is between -55 degC and +125 degC. 2696 */ 2697 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2698 if (data > 0x7d && data < 0xc9) 2699 sc->sensors[n].state = ENVSYS_SINVALID; 2700 else { 2701 if (data & 0x80) 2702 data -= 0x100; 2703 sc->sensors[n].state = ENVSYS_SVALID; 2704 sc->sensors[n].value_cur = data * 1000000 + 273150000; 2705 } 2706 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2707 __func__, n, data, sc->sensors[n].value_cur)); 2708 } 2709 2710 static void 2711 lm_refresh_fanrpm(struct lm_softc *sc, int n) 2712 { 2713 int data, divisor = 1; 2714 2715 /* 2716 * We might get more accurate fan readings by adjusting the 2717 * divisor, but that might interfere with APM or other SMM 2718 * BIOS code reading the fan speeds. 2719 */ 2720 2721 /* FAN3 has a fixed fan divisor. */ 2722 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2723 sc->lm_sensors[n].reg == LMD_FAN2) { 2724 data = (*sc->lm_readreg)(sc, LMD_VIDFAN); 2725 if (sc->lm_sensors[n].reg == LMD_FAN1) 2726 divisor = (data >> 4) & 0x03; 2727 else 2728 divisor = (data >> 6) & 0x03; 2729 } 2730 2731 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2732 if (data == 0xff || data == 0x00) 2733 sc->sensors[n].state = ENVSYS_SINVALID; 2734 else { 2735 sc->sensors[n].state = ENVSYS_SVALID; 2736 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2737 } 2738 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2739 __func__, n, data, sc->sensors[n].value_cur)); 2740 } 2741 2742 static void 2743 wb_refresh_sensor_data(struct lm_softc *sc) 2744 { 2745 uint8_t banksel, bank; 2746 int i; 2747 2748 /* 2749 * Properly save and restore bank selection register. 2750 */ 2751 banksel = bank = sc->lm_readreg(sc, WB_BANKSEL); 2752 for (i = 0; i < sc->numsensors; i++) { 2753 if (bank != sc->lm_sensors[i].bank) { 2754 bank = sc->lm_sensors[i].bank; 2755 lm_generic_banksel(sc, bank); 2756 } 2757 sc->lm_sensors[i].refresh(sc, i); 2758 } 2759 lm_generic_banksel(sc, banksel); 2760 } 2761 2762 static void 2763 wb_w83637hf_refresh_vcore(struct lm_softc *sc, int n) 2764 { 2765 int data; 2766 2767 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2768 /* 2769 * Depending on the voltage detection method, 2770 * one of the following formulas is used: 2771 * VRM8 method: value = raw * 0.016V 2772 * VRM9 method: value = raw * 0.00488V + 0.70V 2773 */ 2774 if (sc->vrm9) 2775 sc->sensors[n].value_cur = (data * 4880) + 700000; 2776 else 2777 sc->sensors[n].value_cur = (data * 16000); 2778 sc->sensors[n].state = ENVSYS_SVALID; 2779 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2780 __func__, n, data, sc->sensors[n].value_cur)); 2781 } 2782 2783 static void 2784 wb_refresh_nvolt(struct lm_softc *sc, int n) 2785 { 2786 int data; 2787 2788 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2789 sc->sensors[n].value_cur = ((data << 4) - WB_VREF); 2790 if (sc->sensors[n].rfact) 2791 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2792 else 2793 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact; 2794 2795 sc->sensors[n].value_cur /= 10; 2796 sc->sensors[n].value_cur += WB_VREF * 1000; 2797 sc->sensors[n].state = ENVSYS_SVALID; 2798 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2799 __func__, n , data, sc->sensors[n].value_cur)); 2800 } 2801 2802 static void 2803 wb_w83627ehf_refresh_nvolt(struct lm_softc *sc, int n) 2804 { 2805 int data; 2806 2807 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2808 sc->sensors[n].value_cur = ((data << 3) - WB_W83627EHF_VREF); 2809 if (sc->sensors[n].rfact) 2810 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2811 else 2812 sc->sensors[n].value_cur *= RFACT(232, 10); 2813 2814 sc->sensors[n].value_cur /= 10; 2815 sc->sensors[n].value_cur += WB_W83627EHF_VREF * 1000; 2816 sc->sensors[n].state = ENVSYS_SVALID; 2817 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2818 __func__, n , data, sc->sensors[n].value_cur)); 2819 } 2820 2821 static void 2822 wb_refresh_temp(struct lm_softc *sc, int n) 2823 { 2824 int data; 2825 2826 /* 2827 * The data sheet suggests that the range of the temperature 2828 * sensor is between -55 degC and +125 degC. However, values 2829 * around -48 degC seem to be a very common bogus values. 2830 * Since such values are unreasonably low, we use -45 degC for 2831 * the lower limit instead. 2832 */ 2833 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1; 2834 data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7; 2835 if (data > 0xfffffff || (data > 0x0fa && data < 0x1a6)) { 2836 sc->sensors[n].state = ENVSYS_SINVALID; 2837 } else { 2838 if (data & 0x100) 2839 data -= 0x200; 2840 sc->sensors[n].state = ENVSYS_SVALID; 2841 sc->sensors[n].value_cur = data * 500000 + 273150000; 2842 } 2843 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2844 __func__, n , data, sc->sensors[n].value_cur)); 2845 } 2846 2847 static void 2848 wb_refresh_fanrpm(struct lm_softc *sc, int n) 2849 { 2850 int fan, data, divisor = 0; 2851 2852 /* 2853 * This is madness; the fan divisor bits are scattered all 2854 * over the place. 2855 */ 2856 2857 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2858 sc->lm_sensors[n].reg == LMD_FAN2 || 2859 sc->lm_sensors[n].reg == LMD_FAN3) { 2860 data = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2861 fan = (sc->lm_sensors[n].reg - LMD_FAN1); 2862 if ((data >> 5) & (1 << fan)) 2863 divisor |= 0x04; 2864 } 2865 2866 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2867 sc->lm_sensors[n].reg == LMD_FAN2) { 2868 data = (*sc->lm_readreg)(sc, LMD_VIDFAN); 2869 if (sc->lm_sensors[n].reg == LMD_FAN1) 2870 divisor |= (data >> 4) & 0x03; 2871 else 2872 divisor |= (data >> 6) & 0x03; 2873 } else if (sc->lm_sensors[n].reg == LMD_FAN3) { 2874 data = (*sc->lm_readreg)(sc, WB_PIN); 2875 divisor |= (data >> 6) & 0x03; 2876 } else if (sc->lm_sensors[n].reg == WB_BANK0_FAN4 || 2877 sc->lm_sensors[n].reg == WB_BANK0_FAN5) { 2878 data = (*sc->lm_readreg)(sc, WB_BANK0_FAN45); 2879 if (sc->lm_sensors[n].reg == WB_BANK0_FAN4) 2880 divisor |= (data >> 0) & 0x07; 2881 else 2882 divisor |= (data >> 4) & 0x07; 2883 } 2884 2885 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2886 if (data >= 0xff || data == 0x00) 2887 sc->sensors[n].state = ENVSYS_SINVALID; 2888 else { 2889 sc->sensors[n].state = ENVSYS_SVALID; 2890 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2891 } 2892 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2893 __func__, n , data, sc->sensors[n].value_cur)); 2894 } 2895 2896 static void 2897 wb_nct6776f_refresh_fanrpm(struct lm_softc *sc, int n) 2898 { 2899 int datah, datal; 2900 2901 datah = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2902 datal = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1); 2903 2904 if ((datah == 0xff) || (datah == 0)) { 2905 sc->sensors[n].state = ENVSYS_SINVALID; 2906 } else { 2907 sc->sensors[n].state = ENVSYS_SVALID; 2908 sc->sensors[n].value_cur = (datah << 8) | datal; 2909 } 2910 } 2911 2912 static void 2913 wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n) 2914 { 2915 int shift, data, divisor = 1; 2916 uint8_t reg; 2917 2918 shift = 0; 2919 2920 switch (sc->lm_sensors[n].reg) { 2921 case 0x28: 2922 reg = 0x47; shift = 0; 2923 break; 2924 case 0x29: 2925 reg = 0x47; shift = 4; 2926 break; 2927 case 0x2a: 2928 reg = 0x5b; shift = 0; 2929 break; 2930 case 0xb8: 2931 reg = 0x5b; shift = 4; 2932 break; 2933 case 0xb9: 2934 reg = 0x5c; shift = 0; 2935 break; 2936 case 0xba: 2937 reg = 0x5c; shift = 4; 2938 break; 2939 case 0xbe: 2940 reg = 0x9e; shift = 0; 2941 break; 2942 default: 2943 reg = 0; 2944 break; 2945 } 2946 2947 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2948 if (data == 0xff || data == 0x00) 2949 sc->sensors[n].state = ENVSYS_SINVALID; 2950 else { 2951 if (reg != 0) 2952 divisor = ((*sc->lm_readreg)(sc, reg) >> shift) & 0x7; 2953 sc->sensors[n].state = ENVSYS_SVALID; 2954 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2955 } 2956 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2957 __func__, n , data, sc->sensors[n].value_cur)); 2958 } 2959 2960 static void 2961 as_refresh_temp(struct lm_softc *sc, int n) 2962 { 2963 int data; 2964 2965 /* 2966 * It seems a shorted temperature diode produces an all-ones 2967 * bit pattern. 2968 */ 2969 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1; 2970 data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7; 2971 if (data == 0x1ff) 2972 sc->sensors[n].state = ENVSYS_SINVALID; 2973 else { 2974 if (data & 0x100) 2975 data -= 0x200; 2976 sc->sensors[n].state = ENVSYS_SVALID; 2977 sc->sensors[n].value_cur = data * 500000 + 273150000; 2978 } 2979 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2980 __func__, n, data, sc->sensors[n].value_cur)); 2981 } 2982 2983 MODULE(MODULE_CLASS_DRIVER, lm, "sysmon_envsys"); 2984 2985 static int 2986 lm_modcmd(modcmd_t cmd, void *opaque) 2987 { 2988 switch (cmd) { 2989 case MODULE_CMD_INIT: 2990 case MODULE_CMD_FINI: 2991 return 0; 2992 default: 2993 return ENOTTY; 2994 } 2995 } 2996