Commit 29c7cb48 authored by Björn Gerhart's avatar Björn Gerhart Committed by Guenter Roeck

hwmon: (nct6775) Integrate new model nct6116

Add support for NCT6116D to nct6775 driver.
Signed-off-by: default avatarBjoern Gerhart <gerhart@posteo.de>
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent c64fce7f
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
* *
* Chip #vin #fan #pwm #temp chip IDs man ID * Chip #vin #fan #pwm #temp chip IDs man ID
* nct6106d 9 3 3 6+3 0xc450 0xc1 0x5ca3 * nct6106d 9 3 3 6+3 0xc450 0xc1 0x5ca3
* nct6116d 9 5 5 3+3 0xd280 0xc1 0x5ca3
* nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3 * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3
* nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3 * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3
* nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3 * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3
...@@ -58,12 +59,13 @@ ...@@ -58,12 +59,13 @@
#define USE_ALTERNATE #define USE_ALTERNATE
enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793, enum kinds { nct6106, nct6116, nct6775, nct6776, nct6779, nct6791, nct6792,
nct6795, nct6796, nct6797, nct6798 }; nct6793, nct6795, nct6796, nct6797, nct6798 };
/* used to set data->name = nct6775_device_names[data->sio_kind] */ /* used to set data->name = nct6775_device_names[data->sio_kind] */
static const char * const nct6775_device_names[] = { static const char * const nct6775_device_names[] = {
"nct6106", "nct6106",
"nct6116",
"nct6775", "nct6775",
"nct6776", "nct6776",
"nct6779", "nct6779",
...@@ -78,6 +80,7 @@ static const char * const nct6775_device_names[] = { ...@@ -78,6 +80,7 @@ static const char * const nct6775_device_names[] = {
static const char * const nct6775_sio_names[] __initconst = { static const char * const nct6775_sio_names[] __initconst = {
"NCT6106D", "NCT6106D",
"NCT6116D",
"NCT6775F", "NCT6775F",
"NCT6776D/F", "NCT6776D/F",
"NCT6779D", "NCT6779D",
...@@ -115,6 +118,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal"); ...@@ -115,6 +118,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
#define SIO_NCT6106_ID 0xc450 #define SIO_NCT6106_ID 0xc450
#define SIO_NCT6116_ID 0xd280
#define SIO_NCT6775_ID 0xb470 #define SIO_NCT6775_ID 0xb470
#define SIO_NCT6776_ID 0xc330 #define SIO_NCT6776_ID 0xc330
#define SIO_NCT6779_ID 0xc560 #define SIO_NCT6779_ID 0xc560
...@@ -825,10 +829,8 @@ static const u16 NCT6106_FAN_PULSE_SHIFT[] = { 0, 2, 4 }; ...@@ -825,10 +829,8 @@ static const u16 NCT6106_FAN_PULSE_SHIFT[] = { 0, 2, 4 };
static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3 }; static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3 };
static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04 }; static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04 };
static const u16 NCT6106_REG_PWM[] = { 0x119, 0x129, 0x139 };
static const u16 NCT6106_REG_PWM_READ[] = { 0x4a, 0x4b, 0x4c }; static const u16 NCT6106_REG_PWM_READ[] = { 0x4a, 0x4b, 0x4c };
static const u16 NCT6106_REG_FAN_MODE[] = { 0x113, 0x123, 0x133 }; static const u16 NCT6106_REG_FAN_MODE[] = { 0x113, 0x123, 0x133 };
static const u16 NCT6106_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130 };
static const u16 NCT6106_REG_TEMP_SOURCE[] = { static const u16 NCT6106_REG_TEMP_SOURCE[] = {
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 }; 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 };
...@@ -896,6 +898,70 @@ static const u16 NCT6106_REG_TEMP_CRIT[32] = { ...@@ -896,6 +898,70 @@ static const u16 NCT6106_REG_TEMP_CRIT[32] = {
[12] = 0x205, [12] = 0x205,
}; };
/* NCT6112D/NCT6114D/NCT6116D specific data */
static const u16 NCT6116_REG_FAN[] = { 0x20, 0x22, 0x24, 0x26, 0x28 };
static const u16 NCT6116_REG_FAN_MIN[] = { 0xe0, 0xe2, 0xe4, 0xe6, 0xe8 };
static const u16 NCT6116_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6, 0xf6, 0xf5 };
static const u16 NCT6116_FAN_PULSE_SHIFT[] = { 0, 2, 4, 6, 6 };
static const u16 NCT6116_REG_PWM[] = { 0x119, 0x129, 0x139, 0x199, 0x1a9 };
static const u16 NCT6116_REG_FAN_MODE[] = { 0x113, 0x123, 0x133, 0x193, 0x1a3 };
static const u16 NCT6116_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130, 0x190, 0x1a0 };
static const u16 NCT6116_REG_TEMP_SOURCE[] = {
0xb0, 0xb1, 0xb2 };
static const u16 NCT6116_REG_CRITICAL_TEMP[] = {
0x11a, 0x12a, 0x13a, 0x19a, 0x1aa };
static const u16 NCT6116_REG_CRITICAL_TEMP_TOLERANCE[] = {
0x11b, 0x12b, 0x13b, 0x19b, 0x1ab };
static const u16 NCT6116_REG_CRITICAL_PWM_ENABLE[] = {
0x11c, 0x12c, 0x13c, 0x19c, 0x1ac };
static const u16 NCT6116_REG_CRITICAL_PWM[] = {
0x11d, 0x12d, 0x13d, 0x19d, 0x1ad };
static const u16 NCT6116_REG_FAN_STEP_UP_TIME[] = {
0x114, 0x124, 0x134, 0x194, 0x1a4 };
static const u16 NCT6116_REG_FAN_STEP_DOWN_TIME[] = {
0x115, 0x125, 0x135, 0x195, 0x1a5 };
static const u16 NCT6116_REG_FAN_STOP_OUTPUT[] = {
0x116, 0x126, 0x136, 0x196, 0x1a6 };
static const u16 NCT6116_REG_FAN_START_OUTPUT[] = {
0x117, 0x127, 0x137, 0x197, 0x1a7 };
static const u16 NCT6116_REG_FAN_STOP_TIME[] = {
0x118, 0x128, 0x138, 0x198, 0x1a8 };
static const u16 NCT6116_REG_TOLERANCE_H[] = {
0x112, 0x122, 0x132, 0x192, 0x1a2 };
static const u16 NCT6116_REG_TARGET[] = {
0x111, 0x121, 0x131, 0x191, 0x1a1 };
static const u16 NCT6116_REG_AUTO_TEMP[] = {
0x160, 0x170, 0x180, 0x1d0, 0x1e0 };
static const u16 NCT6116_REG_AUTO_PWM[] = {
0x164, 0x174, 0x184, 0x1d4, 0x1e4 };
static const s8 NCT6116_ALARM_BITS[] = {
0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */
9, -1, -1, -1, -1, -1, -1, /* in8..in9 */
-1, /* unused */
32, 33, 34, 35, 36, /* fan1..fan5 */
-1, -1, -1, /* unused */
16, 17, 18, -1, -1, -1, /* temp1..temp6 */
48, -1 /* intrusion0, intrusion1 */
};
static const s8 NCT6116_BEEP_BITS[] = {
0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */
9, 10, 11, 12, -1, -1, -1, /* in8..in14 */
32, /* global beep enable */
24, 25, 26, 27, 28, /* fan1..fan5 */
-1, -1, -1, /* unused */
16, 17, 18, -1, -1, -1, /* temp1..temp6 */
34, -1 /* intrusion0, intrusion1 */
};
static enum pwm_enable reg_to_pwm_enable(int pwm, int mode) static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
{ {
if (mode == 0 && pwm == 255) if (mode == 0 && pwm == 255)
...@@ -1294,6 +1360,11 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg) ...@@ -1294,6 +1360,11 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg)
return reg == 0x20 || reg == 0x22 || reg == 0x24 || return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
reg == 0xe0 || reg == 0xe2 || reg == 0xe4 || reg == 0xe0 || reg == 0xe2 || reg == 0xe4 ||
reg == 0x111 || reg == 0x121 || reg == 0x131; reg == 0x111 || reg == 0x121 || reg == 0x131;
case nct6116:
return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
reg == 0x26 || reg == 0x28 || reg == 0xe0 || reg == 0xe2 ||
reg == 0xe4 || reg == 0xe6 || reg == 0xe8 || reg == 0x111 ||
reg == 0x121 || reg == 0x131 || reg == 0x191 || reg == 0x1a1;
case nct6775: case nct6775:
return (((reg & 0xff00) == 0x100 || return (((reg & 0xff00) == 0x100 ||
(reg & 0xff00) == 0x200) && (reg & 0xff00) == 0x200) &&
...@@ -1673,6 +1744,7 @@ static void nct6775_update_pwm_limits(struct device *dev) ...@@ -1673,6 +1744,7 @@ static void nct6775_update_pwm_limits(struct device *dev)
data->auto_pwm[i][data->auto_pwm_num] = 0xff; data->auto_pwm[i][data->auto_pwm_num] = 0xff;
break; break;
case nct6106: case nct6106:
case nct6116:
case nct6779: case nct6779:
case nct6791: case nct6791:
case nct6792: case nct6792:
...@@ -3109,6 +3181,7 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr, ...@@ -3109,6 +3181,7 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr,
case nct6776: case nct6776:
break; /* always enabled, nothing to do */ break; /* always enabled, nothing to do */
case nct6106: case nct6106:
case nct6116:
case nct6779: case nct6779:
case nct6791: case nct6791:
case nct6792: case nct6792:
...@@ -3535,6 +3608,23 @@ nct6775_check_fan_inputs(struct nct6775_data *data) ...@@ -3535,6 +3608,23 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
fan3pin = !(cr24 & 0x80); fan3pin = !(cr24 & 0x80);
pwm3pin = cr24 & 0x08; pwm3pin = cr24 & 0x08;
} else if (data->kind == nct6116) {
int cr1a = superio_inb(sioreg, 0x1a);
int cr1b = superio_inb(sioreg, 0x1b);
int cr24 = superio_inb(sioreg, 0x24);
int cr2a = superio_inb(sioreg, 0x2a);
int cr2b = superio_inb(sioreg, 0x2b);
int cr2f = superio_inb(sioreg, 0x2f);
fan3pin = !(cr2b & 0x10);
fan4pin = (cr2b & 0x80) || // pin 1(2)
(!(cr2f & 0x10) && (cr1a & 0x04)); // pin 65(66)
fan5pin = (cr2b & 0x80) || // pin 126(127)
(!(cr1b & 0x03) && (cr2a & 0x02)); // pin 94(96)
pwm3pin = fan3pin && (cr24 & 0x08);
pwm4pin = fan4pin;
pwm5pin = fan5pin;
} else { } else {
/* /*
* NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D, * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
...@@ -3765,7 +3855,7 @@ static int nct6775_probe(struct platform_device *pdev) ...@@ -3765,7 +3855,7 @@ static int nct6775_probe(struct platform_device *pdev)
data->REG_FAN_TIME[1] = NCT6106_REG_FAN_STEP_UP_TIME; data->REG_FAN_TIME[1] = NCT6106_REG_FAN_STEP_UP_TIME;
data->REG_FAN_TIME[2] = NCT6106_REG_FAN_STEP_DOWN_TIME; data->REG_FAN_TIME[2] = NCT6106_REG_FAN_STEP_DOWN_TIME;
data->REG_TOLERANCE_H = NCT6106_REG_TOLERANCE_H; data->REG_TOLERANCE_H = NCT6106_REG_TOLERANCE_H;
data->REG_PWM[0] = NCT6106_REG_PWM; data->REG_PWM[0] = NCT6116_REG_PWM;
data->REG_PWM[1] = NCT6106_REG_FAN_START_OUTPUT; data->REG_PWM[1] = NCT6106_REG_FAN_START_OUTPUT;
data->REG_PWM[2] = NCT6106_REG_FAN_STOP_OUTPUT; data->REG_PWM[2] = NCT6106_REG_FAN_STOP_OUTPUT;
data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP; data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
...@@ -3784,7 +3874,7 @@ static int nct6775_probe(struct platform_device *pdev) ...@@ -3784,7 +3874,7 @@ static int nct6775_probe(struct platform_device *pdev)
data->REG_CRITICAL_PWM = NCT6106_REG_CRITICAL_PWM; data->REG_CRITICAL_PWM = NCT6106_REG_CRITICAL_PWM;
data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET; data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
data->REG_TEMP_SOURCE = NCT6106_REG_TEMP_SOURCE; data->REG_TEMP_SOURCE = NCT6106_REG_TEMP_SOURCE;
data->REG_TEMP_SEL = NCT6106_REG_TEMP_SEL; data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL;
data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL; data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP; data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL; data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
...@@ -3806,6 +3896,79 @@ static int nct6775_probe(struct platform_device *pdev) ...@@ -3806,6 +3896,79 @@ static int nct6775_probe(struct platform_device *pdev)
reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L; reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L;
reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H; reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H;
break;
case nct6116:
data->in_num = 9;
data->pwm_num = 3;
data->auto_pwm_num = 4;
data->temp_fixed_num = 3;
data->num_temp_alarms = 3;
data->num_temp_beeps = 3;
data->fan_from_reg = fan_from_reg13;
data->fan_from_reg_min = fan_from_reg13;
data->temp_label = nct6776_temp_label;
data->temp_mask = NCT6776_TEMP_MASK;
data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK;
data->REG_VBAT = NCT6106_REG_VBAT;
data->REG_DIODE = NCT6106_REG_DIODE;
data->DIODE_MASK = NCT6106_DIODE_MASK;
data->REG_VIN = NCT6106_REG_IN;
data->REG_IN_MINMAX[0] = NCT6106_REG_IN_MIN;
data->REG_IN_MINMAX[1] = NCT6106_REG_IN_MAX;
data->REG_TARGET = NCT6116_REG_TARGET;
data->REG_FAN = NCT6116_REG_FAN;
data->REG_FAN_MODE = NCT6116_REG_FAN_MODE;
data->REG_FAN_MIN = NCT6116_REG_FAN_MIN;
data->REG_FAN_PULSES = NCT6116_REG_FAN_PULSES;
data->FAN_PULSE_SHIFT = NCT6116_FAN_PULSE_SHIFT;
data->REG_FAN_TIME[0] = NCT6116_REG_FAN_STOP_TIME;
data->REG_FAN_TIME[1] = NCT6116_REG_FAN_STEP_UP_TIME;
data->REG_FAN_TIME[2] = NCT6116_REG_FAN_STEP_DOWN_TIME;
data->REG_TOLERANCE_H = NCT6116_REG_TOLERANCE_H;
data->REG_PWM[0] = NCT6116_REG_PWM;
data->REG_PWM[1] = NCT6116_REG_FAN_START_OUTPUT;
data->REG_PWM[2] = NCT6116_REG_FAN_STOP_OUTPUT;
data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
data->REG_PWM[6] = NCT6106_REG_WEIGHT_DUTY_BASE;
data->REG_PWM_READ = NCT6106_REG_PWM_READ;
data->REG_PWM_MODE = NCT6106_REG_PWM_MODE;
data->PWM_MODE_MASK = NCT6106_PWM_MODE_MASK;
data->REG_AUTO_TEMP = NCT6116_REG_AUTO_TEMP;
data->REG_AUTO_PWM = NCT6116_REG_AUTO_PWM;
data->REG_CRITICAL_TEMP = NCT6116_REG_CRITICAL_TEMP;
data->REG_CRITICAL_TEMP_TOLERANCE
= NCT6116_REG_CRITICAL_TEMP_TOLERANCE;
data->REG_CRITICAL_PWM_ENABLE = NCT6116_REG_CRITICAL_PWM_ENABLE;
data->CRITICAL_PWM_ENABLE_MASK
= NCT6106_CRITICAL_PWM_ENABLE_MASK;
data->REG_CRITICAL_PWM = NCT6116_REG_CRITICAL_PWM;
data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
data->REG_TEMP_SOURCE = NCT6116_REG_TEMP_SOURCE;
data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL;
data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE;
data->REG_ALARM = NCT6106_REG_ALARM;
data->ALARM_BITS = NCT6116_ALARM_BITS;
data->REG_BEEP = NCT6106_REG_BEEP;
data->BEEP_BITS = NCT6116_BEEP_BITS;
reg_temp = NCT6106_REG_TEMP;
reg_temp_mon = NCT6106_REG_TEMP_MON;
num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP);
num_reg_temp_mon = ARRAY_SIZE(NCT6106_REG_TEMP_MON);
reg_temp_over = NCT6106_REG_TEMP_OVER;
reg_temp_hyst = NCT6106_REG_TEMP_HYST;
reg_temp_config = NCT6106_REG_TEMP_CONFIG;
reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE;
reg_temp_crit = NCT6106_REG_TEMP_CRIT;
reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L;
reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H;
break; break;
case nct6775: case nct6775:
data->in_num = 9; data->in_num = 9;
...@@ -4352,6 +4515,7 @@ static int nct6775_probe(struct platform_device *pdev) ...@@ -4352,6 +4515,7 @@ static int nct6775_probe(struct platform_device *pdev)
data->have_vid = (cr2a & 0x60) == 0x40; data->have_vid = (cr2a & 0x60) == 0x40;
break; break;
case nct6106: case nct6106:
case nct6116:
case nct6779: case nct6779:
case nct6791: case nct6791:
case nct6792: case nct6792:
...@@ -4381,6 +4545,7 @@ static int nct6775_probe(struct platform_device *pdev) ...@@ -4381,6 +4545,7 @@ static int nct6775_probe(struct platform_device *pdev)
NCT6775_REG_CR_FAN_DEBOUNCE); NCT6775_REG_CR_FAN_DEBOUNCE);
switch (data->kind) { switch (data->kind) {
case nct6106: case nct6106:
case nct6116:
tmp |= 0xe0; tmp |= 0xe0;
break; break;
case nct6775: case nct6775:
...@@ -4576,6 +4741,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data) ...@@ -4576,6 +4741,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
case SIO_NCT6106_ID: case SIO_NCT6106_ID:
sio_data->kind = nct6106; sio_data->kind = nct6106;
break; break;
case SIO_NCT6116_ID:
sio_data->kind = nct6116;
break;
case SIO_NCT6775_ID: case SIO_NCT6775_ID:
sio_data->kind = nct6775; sio_data->kind = nct6775;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment