1 /* $NetBSD: nslm7x.c,v 1.47 2008/04/28 20:23:50 martin 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.47 2008/04/28 20:23:50 martin 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/conf.h> 41 #include <sys/time.h> 42 43 #include <sys/bus.h> 44 45 #include <dev/isa/isareg.h> 46 #include <dev/isa/isavar.h> 47 48 #include <dev/sysmon/sysmonvar.h> 49 50 #include <dev/ic/nslm7xvar.h> 51 52 #include <sys/intr.h> 53 54 #if defined(LMDEBUG) 55 #define DPRINTF(x) do { printf x; } while (0) 56 #else 57 #define DPRINTF(x) 58 #endif 59 60 /* 61 * LM78-compatible chips can typically measure voltages up to 4.096 V. 62 * To measure higher voltages the input is attenuated with (external) 63 * resistors. Negative voltages are measured using inverting op amps 64 * and resistors. So we have to convert the sensor values back to 65 * real voltages by applying the appropriate resistor factor. 66 */ 67 #define RFACT_NONE 10000 68 #define RFACT(x, y) (RFACT_NONE * ((x) + (y)) / (y)) 69 #define NRFACT(x, y) (-RFACT_NONE * (x) / (y)) 70 71 #define LM_REFRESH_TIMO (2 * hz) /* 2 seconds */ 72 73 static int lm_match(struct lm_softc *); 74 static int wb_match(struct lm_softc *); 75 static int def_match(struct lm_softc *); 76 77 static void lm_refresh(void *); 78 79 static void lm_generic_banksel(struct lm_softc *, int); 80 static void lm_setup_sensors(struct lm_softc *, struct lm_sensor *); 81 static void lm_refresh_sensor_data(struct lm_softc *); 82 static void lm_refresh_volt(struct lm_softc *, int); 83 static void lm_refresh_temp(struct lm_softc *, int); 84 static void lm_refresh_fanrpm(struct lm_softc *, int); 85 86 static void wb_refresh_sensor_data(struct lm_softc *); 87 static void wb_w83637hf_refresh_vcore(struct lm_softc *, int); 88 static void wb_refresh_nvolt(struct lm_softc *, int); 89 static void wb_w83627ehf_refresh_nvolt(struct lm_softc *, int); 90 static void wb_refresh_temp(struct lm_softc *, int); 91 static void wb_refresh_fanrpm(struct lm_softc *, int); 92 static void wb_w83792d_refresh_fanrpm(struct lm_softc *, int); 93 94 static void as_refresh_temp(struct lm_softc *, int); 95 96 struct lm_chip { 97 int (*chip_match)(struct lm_softc *); 98 }; 99 100 static struct lm_chip lm_chips[] = { 101 { wb_match }, 102 { lm_match }, 103 { def_match } /* Must be last */ 104 }; 105 106 /* LM78/78J/79/81 */ 107 static struct lm_sensor lm78_sensors[] = { 108 /* Voltage */ 109 { 110 .desc = "VCore A", 111 .type = ENVSYS_SVOLTS_DC, 112 .bank = 0, 113 .reg = 0x20, 114 .refresh = lm_refresh_volt, 115 .rfact = RFACT_NONE 116 }, 117 { 118 .desc = "VCore B", 119 .type = ENVSYS_SVOLTS_DC, 120 .bank = 0, 121 .reg = 0x21, 122 .refresh = lm_refresh_volt, 123 .rfact = RFACT_NONE 124 }, 125 { 126 .desc = "+3.3V", 127 .type = ENVSYS_SVOLTS_DC, 128 .bank = 0, 129 .reg = 0x22, 130 .refresh = lm_refresh_volt, 131 .rfact = RFACT_NONE 132 }, 133 { 134 .desc = "+5V", 135 .type = ENVSYS_SVOLTS_DC, 136 .bank = 0, 137 .reg = 0x23, 138 .refresh = lm_refresh_volt, 139 .rfact = RFACT(68, 100) 140 }, 141 { 142 .desc = "+12V", 143 .type = ENVSYS_SVOLTS_DC, 144 .bank = 0, 145 .reg = 0x24, 146 .refresh = lm_refresh_volt, 147 .rfact = RFACT(30, 10) 148 }, 149 { 150 .desc = "-12V", 151 .type = ENVSYS_SVOLTS_DC, 152 .bank = 0, 153 .reg = 0x25, 154 .refresh = lm_refresh_volt, 155 .rfact = NRFACT(240, 60) 156 }, 157 { 158 .desc = "-5V", 159 .type = ENVSYS_SVOLTS_DC, 160 .bank = 0, 161 .reg = 0x26, 162 .refresh = lm_refresh_volt, 163 .rfact = NRFACT(100, 60) 164 }, 165 166 /* Temperature */ 167 { 168 .desc = "Temp0", 169 .type = ENVSYS_STEMP, 170 .bank = 0, 171 .reg = 0x27, 172 .refresh = lm_refresh_temp, 173 .rfact = 0 174 }, 175 176 /* Fans */ 177 { 178 .desc = "Fan0", 179 .type = ENVSYS_SFANRPM, 180 .bank = 0, 181 .reg = 0x28, 182 .refresh = lm_refresh_fanrpm, 183 .rfact = 0 184 }, 185 { 186 .desc = "Fan1", 187 .type = ENVSYS_SFANRPM, 188 .bank = 0, 189 .reg = 0x29, 190 .refresh = lm_refresh_fanrpm, 191 .rfact = 0 192 }, 193 { 194 .desc = "Fan2", 195 .type = ENVSYS_SFANRPM, 196 .bank = 0, 197 .reg = 0x2a, 198 .refresh = lm_refresh_fanrpm, 199 .rfact = 0 200 }, 201 202 { .desc = NULL } 203 }; 204 205 /* W83627HF */ 206 static struct lm_sensor w83627hf_sensors[] = { 207 /* Voltage */ 208 { 209 .desc = "VCore A", 210 .type = ENVSYS_SVOLTS_DC, 211 .bank = 0, 212 .reg = 0x20, 213 .refresh = lm_refresh_volt, 214 .rfact = RFACT_NONE 215 }, 216 { 217 .desc = "VCore B", 218 .type = ENVSYS_SVOLTS_DC, 219 .bank = 0, 220 .reg = 0x21, 221 .refresh = lm_refresh_volt, 222 .rfact = RFACT_NONE 223 }, 224 { 225 .desc = "+3.3V", 226 .type = ENVSYS_SVOLTS_DC, 227 .bank = 0, 228 .reg = 0x22, 229 .refresh = lm_refresh_volt, 230 .rfact = RFACT_NONE 231 }, 232 { 233 .desc = "+5V", 234 .type = ENVSYS_SVOLTS_DC, 235 .bank = 0, 236 .reg = 0x23, 237 .refresh = lm_refresh_volt, 238 .rfact = RFACT(34, 50) 239 }, 240 { 241 .desc = "+12V", 242 .type = ENVSYS_SVOLTS_DC, 243 .bank = 0, 244 .reg = 0x24, 245 .refresh = lm_refresh_volt, 246 .rfact = RFACT(28, 10) 247 }, 248 { 249 .desc = "-12V", 250 .type = ENVSYS_SVOLTS_DC, 251 .bank = 0, 252 .reg = 0x25, 253 .refresh = wb_refresh_nvolt, 254 .rfact = RFACT(232, 56) 255 }, 256 { 257 .desc = "-5V", 258 .type = ENVSYS_SVOLTS_DC, 259 .bank = 0, 260 .reg = 0x26, 261 .refresh = wb_refresh_nvolt, 262 .rfact = RFACT(120, 56) 263 }, 264 { 265 .desc = "5VSB", 266 .type = ENVSYS_SVOLTS_DC, 267 .bank = 5, 268 .reg = 0x50, 269 .refresh = lm_refresh_volt, 270 .rfact = RFACT(17, 33) 271 }, 272 { 273 .desc = "VBAT", 274 .type = ENVSYS_SVOLTS_DC, 275 .bank = 5, 276 .reg = 0x51, 277 .refresh = lm_refresh_volt, 278 .rfact = RFACT_NONE 279 }, 280 281 /* Temperature */ 282 { 283 .desc = "Temp0", 284 .type = ENVSYS_STEMP, 285 .bank = 0, 286 .reg = 0x27, 287 .refresh = lm_refresh_temp, 288 .rfact = 0 289 }, 290 { 291 .desc = "Temp1", 292 .type = ENVSYS_STEMP, 293 .bank = 1, 294 .reg = 0x50, 295 .refresh = wb_refresh_temp, 296 .rfact = 0 297 }, 298 { 299 .desc = "Temp2", 300 .type = ENVSYS_STEMP, 301 .bank = 2, 302 .reg = 0x50, 303 .refresh = wb_refresh_temp, 304 .rfact = 0 305 }, 306 307 /* Fans */ 308 { 309 .desc = "Fan0", 310 .type = ENVSYS_SFANRPM, 311 .bank = 0, 312 .reg = 0x28, 313 .refresh = wb_refresh_fanrpm, 314 .rfact = 0 315 }, 316 { 317 .desc = "Fan1", 318 .type = ENVSYS_SFANRPM, 319 .bank = 0, 320 .reg = 0x29, 321 .refresh = wb_refresh_fanrpm, 322 .rfact = 0 323 }, 324 { 325 .desc = "Fan2", 326 .type = ENVSYS_SFANRPM, 327 .bank = 0, 328 .reg = 0x2a, 329 .refresh = wb_refresh_fanrpm, 330 .rfact = 0 331 }, 332 333 { .desc = NULL } 334 }; 335 336 /* W8627EHF */ 337 338 /* 339 * The W83627EHF can measure voltages up to 2.048 V instead of the 340 * traditional 4.096 V. For measuring positive voltages, this can be 341 * accounted for by halving the resistor factor. Negative voltages 342 * need special treatment, also because the reference voltage is 2.048 V 343 * instead of the traditional 3.6 V. 344 */ 345 static struct lm_sensor w83627ehf_sensors[] = { 346 /* Voltage */ 347 { 348 .desc = "VCore", 349 .type = ENVSYS_SVOLTS_DC, 350 .bank = 0, 351 .reg = 0x20, 352 .refresh = lm_refresh_volt, 353 .rfact = RFACT_NONE / 2 354 }, 355 { 356 .desc = "+12V", 357 .type = ENVSYS_SVOLTS_DC, 358 .bank = 0, 359 .reg = 0x21, 360 .refresh = lm_refresh_volt, 361 .rfact = RFACT(56, 10) / 2 362 }, 363 { 364 .desc = "+3.3V", 365 .type = ENVSYS_SVOLTS_DC, 366 .bank = 0, 367 .reg = 0x22, 368 .refresh = lm_refresh_volt, 369 .rfact = RFACT(34, 34) / 2 370 }, 371 { 372 .desc = "VIN3", 373 .type = ENVSYS_SVOLTS_DC, 374 .bank = 0, 375 .reg = 0x23, 376 .refresh = lm_refresh_volt, 377 .rfact = RFACT(34, 34) / 2 378 }, 379 { 380 .desc = "-12V", 381 .type = ENVSYS_SVOLTS_DC, 382 .bank = 0, 383 .reg = 0x24, 384 .refresh = wb_w83627ehf_refresh_nvolt, 385 .rfact = 0 386 }, 387 { 388 .desc = "VIN5", 389 .type = ENVSYS_SVOLTS_DC, 390 .bank = 0, 391 .reg = 0x25, 392 .refresh = lm_refresh_volt, 393 .rfact = RFACT_NONE / 2 394 }, 395 { 396 .desc = "VIN6", 397 .type = ENVSYS_SVOLTS_DC, 398 .bank = 0, 399 .reg = 0x26, 400 .refresh = lm_refresh_volt, 401 .rfact = RFACT_NONE / 2 402 }, 403 { 404 .desc = "3.3VSB", 405 .type = ENVSYS_SVOLTS_DC, 406 .bank = 5, 407 .reg = 0x50, 408 .refresh = lm_refresh_volt, 409 .rfact = RFACT(34, 34) / 2 410 }, 411 { 412 .desc = "VBAT", 413 .type = ENVSYS_SVOLTS_DC, 414 .bank = 5, 415 .reg = 0x51, 416 .refresh = lm_refresh_volt, 417 .rfact = RFACT_NONE / 2 418 }, 419 { 420 .desc = "VIN8", 421 .type = ENVSYS_SVOLTS_DC, 422 .bank = 5, 423 .reg = 0x52, 424 .refresh = lm_refresh_volt, 425 .rfact = RFACT_NONE / 2 426 }, 427 428 /* Temperature */ 429 { 430 .desc = "Temp0", 431 .type = ENVSYS_STEMP, 432 .bank = 0, 433 .reg = 0x27, 434 .refresh = lm_refresh_temp, 435 .rfact = 0 436 }, 437 { 438 .desc = "Temp1", 439 .type = ENVSYS_STEMP, 440 .bank = 1, 441 .reg = 0x50, 442 .refresh = wb_refresh_temp, 443 .rfact = 0 444 }, 445 { 446 .desc = "Temp2", 447 .type = ENVSYS_STEMP, 448 .bank = 2, 449 .reg = 0x50, 450 .refresh = wb_refresh_temp, 451 .rfact = 0 452 }, 453 454 /* Fans */ 455 { 456 .desc = "Fan0", 457 .type = ENVSYS_SFANRPM, 458 .bank = 0, 459 .reg = 0x28, 460 .refresh = wb_refresh_fanrpm, 461 .rfact = 0 462 }, 463 { 464 .desc = "Fan1", 465 .type = ENVSYS_SFANRPM, 466 .bank = 0, 467 .reg = 0x29, 468 .refresh = wb_refresh_fanrpm, 469 .rfact = 0 470 }, 471 { 472 .desc = "Fan2", 473 .type = ENVSYS_SFANRPM, 474 .bank = 0, 475 .reg = 0x2a, 476 .refresh = wb_refresh_fanrpm, 477 .rfact = 0 478 }, 479 480 { .desc = NULL } 481 }; 482 483 /* W83627DHG */ 484 static struct lm_sensor w83627dhg_sensors[] = { 485 /* Voltage */ 486 { 487 .desc = "VCore", 488 .type = ENVSYS_SVOLTS_DC, 489 .bank = 0, 490 .reg = 0x20, 491 .refresh = lm_refresh_volt, 492 .rfact = RFACT_NONE / 2 493 }, 494 { 495 .desc = "+12V", 496 .type = ENVSYS_SVOLTS_DC, 497 .bank = 0, 498 .reg = 0x21, 499 .refresh = lm_refresh_volt, 500 .rfact = RFACT(56, 10) / 2 501 }, 502 { 503 .desc = "AVCC", 504 .type = ENVSYS_SVOLTS_DC, 505 .bank = 0, 506 .reg = 0x22, 507 .refresh = lm_refresh_volt, 508 .rfact = RFACT(34, 34) / 2 509 }, 510 { 511 .desc = "+3.3V", 512 .type = ENVSYS_SVOLTS_DC, 513 .bank = 0, 514 .reg = 0x23, 515 .refresh = lm_refresh_volt, 516 .rfact = RFACT(34, 34) / 2 517 }, 518 { 519 .desc = "-12V", 520 .type = ENVSYS_SVOLTS_DC, 521 .bank = 0, 522 .reg = 0x24, 523 .refresh = wb_w83627ehf_refresh_nvolt, 524 .rfact = 0 525 }, 526 { 527 .desc = "+5V", 528 .type = ENVSYS_SVOLTS_DC, 529 .bank = 0, 530 .reg = 0x25, 531 .refresh = lm_refresh_volt, 532 .rfact = 16000 533 }, 534 { 535 .desc = "VIN3", 536 .type = ENVSYS_SVOLTS_DC, 537 .bank = 0, 538 .reg = 0x26, 539 .refresh = lm_refresh_volt, 540 .rfact = RFACT_NONE 541 }, 542 { 543 .desc = "+3.3VSB", 544 .type = ENVSYS_SVOLTS_DC, 545 .bank = 5, 546 .reg = 0x50, 547 .refresh = lm_refresh_volt, 548 .rfact = RFACT(34, 34) / 2 549 }, 550 { 551 .desc = "VBAT", 552 .type = ENVSYS_SVOLTS_DC, 553 .bank = 5, 554 .reg = 0x51, 555 .refresh = lm_refresh_volt, 556 .rfact = RFACT(34, 34) / 2 557 }, 558 559 /* Temperature */ 560 { 561 .desc = "MB Temperature", 562 .type = ENVSYS_STEMP, 563 .bank = 0, 564 .reg = 0x27, 565 .refresh = lm_refresh_temp, 566 .rfact = 0 567 }, 568 { 569 .desc = "CPU Temperature", 570 .type = ENVSYS_STEMP, 571 .bank = 1, 572 .reg = 0x50, 573 .refresh = lm_refresh_temp, 574 .rfact = 0 575 }, 576 { 577 .desc = "Aux Temp", 578 .type = ENVSYS_STEMP, 579 .bank = 2, 580 .reg = 0x50, 581 .refresh = lm_refresh_temp, 582 .rfact = 0 583 }, 584 585 /* Fans */ 586 { 587 .desc = "System Fan", 588 .type = ENVSYS_SFANRPM, 589 .bank = 0, 590 .reg = 0x28, 591 .refresh = wb_refresh_fanrpm, 592 .rfact = 0 593 }, 594 { 595 .desc = "CPU Fan", 596 .type = ENVSYS_SFANRPM, 597 .bank = 0, 598 .reg = 0x29, 599 .refresh = wb_refresh_fanrpm, 600 .rfact = 0 601 }, 602 { 603 .desc = "Aux Fan", 604 .type = ENVSYS_SFANRPM, 605 .bank = 0, 606 .reg = 0x2a, 607 .refresh = wb_refresh_fanrpm, 608 .rfact = 0 609 }, 610 611 { .desc = NULL } 612 }; 613 614 /* W83637HF */ 615 static struct lm_sensor w83637hf_sensors[] = { 616 /* Voltage */ 617 { 618 .desc = "VCore", 619 .type = ENVSYS_SVOLTS_DC, 620 .bank = 0, 621 .reg = 0x20, 622 .refresh = wb_w83637hf_refresh_vcore, 623 .rfact = 0 624 }, 625 { 626 .desc = "+12V", 627 .type = ENVSYS_SVOLTS_DC, 628 .bank = 0, 629 .reg = 0x21, 630 .refresh = lm_refresh_volt, 631 .rfact = RFACT(28, 10) 632 }, 633 { 634 .desc = "+3.3V", 635 .type = ENVSYS_SVOLTS_DC, 636 .bank = 0, 637 .reg = 0x22, 638 .refresh = lm_refresh_volt, 639 .rfact = RFACT_NONE 640 }, 641 { 642 .desc = "+5V", 643 .type = ENVSYS_SVOLTS_DC, 644 .bank = 0, 645 .reg = 0x23, 646 .refresh = lm_refresh_volt, 647 .rfact = RFACT(34, 51) 648 }, 649 { 650 .desc = "-12V", 651 .type = ENVSYS_SVOLTS_DC, 652 .bank = 0, 653 .reg = 0x24, 654 .refresh = wb_refresh_nvolt, 655 .rfact = RFACT(232, 56) 656 }, 657 { 658 .desc = "5VSB", 659 .type = ENVSYS_SVOLTS_DC, 660 .bank = 5, 661 .reg = 0x50, 662 .refresh = lm_refresh_volt, 663 .rfact = RFACT(34, 51) 664 }, 665 { 666 .desc = "VBAT", 667 .type = ENVSYS_SVOLTS_DC, 668 .bank = 5, 669 .reg = 0x51, 670 .refresh = lm_refresh_volt, 671 .rfact = RFACT_NONE 672 }, 673 674 /* Temperature */ 675 { 676 .desc = "Temp0", 677 .type = ENVSYS_STEMP, 678 .bank = 0, 679 .reg = 0x27, 680 .refresh = lm_refresh_temp, 681 .rfact = 0 682 }, 683 { 684 .desc = "Temp1", 685 .type = ENVSYS_STEMP, 686 .bank = 1, 687 .reg = 0x50, 688 .refresh = wb_refresh_temp, 689 .rfact = 0 690 }, 691 { 692 .desc = "Temp2", 693 .type = ENVSYS_STEMP, 694 .bank = 2, 695 .reg = 0x50, 696 .refresh = wb_refresh_temp, 697 .rfact = 0 698 }, 699 700 /* Fans */ 701 { 702 .desc = "Fan0", 703 .type = ENVSYS_SFANRPM, 704 .bank = 0, 705 .reg = 0x28, 706 .refresh = wb_refresh_fanrpm, 707 .rfact = 0 708 }, 709 { 710 .desc = "Fan1", 711 .type = ENVSYS_SFANRPM, 712 .bank = 0, 713 .reg = 0x29, 714 .refresh = wb_refresh_fanrpm, 715 .rfact = 0 716 }, 717 { 718 .desc = "Fan2", 719 .type = ENVSYS_SFANRPM, 720 .bank = 0, 721 .reg = 0x2a, 722 .refresh = wb_refresh_fanrpm, 723 .rfact = 0 724 }, 725 726 { .desc = NULL } 727 }; 728 729 /* W83697HF */ 730 static struct lm_sensor w83697hf_sensors[] = { 731 /* Voltage */ 732 { 733 .desc = "VCore", 734 .type = ENVSYS_SVOLTS_DC, 735 .bank = 0, 736 .reg = 0x20, 737 .refresh = lm_refresh_volt, 738 .rfact = RFACT_NONE 739 }, 740 { 741 .desc = "+3.3V", 742 .type = ENVSYS_SVOLTS_DC, 743 .bank = 0, 744 .reg = 0x22, 745 .refresh = lm_refresh_volt, 746 .rfact = RFACT_NONE 747 }, 748 { 749 .desc = "+5V", 750 .type = ENVSYS_SVOLTS_DC, 751 .bank = 0, 752 .reg = 0x23, 753 .refresh = lm_refresh_volt, 754 .rfact = RFACT(34, 50) 755 }, 756 { 757 .desc = "+12V", 758 .type = ENVSYS_SVOLTS_DC, 759 .bank = 0, 760 .reg = 0x24, 761 .refresh = lm_refresh_volt, 762 .rfact = RFACT(28, 10) 763 }, 764 { 765 .desc = "-12V", 766 .type = ENVSYS_SVOLTS_DC, 767 .bank = 0, 768 .reg = 0x25, 769 .refresh = wb_refresh_nvolt, 770 .rfact = RFACT(232, 56) 771 }, 772 { 773 .desc = "-5V", 774 .type = ENVSYS_SVOLTS_DC, 775 .bank = 0, 776 .reg = 0x26, 777 .refresh = wb_refresh_nvolt, 778 .rfact = RFACT(120, 56) 779 }, 780 { 781 .desc = "5VSB", 782 .type = ENVSYS_SVOLTS_DC, 783 .bank = 5, 784 .reg = 0x50, 785 .refresh = lm_refresh_volt, 786 .rfact = RFACT(17, 33) 787 }, 788 { 789 .desc = "VBAT", 790 .type = ENVSYS_SVOLTS_DC, 791 .bank = 5, 792 .reg = 0x51, 793 .refresh = lm_refresh_volt, 794 .rfact = RFACT_NONE 795 }, 796 797 /* Temperature */ 798 { 799 .desc = "Temp0", 800 .type = ENVSYS_STEMP, 801 .bank = 0, 802 .reg = 0x27, 803 .refresh = lm_refresh_temp, 804 .rfact = 0 805 }, 806 { 807 .desc = "Temp1", 808 .type = ENVSYS_STEMP, 809 .bank = 1, 810 .reg = 0x50, 811 .refresh = wb_refresh_temp, 812 .rfact = 0 813 }, 814 815 /* Fans */ 816 { 817 .desc = "Fan0", 818 .type = ENVSYS_SFANRPM, 819 .bank = 0, 820 .reg = 0x28, 821 .refresh = wb_refresh_fanrpm, 822 .rfact = 0 823 }, 824 { 825 .desc = "Fan1", 826 .type = ENVSYS_SFANRPM, 827 .bank = 0, 828 .reg = 0x29, 829 .refresh = wb_refresh_fanrpm, 830 .rfact = 0 831 }, 832 833 { .desc = NULL } 834 }; 835 836 /* W83781D */ 837 838 /* 839 * The datasheet doesn't mention the (internal) resistors used for the 840 * +5V, but using the values from the W83782D datasheets seems to 841 * provide sensible results. 842 */ 843 static struct lm_sensor w83781d_sensors[] = { 844 /* Voltage */ 845 { 846 .desc = "VCore A", 847 .type = ENVSYS_SVOLTS_DC, 848 .bank = 0, 849 .reg = 0x20, 850 .refresh = lm_refresh_volt, 851 .rfact = RFACT_NONE 852 }, 853 { 854 .desc = "VCore B", 855 .type = ENVSYS_SVOLTS_DC, 856 .bank = 0, 857 .reg = 0x21, 858 .refresh = lm_refresh_volt, 859 .rfact = RFACT_NONE 860 }, 861 { 862 .desc = "+3.3V", 863 .type = ENVSYS_SVOLTS_DC, 864 .bank = 0, 865 .reg = 0x22, 866 .refresh = lm_refresh_volt, 867 .rfact = RFACT_NONE 868 }, 869 { 870 .desc = "+5V", 871 .type = ENVSYS_SVOLTS_DC, 872 .bank = 0, 873 .reg = 0x23, 874 .refresh = lm_refresh_volt, 875 .rfact = RFACT(34, 50) 876 }, 877 { 878 .desc = "+12V", 879 .type = ENVSYS_SVOLTS_DC, 880 .bank = 0, 881 .reg = 0x24, 882 .refresh = lm_refresh_volt, 883 .rfact = RFACT(28, 10) 884 }, 885 { 886 .desc = "-12V", 887 .type = ENVSYS_SVOLTS_DC, 888 .bank = 0, 889 .reg = 0x25, 890 .refresh = lm_refresh_volt, 891 .rfact = NRFACT(2100, 604) 892 }, 893 { 894 .desc = "-5V", 895 .type = ENVSYS_SVOLTS_DC, 896 .bank = 0, 897 .reg = 0x26, 898 .refresh = lm_refresh_volt, 899 .rfact = NRFACT(909, 604) 900 }, 901 902 /* Temperature */ 903 { 904 .desc = "Temp0", 905 .type = ENVSYS_STEMP, 906 .bank = 0, 907 .reg = 0x27, 908 .refresh = lm_refresh_temp, 909 .rfact = 0 910 }, 911 { 912 .desc = "Temp1", 913 .type = ENVSYS_STEMP, 914 .bank = 1, 915 .reg = 0x50, 916 .refresh = wb_refresh_temp, 917 .rfact = 0 918 }, 919 { 920 .desc = "Temp2", 921 .type = ENVSYS_STEMP, 922 .bank = 2, 923 .reg = 0x50, 924 .refresh = wb_refresh_temp, 925 .rfact = 0 926 }, 927 928 /* Fans */ 929 { 930 .desc = "Fan0", 931 .type = ENVSYS_SFANRPM, 932 .bank = 0, 933 .reg = 0x28, 934 .refresh = lm_refresh_fanrpm, 935 .rfact = 0 936 }, 937 { 938 .desc = "Fan1", 939 .type = ENVSYS_SFANRPM, 940 .bank = 0, 941 .reg = 0x29, 942 .refresh = lm_refresh_fanrpm, 943 .rfact = 0 944 }, 945 { 946 .desc = "Fan2", 947 .type = ENVSYS_SFANRPM, 948 .bank = 0, 949 .reg = 0x2a, 950 .refresh = lm_refresh_fanrpm, 951 .rfact = 0 952 }, 953 954 { .desc = NULL } 955 }; 956 957 /* W83782D */ 958 static struct lm_sensor w83782d_sensors[] = { 959 /* Voltage */ 960 { 961 .desc = "VCore", 962 .type = ENVSYS_SVOLTS_DC, 963 .bank = 0, 964 .reg = 0x20, 965 .refresh = lm_refresh_volt, 966 .rfact = RFACT_NONE 967 }, 968 { 969 .desc = "VINR0", 970 .type = ENVSYS_SVOLTS_DC, 971 .bank = 0, 972 .reg = 0x21, 973 .refresh = lm_refresh_volt, 974 .rfact = RFACT_NONE 975 }, 976 { 977 .desc = "+3.3V", 978 .type = ENVSYS_SVOLTS_DC, 979 .bank = 0, 980 .reg = 0x22, 981 .refresh = lm_refresh_volt, 982 .rfact = RFACT_NONE 983 }, 984 { 985 .desc = "+5V", 986 .type = ENVSYS_SVOLTS_DC, 987 .bank = 0, 988 .reg = 0x23, 989 .refresh = lm_refresh_volt, 990 .rfact = RFACT(34, 50) 991 }, 992 { 993 .desc = "+12V", 994 .type = ENVSYS_SVOLTS_DC, 995 .bank = 0, 996 .reg = 0x24, 997 .refresh = lm_refresh_volt, 998 .rfact = RFACT(28, 10) 999 }, 1000 { 1001 .desc = "-12V", 1002 .type = ENVSYS_SVOLTS_DC, 1003 .bank = 0, 1004 .reg = 0x25, 1005 .refresh = wb_refresh_nvolt, 1006 .rfact = RFACT(232, 56) 1007 }, 1008 { 1009 .desc = "-5V", 1010 .type = ENVSYS_SVOLTS_DC, 1011 .bank = 0, 1012 .reg = 0x26, 1013 .refresh = wb_refresh_nvolt, 1014 .rfact = RFACT(120, 56) 1015 }, 1016 { 1017 .desc = "5VSB", 1018 .type = ENVSYS_SVOLTS_DC, 1019 .bank = 5, 1020 .reg = 0x50, 1021 .refresh = lm_refresh_volt, 1022 .rfact = RFACT(17, 33) 1023 }, 1024 { 1025 .desc = "VBAT", 1026 .type = ENVSYS_SVOLTS_DC, 1027 .bank = 5, 1028 .reg = 0x51, 1029 .refresh = lm_refresh_volt, 1030 .rfact = RFACT_NONE 1031 }, 1032 1033 /* Temperature */ 1034 { 1035 .desc = "Temp0", 1036 .type = ENVSYS_STEMP, 1037 .bank = 0, 1038 .reg = 0x27, 1039 .refresh = lm_refresh_temp, 1040 .rfact = 0 1041 }, 1042 { 1043 .desc = "Temp1", 1044 .type = ENVSYS_STEMP, 1045 .bank = 1, 1046 .reg = 0x50, 1047 .refresh = wb_refresh_temp, 1048 .rfact = 0 1049 }, 1050 { 1051 .desc = "Temp2", 1052 .type = ENVSYS_STEMP, 1053 .bank = 2, 1054 .reg = 0x50, 1055 .refresh = wb_refresh_temp, 1056 .rfact = 0 1057 }, 1058 1059 /* Fans */ 1060 { 1061 .desc = "Fan0", 1062 .type = ENVSYS_SFANRPM, 1063 .bank = 0, 1064 .reg = 0x28, 1065 .refresh = wb_refresh_fanrpm, 1066 .rfact = 0 1067 }, 1068 { 1069 .desc = "Fan1", 1070 .type = ENVSYS_SFANRPM, 1071 .bank = 0, 1072 .reg = 0x29, 1073 .refresh = wb_refresh_fanrpm, 1074 .rfact = 0 1075 }, 1076 { 1077 .desc = "Fan2", 1078 .type = ENVSYS_SFANRPM, 1079 .bank = 0, 1080 .reg = 0x2a, 1081 .refresh = wb_refresh_fanrpm, 1082 .rfact = 0 1083 }, 1084 1085 { .desc = NULL } 1086 }; 1087 1088 /* W83783S */ 1089 static struct lm_sensor w83783s_sensors[] = { 1090 /* Voltage */ 1091 { 1092 .desc = "VCore", 1093 .type = ENVSYS_SVOLTS_DC, 1094 .bank = 0, 1095 .reg = 0x20, 1096 .refresh = lm_refresh_volt, 1097 .rfact = RFACT_NONE 1098 }, 1099 { 1100 .desc = "+3.3V", 1101 .type = ENVSYS_SVOLTS_DC, 1102 .bank = 0, 1103 .reg = 0x22, 1104 .refresh = lm_refresh_volt, 1105 .rfact = RFACT_NONE 1106 }, 1107 { 1108 .desc = "+5V", 1109 .type = ENVSYS_SVOLTS_DC, 1110 .bank = 0, 1111 .reg = 0x23, 1112 .refresh = lm_refresh_volt, 1113 .rfact = RFACT(34, 50) 1114 }, 1115 { 1116 .desc = "+12V", 1117 .type = ENVSYS_SVOLTS_DC, 1118 .bank = 0, 1119 .reg = 0x24, 1120 .refresh = lm_refresh_volt, 1121 .rfact = RFACT(28, 10) 1122 }, 1123 { 1124 .desc = "-12V", 1125 .type = ENVSYS_SVOLTS_DC, 1126 .bank = 0, 1127 .reg = 0x25, 1128 .refresh = wb_refresh_nvolt, 1129 .rfact = RFACT(232, 56) 1130 }, 1131 { 1132 .desc = "-5V", 1133 .type = ENVSYS_SVOLTS_DC, 1134 .bank = 0, 1135 .reg = 0x26, 1136 .refresh = wb_refresh_nvolt, 1137 .rfact = RFACT(120, 56) 1138 }, 1139 1140 /* Temperature */ 1141 { 1142 .desc = "Temp0", 1143 .type = ENVSYS_STEMP, 1144 .bank = 0, 1145 .reg = 0x27, 1146 .refresh = lm_refresh_temp, 1147 .rfact = 0 1148 }, 1149 { 1150 .desc = "Temp1", 1151 .type = ENVSYS_STEMP, 1152 .bank = 1, 1153 .reg = 0x50, 1154 .refresh = wb_refresh_temp, 1155 .rfact = 0 1156 }, 1157 1158 /* Fans */ 1159 { 1160 .desc = "Fan0", 1161 .type = ENVSYS_SFANRPM, 1162 .bank = 0, 1163 .reg = 0x28, 1164 .refresh = wb_refresh_fanrpm, 1165 .rfact = 0 1166 }, 1167 { 1168 .desc = "Fan1", 1169 .type = ENVSYS_SFANRPM, 1170 .bank = 0, 1171 .reg = 0x29, 1172 .refresh = wb_refresh_fanrpm, 1173 .rfact = 0 1174 }, 1175 { 1176 .desc = "Fan2", 1177 .type = ENVSYS_SFANRPM, 1178 .bank = 0, 1179 .reg = 0x2a, 1180 .refresh = wb_refresh_fanrpm, 1181 .rfact = 0 1182 }, 1183 1184 { .desc = NULL } 1185 }; 1186 1187 /* W83791D */ 1188 static struct lm_sensor w83791d_sensors[] = { 1189 /* Voltage */ 1190 { 1191 .desc = "VCore", 1192 .type = ENVSYS_SVOLTS_DC, 1193 .bank = 0, 1194 .reg = 0x20, 1195 .refresh = lm_refresh_volt, 1196 .rfact = 10000 1197 }, 1198 { 1199 .desc = "VINR0", 1200 .type = ENVSYS_SVOLTS_DC, 1201 .bank = 0, 1202 .reg = 0x21, 1203 .refresh = lm_refresh_volt, 1204 .rfact = 10000 1205 }, 1206 { 1207 .desc = "+3.3V", 1208 .type = ENVSYS_SVOLTS_DC, 1209 .bank = 0, 1210 .reg = 0x22, 1211 .refresh = lm_refresh_volt, 1212 .rfact = 10000 1213 }, 1214 { 1215 .desc = "+5V", 1216 .type = ENVSYS_SVOLTS_DC, 1217 .bank = 0, 1218 .reg = 0x23, 1219 .refresh = lm_refresh_volt, 1220 .rfact = RFACT(34, 50) 1221 }, 1222 { 1223 .desc = "+12V", 1224 .type = ENVSYS_SVOLTS_DC, 1225 .bank = 0, 1226 .reg = 0x24, 1227 .refresh = lm_refresh_volt, 1228 .rfact = RFACT(28, 10) 1229 }, 1230 { 1231 .desc = "-12V", 1232 .type = ENVSYS_SVOLTS_DC, 1233 .bank = 0, 1234 .reg = 0x25, 1235 .refresh = wb_refresh_nvolt, 1236 .rfact = RFACT(232, 56) 1237 }, 1238 { 1239 .desc = "-5V", 1240 .type = ENVSYS_SVOLTS_DC, 1241 .bank = 0, 1242 .reg = 0x26, 1243 .refresh = wb_refresh_nvolt, 1244 .rfact = RFACT(120, 56) 1245 }, 1246 { 1247 .desc = "5VSB", 1248 .type = ENVSYS_SVOLTS_DC, 1249 .bank = 0, 1250 .reg = 0xb0, 1251 .refresh = lm_refresh_volt, 1252 .rfact = RFACT(17, 33) 1253 }, 1254 { 1255 .desc = "VBAT", 1256 .type = ENVSYS_SVOLTS_DC, 1257 .bank = 0, 1258 .reg = 0xb1, 1259 .refresh = lm_refresh_volt, 1260 .rfact = RFACT_NONE 1261 }, 1262 { 1263 .desc = "VINR1", 1264 .type = ENVSYS_SVOLTS_DC, 1265 .bank = 0, 1266 .reg = 0xb2, 1267 .refresh = lm_refresh_volt, 1268 .rfact = RFACT_NONE 1269 }, 1270 1271 /* Temperature */ 1272 { 1273 .desc = "Temp0", 1274 .type = ENVSYS_STEMP, 1275 .bank = 0, 1276 .reg = 0x27, 1277 .refresh = lm_refresh_temp, 1278 .rfact = 0 1279 }, 1280 { 1281 .desc = "Temp1", 1282 .type = ENVSYS_STEMP, 1283 .bank = 0, 1284 .reg = 0xc0, 1285 .refresh = wb_refresh_temp, 1286 .rfact = 0 1287 }, 1288 { 1289 .desc = "Temp2", 1290 .type = ENVSYS_STEMP, 1291 .bank = 0, 1292 .reg = 0xc8, 1293 .refresh = wb_refresh_temp, 1294 .rfact = 0 1295 }, 1296 1297 /* Fans */ 1298 { 1299 .desc = "Fan0", 1300 .type = ENVSYS_SFANRPM, 1301 .bank = 0, 1302 .reg = 0x28, 1303 .refresh = wb_refresh_fanrpm, 1304 .rfact = 0 1305 }, 1306 { 1307 .desc = "Fan1", 1308 .type = ENVSYS_SFANRPM, 1309 .bank = 0, 1310 .reg = 0x29, 1311 .refresh = wb_refresh_fanrpm, 1312 .rfact = 0 1313 }, 1314 { 1315 .desc = "Fan2", 1316 .type = ENVSYS_SFANRPM, 1317 .bank = 0, 1318 .reg = 0x2a, 1319 .refresh = wb_refresh_fanrpm, 1320 .rfact = 0 1321 }, 1322 { 1323 .desc = "Fan3", 1324 .type = ENVSYS_SFANRPM, 1325 .bank = 0, 1326 .reg = 0xba, 1327 .refresh = wb_refresh_fanrpm, 1328 .rfact = 0 1329 }, 1330 { 1331 .desc = "Fan4", 1332 .type = ENVSYS_SFANRPM, 1333 .bank = 0, 1334 .reg = 0xbb, 1335 .refresh = wb_refresh_fanrpm, 1336 .rfact = 0 1337 }, 1338 1339 { .desc = NULL } 1340 }; 1341 1342 /* W83792D */ 1343 static struct lm_sensor w83792d_sensors[] = { 1344 /* Voltage */ 1345 { 1346 .desc = "VCore A", 1347 .type = ENVSYS_SVOLTS_DC, 1348 .bank = 0, 1349 .reg = 0x20, 1350 .refresh = lm_refresh_volt, 1351 .rfact = RFACT_NONE 1352 }, 1353 { 1354 .desc = "VCore B", 1355 .type = ENVSYS_SVOLTS_DC, 1356 .bank = 0, 1357 .reg = 0x21, 1358 .refresh = lm_refresh_volt, 1359 .rfact = RFACT_NONE 1360 }, 1361 { 1362 .desc = "+3.3V", 1363 .type = ENVSYS_SVOLTS_DC, 1364 .bank = 0, 1365 .reg = 0x22, 1366 .refresh = lm_refresh_volt, 1367 .rfact = RFACT_NONE 1368 }, 1369 { 1370 .desc = "-5V", 1371 .type = ENVSYS_SVOLTS_DC, 1372 .bank = 0, 1373 .reg = 0x23, 1374 .refresh = wb_refresh_nvolt, 1375 .rfact = RFACT(120, 56) 1376 }, 1377 { 1378 .desc = "+12V", 1379 .type = ENVSYS_SVOLTS_DC, 1380 .bank = 0, 1381 .reg = 0x24, 1382 .refresh = lm_refresh_volt, 1383 .rfact = RFACT(28, 10) 1384 }, 1385 { 1386 .desc = "-12V", 1387 .type = ENVSYS_SVOLTS_DC, 1388 .bank = 0, 1389 .reg = 0x25, 1390 .refresh = wb_refresh_nvolt, 1391 .rfact = RFACT(232, 56) 1392 }, 1393 { 1394 .desc = "+5V", 1395 .type = ENVSYS_SVOLTS_DC, 1396 .bank = 0, 1397 .reg = 0x26, 1398 .refresh = lm_refresh_volt, 1399 .rfact = RFACT(34, 50) 1400 }, 1401 { 1402 .desc = "5VSB", 1403 .type = ENVSYS_SVOLTS_DC, 1404 .bank = 0, 1405 .reg = 0xb0, 1406 .refresh = lm_refresh_volt, 1407 .rfact = RFACT(17, 33) 1408 }, 1409 { 1410 .desc = "VBAT", 1411 .type = ENVSYS_SVOLTS_DC, 1412 .bank = 0, 1413 .reg = 0xb1, 1414 .refresh = lm_refresh_volt, 1415 .rfact = RFACT_NONE 1416 }, 1417 1418 /* Temperature */ 1419 { 1420 .desc = "Temp0", 1421 .type = ENVSYS_STEMP, 1422 .bank = 0, 1423 .reg = 0x27, 1424 .refresh = lm_refresh_temp, 1425 .rfact = 0 1426 }, 1427 { 1428 .desc = "Temp1", 1429 .type = ENVSYS_STEMP, 1430 .bank = 0, 1431 .reg = 0xc0, 1432 .refresh = wb_refresh_temp, 1433 .rfact = 0 1434 }, 1435 { 1436 .desc = "Temp2", 1437 .type = ENVSYS_STEMP, 1438 .bank = 0, 1439 .reg = 0xc8, 1440 .refresh = wb_refresh_temp, 1441 .rfact = 0 1442 }, 1443 1444 /* Fans */ 1445 { 1446 .desc = "Fan0", 1447 .type = ENVSYS_SFANRPM, 1448 .bank = 0, 1449 .reg = 0x28, 1450 .refresh = wb_w83792d_refresh_fanrpm, 1451 .rfact = 0 1452 }, 1453 { 1454 .desc = "Fan1", 1455 .type = ENVSYS_SFANRPM, 1456 .bank = 0, 1457 .reg = 0x29, 1458 .refresh = wb_w83792d_refresh_fanrpm, 1459 .rfact = 0 1460 }, 1461 { 1462 .desc = "Fan2", 1463 .type = ENVSYS_SFANRPM, 1464 .bank = 0, 1465 .reg = 0x2a, 1466 .refresh = wb_w83792d_refresh_fanrpm, 1467 .rfact = 0 1468 }, 1469 { 1470 .desc = "Fan3", 1471 .type = ENVSYS_SFANRPM, 1472 .bank = 0, 1473 .reg = 0xb8, 1474 .refresh = wb_w83792d_refresh_fanrpm, 1475 .rfact = 0 1476 }, 1477 { 1478 .desc = "Fan4", 1479 .type = ENVSYS_SFANRPM, 1480 .bank = 0, 1481 .reg = 0xb9, 1482 .refresh = wb_w83792d_refresh_fanrpm, 1483 .rfact = 0 1484 }, 1485 { 1486 .desc = "Fan5", 1487 .type = ENVSYS_SFANRPM, 1488 .bank = 0, 1489 .reg = 0xba, 1490 .refresh = wb_w83792d_refresh_fanrpm, 1491 .rfact = 0 1492 }, 1493 { 1494 .desc = "Fan6", 1495 .type = ENVSYS_SFANRPM, 1496 .bank = 0, 1497 .reg = 0xbe, 1498 .refresh = wb_w83792d_refresh_fanrpm, 1499 .rfact = 0 1500 }, 1501 1502 { .desc = NULL } 1503 }; 1504 1505 /* AS99127F */ 1506 static struct lm_sensor as99127f_sensors[] = { 1507 /* Voltage */ 1508 { 1509 .desc = "VCore A", 1510 .type = ENVSYS_SVOLTS_DC, 1511 .bank = 0, 1512 .reg = 0x20, 1513 .refresh = lm_refresh_volt, 1514 .rfact = RFACT_NONE 1515 }, 1516 { 1517 .desc = "VCore B", 1518 .type = ENVSYS_SVOLTS_DC, 1519 .bank = 0, 1520 .reg = 0x21, 1521 .refresh = lm_refresh_volt, 1522 .rfact = RFACT_NONE 1523 }, 1524 { 1525 .desc = "+3.3V", 1526 .type = ENVSYS_SVOLTS_DC, 1527 .bank = 0, 1528 .reg = 0x22, 1529 .refresh = lm_refresh_volt, 1530 .rfact = RFACT_NONE 1531 }, 1532 { 1533 .desc = "+5V", 1534 .type = ENVSYS_SVOLTS_DC, 1535 .bank = 0, 1536 .reg = 0x23, 1537 .refresh = lm_refresh_volt, 1538 .rfact = RFACT(34, 50) 1539 }, 1540 { 1541 .desc = "+12V", 1542 .type = ENVSYS_SVOLTS_DC, 1543 .bank = 0, 1544 .reg = 0x24, 1545 .refresh = lm_refresh_volt, 1546 .rfact = RFACT(28, 10) 1547 }, 1548 { 1549 .desc = "-12V", 1550 .type = ENVSYS_SVOLTS_DC, 1551 .bank = 0, 1552 .reg = 0x25, 1553 .refresh = wb_refresh_nvolt, 1554 .rfact = RFACT(232, 56) 1555 }, 1556 { 1557 .desc = "-5V", 1558 .type = ENVSYS_SVOLTS_DC, 1559 .bank = 0, 1560 .reg = 0x26, 1561 .refresh = wb_refresh_nvolt, 1562 .rfact = RFACT(120, 56) 1563 }, 1564 1565 /* Temperature */ 1566 { 1567 .desc = "Temp0", 1568 .type = ENVSYS_STEMP, 1569 .bank = 0, 1570 .reg = 0x27, 1571 .refresh = lm_refresh_temp, 1572 .rfact = 0 1573 }, 1574 { 1575 .desc = "Temp1", 1576 .type = ENVSYS_STEMP, 1577 .bank = 1, 1578 .reg = 0x50, 1579 .refresh = as_refresh_temp, 1580 .rfact = 0 1581 }, 1582 { 1583 .desc = "Temp2", 1584 .type = ENVSYS_STEMP, 1585 .bank = 2, 1586 .reg = 0x50, 1587 .refresh = as_refresh_temp, 1588 .rfact = 0 1589 }, 1590 1591 /* Fans */ 1592 { 1593 .desc = "Fan0", 1594 .type = ENVSYS_SFANRPM, 1595 .bank = 0, 1596 .reg = 0x28, 1597 .refresh = lm_refresh_fanrpm, 1598 .rfact = 0 1599 }, 1600 { 1601 .desc = "Fan1", 1602 .type = ENVSYS_SFANRPM, 1603 .bank = 0, 1604 .reg = 0x29, 1605 .refresh = lm_refresh_fanrpm, 1606 .rfact = 0 1607 }, 1608 { 1609 .desc = "Fan2", 1610 .type = ENVSYS_SFANRPM, 1611 .bank = 0, 1612 .reg = 0x2a, 1613 .refresh = lm_refresh_fanrpm, 1614 .rfact = 0 1615 }, 1616 1617 { .desc = NULL } 1618 }; 1619 1620 static void 1621 lm_generic_banksel(struct lm_softc *lmsc, int bank) 1622 { 1623 (*lmsc->lm_writereg)(lmsc, WB_BANKSEL, bank); 1624 } 1625 1626 /* 1627 * bus independent probe 1628 */ 1629 int 1630 lm_probe(bus_space_tag_t iot, bus_space_handle_t ioh) 1631 { 1632 uint8_t cr; 1633 int rv; 1634 1635 /* Check for some power-on defaults */ 1636 bus_space_write_1(iot, ioh, LMC_ADDR, LMD_CONFIG); 1637 1638 /* Perform LM78 reset */ 1639 /* bus_space_write_1(iot, ioh, LMC_DATA, 0x80); */ 1640 1641 /* XXX - Why do I have to reselect the register? */ 1642 bus_space_write_1(iot, ioh, LMC_ADDR, LMD_CONFIG); 1643 cr = bus_space_read_1(iot, ioh, LMC_DATA); 1644 1645 /* XXX - spec says *only* 0x08! */ 1646 if ((cr == 0x08) || (cr == 0x01) || (cr == 0x03)) 1647 rv = 1; 1648 else 1649 rv = 0; 1650 1651 DPRINTF(("%s: rv = %d, cr = %x\n", __func__, rv, cr)); 1652 1653 return rv; 1654 } 1655 1656 1657 /* 1658 * pre: lmsc contains valid busspace tag and handle 1659 */ 1660 void 1661 lm_attach(struct lm_softc *lmsc) 1662 { 1663 uint32_t i; 1664 1665 for (i = 0; i < __arraycount(lm_chips); i++) 1666 if (lm_chips[i].chip_match(lmsc)) 1667 break; 1668 1669 /* Start the monitoring loop */ 1670 (*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x01); 1671 1672 lmsc->sc_sme = sysmon_envsys_create(); 1673 /* Initialize sensors */ 1674 for (i = 0; i < lmsc->numsensors; i++) { 1675 if (sysmon_envsys_sensor_attach(lmsc->sc_sme, 1676 &lmsc->sensors[i])) { 1677 sysmon_envsys_destroy(lmsc->sc_sme); 1678 return; 1679 } 1680 } 1681 1682 /* 1683 * Setup the callout to refresh sensor data every 2 seconds. 1684 */ 1685 callout_init(&lmsc->sc_callout, 0); 1686 callout_setfunc(&lmsc->sc_callout, lm_refresh, lmsc); 1687 callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO); 1688 1689 /* 1690 * Hook into the System Monitor. 1691 */ 1692 lmsc->sc_sme->sme_name = device_xname(lmsc->sc_dev); 1693 lmsc->sc_sme->sme_flags = SME_DISABLE_REFRESH; 1694 1695 if (sysmon_envsys_register(lmsc->sc_sme)) { 1696 aprint_error_dev(lmsc->sc_dev, 1697 "unable to register with sysmon\n"); 1698 sysmon_envsys_destroy(lmsc->sc_sme); 1699 } 1700 } 1701 1702 /* 1703 * Stop, destroy the callout and unregister the driver with the 1704 * sysmon_envsys(9) framework. 1705 */ 1706 void 1707 lm_detach(struct lm_softc *lmsc) 1708 { 1709 callout_stop(&lmsc->sc_callout); 1710 callout_destroy(&lmsc->sc_callout); 1711 sysmon_envsys_unregister(lmsc->sc_sme); 1712 } 1713 1714 static void 1715 lm_refresh(void *arg) 1716 { 1717 struct lm_softc *lmsc = arg; 1718 1719 lmsc->refresh_sensor_data(lmsc); 1720 callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO); 1721 } 1722 1723 static int 1724 lm_match(struct lm_softc *sc) 1725 { 1726 const char *model = NULL; 1727 int chipid; 1728 1729 /* See if we have an LM78/LM78J/LM79 or LM81 */ 1730 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 1731 switch(chipid) { 1732 case LM_ID_LM78: 1733 model = "LM78"; 1734 break; 1735 case LM_ID_LM78J: 1736 model = "LM78J"; 1737 break; 1738 case LM_ID_LM79: 1739 model = "LM79"; 1740 break; 1741 case LM_ID_LM81: 1742 model = "LM81"; 1743 break; 1744 default: 1745 return 0; 1746 } 1747 1748 aprint_normal("\n"); 1749 aprint_normal_dev(sc->sc_dev, 1750 "National Semiconductor %s Hardware monitor\n", model); 1751 1752 lm_setup_sensors(sc, lm78_sensors); 1753 sc->refresh_sensor_data = lm_refresh_sensor_data; 1754 return 1; 1755 } 1756 1757 static int 1758 def_match(struct lm_softc *sc) 1759 { 1760 int chipid; 1761 1762 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 1763 aprint_normal("\n"); 1764 aprint_error_dev(sc->sc_dev, "Unknown chip (ID %d)\n", chipid); 1765 1766 lm_setup_sensors(sc, lm78_sensors); 1767 sc->refresh_sensor_data = lm_refresh_sensor_data; 1768 return 1; 1769 } 1770 1771 static int 1772 wb_match(struct lm_softc *sc) 1773 { 1774 const char *model = NULL; 1775 int banksel, vendid, devid; 1776 1777 aprint_normal("\n"); 1778 /* Read vendor ID */ 1779 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 1780 lm_generic_banksel(sc, WB_BANKSEL_HBAC); 1781 vendid = (*sc->lm_readreg)(sc, WB_VENDID) << 8; 1782 lm_generic_banksel(sc, 0); 1783 vendid |= (*sc->lm_readreg)(sc, WB_VENDID); 1784 DPRINTF(("%s: winbond vend id 0x%x\n", __func__, vendid)); 1785 if (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS) 1786 return 0; 1787 1788 /* Read device/chip ID */ 1789 lm_generic_banksel(sc, WB_BANKSEL_B0); 1790 devid = (*sc->lm_readreg)(sc, LMD_CHIPID); 1791 sc->chipid = (*sc->lm_readreg)(sc, WB_BANK0_CHIPID); 1792 lm_generic_banksel(sc, banksel); 1793 DPRINTF(("%s: winbond chip id 0x%x\n", __func__, sc->chipid)); 1794 1795 switch(sc->chipid) { 1796 case WB_CHIPID_W83627HF: 1797 model = "W83627HF"; 1798 lm_setup_sensors(sc, w83627hf_sensors); 1799 break; 1800 case WB_CHIPID_W83627THF: 1801 model = "W83627THF"; 1802 lm_setup_sensors(sc, w83637hf_sensors); 1803 break; 1804 case WB_CHIPID_W83627EHF_A: 1805 model = "W83627EHF-A"; 1806 lm_setup_sensors(sc, w83627ehf_sensors); 1807 break; 1808 case WB_CHIPID_W83627EHF: 1809 model = "W83627EHF"; 1810 lm_setup_sensors(sc, w83627ehf_sensors); 1811 break; 1812 case WB_CHIPID_W83627DHG: 1813 model = "W83627DHG"; 1814 lm_setup_sensors(sc, w83627dhg_sensors); 1815 break; 1816 case WB_CHIPID_W83637HF: 1817 model = "W83637HF"; 1818 lm_generic_banksel(sc, WB_BANKSEL_B0); 1819 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9) 1820 sc->vrm9 = 1; 1821 lm_generic_banksel(sc, banksel); 1822 lm_setup_sensors(sc, w83637hf_sensors); 1823 break; 1824 case WB_CHIPID_W83697HF: 1825 model = "W83697HF"; 1826 lm_setup_sensors(sc, w83697hf_sensors); 1827 break; 1828 case WB_CHIPID_W83781D: 1829 case WB_CHIPID_W83781D_2: 1830 model = "W83781D"; 1831 lm_setup_sensors(sc, w83781d_sensors); 1832 break; 1833 case WB_CHIPID_W83782D: 1834 model = "W83782D"; 1835 lm_setup_sensors(sc, w83782d_sensors); 1836 break; 1837 case WB_CHIPID_W83783S: 1838 model = "W83783S"; 1839 lm_setup_sensors(sc, w83783s_sensors); 1840 break; 1841 case WB_CHIPID_W83791D: 1842 model = "W83791D"; 1843 lm_setup_sensors(sc, w83791d_sensors); 1844 break; 1845 case WB_CHIPID_W83791SD: 1846 model = "W83791SD"; 1847 break; 1848 case WB_CHIPID_W83792D: 1849 model = "W83792D"; 1850 lm_setup_sensors(sc, w83792d_sensors); 1851 break; 1852 case WB_CHIPID_AS99127F: 1853 if (vendid == WB_VENDID_ASUS) { 1854 model = "AS99127F"; 1855 lm_setup_sensors(sc, w83781d_sensors); 1856 } else { 1857 model = "AS99127F rev 2"; 1858 lm_setup_sensors(sc, as99127f_sensors); 1859 } 1860 break; 1861 default: 1862 aprint_normal_dev(sc->sc_dev, 1863 "unknown Winbond chip (ID 0x%x)\n", sc->chipid); 1864 /* Handle as a standard LM78. */ 1865 lm_setup_sensors(sc, lm78_sensors); 1866 sc->refresh_sensor_data = lm_refresh_sensor_data; 1867 return 1; 1868 } 1869 1870 aprint_normal_dev(sc->sc_dev, "Winbond %s Hardware monitor\n", model); 1871 1872 sc->refresh_sensor_data = wb_refresh_sensor_data; 1873 return 1; 1874 } 1875 1876 static void 1877 lm_setup_sensors(struct lm_softc *sc, struct lm_sensor *sensors) 1878 { 1879 int i; 1880 1881 for (i = 0; sensors[i].desc; i++) { 1882 sc->sensors[i].units = sensors[i].type; 1883 strlcpy(sc->sensors[i].desc, sensors[i].desc, 1884 sizeof(sc->sensors[i].desc)); 1885 sc->numsensors++; 1886 } 1887 sc->lm_sensors = sensors; 1888 } 1889 1890 static void 1891 lm_refresh_sensor_data(struct lm_softc *sc) 1892 { 1893 int i; 1894 1895 for (i = 0; i < sc->numsensors; i++) 1896 sc->lm_sensors[i].refresh(sc, i); 1897 } 1898 1899 static void 1900 lm_refresh_volt(struct lm_softc *sc, int n) 1901 { 1902 int data; 1903 1904 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 1905 if (data == 0xff) { 1906 sc->sensors[n].state = ENVSYS_SINVALID; 1907 } else { 1908 sc->sensors[n].flags = ENVSYS_FCHANGERFACT; 1909 sc->sensors[n].value_cur = (data << 4); 1910 if (sc->sensors[n].rfact) { 1911 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 1912 sc->sensors[n].value_cur /= 10; 1913 } else { 1914 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact; 1915 sc->sensors[n].value_cur /= 10; 1916 sc->sensors[n].rfact = sc->lm_sensors[n].rfact; 1917 } 1918 sc->sensors[n].state = ENVSYS_SVALID; 1919 } 1920 1921 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 1922 __func__, n, data, sc->sensors[n].value_cur)); 1923 } 1924 1925 static void 1926 lm_refresh_temp(struct lm_softc *sc, int n) 1927 { 1928 int data; 1929 1930 /* 1931 * The data sheet suggests that the range of the temperature 1932 * sensor is between -55 degC and +125 degC. 1933 */ 1934 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 1935 if (data > 0x7d && data < 0xc9) 1936 sc->sensors[n].state = ENVSYS_SINVALID; 1937 else { 1938 if (data & 0x80) 1939 data -= 0x100; 1940 sc->sensors[n].state = ENVSYS_SVALID; 1941 sc->sensors[n].value_cur = data * 1000000 + 273150000; 1942 } 1943 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 1944 __func__, n, data, sc->sensors[n].value_cur)); 1945 } 1946 1947 static void 1948 lm_refresh_fanrpm(struct lm_softc *sc, int n) 1949 { 1950 int data, divisor = 1; 1951 1952 /* 1953 * We might get more accurate fan readings by adjusting the 1954 * divisor, but that might interfere with APM or other SMM 1955 * BIOS code reading the fan speeds. 1956 */ 1957 1958 /* FAN3 has a fixed fan divisor. */ 1959 if (sc->lm_sensors[n].reg == LMD_FAN1 || 1960 sc->lm_sensors[n].reg == LMD_FAN2) { 1961 data = (*sc->lm_readreg)(sc, LMD_VIDFAN); 1962 if (sc->lm_sensors[n].reg == LMD_FAN1) 1963 divisor = (data >> 4) & 0x03; 1964 else 1965 divisor = (data >> 6) & 0x03; 1966 } 1967 1968 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 1969 if (data == 0xff || data == 0x00) 1970 sc->sensors[n].state = ENVSYS_SINVALID; 1971 else { 1972 sc->sensors[n].state = ENVSYS_SVALID; 1973 sc->sensors[n].value_cur = 1350000 / (data << divisor); 1974 } 1975 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 1976 __func__, n, data, sc->sensors[n].value_cur)); 1977 } 1978 1979 static void 1980 wb_refresh_sensor_data(struct lm_softc *sc) 1981 { 1982 int banksel, bank, i; 1983 1984 /* 1985 * Properly save and restore bank selection register. 1986 */ 1987 banksel = bank = sc->lm_readreg(sc, WB_BANKSEL); 1988 for (i = 0; i < sc->numsensors; i++) { 1989 if (bank != sc->lm_sensors[i].bank) { 1990 bank = sc->lm_sensors[i].bank; 1991 lm_generic_banksel(sc, bank); 1992 } 1993 sc->lm_sensors[i].refresh(sc, i); 1994 } 1995 lm_generic_banksel(sc, banksel); 1996 } 1997 1998 static void 1999 wb_w83637hf_refresh_vcore(struct lm_softc *sc, int n) 2000 { 2001 int data; 2002 2003 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2004 /* 2005 * Depending on the voltage detection method, 2006 * one of the following formulas is used: 2007 * VRM8 method: value = raw * 0.016V 2008 * VRM9 method: value = raw * 0.00488V + 0.70V 2009 */ 2010 if (sc->vrm9) 2011 sc->sensors[n].value_cur = (data * 4880) + 700000; 2012 else 2013 sc->sensors[n].value_cur = (data * 16000); 2014 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2015 __func__, n, data, sc->sensors[n].value_cur)); 2016 } 2017 2018 static void 2019 wb_refresh_nvolt(struct lm_softc *sc, int n) 2020 { 2021 int data; 2022 2023 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2024 sc->sensors[n].flags = ENVSYS_FCHANGERFACT; 2025 sc->sensors[n].value_cur = ((data << 4) - WB_VREF); 2026 if (sc->sensors[n].rfact) 2027 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2028 else 2029 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact; 2030 2031 sc->sensors[n].value_cur /= 10; 2032 sc->sensors[n].value_cur += WB_VREF * 1000; 2033 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2034 __func__, n , data, sc->sensors[n].value_cur)); 2035 } 2036 2037 static void 2038 wb_w83627ehf_refresh_nvolt(struct lm_softc *sc, int n) 2039 { 2040 int data; 2041 2042 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2043 sc->sensors[n].value_cur = ((data << 3) - WB_W83627EHF_VREF); 2044 sc->sensors[n].flags = ENVSYS_FCHANGERFACT; 2045 if (sc->sensors[n].rfact) 2046 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2047 else 2048 sc->sensors[n].value_cur *= RFACT(232, 10); 2049 2050 sc->sensors[n].value_cur /= 10; 2051 sc->sensors[n].value_cur += WB_W83627EHF_VREF * 1000; 2052 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2053 __func__, n , data, sc->sensors[n].value_cur)); 2054 } 2055 2056 static void 2057 wb_refresh_temp(struct lm_softc *sc, int n) 2058 { 2059 int data; 2060 2061 /* 2062 * The data sheet suggests that the range of the temperature 2063 * sensor is between -55 degC and +125 degC. However, values 2064 * around -48 degC seem to be a very common bogus values. 2065 * Since such values are unreasonably low, we use -45 degC for 2066 * the lower limit instead. 2067 */ 2068 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1; 2069 data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7; 2070 if (data > 0xfffffff || (data > 0x0fa && data < 0x1a6)) { 2071 sc->sensors[n].state = ENVSYS_SINVALID; 2072 } else { 2073 if (data & 0x100) 2074 data -= 0x200; 2075 sc->sensors[n].state = ENVSYS_SVALID; 2076 sc->sensors[n].value_cur = data * 500000 + 273150000; 2077 } 2078 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2079 __func__, n , data, sc->sensors[n].value_cur)); 2080 } 2081 2082 static void 2083 wb_refresh_fanrpm(struct lm_softc *sc, int n) 2084 { 2085 int fan, data, divisor = 0; 2086 2087 /* 2088 * This is madness; the fan divisor bits are scattered all 2089 * over the place. 2090 */ 2091 2092 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2093 sc->lm_sensors[n].reg == LMD_FAN2 || 2094 sc->lm_sensors[n].reg == LMD_FAN3) { 2095 data = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2096 fan = (sc->lm_sensors[n].reg - LMD_FAN1); 2097 if ((data >> 5) & (1 << fan)) 2098 divisor |= 0x04; 2099 } 2100 2101 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2102 sc->lm_sensors[n].reg == LMD_FAN2) { 2103 data = (*sc->lm_readreg)(sc, LMD_VIDFAN); 2104 if (sc->lm_sensors[n].reg == LMD_FAN1) 2105 divisor |= (data >> 4) & 0x03; 2106 else 2107 divisor |= (data >> 6) & 0x03; 2108 } else if (sc->lm_sensors[n].reg == LMD_FAN3) { 2109 data = (*sc->lm_readreg)(sc, WB_PIN); 2110 divisor |= (data >> 6) & 0x03; 2111 } else if (sc->lm_sensors[n].reg == WB_BANK0_FAN4 || 2112 sc->lm_sensors[n].reg == WB_BANK0_FAN5) { 2113 data = (*sc->lm_readreg)(sc, WB_BANK0_FAN45); 2114 if (sc->lm_sensors[n].reg == WB_BANK0_FAN4) 2115 divisor |= (data >> 0) & 0x07; 2116 else 2117 divisor |= (data >> 4) & 0x07; 2118 } 2119 2120 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2121 if (data >= 0xff || data == 0x00) 2122 sc->sensors[n].state = ENVSYS_SINVALID; 2123 else { 2124 sc->sensors[n].state = ENVSYS_SVALID; 2125 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2126 } 2127 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2128 __func__, n , data, sc->sensors[n].value_cur)); 2129 } 2130 2131 static void 2132 wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n) 2133 { 2134 int reg, shift, data, divisor = 1; 2135 2136 shift = 0; 2137 2138 switch (sc->lm_sensors[n].reg) { 2139 case 0x28: 2140 reg = 0x47; shift = 0; 2141 break; 2142 case 0x29: 2143 reg = 0x47; shift = 4; 2144 break; 2145 case 0x2a: 2146 reg = 0x5b; shift = 0; 2147 break; 2148 case 0xb8: 2149 reg = 0x5b; shift = 4; 2150 break; 2151 case 0xb9: 2152 reg = 0x5c; shift = 0; 2153 break; 2154 case 0xba: 2155 reg = 0x5c; shift = 4; 2156 break; 2157 case 0xbe: 2158 reg = 0x9e; shift = 0; 2159 break; 2160 default: 2161 reg = 0; 2162 break; 2163 } 2164 2165 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2166 if (data == 0xff || data == 0x00) 2167 sc->sensors[n].state = ENVSYS_SINVALID; 2168 else { 2169 if (reg != 0) 2170 divisor = ((*sc->lm_readreg)(sc, reg) >> shift) & 0x7; 2171 sc->sensors[n].state = ENVSYS_SVALID; 2172 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2173 } 2174 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2175 __func__, n , data, sc->sensors[n].value_cur)); 2176 } 2177 2178 static void 2179 as_refresh_temp(struct lm_softc *sc, int n) 2180 { 2181 int data; 2182 2183 /* 2184 * It seems a shorted temperature diode produces an all-ones 2185 * bit pattern. 2186 */ 2187 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1; 2188 data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7; 2189 if (data == 0x1ff) 2190 sc->sensors[n].state = ENVSYS_SINVALID; 2191 else { 2192 if (data & 0x100) 2193 data -= 0x200; 2194 sc->sensors[n].state = ENVSYS_SVALID; 2195 sc->sensors[n].value_cur = data * 500000 + 273150000; 2196 } 2197 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2198 __func__, n, data, sc->sensors[n].value_cur)); 2199 } 2200