diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hwmon/Kconfig | 5 | ||||
-rw-r--r-- | drivers/hwmon/nct6775.c | 172 |
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 | ||
70 | enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793, | 70 | enum 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] */ |
74 | static const char * const nct6775_device_names[] = { | 74 | static 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 | ||
85 | static const char * const nct6775_sio_names[] __initconst = { | 86 | static 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 | ||
96 | static unsigned short force_id; | 98 | static 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 | ||
130 | enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; | 133 | enum 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 | ||
274 | static const u16 NCT6775_REG_TARGET[] = { | 277 | static const u16 NCT6775_REG_TARGET[] = { |
275 | 0x101, 0x201, 0x301, 0x801, 0x901, 0xa01 }; | 278 | 0x101, 0x201, 0x301, 0x801, 0x901, 0xa01, 0xb01 }; |
276 | static const u16 NCT6775_REG_FAN_MODE[] = { | 279 | static const u16 NCT6775_REG_FAN_MODE[] = { |
277 | 0x102, 0x202, 0x302, 0x802, 0x902, 0xa02 }; | 280 | 0x102, 0x202, 0x302, 0x802, 0x902, 0xa02, 0xb02 }; |
278 | static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = { | 281 | static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = { |
279 | 0x103, 0x203, 0x303, 0x803, 0x903, 0xa03 }; | 282 | 0x103, 0x203, 0x303, 0x803, 0x903, 0xa03, 0xb03 }; |
280 | static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = { | 283 | static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = { |
281 | 0x104, 0x204, 0x304, 0x804, 0x904, 0xa04 }; | 284 | 0x104, 0x204, 0x304, 0x804, 0x904, 0xa04, 0xb04 }; |
282 | static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { | 285 | static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { |
283 | 0x105, 0x205, 0x305, 0x805, 0x905, 0xa05 }; | 286 | 0x105, 0x205, 0x305, 0x805, 0x905, 0xa05, 0xb05 }; |
284 | static const u16 NCT6775_REG_FAN_START_OUTPUT[] = { | 287 | static const u16 NCT6775_REG_FAN_START_OUTPUT[] = { |
285 | 0x106, 0x206, 0x306, 0x806, 0x906, 0xa06 }; | 288 | 0x106, 0x206, 0x306, 0x806, 0x906, 0xa06, 0xb06 }; |
286 | static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a }; | 289 | static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a }; |
287 | static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b }; | 290 | static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b }; |
288 | 291 | ||
289 | static const u16 NCT6775_REG_FAN_STOP_TIME[] = { | 292 | static const u16 NCT6775_REG_FAN_STOP_TIME[] = { |
290 | 0x107, 0x207, 0x307, 0x807, 0x907, 0xa07 }; | 293 | 0x107, 0x207, 0x307, 0x807, 0x907, 0xa07, 0xb07 }; |
291 | static const u16 NCT6775_REG_PWM[] = { | 294 | static const u16 NCT6775_REG_PWM[] = { |
292 | 0x109, 0x209, 0x309, 0x809, 0x909, 0xa09 }; | 295 | 0x109, 0x209, 0x309, 0x809, 0x909, 0xa09, 0xb09 }; |
293 | static const u16 NCT6775_REG_PWM_READ[] = { | 296 | static const u16 NCT6775_REG_PWM_READ[] = { |
294 | 0x01, 0x03, 0x11, 0x13, 0x15, 0xa09 }; | 297 | 0x01, 0x03, 0x11, 0x13, 0x15, 0xa09, 0xb09 }; |
295 | 298 | ||
296 | static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; | 299 | static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; |
297 | static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d }; | 300 | static 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 | ||
316 | static const u16 NCT6775_REG_TEMP_SEL[] = { | 319 | static const u16 NCT6775_REG_TEMP_SEL[] = { |
317 | 0x100, 0x200, 0x300, 0x800, 0x900, 0xa00 }; | 320 | 0x100, 0x200, 0x300, 0x800, 0x900, 0xa00, 0xb00 }; |
318 | 321 | ||
319 | static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = { | 322 | static 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[] = { | |||
330 | static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; | 333 | static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; |
331 | 334 | ||
332 | static const u16 NCT6775_REG_AUTO_TEMP[] = { | 335 | static const u16 NCT6775_REG_AUTO_TEMP[] = { |
333 | 0x121, 0x221, 0x321, 0x821, 0x921, 0xa21 }; | 336 | 0x121, 0x221, 0x321, 0x821, 0x921, 0xa21, 0xb21 }; |
334 | static const u16 NCT6775_REG_AUTO_PWM[] = { | 337 | static 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[] = { | |||
340 | static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 }; | 343 | static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 }; |
341 | 344 | ||
342 | static const u16 NCT6775_REG_CRITICAL_TEMP[] = { | 345 | static const u16 NCT6775_REG_CRITICAL_TEMP[] = { |
343 | 0x135, 0x235, 0x335, 0x835, 0x935, 0xa35 }; | 346 | 0x135, 0x235, 0x335, 0x835, 0x935, 0xa35, 0xb35 }; |
344 | static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = { | 347 | static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = { |
345 | 0x138, 0x238, 0x338, 0x838, 0x938, 0xa38 }; | 348 | 0x138, 0x238, 0x338, 0x838, 0x938, 0xa38, 0xb38 }; |
346 | 349 | ||
347 | static const char *const nct6775_temp_label[] = { | 350 | static 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 | ||
416 | static const u16 NCT6776_REG_TOLERANCE_H[] = { | 419 | static const u16 NCT6776_REG_TOLERANCE_H[] = { |
417 | 0x10c, 0x20c, 0x30c, 0x80c, 0x90c, 0xa0c }; | 420 | 0x10c, 0x20c, 0x30c, 0x80c, 0x90c, 0xa0c, 0xb0c }; |
418 | 421 | ||
419 | static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0, 0, 0, 0 }; | 422 | static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0, 0, 0, 0 }; |
420 | static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0, 0, 0, 0 }; | 423 | static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0, 0, 0, 0 }; |
421 | 424 | ||
422 | static const u16 NCT6776_REG_FAN_MIN[] = { | 425 | static const u16 NCT6776_REG_FAN_MIN[] = { |
423 | 0x63a, 0x63c, 0x63e, 0x640, 0x642, 0x64a }; | 426 | 0x63a, 0x63c, 0x63e, 0x640, 0x642, 0x64a, 0x64c }; |
424 | static const u16 NCT6776_REG_FAN_PULSES[] = { | 427 | static const u16 NCT6776_REG_FAN_PULSES[] = { |
425 | 0x644, 0x645, 0x646, 0x647, 0x648, 0x649 }; | 428 | 0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0 }; |
426 | 429 | ||
427 | static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = { | 430 | static 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 | ||
499 | static const u16 NCT6779_REG_FAN[] = { | 502 | static const u16 NCT6779_REG_FAN[] = { |
500 | 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba }; | 503 | 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x660 }; |
501 | static const u16 NCT6779_REG_FAN_PULSES[] = { | 504 | static const u16 NCT6779_REG_FAN_PULSES[] = { |
502 | 0x644, 0x645, 0x646, 0x647, 0x648, 0x649 }; | 505 | 0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0 }; |
503 | 506 | ||
504 | static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = { | 507 | static 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 |
507 | static const u16 NCT6779_REG_CRITICAL_PWM[] = { | 510 | static const u16 NCT6779_REG_CRITICAL_PWM[] = { |
508 | 0x137, 0x237, 0x337, 0x837, 0x937, 0xa37 }; | 511 | 0x137, 0x237, 0x337, 0x837, 0x937, 0xa37, 0xb37 }; |
509 | 512 | ||
510 | static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; | 513 | static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; |
511 | static const u16 NCT6779_REG_TEMP_MON[] = { 0x73, 0x75, 0x77, 0x79, 0x7b }; | 514 | static 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 | ||
715 | static 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 | |||
3361 | nct6775_check_fan_inputs(struct nct6775_data *data) | 3407 | nct6775_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 | ||
3506 | static void add_temp_sensors(struct nct6775_data *data, const u16 *regp, | 3566 | static 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); |