1/* $NetBSD: nslm7x.c,v 1.79 2022/12/16 00:02:28 msaitoh Exp $ */ 2 3/*- 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Bill Squier. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33__KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1.79 2022/12/16 00:02:28 msaitoh Exp $"); 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#include <sys/proc.h> 39#include <sys/device.h> 40#include <sys/module.h> 41#include <sys/conf.h> 42#include <sys/time.h> 43 44#include <sys/bus.h> 45 46#include <dev/isa/isareg.h> 47#include <dev/isa/isavar.h> 48#include <dev/isa/wbsioreg.h> 49 50#include <dev/sysmon/sysmonvar.h> 51 52#include <dev/ic/nslm7xvar.h> 53 54#include <sys/intr.h> 55 56#if defined(LMDEBUG) 57#define DPRINTF(x) do { printf x; } while (0) 58#else 59#define DPRINTF(x) 60#endif 61 62/* 63 * LM78-compatible chips can typically measure voltages up to 4.096 V. 64 * To measure higher voltages the input is attenuated with (external) 65 * resistors. Negative voltages are measured using inverting op amps 66 * and resistors. So we have to convert the sensor values back to 67 * real voltages by applying the appropriate resistor factor. 68 */ 69#define RFACT_NONE 10000 70#define RFACT(x, y) (RFACT_NONE * ((x) + (y)) / (y)) 71#define NRFACT(x, y) (-RFACT_NONE * (x) / (y)) 72 73#define LM_REFRESH_TIMO (2 * hz) /* 2 seconds */ 74 75static const struct wb_product *wb_lookup(struct lm_softc *, 76 const struct wb_product *, uint16_t); 77static int wb_match(struct lm_softc *); 78static int wb_attach(struct lm_softc *); 79static int nslm_match(struct lm_softc *); 80static int nslm_attach(struct lm_softc *); 81static int def_match(struct lm_softc *); 82static int def_attach(struct lm_softc *); 83static void wb_temp_diode_type(struct lm_softc *, int); 84static uint16_t wb_read_vendorid(struct lm_softc *); 85 86static void lm_refresh(void *); 87 88static void lm_generic_banksel(struct lm_softc *, uint8_t); 89static void lm_setup_sensors(struct lm_softc *, const struct lm_sensor *); 90static void lm_refresh_sensor_data(struct lm_softc *); 91static void lm_refresh_volt(struct lm_softc *, int); 92static void lm_refresh_temp(struct lm_softc *, int); 93static void lm_refresh_fanrpm(struct lm_softc *, int); 94 95static void wb_refresh_sensor_data(struct lm_softc *); 96static void wb_w83637hf_refresh_vcore(struct lm_softc *, int); 97static void wb_refresh_nvolt(struct lm_softc *, int); 98static void wb_w83627ehf_refresh_nvolt(struct lm_softc *, int); 99static void wb_refresh_temp(struct lm_softc *, int); 100static void wb_refresh_fanrpm(struct lm_softc *, int); 101static void wb_w83792d_refresh_fanrpm(struct lm_softc *, int); 102static void wb_nct6776f_refresh_fanrpm(struct lm_softc *, int); 103 104static void as_refresh_temp(struct lm_softc *, int); 105 106struct lm_chip { 107 int (*chip_match)(struct lm_softc *); 108 int (*chip_attach)(struct lm_softc *); 109}; 110 111static struct lm_chip lm_chips[] = { 112 { wb_match, wb_attach }, 113 { nslm_match, nslm_attach }, 114 { def_match, def_attach } /* Must be last */ 115}; 116 117/* LM78/78J/79/81 */ 118static const struct lm_sensor lm78_sensors[] = { 119 /* Voltage */ 120 { 121 .desc = "VCore A", 122 .type = ENVSYS_SVOLTS_DC, 123 .bank = 0, 124 .reg = 0x20, 125 .refresh = lm_refresh_volt, 126 .rfact = RFACT_NONE 127 }, 128 { 129 .desc = "VCore B", 130 .type = ENVSYS_SVOLTS_DC, 131 .bank = 0, 132 .reg = 0x21, 133 .refresh = lm_refresh_volt, 134 .rfact = RFACT_NONE 135 }, 136 { 137 .desc = "+3.3V", 138 .type = ENVSYS_SVOLTS_DC, 139 .bank = 0, 140 .reg = 0x22, 141 .refresh = lm_refresh_volt, 142 .rfact = RFACT_NONE 143 }, 144 { 145 .desc = "+5V", 146 .type = ENVSYS_SVOLTS_DC, 147 .bank = 0, 148 .reg = 0x23, 149 .refresh = lm_refresh_volt, 150 .rfact = RFACT(68, 100) 151 }, 152 { 153 .desc = "+12V", 154 .type = ENVSYS_SVOLTS_DC, 155 .bank = 0, 156 .reg = 0x24, 157 .refresh = lm_refresh_volt, 158 .rfact = RFACT(30, 10) 159 }, 160 { 161 .desc = "-12V", 162 .type = ENVSYS_SVOLTS_DC, 163 .bank = 0, 164 .reg = 0x25, 165 .refresh = lm_refresh_volt, 166 .rfact = NRFACT(240, 60) 167 }, 168 { 169 .desc = "-5V", 170 .type = ENVSYS_SVOLTS_DC, 171 .bank = 0, 172 .reg = 0x26, 173 .refresh = lm_refresh_volt, 174 .rfact = NRFACT(100, 60) 175 }, 176 177 /* Temperature */ 178 { 179 .desc = "Temp0", 180 .type = ENVSYS_STEMP, 181 .bank = 0, 182 .reg = 0x27, 183 .refresh = lm_refresh_temp, 184 .rfact = 0 185 }, 186 187 /* Fans */ 188 { 189 .desc = "Fan0", 190 .type = ENVSYS_SFANRPM, 191 .bank = 0, 192 .reg = 0x28, 193 .refresh = lm_refresh_fanrpm, 194 .rfact = 0 195 }, 196 { 197 .desc = "Fan1", 198 .type = ENVSYS_SFANRPM, 199 .bank = 0, 200 .reg = 0x29, 201 .refresh = lm_refresh_fanrpm, 202 .rfact = 0 203 }, 204 { 205 .desc = "Fan2", 206 .type = ENVSYS_SFANRPM, 207 .bank = 0, 208 .reg = 0x2a, 209 .refresh = lm_refresh_fanrpm, 210 .rfact = 0 211 }, 212 213 { .desc = NULL } 214}; 215 216/* W83627HF */ 217static const struct lm_sensor w83627hf_sensors[] = { 218 /* Voltage */ 219 { 220 .desc = "VCore A", 221 .type = ENVSYS_SVOLTS_DC, 222 .bank = 0, 223 .reg = 0x20, 224 .refresh = lm_refresh_volt, 225 .rfact = RFACT_NONE 226 }, 227 { 228 .desc = "VCore B", 229 .type = ENVSYS_SVOLTS_DC, 230 .bank = 0, 231 .reg = 0x21, 232 .refresh = lm_refresh_volt, 233 .rfact = RFACT_NONE 234 }, 235 { 236 .desc = "+3.3V", 237 .type = ENVSYS_SVOLTS_DC, 238 .bank = 0, 239 .reg = 0x22, 240 .refresh = lm_refresh_volt, 241 .rfact = RFACT_NONE 242 }, 243 { 244 .desc = "+5V", 245 .type = ENVSYS_SVOLTS_DC, 246 .bank = 0, 247 .reg = 0x23, 248 .refresh = lm_refresh_volt, 249 .rfact = RFACT(34, 50) 250 }, 251 { 252 .desc = "+12V", 253 .type = ENVSYS_SVOLTS_DC, 254 .bank = 0, 255 .reg = 0x24, 256 .refresh = lm_refresh_volt, 257 .rfact = RFACT(28, 10) 258 }, 259 { 260 .desc = "-12V", 261 .type = ENVSYS_SVOLTS_DC, 262 .bank = 0, 263 .reg = 0x25, 264 .refresh = wb_refresh_nvolt, 265 .rfact = RFACT(232, 56) 266 }, 267 { 268 .desc = "-5V", 269 .type = ENVSYS_SVOLTS_DC, 270 .bank = 0, 271 .reg = 0x26, 272 .refresh = wb_refresh_nvolt, 273 .rfact = RFACT(120, 56) 274 }, 275 { 276 .desc = "5VSB", 277 .type = ENVSYS_SVOLTS_DC, 278 .bank = 5, 279 .reg = 0x50, 280 .refresh = lm_refresh_volt, 281 .rfact = RFACT(17, 33) 282 }, 283 { 284 .desc = "VBAT", 285 .type = ENVSYS_SVOLTS_DC, 286 .bank = 5, 287 .reg = 0x51, 288 .refresh = lm_refresh_volt, 289 .rfact = RFACT_NONE 290 }, 291 292 /* Temperature */ 293 { 294 .desc = "Temp0", 295 .type = ENVSYS_STEMP, 296 .bank = 0, 297 .reg = 0x27, 298 .refresh = lm_refresh_temp, 299 .rfact = 0 300 }, 301 { 302 .desc = "Temp1", 303 .type = ENVSYS_STEMP, 304 .bank = 1, 305 .reg = 0x50, 306 .refresh = wb_refresh_temp, 307 .rfact = 0 308 }, 309 { 310 .desc = "Temp2", 311 .type = ENVSYS_STEMP, 312 .bank = 2, 313 .reg = 0x50, 314 .refresh = wb_refresh_temp, 315 .rfact = 0 316 }, 317 318 /* Fans */ 319 { 320 .desc = "Fan0", 321 .type = ENVSYS_SFANRPM, 322 .bank = 0, 323 .reg = 0x28, 324 .refresh = wb_refresh_fanrpm, 325 .rfact = 0 326 }, 327 { 328 .desc = "Fan1", 329 .type = ENVSYS_SFANRPM, 330 .bank = 0, 331 .reg = 0x29, 332 .refresh = wb_refresh_fanrpm, 333 .rfact = 0 334 }, 335 { 336 .desc = "Fan2", 337 .type = ENVSYS_SFANRPM, 338 .bank = 0, 339 .reg = 0x2a, 340 .refresh = wb_refresh_fanrpm, 341 .rfact = 0 342 }, 343 344 { .desc = NULL } 345}; 346 347/* W8627EHF */ 348 349/* 350 * The W83627EHF can measure voltages up to 2.048 V instead of the 351 * traditional 4.096 V. For measuring positive voltages, this can be 352 * accounted for by halving the resistor factor. Negative voltages 353 * need special treatment, also because the reference voltage is 2.048 V 354 * instead of the traditional 3.6 V. 355 */ 356static const struct lm_sensor w83627ehf_sensors[] = { 357 /* Voltage */ 358 { 359 .desc = "VCore", 360 .type = ENVSYS_SVOLTS_DC, 361 .bank = 0, 362 .reg = 0x20, 363 .refresh = lm_refresh_volt, 364 .rfact = RFACT_NONE / 2 365 }, 366 { 367 .desc = "+12V", 368 .type = ENVSYS_SVOLTS_DC, 369 .bank = 0, 370 .reg = 0x21, 371 .refresh = lm_refresh_volt, 372 .rfact = RFACT(56, 10) / 2 373 }, 374 { 375 .desc = "+3.3V", 376 .type = ENVSYS_SVOLTS_DC, 377 .bank = 0, 378 .reg = 0x22, 379 .refresh = lm_refresh_volt, 380 .rfact = RFACT(34, 34) / 2 381 }, 382 { 383 .desc = "VIN3", 384 .type = ENVSYS_SVOLTS_DC, 385 .bank = 0, 386 .reg = 0x23, 387 .refresh = lm_refresh_volt, 388 .rfact = RFACT(34, 34) / 2 389 }, 390 { 391 .desc = "-12V", 392 .type = ENVSYS_SVOLTS_DC, 393 .bank = 0, 394 .reg = 0x24, 395 .refresh = wb_w83627ehf_refresh_nvolt, 396 .rfact = 0 397 }, 398 { 399 .desc = "VIN5", 400 .type = ENVSYS_SVOLTS_DC, 401 .bank = 0, 402 .reg = 0x25, 403 .refresh = lm_refresh_volt, 404 .rfact = RFACT_NONE / 2 405 }, 406 { 407 .desc = "VIN6", 408 .type = ENVSYS_SVOLTS_DC, 409 .bank = 0, 410 .reg = 0x26, 411 .refresh = lm_refresh_volt, 412 .rfact = RFACT_NONE / 2 413 }, 414 { 415 .desc = "3.3VSB", 416 .type = ENVSYS_SVOLTS_DC, 417 .bank = 5, 418 .reg = 0x50, 419 .refresh = lm_refresh_volt, 420 .rfact = RFACT(34, 34) / 2 421 }, 422 { 423 .desc = "VBAT", 424 .type = ENVSYS_SVOLTS_DC, 425 .bank = 5, 426 .reg = 0x51, 427 .refresh = lm_refresh_volt, 428 .rfact = RFACT_NONE / 2 429 }, 430 { 431 .desc = "VIN8", 432 .type = ENVSYS_SVOLTS_DC, 433 .bank = 5, 434 .reg = 0x52, 435 .refresh = lm_refresh_volt, 436 .rfact = RFACT_NONE / 2 437 }, 438 439 /* Temperature */ 440 { 441 .desc = "Temp0", 442 .type = ENVSYS_STEMP, 443 .bank = 0, 444 .reg = 0x27, 445 .refresh = lm_refresh_temp, 446 .rfact = 0 447 }, 448 { 449 .desc = "Temp1", 450 .type = ENVSYS_STEMP, 451 .bank = 1, 452 .reg = 0x50, 453 .refresh = wb_refresh_temp, 454 .rfact = 0 455 }, 456 { 457 .desc = "Temp2", 458 .type = ENVSYS_STEMP, 459 .bank = 2, 460 .reg = 0x50, 461 .refresh = wb_refresh_temp, 462 .rfact = 0 463 }, 464 465 /* Fans */ 466 { 467 .desc = "Fan0", 468 .type = ENVSYS_SFANRPM, 469 .bank = 0, 470 .reg = 0x28, 471 .refresh = wb_refresh_fanrpm, 472 .rfact = 0 473 }, 474 { 475 .desc = "Fan1", 476 .type = ENVSYS_SFANRPM, 477 .bank = 0, 478 .reg = 0x29, 479 .refresh = wb_refresh_fanrpm, 480 .rfact = 0 481 }, 482 { 483 .desc = "Fan2", 484 .type = ENVSYS_SFANRPM, 485 .bank = 0, 486 .reg = 0x2a, 487 .refresh = wb_refresh_fanrpm, 488 .rfact = 0 489 }, 490 491 { .desc = NULL } 492}; 493 494/* W83627DHG */ 495static const struct lm_sensor w83627dhg_sensors[] = { 496 /* Voltage */ 497 { 498 .desc = "VCore", 499 .type = ENVSYS_SVOLTS_DC, 500 .bank = 0, 501 .reg = 0x20, 502 .refresh = lm_refresh_volt, 503 .rfact = RFACT_NONE / 2 504 }, 505 { 506 .desc = "+12V", 507 .type = ENVSYS_SVOLTS_DC, 508 .bank = 0, 509 .reg = 0x21, 510 .refresh = lm_refresh_volt, 511 .rfact = RFACT(56, 10) / 2 512 }, 513 { 514 .desc = "AVCC", 515 .type = ENVSYS_SVOLTS_DC, 516 .bank = 0, 517 .reg = 0x22, 518 .refresh = lm_refresh_volt, 519 .rfact = RFACT(34, 34) / 2 520 }, 521 { 522 .desc = "+3.3V", 523 .type = ENVSYS_SVOLTS_DC, 524 .bank = 0, 525 .reg = 0x23, 526 .refresh = lm_refresh_volt, 527 .rfact = RFACT(34, 34) / 2 528 }, 529 { 530 .desc = "-12V", 531 .type = ENVSYS_SVOLTS_DC, 532 .bank = 0, 533 .reg = 0x24, 534 .refresh = wb_w83627ehf_refresh_nvolt, 535 .rfact = 0 536 }, 537 { 538 .desc = "+5V", 539 .type = ENVSYS_SVOLTS_DC, 540 .bank = 0, 541 .reg = 0x25, 542 .refresh = lm_refresh_volt, 543 .rfact = 16000 544 }, 545 { 546 .desc = "VIN3", 547 .type = ENVSYS_SVOLTS_DC, 548 .bank = 0, 549 .reg = 0x26, 550 .refresh = lm_refresh_volt, 551 .rfact = RFACT_NONE 552 }, 553 { 554 .desc = "+3.3VSB", 555 .type = ENVSYS_SVOLTS_DC, 556 .bank = 5, 557 .reg = 0x50, 558 .refresh = lm_refresh_volt, 559 .rfact = RFACT(34, 34) / 2 560 }, 561 { 562 .desc = "VBAT", 563 .type = ENVSYS_SVOLTS_DC, 564 .bank = 5, 565 .reg = 0x51, 566 .refresh = lm_refresh_volt, 567 .rfact = RFACT(34, 34) / 2 568 }, 569 570 /* Temperature */ 571 { 572 .desc = "MB Temperature", 573 .type = ENVSYS_STEMP, 574 .bank = 0, 575 .reg = 0x27, 576 .refresh = lm_refresh_temp, 577 .rfact = 0 578 }, 579 { 580 .desc = "CPU Temperature", 581 .type = ENVSYS_STEMP, 582 .bank = 1, 583 .reg = 0x50, 584 .refresh = lm_refresh_temp, 585 .rfact = 0 586 }, 587 { 588 .desc = "Aux Temp", 589 .type = ENVSYS_STEMP, 590 .bank = 2, 591 .reg = 0x50, 592 .refresh = lm_refresh_temp, 593 .rfact = 0 594 }, 595 596 /* Fans */ 597 { 598 .desc = "System Fan", 599 .type = ENVSYS_SFANRPM, 600 .bank = 0, 601 .reg = 0x28, 602 .refresh = wb_refresh_fanrpm, 603 .rfact = 0 604 }, 605 { 606 .desc = "CPU Fan", 607 .type = ENVSYS_SFANRPM, 608 .bank = 0, 609 .reg = 0x29, 610 .refresh = wb_refresh_fanrpm, 611 .rfact = 0 612 }, 613 { 614 .desc = "Aux Fan", 615 .type = ENVSYS_SFANRPM, 616 .bank = 0, 617 .reg = 0x2a, 618 .refresh = wb_refresh_fanrpm, 619 .rfact = 0 620 }, 621 622 { .desc = NULL } 623}; 624 625/* W83637HF */ 626static const struct lm_sensor w83637hf_sensors[] = { 627 /* Voltage */ 628 { 629 .desc = "VCore", 630 .type = ENVSYS_SVOLTS_DC, 631 .bank = 0, 632 .reg = 0x20, 633 .refresh = wb_w83637hf_refresh_vcore, 634 .rfact = 0 635 }, 636 { 637 .desc = "+12V", 638 .type = ENVSYS_SVOLTS_DC, 639 .bank = 0, 640 .reg = 0x21, 641 .refresh = lm_refresh_volt, 642 .rfact = RFACT(28, 10) 643 }, 644 { 645 .desc = "+3.3V", 646 .type = ENVSYS_SVOLTS_DC, 647 .bank = 0, 648 .reg = 0x22, 649 .refresh = lm_refresh_volt, 650 .rfact = RFACT_NONE 651 }, 652 { 653 .desc = "+5V", 654 .type = ENVSYS_SVOLTS_DC, 655 .bank = 0, 656 .reg = 0x23, 657 .refresh = lm_refresh_volt, 658 .rfact = RFACT(34, 51) 659 }, 660 { 661 .desc = "-12V", 662 .type = ENVSYS_SVOLTS_DC, 663 .bank = 0, 664 .reg = 0x24, 665 .refresh = wb_refresh_nvolt, 666 .rfact = RFACT(232, 56) 667 }, 668 { 669 .desc = "5VSB", 670 .type = ENVSYS_SVOLTS_DC, 671 .bank = 5, 672 .reg = 0x50, 673 .refresh = lm_refresh_volt, 674 .rfact = RFACT(34, 51) 675 }, 676 { 677 .desc = "VBAT", 678 .type = ENVSYS_SVOLTS_DC, 679 .bank = 5, 680 .reg = 0x51, 681 .refresh = lm_refresh_volt, 682 .rfact = RFACT_NONE 683 }, 684 685 /* Temperature */ 686 { 687 .desc = "Temp0", 688 .type = ENVSYS_STEMP, 689 .bank = 0, 690 .reg = 0x27, 691 .refresh = lm_refresh_temp, 692 .rfact = 0 693 }, 694 { 695 .desc = "Temp1", 696 .type = ENVSYS_STEMP, 697 .bank = 1, 698 .reg = 0x50, 699 .refresh = wb_refresh_temp, 700 .rfact = 0 701 }, 702 { 703 .desc = "Temp2", 704 .type = ENVSYS_STEMP, 705 .bank = 2, 706 .reg = 0x50, 707 .refresh = wb_refresh_temp, 708 .rfact = 0 709 }, 710 711 /* Fans */ 712 { 713 .desc = "Fan0", 714 .type = ENVSYS_SFANRPM, 715 .bank = 0, 716 .reg = 0x28, 717 .refresh = wb_refresh_fanrpm, 718 .rfact = 0 719 }, 720 { 721 .desc = "Fan1", 722 .type = ENVSYS_SFANRPM, 723 .bank = 0, 724 .reg = 0x29, 725 .refresh = wb_refresh_fanrpm, 726 .rfact = 0 727 }, 728 { 729 .desc = "Fan2", 730 .type = ENVSYS_SFANRPM, 731 .bank = 0, 732 .reg = 0x2a, 733 .refresh = wb_refresh_fanrpm, 734 .rfact = 0 735 }, 736 737 { .desc = NULL } 738}; 739 740/* W83697HF */ 741static const struct lm_sensor w83697hf_sensors[] = { 742 /* Voltage */ 743 { 744 .desc = "VCore", 745 .type = ENVSYS_SVOLTS_DC, 746 .bank = 0, 747 .reg = 0x20, 748 .refresh = lm_refresh_volt, 749 .rfact = RFACT_NONE 750 }, 751 { 752 .desc = "+3.3V", 753 .type = ENVSYS_SVOLTS_DC, 754 .bank = 0, 755 .reg = 0x22, 756 .refresh = lm_refresh_volt, 757 .rfact = RFACT_NONE 758 }, 759 { 760 .desc = "+5V", 761 .type = ENVSYS_SVOLTS_DC, 762 .bank = 0, 763 .reg = 0x23, 764 .refresh = lm_refresh_volt, 765 .rfact = RFACT(34, 50) 766 }, 767 { 768 .desc = "+12V", 769 .type = ENVSYS_SVOLTS_DC, 770 .bank = 0, 771 .reg = 0x24, 772 .refresh = lm_refresh_volt, 773 .rfact = RFACT(28, 10) 774 }, 775 { 776 .desc = "-12V", 777 .type = ENVSYS_SVOLTS_DC, 778 .bank = 0, 779 .reg = 0x25, 780 .refresh = wb_refresh_nvolt, 781 .rfact = RFACT(232, 56) 782 }, 783 { 784 .desc = "-5V", 785 .type = ENVSYS_SVOLTS_DC, 786 .bank = 0, 787 .reg = 0x26, 788 .refresh = wb_refresh_nvolt, 789 .rfact = RFACT(120, 56) 790 }, 791 { 792 .desc = "5VSB", 793 .type = ENVSYS_SVOLTS_DC, 794 .bank = 5, 795 .reg = 0x50, 796 .refresh = lm_refresh_volt, 797 .rfact = RFACT(17, 33) 798 }, 799 { 800 .desc = "VBAT", 801 .type = ENVSYS_SVOLTS_DC, 802 .bank = 5, 803 .reg = 0x51, 804 .refresh = lm_refresh_volt, 805 .rfact = RFACT_NONE 806 }, 807 808 /* Temperature */ 809 { 810 .desc = "Temp0", 811 .type = ENVSYS_STEMP, 812 .bank = 0, 813 .reg = 0x27, 814 .refresh = lm_refresh_temp, 815 .rfact = 0 816 }, 817 { 818 .desc = "Temp1", 819 .type = ENVSYS_STEMP, 820 .bank = 1, 821 .reg = 0x50, 822 .refresh = wb_refresh_temp, 823 .rfact = 0 824 }, 825 826 /* Fans */ 827 { 828 .desc = "Fan0", 829 .type = ENVSYS_SFANRPM, 830 .bank = 0, 831 .reg = 0x28, 832 .refresh = wb_refresh_fanrpm, 833 .rfact = 0 834 }, 835 { 836 .desc = "Fan1", 837 .type = ENVSYS_SFANRPM, 838 .bank = 0, 839 .reg = 0x29, 840 .refresh = wb_refresh_fanrpm, 841 .rfact = 0 842 }, 843 844 { .desc = NULL } 845}; 846 847/* W83781D */ 848 849/* 850 * The datasheet doesn't mention the (internal) resistors used for the 851 * +5V, but using the values from the W83782D datasheets seems to 852 * provide sensible results. 853 */ 854static const struct lm_sensor w83781d_sensors[] = { 855 /* Voltage */ 856 { 857 .desc = "VCore A", 858 .type = ENVSYS_SVOLTS_DC, 859 .bank = 0, 860 .reg = 0x20, 861 .refresh = lm_refresh_volt, 862 .rfact = RFACT_NONE 863 }, 864 { 865 .desc = "VCore B", 866 .type = ENVSYS_SVOLTS_DC, 867 .bank = 0, 868 .reg = 0x21, 869 .refresh = lm_refresh_volt, 870 .rfact = RFACT_NONE 871 }, 872 { 873 .desc = "+3.3V", 874 .type = ENVSYS_SVOLTS_DC, 875 .bank = 0, 876 .reg = 0x22, 877 .refresh = lm_refresh_volt, 878 .rfact = RFACT_NONE 879 }, 880 { 881 .desc = "+5V", 882 .type = ENVSYS_SVOLTS_DC, 883 .bank = 0, 884 .reg = 0x23, 885 .refresh = lm_refresh_volt, 886 .rfact = RFACT(34, 50) 887 }, 888 { 889 .desc = "+12V", 890 .type = ENVSYS_SVOLTS_DC, 891 .bank = 0, 892 .reg = 0x24, 893 .refresh = lm_refresh_volt, 894 .rfact = RFACT(28, 10) 895 }, 896 { 897 .desc = "-12V", 898 .type = ENVSYS_SVOLTS_DC, 899 .bank = 0, 900 .reg = 0x25, 901 .refresh = lm_refresh_volt, 902 .rfact = NRFACT(2100, 604) 903 }, 904 { 905 .desc = "-5V", 906 .type = ENVSYS_SVOLTS_DC, 907 .bank = 0, 908 .reg = 0x26, 909 .refresh = lm_refresh_volt, 910 .rfact = NRFACT(909, 604) 911 }, 912 913 /* Temperature */ 914 { 915 .desc = "Temp0", 916 .type = ENVSYS_STEMP, 917 .bank = 0, 918 .reg = 0x27, 919 .refresh = lm_refresh_temp, 920 .rfact = 0 921 }, 922 { 923 .desc = "Temp1", 924 .type = ENVSYS_STEMP, 925 .bank = 1, 926 .reg = 0x50, 927 .refresh = wb_refresh_temp, 928 .rfact = 0 929 }, 930 { 931 .desc = "Temp2", 932 .type = ENVSYS_STEMP, 933 .bank = 2, 934 .reg = 0x50, 935 .refresh = wb_refresh_temp, 936 .rfact = 0 937 }, 938 939 /* Fans */ 940 { 941 .desc = "Fan0", 942 .type = ENVSYS_SFANRPM, 943 .bank = 0, 944 .reg = 0x28, 945 .refresh = lm_refresh_fanrpm, 946 .rfact = 0 947 }, 948 { 949 .desc = "Fan1", 950 .type = ENVSYS_SFANRPM, 951 .bank = 0, 952 .reg = 0x29, 953 .refresh = lm_refresh_fanrpm, 954 .rfact = 0 955 }, 956 { 957 .desc = "Fan2", 958 .type = ENVSYS_SFANRPM, 959 .bank = 0, 960 .reg = 0x2a, 961 .refresh = lm_refresh_fanrpm, 962 .rfact = 0 963 }, 964 965 { .desc = NULL } 966}; 967 968/* W83782D */ 969static const struct lm_sensor w83782d_sensors[] = { 970 /* Voltage */ 971 { 972 .desc = "VCore", 973 .type = ENVSYS_SVOLTS_DC, 974 .bank = 0, 975 .reg = 0x20, 976 .refresh = lm_refresh_volt, 977 .rfact = RFACT_NONE 978 }, 979 { 980 .desc = "VINR0", 981 .type = ENVSYS_SVOLTS_DC, 982 .bank = 0, 983 .reg = 0x21, 984 .refresh = lm_refresh_volt, 985 .rfact = RFACT_NONE 986 }, 987 { 988 .desc = "+3.3V", 989 .type = ENVSYS_SVOLTS_DC, 990 .bank = 0, 991 .reg = 0x22, 992 .refresh = lm_refresh_volt, 993 .rfact = RFACT_NONE 994 }, 995 { 996 .desc = "+5V", 997 .type = ENVSYS_SVOLTS_DC, 998 .bank = 0, 999 .reg = 0x23, 1000 .refresh = lm_refresh_volt, 1001 .rfact = RFACT(34, 50) 1002 }, 1003 { 1004 .desc = "+12V", 1005 .type = ENVSYS_SVOLTS_DC, 1006 .bank = 0, 1007 .reg = 0x24, 1008 .refresh = lm_refresh_volt, 1009 .rfact = RFACT(28, 10) 1010 }, 1011 { 1012 .desc = "-12V", 1013 .type = ENVSYS_SVOLTS_DC, 1014 .bank = 0, 1015 .reg = 0x25, 1016 .refresh = wb_refresh_nvolt, 1017 .rfact = RFACT(232, 56) 1018 }, 1019 { 1020 .desc = "-5V", 1021 .type = ENVSYS_SVOLTS_DC, 1022 .bank = 0, 1023 .reg = 0x26, 1024 .refresh = wb_refresh_nvolt, 1025 .rfact = RFACT(120, 56) 1026 }, 1027 { 1028 .desc = "5VSB", 1029 .type = ENVSYS_SVOLTS_DC, 1030 .bank = 5, 1031 .reg = 0x50, 1032 .refresh = lm_refresh_volt, 1033 .rfact = RFACT(17, 33) 1034 }, 1035 { 1036 .desc = "VBAT", 1037 .type = ENVSYS_SVOLTS_DC, 1038 .bank = 5, 1039 .reg = 0x51, 1040 .refresh = lm_refresh_volt, 1041 .rfact = RFACT_NONE 1042 }, 1043 1044 /* Temperature */ 1045 { 1046 .desc = "Temp0", 1047 .type = ENVSYS_STEMP, 1048 .bank = 0, 1049 .reg = 0x27, 1050 .refresh = lm_refresh_temp, 1051 .rfact = 0 1052 }, 1053 { 1054 .desc = "Temp1", 1055 .type = ENVSYS_STEMP, 1056 .bank = 1, 1057 .reg = 0x50, 1058 .refresh = wb_refresh_temp, 1059 .rfact = 0 1060 }, 1061 { 1062 .desc = "Temp2", 1063 .type = ENVSYS_STEMP, 1064 .bank = 2, 1065 .reg = 0x50, 1066 .refresh = wb_refresh_temp, 1067 .rfact = 0 1068 }, 1069 1070 /* Fans */ 1071 { 1072 .desc = "Fan0", 1073 .type = ENVSYS_SFANRPM, 1074 .bank = 0, 1075 .reg = 0x28, 1076 .refresh = wb_refresh_fanrpm, 1077 .rfact = 0 1078 }, 1079 { 1080 .desc = "Fan1", 1081 .type = ENVSYS_SFANRPM, 1082 .bank = 0, 1083 .reg = 0x29, 1084 .refresh = wb_refresh_fanrpm, 1085 .rfact = 0 1086 }, 1087 { 1088 .desc = "Fan2", 1089 .type = ENVSYS_SFANRPM, 1090 .bank = 0, 1091 .reg = 0x2a, 1092 .refresh = wb_refresh_fanrpm, 1093 .rfact = 0 1094 }, 1095 1096 { .desc = NULL } 1097}; 1098 1099/* W83783S */ 1100static const struct lm_sensor w83783s_sensors[] = { 1101 /* Voltage */ 1102 { 1103 .desc = "VCore", 1104 .type = ENVSYS_SVOLTS_DC, 1105 .bank = 0, 1106 .reg = 0x20, 1107 .refresh = lm_refresh_volt, 1108 .rfact = RFACT_NONE 1109 }, 1110 { 1111 .desc = "+3.3V", 1112 .type = ENVSYS_SVOLTS_DC, 1113 .bank = 0, 1114 .reg = 0x22, 1115 .refresh = lm_refresh_volt, 1116 .rfact = RFACT_NONE 1117 }, 1118 { 1119 .desc = "+5V", 1120 .type = ENVSYS_SVOLTS_DC, 1121 .bank = 0, 1122 .reg = 0x23, 1123 .refresh = lm_refresh_volt, 1124 .rfact = RFACT(34, 50) 1125 }, 1126 { 1127 .desc = "+12V", 1128 .type = ENVSYS_SVOLTS_DC, 1129 .bank = 0, 1130 .reg = 0x24, 1131 .refresh = lm_refresh_volt, 1132 .rfact = RFACT(28, 10) 1133 }, 1134 { 1135 .desc = "-12V", 1136 .type = ENVSYS_SVOLTS_DC, 1137 .bank = 0, 1138 .reg = 0x25, 1139 .refresh = wb_refresh_nvolt, 1140 .rfact = RFACT(232, 56) 1141 }, 1142 { 1143 .desc = "-5V", 1144 .type = ENVSYS_SVOLTS_DC, 1145 .bank = 0, 1146 .reg = 0x26, 1147 .refresh = wb_refresh_nvolt, 1148 .rfact = RFACT(120, 56) 1149 }, 1150 1151 /* Temperature */ 1152 { 1153 .desc = "Temp0", 1154 .type = ENVSYS_STEMP, 1155 .bank = 0, 1156 .reg = 0x27, 1157 .refresh = lm_refresh_temp, 1158 .rfact = 0 1159 }, 1160 { 1161 .desc = "Temp1", 1162 .type = ENVSYS_STEMP, 1163 .bank = 1, 1164 .reg = 0x50, 1165 .refresh = wb_refresh_temp, 1166 .rfact = 0 1167 }, 1168 1169 /* Fans */ 1170 { 1171 .desc = "Fan0", 1172 .type = ENVSYS_SFANRPM, 1173 .bank = 0, 1174 .reg = 0x28, 1175 .refresh = wb_refresh_fanrpm, 1176 .rfact = 0 1177 }, 1178 { 1179 .desc = "Fan1", 1180 .type = ENVSYS_SFANRPM, 1181 .bank = 0, 1182 .reg = 0x29, 1183 .refresh = wb_refresh_fanrpm, 1184 .rfact = 0 1185 }, 1186 { 1187 .desc = "Fan2", 1188 .type = ENVSYS_SFANRPM, 1189 .bank = 0, 1190 .reg = 0x2a, 1191 .refresh = wb_refresh_fanrpm, 1192 .rfact = 0 1193 }, 1194 1195 { .desc = NULL } 1196}; 1197 1198/* W83791D */ 1199static const struct lm_sensor w83791d_sensors[] = { 1200 /* Voltage */ 1201 { 1202 .desc = "VCore", 1203 .type = ENVSYS_SVOLTS_DC, 1204 .bank = 0, 1205 .reg = 0x20, 1206 .refresh = lm_refresh_volt, 1207 .rfact = 10000 1208 }, 1209 { 1210 .desc = "VINR0", 1211 .type = ENVSYS_SVOLTS_DC, 1212 .bank = 0, 1213 .reg = 0x21, 1214 .refresh = lm_refresh_volt, 1215 .rfact = 10000 1216 }, 1217 { 1218 .desc = "+3.3V", 1219 .type = ENVSYS_SVOLTS_DC, 1220 .bank = 0, 1221 .reg = 0x22, 1222 .refresh = lm_refresh_volt, 1223 .rfact = 10000 1224 }, 1225 { 1226 .desc = "+5V", 1227 .type = ENVSYS_SVOLTS_DC, 1228 .bank = 0, 1229 .reg = 0x23, 1230 .refresh = lm_refresh_volt, 1231 .rfact = RFACT(34, 50) 1232 }, 1233 { 1234 .desc = "+12V", 1235 .type = ENVSYS_SVOLTS_DC, 1236 .bank = 0, 1237 .reg = 0x24, 1238 .refresh = lm_refresh_volt, 1239 .rfact = RFACT(28, 10) 1240 }, 1241 { 1242 .desc = "-12V", 1243 .type = ENVSYS_SVOLTS_DC, 1244 .bank = 0, 1245 .reg = 0x25, 1246 .refresh = wb_refresh_nvolt, 1247 .rfact = RFACT(232, 56) 1248 }, 1249 { 1250 .desc = "-5V", 1251 .type = ENVSYS_SVOLTS_DC, 1252 .bank = 0, 1253 .reg = 0x26, 1254 .refresh = wb_refresh_nvolt, 1255 .rfact = RFACT(120, 56) 1256 }, 1257 { 1258 .desc = "5VSB", 1259 .type = ENVSYS_SVOLTS_DC, 1260 .bank = 0, 1261 .reg = 0xb0, 1262 .refresh = lm_refresh_volt, 1263 .rfact = RFACT(17, 33) 1264 }, 1265 { 1266 .desc = "VBAT", 1267 .type = ENVSYS_SVOLTS_DC, 1268 .bank = 0, 1269 .reg = 0xb1, 1270 .refresh = lm_refresh_volt, 1271 .rfact = RFACT_NONE 1272 }, 1273 { 1274 .desc = "VINR1", 1275 .type = ENVSYS_SVOLTS_DC, 1276 .bank = 0, 1277 .reg = 0xb2, 1278 .refresh = lm_refresh_volt, 1279 .rfact = RFACT_NONE 1280 }, 1281 1282 /* Temperature */ 1283 { 1284 .desc = "Temp0", 1285 .type = ENVSYS_STEMP, 1286 .bank = 0, 1287 .reg = 0x27, 1288 .refresh = lm_refresh_temp, 1289 .rfact = 0 1290 }, 1291 { 1292 .desc = "Temp1", 1293 .type = ENVSYS_STEMP, 1294 .bank = 0, 1295 .reg = 0xc0, 1296 .refresh = wb_refresh_temp, 1297 .rfact = 0 1298 }, 1299 { 1300 .desc = "Temp2", 1301 .type = ENVSYS_STEMP, 1302 .bank = 0, 1303 .reg = 0xc8, 1304 .refresh = wb_refresh_temp, 1305 .rfact = 0 1306 }, 1307 1308 /* Fans */ 1309 { 1310 .desc = "Fan0", 1311 .type = ENVSYS_SFANRPM, 1312 .bank = 0, 1313 .reg = 0x28, 1314 .refresh = wb_refresh_fanrpm, 1315 .rfact = 0 1316 }, 1317 { 1318 .desc = "Fan1", 1319 .type = ENVSYS_SFANRPM, 1320 .bank = 0, 1321 .reg = 0x29, 1322 .refresh = wb_refresh_fanrpm, 1323 .rfact = 0 1324 }, 1325 { 1326 .desc = "Fan2", 1327 .type = ENVSYS_SFANRPM, 1328 .bank = 0, 1329 .reg = 0x2a, 1330 .refresh = wb_refresh_fanrpm, 1331 .rfact = 0 1332 }, 1333 { 1334 .desc = "Fan3", 1335 .type = ENVSYS_SFANRPM, 1336 .bank = 0, 1337 .reg = 0xba, 1338 .refresh = wb_refresh_fanrpm, 1339 .rfact = 0 1340 }, 1341 { 1342 .desc = "Fan4", 1343 .type = ENVSYS_SFANRPM, 1344 .bank = 0, 1345 .reg = 0xbb, 1346 .refresh = wb_refresh_fanrpm, 1347 .rfact = 0 1348 }, 1349 1350 { .desc = NULL } 1351}; 1352 1353/* W83792D */ 1354static const struct lm_sensor w83792d_sensors[] = { 1355 /* Voltage */ 1356 { 1357 .desc = "VCore A", 1358 .type = ENVSYS_SVOLTS_DC, 1359 .bank = 0, 1360 .reg = 0x20, 1361 .refresh = lm_refresh_volt, 1362 .rfact = RFACT_NONE 1363 }, 1364 { 1365 .desc = "VCore B", 1366 .type = ENVSYS_SVOLTS_DC, 1367 .bank = 0, 1368 .reg = 0x21, 1369 .refresh = lm_refresh_volt, 1370 .rfact = RFACT_NONE 1371 }, 1372 { 1373 .desc = "+3.3V", 1374 .type = ENVSYS_SVOLTS_DC, 1375 .bank = 0, 1376 .reg = 0x22, 1377 .refresh = lm_refresh_volt, 1378 .rfact = RFACT_NONE 1379 }, 1380 { 1381 .desc = "-5V", 1382 .type = ENVSYS_SVOLTS_DC, 1383 .bank = 0, 1384 .reg = 0x23, 1385 .refresh = wb_refresh_nvolt, 1386 .rfact = RFACT(120, 56) 1387 }, 1388 { 1389 .desc = "+12V", 1390 .type = ENVSYS_SVOLTS_DC, 1391 .bank = 0, 1392 .reg = 0x24, 1393 .refresh = lm_refresh_volt, 1394 .rfact = RFACT(28, 10) 1395 }, 1396 { 1397 .desc = "-12V", 1398 .type = ENVSYS_SVOLTS_DC, 1399 .bank = 0, 1400 .reg = 0x25, 1401 .refresh = wb_refresh_nvolt, 1402 .rfact = RFACT(232, 56) 1403 }, 1404 { 1405 .desc = "+5V", 1406 .type = ENVSYS_SVOLTS_DC, 1407 .bank = 0, 1408 .reg = 0x26, 1409 .refresh = lm_refresh_volt, 1410 .rfact = RFACT(34, 50) 1411 }, 1412 { 1413 .desc = "5VSB", 1414 .type = ENVSYS_SVOLTS_DC, 1415 .bank = 0, 1416 .reg = 0xb0, 1417 .refresh = lm_refresh_volt, 1418 .rfact = RFACT(17, 33) 1419 }, 1420 { 1421 .desc = "VBAT", 1422 .type = ENVSYS_SVOLTS_DC, 1423 .bank = 0, 1424 .reg = 0xb1, 1425 .refresh = lm_refresh_volt, 1426 .rfact = RFACT_NONE 1427 }, 1428 1429 /* Temperature */ 1430 { 1431 .desc = "Temp0", 1432 .type = ENVSYS_STEMP, 1433 .bank = 0, 1434 .reg = 0x27, 1435 .refresh = lm_refresh_temp, 1436 .rfact = 0 1437 }, 1438 { 1439 .desc = "Temp1", 1440 .type = ENVSYS_STEMP, 1441 .bank = 0, 1442 .reg = 0xc0, 1443 .refresh = wb_refresh_temp, 1444 .rfact = 0 1445 }, 1446 { 1447 .desc = "Temp2", 1448 .type = ENVSYS_STEMP, 1449 .bank = 0, 1450 .reg = 0xc8, 1451 .refresh = wb_refresh_temp, 1452 .rfact = 0 1453 }, 1454 1455 /* Fans */ 1456 { 1457 .desc = "Fan0", 1458 .type = ENVSYS_SFANRPM, 1459 .bank = 0, 1460 .reg = 0x28, 1461 .refresh = wb_w83792d_refresh_fanrpm, 1462 .rfact = 0 1463 }, 1464 { 1465 .desc = "Fan1", 1466 .type = ENVSYS_SFANRPM, 1467 .bank = 0, 1468 .reg = 0x29, 1469 .refresh = wb_w83792d_refresh_fanrpm, 1470 .rfact = 0 1471 }, 1472 { 1473 .desc = "Fan2", 1474 .type = ENVSYS_SFANRPM, 1475 .bank = 0, 1476 .reg = 0x2a, 1477 .refresh = wb_w83792d_refresh_fanrpm, 1478 .rfact = 0 1479 }, 1480 { 1481 .desc = "Fan3", 1482 .type = ENVSYS_SFANRPM, 1483 .bank = 0, 1484 .reg = 0xb8, 1485 .refresh = wb_w83792d_refresh_fanrpm, 1486 .rfact = 0 1487 }, 1488 { 1489 .desc = "Fan4", 1490 .type = ENVSYS_SFANRPM, 1491 .bank = 0, 1492 .reg = 0xb9, 1493 .refresh = wb_w83792d_refresh_fanrpm, 1494 .rfact = 0 1495 }, 1496 { 1497 .desc = "Fan5", 1498 .type = ENVSYS_SFANRPM, 1499 .bank = 0, 1500 .reg = 0xba, 1501 .refresh = wb_w83792d_refresh_fanrpm, 1502 .rfact = 0 1503 }, 1504 { 1505 .desc = "Fan6", 1506 .type = ENVSYS_SFANRPM, 1507 .bank = 0, 1508 .reg = 0xbe, 1509 .refresh = wb_w83792d_refresh_fanrpm, 1510 .rfact = 0 1511 }, 1512 1513 { .desc = NULL } 1514}; 1515 1516/* AS99127F */ 1517static const struct lm_sensor as99127f_sensors[] = { 1518 /* Voltage */ 1519 { 1520 .desc = "VCore A", 1521 .type = ENVSYS_SVOLTS_DC, 1522 .bank = 0, 1523 .reg = 0x20, 1524 .refresh = lm_refresh_volt, 1525 .rfact = RFACT_NONE 1526 }, 1527 { 1528 .desc = "VCore B", 1529 .type = ENVSYS_SVOLTS_DC, 1530 .bank = 0, 1531 .reg = 0x21, 1532 .refresh = lm_refresh_volt, 1533 .rfact = RFACT_NONE 1534 }, 1535 { 1536 .desc = "+3.3V", 1537 .type = ENVSYS_SVOLTS_DC, 1538 .bank = 0, 1539 .reg = 0x22, 1540 .refresh = lm_refresh_volt, 1541 .rfact = RFACT_NONE 1542 }, 1543 { 1544 .desc = "+5V", 1545 .type = ENVSYS_SVOLTS_DC, 1546 .bank = 0, 1547 .reg = 0x23, 1548 .refresh = lm_refresh_volt, 1549 .rfact = RFACT(34, 50) 1550 }, 1551 { 1552 .desc = "+12V", 1553 .type = ENVSYS_SVOLTS_DC, 1554 .bank = 0, 1555 .reg = 0x24, 1556 .refresh = lm_refresh_volt, 1557 .rfact = RFACT(28, 10) 1558 }, 1559 { 1560 .desc = "-12V", 1561 .type = ENVSYS_SVOLTS_DC, 1562 .bank = 0, 1563 .reg = 0x25, 1564 .refresh = wb_refresh_nvolt, 1565 .rfact = RFACT(232, 56) 1566 }, 1567 { 1568 .desc = "-5V", 1569 .type = ENVSYS_SVOLTS_DC, 1570 .bank = 0, 1571 .reg = 0x26, 1572 .refresh = wb_refresh_nvolt, 1573 .rfact = RFACT(120, 56) 1574 }, 1575 1576 /* Temperature */ 1577 { 1578 .desc = "Temp0", 1579 .type = ENVSYS_STEMP, 1580 .bank = 0, 1581 .reg = 0x27, 1582 .refresh = lm_refresh_temp, 1583 .rfact = 0 1584 }, 1585 { 1586 .desc = "Temp1", 1587 .type = ENVSYS_STEMP, 1588 .bank = 1, 1589 .reg = 0x50, 1590 .refresh = as_refresh_temp, 1591 .rfact = 0 1592 }, 1593 { 1594 .desc = "Temp2", 1595 .type = ENVSYS_STEMP, 1596 .bank = 2, 1597 .reg = 0x50, 1598 .refresh = as_refresh_temp, 1599 .rfact = 0 1600 }, 1601 1602 /* Fans */ 1603 { 1604 .desc = "Fan0", 1605 .type = ENVSYS_SFANRPM, 1606 .bank = 0, 1607 .reg = 0x28, 1608 .refresh = lm_refresh_fanrpm, 1609 .rfact = 0 1610 }, 1611 { 1612 .desc = "Fan1", 1613 .type = ENVSYS_SFANRPM, 1614 .bank = 0, 1615 .reg = 0x29, 1616 .refresh = lm_refresh_fanrpm, 1617 .rfact = 0 1618 }, 1619 { 1620 .desc = "Fan2", 1621 .type = ENVSYS_SFANRPM, 1622 .bank = 0, 1623 .reg = 0x2a, 1624 .refresh = lm_refresh_fanrpm, 1625 .rfact = 0 1626 }, 1627 1628 { .desc = NULL } 1629}; 1630 1631/* NCT6776F */ 1632static const struct lm_sensor nct6776f_sensors[] = { 1633 /* Voltage */ 1634 { 1635 .desc = "VCore", 1636 .type = ENVSYS_SVOLTS_DC, 1637 .bank = 0, 1638 .reg = 0x20, 1639 .refresh = lm_refresh_volt, 1640 .rfact = RFACT_NONE / 2 1641 }, 1642 { 1643 .desc = "+12V", 1644 .type = ENVSYS_SVOLTS_DC, 1645 .bank = 0, 1646 .reg = 0x21, 1647 .refresh = lm_refresh_volt, 1648 .rfact = RFACT(56, 10) / 2 1649 }, 1650 { 1651 .desc = "AVCC", 1652 .type = ENVSYS_SVOLTS_DC, 1653 .bank = 0, 1654 .reg = 0x22, 1655 .refresh = lm_refresh_volt, 1656 .rfact = RFACT(34, 34) / 2 1657 }, 1658 { 1659 .desc = "+3.3V", 1660 .type = ENVSYS_SVOLTS_DC, 1661 .bank = 0, 1662 .reg = 0x23, 1663 .refresh = lm_refresh_volt, 1664 .rfact = RFACT(34, 34) / 2 1665 }, 1666 { 1667 .desc = "-12V", 1668 .type = ENVSYS_SVOLTS_DC, 1669 .bank = 0, 1670 .reg = 0x24, 1671 .refresh = wb_w83627ehf_refresh_nvolt, 1672 .rfact = 0 1673 }, 1674 { 1675 .desc = "+5V", 1676 .type = ENVSYS_SVOLTS_DC, 1677 .bank = 0, 1678 .reg = 0x25, 1679 .refresh = lm_refresh_volt, 1680 .rfact = 16000 1681 }, 1682 { 1683 .desc = "VIN3", 1684 .type = ENVSYS_SVOLTS_DC, 1685 .bank = 0, 1686 .reg = 0x26, 1687 .refresh = lm_refresh_volt, 1688 .rfact = RFACT_NONE 1689 }, 1690 { 1691 .desc = "+3.3VSB", 1692 .type = ENVSYS_SVOLTS_DC, 1693 .bank = 5, 1694 .reg = 0x50, 1695 .refresh = lm_refresh_volt, 1696 .rfact = RFACT(34, 34) / 2 1697 }, 1698 { 1699 .desc = "VBAT", 1700 .type = ENVSYS_SVOLTS_DC, 1701 .bank = 5, 1702 .reg = 0x51, 1703 .refresh = lm_refresh_volt, 1704 .rfact = RFACT(34, 34) / 2 1705 }, 1706 1707 /* Temperature */ 1708 { 1709 .desc = "MB Temperature", 1710 .type = ENVSYS_STEMP, 1711 .bank = 0, 1712 .reg = 0x27, 1713 .refresh = lm_refresh_temp, 1714 .rfact = 0 1715 }, 1716 { 1717 .desc = "CPU Temperature", 1718 .type = ENVSYS_STEMP, 1719 .bank = 1, 1720 .reg = 0x50, 1721 .refresh = wb_refresh_temp, 1722 .rfact = 0 1723 }, 1724 { 1725 .desc = "Aux Temp", 1726 .type = ENVSYS_STEMP, 1727 .bank = 2, 1728 .reg = 0x50, 1729 .refresh = wb_refresh_temp, 1730 .rfact = 0 1731 }, 1732 1733 /* Fans */ 1734 { 1735 .desc = "System Fan", 1736 .type = ENVSYS_SFANRPM, 1737 .bank = 6, 1738 .reg = 0x56, 1739 .refresh = wb_nct6776f_refresh_fanrpm, 1740 .rfact = 0 1741 }, 1742 { 1743 .desc = "CPU Fan", 1744 .type = ENVSYS_SFANRPM, 1745 .bank = 6, 1746 .reg = 0x58, 1747 .refresh = wb_nct6776f_refresh_fanrpm, 1748 .rfact = 0 1749 }, 1750 { 1751 .desc = "Aux Fan0", 1752 .type = ENVSYS_SFANRPM, 1753 .bank = 6, 1754 .reg = 0x5a, 1755 .refresh = wb_nct6776f_refresh_fanrpm, 1756 .rfact = 0 1757 }, 1758 { 1759 .desc = "Aux Fan1", 1760 .type = ENVSYS_SFANRPM, 1761 .bank = 6, 1762 .reg = 0x5c, 1763 .refresh = wb_nct6776f_refresh_fanrpm, 1764 .rfact = 0 1765 }, 1766 1767 { 1768 .desc = "Aux Fan2", 1769 .type = ENVSYS_SFANRPM, 1770 .bank = 6, 1771 .reg = 0x5e, 1772 .refresh = wb_nct6776f_refresh_fanrpm, 1773 .rfact = 0 1774 }, 1775 1776 { .desc = NULL } 1777}; 1778 1779/* NCT610[246]D */ 1780static const struct lm_sensor nct6102d_sensors[] = { 1781 /* Voltage */ 1782 { 1783 .desc = "VCore", 1784 .type = ENVSYS_SVOLTS_DC, 1785 .bank = 0, 1786 .reg = 0x00, 1787 .refresh = lm_refresh_volt, 1788 .rfact = RFACT_NONE 1789 }, 1790 { 1791 .desc = "VIN0", 1792 .type = ENVSYS_SVOLTS_DC, 1793 .bank = 0, 1794 .reg = 0x01, 1795 .refresh = lm_refresh_volt, 1796 .rfact = RFACT_NONE 1797 }, 1798 { 1799 .desc = "AVCC", 1800 .type = ENVSYS_SVOLTS_DC, 1801 .bank = 0, 1802 .reg = 0x02, 1803 .refresh = lm_refresh_volt, 1804 .rfact = RFACT(34, 34) / 2 1805 }, 1806 { 1807 .desc = "3VCC", 1808 .type = ENVSYS_SVOLTS_DC, 1809 .bank = 0, 1810 .reg = 0x03, 1811 .refresh = lm_refresh_volt, 1812 .rfact = RFACT(34, 34) / 2 1813 }, 1814 { 1815 .desc = "VIN1", 1816 .type = ENVSYS_SVOLTS_DC, 1817 .bank = 0, 1818 .reg = 0x04, 1819 .refresh = lm_refresh_volt, 1820 .rfact = RFACT_NONE 1821 }, 1822 { 1823 .desc = "VIN2", 1824 .type = ENVSYS_SVOLTS_DC, 1825 .bank = 0, 1826 .reg = 0x05, 1827 .refresh = lm_refresh_volt, 1828 .rfact = RFACT(34, 34) / 2 1829 }, 1830 { 1831 .desc = "+3.3VSB", 1832 .type = ENVSYS_SVOLTS_DC, 1833 .bank = 0, 1834 .reg = 0x07, 1835 .refresh = lm_refresh_volt, 1836 .rfact = RFACT(34, 34) / 2 1837 }, 1838 { 1839 .desc = "VBAT", 1840 .type = ENVSYS_SVOLTS_DC, 1841 .bank = 0, 1842 .reg = 0x08, 1843 .refresh = lm_refresh_volt, 1844 .rfact = RFACT(34, 34) / 2 1845 }, 1846 { 1847 .desc = "VTT", 1848 .type = ENVSYS_SVOLTS_DC, 1849 .bank = 0, 1850 .reg = 0x09, 1851 .refresh = lm_refresh_volt, 1852 .rfact = RFACT_NONE 1853 }, 1854 1855 /* Temperature */ 1856 { 1857 .desc = "MB Temperature", 1858 .type = ENVSYS_STEMP, 1859 .bank = 0, 1860 .reg = 0x18, 1861 .refresh = lm_refresh_temp, 1862 .rfact = 0 1863 }, 1864 { 1865 .desc = "CPU Temperature", 1866 .type = ENVSYS_STEMP, 1867 .bank = 0, 1868 .reg = 0x19, 1869 .refresh = lm_refresh_temp, 1870 .rfact = 0 1871 }, 1872 { 1873 .desc = "Aux Temp", 1874 .type = ENVSYS_STEMP, 1875 .bank = 0, 1876 .reg = 0x1a, 1877 .refresh = lm_refresh_temp, 1878 .rfact = 0 1879 }, 1880 1881 /* Fans */ 1882 { 1883 .desc = "System Fan", 1884 .type = ENVSYS_SFANRPM, 1885 .bank = 0, 1886 .reg = 0x30, 1887 .refresh = wb_nct6776f_refresh_fanrpm, 1888 .rfact = 0 1889 }, 1890 { 1891 .desc = "CPU Fan", 1892 .type = ENVSYS_SFANRPM, 1893 .bank = 0, 1894 .reg = 0x32, 1895 .refresh = wb_nct6776f_refresh_fanrpm, 1896 .rfact = 0 1897 }, 1898 { 1899 .desc = "Aux Fan", 1900 .type = ENVSYS_SFANRPM, 1901 .bank = 0, 1902 .reg = 0x34, 1903 .refresh = wb_nct6776f_refresh_fanrpm, 1904 .rfact = 0 1905 }, 1906 1907 { .desc = NULL } 1908}; 1909 1910/* NCT6779D */ 1911static const struct lm_sensor nct6779d_sensors[] = { 1912 /* Voltage */ 1913 { 1914 .desc = "VCore", 1915 .type = ENVSYS_SVOLTS_DC, 1916 .bank = 4, 1917 .reg = 0x80, 1918 .refresh = lm_refresh_volt, 1919 .rfact = RFACT_NONE / 2 1920 }, 1921 { 1922 .desc = "VIN1", 1923 .type = ENVSYS_SVOLTS_DC, 1924 .bank = 4, 1925 .reg = 0x81, 1926 .refresh = lm_refresh_volt, 1927 .rfact = RFACT(56, 10) / 2 1928 }, 1929 { 1930 .desc = "AVCC", 1931 .type = ENVSYS_SVOLTS_DC, 1932 .bank = 4, 1933 .reg = 0x82, 1934 .refresh = lm_refresh_volt, 1935 .rfact = RFACT(34, 34) / 2 1936 }, 1937 { 1938 .desc = "+3.3V", 1939 .type = ENVSYS_SVOLTS_DC, 1940 .bank = 4, 1941 .reg = 0x83, 1942 .refresh = lm_refresh_volt, 1943 .rfact = RFACT(34, 34) / 2 1944 }, 1945 { 1946 .desc = "VIN0", 1947 .type = ENVSYS_SVOLTS_DC, 1948 .bank = 4, 1949 .reg = 0x84, 1950 .refresh = lm_refresh_volt, 1951 .rfact = RFACT(48600, 10000) 1952 }, 1953 { 1954 .desc = "VIN8", 1955 .type = ENVSYS_SVOLTS_DC, 1956 .bank = 4, 1957 .reg = 0x85, 1958 .refresh = lm_refresh_volt, 1959 .rfact = RFACT_NONE / 2 1960 }, 1961 { 1962 .desc = "VIN4", 1963 .type = ENVSYS_SVOLTS_DC, 1964 .bank = 4, 1965 .reg = 0x86, 1966 .refresh = lm_refresh_volt, 1967 .rfact = RFACT_NONE 1968 }, 1969 { 1970 .desc = "+3.3VSB", 1971 .type = ENVSYS_SVOLTS_DC, 1972 .bank = 4, 1973 .reg = 0x87, 1974 .refresh = lm_refresh_volt, 1975 .rfact = RFACT(34, 34) / 2 1976 }, 1977 { 1978 .desc = "VBAT", 1979 .type = ENVSYS_SVOLTS_DC, 1980 .bank = 4, 1981 .reg = 0x88, 1982 .refresh = lm_refresh_volt, 1983 .rfact = RFACT_NONE 1984 }, 1985 { 1986 .desc = "VTT", 1987 .type = ENVSYS_SVOLTS_DC, 1988 .bank = 4, 1989 .reg = 0x89, 1990 .refresh = lm_refresh_volt, 1991 .rfact = RFACT_NONE 1992 }, 1993 { 1994 .desc = "VIN5", 1995 .type = ENVSYS_SVOLTS_DC, 1996 .bank = 4, 1997 .reg = 0x8a, 1998 .refresh = lm_refresh_volt, 1999 .rfact = RFACT_NONE 2000 }, 2001 { 2002 .desc = "VIN6", 2003 .type = ENVSYS_SVOLTS_DC, 2004 .bank = 4, 2005 .reg = 0x8b, 2006 .refresh = lm_refresh_volt, 2007 .rfact = RFACT_NONE 2008 }, 2009 { 2010 .desc = "VIN2", 2011 .type = ENVSYS_SVOLTS_DC, 2012 .bank = 4, 2013 .reg = 0x8c, 2014 .refresh = lm_refresh_volt, 2015 .rfact = RFACT_NONE 2016 }, 2017 { 2018 .desc = "VIN3", 2019 .type = ENVSYS_SVOLTS_DC, 2020 .bank = 4, 2021 .reg = 0x8d, 2022 .refresh = lm_refresh_volt, 2023 .rfact = RFACT(14414, 10000) 2024 }, 2025 { 2026 .desc = "VIN7", 2027 .type = ENVSYS_SVOLTS_DC, 2028 .bank = 4, 2029 .reg = 0x8e, 2030 .refresh = lm_refresh_volt, 2031 .rfact = RFACT_NONE / 2 2032 }, 2033 2034 /* Temperature */ 2035 { 2036 .desc = "MB Temperature", 2037 .type = ENVSYS_STEMP, 2038 .bank = 4, 2039 .reg = 0x90, 2040 .refresh = lm_refresh_temp, 2041 .rfact = 0 2042 }, 2043 { 2044 .desc = "CPU Temperature", 2045 .type = ENVSYS_STEMP, 2046 .bank = 4, 2047 .reg = 0x91, 2048 .refresh = wb_refresh_temp, 2049 .rfact = 0 2050 }, 2051 { 2052 .desc = "Aux Temp0", 2053 .type = ENVSYS_STEMP, 2054 .bank = 4, 2055 .reg = 0x92, 2056 .refresh = wb_refresh_temp, 2057 .rfact = 0 2058 }, 2059 { 2060 .desc = "Aux Temp1", 2061 .type = ENVSYS_STEMP, 2062 .bank = 4, 2063 .reg = 0x93, 2064 .refresh = wb_refresh_temp, 2065 .rfact = 0 2066 }, 2067 { 2068 .desc = "Aux Temp2", 2069 .type = ENVSYS_STEMP, 2070 .bank = 4, 2071 .reg = 0x94, 2072 .refresh = wb_refresh_temp, 2073 .rfact = 0 2074 }, 2075 { 2076 .desc = "Aux Temp3", 2077 .type = ENVSYS_STEMP, 2078 .bank = 4, 2079 .reg = 0x95, 2080 .refresh = wb_refresh_temp, 2081 .rfact = 0 2082 }, 2083 2084 /* Fans */ 2085 { 2086 .desc = "System Fan", 2087 .type = ENVSYS_SFANRPM, 2088 .bank = 4, 2089 .reg = 0xc0, 2090 .refresh = wb_nct6776f_refresh_fanrpm, 2091 .rfact = 0 2092 }, 2093 { 2094 .desc = "CPU Fan", 2095 .type = ENVSYS_SFANRPM, 2096 .bank = 4, 2097 .reg = 0xc2, 2098 .refresh = wb_nct6776f_refresh_fanrpm, 2099 .rfact = 0 2100 }, 2101 { 2102 .desc = "Aux Fan0", 2103 .type = ENVSYS_SFANRPM, 2104 .bank = 4, 2105 .reg = 0xc4, 2106 .refresh = wb_nct6776f_refresh_fanrpm, 2107 .rfact = 0 2108 }, 2109 { 2110 .desc = "Aux Fan1", 2111 .type = ENVSYS_SFANRPM, 2112 .bank = 4, 2113 .reg = 0xc6, 2114 .refresh = wb_nct6776f_refresh_fanrpm, 2115 .rfact = 0 2116 }, 2117 { 2118 .desc = "Aux Fan2", 2119 .type = ENVSYS_SFANRPM, 2120 .bank = 4, 2121 .reg = 0xc8, 2122 .refresh = wb_nct6776f_refresh_fanrpm, 2123 .rfact = 0 2124 }, 2125 2126 { .desc = NULL } 2127}; 2128 2129static const struct wb_product wb_products[] = { 2130 { WB_CHIPID_W83627HF, "W83627HF", w83627hf_sensors, NULL }, 2131 { WB_CHIPID_W83627THF, "W83627THF",w83637hf_sensors, NULL }, 2132 { WB_CHIPID_W83627EHF_A,"W83627EHF-A",w83627ehf_sensors,NULL }, 2133 { WB_CHIPID_W83627EHF, "W83627EHF",w83627ehf_sensors,NULL }, 2134 { WB_CHIPID_W83627DHG, NULL, NULL, NULL }, 2135 { WB_CHIPID_W83637HF, "W83637HF", w83637hf_sensors, NULL }, 2136 { WB_CHIPID_W83697HF, "W83697HF", w83697hf_sensors, NULL }, 2137 { WB_CHIPID_W83781D, "W83781D", w83781d_sensors, NULL }, 2138 { WB_CHIPID_W83781D_2, "W83781D", w83781d_sensors, NULL }, 2139 { WB_CHIPID_W83782D, "W83782D", w83782d_sensors, NULL }, 2140 { WB_CHIPID_W83783S, "W83783S", w83783s_sensors, NULL }, 2141 { WB_CHIPID_W83791D, "W83791D", w83791d_sensors, NULL }, 2142 { WB_CHIPID_W83791SD, "W83791SD", NULL, NULL }, 2143 { WB_CHIPID_W83792D, "W83792D", w83792d_sensors, NULL }, 2144 { WB_CHIPID_AS99127F, NULL, NULL, NULL }, 2145 { 0, NULL, NULL, NULL } 2146}; 2147 2148static const struct wb_product wbsio_products[] = { 2149 { WBSIO_ID_W83627DHG, "W83627DHG",w83627dhg_sensors,NULL }, 2150 { WBSIO_ID_NCT6775F, "NCT6775F", nct6776f_sensors, NULL }, 2151 { WBSIO_ID_NCT6776F, "NCT6776F", nct6776f_sensors, NULL }, 2152 { WBSIO_ID_NCT5104D, "NCT5104D or 610[246]D",nct6102d_sensors,NULL }, 2153 { WBSIO_ID_NCT6779D, "NCT6779D", nct6779d_sensors, NULL }, 2154 { WBSIO_ID_NCT6791D, "NCT6791D", nct6779d_sensors, NULL }, 2155 { WBSIO_ID_NCT6792D, "NCT6792D", nct6779d_sensors, NULL }, 2156 { WBSIO_ID_NCT6793D, "NCT6793D", nct6779d_sensors, NULL }, 2157 { WBSIO_ID_NCT6795D, "NCT6795D", nct6779d_sensors, NULL }, 2158 { WBSIO_ID_NCT6796D, "NCT6796D", nct6779d_sensors, NULL }, 2159 { WBSIO_ID_NCT6797D, "NCT6797D", nct6779d_sensors, NULL }, 2160 { WBSIO_ID_NCT6798D, "NCT6798D", nct6779d_sensors, NULL }, 2161 { WBSIO_ID_NCT6799D, "NCT6799D", nct6779d_sensors, NULL }, 2162 { 0, NULL, NULL, NULL } 2163}; 2164 2165static const struct wb_product as99127f_products[] = { 2166 { WB_VENDID_ASUS, "AS99127F", w83781d_sensors, NULL }, 2167 { WB_VENDID_WINBOND, "AS99127F rev 2",as99127f_sensors,NULL }, 2168 { 0, NULL, NULL, NULL } 2169}; 2170 2171static void 2172lm_generic_banksel(struct lm_softc *lmsc, uint8_t bank) 2173{ 2174 (*lmsc->lm_writereg)(lmsc, WB_BANKSEL, bank); 2175} 2176 2177/* 2178 * bus independent match 2179 * 2180 * prerequisites: lmsc contains valid lm_{read,write}reg() routines 2181 * and associated bus access data is present in attachment's softc 2182 */ 2183int 2184lm_match(struct lm_softc *lmsc) 2185{ 2186 uint8_t cr; 2187 int i, rv; 2188 2189 /* Perform LM78 reset */ 2190 /*(*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x80); */ 2191 2192 cr = (*lmsc->lm_readreg)(lmsc, LMD_CONFIG); 2193 2194 /* XXX - spec says *only* 0x08! */ 2195 if ((cr != 0x08) && (cr != 0x01) && (cr != 0x03) && (cr != 0x06)) 2196 return 0; 2197 2198 DPRINTF(("%s: 0x80 check: cr = %x\n", __func__, cr)); 2199 2200 for (i = 0; i < __arraycount(lm_chips); i++) 2201 if ((rv = lm_chips[i].chip_match(lmsc)) != 0) 2202 return rv; 2203 2204 return 0; 2205} 2206 2207int 2208nslm_match(struct lm_softc *sc) 2209{ 2210 uint8_t chipid; 2211 2212 /* See if we have an LM78/LM78J/LM79 or LM81 */ 2213 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 2214 switch(chipid) { 2215 case LM_ID_LM78: 2216 case LM_ID_LM78J: 2217 case LM_ID_LM79: 2218 case LM_ID_LM81: 2219 break; 2220 default: 2221 return 0; 2222 } 2223 DPRINTF(("%s: chipid %x\n", __func__, chipid)); 2224 return 1; 2225} 2226 2227void 2228lm_attach(struct lm_softc *lmsc) 2229{ 2230 uint32_t i; 2231 int rv; 2232 2233 for (i = 0; i < __arraycount(lm_chips); i++) { 2234 if (lm_chips[i].chip_match(lmsc) != 0) { 2235 if (lm_chips[i].chip_attach(lmsc) == 0) 2236 break; 2237 else 2238 return; 2239 } 2240 } 2241 2242 /* Start the monitoring loop */ 2243 (*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x01); 2244 2245 lmsc->sc_sme = sysmon_envsys_create(); 2246 /* Initialize sensors */ 2247 for (i = 0; i < lmsc->numsensors; i++) { 2248 lmsc->sensors[i].state = ENVSYS_SINVALID; 2249 if ((rv = sysmon_envsys_sensor_attach(lmsc->sc_sme, 2250 &lmsc->sensors[i])) != 0) { 2251 sysmon_envsys_destroy(lmsc->sc_sme); 2252 lmsc->sc_sme = NULL; 2253 aprint_error_dev(lmsc->sc_dev, 2254 "sysmon_envsys_sensor_attach() returned %d\n", rv); 2255 return; 2256 } 2257 } 2258 2259 /* 2260 * Setup the callout to refresh sensor data every 2 seconds. 2261 */ 2262 callout_init(&lmsc->sc_callout, 0); 2263 callout_setfunc(&lmsc->sc_callout, lm_refresh, lmsc); 2264 callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO); 2265 2266 /* 2267 * Hook into the System Monitor. 2268 */ 2269 lmsc->sc_sme->sme_name = device_xname(lmsc->sc_dev); 2270 lmsc->sc_sme->sme_flags = SME_DISABLE_REFRESH; 2271 2272 if (sysmon_envsys_register(lmsc->sc_sme)) { 2273 aprint_error_dev(lmsc->sc_dev, 2274 "unable to register with sysmon\n"); 2275 sysmon_envsys_destroy(lmsc->sc_sme); 2276 lmsc->sc_sme = NULL; 2277 } 2278 if (!pmf_device_register(lmsc->sc_dev, NULL, NULL)) 2279 aprint_error_dev(lmsc->sc_dev, 2280 "couldn't establish power handler\n"); 2281} 2282 2283/* 2284 * Stop, destroy the callout and unregister the driver with the 2285 * sysmon_envsys(9) framework. 2286 */ 2287void 2288lm_detach(struct lm_softc *lmsc) 2289{ 2290 callout_halt(&lmsc->sc_callout, NULL); 2291 callout_destroy(&lmsc->sc_callout); 2292 2293 if (lmsc->sc_sme != NULL) 2294 sysmon_envsys_unregister(lmsc->sc_sme); 2295 pmf_device_deregister(lmsc->sc_dev); 2296} 2297 2298static void 2299lm_refresh(void *arg) 2300{ 2301 struct lm_softc *lmsc = arg; 2302 2303 lmsc->refresh_sensor_data(lmsc); 2304 callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO); 2305} 2306 2307static int 2308nslm_attach(struct lm_softc *sc) 2309{ 2310 const char *model = NULL; 2311 uint8_t chipid; 2312 2313 /* See if we have an LM78/LM78J/LM79 or LM81 */ 2314 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 2315 switch(chipid) { 2316 case LM_ID_LM78: 2317 model = "LM78"; 2318 break; 2319 case LM_ID_LM78J: 2320 model = "LM78J"; 2321 break; 2322 case LM_ID_LM79: 2323 model = "LM79"; 2324 break; 2325 case LM_ID_LM81: 2326 model = "LM81"; 2327 break; 2328 default: 2329 return -1; 2330 } 2331 2332 aprint_naive("\n"); 2333 aprint_normal("\n"); 2334 aprint_normal_dev(sc->sc_dev, 2335 "National Semiconductor %s Hardware monitor\n", model); 2336 2337 lm_setup_sensors(sc, lm78_sensors); 2338 sc->refresh_sensor_data = lm_refresh_sensor_data; 2339 return 0; 2340} 2341 2342static int 2343def_match(struct lm_softc *sc) 2344{ 2345 2346 return 1; 2347} 2348 2349static int 2350def_attach(struct lm_softc *sc) 2351{ 2352 uint8_t chipid; 2353 2354 chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; 2355 aprint_naive("\n"); 2356 aprint_normal("\n"); 2357 aprint_error_dev(sc->sc_dev, "Unknown chip (ID 0x%02x)\n", chipid); 2358 2359 lm_setup_sensors(sc, lm78_sensors); 2360 sc->refresh_sensor_data = lm_refresh_sensor_data; 2361 return 0; 2362} 2363 2364static void 2365wb_temp_diode_type(struct lm_softc *sc, int diode_type) 2366{ 2367 uint8_t regval, banksel; 2368 2369 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2370 switch (diode_type) { 2371 case 1: /* Switch to Pentium-II diode mode */ 2372 lm_generic_banksel(sc, WB_BANKSEL_B0); 2373 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2374 regval |= 0x0e; 2375 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval); 2376 regval = (*sc->lm_readreg)(sc, WB_BANK0_RESVD1); 2377 regval |= 0x70; 2378 (*sc->lm_writereg)(sc, WB_BANK0_RESVD1, 0x0); 2379 lm_generic_banksel(sc, banksel); 2380 aprint_verbose_dev(sc->sc_dev, "Pentium-II diode temp sensors\n"); 2381 break; 2382 case 2: /* Switch to 2N3904 mode */ 2383 lm_generic_banksel(sc, WB_BANKSEL_B0); 2384 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2385 regval |= 0xe; 2386 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval); 2387 regval = (*sc->lm_readreg)(sc, WB_BANK0_RESVD1); 2388 regval &= ~0x70; 2389 (*sc->lm_writereg)(sc, WB_BANK0_RESVD1, 0x0); 2390 lm_generic_banksel(sc, banksel); 2391 aprint_verbose_dev(sc->sc_dev, "2N3904 bipolar temp sensors\n"); 2392 break; 2393 case 4: /* Switch to generic thermistor mode */ 2394 lm_generic_banksel(sc, WB_BANKSEL_B0); 2395 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2396 regval &= ~0xe; 2397 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval); 2398 lm_generic_banksel(sc, banksel); 2399 aprint_verbose_dev(sc->sc_dev, "Thermistor temp sensors\n"); 2400 break; 2401 case 0: /* Unspecified - use default */ 2402 aprint_verbose_dev(sc->sc_dev, "Using default temp sensors\n"); 2403 break; 2404 default: 2405 aprint_error_dev(sc->sc_dev, 2406 "Ignoring invalid temp sensor mode %d\n", 2407 diode_type); 2408 break; 2409 } 2410} 2411 2412static const struct wb_product * 2413wb_lookup(struct lm_softc *sc, const struct wb_product *products, uint16_t id) 2414{ 2415 const struct wb_product *prod = products; 2416 int i = 0; 2417 2418 while (prod[i].id != 0) { 2419 if (prod[i].id != id) { 2420 i++; 2421 continue; 2422 } 2423 if (prod[i].str == NULL) { 2424 if (products == wb_products) { 2425 if (id == WB_CHIPID_W83627DHG) { 2426 /* 2427 * Lookup wbsio_products 2428 * with WBSIO_ID. 2429 */ 2430 return wb_lookup(sc, wbsio_products, 2431 sc->sioid); 2432 } else if (id == WB_CHIPID_AS99127F) { 2433 /* 2434 * Lookup as99127f_products 2435 * with WB_VENDID. 2436 */ 2437 return wb_lookup(sc, as99127f_products, 2438 wb_read_vendorid(sc)); 2439 } else 2440 return NULL; /* not occur */ 2441 } 2442 return NULL; /* not occur */ 2443 } 2444 return &prod[i]; 2445 } 2446 2447 /* Not found */ 2448 return NULL; 2449} 2450 2451static uint16_t 2452wb_read_vendorid(struct lm_softc *sc) 2453{ 2454 uint16_t vendid; 2455 uint8_t vendidreg; 2456 uint8_t banksel; 2457 2458 /* Save bank */ 2459 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2460 2461 /* Check default vendor ID register first */ 2462 vendidreg = WB_VENDID; 2463 2464retry: 2465 /* Read vendor ID */ 2466 lm_generic_banksel(sc, WB_BANKSEL_HBAC); 2467 vendid = (*sc->lm_readreg)(sc, vendidreg) << 8; 2468 lm_generic_banksel(sc, 0); 2469 vendid |= (*sc->lm_readreg)(sc, vendidreg); 2470 2471 if ((vendidreg == WB_VENDID) 2472 && (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)) { 2473 /* If it failed, try NCT6102 vendor ID register */ 2474 vendidreg = WB_NCT6102_VENDID; 2475 goto retry; 2476 } else if ((vendidreg == WB_NCT6102_VENDID) 2477 && (vendid != WB_VENDID_WINBOND)) 2478 vendid = 0; /* XXX */ 2479 2480 /* Restore bank */ 2481 lm_generic_banksel(sc, banksel); 2482 2483 return vendid; 2484} 2485 2486static uint8_t 2487wb_read_chipid(struct lm_softc *sc) 2488{ 2489 const struct wb_product *prod; 2490 uint8_t chipidreg, chipid, banksel; 2491 2492 /* Save bank */ 2493 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2494 2495 /* Check default vendor ID register first */ 2496 chipidreg = WB_BANK0_CHIPID; 2497 lm_generic_banksel(sc, WB_BANKSEL_B0); 2498 2499retry: 2500 (void)(*sc->lm_readreg)(sc, LMD_CHIPID); 2501 chipid = (*sc->lm_readreg)(sc, chipidreg); 2502 prod = wb_lookup(sc, wb_products, chipid); 2503 if (prod == NULL) { 2504 if (chipidreg == WB_BANK0_CHIPID) { 2505 chipidreg = WB_BANK0_NCT6102_CHIPID; 2506 goto retry; 2507 } else 2508 chipid = 0; 2509 } 2510 /* Restore bank */ 2511 lm_generic_banksel(sc, banksel); 2512 2513 return chipid; 2514} 2515 2516static int 2517wb_match(struct lm_softc *sc) 2518{ 2519 const struct wb_product *prod; 2520 uint16_t vendid; 2521 uint8_t chipid; 2522 2523 /* Read vendor ID */ 2524 vendid = wb_read_vendorid(sc); 2525 DPRINTF(("%s: winbond vend id 0x%x\n", __func__, vendid)); 2526 if ((vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)) 2527 return 0; 2528 2529 /* Read device/chip ID */ 2530 chipid = wb_read_chipid(sc); 2531 DPRINTF(("%s: winbond chip id 0x%x\n", __func__, chipid)); 2532 prod = wb_lookup(sc, wb_products, chipid); 2533 2534 if (prod == NULL) { 2535 if (vendid == WB_VENDID_WINBOND) 2536 return 1; /* Generic match */ 2537 else 2538 return 0; 2539 } 2540 DPRINTF(("%s: chipid %02x, sioid = %04x\n", __func__, chipid, 2541 sc->sioid)); 2542 2543 return 10; /* found */ 2544} 2545 2546static int 2547wb_attach(struct lm_softc *sc) 2548{ 2549 device_t dev = sc->sc_dev; 2550 const struct wb_product *prod; 2551 const char *model = NULL; 2552 const char *vendor = "Winbond"; 2553 const struct lm_sensor *sensors; 2554 uint16_t vendid; 2555 uint8_t banksel; 2556 int cf_flags; 2557 2558 aprint_naive("\n"); 2559 aprint_normal("\n"); 2560 /* Read device/chip ID */ 2561 sc->chipid = wb_read_chipid(sc); 2562 DPRINTF(("%s: winbond chip id 0x%x\n", __func__, sc->chipid)); 2563 2564 if ((prod = wb_lookup(sc, wb_products, sc->chipid)) != NULL) { 2565 model = prod->str; 2566 switch (model[0]) { 2567 case 'W': 2568 vendor = "Winbond"; 2569 break; 2570 case 'A': 2571 vendor = "ASUS"; 2572 break; 2573 case 'N': 2574 vendor = "Nuvoton"; 2575 break; 2576 default: 2577 aprint_error_dev(dev, "Unknown model (%s)\n", model); 2578 return -1; 2579 } 2580 sensors = prod->sensors; 2581 sc->refresh_sensor_data = wb_refresh_sensor_data; 2582 if (prod->extattach != NULL) 2583 prod->extattach(sc); 2584 } else { 2585 vendid = wb_read_vendorid(sc); 2586 if (vendid == WB_VENDID_WINBOND) { 2587 vendor = "Winbond"; 2588 model = "unknown-model"; 2589 2590 /* Handle as a standard LM78. */ 2591 sensors = lm78_sensors; 2592 sc->refresh_sensor_data = lm_refresh_sensor_data; 2593 } else { 2594 aprint_error_dev(dev, "Unknown chip (ID %02x)\n", 2595 sc->chipid); 2596 return -1; 2597 } 2598 } 2599 2600 cf_flags = device_cfdata(dev)->cf_flags; 2601 2602 if (sensors != NULL) { 2603 lm_setup_sensors(sc, sensors); 2604 2605 /* XXX Is this correct? Check all datasheets. */ 2606 switch (sc->chipid) { 2607 case WB_CHIPID_W83627EHF_A: 2608 case WB_CHIPID_W83781D: 2609 case WB_CHIPID_W83781D_2: 2610 case WB_CHIPID_W83791SD: 2611 case WB_CHIPID_W83792D: 2612 case WB_CHIPID_AS99127F: 2613 break; 2614 default: 2615 wb_temp_diode_type(sc, cf_flags); 2616 break; 2617 } 2618 } 2619 2620 /* XXX Is this correct? Check all datasheets. */ 2621 banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); 2622 switch(sc->chipid) { 2623 case WB_CHIPID_W83627THF: 2624 lm_generic_banksel(sc, WB_BANKSEL_B0); 2625 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9) 2626 sc->vrm9 = 1; 2627 lm_generic_banksel(sc, banksel); 2628 break; 2629 case WB_CHIPID_W83637HF: 2630 lm_generic_banksel(sc, WB_BANKSEL_B0); 2631 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9) 2632 sc->vrm9 = 1; 2633 lm_generic_banksel(sc, banksel); 2634 break; 2635 default: 2636 break; 2637 } 2638 2639 aprint_normal_dev(dev, "%s %s Hardware monitor\n", vendor, model); 2640 2641 return 0; 2642} 2643 2644static void 2645lm_setup_sensors(struct lm_softc *sc, const struct lm_sensor *sensors) 2646{ 2647 int i; 2648 2649 for (i = 0; sensors[i].desc; i++) { 2650 sc->sensors[i].units = sensors[i].type; 2651 if (sc->sensors[i].units == ENVSYS_SVOLTS_DC) 2652 sc->sensors[i].flags = ENVSYS_FCHANGERFACT; 2653 strlcpy(sc->sensors[i].desc, sensors[i].desc, 2654 sizeof(sc->sensors[i].desc)); 2655 sc->numsensors++; 2656 } 2657 sc->lm_sensors = sensors; 2658} 2659 2660static void 2661lm_refresh_sensor_data(struct lm_softc *sc) 2662{ 2663 int i; 2664 2665 for (i = 0; i < sc->numsensors; i++) 2666 sc->lm_sensors[i].refresh(sc, i); 2667} 2668 2669static void 2670lm_refresh_volt(struct lm_softc *sc, int n) 2671{ 2672 int data; 2673 2674 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2675 if (data == 0xff) { 2676 sc->sensors[n].state = ENVSYS_SINVALID; 2677 } else { 2678 sc->sensors[n].value_cur = (data << 4); 2679 if (sc->sensors[n].rfact) { 2680 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2681 sc->sensors[n].value_cur /= 10; 2682 } else { 2683 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact; 2684 sc->sensors[n].value_cur /= 10; 2685 sc->sensors[n].rfact = sc->lm_sensors[n].rfact; 2686 } 2687 sc->sensors[n].state = ENVSYS_SVALID; 2688 } 2689 2690 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2691 __func__, n, data, sc->sensors[n].value_cur)); 2692} 2693 2694static void 2695lm_refresh_temp(struct lm_softc *sc, int n) 2696{ 2697 int data; 2698 2699 /* 2700 * The data sheet suggests that the range of the temperature 2701 * sensor is between -55 degC and +125 degC. 2702 */ 2703 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2704 if (data > 0x7d && data < 0xc9) 2705 sc->sensors[n].state = ENVSYS_SINVALID; 2706 else { 2707 if (data & 0x80) 2708 data -= 0x100; 2709 sc->sensors[n].state = ENVSYS_SVALID; 2710 sc->sensors[n].value_cur = data * 1000000 + 273150000; 2711 } 2712 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2713 __func__, n, data, sc->sensors[n].value_cur)); 2714} 2715 2716static void 2717lm_refresh_fanrpm(struct lm_softc *sc, int n) 2718{ 2719 int data, divisor = 1; 2720 2721 /* 2722 * We might get more accurate fan readings by adjusting the 2723 * divisor, but that might interfere with APM or other SMM 2724 * BIOS code reading the fan speeds. 2725 */ 2726 2727 /* FAN3 has a fixed fan divisor. */ 2728 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2729 sc->lm_sensors[n].reg == LMD_FAN2) { 2730 data = (*sc->lm_readreg)(sc, LMD_VIDFAN); 2731 if (sc->lm_sensors[n].reg == LMD_FAN1) 2732 divisor = (data >> 4) & 0x03; 2733 else 2734 divisor = (data >> 6) & 0x03; 2735 } 2736 2737 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2738 if (data == 0xff || data == 0x00) 2739 sc->sensors[n].state = ENVSYS_SINVALID; 2740 else { 2741 sc->sensors[n].state = ENVSYS_SVALID; 2742 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2743 } 2744 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2745 __func__, n, data, sc->sensors[n].value_cur)); 2746} 2747 2748static void 2749wb_refresh_sensor_data(struct lm_softc *sc) 2750{ 2751 uint8_t banksel, bank; 2752 int i; 2753 2754 /* 2755 * Properly save and restore bank selection register. 2756 */ 2757 banksel = bank = sc->lm_readreg(sc, WB_BANKSEL); 2758 for (i = 0; i < sc->numsensors; i++) { 2759 if (bank != sc->lm_sensors[i].bank) { 2760 bank = sc->lm_sensors[i].bank; 2761 lm_generic_banksel(sc, bank); 2762 } 2763 sc->lm_sensors[i].refresh(sc, i); 2764 } 2765 lm_generic_banksel(sc, banksel); 2766} 2767 2768static void 2769wb_w83637hf_refresh_vcore(struct lm_softc *sc, int n) 2770{ 2771 int data; 2772 2773 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2774 /* 2775 * Depending on the voltage detection method, 2776 * one of the following formulas is used: 2777 * VRM8 method: value = raw * 0.016V 2778 * VRM9 method: value = raw * 0.00488V + 0.70V 2779 */ 2780 if (sc->vrm9) 2781 sc->sensors[n].value_cur = (data * 4880) + 700000; 2782 else 2783 sc->sensors[n].value_cur = (data * 16000); 2784 sc->sensors[n].state = ENVSYS_SVALID; 2785 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2786 __func__, n, data, sc->sensors[n].value_cur)); 2787} 2788 2789static void 2790wb_refresh_nvolt(struct lm_softc *sc, int n) 2791{ 2792 int data; 2793 2794 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2795 sc->sensors[n].value_cur = ((data << 4) - WB_VREF); 2796 if (sc->sensors[n].rfact) 2797 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2798 else 2799 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact; 2800 2801 sc->sensors[n].value_cur /= 10; 2802 sc->sensors[n].value_cur += WB_VREF * 1000; 2803 sc->sensors[n].state = ENVSYS_SVALID; 2804 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2805 __func__, n , data, sc->sensors[n].value_cur)); 2806} 2807 2808static void 2809wb_w83627ehf_refresh_nvolt(struct lm_softc *sc, int n) 2810{ 2811 int data; 2812 2813 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2814 sc->sensors[n].value_cur = ((data << 3) - WB_W83627EHF_VREF); 2815 if (sc->sensors[n].rfact) 2816 sc->sensors[n].value_cur *= sc->sensors[n].rfact; 2817 else 2818 sc->sensors[n].value_cur *= RFACT(232, 10); 2819 2820 sc->sensors[n].value_cur /= 10; 2821 sc->sensors[n].value_cur += WB_W83627EHF_VREF * 1000; 2822 sc->sensors[n].state = ENVSYS_SVALID; 2823 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n", 2824 __func__, n , data, sc->sensors[n].value_cur)); 2825} 2826 2827static void 2828wb_refresh_temp(struct lm_softc *sc, int n) 2829{ 2830 int data; 2831 2832 /* 2833 * The data sheet suggests that the range of the temperature 2834 * sensor is between -55 degC and +125 degC. However, values 2835 * around -48 degC seem to be a very common bogus values. 2836 * Since such values are unreasonably low, we use -45 degC for 2837 * the lower limit instead. 2838 */ 2839 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1; 2840 data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7; 2841 if (data > 0xfffffff || (data > 0x0fa && data < 0x1a6)) { 2842 sc->sensors[n].state = ENVSYS_SINVALID; 2843 } else { 2844 if (data & 0x100) 2845 data -= 0x200; 2846 sc->sensors[n].state = ENVSYS_SVALID; 2847 sc->sensors[n].value_cur = data * 500000 + 273150000; 2848 } 2849 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2850 __func__, n , data, sc->sensors[n].value_cur)); 2851} 2852 2853static void 2854wb_refresh_fanrpm(struct lm_softc *sc, int n) 2855{ 2856 int fan, data, divisor = 0; 2857 2858 /* 2859 * This is madness; the fan divisor bits are scattered all 2860 * over the place. 2861 */ 2862 2863 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2864 sc->lm_sensors[n].reg == LMD_FAN2 || 2865 sc->lm_sensors[n].reg == LMD_FAN3) { 2866 data = (*sc->lm_readreg)(sc, WB_BANK0_VBAT); 2867 fan = (sc->lm_sensors[n].reg - LMD_FAN1); 2868 if ((data >> 5) & (1 << fan)) 2869 divisor |= 0x04; 2870 } 2871 2872 if (sc->lm_sensors[n].reg == LMD_FAN1 || 2873 sc->lm_sensors[n].reg == LMD_FAN2) { 2874 data = (*sc->lm_readreg)(sc, LMD_VIDFAN); 2875 if (sc->lm_sensors[n].reg == LMD_FAN1) 2876 divisor |= (data >> 4) & 0x03; 2877 else 2878 divisor |= (data >> 6) & 0x03; 2879 } else if (sc->lm_sensors[n].reg == LMD_FAN3) { 2880 data = (*sc->lm_readreg)(sc, WB_PIN); 2881 divisor |= (data >> 6) & 0x03; 2882 } else if (sc->lm_sensors[n].reg == WB_BANK0_FAN4 || 2883 sc->lm_sensors[n].reg == WB_BANK0_FAN5) { 2884 data = (*sc->lm_readreg)(sc, WB_BANK0_FAN45); 2885 if (sc->lm_sensors[n].reg == WB_BANK0_FAN4) 2886 divisor |= (data >> 0) & 0x07; 2887 else 2888 divisor |= (data >> 4) & 0x07; 2889 } 2890 2891 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2892 if (data >= 0xff || data == 0x00) 2893 sc->sensors[n].state = ENVSYS_SINVALID; 2894 else { 2895 sc->sensors[n].state = ENVSYS_SVALID; 2896 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2897 } 2898 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2899 __func__, n , data, sc->sensors[n].value_cur)); 2900} 2901 2902static void 2903wb_nct6776f_refresh_fanrpm(struct lm_softc *sc, int n) 2904{ 2905 int datah, datal; 2906 2907 datah = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2908 datal = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1); 2909 2910 if ((datah == 0xff) || (datah == 0)) { 2911 sc->sensors[n].state = ENVSYS_SINVALID; 2912 } else { 2913 sc->sensors[n].state = ENVSYS_SVALID; 2914 sc->sensors[n].value_cur = (datah << 8) | datal; 2915 } 2916} 2917 2918static void 2919wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n) 2920{ 2921 int shift, data, divisor = 1; 2922 uint8_t reg; 2923 2924 shift = 0; 2925 2926 switch (sc->lm_sensors[n].reg) { 2927 case 0x28: 2928 reg = 0x47; shift = 0; 2929 break; 2930 case 0x29: 2931 reg = 0x47; shift = 4; 2932 break; 2933 case 0x2a: 2934 reg = 0x5b; shift = 0; 2935 break; 2936 case 0xb8: 2937 reg = 0x5b; shift = 4; 2938 break; 2939 case 0xb9: 2940 reg = 0x5c; shift = 0; 2941 break; 2942 case 0xba: 2943 reg = 0x5c; shift = 4; 2944 break; 2945 case 0xbe: 2946 reg = 0x9e; shift = 0; 2947 break; 2948 default: 2949 reg = 0; 2950 break; 2951 } 2952 2953 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg); 2954 if (data == 0xff || data == 0x00) 2955 sc->sensors[n].state = ENVSYS_SINVALID; 2956 else { 2957 if (reg != 0) 2958 divisor = ((*sc->lm_readreg)(sc, reg) >> shift) & 0x7; 2959 sc->sensors[n].state = ENVSYS_SVALID; 2960 sc->sensors[n].value_cur = 1350000 / (data << divisor); 2961 } 2962 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n", 2963 __func__, n , data, sc->sensors[n].value_cur)); 2964} 2965 2966static void 2967as_refresh_temp(struct lm_softc *sc, int n) 2968{ 2969 int data; 2970 2971 /* 2972 * It seems a shorted temperature diode produces an all-ones 2973 * bit pattern. 2974 */ 2975 data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1; 2976 data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7; 2977 if (data == 0x1ff) 2978 sc->sensors[n].state = ENVSYS_SINVALID; 2979 else { 2980 if (data & 0x100) 2981 data -= 0x200; 2982 sc->sensors[n].state = ENVSYS_SVALID; 2983 sc->sensors[n].value_cur = data * 500000 + 273150000; 2984 } 2985 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n", 2986 __func__, n, data, sc->sensors[n].value_cur)); 2987} 2988 2989MODULE(MODULE_CLASS_DRIVER, lm, "sysmon_envsys"); 2990 2991static int 2992lm_modcmd(modcmd_t cmd, void *opaque) 2993{ 2994 switch (cmd) { 2995 case MODULE_CMD_INIT: 2996 case MODULE_CMD_FINI: 2997 return 0; 2998 default: 2999 return ENOTTY; 3000 } 3001} 3002