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