diff options
author | Guenter Roeck <linux@roeck-us.net> | 2014-11-16 12:50:04 -0500 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2014-11-30 23:13:13 -0500 |
commit | 8aefb93f09bf4464f6da8ee071edcede9517d4bf (patch) | |
tree | 6156386531f2b72078efd0afdaac91f323ecb9b6 /drivers/hwmon | |
parent | b6e6dd8e9f6adf9765db2bb93e6a11f92811369a (diff) |
hwmon: (nct6775) Add support for NCT6792D
NCT6792D is similar to NCT6791D. Only beep control and temperature
monitoring registers are different.
Reviewed-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 4 | ||||
-rw-r--r-- | drivers/hwmon/nct6775.c | 47 |
2 files changed, 39 insertions, 12 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index f893e0ff0081..fcca19b53bd2 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -1117,8 +1117,8 @@ config SENSORS_NCT6775 | |||
1117 | help | 1117 | help |
1118 | If you say yes here you get support for the hardware monitoring | 1118 | If you say yes here you get support for the hardware monitoring |
1119 | functionality of the Nuvoton NCT6106D, NCT6775F, NCT6776F, NCT6779D, | 1119 | functionality of the Nuvoton NCT6106D, NCT6775F, NCT6776F, NCT6779D, |
1120 | NCT6791D and compatible Super-I/O chips. This driver replaces the | 1120 | NCT6791D, NCT6792D and compatible Super-I/O chips. This driver |
1121 | w83627ehf driver for NCT6775F and NCT6776F. | 1121 | replaces the w83627ehf driver for NCT6775F and NCT6776F. |
1122 | 1122 | ||
1123 | This driver can also be built as a module. If so, the module | 1123 | This driver can also be built as a module. If so, the module |
1124 | will be called nct6775. | 1124 | will be called nct6775. |
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 504cbddbdd90..c0dd307001c9 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c | |||
@@ -38,6 +38,7 @@ | |||
38 | * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3 | 38 | * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3 |
39 | * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3 | 39 | * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3 |
40 | * nct6791d 15 6 6 2+6 0xc800 0xc1 0x5ca3 | 40 | * nct6791d 15 6 6 2+6 0xc800 0xc1 0x5ca3 |
41 | * nct6792d 15 6 6 2+6 0xc910 0xc1 0x5ca3 | ||
41 | * | 42 | * |
42 | * #temp lists the number of monitored temperature sources (first value) plus | 43 | * #temp lists the number of monitored temperature sources (first value) plus |
43 | * the number of directly connectable temperature sensors (second value). | 44 | * the number of directly connectable temperature sensors (second value). |
@@ -61,7 +62,7 @@ | |||
61 | 62 | ||
62 | #define USE_ALTERNATE | 63 | #define USE_ALTERNATE |
63 | 64 | ||
64 | enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791 }; | 65 | enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792 }; |
65 | 66 | ||
66 | /* used to set data->name = nct6775_device_names[data->sio_kind] */ | 67 | /* used to set data->name = nct6775_device_names[data->sio_kind] */ |
67 | static const char * const nct6775_device_names[] = { | 68 | static const char * const nct6775_device_names[] = { |
@@ -70,6 +71,7 @@ static const char * const nct6775_device_names[] = { | |||
70 | "nct6776", | 71 | "nct6776", |
71 | "nct6779", | 72 | "nct6779", |
72 | "nct6791", | 73 | "nct6791", |
74 | "nct6792", | ||
73 | }; | 75 | }; |
74 | 76 | ||
75 | static unsigned short force_id; | 77 | static unsigned short force_id; |
@@ -100,6 +102,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal"); | |||
100 | #define SIO_NCT6776_ID 0xc330 | 102 | #define SIO_NCT6776_ID 0xc330 |
101 | #define SIO_NCT6779_ID 0xc560 | 103 | #define SIO_NCT6779_ID 0xc560 |
102 | #define SIO_NCT6791_ID 0xc800 | 104 | #define SIO_NCT6791_ID 0xc800 |
105 | #define SIO_NCT6792_ID 0xc910 | ||
103 | #define SIO_ID_MASK 0xFFF0 | 106 | #define SIO_ID_MASK 0xFFF0 |
104 | 107 | ||
105 | enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; | 108 | enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; |
@@ -529,6 +532,12 @@ static const s8 NCT6791_ALARM_BITS[] = { | |||
529 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ | 532 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ |
530 | 12, 9 }; /* intrusion0, intrusion1 */ | 533 | 12, 9 }; /* intrusion0, intrusion1 */ |
531 | 534 | ||
535 | /* NCT6792 specific data */ | ||
536 | |||
537 | static const u16 NCT6792_REG_TEMP_MON[] = { | ||
538 | 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d }; | ||
539 | static const u16 NCT6792_REG_BEEP[NUM_REG_BEEP] = { | ||
540 | 0xb2, 0xb3, 0xb4, 0xb5, 0xbf }; | ||
532 | 541 | ||
533 | /* NCT6102D/NCT6106D specific data */ | 542 | /* NCT6102D/NCT6106D specific data */ |
534 | 543 | ||
@@ -1043,13 +1052,14 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg) | |||
1043 | reg == 0x73 || reg == 0x75 || reg == 0x77; | 1052 | reg == 0x73 || reg == 0x75 || reg == 0x77; |
1044 | case nct6779: | 1053 | case nct6779: |
1045 | case nct6791: | 1054 | case nct6791: |
1055 | case nct6792: | ||
1046 | return reg == 0x150 || reg == 0x153 || reg == 0x155 || | 1056 | return reg == 0x150 || reg == 0x153 || reg == 0x155 || |
1047 | ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) || | 1057 | ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) || |
1048 | reg == 0x402 || | 1058 | reg == 0x402 || |
1049 | reg == 0x63a || reg == 0x63c || reg == 0x63e || | 1059 | reg == 0x63a || reg == 0x63c || reg == 0x63e || |
1050 | reg == 0x640 || reg == 0x642 || | 1060 | reg == 0x640 || reg == 0x642 || |
1051 | reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 || | 1061 | reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 || |
1052 | reg == 0x7b; | 1062 | reg == 0x7b || reg == 0x7d; |
1053 | } | 1063 | } |
1054 | return false; | 1064 | return false; |
1055 | } | 1065 | } |
@@ -1391,6 +1401,7 @@ static void nct6775_update_pwm_limits(struct device *dev) | |||
1391 | case nct6106: | 1401 | case nct6106: |
1392 | case nct6779: | 1402 | case nct6779: |
1393 | case nct6791: | 1403 | case nct6791: |
1404 | case nct6792: | ||
1394 | reg = nct6775_read_value(data, | 1405 | reg = nct6775_read_value(data, |
1395 | data->REG_CRITICAL_PWM_ENABLE[i]); | 1406 | data->REG_CRITICAL_PWM_ENABLE[i]); |
1396 | if (reg & data->CRITICAL_PWM_ENABLE_MASK) | 1407 | if (reg & data->CRITICAL_PWM_ENABLE_MASK) |
@@ -2790,6 +2801,7 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr, | |||
2790 | case nct6106: | 2801 | case nct6106: |
2791 | case nct6779: | 2802 | case nct6779: |
2792 | case nct6791: | 2803 | case nct6791: |
2804 | case nct6792: | ||
2793 | nct6775_write_value(data, data->REG_CRITICAL_PWM[nr], | 2805 | nct6775_write_value(data, data->REG_CRITICAL_PWM[nr], |
2794 | val); | 2806 | val); |
2795 | reg = nct6775_read_value(data, | 2807 | reg = nct6775_read_value(data, |
@@ -3202,7 +3214,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data) | |||
3202 | pwm4pin = false; | 3214 | pwm4pin = false; |
3203 | pwm5pin = false; | 3215 | pwm5pin = false; |
3204 | pwm6pin = false; | 3216 | pwm6pin = false; |
3205 | } else { /* NCT6779D or NCT6791D */ | 3217 | } else { /* NCT6779D, NCT6791D, or NCT6792D */ |
3206 | regval = superio_inb(sioreg, 0x1c); | 3218 | regval = superio_inb(sioreg, 0x1c); |
3207 | 3219 | ||
3208 | fan3pin = !(regval & (1 << 5)); | 3220 | fan3pin = !(regval & (1 << 5)); |
@@ -3215,7 +3227,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data) | |||
3215 | 3227 | ||
3216 | fan4min = fan4pin; | 3228 | fan4min = fan4pin; |
3217 | 3229 | ||
3218 | if (data->kind == nct6791) { | 3230 | if (data->kind == nct6791 || data->kind == nct6792) { |
3219 | regval = superio_inb(sioreg, 0x2d); | 3231 | regval = superio_inb(sioreg, 0x2d); |
3220 | fan6pin = (regval & (1 << 1)); | 3232 | fan6pin = (regval & (1 << 1)); |
3221 | pwm6pin = (regval & (1 << 0)); | 3233 | pwm6pin = (regval & (1 << 0)); |
@@ -3588,6 +3600,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3588 | 3600 | ||
3589 | break; | 3601 | break; |
3590 | case nct6791: | 3602 | case nct6791: |
3603 | case nct6792: | ||
3591 | data->in_num = 15; | 3604 | data->in_num = 15; |
3592 | data->pwm_num = 6; | 3605 | data->pwm_num = 6; |
3593 | data->auto_pwm_num = 4; | 3606 | data->auto_pwm_num = 4; |
@@ -3650,12 +3663,20 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3650 | data->REG_WEIGHT_TEMP[1] = NCT6791_REG_WEIGHT_TEMP_STEP_TOL; | 3663 | data->REG_WEIGHT_TEMP[1] = NCT6791_REG_WEIGHT_TEMP_STEP_TOL; |
3651 | data->REG_WEIGHT_TEMP[2] = NCT6791_REG_WEIGHT_TEMP_BASE; | 3664 | data->REG_WEIGHT_TEMP[2] = NCT6791_REG_WEIGHT_TEMP_BASE; |
3652 | data->REG_ALARM = NCT6791_REG_ALARM; | 3665 | data->REG_ALARM = NCT6791_REG_ALARM; |
3653 | data->REG_BEEP = NCT6776_REG_BEEP; | 3666 | if (data->kind == nct6791) |
3667 | data->REG_BEEP = NCT6776_REG_BEEP; | ||
3668 | else | ||
3669 | data->REG_BEEP = NCT6792_REG_BEEP; | ||
3654 | 3670 | ||
3655 | reg_temp = NCT6779_REG_TEMP; | 3671 | reg_temp = NCT6779_REG_TEMP; |
3656 | reg_temp_mon = NCT6779_REG_TEMP_MON; | ||
3657 | num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); | 3672 | num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); |
3658 | num_reg_temp_mon = ARRAY_SIZE(NCT6779_REG_TEMP_MON); | 3673 | if (data->kind == nct6791) { |
3674 | reg_temp_mon = NCT6779_REG_TEMP_MON; | ||
3675 | num_reg_temp_mon = ARRAY_SIZE(NCT6779_REG_TEMP_MON); | ||
3676 | } else { | ||
3677 | reg_temp_mon = NCT6792_REG_TEMP_MON; | ||
3678 | num_reg_temp_mon = ARRAY_SIZE(NCT6792_REG_TEMP_MON); | ||
3679 | } | ||
3659 | reg_temp_over = NCT6779_REG_TEMP_OVER; | 3680 | reg_temp_over = NCT6779_REG_TEMP_OVER; |
3660 | reg_temp_hyst = NCT6779_REG_TEMP_HYST; | 3681 | reg_temp_hyst = NCT6779_REG_TEMP_HYST; |
3661 | reg_temp_config = NCT6779_REG_TEMP_CONFIG; | 3682 | reg_temp_config = NCT6779_REG_TEMP_CONFIG; |
@@ -3854,6 +3875,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3854 | case nct6106: | 3875 | case nct6106: |
3855 | case nct6779: | 3876 | case nct6779: |
3856 | case nct6791: | 3877 | case nct6791: |
3878 | case nct6792: | ||
3857 | break; | 3879 | break; |
3858 | } | 3880 | } |
3859 | 3881 | ||
@@ -3885,6 +3907,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3885 | tmp |= 0x3e; | 3907 | tmp |= 0x3e; |
3886 | break; | 3908 | break; |
3887 | case nct6791: | 3909 | case nct6791: |
3910 | case nct6792: | ||
3888 | tmp |= 0x7e; | 3911 | tmp |= 0x7e; |
3889 | break; | 3912 | break; |
3890 | } | 3913 | } |
@@ -3972,7 +3995,7 @@ static int nct6775_resume(struct device *dev) | |||
3972 | mutex_lock(&data->update_lock); | 3995 | mutex_lock(&data->update_lock); |
3973 | data->bank = 0xff; /* Force initial bank selection */ | 3996 | data->bank = 0xff; /* Force initial bank selection */ |
3974 | 3997 | ||
3975 | if (data->kind == nct6791) { | 3998 | if (data->kind == nct6791 || data->kind == nct6792) { |
3976 | err = superio_enter(data->sioreg); | 3999 | err = superio_enter(data->sioreg); |
3977 | if (err) | 4000 | if (err) |
3978 | goto abort; | 4001 | goto abort; |
@@ -4052,6 +4075,7 @@ static const char * const nct6775_sio_names[] __initconst = { | |||
4052 | "NCT6776D/F", | 4075 | "NCT6776D/F", |
4053 | "NCT6779D", | 4076 | "NCT6779D", |
4054 | "NCT6791D", | 4077 | "NCT6791D", |
4078 | "NCT6792D", | ||
4055 | }; | 4079 | }; |
4056 | 4080 | ||
4057 | /* nct6775_find() looks for a '627 in the Super-I/O config space */ | 4081 | /* nct6775_find() looks for a '627 in the Super-I/O config space */ |
@@ -4086,6 +4110,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data) | |||
4086 | case SIO_NCT6791_ID: | 4110 | case SIO_NCT6791_ID: |
4087 | sio_data->kind = nct6791; | 4111 | sio_data->kind = nct6791; |
4088 | break; | 4112 | break; |
4113 | case SIO_NCT6792_ID: | ||
4114 | sio_data->kind = nct6792; | ||
4115 | break; | ||
4089 | default: | 4116 | default: |
4090 | if (val != 0xffff) | 4117 | if (val != 0xffff) |
4091 | pr_debug("unsupported chip ID: 0x%04x\n", val); | 4118 | pr_debug("unsupported chip ID: 0x%04x\n", val); |
@@ -4111,7 +4138,7 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data) | |||
4111 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); | 4138 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); |
4112 | } | 4139 | } |
4113 | 4140 | ||
4114 | if (sio_data->kind == nct6791) | 4141 | if (sio_data->kind == nct6791 || sio_data->kind == nct6792) |
4115 | nct6791_enable_io_mapping(sioaddr); | 4142 | nct6791_enable_io_mapping(sioaddr); |
4116 | 4143 | ||
4117 | superio_exit(sioaddr); | 4144 | superio_exit(sioaddr); |
@@ -4221,7 +4248,7 @@ static void __exit sensors_nct6775_exit(void) | |||
4221 | } | 4248 | } |
4222 | 4249 | ||
4223 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); | 4250 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); |
4224 | MODULE_DESCRIPTION("NCT6106D/NCT6775F/NCT6776F/NCT6779D/NCT6791D driver"); | 4251 | MODULE_DESCRIPTION("NCT6106D/NCT6775F/NCT6776F/NCT6779D/NCT6791D/NCT6792D driver"); |
4225 | MODULE_LICENSE("GPL"); | 4252 | MODULE_LICENSE("GPL"); |
4226 | 4253 | ||
4227 | module_init(sensors_nct6775_init); | 4254 | module_init(sensors_nct6775_init); |