aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-07-01 11:23:15 -0400
committerGuenter Roeck <linux@roeck-us.net>2013-08-12 01:10:39 -0400
commit6c009501ff20012e80ef997443b49cf121a6e4b0 (patch)
tree08218967693dca5099f01903639e2c6b7c4277c8 /drivers/hwmon
parent698a7c24a5447ffd940bfc9f5e6e8448d836a2b4 (diff)
hwmon: (nct6775) Add support for NCT6102D/6106D
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/nct6775.c250
1 files changed, 225 insertions, 25 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index caff72658c1a..bebddbbd3907 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -33,6 +33,7 @@
33 * Supports the following chips: 33 * Supports the following chips:
34 * 34 *
35 * Chip #vin #fan #pwm #temp chip IDs man ID 35 * Chip #vin #fan #pwm #temp chip IDs man ID
36 * nct6106d 9 3 3 6+3 0xc450 0xc1 0x5ca3
36 * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3 37 * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3
37 * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3 38 * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3
38 * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3 39 * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3
@@ -59,10 +60,11 @@
59 60
60#define USE_ALTERNATE 61#define USE_ALTERNATE
61 62
62enum kinds { nct6775, nct6776, nct6779 }; 63enum kinds { nct6106, nct6775, nct6776, nct6779 };
63 64
64/* used to set data->name = nct6775_device_names[data->sio_kind] */ 65/* used to set data->name = nct6775_device_names[data->sio_kind] */
65static const char * const nct6775_device_names[] = { 66static const char * const nct6775_device_names[] = {
67 "nct6106",
66 "nct6775", 68 "nct6775",
67 "nct6776", 69 "nct6776",
68 "nct6779", 70 "nct6779",
@@ -91,6 +93,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
91#define SIO_REG_ENABLE 0x30 /* Logical device enable */ 93#define SIO_REG_ENABLE 0x30 /* Logical device enable */
92#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 94#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
93 95
96#define SIO_NCT6106_ID 0xc450
94#define SIO_NCT6775_ID 0xb470 97#define SIO_NCT6775_ID 0xb470
95#define SIO_NCT6776_ID 0xc330 98#define SIO_NCT6776_ID 0xc330
96#define SIO_NCT6779_ID 0xc560 99#define SIO_NCT6779_ID 0xc560
@@ -167,7 +170,7 @@ superio_exit(int ioreg)
167#define NUM_TEMP 10 /* Max number of temp attribute sets w/ limits*/ 170#define NUM_TEMP 10 /* Max number of temp attribute sets w/ limits*/
168#define NUM_TEMP_FIXED 6 /* Max number of fixed temp attribute sets */ 171#define NUM_TEMP_FIXED 6 /* Max number of fixed temp attribute sets */
169 172
170#define NUM_REG_ALARM 4 /* Max number of alarm registers */ 173#define NUM_REG_ALARM 7 /* Max number of alarm registers */
171 174
172/* Common and NCT6775 specific data */ 175/* Common and NCT6775 specific data */
173 176
@@ -185,6 +188,7 @@ static const u16 NCT6775_REG_IN[] = {
185 188
186#define NCT6775_REG_VBAT 0x5D 189#define NCT6775_REG_VBAT 0x5D
187#define NCT6775_REG_DIODE 0x5E 190#define NCT6775_REG_DIODE 0x5E
191#define NCT6775_DIODE_MASK 0x02
188 192
189#define NCT6775_REG_FANDIV1 0x506 193#define NCT6775_REG_FANDIV1 0x506
190#define NCT6775_REG_FANDIV2 0x507 194#define NCT6775_REG_FANDIV2 0x507
@@ -238,6 +242,7 @@ static const u16 NCT6775_REG_PWM_READ[] = { 0x01, 0x03, 0x11, 0x13, 0x15 };
238static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; 242static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
239static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d }; 243static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
240static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 }; 244static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 };
245static const u16 NCT6775_FAN_PULSE_SHIFT[] = { 0, 0, 0, 0, 0 };
241 246
242static const u16 NCT6775_REG_TEMP[] = { 247static const u16 NCT6775_REG_TEMP[] = {
243 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d }; 248 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d };
@@ -396,6 +401,7 @@ static const u16 NCT6779_REG_FAN_PULSES[] = {
396 401
397static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = { 402static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
398 0x136, 0x236, 0x336, 0x836, 0x936 }; 403 0x136, 0x236, 0x336, 0x836, 0x936 };
404#define NCT6779_CRITICAL_PWM_ENABLE_MASK 0x01
399static const u16 NCT6779_REG_CRITICAL_PWM[] = { 405static const u16 NCT6779_REG_CRITICAL_PWM[] = {
400 0x137, 0x237, 0x337, 0x837, 0x937 }; 406 0x137, 0x237, 0x337, 0x837, 0x937 };
401 407
@@ -449,6 +455,88 @@ static const u16 NCT6779_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6779_temp_label) - 1]
449static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1] 455static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1]
450 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a }; 456 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
451 457
458/* NCT6102D/NCT6106D specific data */
459
460#define NCT6106_REG_VBAT 0x318
461#define NCT6106_REG_DIODE 0x319
462#define NCT6106_DIODE_MASK 0x01
463
464static const u16 NCT6106_REG_IN_MAX[] = {
465 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9e, 0xa0, 0xa2 };
466static const u16 NCT6106_REG_IN_MIN[] = {
467 0x91, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9f, 0xa1, 0xa3 };
468static const u16 NCT6106_REG_IN[] = {
469 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09 };
470
471static const u16 NCT6106_REG_TEMP[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 };
472static const u16 NCT6106_REG_TEMP_HYST[] = {
473 0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7 };
474static const u16 NCT6106_REG_TEMP_OVER[] = {
475 0xc2, 0xc6, 0xca, 0xce, 0xd2, 0xd4 };
476static const u16 NCT6106_REG_TEMP_OFFSET[] = { 0x311, 0x312, 0x313 };
477static const u16 NCT6106_REG_TEMP_CONFIG[] = {
478 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc };
479
480static const u16 NCT6106_REG_FAN[] = { 0x20, 0x22, 0x24 };
481static const u16 NCT6106_REG_FAN_MIN[] = { 0xe0, 0xe2, 0xe4 };
482static const u16 NCT6106_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6, 0, 0 };
483static const u16 NCT6106_FAN_PULSE_SHIFT[] = { 0, 2, 4, 0, 0 };
484
485static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3 };
486static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04 };
487static const u16 NCT6106_REG_PWM[] = { 0x119, 0x129, 0x139 };
488static const u16 NCT6106_REG_PWM_READ[] = { 0x4a, 0x4b, 0x4c };
489static const u16 NCT6106_REG_FAN_MODE[] = { 0x113, 0x123, 0x133 };
490static const u16 NCT6106_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130 };
491static const u16 NCT6106_REG_TEMP_SOURCE[] = {
492 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 };
493
494static const u16 NCT6106_REG_CRITICAL_TEMP[] = { 0x11a, 0x12a, 0x13a };
495static const u16 NCT6106_REG_CRITICAL_TEMP_TOLERANCE[] = {
496 0x11b, 0x12b, 0x13b };
497
498static const u16 NCT6106_REG_CRITICAL_PWM_ENABLE[] = { 0x11c, 0x12c, 0x13c };
499#define NCT6106_CRITICAL_PWM_ENABLE_MASK 0x10
500static const u16 NCT6106_REG_CRITICAL_PWM[] = { 0x11d, 0x12d, 0x13d };
501
502static const u16 NCT6106_REG_FAN_STEP_UP_TIME[] = { 0x114, 0x124, 0x134 };
503static const u16 NCT6106_REG_FAN_STEP_DOWN_TIME[] = { 0x115, 0x125, 0x135 };
504static const u16 NCT6106_REG_FAN_STOP_OUTPUT[] = { 0x116, 0x126, 0x136 };
505static const u16 NCT6106_REG_FAN_START_OUTPUT[] = { 0x117, 0x127, 0x137 };
506static const u16 NCT6106_REG_FAN_STOP_TIME[] = { 0x118, 0x128, 0x138 };
507static const u16 NCT6106_REG_TOLERANCE_H[] = { 0x112, 0x122, 0x132 };
508
509static const u16 NCT6106_REG_TARGET[] = { 0x111, 0x121, 0x131 };
510
511static const u16 NCT6106_REG_WEIGHT_TEMP_SEL[] = { 0x168, 0x178, 0x188 };
512static const u16 NCT6106_REG_WEIGHT_TEMP_STEP[] = { 0x169, 0x179, 0x189 };
513static const u16 NCT6106_REG_WEIGHT_TEMP_STEP_TOL[] = { 0x16a, 0x17a, 0x18a };
514static const u16 NCT6106_REG_WEIGHT_DUTY_STEP[] = { 0x16b, 0x17b, 0x17c };
515static const u16 NCT6106_REG_WEIGHT_TEMP_BASE[] = { 0x16c, 0x17c, 0x18c };
516static const u16 NCT6106_REG_WEIGHT_DUTY_BASE[] = { 0x16d, 0x17d, 0x18d };
517
518static const u16 NCT6106_REG_AUTO_TEMP[] = { 0x160, 0x170, 0x180 };
519static const u16 NCT6106_REG_AUTO_PWM[] = { 0x164, 0x174, 0x184 };
520
521static const u16 NCT6106_REG_ALARM[NUM_REG_ALARM] = {
522 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d };
523
524static const s8 NCT6106_ALARM_BITS[] = {
525 0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */
526 9, -1, -1, -1, -1, -1, -1, /* in8..in14 */
527 -1, /* unused */
528 32, 33, 34, -1, -1, /* fan1..fan5 */
529 -1, -1, -1, /* unused */
530 16, 17, 18, 19, 20, 21, /* temp1..temp6 */
531 48, -1 /* intrusion0, intrusion1 */
532};
533
534static const u16 NCT6106_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1]
535 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x51, 0x52, 0x54 };
536
537static const u16 NCT6106_REG_TEMP_CRIT[ARRAY_SIZE(nct6776_temp_label) - 1]
538 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x204, 0x205 };
539
452static enum pwm_enable reg_to_pwm_enable(int pwm, int mode) 540static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
453{ 541{
454 if (mode == 0 && pwm == 255) 542 if (mode == 0 && pwm == 255)
@@ -570,6 +658,7 @@ struct nct6775_data {
570 u16 REG_CONFIG; 658 u16 REG_CONFIG;
571 u16 REG_VBAT; 659 u16 REG_VBAT;
572 u16 REG_DIODE; 660 u16 REG_DIODE;
661 u8 DIODE_MASK;
573 662
574 const s8 *ALARM_BITS; 663 const s8 *ALARM_BITS;
575 664
@@ -581,6 +670,7 @@ struct nct6775_data {
581 const u16 *REG_FAN_MODE; 670 const u16 *REG_FAN_MODE;
582 const u16 *REG_FAN_MIN; 671 const u16 *REG_FAN_MIN;
583 const u16 *REG_FAN_PULSES; 672 const u16 *REG_FAN_PULSES;
673 const u16 *FAN_PULSE_SHIFT;
584 const u16 *REG_FAN_TIME[3]; 674 const u16 *REG_FAN_TIME[3];
585 675
586 const u16 *REG_TOLERANCE_H; 676 const u16 *REG_TOLERANCE_H;
@@ -594,6 +684,10 @@ struct nct6775_data {
594 */ 684 */
595 const u16 *REG_PWM_READ; 685 const u16 *REG_PWM_READ;
596 686
687 const u16 *REG_CRITICAL_PWM_ENABLE;
688 u8 CRITICAL_PWM_ENABLE_MASK;
689 const u16 *REG_CRITICAL_PWM;
690
597 const u16 *REG_AUTO_TEMP; 691 const u16 *REG_AUTO_TEMP;
598 const u16 *REG_AUTO_PWM; 692 const u16 *REG_AUTO_PWM;
599 693
@@ -629,7 +723,7 @@ struct nct6775_data {
629 u8 has_fan_min; /* some fans don't have min register */ 723 u8 has_fan_min; /* some fans don't have min register */
630 bool has_fan_div; 724 bool has_fan_div;
631 725
632 u8 num_temp_alarms; /* 2 or 3 */ 726 u8 num_temp_alarms; /* 2, 3, or 6 */
633 u8 temp_fixed_num; /* 3 or 6 */ 727 u8 temp_fixed_num; /* 3 or 6 */
634 u8 temp_type[NUM_TEMP_FIXED]; 728 u8 temp_type[NUM_TEMP_FIXED];
635 s8 temp_offset[NUM_TEMP_FIXED]; 729 s8 temp_offset[NUM_TEMP_FIXED];
@@ -829,6 +923,10 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg,
829static bool is_word_sized(struct nct6775_data *data, u16 reg) 923static bool is_word_sized(struct nct6775_data *data, u16 reg)
830{ 924{
831 switch (data->kind) { 925 switch (data->kind) {
926 case nct6106:
927 return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
928 reg == 0xe0 || reg == 0xe2 || reg == 0xe4 ||
929 reg == 0x111 || reg == 0x121 || reg == 0x131;
832 case nct6775: 930 case nct6775:
833 return (((reg & 0xff00) == 0x100 || 931 return (((reg & 0xff00) == 0x100 ||
834 (reg & 0xff00) == 0x200) && 932 (reg & 0xff00) == 0x200) &&
@@ -1194,15 +1292,16 @@ static void nct6775_update_pwm_limits(struct device *dev)
1194 case nct6776: 1292 case nct6776:
1195 data->auto_pwm[i][data->auto_pwm_num] = 0xff; 1293 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1196 break; 1294 break;
1295 case nct6106:
1197 case nct6779: 1296 case nct6779:
1198 reg = nct6775_read_value(data, 1297 reg = nct6775_read_value(data,
1199 NCT6779_REG_CRITICAL_PWM_ENABLE[i]); 1298 data->REG_CRITICAL_PWM_ENABLE[i]);
1200 if (reg & 1) 1299 if (reg & data->CRITICAL_PWM_ENABLE_MASK)
1201 data->auto_pwm[i][data->auto_pwm_num] = 1300 reg = nct6775_read_value(data,
1202 nct6775_read_value(data, 1301 data->REG_CRITICAL_PWM[i]);
1203 NCT6779_REG_CRITICAL_PWM[i]);
1204 else 1302 else
1205 data->auto_pwm[i][data->auto_pwm_num] = 0xff; 1303 reg = 0xff;
1304 data->auto_pwm[i][data->auto_pwm_num] = reg;
1206 break; 1305 break;
1207 } 1306 }
1208 } 1307 }
@@ -1248,7 +1347,8 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
1248 data->fan_min[i] = nct6775_read_value(data, 1347 data->fan_min[i] = nct6775_read_value(data,
1249 data->REG_FAN_MIN[i]); 1348 data->REG_FAN_MIN[i]);
1250 data->fan_pulses[i] = 1349 data->fan_pulses[i] =
1251 nct6775_read_value(data, data->REG_FAN_PULSES[i]); 1350 (nct6775_read_value(data, data->REG_FAN_PULSES[i])
1351 >> data->FAN_PULSE_SHIFT[i]) & 0x03;
1252 1352
1253 nct6775_select_fan_div(dev, data, i, reg); 1353 nct6775_select_fan_div(dev, data, i, reg);
1254 } 1354 }
@@ -1548,6 +1648,7 @@ store_fan_pulses(struct device *dev, struct device_attribute *attr,
1548 int nr = sattr->index; 1648 int nr = sattr->index;
1549 unsigned long val; 1649 unsigned long val;
1550 int err; 1650 int err;
1651 u8 reg;
1551 1652
1552 err = kstrtoul(buf, 10, &val); 1653 err = kstrtoul(buf, 10, &val);
1553 if (err < 0) 1654 if (err < 0)
@@ -1558,7 +1659,10 @@ store_fan_pulses(struct device *dev, struct device_attribute *attr,
1558 1659
1559 mutex_lock(&data->update_lock); 1660 mutex_lock(&data->update_lock);
1560 data->fan_pulses[nr] = val & 3; 1661 data->fan_pulses[nr] = val & 3;
1561 nct6775_write_value(data, data->REG_FAN_PULSES[nr], val & 3); 1662 reg = nct6775_read_value(data, data->REG_FAN_PULSES[nr]);
1663 reg &= ~(0x03 << data->FAN_PULSE_SHIFT[nr]);
1664 reg |= (val & 3) << data->FAN_PULSE_SHIFT[nr];
1665 nct6775_write_value(data, data->REG_FAN_PULSES[nr], reg);
1562 mutex_unlock(&data->update_lock); 1666 mutex_unlock(&data->update_lock);
1563 1667
1564 return count; 1668 return count;
@@ -1708,7 +1812,7 @@ store_temp_type(struct device *dev, struct device_attribute *attr,
1708 int nr = sattr->index; 1812 int nr = sattr->index;
1709 unsigned long val; 1813 unsigned long val;
1710 int err; 1814 int err;
1711 u8 vbat, diode, bit; 1815 u8 vbat, diode, vbit, dbit;
1712 1816
1713 err = kstrtoul(buf, 10, &val); 1817 err = kstrtoul(buf, 10, &val);
1714 if (err < 0) 1818 if (err < 0)
@@ -1720,16 +1824,17 @@ store_temp_type(struct device *dev, struct device_attribute *attr,
1720 mutex_lock(&data->update_lock); 1824 mutex_lock(&data->update_lock);
1721 1825
1722 data->temp_type[nr] = val; 1826 data->temp_type[nr] = val;
1723 vbat = nct6775_read_value(data, data->REG_VBAT) & ~(0x02 << nr); 1827 vbit = 0x02 << nr;
1724 diode = nct6775_read_value(data, data->REG_DIODE) & ~(0x02 << nr); 1828 dbit = data->DIODE_MASK << nr;
1725 bit = 0x02 << nr; 1829 vbat = nct6775_read_value(data, data->REG_VBAT) & ~vbit;
1830 diode = nct6775_read_value(data, data->REG_DIODE) & ~dbit;
1726 switch (val) { 1831 switch (val) {
1727 case 1: /* CPU diode (diode, current mode) */ 1832 case 1: /* CPU diode (diode, current mode) */
1728 vbat |= bit; 1833 vbat |= vbit;
1729 diode |= bit; 1834 diode |= dbit;
1730 break; 1835 break;
1731 case 3: /* diode, voltage mode */ 1836 case 3: /* diode, voltage mode */
1732 vbat |= bit; 1837 vbat |= dbit;
1733 break; 1838 break;
1734 case 4: /* thermistor */ 1839 case 4: /* thermistor */
1735 break; 1840 break;
@@ -2471,17 +2576,18 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr,
2471 break; 2576 break;
2472 case nct6776: 2577 case nct6776:
2473 break; /* always enabled, nothing to do */ 2578 break; /* always enabled, nothing to do */
2579 case nct6106:
2474 case nct6779: 2580 case nct6779:
2475 nct6775_write_value(data, NCT6779_REG_CRITICAL_PWM[nr], 2581 nct6775_write_value(data, data->REG_CRITICAL_PWM[nr],
2476 val); 2582 val);
2477 reg = nct6775_read_value(data, 2583 reg = nct6775_read_value(data,
2478 NCT6779_REG_CRITICAL_PWM_ENABLE[nr]); 2584 data->REG_CRITICAL_PWM_ENABLE[nr]);
2479 if (val == 255) 2585 if (val == 255)
2480 reg &= ~0x01; 2586 reg &= ~data->CRITICAL_PWM_ENABLE_MASK;
2481 else 2587 else
2482 reg |= 0x01; 2588 reg |= data->CRITICAL_PWM_ENABLE_MASK;
2483 nct6775_write_value(data, 2589 nct6775_write_value(data,
2484 NCT6779_REG_CRITICAL_PWM_ENABLE[nr], 2590 data->REG_CRITICAL_PWM_ENABLE[nr],
2485 reg); 2591 reg);
2486 break; 2592 break;
2487 } 2593 }
@@ -2820,8 +2926,9 @@ static inline void nct6775_init_device(struct nct6775_data *data)
2820 for (i = 0; i < data->temp_fixed_num; i++) { 2926 for (i = 0; i < data->temp_fixed_num; i++) {
2821 if (!(data->have_temp_fixed & (1 << i))) 2927 if (!(data->have_temp_fixed & (1 << i)))
2822 continue; 2928 continue;
2823 if ((tmp & (0x02 << i))) /* diode */ 2929 if ((tmp & (data->DIODE_MASK << i))) /* diode */
2824 data->temp_type[i] = 3 - ((diode >> i) & 0x02); 2930 data->temp_type[i]
2931 = 3 - ((diode >> i) & data->DIODE_MASK);
2825 else /* thermistor */ 2932 else /* thermistor */
2826 data->temp_type[i] = 4; 2933 data->temp_type[i] = 4;
2827 } 2934 }
@@ -2875,6 +2982,17 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
2875 pwm3pin = fan3pin; 2982 pwm3pin = fan3pin;
2876 pwm4pin = 0; 2983 pwm4pin = 0;
2877 pwm5pin = 0; 2984 pwm5pin = 0;
2985 } else if (data->kind == nct6106) {
2986 regval = superio_inb(sio_data->sioreg, 0x24);
2987 fan3pin = !(regval & 0x80);
2988 pwm3pin = regval & 0x08;
2989 fan3min = fan3pin;
2990
2991 fan4pin = false;
2992 fan4min = false;
2993 fan5pin = false;
2994 pwm4pin = false;
2995 pwm5pin = false;
2878 } else { /* NCT6779D */ 2996 } else { /* NCT6779D */
2879 regval = superio_inb(sio_data->sioreg, 0x1c); 2997 regval = superio_inb(sio_data->sioreg, 0x1c);
2880 2998
@@ -2958,6 +3076,70 @@ static int nct6775_probe(struct platform_device *pdev)
2958 platform_set_drvdata(pdev, data); 3076 platform_set_drvdata(pdev, data);
2959 3077
2960 switch (data->kind) { 3078 switch (data->kind) {
3079 case nct6106:
3080 data->in_num = 9;
3081 data->pwm_num = 3;
3082 data->auto_pwm_num = 4;
3083 data->temp_fixed_num = 3;
3084 data->num_temp_alarms = 6;
3085
3086 data->fan_from_reg = fan_from_reg13;
3087 data->fan_from_reg_min = fan_from_reg13;
3088
3089 data->temp_label = nct6776_temp_label;
3090 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
3091
3092 data->REG_VBAT = NCT6106_REG_VBAT;
3093 data->REG_DIODE = NCT6106_REG_DIODE;
3094 data->DIODE_MASK = NCT6106_DIODE_MASK;
3095 data->REG_VIN = NCT6106_REG_IN;
3096 data->REG_IN_MINMAX[0] = NCT6106_REG_IN_MIN;
3097 data->REG_IN_MINMAX[1] = NCT6106_REG_IN_MAX;
3098 data->REG_TARGET = NCT6106_REG_TARGET;
3099 data->REG_FAN = NCT6106_REG_FAN;
3100 data->REG_FAN_MODE = NCT6106_REG_FAN_MODE;
3101 data->REG_FAN_MIN = NCT6106_REG_FAN_MIN;
3102 data->REG_FAN_PULSES = NCT6106_REG_FAN_PULSES;
3103 data->FAN_PULSE_SHIFT = NCT6106_FAN_PULSE_SHIFT;
3104 data->REG_FAN_TIME[0] = NCT6106_REG_FAN_STOP_TIME;
3105 data->REG_FAN_TIME[1] = NCT6106_REG_FAN_STEP_UP_TIME;
3106 data->REG_FAN_TIME[2] = NCT6106_REG_FAN_STEP_DOWN_TIME;
3107 data->REG_PWM[0] = NCT6106_REG_PWM;
3108 data->REG_PWM[1] = NCT6106_REG_FAN_START_OUTPUT;
3109 data->REG_PWM[2] = NCT6106_REG_FAN_STOP_OUTPUT;
3110 data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
3111 data->REG_PWM[6] = NCT6106_REG_WEIGHT_DUTY_BASE;
3112 data->REG_PWM_READ = NCT6106_REG_PWM_READ;
3113 data->REG_PWM_MODE = NCT6106_REG_PWM_MODE;
3114 data->PWM_MODE_MASK = NCT6106_PWM_MODE_MASK;
3115 data->REG_AUTO_TEMP = NCT6106_REG_AUTO_TEMP;
3116 data->REG_AUTO_PWM = NCT6106_REG_AUTO_PWM;
3117 data->REG_CRITICAL_TEMP = NCT6106_REG_CRITICAL_TEMP;
3118 data->REG_CRITICAL_TEMP_TOLERANCE
3119 = NCT6106_REG_CRITICAL_TEMP_TOLERANCE;
3120 data->REG_CRITICAL_PWM_ENABLE = NCT6106_REG_CRITICAL_PWM_ENABLE;
3121 data->CRITICAL_PWM_ENABLE_MASK
3122 = NCT6106_CRITICAL_PWM_ENABLE_MASK;
3123 data->REG_CRITICAL_PWM = NCT6106_REG_CRITICAL_PWM;
3124 data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
3125 data->REG_TEMP_SOURCE = NCT6106_REG_TEMP_SOURCE;
3126 data->REG_TEMP_SEL = NCT6106_REG_TEMP_SEL;
3127 data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
3128 data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
3129 data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
3130 data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE;
3131 data->REG_ALARM = NCT6106_REG_ALARM;
3132 data->ALARM_BITS = NCT6106_ALARM_BITS;
3133
3134 reg_temp = NCT6106_REG_TEMP;
3135 num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP);
3136 reg_temp_over = NCT6106_REG_TEMP_OVER;
3137 reg_temp_hyst = NCT6106_REG_TEMP_HYST;
3138 reg_temp_config = NCT6106_REG_TEMP_CONFIG;
3139 reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE;
3140 reg_temp_crit = NCT6106_REG_TEMP_CRIT;
3141
3142 break;
2961 case nct6775: 3143 case nct6775:
2962 data->in_num = 9; 3144 data->in_num = 9;
2963 data->pwm_num = 3; 3145 data->pwm_num = 3;
@@ -2980,6 +3162,7 @@ static int nct6775_probe(struct platform_device *pdev)
2980 data->REG_CONFIG = NCT6775_REG_CONFIG; 3162 data->REG_CONFIG = NCT6775_REG_CONFIG;
2981 data->REG_VBAT = NCT6775_REG_VBAT; 3163 data->REG_VBAT = NCT6775_REG_VBAT;
2982 data->REG_DIODE = NCT6775_REG_DIODE; 3164 data->REG_DIODE = NCT6775_REG_DIODE;
3165 data->DIODE_MASK = NCT6775_DIODE_MASK;
2983 data->REG_VIN = NCT6775_REG_IN; 3166 data->REG_VIN = NCT6775_REG_IN;
2984 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 3167 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
2985 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 3168 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
@@ -2988,6 +3171,7 @@ static int nct6775_probe(struct platform_device *pdev)
2988 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; 3171 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
2989 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN; 3172 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
2990 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES; 3173 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
3174 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
2991 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; 3175 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
2992 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; 3176 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
2993 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; 3177 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
@@ -3045,6 +3229,7 @@ static int nct6775_probe(struct platform_device *pdev)
3045 data->REG_CONFIG = NCT6775_REG_CONFIG; 3229 data->REG_CONFIG = NCT6775_REG_CONFIG;
3046 data->REG_VBAT = NCT6775_REG_VBAT; 3230 data->REG_VBAT = NCT6775_REG_VBAT;
3047 data->REG_DIODE = NCT6775_REG_DIODE; 3231 data->REG_DIODE = NCT6775_REG_DIODE;
3232 data->DIODE_MASK = NCT6775_DIODE_MASK;
3048 data->REG_VIN = NCT6775_REG_IN; 3233 data->REG_VIN = NCT6775_REG_IN;
3049 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 3234 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3050 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 3235 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
@@ -3053,6 +3238,7 @@ static int nct6775_probe(struct platform_device *pdev)
3053 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; 3238 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
3054 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; 3239 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
3055 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES; 3240 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
3241 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
3056 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; 3242 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3057 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; 3243 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3058 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; 3244 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
@@ -3110,6 +3296,7 @@ static int nct6775_probe(struct platform_device *pdev)
3110 data->REG_CONFIG = NCT6775_REG_CONFIG; 3296 data->REG_CONFIG = NCT6775_REG_CONFIG;
3111 data->REG_VBAT = NCT6775_REG_VBAT; 3297 data->REG_VBAT = NCT6775_REG_VBAT;
3112 data->REG_DIODE = NCT6775_REG_DIODE; 3298 data->REG_DIODE = NCT6775_REG_DIODE;
3299 data->DIODE_MASK = NCT6775_DIODE_MASK;
3113 data->REG_VIN = NCT6779_REG_IN; 3300 data->REG_VIN = NCT6779_REG_IN;
3114 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 3301 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3115 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 3302 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
@@ -3118,6 +3305,7 @@ static int nct6775_probe(struct platform_device *pdev)
3118 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; 3305 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
3119 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; 3306 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
3120 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES; 3307 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
3308 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
3121 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; 3309 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3122 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; 3310 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3123 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; 3311 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
@@ -3135,6 +3323,10 @@ static int nct6775_probe(struct platform_device *pdev)
3135 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP; 3323 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3136 data->REG_CRITICAL_TEMP_TOLERANCE 3324 data->REG_CRITICAL_TEMP_TOLERANCE
3137 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE; 3325 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
3326 data->REG_CRITICAL_PWM_ENABLE = NCT6779_REG_CRITICAL_PWM_ENABLE;
3327 data->CRITICAL_PWM_ENABLE_MASK
3328 = NCT6779_CRITICAL_PWM_ENABLE_MASK;
3329 data->REG_CRITICAL_PWM = NCT6779_REG_CRITICAL_PWM;
3138 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; 3330 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
3139 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; 3331 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
3140 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; 3332 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
@@ -3286,6 +3478,7 @@ static int nct6775_probe(struct platform_device *pdev)
3286 case nct6776: 3478 case nct6776:
3287 data->have_vid = (cr2a & 0x60) == 0x40; 3479 data->have_vid = (cr2a & 0x60) == 0x40;
3288 break; 3480 break;
3481 case nct6106:
3289 case nct6779: 3482 case nct6779:
3290 break; 3483 break;
3291 } 3484 }
@@ -3307,6 +3500,9 @@ static int nct6775_probe(struct platform_device *pdev)
3307 tmp = superio_inb(sio_data->sioreg, 3500 tmp = superio_inb(sio_data->sioreg,
3308 NCT6775_REG_CR_FAN_DEBOUNCE); 3501 NCT6775_REG_CR_FAN_DEBOUNCE);
3309 switch (data->kind) { 3502 switch (data->kind) {
3503 case nct6106:
3504 tmp |= 0xe0;
3505 break;
3310 case nct6775: 3506 case nct6775:
3311 tmp |= 0x1e; 3507 tmp |= 0x1e;
3312 break; 3508 break;
@@ -3478,6 +3674,7 @@ static struct platform_driver nct6775_driver = {
3478}; 3674};
3479 3675
3480static const char * const nct6775_sio_names[] __initconst = { 3676static const char * const nct6775_sio_names[] __initconst = {
3677 "NCT6106D",
3481 "NCT6775F", 3678 "NCT6775F",
3482 "NCT6776D/F", 3679 "NCT6776D/F",
3483 "NCT6779D", 3680 "NCT6779D",
@@ -3500,6 +3697,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
3500 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) 3697 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
3501 | superio_inb(sioaddr, SIO_REG_DEVID + 1); 3698 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
3502 switch (val & SIO_ID_MASK) { 3699 switch (val & SIO_ID_MASK) {
3700 case SIO_NCT6106_ID:
3701 sio_data->kind = nct6106;
3702 break;
3503 case SIO_NCT6775_ID: 3703 case SIO_NCT6775_ID:
3504 sio_data->kind = nct6775; 3704 sio_data->kind = nct6775;
3505 break; 3705 break;