summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/Kconfig5
-rw-r--r--drivers/hwmon/nct6775.c172
2 files changed, 125 insertions, 52 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index ef23553ff5cb..15bc62ac5749 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1219,8 +1219,9 @@ config SENSORS_NCT6775
1219 help 1219 help
1220 If you say yes here you get support for the hardware monitoring 1220 If you say yes here you get support for the hardware monitoring
1221 functionality of the Nuvoton NCT6106D, NCT6775F, NCT6776F, NCT6779D, 1221 functionality of the Nuvoton NCT6106D, NCT6775F, NCT6776F, NCT6779D,
1222 NCT6791D, NCT6792D, NCT6793D, and compatible Super-I/O chips. This 1222 NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D, and compatible
1223 driver replaces the w83627ehf driver for NCT6775F and NCT6776F. 1223 Super-I/O chips. This driver replaces the w83627ehf driver for
1224 NCT6775F and NCT6776F.
1224 1225
1225 This driver can also be built as a module. If so, the module 1226 This driver can also be built as a module. If so, the module
1226 will be called nct6775. 1227 will be called nct6775.
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index 5662b23dbffa..fdf24f008d75 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -41,7 +41,7 @@
41 * nct6792d 15 6 6 2+6 0xc910 0xc1 0x5ca3 41 * nct6792d 15 6 6 2+6 0xc910 0xc1 0x5ca3
42 * nct6793d 15 6 6 2+6 0xd120 0xc1 0x5ca3 42 * nct6793d 15 6 6 2+6 0xd120 0xc1 0x5ca3
43 * nct6795d 14 6 6 2+6 0xd350 0xc1 0x5ca3 43 * nct6795d 14 6 6 2+6 0xd350 0xc1 0x5ca3
44 * 44 * nct6796d 14 7 7 2+6 0xd420 0xc1 0x5ca3
45 * 45 *
46 * #temp lists the number of monitored temperature sources (first value) plus 46 * #temp lists the number of monitored temperature sources (first value) plus
47 * the number of directly connectable temperature sensors (second value). 47 * the number of directly connectable temperature sensors (second value).
@@ -68,7 +68,7 @@
68#define USE_ALTERNATE 68#define USE_ALTERNATE
69 69
70enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793, 70enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793,
71 nct6795 }; 71 nct6795, nct6796 };
72 72
73/* used to set data->name = nct6775_device_names[data->sio_kind] */ 73/* used to set data->name = nct6775_device_names[data->sio_kind] */
74static const char * const nct6775_device_names[] = { 74static const char * const nct6775_device_names[] = {
@@ -80,6 +80,7 @@ static const char * const nct6775_device_names[] = {
80 "nct6792", 80 "nct6792",
81 "nct6793", 81 "nct6793",
82 "nct6795", 82 "nct6795",
83 "nct6796",
83}; 84};
84 85
85static const char * const nct6775_sio_names[] __initconst = { 86static const char * const nct6775_sio_names[] __initconst = {
@@ -91,6 +92,7 @@ static const char * const nct6775_sio_names[] __initconst = {
91 "NCT6792D", 92 "NCT6792D",
92 "NCT6793D", 93 "NCT6793D",
93 "NCT6795D", 94 "NCT6795D",
95 "NCT6796D",
94}; 96};
95 97
96static unsigned short force_id; 98static unsigned short force_id;
@@ -125,6 +127,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
125#define SIO_NCT6792_ID 0xc910 127#define SIO_NCT6792_ID 0xc910
126#define SIO_NCT6793_ID 0xd120 128#define SIO_NCT6793_ID 0xd120
127#define SIO_NCT6795_ID 0xd350 129#define SIO_NCT6795_ID 0xd350
130#define SIO_NCT6796_ID 0xd420
128#define SIO_ID_MASK 0xFFF0 131#define SIO_ID_MASK 0xFFF0
129 132
130enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; 133enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
@@ -201,7 +204,7 @@ superio_exit(int ioreg)
201#define NUM_REG_ALARM 7 /* Max number of alarm registers */ 204#define NUM_REG_ALARM 7 /* Max number of alarm registers */
202#define NUM_REG_BEEP 5 /* Max number of beep registers */ 205#define NUM_REG_BEEP 5 /* Max number of beep registers */
203 206
204#define NUM_FAN 6 207#define NUM_FAN 7
205 208
206#define TEMP_SOURCE_VIRTUAL 0x1f 209#define TEMP_SOURCE_VIRTUAL 0x1f
207 210
@@ -272,26 +275,26 @@ static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 };
272/* Advanced Fan control, some values are common for all fans */ 275/* Advanced Fan control, some values are common for all fans */
273 276
274static const u16 NCT6775_REG_TARGET[] = { 277static const u16 NCT6775_REG_TARGET[] = {
275 0x101, 0x201, 0x301, 0x801, 0x901, 0xa01 }; 278 0x101, 0x201, 0x301, 0x801, 0x901, 0xa01, 0xb01 };
276static const u16 NCT6775_REG_FAN_MODE[] = { 279static const u16 NCT6775_REG_FAN_MODE[] = {
277 0x102, 0x202, 0x302, 0x802, 0x902, 0xa02 }; 280 0x102, 0x202, 0x302, 0x802, 0x902, 0xa02, 0xb02 };
278static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = { 281static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = {
279 0x103, 0x203, 0x303, 0x803, 0x903, 0xa03 }; 282 0x103, 0x203, 0x303, 0x803, 0x903, 0xa03, 0xb03 };
280static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = { 283static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = {
281 0x104, 0x204, 0x304, 0x804, 0x904, 0xa04 }; 284 0x104, 0x204, 0x304, 0x804, 0x904, 0xa04, 0xb04 };
282static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { 285static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = {
283 0x105, 0x205, 0x305, 0x805, 0x905, 0xa05 }; 286 0x105, 0x205, 0x305, 0x805, 0x905, 0xa05, 0xb05 };
284static const u16 NCT6775_REG_FAN_START_OUTPUT[] = { 287static const u16 NCT6775_REG_FAN_START_OUTPUT[] = {
285 0x106, 0x206, 0x306, 0x806, 0x906, 0xa06 }; 288 0x106, 0x206, 0x306, 0x806, 0x906, 0xa06, 0xb06 };
286static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a }; 289static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
287static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b }; 290static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
288 291
289static const u16 NCT6775_REG_FAN_STOP_TIME[] = { 292static const u16 NCT6775_REG_FAN_STOP_TIME[] = {
290 0x107, 0x207, 0x307, 0x807, 0x907, 0xa07 }; 293 0x107, 0x207, 0x307, 0x807, 0x907, 0xa07, 0xb07 };
291static const u16 NCT6775_REG_PWM[] = { 294static const u16 NCT6775_REG_PWM[] = {
292 0x109, 0x209, 0x309, 0x809, 0x909, 0xa09 }; 295 0x109, 0x209, 0x309, 0x809, 0x909, 0xa09, 0xb09 };
293static const u16 NCT6775_REG_PWM_READ[] = { 296static const u16 NCT6775_REG_PWM_READ[] = {
294 0x01, 0x03, 0x11, 0x13, 0x15, 0xa09 }; 297 0x01, 0x03, 0x11, 0x13, 0x15, 0xa09, 0xb09 };
295 298
296static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; 299static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
297static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d }; 300static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
@@ -314,7 +317,7 @@ static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
314 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 }; 317 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 };
315 318
316static const u16 NCT6775_REG_TEMP_SEL[] = { 319static const u16 NCT6775_REG_TEMP_SEL[] = {
317 0x100, 0x200, 0x300, 0x800, 0x900, 0xa00 }; 320 0x100, 0x200, 0x300, 0x800, 0x900, 0xa00, 0xb00 };
318 321
319static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = { 322static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = {
320 0x139, 0x239, 0x339, 0x839, 0x939, 0xa39 }; 323 0x139, 0x239, 0x339, 0x839, 0x939, 0xa39 };
@@ -330,9 +333,9 @@ static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = {
330static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; 333static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 };
331 334
332static const u16 NCT6775_REG_AUTO_TEMP[] = { 335static const u16 NCT6775_REG_AUTO_TEMP[] = {
333 0x121, 0x221, 0x321, 0x821, 0x921, 0xa21 }; 336 0x121, 0x221, 0x321, 0x821, 0x921, 0xa21, 0xb21 };
334static const u16 NCT6775_REG_AUTO_PWM[] = { 337static const u16 NCT6775_REG_AUTO_PWM[] = {
335 0x127, 0x227, 0x327, 0x827, 0x927, 0xa27 }; 338 0x127, 0x227, 0x327, 0x827, 0x927, 0xa27, 0xb27 };
336 339
337#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p)) 340#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p))
338#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p)) 341#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p))
@@ -340,9 +343,9 @@ static const u16 NCT6775_REG_AUTO_PWM[] = {
340static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 }; 343static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 };
341 344
342static const u16 NCT6775_REG_CRITICAL_TEMP[] = { 345static const u16 NCT6775_REG_CRITICAL_TEMP[] = {
343 0x135, 0x235, 0x335, 0x835, 0x935, 0xa35 }; 346 0x135, 0x235, 0x335, 0x835, 0x935, 0xa35, 0xb35 };
344static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = { 347static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = {
345 0x138, 0x238, 0x338, 0x838, 0x938, 0xa38 }; 348 0x138, 0x238, 0x338, 0x838, 0x938, 0xa38, 0xb38 };
346 349
347static const char *const nct6775_temp_label[] = { 350static const char *const nct6775_temp_label[] = {
348 "", 351 "",
@@ -414,15 +417,15 @@ static const s8 NCT6776_BEEP_BITS[] = {
414 30, 31 }; /* intrusion0, intrusion1 */ 417 30, 31 }; /* intrusion0, intrusion1 */
415 418
416static const u16 NCT6776_REG_TOLERANCE_H[] = { 419static const u16 NCT6776_REG_TOLERANCE_H[] = {
417 0x10c, 0x20c, 0x30c, 0x80c, 0x90c, 0xa0c }; 420 0x10c, 0x20c, 0x30c, 0x80c, 0x90c, 0xa0c, 0xb0c };
418 421
419static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0, 0, 0, 0 }; 422static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0, 0, 0, 0 };
420static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0, 0, 0, 0 }; 423static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0, 0, 0, 0 };
421 424
422static const u16 NCT6776_REG_FAN_MIN[] = { 425static const u16 NCT6776_REG_FAN_MIN[] = {
423 0x63a, 0x63c, 0x63e, 0x640, 0x642, 0x64a }; 426 0x63a, 0x63c, 0x63e, 0x640, 0x642, 0x64a, 0x64c };
424static const u16 NCT6776_REG_FAN_PULSES[] = { 427static const u16 NCT6776_REG_FAN_PULSES[] = {
425 0x644, 0x645, 0x646, 0x647, 0x648, 0x649 }; 428 0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0 };
426 429
427static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = { 430static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = {
428 0x13e, 0x23e, 0x33e, 0x83e, 0x93e, 0xa3e }; 431 0x13e, 0x23e, 0x33e, 0x83e, 0x93e, 0xa3e };
@@ -497,15 +500,15 @@ static const s8 NCT6779_BEEP_BITS[] = {
497 30, 31 }; /* intrusion0, intrusion1 */ 500 30, 31 }; /* intrusion0, intrusion1 */
498 501
499static const u16 NCT6779_REG_FAN[] = { 502static const u16 NCT6779_REG_FAN[] = {
500 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba }; 503 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x660 };
501static const u16 NCT6779_REG_FAN_PULSES[] = { 504static const u16 NCT6779_REG_FAN_PULSES[] = {
502 0x644, 0x645, 0x646, 0x647, 0x648, 0x649 }; 505 0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0 };
503 506
504static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = { 507static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
505 0x136, 0x236, 0x336, 0x836, 0x936, 0xa36 }; 508 0x136, 0x236, 0x336, 0x836, 0x936, 0xa36, 0xb36 };
506#define NCT6779_CRITICAL_PWM_ENABLE_MASK 0x01 509#define NCT6779_CRITICAL_PWM_ENABLE_MASK 0x01
507static const u16 NCT6779_REG_CRITICAL_PWM[] = { 510static const u16 NCT6779_REG_CRITICAL_PWM[] = {
508 0x137, 0x237, 0x337, 0x837, 0x937, 0xa37 }; 511 0x137, 0x237, 0x337, 0x837, 0x937, 0xa37, 0xb37 };
509 512
510static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; 513static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
511static const u16 NCT6779_REG_TEMP_MON[] = { 0x73, 0x75, 0x77, 0x79, 0x7b }; 514static const u16 NCT6779_REG_TEMP_MON[] = { 0x73, 0x75, 0x77, 0x79, 0x7b };
@@ -709,6 +712,43 @@ static const char *const nct6795_temp_label[] = {
709 712
710#define NCT6795_TEMP_MASK 0xbfffff7e 713#define NCT6795_TEMP_MASK 0xbfffff7e
711 714
715static const char *const nct6796_temp_label[] = {
716 "",
717 "SYSTIN",
718 "CPUTIN",
719 "AUXTIN0",
720 "AUXTIN1",
721 "AUXTIN2",
722 "AUXTIN3",
723 "AUXTIN4",
724 "SMBUSMASTER 0",
725 "SMBUSMASTER 1",
726 "",
727 "",
728 "",
729 "",
730 "",
731 "",
732 "PECI Agent 0",
733 "PECI Agent 1",
734 "PCH_CHIP_CPU_MAX_TEMP",
735 "PCH_CHIP_TEMP",
736 "PCH_CPU_TEMP",
737 "PCH_MCH_TEMP",
738 "PCH_DIM0_TEMP",
739 "PCH_DIM1_TEMP",
740 "PCH_DIM2_TEMP",
741 "PCH_DIM3_TEMP",
742 "BYTE_TEMP0",
743 "BYTE_TEMP1",
744 "PECI Agent 0 Calibration",
745 "PECI Agent 1 Calibration",
746 "",
747 "Virtual_TEMP"
748};
749
750#define NCT6796_TEMP_MASK 0xbfff03fe
751
712/* NCT6102D/NCT6106D specific data */ 752/* NCT6102D/NCT6106D specific data */
713 753
714#define NCT6106_REG_VBAT 0x318 754#define NCT6106_REG_VBAT 0x318
@@ -1233,11 +1273,13 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg)
1233 case nct6792: 1273 case nct6792:
1234 case nct6793: 1274 case nct6793:
1235 case nct6795: 1275 case nct6795:
1276 case nct6796:
1236 return reg == 0x150 || reg == 0x153 || reg == 0x155 || 1277 return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
1237 ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) || 1278 ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) ||
1238 reg == 0x402 || 1279 reg == 0x402 ||
1239 reg == 0x63a || reg == 0x63c || reg == 0x63e || 1280 reg == 0x63a || reg == 0x63c || reg == 0x63e ||
1240 reg == 0x640 || reg == 0x642 || reg == 0x64a || 1281 reg == 0x640 || reg == 0x642 || reg == 0x64a ||
1282 reg == 0x64c || reg == 0x660 ||
1241 reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 || 1283 reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
1242 reg == 0x7b || reg == 0x7d; 1284 reg == 0x7b || reg == 0x7d;
1243 } 1285 }
@@ -1586,6 +1628,7 @@ static void nct6775_update_pwm_limits(struct device *dev)
1586 case nct6792: 1628 case nct6792:
1587 case nct6793: 1629 case nct6793:
1588 case nct6795: 1630 case nct6795:
1631 case nct6796:
1589 reg = nct6775_read_value(data, 1632 reg = nct6775_read_value(data,
1590 data->REG_CRITICAL_PWM_ENABLE[i]); 1633 data->REG_CRITICAL_PWM_ENABLE[i]);
1591 if (reg & data->CRITICAL_PWM_ENABLE_MASK) 1634 if (reg & data->CRITICAL_PWM_ENABLE_MASK)
@@ -2094,6 +2137,8 @@ static umode_t nct6775_fan_is_visible(struct kobject *kobj,
2094 return 0; 2137 return 0;
2095 if (nr == 2 && data->BEEP_BITS[FAN_ALARM_BASE + fan] == -1) 2138 if (nr == 2 && data->BEEP_BITS[FAN_ALARM_BASE + fan] == -1)
2096 return 0; 2139 return 0;
2140 if (nr == 3 && !data->REG_FAN_PULSES[fan])
2141 return 0;
2097 if (nr == 4 && !(data->has_fan_min & BIT(fan))) 2142 if (nr == 4 && !(data->has_fan_min & BIT(fan)))
2098 return 0; 2143 return 0;
2099 if (nr == 5 && data->kind != nct6775) 2144 if (nr == 5 && data->kind != nct6775)
@@ -3006,6 +3051,7 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr,
3006 case nct6792: 3051 case nct6792:
3007 case nct6793: 3052 case nct6793:
3008 case nct6795: 3053 case nct6795:
3054 case nct6796:
3009 nct6775_write_value(data, data->REG_CRITICAL_PWM[nr], 3055 nct6775_write_value(data, data->REG_CRITICAL_PWM[nr],
3010 val); 3056 val);
3011 reg = nct6775_read_value(data, 3057 reg = nct6775_read_value(data,
@@ -3361,9 +3407,9 @@ static void
3361nct6775_check_fan_inputs(struct nct6775_data *data) 3407nct6775_check_fan_inputs(struct nct6775_data *data)
3362{ 3408{
3363 bool fan3pin = false, fan4pin = false, fan4min = false; 3409 bool fan3pin = false, fan4pin = false, fan4min = false;
3364 bool fan5pin = false, fan6pin = false; 3410 bool fan5pin = false, fan6pin = false, fan7pin = false;
3365 bool pwm3pin = false, pwm4pin = false, pwm5pin = false; 3411 bool pwm3pin = false, pwm4pin = false, pwm5pin = false;
3366 bool pwm6pin = false; 3412 bool pwm6pin = false, pwm7pin = false;
3367 int sioreg = data->sioreg; 3413 int sioreg = data->sioreg;
3368 int regval; 3414 int regval;
3369 3415
@@ -3424,8 +3470,9 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
3424 regval = superio_inb(sioreg, 0x24); 3470 regval = superio_inb(sioreg, 0x24);
3425 fan3pin = !(regval & 0x80); 3471 fan3pin = !(regval & 0x80);
3426 pwm3pin = regval & 0x08; 3472 pwm3pin = regval & 0x08;
3427 } else { /* NCT6779D, NCT6791D, NCT6792D, NCT6793D, or NCT6795D */ 3473 } else {
3428 int regval_1b, regval_2a, regval_2f, regval_eb; 3474 /* NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D */
3475 int regval_1b, regval_2a, regval_2f;
3429 bool dsw_en; 3476 bool dsw_en;
3430 3477
3431 regval = superio_inb(sioreg, 0x1c); 3478 regval = superio_inb(sioreg, 0x1c);
@@ -3447,6 +3494,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
3447 break; 3494 break;
3448 case nct6793: 3495 case nct6793:
3449 case nct6795: 3496 case nct6795:
3497 case nct6796:
3450 regval_1b = superio_inb(sioreg, 0x1b); 3498 regval_1b = superio_inb(sioreg, 0x1b);
3451 regval_2a = superio_inb(sioreg, 0x2a); 3499 regval_2a = superio_inb(sioreg, 0x2a);
3452 regval_2f = superio_inb(sioreg, 0x2f); 3500 regval_2f = superio_inb(sioreg, 0x2f);
@@ -3458,24 +3506,27 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
3458 if (!fan5pin) 3506 if (!fan5pin)
3459 fan5pin = regval_1b & BIT(5); 3507 fan5pin = regval_1b & BIT(5);
3460 3508
3461 if (!dsw_en) { 3509 superio_select(sioreg, NCT6775_LD_12);
3462 fan6pin = regval & BIT(1); 3510 if (data->kind != nct6796) {
3463 pwm6pin = regval & BIT(0); 3511 int regval_eb = superio_inb(sioreg, 0xeb);
3512
3513 if (!dsw_en) {
3514 fan6pin = regval & BIT(1);
3515 pwm6pin = regval & BIT(0);
3516 }
3517
3518 if (!fan5pin)
3519 fan5pin = regval_eb & BIT(5);
3520 if (!pwm5pin)
3521 pwm5pin = (regval_eb & BIT(4)) &&
3522 !(regval_2a & BIT(0));
3523 if (!fan6pin)
3524 fan6pin = regval_eb & BIT(3);
3525 if (!pwm6pin)
3526 pwm6pin = regval_eb & BIT(2);
3464 } 3527 }
3465 3528
3466 superio_select(sioreg, NCT6775_LD_12); 3529 if (data->kind == nct6795 || data->kind == nct6796) {
3467 regval_eb = superio_inb(sioreg, 0xeb);
3468 if (!fan5pin)
3469 fan5pin = regval_eb & BIT(5);
3470 if (!pwm5pin)
3471 pwm5pin = (regval_eb & BIT(4)) &&
3472 !(regval_2a & BIT(0));
3473 if (!fan6pin)
3474 fan6pin = regval_eb & BIT(3);
3475 if (!pwm6pin)
3476 pwm6pin = regval_eb & BIT(2);
3477
3478 if (data->kind == nct6795) {
3479 int regval_ed = superio_inb(sioreg, 0xed); 3530 int regval_ed = superio_inb(sioreg, 0xed);
3480 3531
3481 if (!fan6pin) 3532 if (!fan6pin)
@@ -3486,6 +3537,15 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
3486 pwm6pin = (regval_2a & BIT(3)) && 3537 pwm6pin = (regval_2a & BIT(3)) &&
3487 (regval_ed & BIT(2)); 3538 (regval_ed & BIT(2));
3488 } 3539 }
3540
3541 if (data->kind == nct6796) {
3542 int regval_1d = superio_inb(sioreg, 0x1d);
3543 int regval_2b = superio_inb(sioreg, 0x2b);
3544
3545 fan7pin = !(regval_2b & BIT(2));
3546 pwm7pin = !(regval_1d & (BIT(2) | BIT(3)));
3547 }
3548
3489 break; 3549 break;
3490 default: /* NCT6779D */ 3550 default: /* NCT6779D */
3491 break; 3551 break;
@@ -3496,11 +3556,11 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
3496 3556
3497 /* fan 1 and 2 (0x03) are always present */ 3557 /* fan 1 and 2 (0x03) are always present */
3498 data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) | 3558 data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) |
3499 (fan5pin << 4) | (fan6pin << 5); 3559 (fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
3500 data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) | 3560 data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) |
3501 (fan5pin << 4) | (fan6pin << 5); 3561 (fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
3502 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) | 3562 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) |
3503 (pwm5pin << 4) | (pwm6pin << 5); 3563 (pwm5pin << 4) | (pwm6pin << 5) | (pwm7pin << 6);
3504} 3564}
3505 3565
3506static void add_temp_sensors(struct nct6775_data *data, const u16 *regp, 3566static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
@@ -3859,8 +3919,9 @@ static int nct6775_probe(struct platform_device *pdev)
3859 case nct6792: 3919 case nct6792:
3860 case nct6793: 3920 case nct6793:
3861 case nct6795: 3921 case nct6795:
3922 case nct6796:
3862 data->in_num = 15; 3923 data->in_num = 15;
3863 data->pwm_num = 6; 3924 data->pwm_num = (data->kind == nct6796) ? 7 : 6;
3864 data->auto_pwm_num = 4; 3925 data->auto_pwm_num = 4;
3865 data->has_fan_div = false; 3926 data->has_fan_div = false;
3866 data->temp_fixed_num = 6; 3927 data->temp_fixed_num = 6;
@@ -3894,6 +3955,10 @@ static int nct6775_probe(struct platform_device *pdev)
3894 data->temp_label = nct6795_temp_label; 3955 data->temp_label = nct6795_temp_label;
3895 data->temp_mask = NCT6795_TEMP_MASK; 3956 data->temp_mask = NCT6795_TEMP_MASK;
3896 break; 3957 break;
3958 case nct6796:
3959 data->temp_label = nct6796_temp_label;
3960 data->temp_mask = NCT6796_TEMP_MASK;
3961 break;
3897 } 3962 }
3898 3963
3899 data->REG_CONFIG = NCT6775_REG_CONFIG; 3964 data->REG_CONFIG = NCT6775_REG_CONFIG;
@@ -4162,6 +4227,7 @@ static int nct6775_probe(struct platform_device *pdev)
4162 case nct6792: 4227 case nct6792:
4163 case nct6793: 4228 case nct6793:
4164 case nct6795: 4229 case nct6795:
4230 case nct6796:
4165 break; 4231 break;
4166 } 4232 }
4167 4233
@@ -4196,6 +4262,7 @@ static int nct6775_probe(struct platform_device *pdev)
4196 case nct6792: 4262 case nct6792:
4197 case nct6793: 4263 case nct6793:
4198 case nct6795: 4264 case nct6795:
4265 case nct6796:
4199 tmp |= 0x7e; 4266 tmp |= 0x7e;
4200 break; 4267 break;
4201 } 4268 }
@@ -4294,7 +4361,8 @@ static int __maybe_unused nct6775_resume(struct device *dev)
4294 superio_outb(sioreg, SIO_REG_ENABLE, data->sio_reg_enable); 4361 superio_outb(sioreg, SIO_REG_ENABLE, data->sio_reg_enable);
4295 4362
4296 if (data->kind == nct6791 || data->kind == nct6792 || 4363 if (data->kind == nct6791 || data->kind == nct6792 ||
4297 data->kind == nct6793 || data->kind == nct6795) 4364 data->kind == nct6793 || data->kind == nct6795 ||
4365 data->kind == nct6796)
4298 nct6791_enable_io_mapping(sioreg); 4366 nct6791_enable_io_mapping(sioreg);
4299 4367
4300 superio_exit(sioreg); 4368 superio_exit(sioreg);
@@ -4394,6 +4462,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
4394 case SIO_NCT6795_ID: 4462 case SIO_NCT6795_ID:
4395 sio_data->kind = nct6795; 4463 sio_data->kind = nct6795;
4396 break; 4464 break;
4465 case SIO_NCT6796_ID:
4466 sio_data->kind = nct6796;
4467 break;
4397 default: 4468 default:
4398 if (val != 0xffff) 4469 if (val != 0xffff)
4399 pr_debug("unsupported chip ID: 0x%04x\n", val); 4470 pr_debug("unsupported chip ID: 0x%04x\n", val);
@@ -4420,7 +4491,8 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
4420 } 4491 }
4421 4492
4422 if (sio_data->kind == nct6791 || sio_data->kind == nct6792 || 4493 if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
4423 sio_data->kind == nct6793 || sio_data->kind == nct6795) 4494 sio_data->kind == nct6793 || sio_data->kind == nct6795 ||
4495 sio_data->kind == nct6796)
4424 nct6791_enable_io_mapping(sioaddr); 4496 nct6791_enable_io_mapping(sioaddr);
4425 4497
4426 superio_exit(sioaddr); 4498 superio_exit(sioaddr);