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