1 /* $NetBSD: nslm7x.c,v 1.49 2008/10/13 12:44:46 pgoyette 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.49 2008/10/13 12:44:46 pgoyette 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 * prerequisites: lmsc contains valid lm_{read,write}reg() routines 1630 * and associated bus access data is present in attachment's softc 1631 */ 1632 int 1633 lm_probe(struct lm_softc *lmsc) 1634 { 1635 uint8_t cr; 1636 int rv; 1637 1638 /* Perform LM78 reset */ 1639 /*(*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x80); */ 1640 1641 cr = (*lmsc->lm_readreg)(lmsc, LMD_CONFIG); 1642 1643 /* XXX - spec says *only* 0x08! */ 1644 if ((cr == 0x08) || (cr == 0x01) || (cr == 0x03) || (cr == 0x06)) 1645 rv = 1; 1646 else 1647 rv = 0; 1648 1649 DPRINTF(("%s: rv = %d, cr = %x\n", __func__, rv, cr)); 1650 1651 return rv; 1652 } 1653 1654 void 1655 lm_attach(struct lm_softc *lmsc) 1656 { 1657 uint32_t i; 1658 1659 for (i = 0; i < __arraycount(lm_chips); i++) 1660 if (lm_chips[i].chip_match(lmsc)) 1661 break; 1662 1663 /* Start the monitoring loop */ 1664 (*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x01); 1665 1666 lmsc->sc_sme = sysmon_envsys_create(); 1667 /* Initialize sensors */ 1668 for (i = 0; i < lmsc->numsensors; i++) { 1669 if (sysmon_envsys_sensor_attach(lmsc->sc_sme, 1670 &lmsc->sensors[i])) { 1671 sysmon_envsys_destroy(lmsc->sc_sme); 1672 return; 1673 } 1674 } 1675 1676 /* 1677 * Setup the callout to refresh sensor data every 2 seconds. 1678 */ 1679 callout_init(&lmsc->sc_callout, 0); 1680 callout_setfunc(&lmsc->sc_callout, lm_refresh, lmsc); 1681 callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO); 1682 1683 /* 1684 * Hook into the System Monitor. 1685 */ 1686 lmsc->sc_sme->sme_name = device_xname(lmsc->sc_dev); 1687 lmsc->sc_sme->sme_flags = SME_DISABLE_REFRESH; 1688 1689 if (sysmon_envsys_register(lmsc->sc_sme)) { 1690 aprint_error_dev(lmsc->sc_dev, 1691 "unable to register with sysmon\n"); 1692 sysmon_envsys_destroy(lmsc->sc_sme); 1693 } 1694 } 1695 1696 /* 1697 * Stop, destroy the callout and unregister the driver with the 1698 * sysmon_envsys(9) framework. 1699 */ 1700 void 1701 lm_detach(struct lm_softc *lmsc) 1702 { 1703 callout_stop(&lmsc->sc_callout); 1704 callout_destroy(&lmsc->sc_callout); 1705 sysmon_envsys_unregister(lmsc->sc_sme); 1706 } 1707 1708 static void 1709 lm_refresh(void *arg) 1710 { 1711 struct lm_softc *lmsc = arg; 1712 1713 lmsc->refresh_sensor_data(lmsc); 1714 callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO); 1715 } 1716 1717 static int 1718 lm_match(struct lm_softc *sc) 1719 { 1720 const char *model = NULL; 1721 int chipid; 1722 1723 /* See if we have an LM78/LM78J/LM79 or LM81 */ 1724 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 1725 switch(chipid) { 1726 case LM_ID_LM78: 1727 model = "LM78"; 1728 break; 1729 case LM_ID_LM78J: 1730 model = "LM78J"; 1731 break; 1732 case LM_ID_LM79: 1733 model = "LM79"; 1734 break; 1735 case LM_ID_LM81: 1736 model = "LM81"; 1737 break; 1738 default: 1739 return 0; 1740 } 1741 1742 aprint_normal("\n"); 1743 aprint_normal_dev(sc->sc_dev, 1744 "National Semiconductor %s Hardware monitor\n", model); 1745 1746 lm_setup_sensors(sc, lm78_sensors); 1747 sc->refresh_sensor_data = lm_refresh_sensor_data; 1748 return 1; 1749 } 1750 1751 static int 1752 def_match(struct lm_softc *sc) 1753 { 1754 int chipid; 1755 1756 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 1757 aprint_normal("\n"); 1758 aprint_error_dev(sc->sc_dev, "Unknown chip (ID %d)\n", chipid); 1759 1760 lm_setup_sensors(sc, lm78_sensors); 1761 sc->refresh_sensor_data = lm_refresh_sensor_data; 1762 return 1; 1763 } 1764 1765 static int 1766 wb_match(struct lm_softc *sc) 1767 { 1768 const char *model = NULL; 1769 int banksel, vendid, devid; 1770 1771 aprint_normal("\n"); 1772 /* Read vendor ID */ 1773 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 1774 lm_generic_banksel(sc, WB_BANKSEL_HBAC); 1775 vendid = (*sc->lm_readreg)(sc, WB_VENDID) << 8; 1776 lm_generic_banksel(sc, 0); 1777 vendid |= (*sc->lm_readreg)(sc, WB_VENDID); 1778 DPRINTF(("%s: winbond vend id 0x%x\n", __func__, vendid)); 1779 if (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS) 1780 return 0; 1781 1782 /* Read device/chip ID */ 1783 lm_generic_banksel(sc, WB_BANKSEL_B0); 1784 devid = (*sc->lm_readreg)(sc, LMD_CHIPID); 1785 sc->chipid = (*sc->lm_readreg)(sc, WB_BANK0_CHIPID); 1786 lm_generic_banksel(sc, banksel); 1787 DPRINTF(("%s: winbond chip id 0x%x\n", __func__, sc->chipid)); 1788 1789 switch(sc->chipid) { 1790 case WB_CHIPID_W83627HF: 1791 model = "W83627HF"; 1792 lm_setup_sensors(sc, w83627hf_sensors); 1793 break; 1794 case WB_CHIPID_W83627THF: 1795 model = "W83627THF"; 1796 lm_setup_sensors(sc, w83637hf_sensors); 1797 break; 1798 case WB_CHIPID_W83627EHF_A: 1799 model = "W83627EHF-A"; 1800 lm_setup_sensors(sc, w83627ehf_sensors); 1801 break; 1802 case WB_CHIPID_W83627EHF: 1803 model = "W83627EHF"; 1804 lm_setup_sensors(sc, w83627ehf_sensors); 1805 break; 1806 case WB_CHIPID_W83627DHG: 1807 model = "W83627DHG"; 1808 lm_setup_sensors(sc, w83627dhg_sensors); 1809 break; 1810 case WB_CHIPID_W83637HF: 1811 model = "W83637HF"; 1812 lm_generic_banksel(sc, WB_BANKSEL_B0); 1813 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9) 1814 sc->vrm9 = 1; 1815 lm_generic_banksel(sc, banksel); 1816 lm_setup_sensors(sc, w83637hf_sensors); 1817 break; 1818 case WB_CHIPID_W83697HF: 1819 model = "W83697HF"; 1820 lm_setup_sensors(sc, w83697hf_sensors); 1821 break; 1822 case WB_CHIPID_W83781D: 1823 case WB_CHIPID_W83781D_2: 1824 model = "W83781D"; 1825 lm_setup_sensors(sc, w83781d_sensors); 1826 break; 1827 case WB_CHIPID_W83782D: 1828 model = "W83782D"; 1829 lm_setup_sensors(sc, w83782d_sensors); 1830 break; 1831 case WB_CHIPID_W83783S: 1832 model = "W83783S"; 1833 lm_setup_sensors(sc, w83783s_sensors); 1834 break; 1835 case WB_CHIPID_W83791D: 1836 model = "W83791D"; 1837 lm_setup_sensors(sc, w83791d_sensors); 1838 break; 1839 case WB_CHIPID_W83791SD: 1840 model = "W83791SD"; 1841 break; 1842 case WB_CHIPID_W83792D: 1843 model = "W83792D"; 1844 lm_setup_sensors(sc, w83792d_sensors); 1845 break; 1846 case WB_CHIPID_AS99127F: 1847 if (vendid == WB_VENDID_ASUS) { 1848 model = "AS99127F"; 1849 lm_setup_sensors(sc, w83781d_sensors); 1850 } else { 1851 model = "AS99127F rev 2"; 1852 lm_setup_sensors(sc, as99127f_sensors); 1853 } 1854 break; 1855 default: 1856 aprint_normal_dev(sc->sc_dev, 1857 "unknown Winbond chip (ID 0x%x)\n", sc->chipid); 1858 /* Handle as a standard LM78. */ 1859 lm_setup_sensors(sc, lm78_sensors); 1860 sc->refresh_sensor_data = lm_refresh_sensor_data; 1861 return 1; 1862 } 1863 1864 aprint_normal_dev(sc->sc_dev, "Winbond %s Hardware monitor\n", model); 1865 1866 sc->refresh_sensor_data = wb_refresh_sensor_data; 1867 return 1; 1868 } 1869 1870 static void 1871 lm_setup_sensors(struct lm_softc *sc, struct lm_sensor *sensors) 1872 { 1873 int i; 1874 1875 for (i = 0; sensors[i].desc; i++) { 1876 sc->sensors[i].units = sensors[i].type; 1877 strlcpy(sc->sensors[i].desc, sensors[i].desc, 1878 sizeof(sc->sensors[i].desc)); 1879 sc->numsensors++; 1880 } 1881 sc->lm_sensors = sensors; 1882 } 1883 1884 static void 1885 lm_refresh_sensor_data(struct lm_softc *sc) 1886 { 1887 int i; 1888 1889 for (i = 0; i < sc->numsensors; i++) 1890 sc->lm_sensors[i].refresh(sc, i); 1891 } 1892 1893 static void 1894 lm_refresh_volt(struct lm_softc *sc, int n) 1895 { 1896 int data; 1897 1898 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 1899 if (data == 0xff) { 1900 sc->sensors[n].state = ENVSYS_SINVALID; 1901 } else { 1902 sc->sensors[n].flags = ENVSYS_FCHANGERFACT; 1903 sc->sensors[n].value_cur = (data << 4); 1904 if (sc->sensors[n].rfact) { 1905 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 1906 sc->sensors[n].value_cur /= 10; 1907 } else { 1908 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact; 1909 sc->sensors[n].value_cur /= 10; 1910 sc->sensors[n].rfact = sc->lm_sensors[n].rfact; 1911 } 1912 sc->sensors[n].state = ENVSYS_SVALID; 1913 } 1914 1915 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 1916 __func__, n, data, sc->sensors[n].value_cur)); 1917 } 1918 1919 static void 1920 lm_refresh_temp(struct lm_softc *sc, int n) 1921 { 1922 int data; 1923 1924 /* 1925 * The data sheet suggests that the range of the temperature 1926 * sensor is between -55 degC and +125 degC. 1927 */ 1928 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 1929 if (data > 0x7d && data < 0xc9) 1930 sc->sensors[n].state = ENVSYS_SINVALID; 1931 else { 1932 if (data & 0x80) 1933 data -= 0x100; 1934 sc->sensors[n].state = ENVSYS_SVALID; 1935 sc->sensors[n].value_cur = data * 1000000 + 273150000; 1936 } 1937 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 1938 __func__, n, data, sc->sensors[n].value_cur)); 1939 } 1940 1941 static void 1942 lm_refresh_fanrpm(struct lm_softc *sc, int n) 1943 { 1944 int data, divisor = 1; 1945 1946 /* 1947 * We might get more accurate fan readings by adjusting the 1948 * divisor, but that might interfere with APM or other SMM 1949 * BIOS code reading the fan speeds. 1950 */ 1951 1952 /* FAN3 has a fixed fan divisor. */ 1953 if (sc->lm_sensors[n].reg == LMD_FAN1 || 1954 sc->lm_sensors[n].reg == LMD_FAN2) { 1955 data = (*sc->lm_readreg)(sc, LMD_VIDFAN); 1956 if (sc->lm_sensors[n].reg == LMD_FAN1) 1957 divisor = (data >> 4) & 0x03; 1958 else 1959 divisor = (data >> 6) & 0x03; 1960 } 1961 1962 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 1963 if (data == 0xff || data == 0x00) 1964 sc->sensors[n].state = ENVSYS_SINVALID; 1965 else { 1966 sc->sensors[n].state = ENVSYS_SVALID; 1967 sc->sensors[n].value_cur = 1350000 / (data << divisor); 1968 } 1969 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 1970 __func__, n, data, sc->sensors[n].value_cur)); 1971 } 1972 1973 static void 1974 wb_refresh_sensor_data(struct lm_softc *sc) 1975 { 1976 int banksel, bank, i; 1977 1978 /* 1979 * Properly save and restore bank selection register. 1980 */ 1981 banksel = bank = sc->lm_readreg(sc, WB_BANKSEL); 1982 for (i = 0; i < sc->numsensors; i++) { 1983 if (bank != sc->lm_sensors[i].bank) { 1984 bank = sc->lm_sensors[i].bank; 1985 lm_generic_banksel(sc, bank); 1986 } 1987 sc->lm_sensors[i].refresh(sc, i); 1988 } 1989 lm_generic_banksel(sc, banksel); 1990 } 1991 1992 static void 1993 wb_w83637hf_refresh_vcore(struct lm_softc *sc, int n) 1994 { 1995 int data; 1996 1997 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 1998 /* 1999 * Depending on the voltage detection method, 2000 * one of the following formulas is used: 2001 * VRM8 method: value = raw * 0.016V 2002 * VRM9 method: value = raw * 0.00488V + 0.70V 2003 */ 2004 if (sc->vrm9) 2005 sc->sensors[n].value_cur = (data * 4880) + 700000; 2006 else 2007 sc->sensors[n].value_cur = (data * 16000); 2008 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2009 __func__, n, data, sc->sensors[n].value_cur)); 2010 } 2011 2012 static void 2013 wb_refresh_nvolt(struct lm_softc *sc, int n) 2014 { 2015 int data; 2016 2017 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2018 sc->sensors[n].flags = ENVSYS_FCHANGERFACT; 2019 sc->sensors[n].value_cur = ((data << 4) - WB_VREF); 2020 if (sc->sensors[n].rfact) 2021 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2022 else 2023 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact; 2024 2025 sc->sensors[n].value_cur /= 10; 2026 sc->sensors[n].value_cur += WB_VREF * 1000; 2027 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2028 __func__, n , data, sc->sensors[n].value_cur)); 2029 } 2030 2031 static void 2032 wb_w83627ehf_refresh_nvolt(struct lm_softc *sc, int n) 2033 { 2034 int data; 2035 2036 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2037 sc->sensors[n].value_cur = ((data << 3) - WB_W83627EHF_VREF); 2038 sc->sensors[n].flags = ENVSYS_FCHANGERFACT; 2039 if (sc->sensors[n].rfact) 2040 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2041 else 2042 sc->sensors[n].value_cur *= RFACT(232, 10); 2043 2044 sc->sensors[n].value_cur /= 10; 2045 sc->sensors[n].value_cur += WB_W83627EHF_VREF * 1000; 2046 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2047 __func__, n , data, sc->sensors[n].value_cur)); 2048 } 2049 2050 static void 2051 wb_refresh_temp(struct lm_softc *sc, int n) 2052 { 2053 int data; 2054 2055 /* 2056 * The data sheet suggests that the range of the temperature 2057 * sensor is between -55 degC and +125 degC. However, values 2058 * around -48 degC seem to be a very common bogus values. 2059 * Since such values are unreasonably low, we use -45 degC for 2060 * the lower limit instead. 2061 */ 2062 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1; 2063 data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7; 2064 if (data > 0xfffffff || (data > 0x0fa && data < 0x1a6)) { 2065 sc->sensors[n].state = ENVSYS_SINVALID; 2066 } else { 2067 if (data & 0x100) 2068 data -= 0x200; 2069 sc->sensors[n].state = ENVSYS_SVALID; 2070 sc->sensors[n].value_cur = data * 500000 + 273150000; 2071 } 2072 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2073 __func__, n , data, sc->sensors[n].value_cur)); 2074 } 2075 2076 static void 2077 wb_refresh_fanrpm(struct lm_softc *sc, int n) 2078 { 2079 int fan, data, divisor = 0; 2080 2081 /* 2082 * This is madness; the fan divisor bits are scattered all 2083 * over the place. 2084 */ 2085 2086 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2087 sc->lm_sensors[n].reg == LMD_FAN2 || 2088 sc->lm_sensors[n].reg == LMD_FAN3) { 2089 data = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2090 fan = (sc->lm_sensors[n].reg - LMD_FAN1); 2091 if ((data >> 5) & (1 << fan)) 2092 divisor |= 0x04; 2093 } 2094 2095 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2096 sc->lm_sensors[n].reg == LMD_FAN2) { 2097 data = (*sc->lm_readreg)(sc, LMD_VIDFAN); 2098 if (sc->lm_sensors[n].reg == LMD_FAN1) 2099 divisor |= (data >> 4) & 0x03; 2100 else 2101 divisor |= (data >> 6) & 0x03; 2102 } else if (sc->lm_sensors[n].reg == LMD_FAN3) { 2103 data = (*sc->lm_readreg)(sc, WB_PIN); 2104 divisor |= (data >> 6) & 0x03; 2105 } else if (sc->lm_sensors[n].reg == WB_BANK0_FAN4 || 2106 sc->lm_sensors[n].reg == WB_BANK0_FAN5) { 2107 data = (*sc->lm_readreg)(sc, WB_BANK0_FAN45); 2108 if (sc->lm_sensors[n].reg == WB_BANK0_FAN4) 2109 divisor |= (data >> 0) & 0x07; 2110 else 2111 divisor |= (data >> 4) & 0x07; 2112 } 2113 2114 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2115 if (data >= 0xff || data == 0x00) 2116 sc->sensors[n].state = ENVSYS_SINVALID; 2117 else { 2118 sc->sensors[n].state = ENVSYS_SVALID; 2119 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2120 } 2121 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2122 __func__, n , data, sc->sensors[n].value_cur)); 2123 } 2124 2125 static void 2126 wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n) 2127 { 2128 int reg, shift, data, divisor = 1; 2129 2130 shift = 0; 2131 2132 switch (sc->lm_sensors[n].reg) { 2133 case 0x28: 2134 reg = 0x47; shift = 0; 2135 break; 2136 case 0x29: 2137 reg = 0x47; shift = 4; 2138 break; 2139 case 0x2a: 2140 reg = 0x5b; shift = 0; 2141 break; 2142 case 0xb8: 2143 reg = 0x5b; shift = 4; 2144 break; 2145 case 0xb9: 2146 reg = 0x5c; shift = 0; 2147 break; 2148 case 0xba: 2149 reg = 0x5c; shift = 4; 2150 break; 2151 case 0xbe: 2152 reg = 0x9e; shift = 0; 2153 break; 2154 default: 2155 reg = 0; 2156 break; 2157 } 2158 2159 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2160 if (data == 0xff || data == 0x00) 2161 sc->sensors[n].state = ENVSYS_SINVALID; 2162 else { 2163 if (reg != 0) 2164 divisor = ((*sc->lm_readreg)(sc, reg) >> shift) & 0x7; 2165 sc->sensors[n].state = ENVSYS_SVALID; 2166 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2167 } 2168 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2169 __func__, n , data, sc->sensors[n].value_cur)); 2170 } 2171 2172 static void 2173 as_refresh_temp(struct lm_softc *sc, int n) 2174 { 2175 int data; 2176 2177 /* 2178 * It seems a shorted temperature diode produces an all-ones 2179 * bit pattern. 2180 */ 2181 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1; 2182 data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7; 2183 if (data == 0x1ff) 2184 sc->sensors[n].state = ENVSYS_SINVALID; 2185 else { 2186 if (data & 0x100) 2187 data -= 0x200; 2188 sc->sensors[n].state = ENVSYS_SVALID; 2189 sc->sensors[n].value_cur = data * 500000 + 273150000; 2190 } 2191 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2192 __func__, n, data, sc->sensors[n].value_cur)); 2193 } 2194