diff options
Diffstat (limited to 'drivers/hwmon')
66 files changed, 7432 insertions, 1700 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index effbd11ff5ec..f61d98a62967 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -179,9 +179,29 @@ config SENSORS_ADM9240 | |||
179 | This driver can also be built as a module. If so, the module | 179 | This driver can also be built as a module. If so, the module |
180 | will be called adm9240. | 180 | will be called adm9240. |
181 | 181 | ||
182 | config SENSORS_ADT7X10 | ||
183 | tristate | ||
184 | help | ||
185 | This module contains common code shared by the ADT7310/ADT7320 and | ||
186 | ADT7410/ADT7420 temperature monitoring chip drivers. | ||
187 | |||
188 | If build as a module, the module will be called adt7x10. | ||
189 | |||
190 | config SENSORS_ADT7310 | ||
191 | tristate "Analog Devices ADT7310/ADT7320" | ||
192 | depends on SPI_MASTER | ||
193 | select SENSORS_ADT7X10 | ||
194 | help | ||
195 | If you say yes here you get support for the Analog Devices | ||
196 | ADT7310 and ADT7320 temperature monitoring chips. | ||
197 | |||
198 | This driver can also be built as a module. If so, the module | ||
199 | will be called adt7310. | ||
200 | |||
182 | config SENSORS_ADT7410 | 201 | config SENSORS_ADT7410 |
183 | tristate "Analog Devices ADT7410/ADT7420" | 202 | tristate "Analog Devices ADT7410/ADT7420" |
184 | depends on I2C | 203 | depends on I2C |
204 | select SENSORS_ADT7X10 | ||
185 | help | 205 | help |
186 | If you say yes here you get support for the Analog Devices | 206 | If you say yes here you get support for the Analog Devices |
187 | ADT7410 and ADT7420 temperature monitoring chips. | 207 | ADT7410 and ADT7420 temperature monitoring chips. |
@@ -760,6 +780,16 @@ config SENSORS_LTC4261 | |||
760 | This driver can also be built as a module. If so, the module will | 780 | This driver can also be built as a module. If so, the module will |
761 | be called ltc4261. | 781 | be called ltc4261. |
762 | 782 | ||
783 | config SENSORS_LM95234 | ||
784 | tristate "National Semiconductor LM95234" | ||
785 | depends on I2C | ||
786 | help | ||
787 | If you say yes here you get support for the LM95234 temperature | ||
788 | sensor. | ||
789 | |||
790 | This driver can also be built as a module. If so, the module | ||
791 | will be called lm95234. | ||
792 | |||
763 | config SENSORS_LM95241 | 793 | config SENSORS_LM95241 |
764 | tristate "National Semiconductor LM95241 and compatibles" | 794 | tristate "National Semiconductor LM95241 and compatibles" |
765 | depends on I2C | 795 | depends on I2C |
@@ -886,8 +916,22 @@ config SENSORS_MCP3021 | |||
886 | This driver can also be built as a module. If so, the module | 916 | This driver can also be built as a module. If so, the module |
887 | will be called mcp3021. | 917 | will be called mcp3021. |
888 | 918 | ||
919 | config SENSORS_NCT6775 | ||
920 | tristate "Nuvoton NCT6775F and compatibles" | ||
921 | depends on !PPC | ||
922 | select HWMON_VID | ||
923 | help | ||
924 | If you say yes here you get support for the hardware monitoring | ||
925 | functionality of the Nuvoton NCT6775F, NCT6776F, NCT6779D | ||
926 | and compatible Super-I/O chips. This driver replaces the | ||
927 | w83627ehf driver for NCT6775F and NCT6776F. | ||
928 | |||
929 | This driver can also be built as a module. If so, the module | ||
930 | will be called nct6775. | ||
931 | |||
889 | config SENSORS_NTC_THERMISTOR | 932 | config SENSORS_NTC_THERMISTOR |
890 | tristate "NTC thermistor support" | 933 | tristate "NTC thermistor support" |
934 | depends on (!OF && !IIO) || (OF && IIO) | ||
891 | help | 935 | help |
892 | This driver supports NTC thermistors sensor reading and its | 936 | This driver supports NTC thermistors sensor reading and its |
893 | interpretation. The driver can also monitor the temperature and | 937 | interpretation. The driver can also monitor the temperature and |
@@ -1213,8 +1257,8 @@ config SENSORS_TMP401 | |||
1213 | tristate "Texas Instruments TMP401 and compatibles" | 1257 | tristate "Texas Instruments TMP401 and compatibles" |
1214 | depends on I2C | 1258 | depends on I2C |
1215 | help | 1259 | help |
1216 | If you say yes here you get support for Texas Instruments TMP401 and | 1260 | If you say yes here you get support for Texas Instruments TMP401, |
1217 | TMP411 temperature sensor chips. | 1261 | TMP411, TMP431, and TMP432 temperature sensor chips. |
1218 | 1262 | ||
1219 | This driver can also be built as a module. If so, the module | 1263 | This driver can also be built as a module. If so, the module |
1220 | will be called tmp401. | 1264 | will be called tmp401. |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index a87fdabddfff..c51b0dc35dc8 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -34,6 +34,8 @@ obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o | |||
34 | obj-$(CONFIG_SENSORS_ADS1015) += ads1015.o | 34 | obj-$(CONFIG_SENSORS_ADS1015) += ads1015.o |
35 | obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o | 35 | obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o |
36 | obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o | 36 | obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o |
37 | obj-$(CONFIG_SENSORS_ADT7X10) += adt7x10.o | ||
38 | obj-$(CONFIG_SENSORS_ADT7310) += adt7310.o | ||
37 | obj-$(CONFIG_SENSORS_ADT7410) += adt7410.o | 39 | obj-$(CONFIG_SENSORS_ADT7410) += adt7410.o |
38 | obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o | 40 | obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o |
39 | obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o | 41 | obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o |
@@ -87,6 +89,7 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o | |||
87 | obj-$(CONFIG_SENSORS_LM90) += lm90.o | 89 | obj-$(CONFIG_SENSORS_LM90) += lm90.o |
88 | obj-$(CONFIG_SENSORS_LM92) += lm92.o | 90 | obj-$(CONFIG_SENSORS_LM92) += lm92.o |
89 | obj-$(CONFIG_SENSORS_LM93) += lm93.o | 91 | obj-$(CONFIG_SENSORS_LM93) += lm93.o |
92 | obj-$(CONFIG_SENSORS_LM95234) += lm95234.o | ||
90 | obj-$(CONFIG_SENSORS_LM95241) += lm95241.o | 93 | obj-$(CONFIG_SENSORS_LM95241) += lm95241.o |
91 | obj-$(CONFIG_SENSORS_LM95245) += lm95245.o | 94 | obj-$(CONFIG_SENSORS_LM95245) += lm95245.o |
92 | obj-$(CONFIG_SENSORS_LTC4151) += ltc4151.o | 95 | obj-$(CONFIG_SENSORS_LTC4151) += ltc4151.o |
@@ -104,6 +107,7 @@ obj-$(CONFIG_SENSORS_MAX6650) += max6650.o | |||
104 | obj-$(CONFIG_SENSORS_MAX6697) += max6697.o | 107 | obj-$(CONFIG_SENSORS_MAX6697) += max6697.o |
105 | obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o | 108 | obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o |
106 | obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o | 109 | obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o |
110 | obj-$(CONFIG_SENSORS_NCT6775) += nct6775.o | ||
107 | obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o | 111 | obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o |
108 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | 112 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o |
109 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o | 113 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o |
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 6119ff8e8c87..df0b69987914 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c | |||
@@ -96,9 +96,12 @@ | |||
96 | #define ABIT_UGURU_MAX_TIMEOUTS 2 | 96 | #define ABIT_UGURU_MAX_TIMEOUTS 2 |
97 | /* utility macros */ | 97 | /* utility macros */ |
98 | #define ABIT_UGURU_NAME "abituguru" | 98 | #define ABIT_UGURU_NAME "abituguru" |
99 | #define ABIT_UGURU_DEBUG(level, format, arg...) \ | 99 | #define ABIT_UGURU_DEBUG(level, format, arg...) \ |
100 | if (level <= verbose) \ | 100 | do { \ |
101 | printk(KERN_DEBUG ABIT_UGURU_NAME ": " format , ## arg) | 101 | if (level <= verbose) \ |
102 | pr_debug(format , ## arg); \ | ||
103 | } while (0) | ||
104 | |||
102 | /* Macros to help calculate the sysfs_names array length */ | 105 | /* Macros to help calculate the sysfs_names array length */ |
103 | /* | 106 | /* |
104 | * sum of strlen of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, | 107 | * sum of strlen of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, |
@@ -1533,7 +1536,7 @@ static int abituguru_resume(struct device *dev) | |||
1533 | } | 1536 | } |
1534 | 1537 | ||
1535 | static SIMPLE_DEV_PM_OPS(abituguru_pm, abituguru_suspend, abituguru_resume); | 1538 | static SIMPLE_DEV_PM_OPS(abituguru_pm, abituguru_suspend, abituguru_resume); |
1536 | #define ABIT_UGURU_PM &abituguru_pm | 1539 | #define ABIT_UGURU_PM (&abituguru_pm) |
1537 | #else | 1540 | #else |
1538 | #define ABIT_UGURU_PM NULL | 1541 | #define ABIT_UGURU_PM NULL |
1539 | #endif /* CONFIG_PM */ | 1542 | #endif /* CONFIG_PM */ |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 205327d33c4d..1d2da31c27c6 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c | |||
@@ -76,9 +76,11 @@ | |||
76 | #define ABIT_UGURU3_SYNCHRONIZE_TIMEOUT 5 | 76 | #define ABIT_UGURU3_SYNCHRONIZE_TIMEOUT 5 |
77 | /* utility macros */ | 77 | /* utility macros */ |
78 | #define ABIT_UGURU3_NAME "abituguru3" | 78 | #define ABIT_UGURU3_NAME "abituguru3" |
79 | #define ABIT_UGURU3_DEBUG(format, arg...) \ | 79 | #define ABIT_UGURU3_DEBUG(format, arg...) \ |
80 | if (verbose) \ | 80 | do { \ |
81 | printk(KERN_DEBUG ABIT_UGURU3_NAME ": " format , ## arg) | 81 | if (verbose) \ |
82 | pr_debug(format , ## arg); \ | ||
83 | } while (0) | ||
82 | 84 | ||
83 | /* Macros to help calculate the sysfs_names array length */ | 85 | /* Macros to help calculate the sysfs_names array length */ |
84 | #define ABIT_UGURU3_MAX_NO_SENSORS 26 | 86 | #define ABIT_UGURU3_MAX_NO_SENSORS 26 |
@@ -1159,7 +1161,7 @@ static int abituguru3_resume(struct device *dev) | |||
1159 | } | 1161 | } |
1160 | 1162 | ||
1161 | static SIMPLE_DEV_PM_OPS(abituguru3_pm, abituguru3_suspend, abituguru3_resume); | 1163 | static SIMPLE_DEV_PM_OPS(abituguru3_pm, abituguru3_suspend, abituguru3_resume); |
1162 | #define ABIT_UGURU3_PM &abituguru3_pm | 1164 | #define ABIT_UGURU3_PM (&abituguru3_pm) |
1163 | #else | 1165 | #else |
1164 | #define ABIT_UGURU3_PM NULL | 1166 | #define ABIT_UGURU3_PM NULL |
1165 | #endif /* CONFIG_PM */ | 1167 | #endif /* CONFIG_PM */ |
diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index a57584d28a40..f4f9b219bf16 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c | |||
@@ -116,7 +116,7 @@ static int ad7314_probe(struct spi_device *spi_dev) | |||
116 | if (chip == NULL) | 116 | if (chip == NULL) |
117 | return -ENOMEM; | 117 | return -ENOMEM; |
118 | 118 | ||
119 | dev_set_drvdata(&spi_dev->dev, chip); | 119 | spi_set_drvdata(spi_dev, chip); |
120 | 120 | ||
121 | ret = sysfs_create_group(&spi_dev->dev.kobj, &ad7314_group); | 121 | ret = sysfs_create_group(&spi_dev->dev.kobj, &ad7314_group); |
122 | if (ret < 0) | 122 | if (ret < 0) |
@@ -137,7 +137,7 @@ error_remove_group: | |||
137 | 137 | ||
138 | static int ad7314_remove(struct spi_device *spi_dev) | 138 | static int ad7314_remove(struct spi_device *spi_dev) |
139 | { | 139 | { |
140 | struct ad7314_data *chip = dev_get_drvdata(&spi_dev->dev); | 140 | struct ad7314_data *chip = spi_get_drvdata(spi_dev); |
141 | 141 | ||
142 | hwmon_device_unregister(chip->hwmon_dev); | 142 | hwmon_device_unregister(chip->hwmon_dev); |
143 | sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group); | 143 | sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group); |
@@ -166,6 +166,5 @@ static struct spi_driver ad7314_driver = { | |||
166 | module_spi_driver(ad7314_driver); | 166 | module_spi_driver(ad7314_driver); |
167 | 167 | ||
168 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | 168 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); |
169 | MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital" | 169 | MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital temperature sensor driver"); |
170 | " temperature sensor driver"); | ||
171 | MODULE_LICENSE("GPL v2"); | 170 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 71bcba8abfc0..7e76922a4ba9 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c | |||
@@ -312,8 +312,7 @@ static int adm1021_detect(struct i2c_client *client, | |||
312 | int conv_rate, status, config, man_id, dev_id; | 312 | int conv_rate, status, config, man_id, dev_id; |
313 | 313 | ||
314 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 314 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
315 | pr_debug("adm1021: detect failed, " | 315 | pr_debug("detect failed, smbus byte data not supported!\n"); |
316 | "smbus byte data not supported!\n"); | ||
317 | return -ENODEV; | 316 | return -ENODEV; |
318 | } | 317 | } |
319 | 318 | ||
@@ -324,7 +323,7 @@ static int adm1021_detect(struct i2c_client *client, | |||
324 | 323 | ||
325 | /* Check unused bits */ | 324 | /* Check unused bits */ |
326 | if ((status & 0x03) || (config & 0x3F) || (conv_rate & 0xF8)) { | 325 | if ((status & 0x03) || (config & 0x3F) || (conv_rate & 0xF8)) { |
327 | pr_debug("adm1021: detect failed, chip not detected!\n"); | 326 | pr_debug("detect failed, chip not detected!\n"); |
328 | return -ENODEV; | 327 | return -ENODEV; |
329 | } | 328 | } |
330 | 329 | ||
@@ -353,7 +352,7 @@ static int adm1021_detect(struct i2c_client *client, | |||
353 | else | 352 | else |
354 | type_name = "max1617"; | 353 | type_name = "max1617"; |
355 | 354 | ||
356 | pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n", | 355 | pr_debug("Detected chip %s at adapter %d, address 0x%02x.\n", |
357 | type_name, i2c_adapter_id(adapter), client->addr); | 356 | type_name, i2c_adapter_id(adapter), client->addr); |
358 | strlcpy(info->type, type_name, I2C_NAME_SIZE); | 357 | strlcpy(info->type, type_name, I2C_NAME_SIZE); |
359 | 358 | ||
@@ -368,10 +367,8 @@ static int adm1021_probe(struct i2c_client *client, | |||
368 | 367 | ||
369 | data = devm_kzalloc(&client->dev, sizeof(struct adm1021_data), | 368 | data = devm_kzalloc(&client->dev, sizeof(struct adm1021_data), |
370 | GFP_KERNEL); | 369 | GFP_KERNEL); |
371 | if (!data) { | 370 | if (!data) |
372 | pr_debug("adm1021: detect failed, devm_kzalloc failed!\n"); | ||
373 | return -ENOMEM; | 371 | return -ENOMEM; |
374 | } | ||
375 | 372 | ||
376 | i2c_set_clientdata(client, data); | 373 | i2c_set_clientdata(client, data); |
377 | data->type = id->driver_data; | 374 | data->type = id->driver_data; |
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index ea09046e651d..3a6d9ef1c16c 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -49,14 +49,14 @@ static int gpio_fan[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; | |||
49 | module_param_array(gpio_input, int, NULL, 0); | 49 | module_param_array(gpio_input, int, NULL, 0); |
50 | MODULE_PARM_DESC(gpio_input, "List of GPIO pins (0-16) to program as inputs"); | 50 | MODULE_PARM_DESC(gpio_input, "List of GPIO pins (0-16) to program as inputs"); |
51 | module_param_array(gpio_output, int, NULL, 0); | 51 | module_param_array(gpio_output, int, NULL, 0); |
52 | MODULE_PARM_DESC(gpio_output, "List of GPIO pins (0-16) to program as " | 52 | MODULE_PARM_DESC(gpio_output, |
53 | "outputs"); | 53 | "List of GPIO pins (0-16) to program as outputs"); |
54 | module_param_array(gpio_inverted, int, NULL, 0); | 54 | module_param_array(gpio_inverted, int, NULL, 0); |
55 | MODULE_PARM_DESC(gpio_inverted, "List of GPIO pins (0-16) to program as " | 55 | MODULE_PARM_DESC(gpio_inverted, |
56 | "inverted"); | 56 | "List of GPIO pins (0-16) to program as inverted"); |
57 | module_param_array(gpio_normal, int, NULL, 0); | 57 | module_param_array(gpio_normal, int, NULL, 0); |
58 | MODULE_PARM_DESC(gpio_normal, "List of GPIO pins (0-16) to program as " | 58 | MODULE_PARM_DESC(gpio_normal, |
59 | "normal/non-inverted"); | 59 | "List of GPIO pins (0-16) to program as normal/non-inverted"); |
60 | module_param_array(gpio_fan, int, NULL, 0); | 60 | module_param_array(gpio_fan, int, NULL, 0); |
61 | MODULE_PARM_DESC(gpio_fan, "List of GPIO pins (0-7) to program as fan tachs"); | 61 | MODULE_PARM_DESC(gpio_fan, "List of GPIO pins (0-7) to program as fan tachs"); |
62 | 62 | ||
@@ -372,31 +372,31 @@ static void adm1026_init_client(struct i2c_client *client) | |||
372 | dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n", | 372 | dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n", |
373 | data->config1); | 373 | data->config1); |
374 | if ((data->config1 & CFG1_MONITOR) == 0) { | 374 | if ((data->config1 & CFG1_MONITOR) == 0) { |
375 | dev_dbg(&client->dev, "Monitoring not currently " | 375 | dev_dbg(&client->dev, |
376 | "enabled.\n"); | 376 | "Monitoring not currently enabled.\n"); |
377 | } | 377 | } |
378 | if (data->config1 & CFG1_INT_ENABLE) { | 378 | if (data->config1 & CFG1_INT_ENABLE) { |
379 | dev_dbg(&client->dev, "SMBALERT interrupts are " | 379 | dev_dbg(&client->dev, |
380 | "enabled.\n"); | 380 | "SMBALERT interrupts are enabled.\n"); |
381 | } | 381 | } |
382 | if (data->config1 & CFG1_AIN8_9) { | 382 | if (data->config1 & CFG1_AIN8_9) { |
383 | dev_dbg(&client->dev, "in8 and in9 enabled. " | 383 | dev_dbg(&client->dev, |
384 | "temp3 disabled.\n"); | 384 | "in8 and in9 enabled. temp3 disabled.\n"); |
385 | } else { | 385 | } else { |
386 | dev_dbg(&client->dev, "temp3 enabled. in8 and " | 386 | dev_dbg(&client->dev, |
387 | "in9 disabled.\n"); | 387 | "temp3 enabled. in8 and in9 disabled.\n"); |
388 | } | 388 | } |
389 | if (data->config1 & CFG1_THERM_HOT) { | 389 | if (data->config1 & CFG1_THERM_HOT) { |
390 | dev_dbg(&client->dev, "Automatic THERM, PWM, " | 390 | dev_dbg(&client->dev, |
391 | "and temp limits enabled.\n"); | 391 | "Automatic THERM, PWM, and temp limits enabled.\n"); |
392 | } | 392 | } |
393 | 393 | ||
394 | if (data->config3 & CFG3_GPIO16_ENABLE) { | 394 | if (data->config3 & CFG3_GPIO16_ENABLE) { |
395 | dev_dbg(&client->dev, "GPIO16 enabled. THERM " | 395 | dev_dbg(&client->dev, |
396 | "pin disabled.\n"); | 396 | "GPIO16 enabled. THERM pin disabled.\n"); |
397 | } else { | 397 | } else { |
398 | dev_dbg(&client->dev, "THERM pin enabled. " | 398 | dev_dbg(&client->dev, |
399 | "GPIO16 disabled.\n"); | 399 | "THERM pin enabled. GPIO16 disabled.\n"); |
400 | } | 400 | } |
401 | if (data->config3 & CFG3_VREF_250) | 401 | if (data->config3 & CFG3_VREF_250) |
402 | dev_dbg(&client->dev, "Vref is 2.50 Volts.\n"); | 402 | dev_dbg(&client->dev, "Vref is 2.50 Volts.\n"); |
@@ -1798,8 +1798,8 @@ static int adm1026_detect(struct i2c_client *client, | |||
1798 | company = adm1026_read_value(client, ADM1026_REG_COMPANY); | 1798 | company = adm1026_read_value(client, ADM1026_REG_COMPANY); |
1799 | verstep = adm1026_read_value(client, ADM1026_REG_VERSTEP); | 1799 | verstep = adm1026_read_value(client, ADM1026_REG_VERSTEP); |
1800 | 1800 | ||
1801 | dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with" | 1801 | dev_dbg(&adapter->dev, |
1802 | " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", | 1802 | "Detecting device at %d,0x%02x with COMPANY: 0x%02x and VERSTEP: 0x%02x\n", |
1803 | i2c_adapter_id(client->adapter), client->addr, | 1803 | i2c_adapter_id(client->adapter), client->addr, |
1804 | company, verstep); | 1804 | company, verstep); |
1805 | 1805 | ||
@@ -1811,11 +1811,12 @@ static int adm1026_detect(struct i2c_client *client, | |||
1811 | /* Analog Devices ADM1026 */ | 1811 | /* Analog Devices ADM1026 */ |
1812 | } else if (company == ADM1026_COMPANY_ANALOG_DEV | 1812 | } else if (company == ADM1026_COMPANY_ANALOG_DEV |
1813 | && (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) { | 1813 | && (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) { |
1814 | dev_err(&adapter->dev, "Unrecognized stepping " | 1814 | dev_err(&adapter->dev, |
1815 | "0x%02x. Defaulting to ADM1026.\n", verstep); | 1815 | "Unrecognized stepping 0x%02x. Defaulting to ADM1026.\n", |
1816 | verstep); | ||
1816 | } else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) { | 1817 | } else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) { |
1817 | dev_err(&adapter->dev, "Found version/stepping " | 1818 | dev_err(&adapter->dev, |
1818 | "0x%02x. Assuming generic ADM1026.\n", | 1819 | "Found version/stepping 0x%02x. Assuming generic ADM1026.\n", |
1819 | verstep); | 1820 | verstep); |
1820 | } else { | 1821 | } else { |
1821 | dev_dbg(&adapter->dev, "Autodetection failed\n"); | 1822 | dev_dbg(&adapter->dev, "Autodetection failed\n"); |
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 97f4718382f6..9ee5e066423b 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c | |||
@@ -224,8 +224,9 @@ static ssize_t set_fan_div(struct device *dev, | |||
224 | break; | 224 | break; |
225 | default: | 225 | default: |
226 | mutex_unlock(&data->update_lock); | 226 | mutex_unlock(&data->update_lock); |
227 | dev_err(&client->dev, "fan_div value %ld not " | 227 | dev_err(&client->dev, |
228 | "supported. Choose one of 1, 2 or 4!\n", val); | 228 | "fan_div value %ld not supported. Choose one of 1, 2 or 4!\n", |
229 | val); | ||
229 | return -EINVAL; | 230 | return -EINVAL; |
230 | } | 231 | } |
231 | /* Update the value */ | 232 | /* Update the value */ |
@@ -326,8 +327,8 @@ static int adm1029_detect(struct i2c_client *client, | |||
326 | * There are no "official" CHIP ID, so actually | 327 | * There are no "official" CHIP ID, so actually |
327 | * we use Major/Minor revision for that | 328 | * we use Major/Minor revision for that |
328 | */ | 329 | */ |
329 | pr_info("adm1029: Unknown major revision %x, " | 330 | pr_info("Unknown major revision %x, please let us know\n", |
330 | "please let us know\n", chip_id); | 331 | chip_id); |
331 | return -ENODEV; | 332 | return -ENODEV; |
332 | } | 333 | } |
333 | 334 | ||
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 2416628e0ab1..086d02a9ecdc 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -351,8 +351,9 @@ static void adm9240_write_fan_div(struct i2c_client *client, int nr, | |||
351 | reg &= ~(3 << shift); | 351 | reg &= ~(3 << shift); |
352 | reg |= (fan_div << shift); | 352 | reg |= (fan_div << shift); |
353 | i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg); | 353 | i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg); |
354 | dev_dbg(&client->dev, "fan%d clock divider changed from %u " | 354 | dev_dbg(&client->dev, |
355 | "to %u\n", nr + 1, 1 << old, 1 << fan_div); | 355 | "fan%d clock divider changed from %u to %u\n", |
356 | nr + 1, 1 << old, 1 << fan_div); | ||
356 | } | 357 | } |
357 | 358 | ||
358 | /* | 359 | /* |
@@ -699,8 +700,8 @@ static void adm9240_init_client(struct i2c_client *client) | |||
699 | /* start measurement cycle */ | 700 | /* start measurement cycle */ |
700 | i2c_smbus_write_byte_data(client, ADM9240_REG_CONFIG, 1); | 701 | i2c_smbus_write_byte_data(client, ADM9240_REG_CONFIG, 1); |
701 | 702 | ||
702 | dev_info(&client->dev, "cold start: config was 0x%02x " | 703 | dev_info(&client->dev, |
703 | "mode %u\n", conf, mode); | 704 | "cold start: config was 0x%02x mode %u\n", conf, mode); |
704 | } | 705 | } |
705 | } | 706 | } |
706 | 707 | ||
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index a79875986f91..3eff73b6220d 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c | |||
@@ -40,25 +40,25 @@ | |||
40 | * the instruction byte | 40 | * the instruction byte |
41 | */ | 41 | */ |
42 | /*Instruction Bit masks*/ | 42 | /*Instruction Bit masks*/ |
43 | #define INST_MODE_bm (1<<7) | 43 | #define INST_MODE_BM (1 << 7) |
44 | #define INST_READ_bm (1<<6) | 44 | #define INST_READ_BM (1 << 6) |
45 | #define INST_16BIT_bm (1<<5) | 45 | #define INST_16BIT_BM (1 << 5) |
46 | 46 | ||
47 | /*From figure 18 in the datasheet*/ | 47 | /*From figure 18 in the datasheet*/ |
48 | /*bit masks for Rev/Oscillator Control Register*/ | 48 | /*bit masks for Rev/Oscillator Control Register*/ |
49 | #define MUX_CNV_bv 7 | 49 | #define MUX_CNV_BV 7 |
50 | #define MUX_CNV_bm (1<<MUX_CNV_bv) | 50 | #define MUX_CNV_BM (1 << MUX_CNV_BV) |
51 | #define MUX_M3_bm (1<<3) /*M3 selects single ended*/ | 51 | #define MUX_M3_BM (1 << 3) /*M3 selects single ended*/ |
52 | #define MUX_G_bv 4 /*allows for reg = (gain << MUX_G_bv) | ...*/ | 52 | #define MUX_G_BV 4 /*allows for reg = (gain << MUX_G_BV) | ...*/ |
53 | 53 | ||
54 | /*From figure 18 in the datasheet*/ | 54 | /*From figure 18 in the datasheet*/ |
55 | /*bit masks for Rev/Oscillator Control Register*/ | 55 | /*bit masks for Rev/Oscillator Control Register*/ |
56 | #define OSC_OSCR_bm (1<<5) | 56 | #define OSC_OSCR_BM (1 << 5) |
57 | #define OSC_OSCE_bm (1<<4) | 57 | #define OSC_OSCE_BM (1 << 4) |
58 | #define OSC_REFE_bm (1<<3) | 58 | #define OSC_REFE_BM (1 << 3) |
59 | #define OSC_BUFE_bm (1<<2) | 59 | #define OSC_BUFE_BM (1 << 2) |
60 | #define OSC_R2V_bm (1<<1) | 60 | #define OSC_R2V_BM (1 << 1) |
61 | #define OSC_RBG_bm (1<<0) | 61 | #define OSC_RBG_BM (1 << 0) |
62 | 62 | ||
63 | #include <linux/module.h> | 63 | #include <linux/module.h> |
64 | #include <linux/init.h> | 64 | #include <linux/init.h> |
@@ -79,7 +79,7 @@ struct ads7871_data { | |||
79 | static int ads7871_read_reg8(struct spi_device *spi, int reg) | 79 | static int ads7871_read_reg8(struct spi_device *spi, int reg) |
80 | { | 80 | { |
81 | int ret; | 81 | int ret; |
82 | reg = reg | INST_READ_bm; | 82 | reg = reg | INST_READ_BM; |
83 | ret = spi_w8r8(spi, reg); | 83 | ret = spi_w8r8(spi, reg); |
84 | return ret; | 84 | return ret; |
85 | } | 85 | } |
@@ -87,7 +87,7 @@ static int ads7871_read_reg8(struct spi_device *spi, int reg) | |||
87 | static int ads7871_read_reg16(struct spi_device *spi, int reg) | 87 | static int ads7871_read_reg16(struct spi_device *spi, int reg) |
88 | { | 88 | { |
89 | int ret; | 89 | int ret; |
90 | reg = reg | INST_READ_bm | INST_16BIT_bm; | 90 | reg = reg | INST_READ_BM | INST_16BIT_BM; |
91 | ret = spi_w8r16(spi, reg); | 91 | ret = spi_w8r16(spi, reg); |
92 | return ret; | 92 | return ret; |
93 | } | 93 | } |
@@ -111,13 +111,13 @@ static ssize_t show_voltage(struct device *dev, | |||
111 | * TODO: add support for conversions | 111 | * TODO: add support for conversions |
112 | * other than single ended with a gain of 1 | 112 | * other than single ended with a gain of 1 |
113 | */ | 113 | */ |
114 | /*MUX_M3_bm forces single ended*/ | 114 | /*MUX_M3_BM forces single ended*/ |
115 | /*This is also where the gain of the PGA would be set*/ | 115 | /*This is also where the gain of the PGA would be set*/ |
116 | ads7871_write_reg8(spi, REG_GAIN_MUX, | 116 | ads7871_write_reg8(spi, REG_GAIN_MUX, |
117 | (MUX_CNV_bm | MUX_M3_bm | channel)); | 117 | (MUX_CNV_BM | MUX_M3_BM | channel)); |
118 | 118 | ||
119 | ret = ads7871_read_reg8(spi, REG_GAIN_MUX); | 119 | ret = ads7871_read_reg8(spi, REG_GAIN_MUX); |
120 | mux_cnv = ((ret & MUX_CNV_bm)>>MUX_CNV_bv); | 120 | mux_cnv = ((ret & MUX_CNV_BM) >> MUX_CNV_BV); |
121 | /* | 121 | /* |
122 | * on 400MHz arm9 platform the conversion | 122 | * on 400MHz arm9 platform the conversion |
123 | * is already done when we do this test | 123 | * is already done when we do this test |
@@ -125,14 +125,14 @@ static ssize_t show_voltage(struct device *dev, | |||
125 | while ((i < 2) && mux_cnv) { | 125 | while ((i < 2) && mux_cnv) { |
126 | i++; | 126 | i++; |
127 | ret = ads7871_read_reg8(spi, REG_GAIN_MUX); | 127 | ret = ads7871_read_reg8(spi, REG_GAIN_MUX); |
128 | mux_cnv = ((ret & MUX_CNV_bm)>>MUX_CNV_bv); | 128 | mux_cnv = ((ret & MUX_CNV_BM) >> MUX_CNV_BV); |
129 | msleep_interruptible(1); | 129 | msleep_interruptible(1); |
130 | } | 130 | } |
131 | 131 | ||
132 | if (mux_cnv == 0) { | 132 | if (mux_cnv == 0) { |
133 | val = ads7871_read_reg16(spi, REG_LS_BYTE); | 133 | val = ads7871_read_reg16(spi, REG_LS_BYTE); |
134 | /*result in volts*10000 = (val/8192)*2.5*10000*/ | 134 | /*result in volts*10000 = (val/8192)*2.5*10000*/ |
135 | val = ((val>>2) * 25000) / 8192; | 135 | val = ((val >> 2) * 25000) / 8192; |
136 | return sprintf(buf, "%d\n", val); | 136 | return sprintf(buf, "%d\n", val); |
137 | } else { | 137 | } else { |
138 | return -1; | 138 | return -1; |
@@ -189,7 +189,7 @@ static int ads7871_probe(struct spi_device *spi) | |||
189 | ads7871_write_reg8(spi, REG_SER_CONTROL, 0); | 189 | ads7871_write_reg8(spi, REG_SER_CONTROL, 0); |
190 | ads7871_write_reg8(spi, REG_AD_CONTROL, 0); | 190 | ads7871_write_reg8(spi, REG_AD_CONTROL, 0); |
191 | 191 | ||
192 | val = (OSC_OSCR_bm | OSC_OSCE_bm | OSC_REFE_bm | OSC_BUFE_bm); | 192 | val = (OSC_OSCR_BM | OSC_OSCE_BM | OSC_REFE_BM | OSC_BUFE_BM); |
193 | ads7871_write_reg8(spi, REG_OSC_CONTROL, val); | 193 | ads7871_write_reg8(spi, REG_OSC_CONTROL, val); |
194 | ret = ads7871_read_reg8(spi, REG_OSC_CONTROL); | 194 | ret = ads7871_read_reg8(spi, REG_OSC_CONTROL); |
195 | 195 | ||
diff --git a/drivers/hwmon/adt7310.c b/drivers/hwmon/adt7310.c new file mode 100644 index 000000000000..da5f0789fb97 --- /dev/null +++ b/drivers/hwmon/adt7310.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * ADT7310/ADT7310 digital temperature sensor driver | ||
3 | * | ||
4 | * Copyright 2012-2013 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/spi/spi.h> | ||
13 | #include <asm/unaligned.h> | ||
14 | |||
15 | #include "adt7x10.h" | ||
16 | |||
17 | #define ADT7310_STATUS 0 | ||
18 | #define ADT7310_CONFIG 1 | ||
19 | #define ADT7310_TEMPERATURE 2 | ||
20 | #define ADT7310_ID 3 | ||
21 | #define ADT7310_T_CRIT 4 | ||
22 | #define ADT7310_T_HYST 5 | ||
23 | #define ADT7310_T_ALARM_HIGH 6 | ||
24 | #define ADT7310_T_ALARM_LOW 7 | ||
25 | |||
26 | static const u8 adt7310_reg_table[] = { | ||
27 | [ADT7X10_TEMPERATURE] = ADT7310_TEMPERATURE, | ||
28 | [ADT7X10_STATUS] = ADT7310_STATUS, | ||
29 | [ADT7X10_CONFIG] = ADT7310_CONFIG, | ||
30 | [ADT7X10_T_ALARM_HIGH] = ADT7310_T_ALARM_HIGH, | ||
31 | [ADT7X10_T_ALARM_LOW] = ADT7310_T_ALARM_LOW, | ||
32 | [ADT7X10_T_CRIT] = ADT7310_T_CRIT, | ||
33 | [ADT7X10_T_HYST] = ADT7310_T_HYST, | ||
34 | [ADT7X10_ID] = ADT7310_ID, | ||
35 | }; | ||
36 | |||
37 | #define ADT7310_CMD_REG_OFFSET 3 | ||
38 | #define ADT7310_CMD_READ 0x40 | ||
39 | |||
40 | #define AD7310_COMMAND(reg) (adt7310_reg_table[(reg)] << ADT7310_CMD_REG_OFFSET) | ||
41 | |||
42 | static int adt7310_spi_read_word(struct device *dev, u8 reg) | ||
43 | { | ||
44 | struct spi_device *spi = to_spi_device(dev); | ||
45 | int ret; | ||
46 | |||
47 | ret = spi_w8r16(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ); | ||
48 | if (ret < 0) | ||
49 | return ret; | ||
50 | |||
51 | return be16_to_cpu((__force __be16)ret); | ||
52 | } | ||
53 | |||
54 | static int adt7310_spi_write_word(struct device *dev, u8 reg, u16 data) | ||
55 | { | ||
56 | struct spi_device *spi = to_spi_device(dev); | ||
57 | u8 buf[3]; | ||
58 | |||
59 | buf[0] = AD7310_COMMAND(reg); | ||
60 | put_unaligned_be16(data, &buf[1]); | ||
61 | |||
62 | return spi_write(spi, buf, sizeof(buf)); | ||
63 | } | ||
64 | |||
65 | static int adt7310_spi_read_byte(struct device *dev, u8 reg) | ||
66 | { | ||
67 | struct spi_device *spi = to_spi_device(dev); | ||
68 | |||
69 | return spi_w8r8(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ); | ||
70 | } | ||
71 | |||
72 | static int adt7310_spi_write_byte(struct device *dev, u8 reg, | ||
73 | u8 data) | ||
74 | { | ||
75 | struct spi_device *spi = to_spi_device(dev); | ||
76 | u8 buf[2]; | ||
77 | |||
78 | buf[0] = AD7310_COMMAND(reg); | ||
79 | buf[1] = data; | ||
80 | |||
81 | return spi_write(spi, buf, sizeof(buf)); | ||
82 | } | ||
83 | |||
84 | static const struct adt7x10_ops adt7310_spi_ops = { | ||
85 | .read_word = adt7310_spi_read_word, | ||
86 | .write_word = adt7310_spi_write_word, | ||
87 | .read_byte = adt7310_spi_read_byte, | ||
88 | .write_byte = adt7310_spi_write_byte, | ||
89 | }; | ||
90 | |||
91 | static int adt7310_spi_probe(struct spi_device *spi) | ||
92 | { | ||
93 | return adt7x10_probe(&spi->dev, spi_get_device_id(spi)->name, spi->irq, | ||
94 | &adt7310_spi_ops); | ||
95 | } | ||
96 | |||
97 | static int adt7310_spi_remove(struct spi_device *spi) | ||
98 | { | ||
99 | return adt7x10_remove(&spi->dev, spi->irq); | ||
100 | } | ||
101 | |||
102 | static const struct spi_device_id adt7310_id[] = { | ||
103 | { "adt7310", 0 }, | ||
104 | { "adt7320", 0 }, | ||
105 | {} | ||
106 | }; | ||
107 | MODULE_DEVICE_TABLE(spi, adt7310_id); | ||
108 | |||
109 | static struct spi_driver adt7310_driver = { | ||
110 | .driver = { | ||
111 | .name = "adt7310", | ||
112 | .owner = THIS_MODULE, | ||
113 | .pm = ADT7X10_DEV_PM_OPS, | ||
114 | }, | ||
115 | .probe = adt7310_spi_probe, | ||
116 | .remove = adt7310_spi_remove, | ||
117 | .id_table = adt7310_id, | ||
118 | }; | ||
119 | module_spi_driver(adt7310_driver); | ||
120 | |||
121 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
122 | MODULE_DESCRIPTION("ADT7310/ADT7320 driver"); | ||
123 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hwmon/adt7410.c b/drivers/hwmon/adt7410.c index 99a7290da0a3..0dc066a939b4 100644 --- a/drivers/hwmon/adt7410.c +++ b/drivers/hwmon/adt7410.c | |||
@@ -1,460 +1,80 @@ | |||
1 | /* | 1 | /* |
2 | * adt7410.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | * ADT7410/ADT7420 digital temperature sensor driver |
3 | * monitoring | ||
4 | * This driver handles the ADT7410 and compatible digital temperature sensors. | ||
5 | * Hartmut Knaack <knaack.h@gmx.de> 2012-07-22 | ||
6 | * based on lm75.c by Frodo Looijaard <frodol@dds.nl> | ||
7 | * and adt7410.c from iio-staging by Sonic Zhang <sonic.zhang@analog.com> | ||
8 | * | 3 | * |
9 | * This program is free software; you can redistribute it and/or modify | 4 | * Copyright 2012-2013 Analog Devices Inc. |
10 | * it under the terms of the GNU General Public License as published by | 5 | * Author: Lars-Peter Clausen <lars@metafoo.de> |
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | 6 | * |
14 | * This program is distributed in the hope that it will be useful, | 7 | * Licensed under the GPL-2 or later. |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | 8 | */ |
23 | 9 | ||
24 | #include <linux/module.h> | 10 | #include <linux/module.h> |
25 | #include <linux/init.h> | 11 | #include <linux/init.h> |
26 | #include <linux/slab.h> | ||
27 | #include <linux/jiffies.h> | ||
28 | #include <linux/i2c.h> | 12 | #include <linux/i2c.h> |
29 | #include <linux/hwmon.h> | ||
30 | #include <linux/hwmon-sysfs.h> | ||
31 | #include <linux/err.h> | ||
32 | #include <linux/mutex.h> | ||
33 | #include <linux/delay.h> | ||
34 | |||
35 | /* | ||
36 | * ADT7410 registers definition | ||
37 | */ | ||
38 | |||
39 | #define ADT7410_TEMPERATURE 0 | ||
40 | #define ADT7410_STATUS 2 | ||
41 | #define ADT7410_CONFIG 3 | ||
42 | #define ADT7410_T_ALARM_HIGH 4 | ||
43 | #define ADT7410_T_ALARM_LOW 6 | ||
44 | #define ADT7410_T_CRIT 8 | ||
45 | #define ADT7410_T_HYST 0xA | ||
46 | |||
47 | /* | ||
48 | * ADT7410 status | ||
49 | */ | ||
50 | #define ADT7410_STAT_T_LOW (1 << 4) | ||
51 | #define ADT7410_STAT_T_HIGH (1 << 5) | ||
52 | #define ADT7410_STAT_T_CRIT (1 << 6) | ||
53 | #define ADT7410_STAT_NOT_RDY (1 << 7) | ||
54 | |||
55 | /* | ||
56 | * ADT7410 config | ||
57 | */ | ||
58 | #define ADT7410_FAULT_QUEUE_MASK (1 << 0 | 1 << 1) | ||
59 | #define ADT7410_CT_POLARITY (1 << 2) | ||
60 | #define ADT7410_INT_POLARITY (1 << 3) | ||
61 | #define ADT7410_EVENT_MODE (1 << 4) | ||
62 | #define ADT7410_MODE_MASK (1 << 5 | 1 << 6) | ||
63 | #define ADT7410_FULL (0 << 5 | 0 << 6) | ||
64 | #define ADT7410_PD (1 << 5 | 1 << 6) | ||
65 | #define ADT7410_RESOLUTION (1 << 7) | ||
66 | |||
67 | /* | ||
68 | * ADT7410 masks | ||
69 | */ | ||
70 | #define ADT7410_T13_VALUE_MASK 0xFFF8 | ||
71 | #define ADT7410_T_HYST_MASK 0xF | ||
72 | |||
73 | /* straight from the datasheet */ | ||
74 | #define ADT7410_TEMP_MIN (-55000) | ||
75 | #define ADT7410_TEMP_MAX 150000 | ||
76 | |||
77 | enum adt7410_type { /* keep sorted in alphabetical order */ | ||
78 | adt7410, | ||
79 | }; | ||
80 | |||
81 | static const u8 ADT7410_REG_TEMP[4] = { | ||
82 | ADT7410_TEMPERATURE, /* input */ | ||
83 | ADT7410_T_ALARM_HIGH, /* high */ | ||
84 | ADT7410_T_ALARM_LOW, /* low */ | ||
85 | ADT7410_T_CRIT, /* critical */ | ||
86 | }; | ||
87 | |||
88 | /* Each client has this additional data */ | ||
89 | struct adt7410_data { | ||
90 | struct device *hwmon_dev; | ||
91 | struct mutex update_lock; | ||
92 | u8 config; | ||
93 | u8 oldconfig; | ||
94 | bool valid; /* true if registers valid */ | ||
95 | unsigned long last_updated; /* In jiffies */ | ||
96 | s16 temp[4]; /* Register values, | ||
97 | 0 = input | ||
98 | 1 = high | ||
99 | 2 = low | ||
100 | 3 = critical */ | ||
101 | u8 hyst; /* hysteresis offset */ | ||
102 | }; | ||
103 | |||
104 | /* | ||
105 | * adt7410 register access by I2C | ||
106 | */ | ||
107 | static int adt7410_temp_ready(struct i2c_client *client) | ||
108 | { | ||
109 | int i, status; | ||
110 | |||
111 | for (i = 0; i < 6; i++) { | ||
112 | status = i2c_smbus_read_byte_data(client, ADT7410_STATUS); | ||
113 | if (status < 0) | ||
114 | return status; | ||
115 | if (!(status & ADT7410_STAT_NOT_RDY)) | ||
116 | return 0; | ||
117 | msleep(60); | ||
118 | } | ||
119 | return -ETIMEDOUT; | ||
120 | } | ||
121 | |||
122 | static struct adt7410_data *adt7410_update_device(struct device *dev) | ||
123 | { | ||
124 | struct i2c_client *client = to_i2c_client(dev); | ||
125 | struct adt7410_data *data = i2c_get_clientdata(client); | ||
126 | struct adt7410_data *ret = data; | ||
127 | mutex_lock(&data->update_lock); | ||
128 | |||
129 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | ||
130 | || !data->valid) { | ||
131 | int i, status; | ||
132 | 13 | ||
133 | dev_dbg(&client->dev, "Starting update\n"); | 14 | #include "adt7x10.h" |
134 | 15 | ||
135 | status = adt7410_temp_ready(client); /* check for new value */ | 16 | static int adt7410_i2c_read_word(struct device *dev, u8 reg) |
136 | if (unlikely(status)) { | ||
137 | ret = ERR_PTR(status); | ||
138 | goto abort; | ||
139 | } | ||
140 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { | ||
141 | status = i2c_smbus_read_word_swapped(client, | ||
142 | ADT7410_REG_TEMP[i]); | ||
143 | if (unlikely(status < 0)) { | ||
144 | dev_dbg(dev, | ||
145 | "Failed to read value: reg %d, error %d\n", | ||
146 | ADT7410_REG_TEMP[i], status); | ||
147 | ret = ERR_PTR(status); | ||
148 | goto abort; | ||
149 | } | ||
150 | data->temp[i] = status; | ||
151 | } | ||
152 | status = i2c_smbus_read_byte_data(client, ADT7410_T_HYST); | ||
153 | if (unlikely(status < 0)) { | ||
154 | dev_dbg(dev, | ||
155 | "Failed to read value: reg %d, error %d\n", | ||
156 | ADT7410_T_HYST, status); | ||
157 | ret = ERR_PTR(status); | ||
158 | goto abort; | ||
159 | } | ||
160 | data->hyst = status; | ||
161 | data->last_updated = jiffies; | ||
162 | data->valid = true; | ||
163 | } | ||
164 | |||
165 | abort: | ||
166 | mutex_unlock(&data->update_lock); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | static s16 ADT7410_TEMP_TO_REG(long temp) | ||
171 | { | 17 | { |
172 | return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7410_TEMP_MIN, | 18 | return i2c_smbus_read_word_swapped(to_i2c_client(dev), reg); |
173 | ADT7410_TEMP_MAX) * 128, 1000); | ||
174 | } | 19 | } |
175 | 20 | ||
176 | static int ADT7410_REG_TO_TEMP(struct adt7410_data *data, s16 reg) | 21 | static int adt7410_i2c_write_word(struct device *dev, u8 reg, u16 data) |
177 | { | 22 | { |
178 | /* in 13 bit mode, bits 0-2 are status flags - mask them out */ | 23 | return i2c_smbus_write_word_swapped(to_i2c_client(dev), reg, data); |
179 | if (!(data->config & ADT7410_RESOLUTION)) | ||
180 | reg &= ADT7410_T13_VALUE_MASK; | ||
181 | /* | ||
182 | * temperature is stored in twos complement format, in steps of | ||
183 | * 1/128°C | ||
184 | */ | ||
185 | return DIV_ROUND_CLOSEST(reg * 1000, 128); | ||
186 | } | 24 | } |
187 | 25 | ||
188 | /*-----------------------------------------------------------------------*/ | 26 | static int adt7410_i2c_read_byte(struct device *dev, u8 reg) |
189 | |||
190 | /* sysfs attributes for hwmon */ | ||
191 | |||
192 | static ssize_t adt7410_show_temp(struct device *dev, | ||
193 | struct device_attribute *da, char *buf) | ||
194 | { | 27 | { |
195 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 28 | return i2c_smbus_read_byte_data(to_i2c_client(dev), reg); |
196 | struct adt7410_data *data = adt7410_update_device(dev); | ||
197 | |||
198 | if (IS_ERR(data)) | ||
199 | return PTR_ERR(data); | ||
200 | |||
201 | return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data, | ||
202 | data->temp[attr->index])); | ||
203 | } | 29 | } |
204 | 30 | ||
205 | static ssize_t adt7410_set_temp(struct device *dev, | 31 | static int adt7410_i2c_write_byte(struct device *dev, u8 reg, u8 data) |
206 | struct device_attribute *da, | ||
207 | const char *buf, size_t count) | ||
208 | { | 32 | { |
209 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 33 | return i2c_smbus_write_byte_data(to_i2c_client(dev), reg, data); |
210 | struct i2c_client *client = to_i2c_client(dev); | ||
211 | struct adt7410_data *data = i2c_get_clientdata(client); | ||
212 | int nr = attr->index; | ||
213 | long temp; | ||
214 | int ret; | ||
215 | |||
216 | ret = kstrtol(buf, 10, &temp); | ||
217 | if (ret) | ||
218 | return ret; | ||
219 | |||
220 | mutex_lock(&data->update_lock); | ||
221 | data->temp[nr] = ADT7410_TEMP_TO_REG(temp); | ||
222 | ret = i2c_smbus_write_word_swapped(client, ADT7410_REG_TEMP[nr], | ||
223 | data->temp[nr]); | ||
224 | if (ret) | ||
225 | count = ret; | ||
226 | mutex_unlock(&data->update_lock); | ||
227 | return count; | ||
228 | } | 34 | } |
229 | 35 | ||
230 | static ssize_t adt7410_show_t_hyst(struct device *dev, | 36 | static const struct adt7x10_ops adt7410_i2c_ops = { |
231 | struct device_attribute *da, | 37 | .read_word = adt7410_i2c_read_word, |
232 | char *buf) | 38 | .write_word = adt7410_i2c_write_word, |
233 | { | 39 | .read_byte = adt7410_i2c_read_byte, |
234 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 40 | .write_byte = adt7410_i2c_write_byte, |
235 | struct adt7410_data *data; | ||
236 | int nr = attr->index; | ||
237 | int hyst; | ||
238 | |||
239 | data = adt7410_update_device(dev); | ||
240 | if (IS_ERR(data)) | ||
241 | return PTR_ERR(data); | ||
242 | hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000; | ||
243 | |||
244 | /* | ||
245 | * hysteresis is stored as a 4 bit offset in the device, convert it | ||
246 | * to an absolute value | ||
247 | */ | ||
248 | if (nr == 2) /* min has positive offset, others have negative */ | ||
249 | hyst = -hyst; | ||
250 | return sprintf(buf, "%d\n", | ||
251 | ADT7410_REG_TO_TEMP(data, data->temp[nr]) - hyst); | ||
252 | } | ||
253 | |||
254 | static ssize_t adt7410_set_t_hyst(struct device *dev, | ||
255 | struct device_attribute *da, | ||
256 | const char *buf, size_t count) | ||
257 | { | ||
258 | struct i2c_client *client = to_i2c_client(dev); | ||
259 | struct adt7410_data *data = i2c_get_clientdata(client); | ||
260 | int limit, ret; | ||
261 | long hyst; | ||
262 | |||
263 | ret = kstrtol(buf, 10, &hyst); | ||
264 | if (ret) | ||
265 | return ret; | ||
266 | /* convert absolute hysteresis value to a 4 bit delta value */ | ||
267 | limit = ADT7410_REG_TO_TEMP(data, data->temp[1]); | ||
268 | hyst = clamp_val(hyst, ADT7410_TEMP_MIN, ADT7410_TEMP_MAX); | ||
269 | data->hyst = clamp_val(DIV_ROUND_CLOSEST(limit - hyst, 1000), 0, | ||
270 | ADT7410_T_HYST_MASK); | ||
271 | ret = i2c_smbus_write_byte_data(client, ADT7410_T_HYST, data->hyst); | ||
272 | if (ret) | ||
273 | return ret; | ||
274 | |||
275 | return count; | ||
276 | } | ||
277 | |||
278 | static ssize_t adt7410_show_alarm(struct device *dev, | ||
279 | struct device_attribute *da, | ||
280 | char *buf) | ||
281 | { | ||
282 | struct i2c_client *client = to_i2c_client(dev); | ||
283 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
284 | int ret; | ||
285 | |||
286 | ret = i2c_smbus_read_byte_data(client, ADT7410_STATUS); | ||
287 | if (ret < 0) | ||
288 | return ret; | ||
289 | |||
290 | return sprintf(buf, "%d\n", !!(ret & attr->index)); | ||
291 | } | ||
292 | |||
293 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, adt7410_show_temp, NULL, 0); | ||
294 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, | ||
295 | adt7410_show_temp, adt7410_set_temp, 1); | ||
296 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, | ||
297 | adt7410_show_temp, adt7410_set_temp, 2); | ||
298 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, | ||
299 | adt7410_show_temp, adt7410_set_temp, 3); | ||
300 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, | ||
301 | adt7410_show_t_hyst, adt7410_set_t_hyst, 1); | ||
302 | static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO, | ||
303 | adt7410_show_t_hyst, NULL, 2); | ||
304 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, | ||
305 | adt7410_show_t_hyst, NULL, 3); | ||
306 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, adt7410_show_alarm, | ||
307 | NULL, ADT7410_STAT_T_LOW); | ||
308 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, adt7410_show_alarm, | ||
309 | NULL, ADT7410_STAT_T_HIGH); | ||
310 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, adt7410_show_alarm, | ||
311 | NULL, ADT7410_STAT_T_CRIT); | ||
312 | |||
313 | static struct attribute *adt7410_attributes[] = { | ||
314 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
315 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
316 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
317 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
318 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | ||
319 | &sensor_dev_attr_temp1_min_hyst.dev_attr.attr, | ||
320 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, | ||
321 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
322 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
323 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
324 | NULL | ||
325 | }; | 41 | }; |
326 | 42 | ||
327 | static const struct attribute_group adt7410_group = { | 43 | static int adt7410_i2c_probe(struct i2c_client *client, |
328 | .attrs = adt7410_attributes, | 44 | const struct i2c_device_id *id) |
329 | }; | ||
330 | |||
331 | /*-----------------------------------------------------------------------*/ | ||
332 | |||
333 | /* device probe and removal */ | ||
334 | |||
335 | static int adt7410_probe(struct i2c_client *client, | ||
336 | const struct i2c_device_id *id) | ||
337 | { | 45 | { |
338 | struct adt7410_data *data; | ||
339 | int ret; | ||
340 | |||
341 | if (!i2c_check_functionality(client->adapter, | 46 | if (!i2c_check_functionality(client->adapter, |
342 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) | 47 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) |
343 | return -ENODEV; | 48 | return -ENODEV; |
344 | 49 | ||
345 | data = devm_kzalloc(&client->dev, sizeof(struct adt7410_data), | 50 | return adt7x10_probe(&client->dev, NULL, client->irq, &adt7410_i2c_ops); |
346 | GFP_KERNEL); | ||
347 | if (!data) | ||
348 | return -ENOMEM; | ||
349 | |||
350 | i2c_set_clientdata(client, data); | ||
351 | mutex_init(&data->update_lock); | ||
352 | |||
353 | /* configure as specified */ | ||
354 | ret = i2c_smbus_read_byte_data(client, ADT7410_CONFIG); | ||
355 | if (ret < 0) { | ||
356 | dev_dbg(&client->dev, "Can't read config? %d\n", ret); | ||
357 | return ret; | ||
358 | } | ||
359 | data->oldconfig = ret; | ||
360 | /* | ||
361 | * Set to 16 bit resolution, continous conversion and comparator mode. | ||
362 | */ | ||
363 | ret &= ~ADT7410_MODE_MASK; | ||
364 | data->config = ret | ADT7410_FULL | ADT7410_RESOLUTION | | ||
365 | ADT7410_EVENT_MODE; | ||
366 | if (data->config != data->oldconfig) { | ||
367 | ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG, | ||
368 | data->config); | ||
369 | if (ret) | ||
370 | return ret; | ||
371 | } | ||
372 | dev_dbg(&client->dev, "Config %02x\n", data->config); | ||
373 | |||
374 | /* Register sysfs hooks */ | ||
375 | ret = sysfs_create_group(&client->dev.kobj, &adt7410_group); | ||
376 | if (ret) | ||
377 | goto exit_restore; | ||
378 | |||
379 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
380 | if (IS_ERR(data->hwmon_dev)) { | ||
381 | ret = PTR_ERR(data->hwmon_dev); | ||
382 | goto exit_remove; | ||
383 | } | ||
384 | |||
385 | dev_info(&client->dev, "sensor '%s'\n", client->name); | ||
386 | |||
387 | return 0; | ||
388 | |||
389 | exit_remove: | ||
390 | sysfs_remove_group(&client->dev.kobj, &adt7410_group); | ||
391 | exit_restore: | ||
392 | i2c_smbus_write_byte_data(client, ADT7410_CONFIG, data->oldconfig); | ||
393 | return ret; | ||
394 | } | 51 | } |
395 | 52 | ||
396 | static int adt7410_remove(struct i2c_client *client) | 53 | static int adt7410_i2c_remove(struct i2c_client *client) |
397 | { | 54 | { |
398 | struct adt7410_data *data = i2c_get_clientdata(client); | 55 | return adt7x10_remove(&client->dev, client->irq); |
399 | |||
400 | hwmon_device_unregister(data->hwmon_dev); | ||
401 | sysfs_remove_group(&client->dev.kobj, &adt7410_group); | ||
402 | if (data->oldconfig != data->config) | ||
403 | i2c_smbus_write_byte_data(client, ADT7410_CONFIG, | ||
404 | data->oldconfig); | ||
405 | return 0; | ||
406 | } | 56 | } |
407 | 57 | ||
408 | static const struct i2c_device_id adt7410_ids[] = { | 58 | static const struct i2c_device_id adt7410_ids[] = { |
409 | { "adt7410", adt7410, }, | 59 | { "adt7410", 0 }, |
410 | { "adt7420", adt7410, }, | 60 | { "adt7420", 0 }, |
411 | { /* LIST END */ } | 61 | {} |
412 | }; | 62 | }; |
413 | MODULE_DEVICE_TABLE(i2c, adt7410_ids); | 63 | MODULE_DEVICE_TABLE(i2c, adt7410_ids); |
414 | 64 | ||
415 | #ifdef CONFIG_PM_SLEEP | ||
416 | static int adt7410_suspend(struct device *dev) | ||
417 | { | ||
418 | int ret; | ||
419 | struct i2c_client *client = to_i2c_client(dev); | ||
420 | struct adt7410_data *data = i2c_get_clientdata(client); | ||
421 | |||
422 | ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG, | ||
423 | data->config | ADT7410_PD); | ||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | static int adt7410_resume(struct device *dev) | ||
428 | { | ||
429 | int ret; | ||
430 | struct i2c_client *client = to_i2c_client(dev); | ||
431 | struct adt7410_data *data = i2c_get_clientdata(client); | ||
432 | |||
433 | ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG, data->config); | ||
434 | return ret; | ||
435 | } | ||
436 | |||
437 | static SIMPLE_DEV_PM_OPS(adt7410_dev_pm_ops, adt7410_suspend, adt7410_resume); | ||
438 | |||
439 | #define ADT7410_DEV_PM_OPS (&adt7410_dev_pm_ops) | ||
440 | #else | ||
441 | #define ADT7410_DEV_PM_OPS NULL | ||
442 | #endif /* CONFIG_PM */ | ||
443 | |||
444 | static struct i2c_driver adt7410_driver = { | 65 | static struct i2c_driver adt7410_driver = { |
445 | .class = I2C_CLASS_HWMON, | 66 | .class = I2C_CLASS_HWMON, |
446 | .driver = { | 67 | .driver = { |
447 | .name = "adt7410", | 68 | .name = "adt7410", |
448 | .pm = ADT7410_DEV_PM_OPS, | 69 | .pm = ADT7X10_DEV_PM_OPS, |
449 | }, | 70 | }, |
450 | .probe = adt7410_probe, | 71 | .probe = adt7410_i2c_probe, |
451 | .remove = adt7410_remove, | 72 | .remove = adt7410_i2c_remove, |
452 | .id_table = adt7410_ids, | 73 | .id_table = adt7410_ids, |
453 | .address_list = I2C_ADDRS(0x48, 0x49, 0x4a, 0x4b), | 74 | .address_list = I2C_ADDRS(0x48, 0x49, 0x4a, 0x4b), |
454 | }; | 75 | }; |
455 | |||
456 | module_i2c_driver(adt7410_driver); | 76 | module_i2c_driver(adt7410_driver); |
457 | 77 | ||
458 | MODULE_AUTHOR("Hartmut Knaack"); | 78 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
459 | MODULE_DESCRIPTION("ADT7410/ADT7420 driver"); | 79 | MODULE_DESCRIPTION("ADT7410/AD7420 driver"); |
460 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c index 34ff03abb50b..d9299dee37d1 100644 --- a/drivers/hwmon/adt7411.c +++ b/drivers/hwmon/adt7411.c | |||
@@ -259,15 +259,17 @@ static int adt7411_detect(struct i2c_client *client, | |||
259 | 259 | ||
260 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_MANUFACTURER_ID); | 260 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_MANUFACTURER_ID); |
261 | if (val < 0 || val != ADT7411_MANUFACTURER_ID) { | 261 | if (val < 0 || val != ADT7411_MANUFACTURER_ID) { |
262 | dev_dbg(&client->dev, "Wrong manufacturer ID. Got %d, " | 262 | dev_dbg(&client->dev, |
263 | "expected %d\n", val, ADT7411_MANUFACTURER_ID); | 263 | "Wrong manufacturer ID. Got %d, expected %d\n", |
264 | val, ADT7411_MANUFACTURER_ID); | ||
264 | return -ENODEV; | 265 | return -ENODEV; |
265 | } | 266 | } |
266 | 267 | ||
267 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_DEVICE_ID); | 268 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_DEVICE_ID); |
268 | if (val < 0 || val != ADT7411_DEVICE_ID) { | 269 | if (val < 0 || val != ADT7411_DEVICE_ID) { |
269 | dev_dbg(&client->dev, "Wrong device ID. Got %d, " | 270 | dev_dbg(&client->dev, |
270 | "expected %d\n", val, ADT7411_DEVICE_ID); | 271 | "Wrong device ID. Got %d, expected %d\n", |
272 | val, ADT7411_DEVICE_ID); | ||
271 | return -ENODEV; | 273 | return -ENODEV; |
272 | } | 274 | } |
273 | 275 | ||
diff --git a/drivers/hwmon/adt7x10.c b/drivers/hwmon/adt7x10.c new file mode 100644 index 000000000000..98141f483165 --- /dev/null +++ b/drivers/hwmon/adt7x10.c | |||
@@ -0,0 +1,511 @@ | |||
1 | /* | ||
2 | * adt7x10.c - Part of lm_sensors, Linux kernel modules for hardware | ||
3 | * monitoring | ||
4 | * This driver handles the ADT7410 and compatible digital temperature sensors. | ||
5 | * Hartmut Knaack <knaack.h@gmx.de> 2012-07-22 | ||
6 | * based on lm75.c by Frodo Looijaard <frodol@dds.nl> | ||
7 | * and adt7410.c from iio-staging by Sonic Zhang <sonic.zhang@analog.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/jiffies.h> | ||
28 | #include <linux/hwmon.h> | ||
29 | #include <linux/hwmon-sysfs.h> | ||
30 | #include <linux/err.h> | ||
31 | #include <linux/mutex.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | |||
35 | #include "adt7x10.h" | ||
36 | |||
37 | /* | ||
38 | * ADT7X10 status | ||
39 | */ | ||
40 | #define ADT7X10_STAT_T_LOW (1 << 4) | ||
41 | #define ADT7X10_STAT_T_HIGH (1 << 5) | ||
42 | #define ADT7X10_STAT_T_CRIT (1 << 6) | ||
43 | #define ADT7X10_STAT_NOT_RDY (1 << 7) | ||
44 | |||
45 | /* | ||
46 | * ADT7X10 config | ||
47 | */ | ||
48 | #define ADT7X10_FAULT_QUEUE_MASK (1 << 0 | 1 << 1) | ||
49 | #define ADT7X10_CT_POLARITY (1 << 2) | ||
50 | #define ADT7X10_INT_POLARITY (1 << 3) | ||
51 | #define ADT7X10_EVENT_MODE (1 << 4) | ||
52 | #define ADT7X10_MODE_MASK (1 << 5 | 1 << 6) | ||
53 | #define ADT7X10_FULL (0 << 5 | 0 << 6) | ||
54 | #define ADT7X10_PD (1 << 5 | 1 << 6) | ||
55 | #define ADT7X10_RESOLUTION (1 << 7) | ||
56 | |||
57 | /* | ||
58 | * ADT7X10 masks | ||
59 | */ | ||
60 | #define ADT7X10_T13_VALUE_MASK 0xFFF8 | ||
61 | #define ADT7X10_T_HYST_MASK 0xF | ||
62 | |||
63 | /* straight from the datasheet */ | ||
64 | #define ADT7X10_TEMP_MIN (-55000) | ||
65 | #define ADT7X10_TEMP_MAX 150000 | ||
66 | |||
67 | /* Each client has this additional data */ | ||
68 | struct adt7x10_data { | ||
69 | const struct adt7x10_ops *ops; | ||
70 | const char *name; | ||
71 | struct device *hwmon_dev; | ||
72 | struct mutex update_lock; | ||
73 | u8 config; | ||
74 | u8 oldconfig; | ||
75 | bool valid; /* true if registers valid */ | ||
76 | unsigned long last_updated; /* In jiffies */ | ||
77 | s16 temp[4]; /* Register values, | ||
78 | 0 = input | ||
79 | 1 = high | ||
80 | 2 = low | ||
81 | 3 = critical */ | ||
82 | u8 hyst; /* hysteresis offset */ | ||
83 | }; | ||
84 | |||
85 | static int adt7x10_read_byte(struct device *dev, u8 reg) | ||
86 | { | ||
87 | struct adt7x10_data *d = dev_get_drvdata(dev); | ||
88 | return d->ops->read_byte(dev, reg); | ||
89 | } | ||
90 | |||
91 | static int adt7x10_write_byte(struct device *dev, u8 reg, u8 data) | ||
92 | { | ||
93 | struct adt7x10_data *d = dev_get_drvdata(dev); | ||
94 | return d->ops->write_byte(dev, reg, data); | ||
95 | } | ||
96 | |||
97 | static int adt7x10_read_word(struct device *dev, u8 reg) | ||
98 | { | ||
99 | struct adt7x10_data *d = dev_get_drvdata(dev); | ||
100 | return d->ops->read_word(dev, reg); | ||
101 | } | ||
102 | |||
103 | static int adt7x10_write_word(struct device *dev, u8 reg, u16 data) | ||
104 | { | ||
105 | struct adt7x10_data *d = dev_get_drvdata(dev); | ||
106 | return d->ops->write_word(dev, reg, data); | ||
107 | } | ||
108 | |||
109 | static const u8 ADT7X10_REG_TEMP[4] = { | ||
110 | ADT7X10_TEMPERATURE, /* input */ | ||
111 | ADT7X10_T_ALARM_HIGH, /* high */ | ||
112 | ADT7X10_T_ALARM_LOW, /* low */ | ||
113 | ADT7X10_T_CRIT, /* critical */ | ||
114 | }; | ||
115 | |||
116 | static irqreturn_t adt7x10_irq_handler(int irq, void *private) | ||
117 | { | ||
118 | struct device *dev = private; | ||
119 | int status; | ||
120 | |||
121 | status = adt7x10_read_byte(dev, ADT7X10_STATUS); | ||
122 | if (status < 0) | ||
123 | return IRQ_HANDLED; | ||
124 | |||
125 | if (status & ADT7X10_STAT_T_HIGH) | ||
126 | sysfs_notify(&dev->kobj, NULL, "temp1_max_alarm"); | ||
127 | if (status & ADT7X10_STAT_T_LOW) | ||
128 | sysfs_notify(&dev->kobj, NULL, "temp1_min_alarm"); | ||
129 | if (status & ADT7X10_STAT_T_CRIT) | ||
130 | sysfs_notify(&dev->kobj, NULL, "temp1_crit_alarm"); | ||
131 | |||
132 | return IRQ_HANDLED; | ||
133 | } | ||
134 | |||
135 | static int adt7x10_temp_ready(struct device *dev) | ||
136 | { | ||
137 | int i, status; | ||
138 | |||
139 | for (i = 0; i < 6; i++) { | ||
140 | status = adt7x10_read_byte(dev, ADT7X10_STATUS); | ||
141 | if (status < 0) | ||
142 | return status; | ||
143 | if (!(status & ADT7X10_STAT_NOT_RDY)) | ||
144 | return 0; | ||
145 | msleep(60); | ||
146 | } | ||
147 | return -ETIMEDOUT; | ||
148 | } | ||
149 | |||
150 | static int adt7x10_update_temp(struct device *dev) | ||
151 | { | ||
152 | struct adt7x10_data *data = dev_get_drvdata(dev); | ||
153 | int ret = 0; | ||
154 | |||
155 | mutex_lock(&data->update_lock); | ||
156 | |||
157 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | ||
158 | || !data->valid) { | ||
159 | int temp; | ||
160 | |||
161 | dev_dbg(dev, "Starting update\n"); | ||
162 | |||
163 | ret = adt7x10_temp_ready(dev); /* check for new value */ | ||
164 | if (ret) | ||
165 | goto abort; | ||
166 | |||
167 | temp = adt7x10_read_word(dev, ADT7X10_REG_TEMP[0]); | ||
168 | if (temp < 0) { | ||
169 | ret = temp; | ||
170 | dev_dbg(dev, "Failed to read value: reg %d, error %d\n", | ||
171 | ADT7X10_REG_TEMP[0], ret); | ||
172 | goto abort; | ||
173 | } | ||
174 | data->temp[0] = temp; | ||
175 | data->last_updated = jiffies; | ||
176 | data->valid = true; | ||
177 | } | ||
178 | |||
179 | abort: | ||
180 | mutex_unlock(&data->update_lock); | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | static int adt7x10_fill_cache(struct device *dev) | ||
185 | { | ||
186 | struct adt7x10_data *data = dev_get_drvdata(dev); | ||
187 | int ret; | ||
188 | int i; | ||
189 | |||
190 | for (i = 1; i < ARRAY_SIZE(data->temp); i++) { | ||
191 | ret = adt7x10_read_word(dev, ADT7X10_REG_TEMP[i]); | ||
192 | if (ret < 0) { | ||
193 | dev_dbg(dev, "Failed to read value: reg %d, error %d\n", | ||
194 | ADT7X10_REG_TEMP[i], ret); | ||
195 | return ret; | ||
196 | } | ||
197 | data->temp[i] = ret; | ||
198 | } | ||
199 | |||
200 | ret = adt7x10_read_byte(dev, ADT7X10_T_HYST); | ||
201 | if (ret < 0) { | ||
202 | dev_dbg(dev, "Failed to read value: reg %d, error %d\n", | ||
203 | ADT7X10_T_HYST, ret); | ||
204 | return ret; | ||
205 | } | ||
206 | data->hyst = ret; | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | static s16 ADT7X10_TEMP_TO_REG(long temp) | ||
212 | { | ||
213 | return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7X10_TEMP_MIN, | ||
214 | ADT7X10_TEMP_MAX) * 128, 1000); | ||
215 | } | ||
216 | |||
217 | static int ADT7X10_REG_TO_TEMP(struct adt7x10_data *data, s16 reg) | ||
218 | { | ||
219 | /* in 13 bit mode, bits 0-2 are status flags - mask them out */ | ||
220 | if (!(data->config & ADT7X10_RESOLUTION)) | ||
221 | reg &= ADT7X10_T13_VALUE_MASK; | ||
222 | /* | ||
223 | * temperature is stored in twos complement format, in steps of | ||
224 | * 1/128°C | ||
225 | */ | ||
226 | return DIV_ROUND_CLOSEST(reg * 1000, 128); | ||
227 | } | ||
228 | |||
229 | /*-----------------------------------------------------------------------*/ | ||
230 | |||
231 | /* sysfs attributes for hwmon */ | ||
232 | |||
233 | static ssize_t adt7x10_show_temp(struct device *dev, | ||
234 | struct device_attribute *da, | ||
235 | char *buf) | ||
236 | { | ||
237 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
238 | struct adt7x10_data *data = dev_get_drvdata(dev); | ||
239 | |||
240 | |||
241 | if (attr->index == 0) { | ||
242 | int ret; | ||
243 | |||
244 | ret = adt7x10_update_temp(dev); | ||
245 | if (ret) | ||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | return sprintf(buf, "%d\n", ADT7X10_REG_TO_TEMP(data, | ||
250 | data->temp[attr->index])); | ||
251 | } | ||
252 | |||
253 | static ssize_t adt7x10_set_temp(struct device *dev, | ||
254 | struct device_attribute *da, | ||
255 | const char *buf, size_t count) | ||
256 | { | ||
257 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
258 | struct adt7x10_data *data = dev_get_drvdata(dev); | ||
259 | int nr = attr->index; | ||
260 | long temp; | ||
261 | int ret; | ||
262 | |||
263 | ret = kstrtol(buf, 10, &temp); | ||
264 | if (ret) | ||
265 | return ret; | ||
266 | |||
267 | mutex_lock(&data->update_lock); | ||
268 | data->temp[nr] = ADT7X10_TEMP_TO_REG(temp); | ||
269 | ret = adt7x10_write_word(dev, ADT7X10_REG_TEMP[nr], data->temp[nr]); | ||
270 | if (ret) | ||
271 | count = ret; | ||
272 | mutex_unlock(&data->update_lock); | ||
273 | return count; | ||
274 | } | ||
275 | |||
276 | static ssize_t adt7x10_show_t_hyst(struct device *dev, | ||
277 | struct device_attribute *da, | ||
278 | char *buf) | ||
279 | { | ||
280 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
281 | struct adt7x10_data *data = dev_get_drvdata(dev); | ||
282 | int nr = attr->index; | ||
283 | int hyst; | ||
284 | |||
285 | hyst = (data->hyst & ADT7X10_T_HYST_MASK) * 1000; | ||
286 | |||
287 | /* | ||
288 | * hysteresis is stored as a 4 bit offset in the device, convert it | ||
289 | * to an absolute value | ||
290 | */ | ||
291 | if (nr == 2) /* min has positive offset, others have negative */ | ||
292 | hyst = -hyst; | ||
293 | return sprintf(buf, "%d\n", | ||
294 | ADT7X10_REG_TO_TEMP(data, data->temp[nr]) - hyst); | ||
295 | } | ||
296 | |||
297 | static ssize_t adt7x10_set_t_hyst(struct device *dev, | ||
298 | struct device_attribute *da, | ||
299 | const char *buf, size_t count) | ||
300 | { | ||
301 | struct adt7x10_data *data = dev_get_drvdata(dev); | ||
302 | int limit, ret; | ||
303 | long hyst; | ||
304 | |||
305 | ret = kstrtol(buf, 10, &hyst); | ||
306 | if (ret) | ||
307 | return ret; | ||
308 | /* convert absolute hysteresis value to a 4 bit delta value */ | ||
309 | limit = ADT7X10_REG_TO_TEMP(data, data->temp[1]); | ||
310 | hyst = clamp_val(hyst, ADT7X10_TEMP_MIN, ADT7X10_TEMP_MAX); | ||
311 | data->hyst = clamp_val(DIV_ROUND_CLOSEST(limit - hyst, 1000), | ||
312 | 0, ADT7X10_T_HYST_MASK); | ||
313 | ret = adt7x10_write_byte(dev, ADT7X10_T_HYST, data->hyst); | ||
314 | if (ret) | ||
315 | return ret; | ||
316 | |||
317 | return count; | ||
318 | } | ||
319 | |||
320 | static ssize_t adt7x10_show_alarm(struct device *dev, | ||
321 | struct device_attribute *da, | ||
322 | char *buf) | ||
323 | { | ||
324 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
325 | int ret; | ||
326 | |||
327 | ret = adt7x10_read_byte(dev, ADT7X10_STATUS); | ||
328 | if (ret < 0) | ||
329 | return ret; | ||
330 | |||
331 | return sprintf(buf, "%d\n", !!(ret & attr->index)); | ||
332 | } | ||
333 | |||
334 | static ssize_t adt7x10_show_name(struct device *dev, | ||
335 | struct device_attribute *da, | ||
336 | char *buf) | ||
337 | { | ||
338 | struct adt7x10_data *data = dev_get_drvdata(dev); | ||
339 | |||
340 | return sprintf(buf, "%s\n", data->name); | ||
341 | } | ||
342 | |||
343 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, adt7x10_show_temp, NULL, 0); | ||
344 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, | ||
345 | adt7x10_show_temp, adt7x10_set_temp, 1); | ||
346 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, | ||
347 | adt7x10_show_temp, adt7x10_set_temp, 2); | ||
348 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, | ||
349 | adt7x10_show_temp, adt7x10_set_temp, 3); | ||
350 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, | ||
351 | adt7x10_show_t_hyst, adt7x10_set_t_hyst, 1); | ||
352 | static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO, | ||
353 | adt7x10_show_t_hyst, NULL, 2); | ||
354 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, | ||
355 | adt7x10_show_t_hyst, NULL, 3); | ||
356 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, adt7x10_show_alarm, | ||
357 | NULL, ADT7X10_STAT_T_LOW); | ||
358 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, adt7x10_show_alarm, | ||
359 | NULL, ADT7X10_STAT_T_HIGH); | ||
360 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, adt7x10_show_alarm, | ||
361 | NULL, ADT7X10_STAT_T_CRIT); | ||
362 | static DEVICE_ATTR(name, S_IRUGO, adt7x10_show_name, NULL); | ||
363 | |||
364 | static struct attribute *adt7x10_attributes[] = { | ||
365 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
366 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
367 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
368 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
369 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | ||
370 | &sensor_dev_attr_temp1_min_hyst.dev_attr.attr, | ||
371 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, | ||
372 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
373 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
374 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
375 | NULL | ||
376 | }; | ||
377 | |||
378 | static const struct attribute_group adt7x10_group = { | ||
379 | .attrs = adt7x10_attributes, | ||
380 | }; | ||
381 | |||
382 | int adt7x10_probe(struct device *dev, const char *name, int irq, | ||
383 | const struct adt7x10_ops *ops) | ||
384 | { | ||
385 | struct adt7x10_data *data; | ||
386 | int ret; | ||
387 | |||
388 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); | ||
389 | if (!data) | ||
390 | return -ENOMEM; | ||
391 | |||
392 | data->ops = ops; | ||
393 | data->name = name; | ||
394 | |||
395 | dev_set_drvdata(dev, data); | ||
396 | mutex_init(&data->update_lock); | ||
397 | |||
398 | /* configure as specified */ | ||
399 | ret = adt7x10_read_byte(dev, ADT7X10_CONFIG); | ||
400 | if (ret < 0) { | ||
401 | dev_dbg(dev, "Can't read config? %d\n", ret); | ||
402 | return ret; | ||
403 | } | ||
404 | data->oldconfig = ret; | ||
405 | |||
406 | /* | ||
407 | * Set to 16 bit resolution, continous conversion and comparator mode. | ||
408 | */ | ||
409 | data->config = data->oldconfig; | ||
410 | data->config &= ~(ADT7X10_MODE_MASK | ADT7X10_CT_POLARITY | | ||
411 | ADT7X10_INT_POLARITY); | ||
412 | data->config |= ADT7X10_FULL | ADT7X10_RESOLUTION | ADT7X10_EVENT_MODE; | ||
413 | |||
414 | if (data->config != data->oldconfig) { | ||
415 | ret = adt7x10_write_byte(dev, ADT7X10_CONFIG, data->config); | ||
416 | if (ret) | ||
417 | return ret; | ||
418 | } | ||
419 | dev_dbg(dev, "Config %02x\n", data->config); | ||
420 | |||
421 | ret = adt7x10_fill_cache(dev); | ||
422 | if (ret) | ||
423 | goto exit_restore; | ||
424 | |||
425 | /* Register sysfs hooks */ | ||
426 | ret = sysfs_create_group(&dev->kobj, &adt7x10_group); | ||
427 | if (ret) | ||
428 | goto exit_restore; | ||
429 | |||
430 | /* | ||
431 | * The I2C device will already have it's own 'name' attribute, but for | ||
432 | * the SPI device we need to register it. name will only be non NULL if | ||
433 | * the device doesn't register the 'name' attribute on its own. | ||
434 | */ | ||
435 | if (name) { | ||
436 | ret = device_create_file(dev, &dev_attr_name); | ||
437 | if (ret) | ||
438 | goto exit_remove; | ||
439 | } | ||
440 | |||
441 | data->hwmon_dev = hwmon_device_register(dev); | ||
442 | if (IS_ERR(data->hwmon_dev)) { | ||
443 | ret = PTR_ERR(data->hwmon_dev); | ||
444 | goto exit_remove_name; | ||
445 | } | ||
446 | |||
447 | if (irq > 0) { | ||
448 | ret = request_threaded_irq(irq, NULL, adt7x10_irq_handler, | ||
449 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
450 | dev_name(dev), dev); | ||
451 | if (ret) | ||
452 | goto exit_hwmon_device_unregister; | ||
453 | } | ||
454 | |||
455 | return 0; | ||
456 | |||
457 | exit_hwmon_device_unregister: | ||
458 | hwmon_device_unregister(data->hwmon_dev); | ||
459 | exit_remove_name: | ||
460 | if (name) | ||
461 | device_remove_file(dev, &dev_attr_name); | ||
462 | exit_remove: | ||
463 | sysfs_remove_group(&dev->kobj, &adt7x10_group); | ||
464 | exit_restore: | ||
465 | adt7x10_write_byte(dev, ADT7X10_CONFIG, data->oldconfig); | ||
466 | return ret; | ||
467 | } | ||
468 | EXPORT_SYMBOL_GPL(adt7x10_probe); | ||
469 | |||
470 | int adt7x10_remove(struct device *dev, int irq) | ||
471 | { | ||
472 | struct adt7x10_data *data = dev_get_drvdata(dev); | ||
473 | |||
474 | if (irq > 0) | ||
475 | free_irq(irq, dev); | ||
476 | |||
477 | hwmon_device_unregister(data->hwmon_dev); | ||
478 | if (data->name) | ||
479 | device_remove_file(dev, &dev_attr_name); | ||
480 | sysfs_remove_group(&dev->kobj, &adt7x10_group); | ||
481 | if (data->oldconfig != data->config) | ||
482 | adt7x10_write_byte(dev, ADT7X10_CONFIG, data->oldconfig); | ||
483 | return 0; | ||
484 | } | ||
485 | EXPORT_SYMBOL_GPL(adt7x10_remove); | ||
486 | |||
487 | #ifdef CONFIG_PM_SLEEP | ||
488 | |||
489 | static int adt7x10_suspend(struct device *dev) | ||
490 | { | ||
491 | struct adt7x10_data *data = dev_get_drvdata(dev); | ||
492 | |||
493 | return adt7x10_write_byte(dev, ADT7X10_CONFIG, | ||
494 | data->config | ADT7X10_PD); | ||
495 | } | ||
496 | |||
497 | static int adt7x10_resume(struct device *dev) | ||
498 | { | ||
499 | struct adt7x10_data *data = dev_get_drvdata(dev); | ||
500 | |||
501 | return adt7x10_write_byte(dev, ADT7X10_CONFIG, data->config); | ||
502 | } | ||
503 | |||
504 | SIMPLE_DEV_PM_OPS(adt7x10_dev_pm_ops, adt7x10_suspend, adt7x10_resume); | ||
505 | EXPORT_SYMBOL_GPL(adt7x10_dev_pm_ops); | ||
506 | |||
507 | #endif /* CONFIG_PM_SLEEP */ | ||
508 | |||
509 | MODULE_AUTHOR("Hartmut Knaack"); | ||
510 | MODULE_DESCRIPTION("ADT7410/ADT7420, ADT7310/ADT7320 common code"); | ||
511 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hwmon/adt7x10.h b/drivers/hwmon/adt7x10.h new file mode 100644 index 000000000000..d491c698529e --- /dev/null +++ b/drivers/hwmon/adt7x10.h | |||
@@ -0,0 +1,37 @@ | |||
1 | #ifndef __HWMON_ADT7X10_H__ | ||
2 | #define __HWMON_ADT7X10_H__ | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | #include <linux/pm.h> | ||
6 | |||
7 | /* ADT7410 registers definition */ | ||
8 | #define ADT7X10_TEMPERATURE 0 | ||
9 | #define ADT7X10_STATUS 2 | ||
10 | #define ADT7X10_CONFIG 3 | ||
11 | #define ADT7X10_T_ALARM_HIGH 4 | ||
12 | #define ADT7X10_T_ALARM_LOW 6 | ||
13 | #define ADT7X10_T_CRIT 8 | ||
14 | #define ADT7X10_T_HYST 0xA | ||
15 | #define ADT7X10_ID 0xB | ||
16 | |||
17 | struct device; | ||
18 | |||
19 | struct adt7x10_ops { | ||
20 | int (*read_byte)(struct device *, u8 reg); | ||
21 | int (*write_byte)(struct device *, u8 reg, u8 data); | ||
22 | int (*read_word)(struct device *, u8 reg); | ||
23 | int (*write_word)(struct device *, u8 reg, u16 data); | ||
24 | }; | ||
25 | |||
26 | int adt7x10_probe(struct device *dev, const char *name, int irq, | ||
27 | const struct adt7x10_ops *ops); | ||
28 | int adt7x10_remove(struct device *dev, int irq); | ||
29 | |||
30 | #ifdef CONFIG_PM_SLEEP | ||
31 | extern const struct dev_pm_ops adt7x10_dev_pm_ops; | ||
32 | #define ADT7X10_DEV_PM_OPS (&adt7x10_dev_pm_ops) | ||
33 | #else | ||
34 | #define ADT7X10_DEV_PM_OPS NULL | ||
35 | #endif | ||
36 | |||
37 | #endif | ||
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index b41baffa20f0..62c2e32e25ef 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -922,7 +922,7 @@ static void applesmc_brightness_set(struct led_classdev *led_cdev, | |||
922 | ret = queue_work(applesmc_led_wq, &backlight_work); | 922 | ret = queue_work(applesmc_led_wq, &backlight_work); |
923 | 923 | ||
924 | if (debug && (!ret)) | 924 | if (debug && (!ret)) |
925 | printk(KERN_DEBUG "applesmc: work was already on the queue.\n"); | 925 | dev_dbg(led_cdev->dev, "work was already on the queue.\n"); |
926 | } | 926 | } |
927 | 927 | ||
928 | static ssize_t applesmc_key_count_show(struct device *dev, | 928 | static ssize_t applesmc_key_count_show(struct device *dev, |
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 6ac612cabda1..f96063680e58 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c | |||
@@ -55,8 +55,8 @@ static const unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; | |||
55 | 55 | ||
56 | static unsigned short force_subclients[4]; | 56 | static unsigned short force_subclients[4]; |
57 | module_param_array(force_subclients, short, NULL, 0); | 57 | module_param_array(force_subclients, short, NULL, 0); |
58 | MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " | 58 | MODULE_PARM_DESC(force_subclients, |
59 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); | 59 | "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); |
60 | 60 | ||
61 | /* Voltage IN registers 0-6 */ | 61 | /* Voltage IN registers 0-6 */ |
62 | #define ASB100_REG_IN(nr) (0x20 + (nr)) | 62 | #define ASB100_REG_IN(nr) (0x20 + (nr)) |
@@ -689,8 +689,8 @@ static int asb100_detect_subclients(struct i2c_client *client) | |||
689 | for (i = 2; i <= 3; i++) { | 689 | for (i = 2; i <= 3; i++) { |
690 | if (force_subclients[i] < 0x48 || | 690 | if (force_subclients[i] < 0x48 || |
691 | force_subclients[i] > 0x4f) { | 691 | force_subclients[i] > 0x4f) { |
692 | dev_err(&client->dev, "invalid subclient " | 692 | dev_err(&client->dev, |
693 | "address %d; must be 0x48-0x4f\n", | 693 | "invalid subclient address %d; must be 0x48-0x4f\n", |
694 | force_subclients[i]); | 694 | force_subclients[i]); |
695 | err = -ENODEV; | 695 | err = -ENODEV; |
696 | goto ERROR_SC_2; | 696 | goto ERROR_SC_2; |
@@ -708,24 +708,27 @@ static int asb100_detect_subclients(struct i2c_client *client) | |||
708 | } | 708 | } |
709 | 709 | ||
710 | if (sc_addr[0] == sc_addr[1]) { | 710 | if (sc_addr[0] == sc_addr[1]) { |
711 | dev_err(&client->dev, "duplicate addresses 0x%x " | 711 | dev_err(&client->dev, |
712 | "for subclients\n", sc_addr[0]); | 712 | "duplicate addresses 0x%x for subclients\n", |
713 | sc_addr[0]); | ||
713 | err = -ENODEV; | 714 | err = -ENODEV; |
714 | goto ERROR_SC_2; | 715 | goto ERROR_SC_2; |
715 | } | 716 | } |
716 | 717 | ||
717 | data->lm75[0] = i2c_new_dummy(adapter, sc_addr[0]); | 718 | data->lm75[0] = i2c_new_dummy(adapter, sc_addr[0]); |
718 | if (!data->lm75[0]) { | 719 | if (!data->lm75[0]) { |
719 | dev_err(&client->dev, "subclient %d registration " | 720 | dev_err(&client->dev, |
720 | "at address 0x%x failed.\n", 1, sc_addr[0]); | 721 | "subclient %d registration at address 0x%x failed.\n", |
722 | 1, sc_addr[0]); | ||
721 | err = -ENOMEM; | 723 | err = -ENOMEM; |
722 | goto ERROR_SC_2; | 724 | goto ERROR_SC_2; |
723 | } | 725 | } |
724 | 726 | ||
725 | data->lm75[1] = i2c_new_dummy(adapter, sc_addr[1]); | 727 | data->lm75[1] = i2c_new_dummy(adapter, sc_addr[1]); |
726 | if (!data->lm75[1]) { | 728 | if (!data->lm75[1]) { |
727 | dev_err(&client->dev, "subclient %d registration " | 729 | dev_err(&client->dev, |
728 | "at address 0x%x failed.\n", 2, sc_addr[1]); | 730 | "subclient %d registration at address 0x%x failed.\n", |
731 | 2, sc_addr[1]); | ||
729 | err = -ENOMEM; | 732 | err = -ENOMEM; |
730 | goto ERROR_SC_3; | 733 | goto ERROR_SC_3; |
731 | } | 734 | } |
diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c index da7f5b5d5db5..3ad9d849add2 100644 --- a/drivers/hwmon/asc7621.c +++ b/drivers/hwmon/asc7621.c | |||
@@ -159,12 +159,12 @@ static inline int write_byte(struct i2c_client *client, u8 reg, u8 data) | |||
159 | * and retrieval of like parameters. | 159 | * and retrieval of like parameters. |
160 | */ | 160 | */ |
161 | 161 | ||
162 | #define SETUP_SHOW_data_param(d, a) \ | 162 | #define SETUP_SHOW_DATA_PARAM(d, a) \ |
163 | struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \ | 163 | struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \ |
164 | struct asc7621_data *data = asc7621_update_device(d); \ | 164 | struct asc7621_data *data = asc7621_update_device(d); \ |
165 | struct asc7621_param *param = to_asc7621_param(sda) | 165 | struct asc7621_param *param = to_asc7621_param(sda) |
166 | 166 | ||
167 | #define SETUP_STORE_data_param(d, a) \ | 167 | #define SETUP_STORE_DATA_PARAM(d, a) \ |
168 | struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \ | 168 | struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \ |
169 | struct i2c_client *client = to_i2c_client(d); \ | 169 | struct i2c_client *client = to_i2c_client(d); \ |
170 | struct asc7621_data *data = i2c_get_clientdata(client); \ | 170 | struct asc7621_data *data = i2c_get_clientdata(client); \ |
@@ -177,7 +177,7 @@ static inline int write_byte(struct i2c_client *client, u8 reg, u8 data) | |||
177 | static ssize_t show_u8(struct device *dev, struct device_attribute *attr, | 177 | static ssize_t show_u8(struct device *dev, struct device_attribute *attr, |
178 | char *buf) | 178 | char *buf) |
179 | { | 179 | { |
180 | SETUP_SHOW_data_param(dev, attr); | 180 | SETUP_SHOW_DATA_PARAM(dev, attr); |
181 | 181 | ||
182 | return sprintf(buf, "%u\n", data->reg[param->msb[0]]); | 182 | return sprintf(buf, "%u\n", data->reg[param->msb[0]]); |
183 | } | 183 | } |
@@ -185,7 +185,7 @@ static ssize_t show_u8(struct device *dev, struct device_attribute *attr, | |||
185 | static ssize_t store_u8(struct device *dev, struct device_attribute *attr, | 185 | static ssize_t store_u8(struct device *dev, struct device_attribute *attr, |
186 | const char *buf, size_t count) | 186 | const char *buf, size_t count) |
187 | { | 187 | { |
188 | SETUP_STORE_data_param(dev, attr); | 188 | SETUP_STORE_DATA_PARAM(dev, attr); |
189 | long reqval; | 189 | long reqval; |
190 | 190 | ||
191 | if (kstrtol(buf, 10, &reqval)) | 191 | if (kstrtol(buf, 10, &reqval)) |
@@ -206,7 +206,7 @@ static ssize_t store_u8(struct device *dev, struct device_attribute *attr, | |||
206 | static ssize_t show_bitmask(struct device *dev, | 206 | static ssize_t show_bitmask(struct device *dev, |
207 | struct device_attribute *attr, char *buf) | 207 | struct device_attribute *attr, char *buf) |
208 | { | 208 | { |
209 | SETUP_SHOW_data_param(dev, attr); | 209 | SETUP_SHOW_DATA_PARAM(dev, attr); |
210 | 210 | ||
211 | return sprintf(buf, "%u\n", | 211 | return sprintf(buf, "%u\n", |
212 | (data->reg[param->msb[0]] >> param-> | 212 | (data->reg[param->msb[0]] >> param-> |
@@ -217,7 +217,7 @@ static ssize_t store_bitmask(struct device *dev, | |||
217 | struct device_attribute *attr, | 217 | struct device_attribute *attr, |
218 | const char *buf, size_t count) | 218 | const char *buf, size_t count) |
219 | { | 219 | { |
220 | SETUP_STORE_data_param(dev, attr); | 220 | SETUP_STORE_DATA_PARAM(dev, attr); |
221 | long reqval; | 221 | long reqval; |
222 | u8 currval; | 222 | u8 currval; |
223 | 223 | ||
@@ -246,7 +246,7 @@ static ssize_t store_bitmask(struct device *dev, | |||
246 | static ssize_t show_fan16(struct device *dev, | 246 | static ssize_t show_fan16(struct device *dev, |
247 | struct device_attribute *attr, char *buf) | 247 | struct device_attribute *attr, char *buf) |
248 | { | 248 | { |
249 | SETUP_SHOW_data_param(dev, attr); | 249 | SETUP_SHOW_DATA_PARAM(dev, attr); |
250 | u16 regval; | 250 | u16 regval; |
251 | 251 | ||
252 | mutex_lock(&data->update_lock); | 252 | mutex_lock(&data->update_lock); |
@@ -262,7 +262,7 @@ static ssize_t store_fan16(struct device *dev, | |||
262 | struct device_attribute *attr, const char *buf, | 262 | struct device_attribute *attr, const char *buf, |
263 | size_t count) | 263 | size_t count) |
264 | { | 264 | { |
265 | SETUP_STORE_data_param(dev, attr); | 265 | SETUP_STORE_DATA_PARAM(dev, attr); |
266 | long reqval; | 266 | long reqval; |
267 | 267 | ||
268 | if (kstrtol(buf, 10, &reqval)) | 268 | if (kstrtol(buf, 10, &reqval)) |
@@ -307,7 +307,7 @@ static int asc7621_in_scaling[] = { | |||
307 | static ssize_t show_in10(struct device *dev, struct device_attribute *attr, | 307 | static ssize_t show_in10(struct device *dev, struct device_attribute *attr, |
308 | char *buf) | 308 | char *buf) |
309 | { | 309 | { |
310 | SETUP_SHOW_data_param(dev, attr); | 310 | SETUP_SHOW_DATA_PARAM(dev, attr); |
311 | u16 regval; | 311 | u16 regval; |
312 | u8 nr = sda->index; | 312 | u8 nr = sda->index; |
313 | 313 | ||
@@ -325,7 +325,7 @@ static ssize_t show_in10(struct device *dev, struct device_attribute *attr, | |||
325 | static ssize_t show_in8(struct device *dev, struct device_attribute *attr, | 325 | static ssize_t show_in8(struct device *dev, struct device_attribute *attr, |
326 | char *buf) | 326 | char *buf) |
327 | { | 327 | { |
328 | SETUP_SHOW_data_param(dev, attr); | 328 | SETUP_SHOW_DATA_PARAM(dev, attr); |
329 | u8 nr = sda->index; | 329 | u8 nr = sda->index; |
330 | 330 | ||
331 | return sprintf(buf, "%u\n", | 331 | return sprintf(buf, "%u\n", |
@@ -336,7 +336,7 @@ static ssize_t show_in8(struct device *dev, struct device_attribute *attr, | |||
336 | static ssize_t store_in8(struct device *dev, struct device_attribute *attr, | 336 | static ssize_t store_in8(struct device *dev, struct device_attribute *attr, |
337 | const char *buf, size_t count) | 337 | const char *buf, size_t count) |
338 | { | 338 | { |
339 | SETUP_STORE_data_param(dev, attr); | 339 | SETUP_STORE_DATA_PARAM(dev, attr); |
340 | long reqval; | 340 | long reqval; |
341 | u8 nr = sda->index; | 341 | u8 nr = sda->index; |
342 | 342 | ||
@@ -360,7 +360,7 @@ static ssize_t store_in8(struct device *dev, struct device_attribute *attr, | |||
360 | static ssize_t show_temp8(struct device *dev, | 360 | static ssize_t show_temp8(struct device *dev, |
361 | struct device_attribute *attr, char *buf) | 361 | struct device_attribute *attr, char *buf) |
362 | { | 362 | { |
363 | SETUP_SHOW_data_param(dev, attr); | 363 | SETUP_SHOW_DATA_PARAM(dev, attr); |
364 | 364 | ||
365 | return sprintf(buf, "%d\n", ((s8) data->reg[param->msb[0]]) * 1000); | 365 | return sprintf(buf, "%d\n", ((s8) data->reg[param->msb[0]]) * 1000); |
366 | } | 366 | } |
@@ -369,7 +369,7 @@ static ssize_t store_temp8(struct device *dev, | |||
369 | struct device_attribute *attr, const char *buf, | 369 | struct device_attribute *attr, const char *buf, |
370 | size_t count) | 370 | size_t count) |
371 | { | 371 | { |
372 | SETUP_STORE_data_param(dev, attr); | 372 | SETUP_STORE_DATA_PARAM(dev, attr); |
373 | long reqval; | 373 | long reqval; |
374 | s8 temp; | 374 | s8 temp; |
375 | 375 | ||
@@ -397,7 +397,7 @@ static ssize_t store_temp8(struct device *dev, | |||
397 | static ssize_t show_temp10(struct device *dev, | 397 | static ssize_t show_temp10(struct device *dev, |
398 | struct device_attribute *attr, char *buf) | 398 | struct device_attribute *attr, char *buf) |
399 | { | 399 | { |
400 | SETUP_SHOW_data_param(dev, attr); | 400 | SETUP_SHOW_DATA_PARAM(dev, attr); |
401 | u8 msb, lsb; | 401 | u8 msb, lsb; |
402 | int temp; | 402 | int temp; |
403 | 403 | ||
@@ -414,7 +414,7 @@ static ssize_t show_temp10(struct device *dev, | |||
414 | static ssize_t show_temp62(struct device *dev, | 414 | static ssize_t show_temp62(struct device *dev, |
415 | struct device_attribute *attr, char *buf) | 415 | struct device_attribute *attr, char *buf) |
416 | { | 416 | { |
417 | SETUP_SHOW_data_param(dev, attr); | 417 | SETUP_SHOW_DATA_PARAM(dev, attr); |
418 | u8 regval = data->reg[param->msb[0]]; | 418 | u8 regval = data->reg[param->msb[0]]; |
419 | int temp = ((s8) (regval & 0xfc) * 1000) + ((regval & 0x03) * 250); | 419 | int temp = ((s8) (regval & 0xfc) * 1000) + ((regval & 0x03) * 250); |
420 | 420 | ||
@@ -425,7 +425,7 @@ static ssize_t store_temp62(struct device *dev, | |||
425 | struct device_attribute *attr, const char *buf, | 425 | struct device_attribute *attr, const char *buf, |
426 | size_t count) | 426 | size_t count) |
427 | { | 427 | { |
428 | SETUP_STORE_data_param(dev, attr); | 428 | SETUP_STORE_DATA_PARAM(dev, attr); |
429 | long reqval, i, f; | 429 | long reqval, i, f; |
430 | s8 temp; | 430 | s8 temp; |
431 | 431 | ||
@@ -459,7 +459,7 @@ static u32 asc7621_range_map[] = { | |||
459 | static ssize_t show_ap2_temp(struct device *dev, | 459 | static ssize_t show_ap2_temp(struct device *dev, |
460 | struct device_attribute *attr, char *buf) | 460 | struct device_attribute *attr, char *buf) |
461 | { | 461 | { |
462 | SETUP_SHOW_data_param(dev, attr); | 462 | SETUP_SHOW_DATA_PARAM(dev, attr); |
463 | long auto_point1; | 463 | long auto_point1; |
464 | u8 regval; | 464 | u8 regval; |
465 | int temp; | 465 | int temp; |
@@ -479,7 +479,7 @@ static ssize_t store_ap2_temp(struct device *dev, | |||
479 | struct device_attribute *attr, | 479 | struct device_attribute *attr, |
480 | const char *buf, size_t count) | 480 | const char *buf, size_t count) |
481 | { | 481 | { |
482 | SETUP_STORE_data_param(dev, attr); | 482 | SETUP_STORE_DATA_PARAM(dev, attr); |
483 | long reqval, auto_point1; | 483 | long reqval, auto_point1; |
484 | int i; | 484 | int i; |
485 | u8 currval, newval = 0; | 485 | u8 currval, newval = 0; |
@@ -510,7 +510,7 @@ static ssize_t store_ap2_temp(struct device *dev, | |||
510 | static ssize_t show_pwm_ac(struct device *dev, | 510 | static ssize_t show_pwm_ac(struct device *dev, |
511 | struct device_attribute *attr, char *buf) | 511 | struct device_attribute *attr, char *buf) |
512 | { | 512 | { |
513 | SETUP_SHOW_data_param(dev, attr); | 513 | SETUP_SHOW_DATA_PARAM(dev, attr); |
514 | u8 config, altbit, regval; | 514 | u8 config, altbit, regval; |
515 | u8 map[] = { | 515 | u8 map[] = { |
516 | 0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10, | 516 | 0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10, |
@@ -530,7 +530,7 @@ static ssize_t store_pwm_ac(struct device *dev, | |||
530 | struct device_attribute *attr, | 530 | struct device_attribute *attr, |
531 | const char *buf, size_t count) | 531 | const char *buf, size_t count) |
532 | { | 532 | { |
533 | SETUP_STORE_data_param(dev, attr); | 533 | SETUP_STORE_DATA_PARAM(dev, attr); |
534 | unsigned long reqval; | 534 | unsigned long reqval; |
535 | u8 currval, config, altbit, newval; | 535 | u8 currval, config, altbit, newval; |
536 | u16 map[] = { | 536 | u16 map[] = { |
@@ -569,7 +569,7 @@ static ssize_t store_pwm_ac(struct device *dev, | |||
569 | static ssize_t show_pwm_enable(struct device *dev, | 569 | static ssize_t show_pwm_enable(struct device *dev, |
570 | struct device_attribute *attr, char *buf) | 570 | struct device_attribute *attr, char *buf) |
571 | { | 571 | { |
572 | SETUP_SHOW_data_param(dev, attr); | 572 | SETUP_SHOW_DATA_PARAM(dev, attr); |
573 | u8 config, altbit, minoff, val, newval; | 573 | u8 config, altbit, minoff, val, newval; |
574 | 574 | ||
575 | mutex_lock(&data->update_lock); | 575 | mutex_lock(&data->update_lock); |
@@ -599,7 +599,7 @@ static ssize_t store_pwm_enable(struct device *dev, | |||
599 | struct device_attribute *attr, | 599 | struct device_attribute *attr, |
600 | const char *buf, size_t count) | 600 | const char *buf, size_t count) |
601 | { | 601 | { |
602 | SETUP_STORE_data_param(dev, attr); | 602 | SETUP_STORE_DATA_PARAM(dev, attr); |
603 | long reqval; | 603 | long reqval; |
604 | u8 currval, config, altbit, newval, minoff = 255; | 604 | u8 currval, config, altbit, newval, minoff = 255; |
605 | 605 | ||
@@ -659,7 +659,7 @@ static u32 asc7621_pwm_freq_map[] = { | |||
659 | static ssize_t show_pwm_freq(struct device *dev, | 659 | static ssize_t show_pwm_freq(struct device *dev, |
660 | struct device_attribute *attr, char *buf) | 660 | struct device_attribute *attr, char *buf) |
661 | { | 661 | { |
662 | SETUP_SHOW_data_param(dev, attr); | 662 | SETUP_SHOW_DATA_PARAM(dev, attr); |
663 | u8 regval = | 663 | u8 regval = |
664 | (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]; | 664 | (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]; |
665 | 665 | ||
@@ -672,7 +672,7 @@ static ssize_t store_pwm_freq(struct device *dev, | |||
672 | struct device_attribute *attr, | 672 | struct device_attribute *attr, |
673 | const char *buf, size_t count) | 673 | const char *buf, size_t count) |
674 | { | 674 | { |
675 | SETUP_STORE_data_param(dev, attr); | 675 | SETUP_STORE_DATA_PARAM(dev, attr); |
676 | unsigned long reqval; | 676 | unsigned long reqval; |
677 | u8 currval, newval = 255; | 677 | u8 currval, newval = 255; |
678 | int i; | 678 | int i; |
@@ -707,7 +707,7 @@ static u32 asc7621_pwm_auto_spinup_map[] = { | |||
707 | static ssize_t show_pwm_ast(struct device *dev, | 707 | static ssize_t show_pwm_ast(struct device *dev, |
708 | struct device_attribute *attr, char *buf) | 708 | struct device_attribute *attr, char *buf) |
709 | { | 709 | { |
710 | SETUP_SHOW_data_param(dev, attr); | 710 | SETUP_SHOW_DATA_PARAM(dev, attr); |
711 | u8 regval = | 711 | u8 regval = |
712 | (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]; | 712 | (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]; |
713 | 713 | ||
@@ -721,7 +721,7 @@ static ssize_t store_pwm_ast(struct device *dev, | |||
721 | struct device_attribute *attr, | 721 | struct device_attribute *attr, |
722 | const char *buf, size_t count) | 722 | const char *buf, size_t count) |
723 | { | 723 | { |
724 | SETUP_STORE_data_param(dev, attr); | 724 | SETUP_STORE_DATA_PARAM(dev, attr); |
725 | long reqval; | 725 | long reqval; |
726 | u8 currval, newval = 255; | 726 | u8 currval, newval = 255; |
727 | u32 i; | 727 | u32 i; |
@@ -756,7 +756,7 @@ static u32 asc7621_temp_smoothing_time_map[] = { | |||
756 | static ssize_t show_temp_st(struct device *dev, | 756 | static ssize_t show_temp_st(struct device *dev, |
757 | struct device_attribute *attr, char *buf) | 757 | struct device_attribute *attr, char *buf) |
758 | { | 758 | { |
759 | SETUP_SHOW_data_param(dev, attr); | 759 | SETUP_SHOW_DATA_PARAM(dev, attr); |
760 | u8 regval = | 760 | u8 regval = |
761 | (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]; | 761 | (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]; |
762 | regval = clamp_val(regval, 0, 7); | 762 | regval = clamp_val(regval, 0, 7); |
@@ -768,7 +768,7 @@ static ssize_t store_temp_st(struct device *dev, | |||
768 | struct device_attribute *attr, | 768 | struct device_attribute *attr, |
769 | const char *buf, size_t count) | 769 | const char *buf, size_t count) |
770 | { | 770 | { |
771 | SETUP_STORE_data_param(dev, attr); | 771 | SETUP_STORE_DATA_PARAM(dev, attr); |
772 | long reqval; | 772 | long reqval; |
773 | u8 currval, newval = 255; | 773 | u8 currval, newval = 255; |
774 | u32 i; | 774 | u32 i; |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 3f1e297663ad..658ce3a8717f 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -411,8 +411,7 @@ static int __cpuinit chk_ucode_version(unsigned int cpu) | |||
411 | * fixed for stepping D0 (6EC). | 411 | * fixed for stepping D0 (6EC). |
412 | */ | 412 | */ |
413 | if (c->x86_model == 0xe && c->x86_mask < 0xc && c->microcode < 0x39) { | 413 | if (c->x86_model == 0xe && c->x86_mask < 0xc && c->microcode < 0x39) { |
414 | pr_err("Errata AE18 not fixed, update BIOS or " | 414 | pr_err("Errata AE18 not fixed, update BIOS or microcode of the CPU!\n"); |
415 | "microcode of the CPU!\n"); | ||
416 | return -ENODEV; | 415 | return -ENODEV; |
417 | } | 416 | } |
418 | return 0; | 417 | return 0; |
diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c index ab4452c5a98c..960fac3fb166 100644 --- a/drivers/hwmon/da9052-hwmon.c +++ b/drivers/hwmon/da9052-hwmon.c | |||
@@ -43,19 +43,19 @@ static const char * const input_names[] = { | |||
43 | }; | 43 | }; |
44 | 44 | ||
45 | /* Conversion function for VDDOUT and VBAT */ | 45 | /* Conversion function for VDDOUT and VBAT */ |
46 | static inline int volt_reg_to_mV(int value) | 46 | static inline int volt_reg_to_mv(int value) |
47 | { | 47 | { |
48 | return DIV_ROUND_CLOSEST(value * 1000, 512) + 2500; | 48 | return DIV_ROUND_CLOSEST(value * 1000, 512) + 2500; |
49 | } | 49 | } |
50 | 50 | ||
51 | /* Conversion function for ADC channels 4, 5 and 6 */ | 51 | /* Conversion function for ADC channels 4, 5 and 6 */ |
52 | static inline int input_reg_to_mV(int value) | 52 | static inline int input_reg_to_mv(int value) |
53 | { | 53 | { |
54 | return DIV_ROUND_CLOSEST(value * 2500, 1023); | 54 | return DIV_ROUND_CLOSEST(value * 2500, 1023); |
55 | } | 55 | } |
56 | 56 | ||
57 | /* Conversion function for VBBAT */ | 57 | /* Conversion function for VBBAT */ |
58 | static inline int vbbat_reg_to_mV(int value) | 58 | static inline int vbbat_reg_to_mv(int value) |
59 | { | 59 | { |
60 | return DIV_ROUND_CLOSEST(value * 2500, 512); | 60 | return DIV_ROUND_CLOSEST(value * 2500, 512); |
61 | } | 61 | } |
@@ -96,7 +96,7 @@ static ssize_t da9052_read_vddout(struct device *dev, | |||
96 | goto hwmon_err; | 96 | goto hwmon_err; |
97 | 97 | ||
98 | mutex_unlock(&hwmon->hwmon_lock); | 98 | mutex_unlock(&hwmon->hwmon_lock); |
99 | return sprintf(buf, "%d\n", volt_reg_to_mV(vdd)); | 99 | return sprintf(buf, "%d\n", volt_reg_to_mv(vdd)); |
100 | 100 | ||
101 | hwmon_err_release: | 101 | hwmon_err_release: |
102 | da9052_disable_vddout_channel(hwmon->da9052); | 102 | da9052_disable_vddout_channel(hwmon->da9052); |
@@ -137,7 +137,7 @@ static ssize_t da9052_read_vbat(struct device *dev, | |||
137 | if (ret < 0) | 137 | if (ret < 0) |
138 | return ret; | 138 | return ret; |
139 | 139 | ||
140 | return sprintf(buf, "%d\n", volt_reg_to_mV(ret)); | 140 | return sprintf(buf, "%d\n", volt_reg_to_mv(ret)); |
141 | } | 141 | } |
142 | 142 | ||
143 | static ssize_t da9052_read_misc_channel(struct device *dev, | 143 | static ssize_t da9052_read_misc_channel(struct device *dev, |
@@ -152,7 +152,7 @@ static ssize_t da9052_read_misc_channel(struct device *dev, | |||
152 | if (ret < 0) | 152 | if (ret < 0) |
153 | return ret; | 153 | return ret; |
154 | 154 | ||
155 | return sprintf(buf, "%d\n", input_reg_to_mV(ret)); | 155 | return sprintf(buf, "%d\n", input_reg_to_mv(ret)); |
156 | } | 156 | } |
157 | 157 | ||
158 | static ssize_t da9052_read_tjunc(struct device *dev, | 158 | static ssize_t da9052_read_tjunc(struct device *dev, |
@@ -187,7 +187,7 @@ static ssize_t da9052_read_vbbat(struct device *dev, | |||
187 | if (ret < 0) | 187 | if (ret < 0) |
188 | return ret; | 188 | return ret; |
189 | 189 | ||
190 | return sprintf(buf, "%d\n", vbbat_reg_to_mV(ret)); | 190 | return sprintf(buf, "%d\n", vbbat_reg_to_mv(ret)); |
191 | } | 191 | } |
192 | 192 | ||
193 | static ssize_t da9052_hwmon_show_name(struct device *dev, | 193 | static ssize_t da9052_hwmon_show_name(struct device *dev, |
diff --git a/drivers/hwmon/da9055-hwmon.c b/drivers/hwmon/da9055-hwmon.c index 9465c050c326..029ecabc4380 100644 --- a/drivers/hwmon/da9055-hwmon.c +++ b/drivers/hwmon/da9055-hwmon.c | |||
@@ -119,7 +119,7 @@ static irqreturn_t da9055_auxadc_irq(int irq, void *irq_data) | |||
119 | } | 119 | } |
120 | 120 | ||
121 | /* Conversion function for VSYS and ADCINx */ | 121 | /* Conversion function for VSYS and ADCINx */ |
122 | static inline int volt_reg_to_mV(int value, int channel) | 122 | static inline int volt_reg_to_mv(int value, int channel) |
123 | { | 123 | { |
124 | if (channel == DA9055_ADC_VSYS) | 124 | if (channel == DA9055_ADC_VSYS) |
125 | return DIV_ROUND_CLOSEST(value * 1000, DA9055_VSYS_DIV) + 2500; | 125 | return DIV_ROUND_CLOSEST(value * 1000, DA9055_VSYS_DIV) + 2500; |
@@ -168,7 +168,7 @@ static ssize_t da9055_read_auto_ch(struct device *dev, | |||
168 | 168 | ||
169 | mutex_unlock(&hwmon->hwmon_lock); | 169 | mutex_unlock(&hwmon->hwmon_lock); |
170 | 170 | ||
171 | return sprintf(buf, "%d\n", volt_reg_to_mV(adc, channel)); | 171 | return sprintf(buf, "%d\n", volt_reg_to_mv(adc, channel)); |
172 | 172 | ||
173 | hwmon_err_release: | 173 | hwmon_err_release: |
174 | da9055_disable_auto_mode(hwmon->da9055, channel); | 174 | da9055_disable_auto_mode(hwmon->da9055, channel); |
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index c347c94f2f73..4ae3fff13f44 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
@@ -55,14 +55,16 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); | |||
55 | 55 | ||
56 | static bool probe_all_addr; | 56 | static bool probe_all_addr; |
57 | module_param(probe_all_addr, bool, 0); | 57 | module_param(probe_all_addr, bool, 0); |
58 | MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC " | 58 | MODULE_PARM_DESC(probe_all_addr, |
59 | "addresses"); | 59 | "Include probing of non-standard LPC addresses"); |
60 | 60 | ||
61 | /* Addresses to scan */ | 61 | /* Addresses to scan */ |
62 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; | 62 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; |
63 | 63 | ||
64 | enum chips { dme1737, sch5027, sch311x, sch5127 }; | 64 | enum chips { dme1737, sch5027, sch311x, sch5127 }; |
65 | 65 | ||
66 | #define DO_REPORT "Please report to the driver maintainer." | ||
67 | |||
66 | /* --------------------------------------------------------------------- | 68 | /* --------------------------------------------------------------------- |
67 | * Registers | 69 | * Registers |
68 | * | 70 | * |
@@ -566,9 +568,9 @@ static u8 dme1737_read(const struct dme1737_data *data, u8 reg) | |||
566 | val = i2c_smbus_read_byte_data(client, reg); | 568 | val = i2c_smbus_read_byte_data(client, reg); |
567 | 569 | ||
568 | if (val < 0) { | 570 | if (val < 0) { |
569 | dev_warn(&client->dev, "Read from register " | 571 | dev_warn(&client->dev, |
570 | "0x%02x failed! Please report to the driver " | 572 | "Read from register 0x%02x failed! %s\n", |
571 | "maintainer.\n", reg); | 573 | reg, DO_REPORT); |
572 | } | 574 | } |
573 | } else { /* ISA device */ | 575 | } else { /* ISA device */ |
574 | outb(reg, data->addr); | 576 | outb(reg, data->addr); |
@@ -587,9 +589,9 @@ static s32 dme1737_write(const struct dme1737_data *data, u8 reg, u8 val) | |||
587 | res = i2c_smbus_write_byte_data(client, reg, val); | 589 | res = i2c_smbus_write_byte_data(client, reg, val); |
588 | 590 | ||
589 | if (res < 0) { | 591 | if (res < 0) { |
590 | dev_warn(&client->dev, "Write to register " | 592 | dev_warn(&client->dev, |
591 | "0x%02x failed! Please report to the driver " | 593 | "Write to register 0x%02x failed! %s\n", |
592 | "maintainer.\n", reg); | 594 | reg, DO_REPORT); |
593 | } | 595 | } |
594 | } else { /* ISA device */ | 596 | } else { /* ISA device */ |
595 | outb(reg, data->addr); | 597 | outb(reg, data->addr); |
@@ -1167,8 +1169,8 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | |||
1167 | /* Only valid for fan[1-4] */ | 1169 | /* Only valid for fan[1-4] */ |
1168 | if (!(val == 1 || val == 2 || val == 4)) { | 1170 | if (!(val == 1 || val == 2 || val == 4)) { |
1169 | count = -EINVAL; | 1171 | count = -EINVAL; |
1170 | dev_warn(dev, "Fan type value %ld not " | 1172 | dev_warn(dev, |
1171 | "supported. Choose one of 1, 2, or 4.\n", | 1173 | "Fan type value %ld not supported. Choose one of 1, 2, or 4.\n", |
1172 | val); | 1174 | val); |
1173 | goto exit; | 1175 | goto exit; |
1174 | } | 1176 | } |
@@ -1294,8 +1296,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1294 | /* Only valid for pwm[1-3] */ | 1296 | /* Only valid for pwm[1-3] */ |
1295 | if (val < 0 || val > 2) { | 1297 | if (val < 0 || val > 2) { |
1296 | count = -EINVAL; | 1298 | count = -EINVAL; |
1297 | dev_warn(dev, "PWM enable %ld not " | 1299 | dev_warn(dev, |
1298 | "supported. Choose one of 0, 1, or 2.\n", | 1300 | "PWM enable %ld not supported. Choose one of 0, 1, or 2.\n", |
1299 | val); | 1301 | val); |
1300 | goto exit; | 1302 | goto exit; |
1301 | } | 1303 | } |
@@ -1399,8 +1401,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1399 | if (!(val == 1 || val == 2 || val == 4 || | 1401 | if (!(val == 1 || val == 2 || val == 4 || |
1400 | val == 6 || val == 7)) { | 1402 | val == 6 || val == 7)) { |
1401 | count = -EINVAL; | 1403 | count = -EINVAL; |
1402 | dev_warn(dev, "PWM auto channels zone %ld " | 1404 | dev_warn(dev, |
1403 | "not supported. Choose one of 1, 2, 4, 6, " | 1405 | "PWM auto channels zone %ld not supported. Choose one of 1, 2, 4, 6, " |
1404 | "or 7.\n", val); | 1406 | "or 7.\n", val); |
1405 | goto exit; | 1407 | goto exit; |
1406 | } | 1408 | } |
@@ -2178,8 +2180,8 @@ static int dme1737_create_files(struct device *dev) | |||
2178 | * selected attributes from read-only to read-writeable. | 2180 | * selected attributes from read-only to read-writeable. |
2179 | */ | 2181 | */ |
2180 | if (data->config & 0x02) { | 2182 | if (data->config & 0x02) { |
2181 | dev_info(dev, "Device is locked. Some attributes " | 2183 | dev_info(dev, |
2182 | "will be read-only.\n"); | 2184 | "Device is locked. Some attributes will be read-only.\n"); |
2183 | } else { | 2185 | } else { |
2184 | /* Change permissions of zone sysfs attributes */ | 2186 | /* Change permissions of zone sysfs attributes */ |
2185 | dme1737_chmod_group(dev, &dme1737_zone_chmod_group, | 2187 | dme1737_chmod_group(dev, &dme1737_zone_chmod_group, |
@@ -2247,9 +2249,8 @@ static int dme1737_init_device(struct device *dev) | |||
2247 | /* Inform if part is not monitoring/started */ | 2249 | /* Inform if part is not monitoring/started */ |
2248 | if (!(data->config & 0x01)) { | 2250 | if (!(data->config & 0x01)) { |
2249 | if (!force_start) { | 2251 | if (!force_start) { |
2250 | dev_err(dev, "Device is not monitoring. " | 2252 | dev_err(dev, |
2251 | "Use the force_start load parameter to " | 2253 | "Device is not monitoring. Use the force_start load parameter to override.\n"); |
2252 | "override.\n"); | ||
2253 | return -EFAULT; | 2254 | return -EFAULT; |
2254 | } | 2255 | } |
2255 | 2256 | ||
@@ -2289,8 +2290,8 @@ static int dme1737_init_device(struct device *dev) | |||
2289 | */ | 2290 | */ |
2290 | if (dme1737_i2c_get_features(0x2e, data) && | 2291 | if (dme1737_i2c_get_features(0x2e, data) && |
2291 | dme1737_i2c_get_features(0x4e, data)) { | 2292 | dme1737_i2c_get_features(0x4e, data)) { |
2292 | dev_warn(dev, "Failed to query Super-IO for optional " | 2293 | dev_warn(dev, |
2293 | "features.\n"); | 2294 | "Failed to query Super-IO for optional features.\n"); |
2294 | } | 2295 | } |
2295 | } | 2296 | } |
2296 | 2297 | ||
@@ -2317,8 +2318,8 @@ static int dme1737_init_device(struct device *dev) | |||
2317 | break; | 2318 | break; |
2318 | } | 2319 | } |
2319 | 2320 | ||
2320 | dev_info(dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " | 2321 | dev_info(dev, |
2321 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", | 2322 | "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", |
2322 | (data->has_features & HAS_PWM(2)) ? "yes" : "no", | 2323 | (data->has_features & HAS_PWM(2)) ? "yes" : "no", |
2323 | (data->has_features & HAS_PWM(4)) ? "yes" : "no", | 2324 | (data->has_features & HAS_PWM(4)) ? "yes" : "no", |
2324 | (data->has_features & HAS_PWM(5)) ? "yes" : "no", | 2325 | (data->has_features & HAS_PWM(5)) ? "yes" : "no", |
@@ -2330,18 +2331,16 @@ static int dme1737_init_device(struct device *dev) | |||
2330 | reg = dme1737_read(data, DME1737_REG_TACH_PWM); | 2331 | reg = dme1737_read(data, DME1737_REG_TACH_PWM); |
2331 | /* Inform if fan-to-pwm mapping differs from the default */ | 2332 | /* Inform if fan-to-pwm mapping differs from the default */ |
2332 | if (client && reg != 0xa4) { /* I2C chip */ | 2333 | if (client && reg != 0xa4) { /* I2C chip */ |
2333 | dev_warn(dev, "Non-standard fan to pwm mapping: " | 2334 | dev_warn(dev, |
2334 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " | 2335 | "Non-standard fan to pwm mapping: fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, fan4->pwm%d. %s\n", |
2335 | "fan4->pwm%d. Please report to the driver " | ||
2336 | "maintainer.\n", | ||
2337 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, | 2336 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, |
2338 | ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); | 2337 | ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1, |
2338 | DO_REPORT); | ||
2339 | } else if (!client && reg != 0x24) { /* ISA chip */ | 2339 | } else if (!client && reg != 0x24) { /* ISA chip */ |
2340 | dev_warn(dev, "Non-standard fan to pwm mapping: " | 2340 | dev_warn(dev, |
2341 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. " | 2341 | "Non-standard fan to pwm mapping: fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. %s\n", |
2342 | "Please report to the driver maintainer.\n", | ||
2343 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, | 2342 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, |
2344 | ((reg >> 4) & 0x03) + 1); | 2343 | ((reg >> 4) & 0x03) + 1, DO_REPORT); |
2345 | } | 2344 | } |
2346 | 2345 | ||
2347 | /* | 2346 | /* |
@@ -2355,8 +2354,9 @@ static int dme1737_init_device(struct device *dev) | |||
2355 | DME1737_REG_PWM_CONFIG(ix)); | 2354 | DME1737_REG_PWM_CONFIG(ix)); |
2356 | if ((data->has_features & HAS_PWM(ix)) && | 2355 | if ((data->has_features & HAS_PWM(ix)) && |
2357 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { | 2356 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { |
2358 | dev_info(dev, "Switching pwm%d to " | 2357 | dev_info(dev, |
2359 | "manual mode.\n", ix + 1); | 2358 | "Switching pwm%d to manual mode.\n", |
2359 | ix + 1); | ||
2360 | data->pwm_config[ix] = PWM_EN_TO_REG(1, | 2360 | data->pwm_config[ix] = PWM_EN_TO_REG(1, |
2361 | data->pwm_config[ix]); | 2361 | data->pwm_config[ix]); |
2362 | dme1737_write(data, DME1737_REG_PWM(ix), 0); | 2362 | dme1737_write(data, DME1737_REG_PWM(ix), 0); |
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index a9816979c5de..0c9f3da242bf 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c | |||
@@ -1350,8 +1350,7 @@ static void f71805f_init_device(struct f71805f_data *data) | |||
1350 | 1350 | ||
1351 | reg = f71805f_read8(data, F71805F_REG_START); | 1351 | reg = f71805f_read8(data, F71805F_REG_START); |
1352 | if ((reg & 0x41) != 0x01) { | 1352 | if ((reg & 0x41) != 0x01) { |
1353 | printk(KERN_DEBUG DRVNAME ": Starting monitoring " | 1353 | pr_debug("Starting monitoring operations\n"); |
1354 | "operations\n"); | ||
1355 | f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40); | 1354 | f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40); |
1356 | } | 1355 | } |
1357 | 1356 | ||
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index b757088aeddb..dff841085baf 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c | |||
@@ -189,8 +189,8 @@ static void fam15h_power_init_data(struct pci_dev *f4, | |||
189 | 189 | ||
190 | /* result not allowed to be >= 256W */ | 190 | /* result not allowed to be >= 256W */ |
191 | if ((tmp >> 16) >= 256) | 191 | if ((tmp >> 16) >= 256) |
192 | dev_warn(&f4->dev, "Bogus value for ProcessorPwrWatts " | 192 | dev_warn(&f4->dev, |
193 | "(processor_pwr_watts>=%u)\n", | 193 | "Bogus value for ProcessorPwrWatts (processor_pwr_watts>=%u)\n", |
194 | (unsigned int) (tmp >> 16)); | 194 | (unsigned int) (tmp >> 16)); |
195 | 195 | ||
196 | /* convert to microWatt */ | 196 | /* convert to microWatt */ |
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index 8af2755cdb87..d58abdc5a4cf 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c | |||
@@ -463,8 +463,9 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute | |||
463 | v = 3; | 463 | v = 3; |
464 | break; | 464 | break; |
465 | default: | 465 | default: |
466 | dev_err(dev, "fan_div value %lu not supported. " | 466 | dev_err(dev, |
467 | "Choose one of 2, 4 or 8!\n", v); | 467 | "fan_div value %lu not supported. Choose one of 2, 4 or 8!\n", |
468 | v); | ||
468 | return -EINVAL; | 469 | return -EINVAL; |
469 | } | 470 | } |
470 | 471 | ||
@@ -1249,8 +1250,8 @@ static int fschmd_probe(struct i2c_client *client, | |||
1249 | } | 1250 | } |
1250 | if (i == ARRAY_SIZE(watchdog_minors)) { | 1251 | if (i == ARRAY_SIZE(watchdog_minors)) { |
1251 | data->watchdog_miscdev.minor = 0; | 1252 | data->watchdog_miscdev.minor = 0; |
1252 | dev_warn(&client->dev, "Couldn't register watchdog chardev " | 1253 | dev_warn(&client->dev, |
1253 | "(due to no free minor)\n"); | 1254 | "Couldn't register watchdog chardev (due to no free minor)\n"); |
1254 | } | 1255 | } |
1255 | mutex_unlock(&watchdog_data_mutex); | 1256 | mutex_unlock(&watchdog_data_mutex); |
1256 | 1257 | ||
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index e2e5909a34df..95257a5621d8 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c | |||
@@ -344,8 +344,9 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
344 | val = 3; | 344 | val = 3; |
345 | break; | 345 | break; |
346 | default: | 346 | default: |
347 | dev_err(dev, "Invalid fan clock divider %lu, choose one " | 347 | dev_err(dev, |
348 | "of 1, 2, 4 or 8\n", val); | 348 | "Invalid fan clock divider %lu, choose one of 1, 2, 4 or 8\n", |
349 | val); | ||
349 | return -EINVAL; | 350 | return -EINVAL; |
350 | } | 351 | } |
351 | 352 | ||
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 39781945a5d2..3104149795c5 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c | |||
@@ -105,10 +105,6 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, | |||
105 | if (err) | 105 | if (err) |
106 | return err; | 106 | return err; |
107 | 107 | ||
108 | err = device_create_file(&pdev->dev, &dev_attr_fan1_alarm); | ||
109 | if (err) | ||
110 | return err; | ||
111 | |||
112 | /* | 108 | /* |
113 | * If the alarm GPIO don't support interrupts, just leave | 109 | * If the alarm GPIO don't support interrupts, just leave |
114 | * without initializing the fail notification support. | 110 | * without initializing the fail notification support. |
@@ -121,23 +117,9 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, | |||
121 | irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH); | 117 | irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH); |
122 | err = devm_request_irq(&pdev->dev, alarm_irq, fan_alarm_irq_handler, | 118 | err = devm_request_irq(&pdev->dev, alarm_irq, fan_alarm_irq_handler, |
123 | IRQF_SHARED, "GPIO fan alarm", fan_data); | 119 | IRQF_SHARED, "GPIO fan alarm", fan_data); |
124 | if (err) | ||
125 | goto err_free_sysfs; | ||
126 | |||
127 | return 0; | ||
128 | |||
129 | err_free_sysfs: | ||
130 | device_remove_file(&pdev->dev, &dev_attr_fan1_alarm); | ||
131 | return err; | 120 | return err; |
132 | } | 121 | } |
133 | 122 | ||
134 | static void fan_alarm_free(struct gpio_fan_data *fan_data) | ||
135 | { | ||
136 | struct platform_device *pdev = fan_data->pdev; | ||
137 | |||
138 | device_remove_file(&pdev->dev, &dev_attr_fan1_alarm); | ||
139 | } | ||
140 | |||
141 | /* | 123 | /* |
142 | * Control GPIOs. | 124 | * Control GPIOs. |
143 | */ | 125 | */ |
@@ -327,6 +309,12 @@ exit_unlock: | |||
327 | return ret; | 309 | return ret; |
328 | } | 310 | } |
329 | 311 | ||
312 | static ssize_t show_name(struct device *dev, | ||
313 | struct device_attribute *attr, char *buf) | ||
314 | { | ||
315 | return sprintf(buf, "gpio-fan\n"); | ||
316 | } | ||
317 | |||
330 | static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm); | 318 | static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm); |
331 | static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, | 319 | static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, |
332 | show_pwm_enable, set_pwm_enable); | 320 | show_pwm_enable, set_pwm_enable); |
@@ -336,8 +324,26 @@ static DEVICE_ATTR(fan1_max, S_IRUGO, show_rpm_max, NULL); | |||
336 | static DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, NULL); | 324 | static DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, NULL); |
337 | static DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, show_rpm, set_rpm); | 325 | static DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, show_rpm, set_rpm); |
338 | 326 | ||
339 | static struct attribute *gpio_fan_ctrl_attributes[] = { | 327 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
340 | &dev_attr_pwm1.attr, | 328 | |
329 | static umode_t gpio_fan_is_visible(struct kobject *kobj, | ||
330 | struct attribute *attr, int index) | ||
331 | { | ||
332 | struct device *dev = container_of(kobj, struct device, kobj); | ||
333 | struct gpio_fan_data *data = dev_get_drvdata(dev); | ||
334 | |||
335 | if (index == 1 && !data->alarm) | ||
336 | return 0; | ||
337 | if (index > 1 && !data->ctrl) | ||
338 | return 0; | ||
339 | |||
340 | return attr->mode; | ||
341 | } | ||
342 | |||
343 | static struct attribute *gpio_fan_attributes[] = { | ||
344 | &dev_attr_name.attr, | ||
345 | &dev_attr_fan1_alarm.attr, /* 1 */ | ||
346 | &dev_attr_pwm1.attr, /* 2 */ | ||
341 | &dev_attr_pwm1_enable.attr, | 347 | &dev_attr_pwm1_enable.attr, |
342 | &dev_attr_pwm1_mode.attr, | 348 | &dev_attr_pwm1_mode.attr, |
343 | &dev_attr_fan1_input.attr, | 349 | &dev_attr_fan1_input.attr, |
@@ -347,8 +353,9 @@ static struct attribute *gpio_fan_ctrl_attributes[] = { | |||
347 | NULL | 353 | NULL |
348 | }; | 354 | }; |
349 | 355 | ||
350 | static const struct attribute_group gpio_fan_ctrl_group = { | 356 | static const struct attribute_group gpio_fan_group = { |
351 | .attrs = gpio_fan_ctrl_attributes, | 357 | .attrs = gpio_fan_attributes, |
358 | .is_visible = gpio_fan_is_visible, | ||
352 | }; | 359 | }; |
353 | 360 | ||
354 | static int fan_ctrl_init(struct gpio_fan_data *fan_data, | 361 | static int fan_ctrl_init(struct gpio_fan_data *fan_data, |
@@ -379,30 +386,9 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, | |||
379 | if (fan_data->speed_index < 0) | 386 | if (fan_data->speed_index < 0) |
380 | return -ENODEV; | 387 | return -ENODEV; |
381 | 388 | ||
382 | err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); | 389 | return 0; |
383 | return err; | ||
384 | } | ||
385 | |||
386 | static void fan_ctrl_free(struct gpio_fan_data *fan_data) | ||
387 | { | ||
388 | struct platform_device *pdev = fan_data->pdev; | ||
389 | |||
390 | sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); | ||
391 | } | ||
392 | |||
393 | /* | ||
394 | * Platform driver. | ||
395 | */ | ||
396 | |||
397 | static ssize_t show_name(struct device *dev, | ||
398 | struct device_attribute *attr, char *buf) | ||
399 | { | ||
400 | return sprintf(buf, "gpio-fan\n"); | ||
401 | } | 390 | } |
402 | 391 | ||
403 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
404 | |||
405 | |||
406 | #ifdef CONFIG_OF_GPIO | 392 | #ifdef CONFIG_OF_GPIO |
407 | /* | 393 | /* |
408 | * Translate OpenFirmware node properties into platform_data | 394 | * Translate OpenFirmware node properties into platform_data |
@@ -546,38 +532,30 @@ static int gpio_fan_probe(struct platform_device *pdev) | |||
546 | 532 | ||
547 | /* Configure control GPIOs if available. */ | 533 | /* Configure control GPIOs if available. */ |
548 | if (pdata->ctrl && pdata->num_ctrl > 0) { | 534 | if (pdata->ctrl && pdata->num_ctrl > 0) { |
549 | if (!pdata->speed || pdata->num_speed <= 1) { | 535 | if (!pdata->speed || pdata->num_speed <= 1) |
550 | err = -EINVAL; | 536 | return -EINVAL; |
551 | goto err_free_alarm; | ||
552 | } | ||
553 | err = fan_ctrl_init(fan_data, pdata); | 537 | err = fan_ctrl_init(fan_data, pdata); |
554 | if (err) | 538 | if (err) |
555 | goto err_free_alarm; | 539 | return err; |
556 | } | 540 | } |
557 | 541 | ||
558 | err = device_create_file(&pdev->dev, &dev_attr_name); | 542 | err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_group); |
559 | if (err) | 543 | if (err) |
560 | goto err_free_ctrl; | 544 | return err; |
561 | 545 | ||
562 | /* Make this driver part of hwmon class. */ | 546 | /* Make this driver part of hwmon class. */ |
563 | fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); | 547 | fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); |
564 | if (IS_ERR(fan_data->hwmon_dev)) { | 548 | if (IS_ERR(fan_data->hwmon_dev)) { |
565 | err = PTR_ERR(fan_data->hwmon_dev); | 549 | err = PTR_ERR(fan_data->hwmon_dev); |
566 | goto err_remove_name; | 550 | goto err_remove; |
567 | } | 551 | } |
568 | 552 | ||
569 | dev_info(&pdev->dev, "GPIO fan initialized\n"); | 553 | dev_info(&pdev->dev, "GPIO fan initialized\n"); |
570 | 554 | ||
571 | return 0; | 555 | return 0; |
572 | 556 | ||
573 | err_remove_name: | 557 | err_remove: |
574 | device_remove_file(&pdev->dev, &dev_attr_name); | 558 | sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_group); |
575 | err_free_ctrl: | ||
576 | if (fan_data->ctrl) | ||
577 | fan_ctrl_free(fan_data); | ||
578 | err_free_alarm: | ||
579 | if (fan_data->alarm) | ||
580 | fan_alarm_free(fan_data); | ||
581 | return err; | 559 | return err; |
582 | } | 560 | } |
583 | 561 | ||
@@ -586,11 +564,7 @@ static int gpio_fan_remove(struct platform_device *pdev) | |||
586 | struct gpio_fan_data *fan_data = platform_get_drvdata(pdev); | 564 | struct gpio_fan_data *fan_data = platform_get_drvdata(pdev); |
587 | 565 | ||
588 | hwmon_device_unregister(fan_data->hwmon_dev); | 566 | hwmon_device_unregister(fan_data->hwmon_dev); |
589 | device_remove_file(&pdev->dev, &dev_attr_name); | 567 | sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_group); |
590 | if (fan_data->alarm) | ||
591 | fan_alarm_free(fan_data); | ||
592 | if (fan_data->ctrl) | ||
593 | fan_ctrl_free(fan_data); | ||
594 | 568 | ||
595 | return 0; | 569 | return 0; |
596 | } | 570 | } |
@@ -619,7 +593,7 @@ static int gpio_fan_resume(struct device *dev) | |||
619 | } | 593 | } |
620 | 594 | ||
621 | static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume); | 595 | static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume); |
622 | #define GPIO_FAN_PM &gpio_fan_pm | 596 | #define GPIO_FAN_PM (&gpio_fan_pm) |
623 | #else | 597 | #else |
624 | #define GPIO_FAN_PM NULL | 598 | #define GPIO_FAN_PM NULL |
625 | #endif | 599 | #endif |
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index a14f634248e7..1429f6e177f4 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c | |||
@@ -289,8 +289,9 @@ static int aem_init_ipmi_data(struct aem_ipmi_data *data, int iface, | |||
289 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, | 289 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, |
290 | data, &data->user); | 290 | data, &data->user); |
291 | if (err < 0) { | 291 | if (err < 0) { |
292 | dev_err(bmc, "Unable to register user with IPMI " | 292 | dev_err(bmc, |
293 | "interface %d\n", data->interface); | 293 | "Unable to register user with IPMI interface %d\n", |
294 | data->interface); | ||
294 | return -EACCES; | 295 | return -EACCES; |
295 | } | 296 | } |
296 | 297 | ||
@@ -328,8 +329,8 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
328 | struct aem_ipmi_data *data = user_msg_data; | 329 | struct aem_ipmi_data *data = user_msg_data; |
329 | 330 | ||
330 | if (msg->msgid != data->tx_msgid) { | 331 | if (msg->msgid != data->tx_msgid) { |
331 | dev_err(data->bmc_device, "Mismatch between received msgid " | 332 | dev_err(data->bmc_device, |
332 | "(%02x) and transmitted msgid (%02x)!\n", | 333 | "Mismatch between received msgid (%02x) and transmitted msgid (%02x)!\n", |
333 | (int)msg->msgid, | 334 | (int)msg->msgid, |
334 | (int)data->tx_msgid); | 335 | (int)data->tx_msgid); |
335 | ipmi_free_recv_msg(msg); | 336 | ipmi_free_recv_msg(msg); |
@@ -575,8 +576,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | |||
575 | /* Register with hwmon */ | 576 | /* Register with hwmon */ |
576 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); | 577 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); |
577 | if (IS_ERR(data->hwmon_dev)) { | 578 | if (IS_ERR(data->hwmon_dev)) { |
578 | dev_err(&data->pdev->dev, "Unable to register hwmon " | 579 | dev_err(&data->pdev->dev, |
579 | "device for IPMI interface %d\n", | 580 | "Unable to register hwmon device for IPMI interface %d\n", |
580 | probe->interface); | 581 | probe->interface); |
581 | res = PTR_ERR(data->hwmon_dev); | 582 | res = PTR_ERR(data->hwmon_dev); |
582 | goto hwmon_reg_err; | 583 | goto hwmon_reg_err; |
@@ -715,8 +716,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | |||
715 | /* Register with hwmon */ | 716 | /* Register with hwmon */ |
716 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); | 717 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); |
717 | if (IS_ERR(data->hwmon_dev)) { | 718 | if (IS_ERR(data->hwmon_dev)) { |
718 | dev_err(&data->pdev->dev, "Unable to register hwmon " | 719 | dev_err(&data->pdev->dev, |
719 | "device for IPMI interface %d\n", | 720 | "Unable to register hwmon device for IPMI interface %d\n", |
720 | probe->interface); | 721 | probe->interface); |
721 | res = PTR_ERR(data->hwmon_dev); | 722 | res = PTR_ERR(data->hwmon_dev); |
722 | goto hwmon_reg_err; | 723 | goto hwmon_reg_err; |
@@ -768,8 +769,8 @@ static void aem_init_aem2(struct aem_ipmi_data *probe) | |||
768 | 769 | ||
769 | while (!aem_find_aem2(probe, &fi_resp, i)) { | 770 | while (!aem_find_aem2(probe, &fi_resp, i)) { |
770 | if (fi_resp.major != 2) { | 771 | if (fi_resp.major != 2) { |
771 | dev_err(probe->bmc_device, "Unknown AEM v%d; please " | 772 | dev_err(probe->bmc_device, |
772 | "report this to the maintainer.\n", | 773 | "Unknown AEM v%d; please report this to the maintainer.\n", |
773 | fi_resp.major); | 774 | fi_resp.major); |
774 | i++; | 775 | i++; |
775 | continue; | 776 | continue; |
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index b622a93ec32c..74b365ea01c7 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c | |||
@@ -163,8 +163,8 @@ static int ibmpex_ver_check(struct ibmpex_bmc_data *data) | |||
163 | data->sensor_major = data->rx_msg_data[0]; | 163 | data->sensor_major = data->rx_msg_data[0]; |
164 | data->sensor_minor = data->rx_msg_data[1]; | 164 | data->sensor_minor = data->rx_msg_data[1]; |
165 | 165 | ||
166 | dev_info(data->bmc_device, "Found BMC with sensor interface " | 166 | dev_info(data->bmc_device, |
167 | "v%d.%d %d-%02d-%02d on interface %d\n", | 167 | "Found BMC with sensor interface v%d.%d %d-%02d-%02d on interface %d\n", |
168 | data->sensor_major, | 168 | data->sensor_major, |
169 | data->sensor_minor, | 169 | data->sensor_minor, |
170 | extract_value(data->rx_msg_data, 2), | 170 | extract_value(data->rx_msg_data, 2), |
@@ -478,8 +478,9 @@ static void ibmpex_register_bmc(int iface, struct device *dev) | |||
478 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, | 478 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, |
479 | data, &data->user); | 479 | data, &data->user); |
480 | if (err < 0) { | 480 | if (err < 0) { |
481 | dev_err(dev, "Unable to register user with IPMI " | 481 | dev_err(dev, |
482 | "interface %d\n", data->interface); | 482 | "Unable to register user with IPMI interface %d\n", |
483 | data->interface); | ||
483 | goto out; | 484 | goto out; |
484 | } | 485 | } |
485 | 486 | ||
@@ -501,8 +502,8 @@ static void ibmpex_register_bmc(int iface, struct device *dev) | |||
501 | data->hwmon_dev = hwmon_device_register(data->bmc_device); | 502 | data->hwmon_dev = hwmon_device_register(data->bmc_device); |
502 | 503 | ||
503 | if (IS_ERR(data->hwmon_dev)) { | 504 | if (IS_ERR(data->hwmon_dev)) { |
504 | dev_err(data->bmc_device, "Unable to register hwmon " | 505 | dev_err(data->bmc_device, |
505 | "device for IPMI interface %d\n", | 506 | "Unable to register hwmon device for IPMI interface %d\n", |
506 | data->interface); | 507 | data->interface); |
507 | goto out_user; | 508 | goto out_user; |
508 | } | 509 | } |
@@ -567,8 +568,8 @@ static void ibmpex_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
567 | struct ibmpex_bmc_data *data = (struct ibmpex_bmc_data *)user_msg_data; | 568 | struct ibmpex_bmc_data *data = (struct ibmpex_bmc_data *)user_msg_data; |
568 | 569 | ||
569 | if (msg->msgid != data->tx_msgid) { | 570 | if (msg->msgid != data->tx_msgid) { |
570 | dev_err(data->bmc_device, "Mismatch between received msgid " | 571 | dev_err(data->bmc_device, |
571 | "(%02x) and transmitted msgid (%02x)!\n", | 572 | "Mismatch between received msgid (%02x) and transmitted msgid (%02x)!\n", |
572 | (int)msg->msgid, | 573 | (int)msg->msgid, |
573 | (int)data->tx_msgid); | 574 | (int)data->tx_msgid); |
574 | ipmi_free_recv_msg(msg); | 575 | ipmi_free_recv_msg(msg); |
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 8e7158c3ad2f..4958b2f89dce 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c | |||
@@ -186,20 +186,20 @@ static ssize_t ina2xx_show_value(struct device *dev, | |||
186 | } | 186 | } |
187 | 187 | ||
188 | /* shunt voltage */ | 188 | /* shunt voltage */ |
189 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, \ | 189 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ina2xx_show_value, NULL, |
190 | ina2xx_show_value, NULL, INA2XX_SHUNT_VOLTAGE); | 190 | INA2XX_SHUNT_VOLTAGE); |
191 | 191 | ||
192 | /* bus voltage */ | 192 | /* bus voltage */ |
193 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, \ | 193 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ina2xx_show_value, NULL, |
194 | ina2xx_show_value, NULL, INA2XX_BUS_VOLTAGE); | 194 | INA2XX_BUS_VOLTAGE); |
195 | 195 | ||
196 | /* calculated current */ | 196 | /* calculated current */ |
197 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, \ | 197 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ina2xx_show_value, NULL, |
198 | ina2xx_show_value, NULL, INA2XX_CURRENT); | 198 | INA2XX_CURRENT); |
199 | 199 | ||
200 | /* calculated power */ | 200 | /* calculated power */ |
201 | static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, \ | 201 | static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL, |
202 | ina2xx_show_value, NULL, INA2XX_POWER); | 202 | INA2XX_POWER); |
203 | 203 | ||
204 | /* pointers to created device attributes */ | 204 | /* pointers to created device attributes */ |
205 | static struct attribute *ina2xx_attributes[] = { | 205 | static struct attribute *ina2xx_attributes[] = { |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 37fc980fde24..72b21d5b1c62 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -1778,7 +1778,7 @@ static int __init it87_find(unsigned short *address, | |||
1778 | superio_select(5); | 1778 | superio_select(5); |
1779 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; | 1779 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; |
1780 | } else if (sio_data->type == it8783) { | 1780 | } else if (sio_data->type == it8783) { |
1781 | int reg25, reg27, reg2A, reg2C, regEF; | 1781 | int reg25, reg27, reg2a, reg2c, regef; |
1782 | 1782 | ||
1783 | sio_data->skip_vid = 1; /* No VID */ | 1783 | sio_data->skip_vid = 1; /* No VID */ |
1784 | 1784 | ||
@@ -1786,15 +1786,15 @@ static int __init it87_find(unsigned short *address, | |||
1786 | 1786 | ||
1787 | reg25 = superio_inb(IT87_SIO_GPIO1_REG); | 1787 | reg25 = superio_inb(IT87_SIO_GPIO1_REG); |
1788 | reg27 = superio_inb(IT87_SIO_GPIO3_REG); | 1788 | reg27 = superio_inb(IT87_SIO_GPIO3_REG); |
1789 | reg2A = superio_inb(IT87_SIO_PINX1_REG); | 1789 | reg2a = superio_inb(IT87_SIO_PINX1_REG); |
1790 | reg2C = superio_inb(IT87_SIO_PINX2_REG); | 1790 | reg2c = superio_inb(IT87_SIO_PINX2_REG); |
1791 | regEF = superio_inb(IT87_SIO_SPI_REG); | 1791 | regef = superio_inb(IT87_SIO_SPI_REG); |
1792 | 1792 | ||
1793 | /* Check if fan3 is there or not */ | 1793 | /* Check if fan3 is there or not */ |
1794 | if ((reg27 & (1 << 0)) || !(reg2C & (1 << 2))) | 1794 | if ((reg27 & (1 << 0)) || !(reg2c & (1 << 2))) |
1795 | sio_data->skip_fan |= (1 << 2); | 1795 | sio_data->skip_fan |= (1 << 2); |
1796 | if ((reg25 & (1 << 4)) | 1796 | if ((reg25 & (1 << 4)) |
1797 | || (!(reg2A & (1 << 1)) && (regEF & (1 << 0)))) | 1797 | || (!(reg2a & (1 << 1)) && (regef & (1 << 0)))) |
1798 | sio_data->skip_pwm |= (1 << 2); | 1798 | sio_data->skip_pwm |= (1 << 2); |
1799 | 1799 | ||
1800 | /* Check if fan2 is there or not */ | 1800 | /* Check if fan2 is there or not */ |
@@ -1804,7 +1804,7 @@ static int __init it87_find(unsigned short *address, | |||
1804 | sio_data->skip_pwm |= (1 << 1); | 1804 | sio_data->skip_pwm |= (1 << 1); |
1805 | 1805 | ||
1806 | /* VIN5 */ | 1806 | /* VIN5 */ |
1807 | if ((reg27 & (1 << 0)) || (reg2C & (1 << 2))) | 1807 | if ((reg27 & (1 << 0)) || (reg2c & (1 << 2))) |
1808 | sio_data->skip_in |= (1 << 5); /* No VIN5 */ | 1808 | sio_data->skip_in |= (1 << 5); /* No VIN5 */ |
1809 | 1809 | ||
1810 | /* VIN6 */ | 1810 | /* VIN6 */ |
@@ -1829,18 +1829,18 @@ static int __init it87_find(unsigned short *address, | |||
1829 | * not the case, and ask the user to report if the | 1829 | * not the case, and ask the user to report if the |
1830 | * resulting voltage is sane. | 1830 | * resulting voltage is sane. |
1831 | */ | 1831 | */ |
1832 | if (!(reg2C & (1 << 1))) { | 1832 | if (!(reg2c & (1 << 1))) { |
1833 | reg2C |= (1 << 1); | 1833 | reg2c |= (1 << 1); |
1834 | superio_outb(IT87_SIO_PINX2_REG, reg2C); | 1834 | superio_outb(IT87_SIO_PINX2_REG, reg2c); |
1835 | pr_notice("Routing internal VCCH5V to in7.\n"); | 1835 | pr_notice("Routing internal VCCH5V to in7.\n"); |
1836 | } | 1836 | } |
1837 | pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n"); | 1837 | pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n"); |
1838 | pr_notice("Please report if it displays a reasonable voltage.\n"); | 1838 | pr_notice("Please report if it displays a reasonable voltage.\n"); |
1839 | } | 1839 | } |
1840 | 1840 | ||
1841 | if (reg2C & (1 << 0)) | 1841 | if (reg2c & (1 << 0)) |
1842 | sio_data->internal |= (1 << 0); | 1842 | sio_data->internal |= (1 << 0); |
1843 | if (reg2C & (1 << 1)) | 1843 | if (reg2c & (1 << 1)) |
1844 | sio_data->internal |= (1 << 1); | 1844 | sio_data->internal |= (1 << 1); |
1845 | 1845 | ||
1846 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; | 1846 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; |
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 9f3c0aeacdb9..5b50e9e4f96b 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c | |||
@@ -200,8 +200,8 @@ static int k8temp_probe(struct pci_dev *pdev, | |||
200 | */ | 200 | */ |
201 | if (model >= 0x40) { | 201 | if (model >= 0x40) { |
202 | data->swap_core_select = 1; | 202 | data->swap_core_select = 1; |
203 | dev_warn(&pdev->dev, "Temperature readouts might be wrong - " | 203 | dev_warn(&pdev->dev, |
204 | "check erratum #141\n"); | 204 | "Temperature readouts might be wrong - check erratum #141\n"); |
205 | } | 205 | } |
206 | 206 | ||
207 | /* | 207 | /* |
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 483538fa1bd5..6cf6bff79003 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
@@ -386,8 +386,9 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, | |||
386 | data->fan_div[nr] = 3; | 386 | data->fan_div[nr] = 3; |
387 | break; | 387 | break; |
388 | default: | 388 | default: |
389 | dev_err(dev, "fan_div value %ld not " | 389 | dev_err(dev, |
390 | "supported. Choose one of 1, 2, 4 or 8!\n", val); | 390 | "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", |
391 | val); | ||
391 | mutex_unlock(&data->update_lock); | 392 | mutex_unlock(&data->update_lock); |
392 | return -EINVAL; | 393 | return -EINVAL; |
393 | } | 394 | } |
@@ -636,8 +637,9 @@ static int lm78_i2c_detect(struct i2c_client *client, | |||
636 | goto err_nodev; | 637 | goto err_nodev; |
637 | 638 | ||
638 | if (lm78_alias_detect(client, i)) { | 639 | if (lm78_alias_detect(client, i)) { |
639 | dev_dbg(&adapter->dev, "Device at 0x%02x appears to " | 640 | dev_dbg(&adapter->dev, |
640 | "be the same as ISA device\n", address); | 641 | "Device at 0x%02x appears to be the same as ISA device\n", |
642 | address); | ||
641 | goto err_nodev; | 643 | goto err_nodev; |
642 | } | 644 | } |
643 | 645 | ||
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index 357fbb998728..eba89aac3ece 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c | |||
@@ -286,8 +286,9 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
286 | data->fan_div[nr] = 3; | 286 | data->fan_div[nr] = 3; |
287 | break; | 287 | break; |
288 | default: | 288 | default: |
289 | dev_err(&client->dev, "fan_div value %ld not " | 289 | dev_err(&client->dev, |
290 | "supported. Choose one of 1, 2, 4 or 8!\n", val); | 290 | "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", |
291 | val); | ||
291 | mutex_unlock(&data->update_lock); | 292 | mutex_unlock(&data->update_lock); |
292 | return -EINVAL; | 293 | return -EINVAL; |
293 | } | 294 | } |
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 47ade8ba152d..3894c408fda3 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
@@ -1293,8 +1293,8 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info) | |||
1293 | company = lm85_read_value(client, LM85_REG_COMPANY); | 1293 | company = lm85_read_value(client, LM85_REG_COMPANY); |
1294 | verstep = lm85_read_value(client, LM85_REG_VERSTEP); | 1294 | verstep = lm85_read_value(client, LM85_REG_VERSTEP); |
1295 | 1295 | ||
1296 | dev_dbg(&adapter->dev, "Detecting device at 0x%02x with " | 1296 | dev_dbg(&adapter->dev, |
1297 | "COMPANY: 0x%02x and VERSTEP: 0x%02x\n", | 1297 | "Detecting device at 0x%02x with COMPANY: 0x%02x and VERSTEP: 0x%02x\n", |
1298 | address, company, verstep); | 1298 | address, company, verstep); |
1299 | 1299 | ||
1300 | /* All supported chips have the version in common */ | 1300 | /* All supported chips have the version in common */ |
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index b40f34cdb3ca..a6f46058b1be 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c | |||
@@ -354,12 +354,12 @@ static const unsigned long lm93_vin_val_max[16] = { | |||
354 | 354 | ||
355 | static unsigned LM93_IN_FROM_REG(int nr, u8 reg) | 355 | static unsigned LM93_IN_FROM_REG(int nr, u8 reg) |
356 | { | 356 | { |
357 | const long uV_max = lm93_vin_val_max[nr] * 1000; | 357 | const long uv_max = lm93_vin_val_max[nr] * 1000; |
358 | const long uV_min = lm93_vin_val_min[nr] * 1000; | 358 | const long uv_min = lm93_vin_val_min[nr] * 1000; |
359 | 359 | ||
360 | const long slope = (uV_max - uV_min) / | 360 | const long slope = (uv_max - uv_min) / |
361 | (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); | 361 | (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); |
362 | const long intercept = uV_min - slope * lm93_vin_reg_min[nr]; | 362 | const long intercept = uv_min - slope * lm93_vin_reg_min[nr]; |
363 | 363 | ||
364 | return (slope * reg + intercept + 500) / 1000; | 364 | return (slope * reg + intercept + 500) / 1000; |
365 | } | 365 | } |
@@ -371,20 +371,20 @@ static unsigned LM93_IN_FROM_REG(int nr, u8 reg) | |||
371 | static u8 LM93_IN_TO_REG(int nr, unsigned val) | 371 | static u8 LM93_IN_TO_REG(int nr, unsigned val) |
372 | { | 372 | { |
373 | /* range limit */ | 373 | /* range limit */ |
374 | const long mV = clamp_val(val, | 374 | const long mv = clamp_val(val, |
375 | lm93_vin_val_min[nr], lm93_vin_val_max[nr]); | 375 | lm93_vin_val_min[nr], lm93_vin_val_max[nr]); |
376 | 376 | ||
377 | /* try not to lose too much precision here */ | 377 | /* try not to lose too much precision here */ |
378 | const long uV = mV * 1000; | 378 | const long uv = mv * 1000; |
379 | const long uV_max = lm93_vin_val_max[nr] * 1000; | 379 | const long uv_max = lm93_vin_val_max[nr] * 1000; |
380 | const long uV_min = lm93_vin_val_min[nr] * 1000; | 380 | const long uv_min = lm93_vin_val_min[nr] * 1000; |
381 | 381 | ||
382 | /* convert */ | 382 | /* convert */ |
383 | const long slope = (uV_max - uV_min) / | 383 | const long slope = (uv_max - uv_min) / |
384 | (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); | 384 | (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); |
385 | const long intercept = uV_min - slope * lm93_vin_reg_min[nr]; | 385 | const long intercept = uv_min - slope * lm93_vin_reg_min[nr]; |
386 | 386 | ||
387 | u8 result = ((uV - intercept + (slope/2)) / slope); | 387 | u8 result = ((uv - intercept + (slope/2)) / slope); |
388 | result = clamp_val(result, | 388 | result = clamp_val(result, |
389 | lm93_vin_reg_min[nr], lm93_vin_reg_max[nr]); | 389 | lm93_vin_reg_min[nr], lm93_vin_reg_max[nr]); |
390 | return result; | 390 | return result; |
@@ -393,10 +393,10 @@ static u8 LM93_IN_TO_REG(int nr, unsigned val) | |||
393 | /* vid in mV, upper == 0 indicates low limit, otherwise upper limit */ | 393 | /* vid in mV, upper == 0 indicates low limit, otherwise upper limit */ |
394 | static unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid) | 394 | static unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid) |
395 | { | 395 | { |
396 | const long uV_offset = upper ? (((reg >> 4 & 0x0f) + 1) * 12500) : | 396 | const long uv_offset = upper ? (((reg >> 4 & 0x0f) + 1) * 12500) : |
397 | (((reg >> 0 & 0x0f) + 1) * -25000); | 397 | (((reg >> 0 & 0x0f) + 1) * -25000); |
398 | const long uV_vid = vid * 1000; | 398 | const long uv_vid = vid * 1000; |
399 | return (uV_vid + uV_offset + 5000) / 10000; | 399 | return (uv_vid + uv_offset + 5000) / 10000; |
400 | } | 400 | } |
401 | 401 | ||
402 | #define LM93_IN_MIN_FROM_REG(reg, vid) LM93_IN_REL_FROM_REG((reg), 0, (vid)) | 402 | #define LM93_IN_MIN_FROM_REG(reg, vid) LM93_IN_REL_FROM_REG((reg), 0, (vid)) |
@@ -409,13 +409,13 @@ static unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid) | |||
409 | */ | 409 | */ |
410 | static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid) | 410 | static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid) |
411 | { | 411 | { |
412 | long uV_offset = vid * 1000 - val * 10000; | 412 | long uv_offset = vid * 1000 - val * 10000; |
413 | if (upper) { | 413 | if (upper) { |
414 | uV_offset = clamp_val(uV_offset, 12500, 200000); | 414 | uv_offset = clamp_val(uv_offset, 12500, 200000); |
415 | return (u8)((uV_offset / 12500 - 1) << 4); | 415 | return (u8)((uv_offset / 12500 - 1) << 4); |
416 | } else { | 416 | } else { |
417 | uV_offset = clamp_val(uV_offset, -400000, -25000); | 417 | uv_offset = clamp_val(uv_offset, -400000, -25000); |
418 | return (u8)((uV_offset / -25000 - 1) << 0); | 418 | return (u8)((uv_offset / -25000 - 1) << 0); |
419 | } | 419 | } |
420 | } | 420 | } |
421 | 421 | ||
@@ -818,8 +818,9 @@ static u8 lm93_read_byte(struct i2c_client *client, u8 reg) | |||
818 | if (value >= 0) { | 818 | if (value >= 0) { |
819 | return value; | 819 | return value; |
820 | } else { | 820 | } else { |
821 | dev_warn(&client->dev, "lm93: read byte data failed, " | 821 | dev_warn(&client->dev, |
822 | "address 0x%02x.\n", reg); | 822 | "lm93: read byte data failed, address 0x%02x.\n", |
823 | reg); | ||
823 | mdelay(i + 3); | 824 | mdelay(i + 3); |
824 | } | 825 | } |
825 | 826 | ||
@@ -838,8 +839,9 @@ static int lm93_write_byte(struct i2c_client *client, u8 reg, u8 value) | |||
838 | result = i2c_smbus_write_byte_data(client, reg, value); | 839 | result = i2c_smbus_write_byte_data(client, reg, value); |
839 | 840 | ||
840 | if (result < 0) | 841 | if (result < 0) |
841 | dev_warn(&client->dev, "lm93: write byte data failed, " | 842 | dev_warn(&client->dev, |
842 | "0x%02x at address 0x%02x.\n", value, reg); | 843 | "lm93: write byte data failed, 0x%02x at address 0x%02x.\n", |
844 | value, reg); | ||
843 | 845 | ||
844 | return result; | 846 | return result; |
845 | } | 847 | } |
@@ -854,8 +856,9 @@ static u16 lm93_read_word(struct i2c_client *client, u8 reg) | |||
854 | if (value >= 0) { | 856 | if (value >= 0) { |
855 | return value; | 857 | return value; |
856 | } else { | 858 | } else { |
857 | dev_warn(&client->dev, "lm93: read word data failed, " | 859 | dev_warn(&client->dev, |
858 | "address 0x%02x.\n", reg); | 860 | "lm93: read word data failed, address 0x%02x.\n", |
861 | reg); | ||
859 | mdelay(i + 3); | 862 | mdelay(i + 3); |
860 | } | 863 | } |
861 | 864 | ||
@@ -874,8 +877,9 @@ static int lm93_write_word(struct i2c_client *client, u8 reg, u16 value) | |||
874 | result = i2c_smbus_write_word_data(client, reg, value); | 877 | result = i2c_smbus_write_word_data(client, reg, value); |
875 | 878 | ||
876 | if (result < 0) | 879 | if (result < 0) |
877 | dev_warn(&client->dev, "lm93: write word data failed, " | 880 | dev_warn(&client->dev, |
878 | "0x%04x at address 0x%02x.\n", value, reg); | 881 | "lm93: write word data failed, 0x%04x at address 0x%02x.\n", |
882 | value, reg); | ||
879 | 883 | ||
880 | return result; | 884 | return result; |
881 | } | 885 | } |
@@ -898,8 +902,8 @@ static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values) | |||
898 | if (result == lm93_block_read_cmds[fbn].len) { | 902 | if (result == lm93_block_read_cmds[fbn].len) { |
899 | break; | 903 | break; |
900 | } else { | 904 | } else { |
901 | dev_warn(&client->dev, "lm93: block read data failed, " | 905 | dev_warn(&client->dev, |
902 | "command 0x%02x.\n", | 906 | "lm93: block read data failed, command 0x%02x.\n", |
903 | lm93_block_read_cmds[fbn].cmd); | 907 | lm93_block_read_cmds[fbn].cmd); |
904 | mdelay(i + 3); | 908 | mdelay(i + 3); |
905 | } | 909 | } |
@@ -2672,8 +2676,8 @@ static void lm93_init_client(struct i2c_client *client) | |||
2672 | return; | 2676 | return; |
2673 | } | 2677 | } |
2674 | 2678 | ||
2675 | dev_warn(&client->dev, "timed out waiting for sensor " | 2679 | dev_warn(&client->dev, |
2676 | "chip to signal ready!\n"); | 2680 | "timed out waiting for sensor chip to signal ready!\n"); |
2677 | } | 2681 | } |
2678 | 2682 | ||
2679 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 2683 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
@@ -2733,12 +2737,12 @@ static int lm93_probe(struct i2c_client *client, | |||
2733 | dev_dbg(&client->dev, "using SMBus block data transactions\n"); | 2737 | dev_dbg(&client->dev, "using SMBus block data transactions\n"); |
2734 | update = lm93_update_client_full; | 2738 | update = lm93_update_client_full; |
2735 | } else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) { | 2739 | } else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) { |
2736 | dev_dbg(&client->dev, "disabled SMBus block data " | 2740 | dev_dbg(&client->dev, |
2737 | "transactions\n"); | 2741 | "disabled SMBus block data transactions\n"); |
2738 | update = lm93_update_client_min; | 2742 | update = lm93_update_client_min; |
2739 | } else { | 2743 | } else { |
2740 | dev_dbg(&client->dev, "detect failed, " | 2744 | dev_dbg(&client->dev, |
2741 | "smbus byte and/or word data not supported!\n"); | 2745 | "detect failed, smbus byte and/or word data not supported!\n"); |
2742 | return -ENODEV; | 2746 | return -ENODEV; |
2743 | } | 2747 | } |
2744 | 2748 | ||
diff --git a/drivers/hwmon/lm95234.c b/drivers/hwmon/lm95234.c new file mode 100644 index 000000000000..307c9eaeeb9f --- /dev/null +++ b/drivers/hwmon/lm95234.c | |||
@@ -0,0 +1,769 @@ | |||
1 | /* | ||
2 | * Driver for Texas Instruments / National Semiconductor LM95234 | ||
3 | * | ||
4 | * Copyright (c) 2013 Guenter Roeck <linux@roeck-us.net> | ||
5 | * | ||
6 | * Derived from lm95241.c | ||
7 | * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/jiffies.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/hwmon.h> | ||
26 | #include <linux/hwmon-sysfs.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/sysfs.h> | ||
30 | |||
31 | #define DRVNAME "lm95234" | ||
32 | |||
33 | static const unsigned short normal_i2c[] = { 0x18, 0x4d, 0x4e, I2C_CLIENT_END }; | ||
34 | |||
35 | /* LM95234 registers */ | ||
36 | #define LM95234_REG_MAN_ID 0xFE | ||
37 | #define LM95234_REG_CHIP_ID 0xFF | ||
38 | #define LM95234_REG_STATUS 0x02 | ||
39 | #define LM95234_REG_CONFIG 0x03 | ||
40 | #define LM95234_REG_CONVRATE 0x04 | ||
41 | #define LM95234_REG_STS_FAULT 0x07 | ||
42 | #define LM95234_REG_STS_TCRIT1 0x08 | ||
43 | #define LM95234_REG_STS_TCRIT2 0x09 | ||
44 | #define LM95234_REG_TEMPH(x) ((x) + 0x10) | ||
45 | #define LM95234_REG_TEMPL(x) ((x) + 0x20) | ||
46 | #define LM95234_REG_UTEMPH(x) ((x) + 0x19) /* Remote only */ | ||
47 | #define LM95234_REG_UTEMPL(x) ((x) + 0x29) | ||
48 | #define LM95234_REG_REM_MODEL 0x30 | ||
49 | #define LM95234_REG_REM_MODEL_STS 0x38 | ||
50 | #define LM95234_REG_OFFSET(x) ((x) + 0x31) /* Remote only */ | ||
51 | #define LM95234_REG_TCRIT1(x) ((x) + 0x40) | ||
52 | #define LM95234_REG_TCRIT2(x) ((x) + 0x49) /* Remote channel 1,2 */ | ||
53 | #define LM95234_REG_TCRIT_HYST 0x5a | ||
54 | |||
55 | #define NATSEMI_MAN_ID 0x01 | ||
56 | #define LM95234_CHIP_ID 0x79 | ||
57 | |||
58 | /* Client data (each client gets its own) */ | ||
59 | struct lm95234_data { | ||
60 | struct device *hwmon_dev; | ||
61 | struct mutex update_lock; | ||
62 | unsigned long last_updated, interval; /* in jiffies */ | ||
63 | bool valid; /* false until following fields are valid */ | ||
64 | /* registers values */ | ||
65 | int temp[5]; /* temperature (signed) */ | ||
66 | u32 status; /* fault/alarm status */ | ||
67 | u8 tcrit1[5]; /* critical temperature limit */ | ||
68 | u8 tcrit2[2]; /* high temperature limit */ | ||
69 | s8 toffset[4]; /* remote temperature offset */ | ||
70 | u8 thyst; /* common hysteresis */ | ||
71 | |||
72 | u8 sensor_type; /* temperature sensor type */ | ||
73 | }; | ||
74 | |||
75 | static int lm95234_read_temp(struct i2c_client *client, int index, int *t) | ||
76 | { | ||
77 | int val; | ||
78 | u16 temp = 0; | ||
79 | |||
80 | if (index) { | ||
81 | val = i2c_smbus_read_byte_data(client, | ||
82 | LM95234_REG_UTEMPH(index - 1)); | ||
83 | if (val < 0) | ||
84 | return val; | ||
85 | temp = val << 8; | ||
86 | val = i2c_smbus_read_byte_data(client, | ||
87 | LM95234_REG_UTEMPL(index - 1)); | ||
88 | if (val < 0) | ||
89 | return val; | ||
90 | temp |= val; | ||
91 | *t = temp; | ||
92 | } | ||
93 | /* | ||
94 | * Read signed temperature if unsigned temperature is 0, | ||
95 | * or if this is the local sensor. | ||
96 | */ | ||
97 | if (!temp) { | ||
98 | val = i2c_smbus_read_byte_data(client, | ||
99 | LM95234_REG_TEMPH(index)); | ||
100 | if (val < 0) | ||
101 | return val; | ||
102 | temp = val << 8; | ||
103 | val = i2c_smbus_read_byte_data(client, | ||
104 | LM95234_REG_TEMPL(index)); | ||
105 | if (val < 0) | ||
106 | return val; | ||
107 | temp |= val; | ||
108 | *t = (s16)temp; | ||
109 | } | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static u16 update_intervals[] = { 143, 364, 1000, 2500 }; | ||
114 | |||
115 | /* Fill value cache. Must be called with update lock held. */ | ||
116 | |||
117 | static int lm95234_fill_cache(struct i2c_client *client) | ||
118 | { | ||
119 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
120 | int i, ret; | ||
121 | |||
122 | ret = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE); | ||
123 | if (ret < 0) | ||
124 | return ret; | ||
125 | |||
126 | data->interval = msecs_to_jiffies(update_intervals[ret & 0x03]); | ||
127 | |||
128 | for (i = 0; i < ARRAY_SIZE(data->tcrit1); i++) { | ||
129 | ret = i2c_smbus_read_byte_data(client, LM95234_REG_TCRIT1(i)); | ||
130 | if (ret < 0) | ||
131 | return ret; | ||
132 | data->tcrit1[i] = ret; | ||
133 | } | ||
134 | for (i = 0; i < ARRAY_SIZE(data->tcrit2); i++) { | ||
135 | ret = i2c_smbus_read_byte_data(client, LM95234_REG_TCRIT2(i)); | ||
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | data->tcrit2[i] = ret; | ||
139 | } | ||
140 | for (i = 0; i < ARRAY_SIZE(data->toffset); i++) { | ||
141 | ret = i2c_smbus_read_byte_data(client, LM95234_REG_OFFSET(i)); | ||
142 | if (ret < 0) | ||
143 | return ret; | ||
144 | data->toffset[i] = ret; | ||
145 | } | ||
146 | |||
147 | ret = i2c_smbus_read_byte_data(client, LM95234_REG_TCRIT_HYST); | ||
148 | if (ret < 0) | ||
149 | return ret; | ||
150 | data->thyst = ret; | ||
151 | |||
152 | ret = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); | ||
153 | if (ret < 0) | ||
154 | return ret; | ||
155 | data->sensor_type = ret; | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int lm95234_update_device(struct i2c_client *client, | ||
161 | struct lm95234_data *data) | ||
162 | { | ||
163 | int ret; | ||
164 | |||
165 | mutex_lock(&data->update_lock); | ||
166 | |||
167 | if (time_after(jiffies, data->last_updated + data->interval) || | ||
168 | !data->valid) { | ||
169 | int i; | ||
170 | |||
171 | if (!data->valid) { | ||
172 | ret = lm95234_fill_cache(client); | ||
173 | if (ret < 0) | ||
174 | goto abort; | ||
175 | } | ||
176 | |||
177 | data->valid = false; | ||
178 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { | ||
179 | ret = lm95234_read_temp(client, i, &data->temp[i]); | ||
180 | if (ret < 0) | ||
181 | goto abort; | ||
182 | } | ||
183 | |||
184 | ret = i2c_smbus_read_byte_data(client, LM95234_REG_STS_FAULT); | ||
185 | if (ret < 0) | ||
186 | goto abort; | ||
187 | data->status = ret; | ||
188 | |||
189 | ret = i2c_smbus_read_byte_data(client, LM95234_REG_STS_TCRIT1); | ||
190 | if (ret < 0) | ||
191 | goto abort; | ||
192 | data->status |= ret << 8; | ||
193 | |||
194 | ret = i2c_smbus_read_byte_data(client, LM95234_REG_STS_TCRIT2); | ||
195 | if (ret < 0) | ||
196 | goto abort; | ||
197 | data->status |= ret << 16; | ||
198 | |||
199 | data->last_updated = jiffies; | ||
200 | data->valid = true; | ||
201 | } | ||
202 | ret = 0; | ||
203 | abort: | ||
204 | mutex_unlock(&data->update_lock); | ||
205 | |||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | ||
210 | char *buf) | ||
211 | { | ||
212 | struct i2c_client *client = to_i2c_client(dev); | ||
213 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
214 | int index = to_sensor_dev_attr(attr)->index; | ||
215 | int ret = lm95234_update_device(client, data); | ||
216 | |||
217 | if (ret) | ||
218 | return ret; | ||
219 | |||
220 | return sprintf(buf, "%d\n", | ||
221 | DIV_ROUND_CLOSEST(data->temp[index] * 125, 32)); | ||
222 | } | ||
223 | |||
224 | static ssize_t show_alarm(struct device *dev, | ||
225 | struct device_attribute *attr, char *buf) | ||
226 | { | ||
227 | struct i2c_client *client = to_i2c_client(dev); | ||
228 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
229 | u32 mask = to_sensor_dev_attr(attr)->index; | ||
230 | int ret = lm95234_update_device(client, data); | ||
231 | |||
232 | if (ret) | ||
233 | return ret; | ||
234 | |||
235 | return sprintf(buf, "%u", !!(data->status & mask)); | ||
236 | } | ||
237 | |||
238 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, | ||
239 | char *buf) | ||
240 | { | ||
241 | struct i2c_client *client = to_i2c_client(dev); | ||
242 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
243 | u8 mask = to_sensor_dev_attr(attr)->index; | ||
244 | int ret = lm95234_update_device(client, data); | ||
245 | |||
246 | if (ret) | ||
247 | return ret; | ||
248 | |||
249 | return sprintf(buf, data->sensor_type & mask ? "1\n" : "2\n"); | ||
250 | } | ||
251 | |||
252 | static ssize_t set_type(struct device *dev, struct device_attribute *attr, | ||
253 | const char *buf, size_t count) | ||
254 | { | ||
255 | struct i2c_client *client = to_i2c_client(dev); | ||
256 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
257 | unsigned long val; | ||
258 | u8 mask = to_sensor_dev_attr(attr)->index; | ||
259 | int ret = lm95234_update_device(client, data); | ||
260 | |||
261 | if (ret) | ||
262 | return ret; | ||
263 | |||
264 | ret = kstrtoul(buf, 10, &val); | ||
265 | if (ret < 0) | ||
266 | return ret; | ||
267 | |||
268 | if (val != 1 && val != 2) | ||
269 | return -EINVAL; | ||
270 | |||
271 | mutex_lock(&data->update_lock); | ||
272 | if (val == 1) | ||
273 | data->sensor_type |= mask; | ||
274 | else | ||
275 | data->sensor_type &= ~mask; | ||
276 | data->valid = false; | ||
277 | i2c_smbus_write_byte_data(client, LM95234_REG_REM_MODEL, | ||
278 | data->sensor_type); | ||
279 | mutex_unlock(&data->update_lock); | ||
280 | |||
281 | return count; | ||
282 | } | ||
283 | |||
284 | static ssize_t show_tcrit2(struct device *dev, struct device_attribute *attr, | ||
285 | char *buf) | ||
286 | { | ||
287 | struct i2c_client *client = to_i2c_client(dev); | ||
288 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
289 | int index = to_sensor_dev_attr(attr)->index; | ||
290 | int ret = lm95234_update_device(client, data); | ||
291 | |||
292 | if (ret) | ||
293 | return ret; | ||
294 | |||
295 | return sprintf(buf, "%u", data->tcrit2[index] * 1000); | ||
296 | } | ||
297 | |||
298 | static ssize_t set_tcrit2(struct device *dev, struct device_attribute *attr, | ||
299 | const char *buf, size_t count) | ||
300 | { | ||
301 | struct i2c_client *client = to_i2c_client(dev); | ||
302 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
303 | int index = to_sensor_dev_attr(attr)->index; | ||
304 | long val; | ||
305 | int ret = lm95234_update_device(client, data); | ||
306 | |||
307 | if (ret) | ||
308 | return ret; | ||
309 | |||
310 | ret = kstrtol(buf, 10, &val); | ||
311 | if (ret < 0) | ||
312 | return ret; | ||
313 | |||
314 | val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, index ? 255 : 127); | ||
315 | |||
316 | mutex_lock(&data->update_lock); | ||
317 | data->tcrit2[index] = val; | ||
318 | i2c_smbus_write_byte_data(client, LM95234_REG_TCRIT2(index), val); | ||
319 | mutex_unlock(&data->update_lock); | ||
320 | |||
321 | return count; | ||
322 | } | ||
323 | |||
324 | static ssize_t show_tcrit2_hyst(struct device *dev, | ||
325 | struct device_attribute *attr, char *buf) | ||
326 | { | ||
327 | struct i2c_client *client = to_i2c_client(dev); | ||
328 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
329 | int index = to_sensor_dev_attr(attr)->index; | ||
330 | int ret = lm95234_update_device(client, data); | ||
331 | |||
332 | if (ret) | ||
333 | return ret; | ||
334 | |||
335 | /* Result can be negative, so be careful with unsigned operands */ | ||
336 | return sprintf(buf, "%d", | ||
337 | ((int)data->tcrit2[index] - (int)data->thyst) * 1000); | ||
338 | } | ||
339 | |||
340 | static ssize_t show_tcrit1(struct device *dev, struct device_attribute *attr, | ||
341 | char *buf) | ||
342 | { | ||
343 | struct i2c_client *client = to_i2c_client(dev); | ||
344 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
345 | int index = to_sensor_dev_attr(attr)->index; | ||
346 | |||
347 | return sprintf(buf, "%u", data->tcrit1[index] * 1000); | ||
348 | } | ||
349 | |||
350 | static ssize_t set_tcrit1(struct device *dev, struct device_attribute *attr, | ||
351 | const char *buf, size_t count) | ||
352 | { | ||
353 | struct i2c_client *client = to_i2c_client(dev); | ||
354 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
355 | int index = to_sensor_dev_attr(attr)->index; | ||
356 | long val; | ||
357 | int ret = lm95234_update_device(client, data); | ||
358 | |||
359 | if (ret) | ||
360 | return ret; | ||
361 | |||
362 | ret = kstrtol(buf, 10, &val); | ||
363 | if (ret < 0) | ||
364 | return ret; | ||
365 | |||
366 | val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255); | ||
367 | |||
368 | mutex_lock(&data->update_lock); | ||
369 | data->tcrit1[index] = val; | ||
370 | i2c_smbus_write_byte_data(client, LM95234_REG_TCRIT1(index), val); | ||
371 | mutex_unlock(&data->update_lock); | ||
372 | |||
373 | return count; | ||
374 | } | ||
375 | |||
376 | static ssize_t show_tcrit1_hyst(struct device *dev, | ||
377 | struct device_attribute *attr, char *buf) | ||
378 | { | ||
379 | struct i2c_client *client = to_i2c_client(dev); | ||
380 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
381 | int index = to_sensor_dev_attr(attr)->index; | ||
382 | int ret = lm95234_update_device(client, data); | ||
383 | |||
384 | if (ret) | ||
385 | return ret; | ||
386 | |||
387 | /* Result can be negative, so be careful with unsigned operands */ | ||
388 | return sprintf(buf, "%d", | ||
389 | ((int)data->tcrit1[index] - (int)data->thyst) * 1000); | ||
390 | } | ||
391 | |||
392 | static ssize_t set_tcrit1_hyst(struct device *dev, | ||
393 | struct device_attribute *attr, | ||
394 | const char *buf, size_t count) | ||
395 | { | ||
396 | struct i2c_client *client = to_i2c_client(dev); | ||
397 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
398 | int index = to_sensor_dev_attr(attr)->index; | ||
399 | long val; | ||
400 | int ret = lm95234_update_device(client, data); | ||
401 | |||
402 | if (ret) | ||
403 | return ret; | ||
404 | |||
405 | ret = kstrtol(buf, 10, &val); | ||
406 | if (ret < 0) | ||
407 | return ret; | ||
408 | |||
409 | val = DIV_ROUND_CLOSEST(val, 1000); | ||
410 | val = clamp_val((int)data->tcrit1[index] - val, 0, 31); | ||
411 | |||
412 | mutex_lock(&data->update_lock); | ||
413 | data->thyst = val; | ||
414 | i2c_smbus_write_byte_data(client, LM95234_REG_TCRIT_HYST, val); | ||
415 | mutex_unlock(&data->update_lock); | ||
416 | |||
417 | return count; | ||
418 | } | ||
419 | |||
420 | static ssize_t show_offset(struct device *dev, struct device_attribute *attr, | ||
421 | char *buf) | ||
422 | { | ||
423 | struct i2c_client *client = to_i2c_client(dev); | ||
424 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
425 | int index = to_sensor_dev_attr(attr)->index; | ||
426 | int ret = lm95234_update_device(client, data); | ||
427 | |||
428 | if (ret) | ||
429 | return ret; | ||
430 | |||
431 | return sprintf(buf, "%d", data->toffset[index] * 500); | ||
432 | } | ||
433 | |||
434 | static ssize_t set_offset(struct device *dev, struct device_attribute *attr, | ||
435 | const char *buf, size_t count) | ||
436 | { | ||
437 | struct i2c_client *client = to_i2c_client(dev); | ||
438 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
439 | int index = to_sensor_dev_attr(attr)->index; | ||
440 | long val; | ||
441 | int ret = lm95234_update_device(client, data); | ||
442 | |||
443 | if (ret) | ||
444 | return ret; | ||
445 | |||
446 | ret = kstrtol(buf, 10, &val); | ||
447 | if (ret < 0) | ||
448 | return ret; | ||
449 | |||
450 | /* Accuracy is 1/2 degrees C */ | ||
451 | val = clamp_val(DIV_ROUND_CLOSEST(val, 500), -128, 127); | ||
452 | |||
453 | mutex_lock(&data->update_lock); | ||
454 | data->toffset[index] = val; | ||
455 | i2c_smbus_write_byte_data(client, LM95234_REG_OFFSET(index), val); | ||
456 | mutex_unlock(&data->update_lock); | ||
457 | |||
458 | return count; | ||
459 | } | ||
460 | |||
461 | static ssize_t show_interval(struct device *dev, struct device_attribute *attr, | ||
462 | char *buf) | ||
463 | { | ||
464 | struct i2c_client *client = to_i2c_client(dev); | ||
465 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
466 | int ret = lm95234_update_device(client, data); | ||
467 | |||
468 | if (ret) | ||
469 | return ret; | ||
470 | |||
471 | return sprintf(buf, "%lu\n", | ||
472 | DIV_ROUND_CLOSEST(data->interval * 1000, HZ)); | ||
473 | } | ||
474 | |||
475 | static ssize_t set_interval(struct device *dev, struct device_attribute *attr, | ||
476 | const char *buf, size_t count) | ||
477 | { | ||
478 | struct i2c_client *client = to_i2c_client(dev); | ||
479 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
480 | unsigned long val; | ||
481 | u8 regval; | ||
482 | int ret = lm95234_update_device(client, data); | ||
483 | |||
484 | if (ret) | ||
485 | return ret; | ||
486 | |||
487 | ret = kstrtoul(buf, 10, &val); | ||
488 | if (ret < 0) | ||
489 | return ret; | ||
490 | |||
491 | for (regval = 0; regval < 3; regval++) { | ||
492 | if (val <= update_intervals[regval]) | ||
493 | break; | ||
494 | } | ||
495 | |||
496 | mutex_lock(&data->update_lock); | ||
497 | data->interval = msecs_to_jiffies(update_intervals[regval]); | ||
498 | i2c_smbus_write_byte_data(client, LM95234_REG_CONVRATE, regval); | ||
499 | mutex_unlock(&data->update_lock); | ||
500 | |||
501 | return count; | ||
502 | } | ||
503 | |||
504 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
505 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
506 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); | ||
507 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); | ||
508 | static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4); | ||
509 | |||
510 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, | ||
511 | BIT(0) | BIT(1)); | ||
512 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, | ||
513 | BIT(2) | BIT(3)); | ||
514 | static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_alarm, NULL, | ||
515 | BIT(4) | BIT(5)); | ||
516 | static SENSOR_DEVICE_ATTR(temp5_fault, S_IRUGO, show_alarm, NULL, | ||
517 | BIT(6) | BIT(7)); | ||
518 | |||
519 | static SENSOR_DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, set_type, | ||
520 | BIT(1)); | ||
521 | static SENSOR_DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type, set_type, | ||
522 | BIT(2)); | ||
523 | static SENSOR_DEVICE_ATTR(temp4_type, S_IWUSR | S_IRUGO, show_type, set_type, | ||
524 | BIT(3)); | ||
525 | static SENSOR_DEVICE_ATTR(temp5_type, S_IWUSR | S_IRUGO, show_type, set_type, | ||
526 | BIT(4)); | ||
527 | |||
528 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_tcrit1, | ||
529 | set_tcrit1, 0); | ||
530 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_tcrit2, | ||
531 | set_tcrit2, 0); | ||
532 | static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_tcrit2, | ||
533 | set_tcrit2, 1); | ||
534 | static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_tcrit1, | ||
535 | set_tcrit1, 3); | ||
536 | static SENSOR_DEVICE_ATTR(temp5_max, S_IWUSR | S_IRUGO, show_tcrit1, | ||
537 | set_tcrit1, 4); | ||
538 | |||
539 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_tcrit1_hyst, | ||
540 | set_tcrit1_hyst, 0); | ||
541 | static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO, show_tcrit2_hyst, NULL, 0); | ||
542 | static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO, show_tcrit2_hyst, NULL, 1); | ||
543 | static SENSOR_DEVICE_ATTR(temp4_max_hyst, S_IRUGO, show_tcrit1_hyst, NULL, 3); | ||
544 | static SENSOR_DEVICE_ATTR(temp5_max_hyst, S_IRUGO, show_tcrit1_hyst, NULL, 4); | ||
545 | |||
546 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, | ||
547 | BIT(0 + 8)); | ||
548 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, | ||
549 | BIT(1 + 16)); | ||
550 | static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, | ||
551 | BIT(2 + 16)); | ||
552 | static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, | ||
553 | BIT(3 + 8)); | ||
554 | static SENSOR_DEVICE_ATTR(temp5_max_alarm, S_IRUGO, show_alarm, NULL, | ||
555 | BIT(4 + 8)); | ||
556 | |||
557 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_tcrit1, | ||
558 | set_tcrit1, 1); | ||
559 | static SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_tcrit1, | ||
560 | set_tcrit1, 2); | ||
561 | |||
562 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_tcrit1_hyst, NULL, 1); | ||
563 | static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_tcrit1_hyst, NULL, 2); | ||
564 | |||
565 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
566 | BIT(1 + 8)); | ||
567 | static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
568 | BIT(2 + 8)); | ||
569 | |||
570 | static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_offset, | ||
571 | set_offset, 0); | ||
572 | static SENSOR_DEVICE_ATTR(temp3_offset, S_IWUSR | S_IRUGO, show_offset, | ||
573 | set_offset, 1); | ||
574 | static SENSOR_DEVICE_ATTR(temp4_offset, S_IWUSR | S_IRUGO, show_offset, | ||
575 | set_offset, 2); | ||
576 | static SENSOR_DEVICE_ATTR(temp5_offset, S_IWUSR | S_IRUGO, show_offset, | ||
577 | set_offset, 3); | ||
578 | |||
579 | static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, | ||
580 | set_interval); | ||
581 | |||
582 | static struct attribute *lm95234_attributes[] = { | ||
583 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
584 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
585 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
586 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
587 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
588 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
589 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
590 | &sensor_dev_attr_temp4_fault.dev_attr.attr, | ||
591 | &sensor_dev_attr_temp5_fault.dev_attr.attr, | ||
592 | &sensor_dev_attr_temp2_type.dev_attr.attr, | ||
593 | &sensor_dev_attr_temp3_type.dev_attr.attr, | ||
594 | &sensor_dev_attr_temp4_type.dev_attr.attr, | ||
595 | &sensor_dev_attr_temp5_type.dev_attr.attr, | ||
596 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
597 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
598 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
599 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
600 | &sensor_dev_attr_temp5_max.dev_attr.attr, | ||
601 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | ||
602 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, | ||
603 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, | ||
604 | &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, | ||
605 | &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, | ||
606 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
607 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | ||
608 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | ||
609 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, | ||
610 | &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, | ||
611 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
612 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | ||
613 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, | ||
614 | &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, | ||
615 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | ||
616 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | ||
617 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | ||
618 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | ||
619 | &sensor_dev_attr_temp4_offset.dev_attr.attr, | ||
620 | &sensor_dev_attr_temp5_offset.dev_attr.attr, | ||
621 | &dev_attr_update_interval.attr, | ||
622 | NULL | ||
623 | }; | ||
624 | |||
625 | static const struct attribute_group lm95234_group = { | ||
626 | .attrs = lm95234_attributes, | ||
627 | }; | ||
628 | |||
629 | static int lm95234_detect(struct i2c_client *client, | ||
630 | struct i2c_board_info *info) | ||
631 | { | ||
632 | struct i2c_adapter *adapter = client->adapter; | ||
633 | int mfg_id, chip_id, val; | ||
634 | |||
635 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
636 | return -ENODEV; | ||
637 | |||
638 | mfg_id = i2c_smbus_read_byte_data(client, LM95234_REG_MAN_ID); | ||
639 | if (mfg_id != NATSEMI_MAN_ID) | ||
640 | return -ENODEV; | ||
641 | |||
642 | chip_id = i2c_smbus_read_byte_data(client, LM95234_REG_CHIP_ID); | ||
643 | if (chip_id != LM95234_CHIP_ID) | ||
644 | return -ENODEV; | ||
645 | |||
646 | val = i2c_smbus_read_byte_data(client, LM95234_REG_STATUS); | ||
647 | if (val & 0x30) | ||
648 | return -ENODEV; | ||
649 | |||
650 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG); | ||
651 | if (val & 0xbc) | ||
652 | return -ENODEV; | ||
653 | |||
654 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE); | ||
655 | if (val & 0xfc) | ||
656 | return -ENODEV; | ||
657 | |||
658 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); | ||
659 | if (val & 0xe1) | ||
660 | return -ENODEV; | ||
661 | |||
662 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS); | ||
663 | if (val & 0xe1) | ||
664 | return -ENODEV; | ||
665 | |||
666 | strlcpy(info->type, "lm95234", I2C_NAME_SIZE); | ||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | static int lm95234_init_client(struct i2c_client *client) | ||
671 | { | ||
672 | int val, model; | ||
673 | |||
674 | /* start conversion if necessary */ | ||
675 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG); | ||
676 | if (val < 0) | ||
677 | return val; | ||
678 | if (val & 0x40) | ||
679 | i2c_smbus_write_byte_data(client, LM95234_REG_CONFIG, | ||
680 | val & ~0x40); | ||
681 | |||
682 | /* If diode type status reports an error, try to fix it */ | ||
683 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS); | ||
684 | if (val < 0) | ||
685 | return val; | ||
686 | model = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); | ||
687 | if (model < 0) | ||
688 | return model; | ||
689 | if (model & val) { | ||
690 | dev_notice(&client->dev, | ||
691 | "Fixing remote diode type misconfiguration (0x%x)\n", | ||
692 | val); | ||
693 | i2c_smbus_write_byte_data(client, LM95234_REG_REM_MODEL, | ||
694 | model & ~val); | ||
695 | } | ||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | static int lm95234_probe(struct i2c_client *client, | ||
700 | const struct i2c_device_id *id) | ||
701 | { | ||
702 | struct device *dev = &client->dev; | ||
703 | struct lm95234_data *data; | ||
704 | int err; | ||
705 | |||
706 | data = devm_kzalloc(dev, sizeof(struct lm95234_data), GFP_KERNEL); | ||
707 | if (!data) | ||
708 | return -ENOMEM; | ||
709 | |||
710 | i2c_set_clientdata(client, data); | ||
711 | mutex_init(&data->update_lock); | ||
712 | |||
713 | /* Initialize the LM95234 chip */ | ||
714 | err = lm95234_init_client(client); | ||
715 | if (err < 0) | ||
716 | return err; | ||
717 | |||
718 | /* Register sysfs hooks */ | ||
719 | err = sysfs_create_group(&dev->kobj, &lm95234_group); | ||
720 | if (err) | ||
721 | return err; | ||
722 | |||
723 | data->hwmon_dev = hwmon_device_register(dev); | ||
724 | if (IS_ERR(data->hwmon_dev)) { | ||
725 | err = PTR_ERR(data->hwmon_dev); | ||
726 | goto exit_remove_files; | ||
727 | } | ||
728 | |||
729 | return 0; | ||
730 | |||
731 | exit_remove_files: | ||
732 | sysfs_remove_group(&dev->kobj, &lm95234_group); | ||
733 | return err; | ||
734 | } | ||
735 | |||
736 | static int lm95234_remove(struct i2c_client *client) | ||
737 | { | ||
738 | struct lm95234_data *data = i2c_get_clientdata(client); | ||
739 | |||
740 | hwmon_device_unregister(data->hwmon_dev); | ||
741 | sysfs_remove_group(&client->dev.kobj, &lm95234_group); | ||
742 | |||
743 | return 0; | ||
744 | } | ||
745 | |||
746 | /* Driver data (common to all clients) */ | ||
747 | static const struct i2c_device_id lm95234_id[] = { | ||
748 | { "lm95234", 0 }, | ||
749 | { } | ||
750 | }; | ||
751 | MODULE_DEVICE_TABLE(i2c, lm95234_id); | ||
752 | |||
753 | static struct i2c_driver lm95234_driver = { | ||
754 | .class = I2C_CLASS_HWMON, | ||
755 | .driver = { | ||
756 | .name = DRVNAME, | ||
757 | }, | ||
758 | .probe = lm95234_probe, | ||
759 | .remove = lm95234_remove, | ||
760 | .id_table = lm95234_id, | ||
761 | .detect = lm95234_detect, | ||
762 | .address_list = normal_i2c, | ||
763 | }; | ||
764 | |||
765 | module_i2c_driver(lm95234_driver); | ||
766 | |||
767 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); | ||
768 | MODULE_DESCRIPTION("LM95234 sensor driver"); | ||
769 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hwmon/ltc4151.c b/drivers/hwmon/ltc4151.c index 4319a94f549d..af81be1237c9 100644 --- a/drivers/hwmon/ltc4151.c +++ b/drivers/hwmon/ltc4151.c | |||
@@ -146,14 +146,14 @@ static ssize_t ltc4151_show_value(struct device *dev, | |||
146 | /* | 146 | /* |
147 | * Input voltages. | 147 | * Input voltages. |
148 | */ | 148 | */ |
149 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, \ | 149 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4151_show_value, NULL, |
150 | ltc4151_show_value, NULL, LTC4151_VIN_H); | 150 | LTC4151_VIN_H); |
151 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, \ | 151 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4151_show_value, NULL, |
152 | ltc4151_show_value, NULL, LTC4151_ADIN_H); | 152 | LTC4151_ADIN_H); |
153 | 153 | ||
154 | /* Currents (via sense resistor) */ | 154 | /* Currents (via sense resistor) */ |
155 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, \ | 155 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4151_show_value, NULL, |
156 | ltc4151_show_value, NULL, LTC4151_SENSE_H); | 156 | LTC4151_SENSE_H); |
157 | 157 | ||
158 | /* | 158 | /* |
159 | * Finally, construct an array of pointers to members of the above objects, | 159 | * Finally, construct an array of pointers to members of the above objects, |
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index e8876108a6b3..8a142960d69e 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c | |||
@@ -172,12 +172,12 @@ static ssize_t ltc4215_show_alarm(struct device *dev, | |||
172 | struct device_attribute *da, | 172 | struct device_attribute *da, |
173 | char *buf) | 173 | char *buf) |
174 | { | 174 | { |
175 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da); | 175 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
176 | struct ltc4215_data *data = ltc4215_update_device(dev); | 176 | struct ltc4215_data *data = ltc4215_update_device(dev); |
177 | const u8 reg = data->regs[attr->index]; | 177 | const u8 reg = data->regs[LTC4215_STATUS]; |
178 | const u32 mask = attr->nr; | 178 | const u32 mask = attr->index; |
179 | 179 | ||
180 | return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0); | 180 | return snprintf(buf, PAGE_SIZE, "%u\n", !!(reg & mask)); |
181 | } | 181 | } |
182 | 182 | ||
183 | /* | 183 | /* |
@@ -186,39 +186,29 @@ static ssize_t ltc4215_show_alarm(struct device *dev, | |||
186 | * for each register. | 186 | * for each register. |
187 | */ | 187 | */ |
188 | 188 | ||
189 | #define LTC4215_VOLTAGE(name, ltc4215_cmd_idx) \ | ||
190 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ | ||
191 | ltc4215_show_voltage, NULL, ltc4215_cmd_idx) | ||
192 | |||
193 | #define LTC4215_CURRENT(name) \ | ||
194 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ | ||
195 | ltc4215_show_current, NULL, 0); | ||
196 | |||
197 | #define LTC4215_POWER(name) \ | ||
198 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ | ||
199 | ltc4215_show_power, NULL, 0); | ||
200 | |||
201 | #define LTC4215_ALARM(name, mask, reg) \ | ||
202 | static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \ | ||
203 | ltc4215_show_alarm, NULL, (mask), reg) | ||
204 | |||
205 | /* Construct a sensor_device_attribute structure for each register */ | 189 | /* Construct a sensor_device_attribute structure for each register */ |
206 | 190 | ||
207 | /* Current */ | 191 | /* Current */ |
208 | LTC4215_CURRENT(curr1_input); | 192 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4215_show_current, NULL, 0); |
209 | LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS); | 193 | static SENSOR_DEVICE_ATTR(curr1_max_alarm, S_IRUGO, ltc4215_show_alarm, NULL, |
194 | 1 << 2); | ||
210 | 195 | ||
211 | /* Power (virtual) */ | 196 | /* Power (virtual) */ |
212 | LTC4215_POWER(power1_input); | 197 | static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ltc4215_show_power, NULL, 0); |
213 | 198 | ||
214 | /* Input Voltage */ | 199 | /* Input Voltage */ |
215 | LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); | 200 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4215_show_voltage, NULL, |
216 | LTC4215_ALARM(in1_max_alarm, (1 << 0), LTC4215_STATUS); | 201 | LTC4215_ADIN); |
217 | LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS); | 202 | static SENSOR_DEVICE_ATTR(in1_max_alarm, S_IRUGO, ltc4215_show_alarm, NULL, |
203 | 1 << 0); | ||
204 | static SENSOR_DEVICE_ATTR(in1_min_alarm, S_IRUGO, ltc4215_show_alarm, NULL, | ||
205 | 1 << 1); | ||
218 | 206 | ||
219 | /* Output Voltage */ | 207 | /* Output Voltage */ |
220 | LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); | 208 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4215_show_voltage, NULL, |
221 | LTC4215_ALARM(in2_min_alarm, (1 << 3), LTC4215_STATUS); | 209 | LTC4215_SOURCE); |
210 | static SENSOR_DEVICE_ATTR(in2_min_alarm, S_IRUGO, ltc4215_show_alarm, NULL, | ||
211 | 1 << 3); | ||
222 | 212 | ||
223 | /* | 213 | /* |
224 | * Finally, construct an array of pointers to members of the above objects, | 214 | * Finally, construct an array of pointers to members of the above objects, |
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index 3653f79dc2de..cdc1ecc6734d 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c | |||
@@ -319,80 +319,82 @@ static ssize_t ltc4245_show_gpio(struct device *dev, | |||
319 | return snprintf(buf, PAGE_SIZE, "%u\n", val * 10); | 319 | return snprintf(buf, PAGE_SIZE, "%u\n", val * 10); |
320 | } | 320 | } |
321 | 321 | ||
322 | /* | ||
323 | * These macros are used below in constructing device attribute objects | ||
324 | * for use with sysfs_create_group() to make a sysfs device file | ||
325 | * for each register. | ||
326 | */ | ||
327 | |||
328 | #define LTC4245_VOLTAGE(name, ltc4245_cmd_idx) \ | ||
329 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ | ||
330 | ltc4245_show_voltage, NULL, ltc4245_cmd_idx) | ||
331 | |||
332 | #define LTC4245_CURRENT(name, ltc4245_cmd_idx) \ | ||
333 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ | ||
334 | ltc4245_show_current, NULL, ltc4245_cmd_idx) | ||
335 | |||
336 | #define LTC4245_POWER(name, ltc4245_cmd_idx) \ | ||
337 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ | ||
338 | ltc4245_show_power, NULL, ltc4245_cmd_idx) | ||
339 | |||
340 | #define LTC4245_ALARM(name, mask, reg) \ | ||
341 | static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \ | ||
342 | ltc4245_show_alarm, NULL, (mask), reg) | ||
343 | |||
344 | #define LTC4245_GPIO_VOLTAGE(name, gpio_num) \ | ||
345 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ | ||
346 | ltc4245_show_gpio, NULL, gpio_num) | ||
347 | |||
348 | /* Construct a sensor_device_attribute structure for each register */ | 322 | /* Construct a sensor_device_attribute structure for each register */ |
349 | 323 | ||
350 | /* Input voltages */ | 324 | /* Input voltages */ |
351 | LTC4245_VOLTAGE(in1_input, LTC4245_12VIN); | 325 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4245_show_voltage, NULL, |
352 | LTC4245_VOLTAGE(in2_input, LTC4245_5VIN); | 326 | LTC4245_12VIN); |
353 | LTC4245_VOLTAGE(in3_input, LTC4245_3VIN); | 327 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4245_show_voltage, NULL, |
354 | LTC4245_VOLTAGE(in4_input, LTC4245_VEEIN); | 328 | LTC4245_5VIN); |
329 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ltc4245_show_voltage, NULL, | ||
330 | LTC4245_3VIN); | ||
331 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, ltc4245_show_voltage, NULL, | ||
332 | LTC4245_VEEIN); | ||
355 | 333 | ||
356 | /* Input undervoltage alarms */ | 334 | /* Input undervoltage alarms */ |
357 | LTC4245_ALARM(in1_min_alarm, (1 << 0), LTC4245_FAULT1); | 335 | static SENSOR_DEVICE_ATTR_2(in1_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, |
358 | LTC4245_ALARM(in2_min_alarm, (1 << 1), LTC4245_FAULT1); | 336 | 1 << 0, LTC4245_FAULT1); |
359 | LTC4245_ALARM(in3_min_alarm, (1 << 2), LTC4245_FAULT1); | 337 | static SENSOR_DEVICE_ATTR_2(in2_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, |
360 | LTC4245_ALARM(in4_min_alarm, (1 << 3), LTC4245_FAULT1); | 338 | 1 << 1, LTC4245_FAULT1); |
339 | static SENSOR_DEVICE_ATTR_2(in3_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
340 | 1 << 2, LTC4245_FAULT1); | ||
341 | static SENSOR_DEVICE_ATTR_2(in4_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
342 | 1 << 3, LTC4245_FAULT1); | ||
361 | 343 | ||
362 | /* Currents (via sense resistor) */ | 344 | /* Currents (via sense resistor) */ |
363 | LTC4245_CURRENT(curr1_input, LTC4245_12VSENSE); | 345 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4245_show_current, NULL, |
364 | LTC4245_CURRENT(curr2_input, LTC4245_5VSENSE); | 346 | LTC4245_12VSENSE); |
365 | LTC4245_CURRENT(curr3_input, LTC4245_3VSENSE); | 347 | static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc4245_show_current, NULL, |
366 | LTC4245_CURRENT(curr4_input, LTC4245_VEESENSE); | 348 | LTC4245_5VSENSE); |
349 | static SENSOR_DEVICE_ATTR(curr3_input, S_IRUGO, ltc4245_show_current, NULL, | ||
350 | LTC4245_3VSENSE); | ||
351 | static SENSOR_DEVICE_ATTR(curr4_input, S_IRUGO, ltc4245_show_current, NULL, | ||
352 | LTC4245_VEESENSE); | ||
367 | 353 | ||
368 | /* Overcurrent alarms */ | 354 | /* Overcurrent alarms */ |
369 | LTC4245_ALARM(curr1_max_alarm, (1 << 4), LTC4245_FAULT1); | 355 | static SENSOR_DEVICE_ATTR_2(curr1_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, |
370 | LTC4245_ALARM(curr2_max_alarm, (1 << 5), LTC4245_FAULT1); | 356 | 1 << 4, LTC4245_FAULT1); |
371 | LTC4245_ALARM(curr3_max_alarm, (1 << 6), LTC4245_FAULT1); | 357 | static SENSOR_DEVICE_ATTR_2(curr2_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, |
372 | LTC4245_ALARM(curr4_max_alarm, (1 << 7), LTC4245_FAULT1); | 358 | 1 << 5, LTC4245_FAULT1); |
359 | static SENSOR_DEVICE_ATTR_2(curr3_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
360 | 1 << 6, LTC4245_FAULT1); | ||
361 | static SENSOR_DEVICE_ATTR_2(curr4_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
362 | 1 << 7, LTC4245_FAULT1); | ||
373 | 363 | ||
374 | /* Output voltages */ | 364 | /* Output voltages */ |
375 | LTC4245_VOLTAGE(in5_input, LTC4245_12VOUT); | 365 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ltc4245_show_voltage, NULL, |
376 | LTC4245_VOLTAGE(in6_input, LTC4245_5VOUT); | 366 | LTC4245_12VOUT); |
377 | LTC4245_VOLTAGE(in7_input, LTC4245_3VOUT); | 367 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ltc4245_show_voltage, NULL, |
378 | LTC4245_VOLTAGE(in8_input, LTC4245_VEEOUT); | 368 | LTC4245_5VOUT); |
369 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ltc4245_show_voltage, NULL, | ||
370 | LTC4245_3VOUT); | ||
371 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, ltc4245_show_voltage, NULL, | ||
372 | LTC4245_VEEOUT); | ||
379 | 373 | ||
380 | /* Power Bad alarms */ | 374 | /* Power Bad alarms */ |
381 | LTC4245_ALARM(in5_min_alarm, (1 << 0), LTC4245_FAULT2); | 375 | static SENSOR_DEVICE_ATTR_2(in5_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, |
382 | LTC4245_ALARM(in6_min_alarm, (1 << 1), LTC4245_FAULT2); | 376 | 1 << 0, LTC4245_FAULT2); |
383 | LTC4245_ALARM(in7_min_alarm, (1 << 2), LTC4245_FAULT2); | 377 | static SENSOR_DEVICE_ATTR_2(in6_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, |
384 | LTC4245_ALARM(in8_min_alarm, (1 << 3), LTC4245_FAULT2); | 378 | 1 << 1, LTC4245_FAULT2); |
379 | static SENSOR_DEVICE_ATTR_2(in7_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
380 | 1 << 2, LTC4245_FAULT2); | ||
381 | static SENSOR_DEVICE_ATTR_2(in8_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
382 | 1 << 3, LTC4245_FAULT2); | ||
385 | 383 | ||
386 | /* GPIO voltages */ | 384 | /* GPIO voltages */ |
387 | LTC4245_GPIO_VOLTAGE(in9_input, 0); | 385 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, ltc4245_show_gpio, NULL, 0); |
388 | LTC4245_GPIO_VOLTAGE(in10_input, 1); | 386 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, ltc4245_show_gpio, NULL, 1); |
389 | LTC4245_GPIO_VOLTAGE(in11_input, 2); | 387 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, ltc4245_show_gpio, NULL, 2); |
390 | 388 | ||
391 | /* Power Consumption (virtual) */ | 389 | /* Power Consumption (virtual) */ |
392 | LTC4245_POWER(power1_input, LTC4245_12VSENSE); | 390 | static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ltc4245_show_power, NULL, |
393 | LTC4245_POWER(power2_input, LTC4245_5VSENSE); | 391 | LTC4245_12VSENSE); |
394 | LTC4245_POWER(power3_input, LTC4245_3VSENSE); | 392 | static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, ltc4245_show_power, NULL, |
395 | LTC4245_POWER(power4_input, LTC4245_VEESENSE); | 393 | LTC4245_5VSENSE); |
394 | static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO, ltc4245_show_power, NULL, | ||
395 | LTC4245_3VSENSE); | ||
396 | static SENSOR_DEVICE_ATTR(power4_input, S_IRUGO, ltc4245_show_power, NULL, | ||
397 | LTC4245_VEESENSE); | ||
396 | 398 | ||
397 | /* | 399 | /* |
398 | * Finally, construct an array of pointers to members of the above objects, | 400 | * Finally, construct an array of pointers to members of the above objects, |
diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 84a2d2872b20..487da58ec86c 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c | |||
@@ -165,24 +165,12 @@ static ssize_t ltc4261_show_bool(struct device *dev, | |||
165 | } | 165 | } |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * These macros are used below in constructing device attribute objects | ||
169 | * for use with sysfs_create_group() to make a sysfs device file | ||
170 | * for each register. | ||
171 | */ | ||
172 | |||
173 | #define LTC4261_VALUE(name, ltc4261_cmd_idx) \ | ||
174 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ | ||
175 | ltc4261_show_value, NULL, ltc4261_cmd_idx) | ||
176 | |||
177 | #define LTC4261_BOOL(name, mask) \ | ||
178 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ | ||
179 | ltc4261_show_bool, NULL, (mask)) | ||
180 | |||
181 | /* | ||
182 | * Input voltages. | 168 | * Input voltages. |
183 | */ | 169 | */ |
184 | LTC4261_VALUE(in1_input, LTC4261_ADIN_H); | 170 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4261_show_value, NULL, |
185 | LTC4261_VALUE(in2_input, LTC4261_ADIN2_H); | 171 | LTC4261_ADIN_H); |
172 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4261_show_value, NULL, | ||
173 | LTC4261_ADIN2_H); | ||
186 | 174 | ||
187 | /* | 175 | /* |
188 | * Voltage alarms. The chip has only one set of voltage alarm status bits, | 176 | * Voltage alarms. The chip has only one set of voltage alarm status bits, |
@@ -192,16 +180,22 @@ LTC4261_VALUE(in2_input, LTC4261_ADIN2_H); | |||
192 | * To ensure that the alarm condition is reported to the user, report it | 180 | * To ensure that the alarm condition is reported to the user, report it |
193 | * with both voltage sensors. | 181 | * with both voltage sensors. |
194 | */ | 182 | */ |
195 | LTC4261_BOOL(in1_min_alarm, FAULT_UV); | 183 | static SENSOR_DEVICE_ATTR(in1_min_alarm, S_IRUGO, ltc4261_show_bool, NULL, |
196 | LTC4261_BOOL(in1_max_alarm, FAULT_OV); | 184 | FAULT_UV); |
197 | LTC4261_BOOL(in2_min_alarm, FAULT_UV); | 185 | static SENSOR_DEVICE_ATTR(in1_max_alarm, S_IRUGO, ltc4261_show_bool, NULL, |
198 | LTC4261_BOOL(in2_max_alarm, FAULT_OV); | 186 | FAULT_OV); |
187 | static SENSOR_DEVICE_ATTR(in2_min_alarm, S_IRUGO, ltc4261_show_bool, NULL, | ||
188 | FAULT_UV); | ||
189 | static SENSOR_DEVICE_ATTR(in2_max_alarm, S_IRUGO, ltc4261_show_bool, NULL, | ||
190 | FAULT_OV); | ||
199 | 191 | ||
200 | /* Currents (via sense resistor) */ | 192 | /* Currents (via sense resistor) */ |
201 | LTC4261_VALUE(curr1_input, LTC4261_SENSE_H); | 193 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4261_show_value, NULL, |
194 | LTC4261_SENSE_H); | ||
202 | 195 | ||
203 | /* Overcurrent alarm */ | 196 | /* Overcurrent alarm */ |
204 | LTC4261_BOOL(curr1_max_alarm, FAULT_OC); | 197 | static SENSOR_DEVICE_ATTR(curr1_max_alarm, S_IRUGO, ltc4261_show_bool, NULL, |
198 | FAULT_OC); | ||
205 | 199 | ||
206 | static struct attribute *ltc4261_attributes[] = { | 200 | static struct attribute *ltc4261_attributes[] = { |
207 | &sensor_dev_attr_in1_input.dev_attr.attr, | 201 | &sensor_dev_attr_in1_input.dev_attr.attr, |
diff --git a/drivers/hwmon/max6697.c b/drivers/hwmon/max6697.c index bf4aa3777fc1..328fb0353c17 100644 --- a/drivers/hwmon/max6697.c +++ b/drivers/hwmon/max6697.c | |||
@@ -399,82 +399,95 @@ static SENSOR_DEVICE_ATTR(temp6_fault, S_IRUGO, show_alarm, NULL, 5); | |||
399 | static SENSOR_DEVICE_ATTR(temp7_fault, S_IRUGO, show_alarm, NULL, 6); | 399 | static SENSOR_DEVICE_ATTR(temp7_fault, S_IRUGO, show_alarm, NULL, 6); |
400 | static SENSOR_DEVICE_ATTR(temp8_fault, S_IRUGO, show_alarm, NULL, 7); | 400 | static SENSOR_DEVICE_ATTR(temp8_fault, S_IRUGO, show_alarm, NULL, 7); |
401 | 401 | ||
402 | static struct attribute *max6697_attributes[8][7] = { | 402 | static DEVICE_ATTR(dummy, 0, NULL, NULL); |
403 | { | 403 | |
404 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 404 | static umode_t max6697_is_visible(struct kobject *kobj, struct attribute *attr, |
405 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 405 | int index) |
406 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 406 | { |
407 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | 407 | struct device *dev = container_of(kobj, struct device, kobj); |
408 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | 408 | struct i2c_client *client = to_i2c_client(dev); |
409 | NULL | 409 | struct max6697_data *data = i2c_get_clientdata(client); |
410 | }, { | 410 | const struct max6697_chip_data *chip = data->chip; |
411 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 411 | int channel = index / 6; /* channel number */ |
412 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 412 | int nr = index % 6; /* attribute index within channel */ |
413 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 413 | |
414 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | 414 | if (channel >= chip->channels) |
415 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | 415 | return 0; |
416 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | 416 | |
417 | NULL | 417 | if ((nr == 3 || nr == 4) && !(chip->have_crit & (1 << channel))) |
418 | }, { | 418 | return 0; |
419 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 419 | if (nr == 5 && !(chip->have_fault & (1 << channel))) |
420 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 420 | return 0; |
421 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | 421 | |
422 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | 422 | return attr->mode; |
423 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | 423 | } |
424 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | 424 | |
425 | NULL | 425 | /* |
426 | }, { | 426 | * max6697_is_visible uses the index into the following array to determine |
427 | &sensor_dev_attr_temp4_input.dev_attr.attr, | 427 | * if attributes should be created or not. Any change in order or content |
428 | &sensor_dev_attr_temp4_max.dev_attr.attr, | 428 | * must be matched in max6697_is_visible. |
429 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, | 429 | */ |
430 | &sensor_dev_attr_temp4_crit.dev_attr.attr, | 430 | static struct attribute *max6697_attributes[] = { |
431 | &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, | 431 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
432 | &sensor_dev_attr_temp4_fault.dev_attr.attr, | 432 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
433 | NULL | 433 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
434 | }, { | 434 | &sensor_dev_attr_temp1_crit.dev_attr.attr, |
435 | &sensor_dev_attr_temp5_input.dev_attr.attr, | 435 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
436 | &sensor_dev_attr_temp5_max.dev_attr.attr, | 436 | &dev_attr_dummy.attr, |
437 | &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, | 437 | |
438 | &sensor_dev_attr_temp5_crit.dev_attr.attr, | 438 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
439 | &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr, | 439 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
440 | &sensor_dev_attr_temp5_fault.dev_attr.attr, | 440 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
441 | NULL | 441 | &sensor_dev_attr_temp2_crit.dev_attr.attr, |
442 | }, { | 442 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, |
443 | &sensor_dev_attr_temp6_input.dev_attr.attr, | 443 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
444 | &sensor_dev_attr_temp6_max.dev_attr.attr, | 444 | |
445 | &sensor_dev_attr_temp6_max_alarm.dev_attr.attr, | 445 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
446 | &sensor_dev_attr_temp6_crit.dev_attr.attr, | 446 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
447 | &sensor_dev_attr_temp6_crit_alarm.dev_attr.attr, | 447 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, |
448 | &sensor_dev_attr_temp6_fault.dev_attr.attr, | 448 | &sensor_dev_attr_temp3_crit.dev_attr.attr, |
449 | NULL | 449 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, |
450 | }, { | 450 | &sensor_dev_attr_temp3_fault.dev_attr.attr, |
451 | &sensor_dev_attr_temp7_input.dev_attr.attr, | 451 | |
452 | &sensor_dev_attr_temp7_max.dev_attr.attr, | 452 | &sensor_dev_attr_temp4_input.dev_attr.attr, |
453 | &sensor_dev_attr_temp7_max_alarm.dev_attr.attr, | 453 | &sensor_dev_attr_temp4_max.dev_attr.attr, |
454 | &sensor_dev_attr_temp7_crit.dev_attr.attr, | 454 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, |
455 | &sensor_dev_attr_temp7_crit_alarm.dev_attr.attr, | 455 | &sensor_dev_attr_temp4_crit.dev_attr.attr, |
456 | &sensor_dev_attr_temp7_fault.dev_attr.attr, | 456 | &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, |
457 | NULL | 457 | &sensor_dev_attr_temp4_fault.dev_attr.attr, |
458 | }, { | 458 | |
459 | &sensor_dev_attr_temp8_input.dev_attr.attr, | 459 | &sensor_dev_attr_temp5_input.dev_attr.attr, |
460 | &sensor_dev_attr_temp8_max.dev_attr.attr, | 460 | &sensor_dev_attr_temp5_max.dev_attr.attr, |
461 | &sensor_dev_attr_temp8_max_alarm.dev_attr.attr, | 461 | &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, |
462 | &sensor_dev_attr_temp8_crit.dev_attr.attr, | 462 | &sensor_dev_attr_temp5_crit.dev_attr.attr, |
463 | &sensor_dev_attr_temp8_crit_alarm.dev_attr.attr, | 463 | &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr, |
464 | &sensor_dev_attr_temp8_fault.dev_attr.attr, | 464 | &sensor_dev_attr_temp5_fault.dev_attr.attr, |
465 | NULL | 465 | |
466 | } | 466 | &sensor_dev_attr_temp6_input.dev_attr.attr, |
467 | &sensor_dev_attr_temp6_max.dev_attr.attr, | ||
468 | &sensor_dev_attr_temp6_max_alarm.dev_attr.attr, | ||
469 | &sensor_dev_attr_temp6_crit.dev_attr.attr, | ||
470 | &sensor_dev_attr_temp6_crit_alarm.dev_attr.attr, | ||
471 | &sensor_dev_attr_temp6_fault.dev_attr.attr, | ||
472 | |||
473 | &sensor_dev_attr_temp7_input.dev_attr.attr, | ||
474 | &sensor_dev_attr_temp7_max.dev_attr.attr, | ||
475 | &sensor_dev_attr_temp7_max_alarm.dev_attr.attr, | ||
476 | &sensor_dev_attr_temp7_crit.dev_attr.attr, | ||
477 | &sensor_dev_attr_temp7_crit_alarm.dev_attr.attr, | ||
478 | &sensor_dev_attr_temp7_fault.dev_attr.attr, | ||
479 | |||
480 | &sensor_dev_attr_temp8_input.dev_attr.attr, | ||
481 | &sensor_dev_attr_temp8_max.dev_attr.attr, | ||
482 | &sensor_dev_attr_temp8_max_alarm.dev_attr.attr, | ||
483 | &sensor_dev_attr_temp8_crit.dev_attr.attr, | ||
484 | &sensor_dev_attr_temp8_crit_alarm.dev_attr.attr, | ||
485 | &sensor_dev_attr_temp8_fault.dev_attr.attr, | ||
486 | NULL | ||
467 | }; | 487 | }; |
468 | 488 | ||
469 | static const struct attribute_group max6697_group[8] = { | 489 | static const struct attribute_group max6697_group = { |
470 | { .attrs = max6697_attributes[0] }, | 490 | .attrs = max6697_attributes, .is_visible = max6697_is_visible, |
471 | { .attrs = max6697_attributes[1] }, | ||
472 | { .attrs = max6697_attributes[2] }, | ||
473 | { .attrs = max6697_attributes[3] }, | ||
474 | { .attrs = max6697_attributes[4] }, | ||
475 | { .attrs = max6697_attributes[5] }, | ||
476 | { .attrs = max6697_attributes[6] }, | ||
477 | { .attrs = max6697_attributes[7] }, | ||
478 | }; | 491 | }; |
479 | 492 | ||
480 | static void max6697_get_config_of(struct device_node *node, | 493 | static void max6697_get_config_of(struct device_node *node, |
@@ -606,21 +619,13 @@ done: | |||
606 | return 0; | 619 | return 0; |
607 | } | 620 | } |
608 | 621 | ||
609 | static void max6697_remove_files(struct i2c_client *client) | ||
610 | { | ||
611 | int i; | ||
612 | |||
613 | for (i = 0; i < ARRAY_SIZE(max6697_group); i++) | ||
614 | sysfs_remove_group(&client->dev.kobj, &max6697_group[i]); | ||
615 | } | ||
616 | |||
617 | static int max6697_probe(struct i2c_client *client, | 622 | static int max6697_probe(struct i2c_client *client, |
618 | const struct i2c_device_id *id) | 623 | const struct i2c_device_id *id) |
619 | { | 624 | { |
620 | struct i2c_adapter *adapter = client->adapter; | 625 | struct i2c_adapter *adapter = client->adapter; |
621 | struct device *dev = &client->dev; | 626 | struct device *dev = &client->dev; |
622 | struct max6697_data *data; | 627 | struct max6697_data *data; |
623 | int i, err; | 628 | int err; |
624 | 629 | ||
625 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 630 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
626 | return -ENODEV; | 631 | return -ENODEV; |
@@ -639,37 +644,9 @@ static int max6697_probe(struct i2c_client *client, | |||
639 | if (err) | 644 | if (err) |
640 | return err; | 645 | return err; |
641 | 646 | ||
642 | for (i = 0; i < data->chip->channels; i++) { | 647 | err = sysfs_create_group(&client->dev.kobj, &max6697_group); |
643 | err = sysfs_create_file(&dev->kobj, | 648 | if (err) |
644 | max6697_attributes[i][0]); | 649 | return err; |
645 | if (err) | ||
646 | goto error; | ||
647 | err = sysfs_create_file(&dev->kobj, | ||
648 | max6697_attributes[i][1]); | ||
649 | if (err) | ||
650 | goto error; | ||
651 | err = sysfs_create_file(&dev->kobj, | ||
652 | max6697_attributes[i][2]); | ||
653 | if (err) | ||
654 | goto error; | ||
655 | |||
656 | if (data->chip->have_crit & (1 << i)) { | ||
657 | err = sysfs_create_file(&dev->kobj, | ||
658 | max6697_attributes[i][3]); | ||
659 | if (err) | ||
660 | goto error; | ||
661 | err = sysfs_create_file(&dev->kobj, | ||
662 | max6697_attributes[i][4]); | ||
663 | if (err) | ||
664 | goto error; | ||
665 | } | ||
666 | if (data->chip->have_fault & (1 << i)) { | ||
667 | err = sysfs_create_file(&dev->kobj, | ||
668 | max6697_attributes[i][5]); | ||
669 | if (err) | ||
670 | goto error; | ||
671 | } | ||
672 | } | ||
673 | 650 | ||
674 | data->hwmon_dev = hwmon_device_register(dev); | 651 | data->hwmon_dev = hwmon_device_register(dev); |
675 | if (IS_ERR(data->hwmon_dev)) { | 652 | if (IS_ERR(data->hwmon_dev)) { |
@@ -680,7 +657,7 @@ static int max6697_probe(struct i2c_client *client, | |||
680 | return 0; | 657 | return 0; |
681 | 658 | ||
682 | error: | 659 | error: |
683 | max6697_remove_files(client); | 660 | sysfs_remove_group(&client->dev.kobj, &max6697_group); |
684 | return err; | 661 | return err; |
685 | } | 662 | } |
686 | 663 | ||
@@ -689,7 +666,7 @@ static int max6697_remove(struct i2c_client *client) | |||
689 | struct max6697_data *data = i2c_get_clientdata(client); | 666 | struct max6697_data *data = i2c_get_clientdata(client); |
690 | 667 | ||
691 | hwmon_device_unregister(data->hwmon_dev); | 668 | hwmon_device_unregister(data->hwmon_dev); |
692 | max6697_remove_files(client); | 669 | sysfs_remove_group(&client->dev.kobj, &max6697_group); |
693 | 670 | ||
694 | return 0; | 671 | return 0; |
695 | } | 672 | } |
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c index 2a7f331cd3c0..982d8622c09b 100644 --- a/drivers/hwmon/mc13783-adc.c +++ b/drivers/hwmon/mc13783-adc.c | |||
@@ -273,18 +273,7 @@ static struct platform_driver mc13783_adc_driver = { | |||
273 | .id_table = mc13783_adc_idtable, | 273 | .id_table = mc13783_adc_idtable, |
274 | }; | 274 | }; |
275 | 275 | ||
276 | static int __init mc13783_adc_init(void) | 276 | module_platform_driver_probe(mc13783_adc_driver, mc13783_adc_probe); |
277 | { | ||
278 | return platform_driver_probe(&mc13783_adc_driver, mc13783_adc_probe); | ||
279 | } | ||
280 | |||
281 | static void __exit mc13783_adc_exit(void) | ||
282 | { | ||
283 | platform_driver_unregister(&mc13783_adc_driver); | ||
284 | } | ||
285 | |||
286 | module_init(mc13783_adc_init); | ||
287 | module_exit(mc13783_adc_exit); | ||
288 | 277 | ||
289 | MODULE_DESCRIPTION("MC13783 ADC driver"); | 278 | MODULE_DESCRIPTION("MC13783 ADC driver"); |
290 | MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); | 279 | MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); |
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c new file mode 100644 index 000000000000..f43f5e571db9 --- /dev/null +++ b/drivers/hwmon/nct6775.c | |||
@@ -0,0 +1,4191 @@ | |||
1 | /* | ||
2 | * nct6775 - Driver for the hardware monitoring functionality of | ||
3 | * Nuvoton NCT677x Super-I/O chips | ||
4 | * | ||
5 | * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net> | ||
6 | * | ||
7 | * Derived from w83627ehf driver | ||
8 | * Copyright (C) 2005-2012 Jean Delvare <khali@linux-fr.org> | ||
9 | * Copyright (C) 2006 Yuan Mu (Winbond), | ||
10 | * Rudolf Marek <r.marek@assembler.cz> | ||
11 | * David Hubbard <david.c.hubbard@gmail.com> | ||
12 | * Daniel J Blueman <daniel.blueman@gmail.com> | ||
13 | * Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00) | ||
14 | * | ||
15 | * Shamelessly ripped from the w83627hf driver | ||
16 | * Copyright (C) 2003 Mark Studebaker | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or modify | ||
19 | * it under the terms of the GNU General Public License as published by | ||
20 | * the Free Software Foundation; either version 2 of the License, or | ||
21 | * (at your option) any later version. | ||
22 | * | ||
23 | * This program is distributed in the hope that it will be useful, | ||
24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
26 | * GNU General Public License for more details. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License | ||
29 | * along with this program; if not, write to the Free Software | ||
30 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
31 | * | ||
32 | * | ||
33 | * Supports the following chips: | ||
34 | * | ||
35 | * Chip #vin #fan #pwm #temp chip IDs man ID | ||
36 | * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3 | ||
37 | * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3 | ||
38 | * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3 | ||
39 | * | ||
40 | * #temp lists the number of monitored temperature sources (first value) plus | ||
41 | * the number of directly connectable temperature sensors (second value). | ||
42 | */ | ||
43 | |||
44 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
45 | |||
46 | #include <linux/module.h> | ||
47 | #include <linux/init.h> | ||
48 | #include <linux/slab.h> | ||
49 | #include <linux/jiffies.h> | ||
50 | #include <linux/platform_device.h> | ||
51 | #include <linux/hwmon.h> | ||
52 | #include <linux/hwmon-sysfs.h> | ||
53 | #include <linux/hwmon-vid.h> | ||
54 | #include <linux/err.h> | ||
55 | #include <linux/mutex.h> | ||
56 | #include <linux/acpi.h> | ||
57 | #include <linux/io.h> | ||
58 | #include "lm75.h" | ||
59 | |||
60 | #define USE_ALTERNATE | ||
61 | |||
62 | enum kinds { nct6775, nct6776, nct6779 }; | ||
63 | |||
64 | /* used to set data->name = nct6775_device_names[data->sio_kind] */ | ||
65 | static const char * const nct6775_device_names[] = { | ||
66 | "nct6775", | ||
67 | "nct6776", | ||
68 | "nct6779", | ||
69 | }; | ||
70 | |||
71 | static unsigned short force_id; | ||
72 | module_param(force_id, ushort, 0); | ||
73 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
74 | |||
75 | static unsigned short fan_debounce; | ||
76 | module_param(fan_debounce, ushort, 0); | ||
77 | MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal"); | ||
78 | |||
79 | #define DRVNAME "nct6775" | ||
80 | |||
81 | /* | ||
82 | * Super-I/O constants and functions | ||
83 | */ | ||
84 | |||
85 | #define NCT6775_LD_ACPI 0x0a | ||
86 | #define NCT6775_LD_HWM 0x0b | ||
87 | #define NCT6775_LD_VID 0x0d | ||
88 | |||
89 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | ||
90 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | ||
91 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | ||
92 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | ||
93 | |||
94 | #define SIO_NCT6775_ID 0xb470 | ||
95 | #define SIO_NCT6776_ID 0xc330 | ||
96 | #define SIO_NCT6779_ID 0xc560 | ||
97 | #define SIO_ID_MASK 0xFFF0 | ||
98 | |||
99 | enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; | ||
100 | |||
101 | static inline void | ||
102 | superio_outb(int ioreg, int reg, int val) | ||
103 | { | ||
104 | outb(reg, ioreg); | ||
105 | outb(val, ioreg + 1); | ||
106 | } | ||
107 | |||
108 | static inline int | ||
109 | superio_inb(int ioreg, int reg) | ||
110 | { | ||
111 | outb(reg, ioreg); | ||
112 | return inb(ioreg + 1); | ||
113 | } | ||
114 | |||
115 | static inline void | ||
116 | superio_select(int ioreg, int ld) | ||
117 | { | ||
118 | outb(SIO_REG_LDSEL, ioreg); | ||
119 | outb(ld, ioreg + 1); | ||
120 | } | ||
121 | |||
122 | static inline int | ||
123 | superio_enter(int ioreg) | ||
124 | { | ||
125 | /* | ||
126 | * Try to reserve <ioreg> and <ioreg + 1> for exclusive access. | ||
127 | */ | ||
128 | if (!request_muxed_region(ioreg, 2, DRVNAME)) | ||
129 | return -EBUSY; | ||
130 | |||
131 | outb(0x87, ioreg); | ||
132 | outb(0x87, ioreg); | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static inline void | ||
138 | superio_exit(int ioreg) | ||
139 | { | ||
140 | outb(0xaa, ioreg); | ||
141 | outb(0x02, ioreg); | ||
142 | outb(0x02, ioreg + 1); | ||
143 | release_region(ioreg, 2); | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * ISA constants | ||
148 | */ | ||
149 | |||
150 | #define IOREGION_ALIGNMENT (~7) | ||
151 | #define IOREGION_OFFSET 5 | ||
152 | #define IOREGION_LENGTH 2 | ||
153 | #define ADDR_REG_OFFSET 0 | ||
154 | #define DATA_REG_OFFSET 1 | ||
155 | |||
156 | #define NCT6775_REG_BANK 0x4E | ||
157 | #define NCT6775_REG_CONFIG 0x40 | ||
158 | |||
159 | /* | ||
160 | * Not currently used: | ||
161 | * REG_MAN_ID has the value 0x5ca3 for all supported chips. | ||
162 | * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. | ||
163 | * REG_MAN_ID is at port 0x4f | ||
164 | * REG_CHIP_ID is at port 0x58 | ||
165 | */ | ||
166 | |||
167 | #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 */ | ||
169 | |||
170 | #define NUM_REG_ALARM 4 /* Max number of alarm registers */ | ||
171 | |||
172 | /* Common and NCT6775 specific data */ | ||
173 | |||
174 | /* Voltage min/max registers for nr=7..14 are in bank 5 */ | ||
175 | |||
176 | static const u16 NCT6775_REG_IN_MAX[] = { | ||
177 | 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x554, 0x556, 0x558, 0x55a, | ||
178 | 0x55c, 0x55e, 0x560, 0x562 }; | ||
179 | static const u16 NCT6775_REG_IN_MIN[] = { | ||
180 | 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x555, 0x557, 0x559, 0x55b, | ||
181 | 0x55d, 0x55f, 0x561, 0x563 }; | ||
182 | static const u16 NCT6775_REG_IN[] = { | ||
183 | 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551, 0x552 | ||
184 | }; | ||
185 | |||
186 | #define NCT6775_REG_VBAT 0x5D | ||
187 | #define NCT6775_REG_DIODE 0x5E | ||
188 | |||
189 | #define NCT6775_REG_FANDIV1 0x506 | ||
190 | #define NCT6775_REG_FANDIV2 0x507 | ||
191 | |||
192 | #define NCT6775_REG_CR_FAN_DEBOUNCE 0xf0 | ||
193 | |||
194 | static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B }; | ||
195 | |||
196 | /* 0..15 voltages, 16..23 fans, 24..31 temperatures */ | ||
197 | |||
198 | static const s8 NCT6775_ALARM_BITS[] = { | ||
199 | 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */ | ||
200 | 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */ | ||
201 | -1, /* unused */ | ||
202 | 6, 7, 11, 10, 23, /* fan1..fan5 */ | ||
203 | -1, -1, -1, /* unused */ | ||
204 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ | ||
205 | 12, -1 }; /* intrusion0, intrusion1 */ | ||
206 | |||
207 | #define FAN_ALARM_BASE 16 | ||
208 | #define TEMP_ALARM_BASE 24 | ||
209 | #define INTRUSION_ALARM_BASE 30 | ||
210 | |||
211 | static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee }; | ||
212 | static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 }; | ||
213 | |||
214 | /* DC or PWM output fan configuration */ | ||
215 | static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 }; | ||
216 | static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 }; | ||
217 | |||
218 | /* Advanced Fan control, some values are common for all fans */ | ||
219 | |||
220 | static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301, 0x801, 0x901 }; | ||
221 | static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302, 0x802, 0x902 }; | ||
222 | static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = { | ||
223 | 0x103, 0x203, 0x303, 0x803, 0x903 }; | ||
224 | static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = { | ||
225 | 0x104, 0x204, 0x304, 0x804, 0x904 }; | ||
226 | static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { | ||
227 | 0x105, 0x205, 0x305, 0x805, 0x905 }; | ||
228 | static const u16 NCT6775_REG_FAN_START_OUTPUT[] | ||
229 | = { 0x106, 0x206, 0x306, 0x806, 0x906 }; | ||
230 | static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a }; | ||
231 | static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b }; | ||
232 | |||
233 | static const u16 NCT6775_REG_FAN_STOP_TIME[] = { | ||
234 | 0x107, 0x207, 0x307, 0x807, 0x907 }; | ||
235 | static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309, 0x809, 0x909 }; | ||
236 | static const u16 NCT6775_REG_PWM_READ[] = { 0x01, 0x03, 0x11, 0x13, 0x15 }; | ||
237 | |||
238 | static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; | ||
239 | static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d }; | ||
240 | static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 }; | ||
241 | |||
242 | static const u16 NCT6775_REG_TEMP[] = { | ||
243 | 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d }; | ||
244 | |||
245 | static const u16 NCT6775_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { | ||
246 | 0, 0x152, 0x252, 0x628, 0x629, 0x62A }; | ||
247 | static const u16 NCT6775_REG_TEMP_HYST[ARRAY_SIZE(NCT6775_REG_TEMP)] = { | ||
248 | 0x3a, 0x153, 0x253, 0x673, 0x678, 0x67D }; | ||
249 | static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = { | ||
250 | 0x39, 0x155, 0x255, 0x672, 0x677, 0x67C }; | ||
251 | |||
252 | static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = { | ||
253 | 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 }; | ||
254 | |||
255 | static const u16 NCT6775_REG_TEMP_SEL[] = { | ||
256 | 0x100, 0x200, 0x300, 0x800, 0x900 }; | ||
257 | |||
258 | static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = { | ||
259 | 0x139, 0x239, 0x339, 0x839, 0x939 }; | ||
260 | static const u16 NCT6775_REG_WEIGHT_TEMP_STEP[] = { | ||
261 | 0x13a, 0x23a, 0x33a, 0x83a, 0x93a }; | ||
262 | static const u16 NCT6775_REG_WEIGHT_TEMP_STEP_TOL[] = { | ||
263 | 0x13b, 0x23b, 0x33b, 0x83b, 0x93b }; | ||
264 | static const u16 NCT6775_REG_WEIGHT_DUTY_STEP[] = { | ||
265 | 0x13c, 0x23c, 0x33c, 0x83c, 0x93c }; | ||
266 | static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = { | ||
267 | 0x13d, 0x23d, 0x33d, 0x83d, 0x93d }; | ||
268 | |||
269 | static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; | ||
270 | |||
271 | static const u16 NCT6775_REG_AUTO_TEMP[] = { | ||
272 | 0x121, 0x221, 0x321, 0x821, 0x921 }; | ||
273 | static const u16 NCT6775_REG_AUTO_PWM[] = { | ||
274 | 0x127, 0x227, 0x327, 0x827, 0x927 }; | ||
275 | |||
276 | #define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p)) | ||
277 | #define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p)) | ||
278 | |||
279 | static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 }; | ||
280 | |||
281 | static const u16 NCT6775_REG_CRITICAL_TEMP[] = { | ||
282 | 0x135, 0x235, 0x335, 0x835, 0x935 }; | ||
283 | static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = { | ||
284 | 0x138, 0x238, 0x338, 0x838, 0x938 }; | ||
285 | |||
286 | static const char *const nct6775_temp_label[] = { | ||
287 | "", | ||
288 | "SYSTIN", | ||
289 | "CPUTIN", | ||
290 | "AUXTIN", | ||
291 | "AMD SB-TSI", | ||
292 | "PECI Agent 0", | ||
293 | "PECI Agent 1", | ||
294 | "PECI Agent 2", | ||
295 | "PECI Agent 3", | ||
296 | "PECI Agent 4", | ||
297 | "PECI Agent 5", | ||
298 | "PECI Agent 6", | ||
299 | "PECI Agent 7", | ||
300 | "PCH_CHIP_CPU_MAX_TEMP", | ||
301 | "PCH_CHIP_TEMP", | ||
302 | "PCH_CPU_TEMP", | ||
303 | "PCH_MCH_TEMP", | ||
304 | "PCH_DIM0_TEMP", | ||
305 | "PCH_DIM1_TEMP", | ||
306 | "PCH_DIM2_TEMP", | ||
307 | "PCH_DIM3_TEMP" | ||
308 | }; | ||
309 | |||
310 | static const u16 NCT6775_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6775_temp_label) - 1] | ||
311 | = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x661, 0x662, 0x664 }; | ||
312 | |||
313 | static const u16 NCT6775_REG_TEMP_CRIT[ARRAY_SIZE(nct6775_temp_label) - 1] | ||
314 | = { 0, 0, 0, 0, 0xa00, 0xa01, 0xa02, 0xa03, 0xa04, 0xa05, 0xa06, | ||
315 | 0xa07 }; | ||
316 | |||
317 | /* NCT6776 specific data */ | ||
318 | |||
319 | static const s8 NCT6776_ALARM_BITS[] = { | ||
320 | 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */ | ||
321 | 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */ | ||
322 | -1, /* unused */ | ||
323 | 6, 7, 11, 10, 23, /* fan1..fan5 */ | ||
324 | -1, -1, -1, /* unused */ | ||
325 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ | ||
326 | 12, 9 }; /* intrusion0, intrusion1 */ | ||
327 | |||
328 | static const u16 NCT6776_REG_TOLERANCE_H[] = { | ||
329 | 0x10c, 0x20c, 0x30c, 0x80c, 0x90c }; | ||
330 | |||
331 | static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0 }; | ||
332 | static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 }; | ||
333 | |||
334 | static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 }; | ||
335 | static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 }; | ||
336 | |||
337 | static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = { | ||
338 | 0x13e, 0x23e, 0x33e, 0x83e, 0x93e }; | ||
339 | |||
340 | static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { | ||
341 | 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A }; | ||
342 | |||
343 | static const char *const nct6776_temp_label[] = { | ||
344 | "", | ||
345 | "SYSTIN", | ||
346 | "CPUTIN", | ||
347 | "AUXTIN", | ||
348 | "SMBUSMASTER 0", | ||
349 | "SMBUSMASTER 1", | ||
350 | "SMBUSMASTER 2", | ||
351 | "SMBUSMASTER 3", | ||
352 | "SMBUSMASTER 4", | ||
353 | "SMBUSMASTER 5", | ||
354 | "SMBUSMASTER 6", | ||
355 | "SMBUSMASTER 7", | ||
356 | "PECI Agent 0", | ||
357 | "PECI Agent 1", | ||
358 | "PCH_CHIP_CPU_MAX_TEMP", | ||
359 | "PCH_CHIP_TEMP", | ||
360 | "PCH_CPU_TEMP", | ||
361 | "PCH_MCH_TEMP", | ||
362 | "PCH_DIM0_TEMP", | ||
363 | "PCH_DIM1_TEMP", | ||
364 | "PCH_DIM2_TEMP", | ||
365 | "PCH_DIM3_TEMP", | ||
366 | "BYTE_TEMP" | ||
367 | }; | ||
368 | |||
369 | static const u16 NCT6776_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1] | ||
370 | = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x401, 0x402, 0x404 }; | ||
371 | |||
372 | static const u16 NCT6776_REG_TEMP_CRIT[ARRAY_SIZE(nct6776_temp_label) - 1] | ||
373 | = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a }; | ||
374 | |||
375 | /* NCT6779 specific data */ | ||
376 | |||
377 | static const u16 NCT6779_REG_IN[] = { | ||
378 | 0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487, | ||
379 | 0x488, 0x489, 0x48a, 0x48b, 0x48c, 0x48d, 0x48e }; | ||
380 | |||
381 | static const u16 NCT6779_REG_ALARM[NUM_REG_ALARM] = { | ||
382 | 0x459, 0x45A, 0x45B, 0x568 }; | ||
383 | |||
384 | static const s8 NCT6779_ALARM_BITS[] = { | ||
385 | 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */ | ||
386 | 17, 24, 25, 26, 27, 28, 29, /* in8..in14 */ | ||
387 | -1, /* unused */ | ||
388 | 6, 7, 11, 10, 23, /* fan1..fan5 */ | ||
389 | -1, -1, -1, /* unused */ | ||
390 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ | ||
391 | 12, 9 }; /* intrusion0, intrusion1 */ | ||
392 | |||
393 | static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 }; | ||
394 | static const u16 NCT6779_REG_FAN_PULSES[] = { | ||
395 | 0x644, 0x645, 0x646, 0x647, 0x648 }; | ||
396 | |||
397 | static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = { | ||
398 | 0x136, 0x236, 0x336, 0x836, 0x936 }; | ||
399 | static const u16 NCT6779_REG_CRITICAL_PWM[] = { | ||
400 | 0x137, 0x237, 0x337, 0x837, 0x937 }; | ||
401 | |||
402 | static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; | ||
403 | static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = { | ||
404 | 0x18, 0x152 }; | ||
405 | static const u16 NCT6779_REG_TEMP_HYST[ARRAY_SIZE(NCT6779_REG_TEMP)] = { | ||
406 | 0x3a, 0x153 }; | ||
407 | static const u16 NCT6779_REG_TEMP_OVER[ARRAY_SIZE(NCT6779_REG_TEMP)] = { | ||
408 | 0x39, 0x155 }; | ||
409 | |||
410 | static const u16 NCT6779_REG_TEMP_OFFSET[] = { | ||
411 | 0x454, 0x455, 0x456, 0x44a, 0x44b, 0x44c }; | ||
412 | |||
413 | static const char *const nct6779_temp_label[] = { | ||
414 | "", | ||
415 | "SYSTIN", | ||
416 | "CPUTIN", | ||
417 | "AUXTIN0", | ||
418 | "AUXTIN1", | ||
419 | "AUXTIN2", | ||
420 | "AUXTIN3", | ||
421 | "", | ||
422 | "SMBUSMASTER 0", | ||
423 | "SMBUSMASTER 1", | ||
424 | "SMBUSMASTER 2", | ||
425 | "SMBUSMASTER 3", | ||
426 | "SMBUSMASTER 4", | ||
427 | "SMBUSMASTER 5", | ||
428 | "SMBUSMASTER 6", | ||
429 | "SMBUSMASTER 7", | ||
430 | "PECI Agent 0", | ||
431 | "PECI Agent 1", | ||
432 | "PCH_CHIP_CPU_MAX_TEMP", | ||
433 | "PCH_CHIP_TEMP", | ||
434 | "PCH_CPU_TEMP", | ||
435 | "PCH_MCH_TEMP", | ||
436 | "PCH_DIM0_TEMP", | ||
437 | "PCH_DIM1_TEMP", | ||
438 | "PCH_DIM2_TEMP", | ||
439 | "PCH_DIM3_TEMP", | ||
440 | "BYTE_TEMP" | ||
441 | }; | ||
442 | |||
443 | static const u16 NCT6779_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6779_temp_label) - 1] | ||
444 | = { 0x490, 0x491, 0x492, 0x493, 0x494, 0x495, 0, 0, | ||
445 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
446 | 0, 0x400, 0x401, 0x402, 0x404, 0x405, 0x406, 0x407, | ||
447 | 0x408, 0 }; | ||
448 | |||
449 | static 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 }; | ||
451 | |||
452 | static enum pwm_enable reg_to_pwm_enable(int pwm, int mode) | ||
453 | { | ||
454 | if (mode == 0 && pwm == 255) | ||
455 | return off; | ||
456 | return mode + 1; | ||
457 | } | ||
458 | |||
459 | static int pwm_enable_to_reg(enum pwm_enable mode) | ||
460 | { | ||
461 | if (mode == off) | ||
462 | return 0; | ||
463 | return mode - 1; | ||
464 | } | ||
465 | |||
466 | /* | ||
467 | * Conversions | ||
468 | */ | ||
469 | |||
470 | /* 1 is DC mode, output in ms */ | ||
471 | static unsigned int step_time_from_reg(u8 reg, u8 mode) | ||
472 | { | ||
473 | return mode ? 400 * reg : 100 * reg; | ||
474 | } | ||
475 | |||
476 | static u8 step_time_to_reg(unsigned int msec, u8 mode) | ||
477 | { | ||
478 | return clamp_val((mode ? (msec + 200) / 400 : | ||
479 | (msec + 50) / 100), 1, 255); | ||
480 | } | ||
481 | |||
482 | static unsigned int fan_from_reg8(u16 reg, unsigned int divreg) | ||
483 | { | ||
484 | if (reg == 0 || reg == 255) | ||
485 | return 0; | ||
486 | return 1350000U / (reg << divreg); | ||
487 | } | ||
488 | |||
489 | static unsigned int fan_from_reg13(u16 reg, unsigned int divreg) | ||
490 | { | ||
491 | if ((reg & 0xff1f) == 0xff1f) | ||
492 | return 0; | ||
493 | |||
494 | reg = (reg & 0x1f) | ((reg & 0xff00) >> 3); | ||
495 | |||
496 | if (reg == 0) | ||
497 | return 0; | ||
498 | |||
499 | return 1350000U / reg; | ||
500 | } | ||
501 | |||
502 | static unsigned int fan_from_reg16(u16 reg, unsigned int divreg) | ||
503 | { | ||
504 | if (reg == 0 || reg == 0xffff) | ||
505 | return 0; | ||
506 | |||
507 | /* | ||
508 | * Even though the registers are 16 bit wide, the fan divisor | ||
509 | * still applies. | ||
510 | */ | ||
511 | return 1350000U / (reg << divreg); | ||
512 | } | ||
513 | |||
514 | static u16 fan_to_reg(u32 fan, unsigned int divreg) | ||
515 | { | ||
516 | if (!fan) | ||
517 | return 0; | ||
518 | |||
519 | return (1350000U / fan) >> divreg; | ||
520 | } | ||
521 | |||
522 | static inline unsigned int | ||
523 | div_from_reg(u8 reg) | ||
524 | { | ||
525 | return 1 << reg; | ||
526 | } | ||
527 | |||
528 | /* | ||
529 | * Some of the voltage inputs have internal scaling, the tables below | ||
530 | * contain 8 (the ADC LSB in mV) * scaling factor * 100 | ||
531 | */ | ||
532 | static const u16 scale_in[15] = { | ||
533 | 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800, 800, 800, 800, | ||
534 | 800, 800 | ||
535 | }; | ||
536 | |||
537 | static inline long in_from_reg(u8 reg, u8 nr) | ||
538 | { | ||
539 | return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100); | ||
540 | } | ||
541 | |||
542 | static inline u8 in_to_reg(u32 val, u8 nr) | ||
543 | { | ||
544 | return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255); | ||
545 | } | ||
546 | |||
547 | /* | ||
548 | * Data structures and manipulation thereof | ||
549 | */ | ||
550 | |||
551 | struct nct6775_data { | ||
552 | int addr; /* IO base of hw monitor block */ | ||
553 | enum kinds kind; | ||
554 | const char *name; | ||
555 | |||
556 | struct device *hwmon_dev; | ||
557 | |||
558 | u16 reg_temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst, | ||
559 | * 3=temp_crit | ||
560 | */ | ||
561 | u8 temp_src[NUM_TEMP]; | ||
562 | u16 reg_temp_config[NUM_TEMP]; | ||
563 | const char * const *temp_label; | ||
564 | int temp_label_num; | ||
565 | |||
566 | u16 REG_CONFIG; | ||
567 | u16 REG_VBAT; | ||
568 | u16 REG_DIODE; | ||
569 | |||
570 | const s8 *ALARM_BITS; | ||
571 | |||
572 | const u16 *REG_VIN; | ||
573 | const u16 *REG_IN_MINMAX[2]; | ||
574 | |||
575 | const u16 *REG_TARGET; | ||
576 | const u16 *REG_FAN; | ||
577 | const u16 *REG_FAN_MODE; | ||
578 | const u16 *REG_FAN_MIN; | ||
579 | const u16 *REG_FAN_PULSES; | ||
580 | const u16 *REG_FAN_TIME[3]; | ||
581 | |||
582 | const u16 *REG_TOLERANCE_H; | ||
583 | |||
584 | const u8 *REG_PWM_MODE; | ||
585 | const u8 *PWM_MODE_MASK; | ||
586 | |||
587 | const u16 *REG_PWM[7]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor, | ||
588 | * [3]=pwm_max, [4]=pwm_step, | ||
589 | * [5]=weight_duty_step, [6]=weight_duty_base | ||
590 | */ | ||
591 | const u16 *REG_PWM_READ; | ||
592 | |||
593 | const u16 *REG_AUTO_TEMP; | ||
594 | const u16 *REG_AUTO_PWM; | ||
595 | |||
596 | const u16 *REG_CRITICAL_TEMP; | ||
597 | const u16 *REG_CRITICAL_TEMP_TOLERANCE; | ||
598 | |||
599 | const u16 *REG_TEMP_SOURCE; /* temp register sources */ | ||
600 | const u16 *REG_TEMP_SEL; | ||
601 | const u16 *REG_WEIGHT_TEMP_SEL; | ||
602 | const u16 *REG_WEIGHT_TEMP[3]; /* 0=base, 1=tolerance, 2=step */ | ||
603 | |||
604 | const u16 *REG_TEMP_OFFSET; | ||
605 | |||
606 | const u16 *REG_ALARM; | ||
607 | |||
608 | unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg); | ||
609 | unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg); | ||
610 | |||
611 | struct mutex update_lock; | ||
612 | bool valid; /* true if following fields are valid */ | ||
613 | unsigned long last_updated; /* In jiffies */ | ||
614 | |||
615 | /* Register values */ | ||
616 | u8 bank; /* current register bank */ | ||
617 | u8 in_num; /* number of in inputs we have */ | ||
618 | u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */ | ||
619 | unsigned int rpm[5]; | ||
620 | u16 fan_min[5]; | ||
621 | u8 fan_pulses[5]; | ||
622 | u8 fan_div[5]; | ||
623 | u8 has_pwm; | ||
624 | u8 has_fan; /* some fan inputs can be disabled */ | ||
625 | u8 has_fan_min; /* some fans don't have min register */ | ||
626 | bool has_fan_div; | ||
627 | |||
628 | u8 temp_fixed_num; /* 3 or 6 */ | ||
629 | u8 temp_type[NUM_TEMP_FIXED]; | ||
630 | s8 temp_offset[NUM_TEMP_FIXED]; | ||
631 | s16 temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst, | ||
632 | * 3=temp_crit */ | ||
633 | u64 alarms; | ||
634 | |||
635 | u8 pwm_num; /* number of pwm */ | ||
636 | u8 pwm_mode[5]; /* 1->DC variable voltage, 0->PWM variable duty cycle */ | ||
637 | enum pwm_enable pwm_enable[5]; | ||
638 | /* 0->off | ||
639 | * 1->manual | ||
640 | * 2->thermal cruise mode (also called SmartFan I) | ||
641 | * 3->fan speed cruise mode | ||
642 | * 4->SmartFan III | ||
643 | * 5->enhanced variable thermal cruise (SmartFan IV) | ||
644 | */ | ||
645 | u8 pwm[7][5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor, | ||
646 | * [3]=pwm_max, [4]=pwm_step, | ||
647 | * [5]=weight_duty_step, [6]=weight_duty_base | ||
648 | */ | ||
649 | |||
650 | u8 target_temp[5]; | ||
651 | u8 target_temp_mask; | ||
652 | u32 target_speed[5]; | ||
653 | u32 target_speed_tolerance[5]; | ||
654 | u8 speed_tolerance_limit; | ||
655 | |||
656 | u8 temp_tolerance[2][5]; | ||
657 | u8 tolerance_mask; | ||
658 | |||
659 | u8 fan_time[3][5]; /* 0 = stop_time, 1 = step_up, 2 = step_down */ | ||
660 | |||
661 | /* Automatic fan speed control registers */ | ||
662 | int auto_pwm_num; | ||
663 | u8 auto_pwm[5][7]; | ||
664 | u8 auto_temp[5][7]; | ||
665 | u8 pwm_temp_sel[5]; | ||
666 | u8 pwm_weight_temp_sel[5]; | ||
667 | u8 weight_temp[3][5]; /* 0->temp_step, 1->temp_step_tol, | ||
668 | * 2->temp_base | ||
669 | */ | ||
670 | |||
671 | u8 vid; | ||
672 | u8 vrm; | ||
673 | |||
674 | u16 have_temp; | ||
675 | u16 have_temp_fixed; | ||
676 | u16 have_in; | ||
677 | #ifdef CONFIG_PM | ||
678 | /* Remember extra register values over suspend/resume */ | ||
679 | u8 vbat; | ||
680 | u8 fandiv1; | ||
681 | u8 fandiv2; | ||
682 | #endif | ||
683 | }; | ||
684 | |||
685 | struct nct6775_sio_data { | ||
686 | int sioreg; | ||
687 | enum kinds kind; | ||
688 | }; | ||
689 | |||
690 | static bool is_word_sized(struct nct6775_data *data, u16 reg) | ||
691 | { | ||
692 | switch (data->kind) { | ||
693 | case nct6775: | ||
694 | return (((reg & 0xff00) == 0x100 || | ||
695 | (reg & 0xff00) == 0x200) && | ||
696 | ((reg & 0x00ff) == 0x50 || | ||
697 | (reg & 0x00ff) == 0x53 || | ||
698 | (reg & 0x00ff) == 0x55)) || | ||
699 | (reg & 0xfff0) == 0x630 || | ||
700 | reg == 0x640 || reg == 0x642 || | ||
701 | reg == 0x662 || | ||
702 | ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) || | ||
703 | reg == 0x73 || reg == 0x75 || reg == 0x77; | ||
704 | case nct6776: | ||
705 | return (((reg & 0xff00) == 0x100 || | ||
706 | (reg & 0xff00) == 0x200) && | ||
707 | ((reg & 0x00ff) == 0x50 || | ||
708 | (reg & 0x00ff) == 0x53 || | ||
709 | (reg & 0x00ff) == 0x55)) || | ||
710 | (reg & 0xfff0) == 0x630 || | ||
711 | reg == 0x402 || | ||
712 | reg == 0x640 || reg == 0x642 || | ||
713 | ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) || | ||
714 | reg == 0x73 || reg == 0x75 || reg == 0x77; | ||
715 | case nct6779: | ||
716 | return reg == 0x150 || reg == 0x153 || reg == 0x155 || | ||
717 | ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x09) || | ||
718 | reg == 0x402 || | ||
719 | reg == 0x63a || reg == 0x63c || reg == 0x63e || | ||
720 | reg == 0x640 || reg == 0x642 || | ||
721 | reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 || | ||
722 | reg == 0x7b; | ||
723 | } | ||
724 | return false; | ||
725 | } | ||
726 | |||
727 | /* | ||
728 | * On older chips, only registers 0x50-0x5f are banked. | ||
729 | * On more recent chips, all registers are banked. | ||
730 | * Assume that is the case and set the bank number for each access. | ||
731 | * Cache the bank number so it only needs to be set if it changes. | ||
732 | */ | ||
733 | static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg) | ||
734 | { | ||
735 | u8 bank = reg >> 8; | ||
736 | if (data->bank != bank) { | ||
737 | outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET); | ||
738 | outb_p(bank, data->addr + DATA_REG_OFFSET); | ||
739 | data->bank = bank; | ||
740 | } | ||
741 | } | ||
742 | |||
743 | static u16 nct6775_read_value(struct nct6775_data *data, u16 reg) | ||
744 | { | ||
745 | int res, word_sized = is_word_sized(data, reg); | ||
746 | |||
747 | nct6775_set_bank(data, reg); | ||
748 | outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); | ||
749 | res = inb_p(data->addr + DATA_REG_OFFSET); | ||
750 | if (word_sized) { | ||
751 | outb_p((reg & 0xff) + 1, | ||
752 | data->addr + ADDR_REG_OFFSET); | ||
753 | res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET); | ||
754 | } | ||
755 | return res; | ||
756 | } | ||
757 | |||
758 | static int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value) | ||
759 | { | ||
760 | int word_sized = is_word_sized(data, reg); | ||
761 | |||
762 | nct6775_set_bank(data, reg); | ||
763 | outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); | ||
764 | if (word_sized) { | ||
765 | outb_p(value >> 8, data->addr + DATA_REG_OFFSET); | ||
766 | outb_p((reg & 0xff) + 1, | ||
767 | data->addr + ADDR_REG_OFFSET); | ||
768 | } | ||
769 | outb_p(value & 0xff, data->addr + DATA_REG_OFFSET); | ||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | /* We left-align 8-bit temperature values to make the code simpler */ | ||
774 | static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg) | ||
775 | { | ||
776 | u16 res; | ||
777 | |||
778 | res = nct6775_read_value(data, reg); | ||
779 | if (!is_word_sized(data, reg)) | ||
780 | res <<= 8; | ||
781 | |||
782 | return res; | ||
783 | } | ||
784 | |||
785 | static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value) | ||
786 | { | ||
787 | if (!is_word_sized(data, reg)) | ||
788 | value >>= 8; | ||
789 | return nct6775_write_value(data, reg, value); | ||
790 | } | ||
791 | |||
792 | /* This function assumes that the caller holds data->update_lock */ | ||
793 | static void nct6775_write_fan_div(struct nct6775_data *data, int nr) | ||
794 | { | ||
795 | u8 reg; | ||
796 | |||
797 | switch (nr) { | ||
798 | case 0: | ||
799 | reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70) | ||
800 | | (data->fan_div[0] & 0x7); | ||
801 | nct6775_write_value(data, NCT6775_REG_FANDIV1, reg); | ||
802 | break; | ||
803 | case 1: | ||
804 | reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7) | ||
805 | | ((data->fan_div[1] << 4) & 0x70); | ||
806 | nct6775_write_value(data, NCT6775_REG_FANDIV1, reg); | ||
807 | break; | ||
808 | case 2: | ||
809 | reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70) | ||
810 | | (data->fan_div[2] & 0x7); | ||
811 | nct6775_write_value(data, NCT6775_REG_FANDIV2, reg); | ||
812 | break; | ||
813 | case 3: | ||
814 | reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7) | ||
815 | | ((data->fan_div[3] << 4) & 0x70); | ||
816 | nct6775_write_value(data, NCT6775_REG_FANDIV2, reg); | ||
817 | break; | ||
818 | } | ||
819 | } | ||
820 | |||
821 | static void nct6775_write_fan_div_common(struct nct6775_data *data, int nr) | ||
822 | { | ||
823 | if (data->kind == nct6775) | ||
824 | nct6775_write_fan_div(data, nr); | ||
825 | } | ||
826 | |||
827 | static void nct6775_update_fan_div(struct nct6775_data *data) | ||
828 | { | ||
829 | u8 i; | ||
830 | |||
831 | i = nct6775_read_value(data, NCT6775_REG_FANDIV1); | ||
832 | data->fan_div[0] = i & 0x7; | ||
833 | data->fan_div[1] = (i & 0x70) >> 4; | ||
834 | i = nct6775_read_value(data, NCT6775_REG_FANDIV2); | ||
835 | data->fan_div[2] = i & 0x7; | ||
836 | if (data->has_fan & (1 << 3)) | ||
837 | data->fan_div[3] = (i & 0x70) >> 4; | ||
838 | } | ||
839 | |||
840 | static void nct6775_update_fan_div_common(struct nct6775_data *data) | ||
841 | { | ||
842 | if (data->kind == nct6775) | ||
843 | nct6775_update_fan_div(data); | ||
844 | } | ||
845 | |||
846 | static void nct6775_init_fan_div(struct nct6775_data *data) | ||
847 | { | ||
848 | int i; | ||
849 | |||
850 | nct6775_update_fan_div_common(data); | ||
851 | /* | ||
852 | * For all fans, start with highest divider value if the divider | ||
853 | * register is not initialized. This ensures that we get a | ||
854 | * reading from the fan count register, even if it is not optimal. | ||
855 | * We'll compute a better divider later on. | ||
856 | */ | ||
857 | for (i = 0; i < ARRAY_SIZE(data->fan_div); i++) { | ||
858 | if (!(data->has_fan & (1 << i))) | ||
859 | continue; | ||
860 | if (data->fan_div[i] == 0) { | ||
861 | data->fan_div[i] = 7; | ||
862 | nct6775_write_fan_div_common(data, i); | ||
863 | } | ||
864 | } | ||
865 | } | ||
866 | |||
867 | static void nct6775_init_fan_common(struct device *dev, | ||
868 | struct nct6775_data *data) | ||
869 | { | ||
870 | int i; | ||
871 | u8 reg; | ||
872 | |||
873 | if (data->has_fan_div) | ||
874 | nct6775_init_fan_div(data); | ||
875 | |||
876 | /* | ||
877 | * If fan_min is not set (0), set it to 0xff to disable it. This | ||
878 | * prevents the unnecessary warning when fanX_min is reported as 0. | ||
879 | */ | ||
880 | for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { | ||
881 | if (data->has_fan_min & (1 << i)) { | ||
882 | reg = nct6775_read_value(data, data->REG_FAN_MIN[i]); | ||
883 | if (!reg) | ||
884 | nct6775_write_value(data, data->REG_FAN_MIN[i], | ||
885 | data->has_fan_div ? 0xff | ||
886 | : 0xff1f); | ||
887 | } | ||
888 | } | ||
889 | } | ||
890 | |||
891 | static void nct6775_select_fan_div(struct device *dev, | ||
892 | struct nct6775_data *data, int nr, u16 reg) | ||
893 | { | ||
894 | u8 fan_div = data->fan_div[nr]; | ||
895 | u16 fan_min; | ||
896 | |||
897 | if (!data->has_fan_div) | ||
898 | return; | ||
899 | |||
900 | /* | ||
901 | * If we failed to measure the fan speed, or the reported value is not | ||
902 | * in the optimal range, and the clock divider can be modified, | ||
903 | * let's try that for next time. | ||
904 | */ | ||
905 | if (reg == 0x00 && fan_div < 0x07) | ||
906 | fan_div++; | ||
907 | else if (reg != 0x00 && reg < 0x30 && fan_div > 0) | ||
908 | fan_div--; | ||
909 | |||
910 | if (fan_div != data->fan_div[nr]) { | ||
911 | dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n", | ||
912 | nr + 1, div_from_reg(data->fan_div[nr]), | ||
913 | div_from_reg(fan_div)); | ||
914 | |||
915 | /* Preserve min limit if possible */ | ||
916 | if (data->has_fan_min & (1 << nr)) { | ||
917 | fan_min = data->fan_min[nr]; | ||
918 | if (fan_div > data->fan_div[nr]) { | ||
919 | if (fan_min != 255 && fan_min > 1) | ||
920 | fan_min >>= 1; | ||
921 | } else { | ||
922 | if (fan_min != 255) { | ||
923 | fan_min <<= 1; | ||
924 | if (fan_min > 254) | ||
925 | fan_min = 254; | ||
926 | } | ||
927 | } | ||
928 | if (fan_min != data->fan_min[nr]) { | ||
929 | data->fan_min[nr] = fan_min; | ||
930 | nct6775_write_value(data, data->REG_FAN_MIN[nr], | ||
931 | fan_min); | ||
932 | } | ||
933 | } | ||
934 | data->fan_div[nr] = fan_div; | ||
935 | nct6775_write_fan_div_common(data, nr); | ||
936 | } | ||
937 | } | ||
938 | |||
939 | static void nct6775_update_pwm(struct device *dev) | ||
940 | { | ||
941 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
942 | int i, j; | ||
943 | int fanmodecfg, reg; | ||
944 | bool duty_is_dc; | ||
945 | |||
946 | for (i = 0; i < data->pwm_num; i++) { | ||
947 | if (!(data->has_pwm & (1 << i))) | ||
948 | continue; | ||
949 | |||
950 | duty_is_dc = data->REG_PWM_MODE[i] && | ||
951 | (nct6775_read_value(data, data->REG_PWM_MODE[i]) | ||
952 | & data->PWM_MODE_MASK[i]); | ||
953 | data->pwm_mode[i] = duty_is_dc; | ||
954 | |||
955 | fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]); | ||
956 | for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) { | ||
957 | if (data->REG_PWM[j] && data->REG_PWM[j][i]) { | ||
958 | data->pwm[j][i] | ||
959 | = nct6775_read_value(data, | ||
960 | data->REG_PWM[j][i]); | ||
961 | } | ||
962 | } | ||
963 | |||
964 | data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i], | ||
965 | (fanmodecfg >> 4) & 7); | ||
966 | |||
967 | if (!data->temp_tolerance[0][i] || | ||
968 | data->pwm_enable[i] != speed_cruise) | ||
969 | data->temp_tolerance[0][i] = fanmodecfg & 0x0f; | ||
970 | if (!data->target_speed_tolerance[i] || | ||
971 | data->pwm_enable[i] == speed_cruise) { | ||
972 | u8 t = fanmodecfg & 0x0f; | ||
973 | if (data->REG_TOLERANCE_H) { | ||
974 | t |= (nct6775_read_value(data, | ||
975 | data->REG_TOLERANCE_H[i]) & 0x70) >> 1; | ||
976 | } | ||
977 | data->target_speed_tolerance[i] = t; | ||
978 | } | ||
979 | |||
980 | data->temp_tolerance[1][i] = | ||
981 | nct6775_read_value(data, | ||
982 | data->REG_CRITICAL_TEMP_TOLERANCE[i]); | ||
983 | |||
984 | reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]); | ||
985 | data->pwm_temp_sel[i] = reg & 0x1f; | ||
986 | /* If fan can stop, report floor as 0 */ | ||
987 | if (reg & 0x80) | ||
988 | data->pwm[2][i] = 0; | ||
989 | |||
990 | reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]); | ||
991 | data->pwm_weight_temp_sel[i] = reg & 0x1f; | ||
992 | /* If weight is disabled, report weight source as 0 */ | ||
993 | if (j == 1 && !(reg & 0x80)) | ||
994 | data->pwm_weight_temp_sel[i] = 0; | ||
995 | |||
996 | /* Weight temp data */ | ||
997 | for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) { | ||
998 | data->weight_temp[j][i] | ||
999 | = nct6775_read_value(data, | ||
1000 | data->REG_WEIGHT_TEMP[j][i]); | ||
1001 | } | ||
1002 | } | ||
1003 | } | ||
1004 | |||
1005 | static void nct6775_update_pwm_limits(struct device *dev) | ||
1006 | { | ||
1007 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1008 | int i, j; | ||
1009 | u8 reg; | ||
1010 | u16 reg_t; | ||
1011 | |||
1012 | for (i = 0; i < data->pwm_num; i++) { | ||
1013 | if (!(data->has_pwm & (1 << i))) | ||
1014 | continue; | ||
1015 | |||
1016 | for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) { | ||
1017 | data->fan_time[j][i] = | ||
1018 | nct6775_read_value(data, data->REG_FAN_TIME[j][i]); | ||
1019 | } | ||
1020 | |||
1021 | reg_t = nct6775_read_value(data, data->REG_TARGET[i]); | ||
1022 | /* Update only in matching mode or if never updated */ | ||
1023 | if (!data->target_temp[i] || | ||
1024 | data->pwm_enable[i] == thermal_cruise) | ||
1025 | data->target_temp[i] = reg_t & data->target_temp_mask; | ||
1026 | if (!data->target_speed[i] || | ||
1027 | data->pwm_enable[i] == speed_cruise) { | ||
1028 | if (data->REG_TOLERANCE_H) { | ||
1029 | reg_t |= (nct6775_read_value(data, | ||
1030 | data->REG_TOLERANCE_H[i]) & 0x0f) << 8; | ||
1031 | } | ||
1032 | data->target_speed[i] = reg_t; | ||
1033 | } | ||
1034 | |||
1035 | for (j = 0; j < data->auto_pwm_num; j++) { | ||
1036 | data->auto_pwm[i][j] = | ||
1037 | nct6775_read_value(data, | ||
1038 | NCT6775_AUTO_PWM(data, i, j)); | ||
1039 | data->auto_temp[i][j] = | ||
1040 | nct6775_read_value(data, | ||
1041 | NCT6775_AUTO_TEMP(data, i, j)); | ||
1042 | } | ||
1043 | |||
1044 | /* critical auto_pwm temperature data */ | ||
1045 | data->auto_temp[i][data->auto_pwm_num] = | ||
1046 | nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]); | ||
1047 | |||
1048 | switch (data->kind) { | ||
1049 | case nct6775: | ||
1050 | reg = nct6775_read_value(data, | ||
1051 | NCT6775_REG_CRITICAL_ENAB[i]); | ||
1052 | data->auto_pwm[i][data->auto_pwm_num] = | ||
1053 | (reg & 0x02) ? 0xff : 0x00; | ||
1054 | break; | ||
1055 | case nct6776: | ||
1056 | data->auto_pwm[i][data->auto_pwm_num] = 0xff; | ||
1057 | break; | ||
1058 | case nct6779: | ||
1059 | reg = nct6775_read_value(data, | ||
1060 | NCT6779_REG_CRITICAL_PWM_ENABLE[i]); | ||
1061 | if (reg & 1) | ||
1062 | data->auto_pwm[i][data->auto_pwm_num] = | ||
1063 | nct6775_read_value(data, | ||
1064 | NCT6779_REG_CRITICAL_PWM[i]); | ||
1065 | else | ||
1066 | data->auto_pwm[i][data->auto_pwm_num] = 0xff; | ||
1067 | break; | ||
1068 | } | ||
1069 | } | ||
1070 | } | ||
1071 | |||
1072 | static struct nct6775_data *nct6775_update_device(struct device *dev) | ||
1073 | { | ||
1074 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1075 | int i, j; | ||
1076 | |||
1077 | mutex_lock(&data->update_lock); | ||
1078 | |||
1079 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | ||
1080 | || !data->valid) { | ||
1081 | /* Fan clock dividers */ | ||
1082 | nct6775_update_fan_div_common(data); | ||
1083 | |||
1084 | /* Measured voltages and limits */ | ||
1085 | for (i = 0; i < data->in_num; i++) { | ||
1086 | if (!(data->have_in & (1 << i))) | ||
1087 | continue; | ||
1088 | |||
1089 | data->in[i][0] = nct6775_read_value(data, | ||
1090 | data->REG_VIN[i]); | ||
1091 | data->in[i][1] = nct6775_read_value(data, | ||
1092 | data->REG_IN_MINMAX[0][i]); | ||
1093 | data->in[i][2] = nct6775_read_value(data, | ||
1094 | data->REG_IN_MINMAX[1][i]); | ||
1095 | } | ||
1096 | |||
1097 | /* Measured fan speeds and limits */ | ||
1098 | for (i = 0; i < ARRAY_SIZE(data->rpm); i++) { | ||
1099 | u16 reg; | ||
1100 | |||
1101 | if (!(data->has_fan & (1 << i))) | ||
1102 | continue; | ||
1103 | |||
1104 | reg = nct6775_read_value(data, data->REG_FAN[i]); | ||
1105 | data->rpm[i] = data->fan_from_reg(reg, | ||
1106 | data->fan_div[i]); | ||
1107 | |||
1108 | if (data->has_fan_min & (1 << i)) | ||
1109 | data->fan_min[i] = nct6775_read_value(data, | ||
1110 | data->REG_FAN_MIN[i]); | ||
1111 | data->fan_pulses[i] = | ||
1112 | nct6775_read_value(data, data->REG_FAN_PULSES[i]); | ||
1113 | |||
1114 | nct6775_select_fan_div(dev, data, i, reg); | ||
1115 | } | ||
1116 | |||
1117 | nct6775_update_pwm(dev); | ||
1118 | nct6775_update_pwm_limits(dev); | ||
1119 | |||
1120 | /* Measured temperatures and limits */ | ||
1121 | for (i = 0; i < NUM_TEMP; i++) { | ||
1122 | if (!(data->have_temp & (1 << i))) | ||
1123 | continue; | ||
1124 | for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) { | ||
1125 | if (data->reg_temp[j][i]) | ||
1126 | data->temp[j][i] | ||
1127 | = nct6775_read_temp(data, | ||
1128 | data->reg_temp[j][i]); | ||
1129 | } | ||
1130 | if (!(data->have_temp_fixed & (1 << i))) | ||
1131 | continue; | ||
1132 | data->temp_offset[i] | ||
1133 | = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]); | ||
1134 | } | ||
1135 | |||
1136 | data->alarms = 0; | ||
1137 | for (i = 0; i < NUM_REG_ALARM; i++) { | ||
1138 | u8 alarm; | ||
1139 | if (!data->REG_ALARM[i]) | ||
1140 | continue; | ||
1141 | alarm = nct6775_read_value(data, data->REG_ALARM[i]); | ||
1142 | data->alarms |= ((u64)alarm) << (i << 3); | ||
1143 | } | ||
1144 | |||
1145 | data->last_updated = jiffies; | ||
1146 | data->valid = true; | ||
1147 | } | ||
1148 | |||
1149 | mutex_unlock(&data->update_lock); | ||
1150 | return data; | ||
1151 | } | ||
1152 | |||
1153 | /* | ||
1154 | * Sysfs callback functions | ||
1155 | */ | ||
1156 | static ssize_t | ||
1157 | show_in_reg(struct device *dev, struct device_attribute *attr, char *buf) | ||
1158 | { | ||
1159 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1160 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
1161 | int nr = sattr->nr; | ||
1162 | int index = sattr->index; | ||
1163 | return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr)); | ||
1164 | } | ||
1165 | |||
1166 | static ssize_t | ||
1167 | store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf, | ||
1168 | size_t count) | ||
1169 | { | ||
1170 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1171 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
1172 | int nr = sattr->nr; | ||
1173 | int index = sattr->index; | ||
1174 | unsigned long val; | ||
1175 | int err = kstrtoul(buf, 10, &val); | ||
1176 | if (err < 0) | ||
1177 | return err; | ||
1178 | mutex_lock(&data->update_lock); | ||
1179 | data->in[nr][index] = in_to_reg(val, nr); | ||
1180 | nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr], | ||
1181 | data->in[nr][index]); | ||
1182 | mutex_unlock(&data->update_lock); | ||
1183 | return count; | ||
1184 | } | ||
1185 | |||
1186 | static ssize_t | ||
1187 | show_alarm(struct device *dev, struct device_attribute *attr, char *buf) | ||
1188 | { | ||
1189 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1190 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1191 | int nr = data->ALARM_BITS[sattr->index]; | ||
1192 | return sprintf(buf, "%u\n", | ||
1193 | (unsigned int)((data->alarms >> nr) & 0x01)); | ||
1194 | } | ||
1195 | |||
1196 | static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in_reg, NULL, 0, 0); | ||
1197 | static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in_reg, NULL, 1, 0); | ||
1198 | static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in_reg, NULL, 2, 0); | ||
1199 | static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in_reg, NULL, 3, 0); | ||
1200 | static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in_reg, NULL, 4, 0); | ||
1201 | static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in_reg, NULL, 5, 0); | ||
1202 | static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in_reg, NULL, 6, 0); | ||
1203 | static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in_reg, NULL, 7, 0); | ||
1204 | static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in_reg, NULL, 8, 0); | ||
1205 | static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in_reg, NULL, 9, 0); | ||
1206 | static SENSOR_DEVICE_ATTR_2(in10_input, S_IRUGO, show_in_reg, NULL, 10, 0); | ||
1207 | static SENSOR_DEVICE_ATTR_2(in11_input, S_IRUGO, show_in_reg, NULL, 11, 0); | ||
1208 | static SENSOR_DEVICE_ATTR_2(in12_input, S_IRUGO, show_in_reg, NULL, 12, 0); | ||
1209 | static SENSOR_DEVICE_ATTR_2(in13_input, S_IRUGO, show_in_reg, NULL, 13, 0); | ||
1210 | static SENSOR_DEVICE_ATTR_2(in14_input, S_IRUGO, show_in_reg, NULL, 14, 0); | ||
1211 | |||
1212 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
1213 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
1214 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
1215 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
1216 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
1217 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
1218 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
1219 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
1220 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
1221 | static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
1222 | static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10); | ||
1223 | static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
1224 | static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, 12); | ||
1225 | static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, 13); | ||
1226 | static SENSOR_DEVICE_ATTR(in14_alarm, S_IRUGO, show_alarm, NULL, 14); | ||
1227 | |||
1228 | static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1229 | store_in_reg, 0, 1); | ||
1230 | static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1231 | store_in_reg, 1, 1); | ||
1232 | static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1233 | store_in_reg, 2, 1); | ||
1234 | static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1235 | store_in_reg, 3, 1); | ||
1236 | static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1237 | store_in_reg, 4, 1); | ||
1238 | static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1239 | store_in_reg, 5, 1); | ||
1240 | static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1241 | store_in_reg, 6, 1); | ||
1242 | static SENSOR_DEVICE_ATTR_2(in7_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1243 | store_in_reg, 7, 1); | ||
1244 | static SENSOR_DEVICE_ATTR_2(in8_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1245 | store_in_reg, 8, 1); | ||
1246 | static SENSOR_DEVICE_ATTR_2(in9_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1247 | store_in_reg, 9, 1); | ||
1248 | static SENSOR_DEVICE_ATTR_2(in10_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1249 | store_in_reg, 10, 1); | ||
1250 | static SENSOR_DEVICE_ATTR_2(in11_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1251 | store_in_reg, 11, 1); | ||
1252 | static SENSOR_DEVICE_ATTR_2(in12_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1253 | store_in_reg, 12, 1); | ||
1254 | static SENSOR_DEVICE_ATTR_2(in13_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1255 | store_in_reg, 13, 1); | ||
1256 | static SENSOR_DEVICE_ATTR_2(in14_min, S_IWUSR | S_IRUGO, show_in_reg, | ||
1257 | store_in_reg, 14, 1); | ||
1258 | |||
1259 | static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1260 | store_in_reg, 0, 2); | ||
1261 | static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1262 | store_in_reg, 1, 2); | ||
1263 | static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1264 | store_in_reg, 2, 2); | ||
1265 | static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1266 | store_in_reg, 3, 2); | ||
1267 | static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1268 | store_in_reg, 4, 2); | ||
1269 | static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1270 | store_in_reg, 5, 2); | ||
1271 | static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1272 | store_in_reg, 6, 2); | ||
1273 | static SENSOR_DEVICE_ATTR_2(in7_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1274 | store_in_reg, 7, 2); | ||
1275 | static SENSOR_DEVICE_ATTR_2(in8_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1276 | store_in_reg, 8, 2); | ||
1277 | static SENSOR_DEVICE_ATTR_2(in9_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1278 | store_in_reg, 9, 2); | ||
1279 | static SENSOR_DEVICE_ATTR_2(in10_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1280 | store_in_reg, 10, 2); | ||
1281 | static SENSOR_DEVICE_ATTR_2(in11_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1282 | store_in_reg, 11, 2); | ||
1283 | static SENSOR_DEVICE_ATTR_2(in12_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1284 | store_in_reg, 12, 2); | ||
1285 | static SENSOR_DEVICE_ATTR_2(in13_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1286 | store_in_reg, 13, 2); | ||
1287 | static SENSOR_DEVICE_ATTR_2(in14_max, S_IWUSR | S_IRUGO, show_in_reg, | ||
1288 | store_in_reg, 14, 2); | ||
1289 | |||
1290 | static struct attribute *nct6775_attributes_in[15][5] = { | ||
1291 | { | ||
1292 | &sensor_dev_attr_in0_input.dev_attr.attr, | ||
1293 | &sensor_dev_attr_in0_min.dev_attr.attr, | ||
1294 | &sensor_dev_attr_in0_max.dev_attr.attr, | ||
1295 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | ||
1296 | NULL | ||
1297 | }, | ||
1298 | { | ||
1299 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
1300 | &sensor_dev_attr_in1_min.dev_attr.attr, | ||
1301 | &sensor_dev_attr_in1_max.dev_attr.attr, | ||
1302 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
1303 | NULL | ||
1304 | }, | ||
1305 | { | ||
1306 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
1307 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
1308 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
1309 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
1310 | NULL | ||
1311 | }, | ||
1312 | { | ||
1313 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
1314 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
1315 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
1316 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
1317 | NULL | ||
1318 | }, | ||
1319 | { | ||
1320 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
1321 | &sensor_dev_attr_in4_min.dev_attr.attr, | ||
1322 | &sensor_dev_attr_in4_max.dev_attr.attr, | ||
1323 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
1324 | NULL | ||
1325 | }, | ||
1326 | { | ||
1327 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
1328 | &sensor_dev_attr_in5_min.dev_attr.attr, | ||
1329 | &sensor_dev_attr_in5_max.dev_attr.attr, | ||
1330 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
1331 | NULL | ||
1332 | }, | ||
1333 | { | ||
1334 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
1335 | &sensor_dev_attr_in6_min.dev_attr.attr, | ||
1336 | &sensor_dev_attr_in6_max.dev_attr.attr, | ||
1337 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
1338 | NULL | ||
1339 | }, | ||
1340 | { | ||
1341 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
1342 | &sensor_dev_attr_in7_min.dev_attr.attr, | ||
1343 | &sensor_dev_attr_in7_max.dev_attr.attr, | ||
1344 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
1345 | NULL | ||
1346 | }, | ||
1347 | { | ||
1348 | &sensor_dev_attr_in8_input.dev_attr.attr, | ||
1349 | &sensor_dev_attr_in8_min.dev_attr.attr, | ||
1350 | &sensor_dev_attr_in8_max.dev_attr.attr, | ||
1351 | &sensor_dev_attr_in8_alarm.dev_attr.attr, | ||
1352 | NULL | ||
1353 | }, | ||
1354 | { | ||
1355 | &sensor_dev_attr_in9_input.dev_attr.attr, | ||
1356 | &sensor_dev_attr_in9_min.dev_attr.attr, | ||
1357 | &sensor_dev_attr_in9_max.dev_attr.attr, | ||
1358 | &sensor_dev_attr_in9_alarm.dev_attr.attr, | ||
1359 | NULL | ||
1360 | }, | ||
1361 | { | ||
1362 | &sensor_dev_attr_in10_input.dev_attr.attr, | ||
1363 | &sensor_dev_attr_in10_min.dev_attr.attr, | ||
1364 | &sensor_dev_attr_in10_max.dev_attr.attr, | ||
1365 | &sensor_dev_attr_in10_alarm.dev_attr.attr, | ||
1366 | NULL | ||
1367 | }, | ||
1368 | { | ||
1369 | &sensor_dev_attr_in11_input.dev_attr.attr, | ||
1370 | &sensor_dev_attr_in11_min.dev_attr.attr, | ||
1371 | &sensor_dev_attr_in11_max.dev_attr.attr, | ||
1372 | &sensor_dev_attr_in11_alarm.dev_attr.attr, | ||
1373 | NULL | ||
1374 | }, | ||
1375 | { | ||
1376 | &sensor_dev_attr_in12_input.dev_attr.attr, | ||
1377 | &sensor_dev_attr_in12_min.dev_attr.attr, | ||
1378 | &sensor_dev_attr_in12_max.dev_attr.attr, | ||
1379 | &sensor_dev_attr_in12_alarm.dev_attr.attr, | ||
1380 | NULL | ||
1381 | }, | ||
1382 | { | ||
1383 | &sensor_dev_attr_in13_input.dev_attr.attr, | ||
1384 | &sensor_dev_attr_in13_min.dev_attr.attr, | ||
1385 | &sensor_dev_attr_in13_max.dev_attr.attr, | ||
1386 | &sensor_dev_attr_in13_alarm.dev_attr.attr, | ||
1387 | NULL | ||
1388 | }, | ||
1389 | { | ||
1390 | &sensor_dev_attr_in14_input.dev_attr.attr, | ||
1391 | &sensor_dev_attr_in14_min.dev_attr.attr, | ||
1392 | &sensor_dev_attr_in14_max.dev_attr.attr, | ||
1393 | &sensor_dev_attr_in14_alarm.dev_attr.attr, | ||
1394 | NULL | ||
1395 | }, | ||
1396 | }; | ||
1397 | |||
1398 | static const struct attribute_group nct6775_group_in[15] = { | ||
1399 | { .attrs = nct6775_attributes_in[0] }, | ||
1400 | { .attrs = nct6775_attributes_in[1] }, | ||
1401 | { .attrs = nct6775_attributes_in[2] }, | ||
1402 | { .attrs = nct6775_attributes_in[3] }, | ||
1403 | { .attrs = nct6775_attributes_in[4] }, | ||
1404 | { .attrs = nct6775_attributes_in[5] }, | ||
1405 | { .attrs = nct6775_attributes_in[6] }, | ||
1406 | { .attrs = nct6775_attributes_in[7] }, | ||
1407 | { .attrs = nct6775_attributes_in[8] }, | ||
1408 | { .attrs = nct6775_attributes_in[9] }, | ||
1409 | { .attrs = nct6775_attributes_in[10] }, | ||
1410 | { .attrs = nct6775_attributes_in[11] }, | ||
1411 | { .attrs = nct6775_attributes_in[12] }, | ||
1412 | { .attrs = nct6775_attributes_in[13] }, | ||
1413 | { .attrs = nct6775_attributes_in[14] }, | ||
1414 | }; | ||
1415 | |||
1416 | static ssize_t | ||
1417 | show_fan(struct device *dev, struct device_attribute *attr, char *buf) | ||
1418 | { | ||
1419 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1420 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1421 | int nr = sattr->index; | ||
1422 | return sprintf(buf, "%d\n", data->rpm[nr]); | ||
1423 | } | ||
1424 | |||
1425 | static ssize_t | ||
1426 | show_fan_min(struct device *dev, struct device_attribute *attr, char *buf) | ||
1427 | { | ||
1428 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1429 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1430 | int nr = sattr->index; | ||
1431 | return sprintf(buf, "%d\n", | ||
1432 | data->fan_from_reg_min(data->fan_min[nr], | ||
1433 | data->fan_div[nr])); | ||
1434 | } | ||
1435 | |||
1436 | static ssize_t | ||
1437 | show_fan_div(struct device *dev, struct device_attribute *attr, char *buf) | ||
1438 | { | ||
1439 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1440 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1441 | int nr = sattr->index; | ||
1442 | return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr])); | ||
1443 | } | ||
1444 | |||
1445 | static ssize_t | ||
1446 | store_fan_min(struct device *dev, struct device_attribute *attr, | ||
1447 | const char *buf, size_t count) | ||
1448 | { | ||
1449 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1450 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1451 | int nr = sattr->index; | ||
1452 | unsigned long val; | ||
1453 | int err; | ||
1454 | unsigned int reg; | ||
1455 | u8 new_div; | ||
1456 | |||
1457 | err = kstrtoul(buf, 10, &val); | ||
1458 | if (err < 0) | ||
1459 | return err; | ||
1460 | |||
1461 | mutex_lock(&data->update_lock); | ||
1462 | if (!data->has_fan_div) { | ||
1463 | /* NCT6776F or NCT6779D; we know this is a 13 bit register */ | ||
1464 | if (!val) { | ||
1465 | val = 0xff1f; | ||
1466 | } else { | ||
1467 | if (val > 1350000U) | ||
1468 | val = 135000U; | ||
1469 | val = 1350000U / val; | ||
1470 | val = (val & 0x1f) | ((val << 3) & 0xff00); | ||
1471 | } | ||
1472 | data->fan_min[nr] = val; | ||
1473 | goto write_min; /* Leave fan divider alone */ | ||
1474 | } | ||
1475 | if (!val) { | ||
1476 | /* No min limit, alarm disabled */ | ||
1477 | data->fan_min[nr] = 255; | ||
1478 | new_div = data->fan_div[nr]; /* No change */ | ||
1479 | dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1); | ||
1480 | goto write_div; | ||
1481 | } | ||
1482 | reg = 1350000U / val; | ||
1483 | if (reg >= 128 * 255) { | ||
1484 | /* | ||
1485 | * Speed below this value cannot possibly be represented, | ||
1486 | * even with the highest divider (128) | ||
1487 | */ | ||
1488 | data->fan_min[nr] = 254; | ||
1489 | new_div = 7; /* 128 == (1 << 7) */ | ||
1490 | dev_warn(dev, | ||
1491 | "fan%u low limit %lu below minimum %u, set to minimum\n", | ||
1492 | nr + 1, val, data->fan_from_reg_min(254, 7)); | ||
1493 | } else if (!reg) { | ||
1494 | /* | ||
1495 | * Speed above this value cannot possibly be represented, | ||
1496 | * even with the lowest divider (1) | ||
1497 | */ | ||
1498 | data->fan_min[nr] = 1; | ||
1499 | new_div = 0; /* 1 == (1 << 0) */ | ||
1500 | dev_warn(dev, | ||
1501 | "fan%u low limit %lu above maximum %u, set to maximum\n", | ||
1502 | nr + 1, val, data->fan_from_reg_min(1, 0)); | ||
1503 | } else { | ||
1504 | /* | ||
1505 | * Automatically pick the best divider, i.e. the one such | ||
1506 | * that the min limit will correspond to a register value | ||
1507 | * in the 96..192 range | ||
1508 | */ | ||
1509 | new_div = 0; | ||
1510 | while (reg > 192 && new_div < 7) { | ||
1511 | reg >>= 1; | ||
1512 | new_div++; | ||
1513 | } | ||
1514 | data->fan_min[nr] = reg; | ||
1515 | } | ||
1516 | |||
1517 | write_div: | ||
1518 | /* | ||
1519 | * Write both the fan clock divider (if it changed) and the new | ||
1520 | * fan min (unconditionally) | ||
1521 | */ | ||
1522 | if (new_div != data->fan_div[nr]) { | ||
1523 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", | ||
1524 | nr + 1, div_from_reg(data->fan_div[nr]), | ||
1525 | div_from_reg(new_div)); | ||
1526 | data->fan_div[nr] = new_div; | ||
1527 | nct6775_write_fan_div_common(data, nr); | ||
1528 | /* Give the chip time to sample a new speed value */ | ||
1529 | data->last_updated = jiffies; | ||
1530 | } | ||
1531 | |||
1532 | write_min: | ||
1533 | nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]); | ||
1534 | mutex_unlock(&data->update_lock); | ||
1535 | |||
1536 | return count; | ||
1537 | } | ||
1538 | |||
1539 | static ssize_t | ||
1540 | show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf) | ||
1541 | { | ||
1542 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1543 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1544 | int p = data->fan_pulses[sattr->index]; | ||
1545 | |||
1546 | return sprintf(buf, "%d\n", p ? : 4); | ||
1547 | } | ||
1548 | |||
1549 | static ssize_t | ||
1550 | store_fan_pulses(struct device *dev, struct device_attribute *attr, | ||
1551 | const char *buf, size_t count) | ||
1552 | { | ||
1553 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1554 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1555 | int nr = sattr->index; | ||
1556 | unsigned long val; | ||
1557 | int err; | ||
1558 | |||
1559 | err = kstrtoul(buf, 10, &val); | ||
1560 | if (err < 0) | ||
1561 | return err; | ||
1562 | |||
1563 | if (val > 4) | ||
1564 | return -EINVAL; | ||
1565 | |||
1566 | mutex_lock(&data->update_lock); | ||
1567 | data->fan_pulses[nr] = val & 3; | ||
1568 | nct6775_write_value(data, data->REG_FAN_PULSES[nr], val & 3); | ||
1569 | mutex_unlock(&data->update_lock); | ||
1570 | |||
1571 | return count; | ||
1572 | } | ||
1573 | |||
1574 | static struct sensor_device_attribute sda_fan_input[] = { | ||
1575 | SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), | ||
1576 | SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), | ||
1577 | SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), | ||
1578 | SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), | ||
1579 | SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4), | ||
1580 | }; | ||
1581 | |||
1582 | static struct sensor_device_attribute sda_fan_alarm[] = { | ||
1583 | SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE), | ||
1584 | SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 1), | ||
1585 | SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 2), | ||
1586 | SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 3), | ||
1587 | SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 4), | ||
1588 | }; | ||
1589 | |||
1590 | static struct sensor_device_attribute sda_fan_min[] = { | ||
1591 | SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1592 | store_fan_min, 0), | ||
1593 | SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1594 | store_fan_min, 1), | ||
1595 | SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1596 | store_fan_min, 2), | ||
1597 | SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1598 | store_fan_min, 3), | ||
1599 | SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1600 | store_fan_min, 4), | ||
1601 | }; | ||
1602 | |||
1603 | static struct sensor_device_attribute sda_fan_pulses[] = { | ||
1604 | SENSOR_ATTR(fan1_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, | ||
1605 | store_fan_pulses, 0), | ||
1606 | SENSOR_ATTR(fan2_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, | ||
1607 | store_fan_pulses, 1), | ||
1608 | SENSOR_ATTR(fan3_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, | ||
1609 | store_fan_pulses, 2), | ||
1610 | SENSOR_ATTR(fan4_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, | ||
1611 | store_fan_pulses, 3), | ||
1612 | SENSOR_ATTR(fan5_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, | ||
1613 | store_fan_pulses, 4), | ||
1614 | }; | ||
1615 | |||
1616 | static struct sensor_device_attribute sda_fan_div[] = { | ||
1617 | SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0), | ||
1618 | SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1), | ||
1619 | SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2), | ||
1620 | SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3), | ||
1621 | SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4), | ||
1622 | }; | ||
1623 | |||
1624 | static ssize_t | ||
1625 | show_temp_label(struct device *dev, struct device_attribute *attr, char *buf) | ||
1626 | { | ||
1627 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1628 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1629 | int nr = sattr->index; | ||
1630 | return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]); | ||
1631 | } | ||
1632 | |||
1633 | static ssize_t | ||
1634 | show_temp(struct device *dev, struct device_attribute *attr, char *buf) | ||
1635 | { | ||
1636 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1637 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
1638 | int nr = sattr->nr; | ||
1639 | int index = sattr->index; | ||
1640 | |||
1641 | return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[index][nr])); | ||
1642 | } | ||
1643 | |||
1644 | static ssize_t | ||
1645 | store_temp(struct device *dev, struct device_attribute *attr, const char *buf, | ||
1646 | size_t count) | ||
1647 | { | ||
1648 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1649 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
1650 | int nr = sattr->nr; | ||
1651 | int index = sattr->index; | ||
1652 | int err; | ||
1653 | long val; | ||
1654 | |||
1655 | err = kstrtol(buf, 10, &val); | ||
1656 | if (err < 0) | ||
1657 | return err; | ||
1658 | |||
1659 | mutex_lock(&data->update_lock); | ||
1660 | data->temp[index][nr] = LM75_TEMP_TO_REG(val); | ||
1661 | nct6775_write_temp(data, data->reg_temp[index][nr], | ||
1662 | data->temp[index][nr]); | ||
1663 | mutex_unlock(&data->update_lock); | ||
1664 | return count; | ||
1665 | } | ||
1666 | |||
1667 | static ssize_t | ||
1668 | show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf) | ||
1669 | { | ||
1670 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1671 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1672 | |||
1673 | return sprintf(buf, "%d\n", data->temp_offset[sattr->index] * 1000); | ||
1674 | } | ||
1675 | |||
1676 | static ssize_t | ||
1677 | store_temp_offset(struct device *dev, struct device_attribute *attr, | ||
1678 | const char *buf, size_t count) | ||
1679 | { | ||
1680 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1681 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1682 | int nr = sattr->index; | ||
1683 | long val; | ||
1684 | int err; | ||
1685 | |||
1686 | err = kstrtol(buf, 10, &val); | ||
1687 | if (err < 0) | ||
1688 | return err; | ||
1689 | |||
1690 | val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); | ||
1691 | |||
1692 | mutex_lock(&data->update_lock); | ||
1693 | data->temp_offset[nr] = val; | ||
1694 | nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val); | ||
1695 | mutex_unlock(&data->update_lock); | ||
1696 | |||
1697 | return count; | ||
1698 | } | ||
1699 | |||
1700 | static ssize_t | ||
1701 | show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) | ||
1702 | { | ||
1703 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1704 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1705 | int nr = sattr->index; | ||
1706 | return sprintf(buf, "%d\n", (int)data->temp_type[nr]); | ||
1707 | } | ||
1708 | |||
1709 | static ssize_t | ||
1710 | store_temp_type(struct device *dev, struct device_attribute *attr, | ||
1711 | const char *buf, size_t count) | ||
1712 | { | ||
1713 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1714 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1715 | int nr = sattr->index; | ||
1716 | unsigned long val; | ||
1717 | int err; | ||
1718 | u8 vbat, diode, bit; | ||
1719 | |||
1720 | err = kstrtoul(buf, 10, &val); | ||
1721 | if (err < 0) | ||
1722 | return err; | ||
1723 | |||
1724 | if (val != 1 && val != 3 && val != 4) | ||
1725 | return -EINVAL; | ||
1726 | |||
1727 | mutex_lock(&data->update_lock); | ||
1728 | |||
1729 | data->temp_type[nr] = val; | ||
1730 | vbat = nct6775_read_value(data, data->REG_VBAT) & ~(0x02 << nr); | ||
1731 | diode = nct6775_read_value(data, data->REG_DIODE) & ~(0x02 << nr); | ||
1732 | bit = 0x02 << nr; | ||
1733 | switch (val) { | ||
1734 | case 1: /* CPU diode (diode, current mode) */ | ||
1735 | vbat |= bit; | ||
1736 | diode |= bit; | ||
1737 | break; | ||
1738 | case 3: /* diode, voltage mode */ | ||
1739 | vbat |= bit; | ||
1740 | break; | ||
1741 | case 4: /* thermistor */ | ||
1742 | break; | ||
1743 | } | ||
1744 | nct6775_write_value(data, data->REG_VBAT, vbat); | ||
1745 | nct6775_write_value(data, data->REG_DIODE, diode); | ||
1746 | |||
1747 | mutex_unlock(&data->update_lock); | ||
1748 | return count; | ||
1749 | } | ||
1750 | |||
1751 | static struct sensor_device_attribute_2 sda_temp_input[] = { | ||
1752 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), | ||
1753 | SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0), | ||
1754 | SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0), | ||
1755 | SENSOR_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0), | ||
1756 | SENSOR_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0), | ||
1757 | SENSOR_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0), | ||
1758 | SENSOR_ATTR_2(temp7_input, S_IRUGO, show_temp, NULL, 6, 0), | ||
1759 | SENSOR_ATTR_2(temp8_input, S_IRUGO, show_temp, NULL, 7, 0), | ||
1760 | SENSOR_ATTR_2(temp9_input, S_IRUGO, show_temp, NULL, 8, 0), | ||
1761 | SENSOR_ATTR_2(temp10_input, S_IRUGO, show_temp, NULL, 9, 0), | ||
1762 | }; | ||
1763 | |||
1764 | static struct sensor_device_attribute sda_temp_label[] = { | ||
1765 | SENSOR_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0), | ||
1766 | SENSOR_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1), | ||
1767 | SENSOR_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2), | ||
1768 | SENSOR_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3), | ||
1769 | SENSOR_ATTR(temp5_label, S_IRUGO, show_temp_label, NULL, 4), | ||
1770 | SENSOR_ATTR(temp6_label, S_IRUGO, show_temp_label, NULL, 5), | ||
1771 | SENSOR_ATTR(temp7_label, S_IRUGO, show_temp_label, NULL, 6), | ||
1772 | SENSOR_ATTR(temp8_label, S_IRUGO, show_temp_label, NULL, 7), | ||
1773 | SENSOR_ATTR(temp9_label, S_IRUGO, show_temp_label, NULL, 8), | ||
1774 | SENSOR_ATTR(temp10_label, S_IRUGO, show_temp_label, NULL, 9), | ||
1775 | }; | ||
1776 | |||
1777 | static struct sensor_device_attribute_2 sda_temp_max[] = { | ||
1778 | SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1779 | 0, 1), | ||
1780 | SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1781 | 1, 1), | ||
1782 | SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1783 | 2, 1), | ||
1784 | SENSOR_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1785 | 3, 1), | ||
1786 | SENSOR_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1787 | 4, 1), | ||
1788 | SENSOR_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1789 | 5, 1), | ||
1790 | SENSOR_ATTR_2(temp7_max, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1791 | 6, 1), | ||
1792 | SENSOR_ATTR_2(temp8_max, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1793 | 7, 1), | ||
1794 | SENSOR_ATTR_2(temp9_max, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1795 | 8, 1), | ||
1796 | SENSOR_ATTR_2(temp10_max, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1797 | 9, 1), | ||
1798 | }; | ||
1799 | |||
1800 | static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { | ||
1801 | SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1802 | 0, 2), | ||
1803 | SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1804 | 1, 2), | ||
1805 | SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1806 | 2, 2), | ||
1807 | SENSOR_ATTR_2(temp4_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1808 | 3, 2), | ||
1809 | SENSOR_ATTR_2(temp5_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1810 | 4, 2), | ||
1811 | SENSOR_ATTR_2(temp6_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1812 | 5, 2), | ||
1813 | SENSOR_ATTR_2(temp7_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1814 | 6, 2), | ||
1815 | SENSOR_ATTR_2(temp8_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1816 | 7, 2), | ||
1817 | SENSOR_ATTR_2(temp9_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1818 | 8, 2), | ||
1819 | SENSOR_ATTR_2(temp10_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1820 | 9, 2), | ||
1821 | }; | ||
1822 | |||
1823 | static struct sensor_device_attribute_2 sda_temp_crit[] = { | ||
1824 | SENSOR_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1825 | 0, 3), | ||
1826 | SENSOR_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1827 | 1, 3), | ||
1828 | SENSOR_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1829 | 2, 3), | ||
1830 | SENSOR_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1831 | 3, 3), | ||
1832 | SENSOR_ATTR_2(temp5_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1833 | 4, 3), | ||
1834 | SENSOR_ATTR_2(temp6_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1835 | 5, 3), | ||
1836 | SENSOR_ATTR_2(temp7_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1837 | 6, 3), | ||
1838 | SENSOR_ATTR_2(temp8_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1839 | 7, 3), | ||
1840 | SENSOR_ATTR_2(temp9_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1841 | 8, 3), | ||
1842 | SENSOR_ATTR_2(temp10_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, | ||
1843 | 9, 3), | ||
1844 | }; | ||
1845 | |||
1846 | static struct sensor_device_attribute sda_temp_offset[] = { | ||
1847 | SENSOR_ATTR(temp1_offset, S_IRUGO | S_IWUSR, show_temp_offset, | ||
1848 | store_temp_offset, 0), | ||
1849 | SENSOR_ATTR(temp2_offset, S_IRUGO | S_IWUSR, show_temp_offset, | ||
1850 | store_temp_offset, 1), | ||
1851 | SENSOR_ATTR(temp3_offset, S_IRUGO | S_IWUSR, show_temp_offset, | ||
1852 | store_temp_offset, 2), | ||
1853 | SENSOR_ATTR(temp4_offset, S_IRUGO | S_IWUSR, show_temp_offset, | ||
1854 | store_temp_offset, 3), | ||
1855 | SENSOR_ATTR(temp5_offset, S_IRUGO | S_IWUSR, show_temp_offset, | ||
1856 | store_temp_offset, 4), | ||
1857 | SENSOR_ATTR(temp6_offset, S_IRUGO | S_IWUSR, show_temp_offset, | ||
1858 | store_temp_offset, 5), | ||
1859 | }; | ||
1860 | |||
1861 | static struct sensor_device_attribute sda_temp_type[] = { | ||
1862 | SENSOR_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_temp_type, | ||
1863 | store_temp_type, 0), | ||
1864 | SENSOR_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type, | ||
1865 | store_temp_type, 1), | ||
1866 | SENSOR_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type, | ||
1867 | store_temp_type, 2), | ||
1868 | SENSOR_ATTR(temp4_type, S_IRUGO | S_IWUSR, show_temp_type, | ||
1869 | store_temp_type, 3), | ||
1870 | SENSOR_ATTR(temp5_type, S_IRUGO | S_IWUSR, show_temp_type, | ||
1871 | store_temp_type, 4), | ||
1872 | SENSOR_ATTR(temp6_type, S_IRUGO | S_IWUSR, show_temp_type, | ||
1873 | store_temp_type, 5), | ||
1874 | }; | ||
1875 | |||
1876 | static struct sensor_device_attribute sda_temp_alarm[] = { | ||
1877 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, | ||
1878 | TEMP_ALARM_BASE), | ||
1879 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, | ||
1880 | TEMP_ALARM_BASE + 1), | ||
1881 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, | ||
1882 | TEMP_ALARM_BASE + 2), | ||
1883 | SENSOR_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, | ||
1884 | TEMP_ALARM_BASE + 3), | ||
1885 | SENSOR_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL, | ||
1886 | TEMP_ALARM_BASE + 4), | ||
1887 | SENSOR_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL, | ||
1888 | TEMP_ALARM_BASE + 5), | ||
1889 | }; | ||
1890 | |||
1891 | #define NUM_TEMP_ALARM ARRAY_SIZE(sda_temp_alarm) | ||
1892 | |||
1893 | static ssize_t | ||
1894 | show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf) | ||
1895 | { | ||
1896 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1897 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1898 | |||
1899 | return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]); | ||
1900 | } | ||
1901 | |||
1902 | static ssize_t | ||
1903 | store_pwm_mode(struct device *dev, struct device_attribute *attr, | ||
1904 | const char *buf, size_t count) | ||
1905 | { | ||
1906 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1907 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1908 | int nr = sattr->index; | ||
1909 | unsigned long val; | ||
1910 | int err; | ||
1911 | u8 reg; | ||
1912 | |||
1913 | err = kstrtoul(buf, 10, &val); | ||
1914 | if (err < 0) | ||
1915 | return err; | ||
1916 | |||
1917 | if (val > 1) | ||
1918 | return -EINVAL; | ||
1919 | |||
1920 | /* Setting DC mode is not supported for all chips/channels */ | ||
1921 | if (data->REG_PWM_MODE[nr] == 0) { | ||
1922 | if (val) | ||
1923 | return -EINVAL; | ||
1924 | return count; | ||
1925 | } | ||
1926 | |||
1927 | mutex_lock(&data->update_lock); | ||
1928 | data->pwm_mode[nr] = val; | ||
1929 | reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]); | ||
1930 | reg &= ~data->PWM_MODE_MASK[nr]; | ||
1931 | if (val) | ||
1932 | reg |= data->PWM_MODE_MASK[nr]; | ||
1933 | nct6775_write_value(data, data->REG_PWM_MODE[nr], reg); | ||
1934 | mutex_unlock(&data->update_lock); | ||
1935 | return count; | ||
1936 | } | ||
1937 | |||
1938 | static ssize_t | ||
1939 | show_pwm(struct device *dev, struct device_attribute *attr, char *buf) | ||
1940 | { | ||
1941 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1942 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
1943 | int nr = sattr->nr; | ||
1944 | int index = sattr->index; | ||
1945 | int pwm; | ||
1946 | |||
1947 | /* | ||
1948 | * For automatic fan control modes, show current pwm readings. | ||
1949 | * Otherwise, show the configured value. | ||
1950 | */ | ||
1951 | if (index == 0 && data->pwm_enable[nr] > manual) | ||
1952 | pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]); | ||
1953 | else | ||
1954 | pwm = data->pwm[index][nr]; | ||
1955 | |||
1956 | return sprintf(buf, "%d\n", pwm); | ||
1957 | } | ||
1958 | |||
1959 | static ssize_t | ||
1960 | store_pwm(struct device *dev, struct device_attribute *attr, const char *buf, | ||
1961 | size_t count) | ||
1962 | { | ||
1963 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1964 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
1965 | int nr = sattr->nr; | ||
1966 | int index = sattr->index; | ||
1967 | unsigned long val; | ||
1968 | int minval[7] = { 0, 1, 1, data->pwm[2][nr], 0, 0, 0 }; | ||
1969 | int maxval[7] | ||
1970 | = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255, 255, 255 }; | ||
1971 | int err; | ||
1972 | u8 reg; | ||
1973 | |||
1974 | err = kstrtoul(buf, 10, &val); | ||
1975 | if (err < 0) | ||
1976 | return err; | ||
1977 | val = clamp_val(val, minval[index], maxval[index]); | ||
1978 | |||
1979 | mutex_lock(&data->update_lock); | ||
1980 | data->pwm[index][nr] = val; | ||
1981 | nct6775_write_value(data, data->REG_PWM[index][nr], val); | ||
1982 | if (index == 2) { /* floor: disable if val == 0 */ | ||
1983 | reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]); | ||
1984 | reg &= 0x7f; | ||
1985 | if (val) | ||
1986 | reg |= 0x80; | ||
1987 | nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg); | ||
1988 | } | ||
1989 | mutex_unlock(&data->update_lock); | ||
1990 | return count; | ||
1991 | } | ||
1992 | |||
1993 | /* Returns 0 if OK, -EINVAL otherwise */ | ||
1994 | static int check_trip_points(struct nct6775_data *data, int nr) | ||
1995 | { | ||
1996 | int i; | ||
1997 | |||
1998 | for (i = 0; i < data->auto_pwm_num - 1; i++) { | ||
1999 | if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1]) | ||
2000 | return -EINVAL; | ||
2001 | } | ||
2002 | for (i = 0; i < data->auto_pwm_num - 1; i++) { | ||
2003 | if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1]) | ||
2004 | return -EINVAL; | ||
2005 | } | ||
2006 | /* validate critical temperature and pwm if enabled (pwm > 0) */ | ||
2007 | if (data->auto_pwm[nr][data->auto_pwm_num]) { | ||
2008 | if (data->auto_temp[nr][data->auto_pwm_num - 1] > | ||
2009 | data->auto_temp[nr][data->auto_pwm_num] || | ||
2010 | data->auto_pwm[nr][data->auto_pwm_num - 1] > | ||
2011 | data->auto_pwm[nr][data->auto_pwm_num]) | ||
2012 | return -EINVAL; | ||
2013 | } | ||
2014 | return 0; | ||
2015 | } | ||
2016 | |||
2017 | static void pwm_update_registers(struct nct6775_data *data, int nr) | ||
2018 | { | ||
2019 | u8 reg; | ||
2020 | |||
2021 | switch (data->pwm_enable[nr]) { | ||
2022 | case off: | ||
2023 | case manual: | ||
2024 | break; | ||
2025 | case speed_cruise: | ||
2026 | reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]); | ||
2027 | reg = (reg & ~data->tolerance_mask) | | ||
2028 | (data->target_speed_tolerance[nr] & data->tolerance_mask); | ||
2029 | nct6775_write_value(data, data->REG_FAN_MODE[nr], reg); | ||
2030 | nct6775_write_value(data, data->REG_TARGET[nr], | ||
2031 | data->target_speed[nr] & 0xff); | ||
2032 | if (data->REG_TOLERANCE_H) { | ||
2033 | reg = (data->target_speed[nr] >> 8) & 0x0f; | ||
2034 | reg |= (data->target_speed_tolerance[nr] & 0x38) << 1; | ||
2035 | nct6775_write_value(data, | ||
2036 | data->REG_TOLERANCE_H[nr], | ||
2037 | reg); | ||
2038 | } | ||
2039 | break; | ||
2040 | case thermal_cruise: | ||
2041 | nct6775_write_value(data, data->REG_TARGET[nr], | ||
2042 | data->target_temp[nr]); | ||
2043 | /* intentional */ | ||
2044 | default: | ||
2045 | reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]); | ||
2046 | reg = (reg & ~data->tolerance_mask) | | ||
2047 | data->temp_tolerance[0][nr]; | ||
2048 | nct6775_write_value(data, data->REG_FAN_MODE[nr], reg); | ||
2049 | break; | ||
2050 | } | ||
2051 | } | ||
2052 | |||
2053 | static ssize_t | ||
2054 | show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) | ||
2055 | { | ||
2056 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2057 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2058 | |||
2059 | return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]); | ||
2060 | } | ||
2061 | |||
2062 | static ssize_t | ||
2063 | store_pwm_enable(struct device *dev, struct device_attribute *attr, | ||
2064 | const char *buf, size_t count) | ||
2065 | { | ||
2066 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2067 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2068 | int nr = sattr->index; | ||
2069 | unsigned long val; | ||
2070 | int err; | ||
2071 | u16 reg; | ||
2072 | |||
2073 | err = kstrtoul(buf, 10, &val); | ||
2074 | if (err < 0) | ||
2075 | return err; | ||
2076 | |||
2077 | if (val > sf4) | ||
2078 | return -EINVAL; | ||
2079 | |||
2080 | if (val == sf3 && data->kind != nct6775) | ||
2081 | return -EINVAL; | ||
2082 | |||
2083 | if (val == sf4 && check_trip_points(data, nr)) { | ||
2084 | dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n"); | ||
2085 | dev_err(dev, "Adjust trip points and try again\n"); | ||
2086 | return -EINVAL; | ||
2087 | } | ||
2088 | |||
2089 | mutex_lock(&data->update_lock); | ||
2090 | data->pwm_enable[nr] = val; | ||
2091 | if (val == off) { | ||
2092 | /* | ||
2093 | * turn off pwm control: select manual mode, set pwm to maximum | ||
2094 | */ | ||
2095 | data->pwm[0][nr] = 255; | ||
2096 | nct6775_write_value(data, data->REG_PWM[0][nr], 255); | ||
2097 | } | ||
2098 | pwm_update_registers(data, nr); | ||
2099 | reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]); | ||
2100 | reg &= 0x0f; | ||
2101 | reg |= pwm_enable_to_reg(val) << 4; | ||
2102 | nct6775_write_value(data, data->REG_FAN_MODE[nr], reg); | ||
2103 | mutex_unlock(&data->update_lock); | ||
2104 | return count; | ||
2105 | } | ||
2106 | |||
2107 | static ssize_t | ||
2108 | show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src) | ||
2109 | { | ||
2110 | int i, sel = 0; | ||
2111 | |||
2112 | for (i = 0; i < NUM_TEMP; i++) { | ||
2113 | if (!(data->have_temp & (1 << i))) | ||
2114 | continue; | ||
2115 | if (src == data->temp_src[i]) { | ||
2116 | sel = i + 1; | ||
2117 | break; | ||
2118 | } | ||
2119 | } | ||
2120 | |||
2121 | return sprintf(buf, "%d\n", sel); | ||
2122 | } | ||
2123 | |||
2124 | static ssize_t | ||
2125 | show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf) | ||
2126 | { | ||
2127 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2128 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2129 | int index = sattr->index; | ||
2130 | |||
2131 | return show_pwm_temp_sel_common(data, buf, data->pwm_temp_sel[index]); | ||
2132 | } | ||
2133 | |||
2134 | static ssize_t | ||
2135 | store_pwm_temp_sel(struct device *dev, struct device_attribute *attr, | ||
2136 | const char *buf, size_t count) | ||
2137 | { | ||
2138 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2139 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2140 | int nr = sattr->index; | ||
2141 | unsigned long val; | ||
2142 | int err, reg, src; | ||
2143 | |||
2144 | err = kstrtoul(buf, 10, &val); | ||
2145 | if (err < 0) | ||
2146 | return err; | ||
2147 | if (val == 0 || val > NUM_TEMP) | ||
2148 | return -EINVAL; | ||
2149 | if (!(data->have_temp & (1 << (val - 1))) || !data->temp_src[val - 1]) | ||
2150 | return -EINVAL; | ||
2151 | |||
2152 | mutex_lock(&data->update_lock); | ||
2153 | src = data->temp_src[val - 1]; | ||
2154 | data->pwm_temp_sel[nr] = src; | ||
2155 | reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]); | ||
2156 | reg &= 0xe0; | ||
2157 | reg |= src; | ||
2158 | nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg); | ||
2159 | mutex_unlock(&data->update_lock); | ||
2160 | |||
2161 | return count; | ||
2162 | } | ||
2163 | |||
2164 | static ssize_t | ||
2165 | show_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr, | ||
2166 | char *buf) | ||
2167 | { | ||
2168 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2169 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2170 | int index = sattr->index; | ||
2171 | |||
2172 | return show_pwm_temp_sel_common(data, buf, | ||
2173 | data->pwm_weight_temp_sel[index]); | ||
2174 | } | ||
2175 | |||
2176 | static ssize_t | ||
2177 | store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr, | ||
2178 | const char *buf, size_t count) | ||
2179 | { | ||
2180 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2181 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2182 | int nr = sattr->index; | ||
2183 | unsigned long val; | ||
2184 | int err, reg, src; | ||
2185 | |||
2186 | err = kstrtoul(buf, 10, &val); | ||
2187 | if (err < 0) | ||
2188 | return err; | ||
2189 | if (val > NUM_TEMP) | ||
2190 | return -EINVAL; | ||
2191 | if (val && (!(data->have_temp & (1 << (val - 1))) || | ||
2192 | !data->temp_src[val - 1])) | ||
2193 | return -EINVAL; | ||
2194 | |||
2195 | mutex_lock(&data->update_lock); | ||
2196 | if (val) { | ||
2197 | src = data->temp_src[val - 1]; | ||
2198 | data->pwm_weight_temp_sel[nr] = src; | ||
2199 | reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]); | ||
2200 | reg &= 0xe0; | ||
2201 | reg |= (src | 0x80); | ||
2202 | nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg); | ||
2203 | } else { | ||
2204 | data->pwm_weight_temp_sel[nr] = 0; | ||
2205 | reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]); | ||
2206 | reg &= 0x7f; | ||
2207 | nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg); | ||
2208 | } | ||
2209 | mutex_unlock(&data->update_lock); | ||
2210 | |||
2211 | return count; | ||
2212 | } | ||
2213 | |||
2214 | static ssize_t | ||
2215 | show_target_temp(struct device *dev, struct device_attribute *attr, char *buf) | ||
2216 | { | ||
2217 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2218 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2219 | |||
2220 | return sprintf(buf, "%d\n", data->target_temp[sattr->index] * 1000); | ||
2221 | } | ||
2222 | |||
2223 | static ssize_t | ||
2224 | store_target_temp(struct device *dev, struct device_attribute *attr, | ||
2225 | const char *buf, size_t count) | ||
2226 | { | ||
2227 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2228 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2229 | int nr = sattr->index; | ||
2230 | unsigned long val; | ||
2231 | int err; | ||
2232 | |||
2233 | err = kstrtoul(buf, 10, &val); | ||
2234 | if (err < 0) | ||
2235 | return err; | ||
2236 | |||
2237 | val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, | ||
2238 | data->target_temp_mask); | ||
2239 | |||
2240 | mutex_lock(&data->update_lock); | ||
2241 | data->target_temp[nr] = val; | ||
2242 | pwm_update_registers(data, nr); | ||
2243 | mutex_unlock(&data->update_lock); | ||
2244 | return count; | ||
2245 | } | ||
2246 | |||
2247 | static ssize_t | ||
2248 | show_target_speed(struct device *dev, struct device_attribute *attr, char *buf) | ||
2249 | { | ||
2250 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2251 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2252 | int nr = sattr->index; | ||
2253 | |||
2254 | return sprintf(buf, "%d\n", | ||
2255 | fan_from_reg16(data->target_speed[nr], | ||
2256 | data->fan_div[nr])); | ||
2257 | } | ||
2258 | |||
2259 | static ssize_t | ||
2260 | store_target_speed(struct device *dev, struct device_attribute *attr, | ||
2261 | const char *buf, size_t count) | ||
2262 | { | ||
2263 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2264 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2265 | int nr = sattr->index; | ||
2266 | unsigned long val; | ||
2267 | int err; | ||
2268 | u16 speed; | ||
2269 | |||
2270 | err = kstrtoul(buf, 10, &val); | ||
2271 | if (err < 0) | ||
2272 | return err; | ||
2273 | |||
2274 | val = clamp_val(val, 0, 1350000U); | ||
2275 | speed = fan_to_reg(val, data->fan_div[nr]); | ||
2276 | |||
2277 | mutex_lock(&data->update_lock); | ||
2278 | data->target_speed[nr] = speed; | ||
2279 | pwm_update_registers(data, nr); | ||
2280 | mutex_unlock(&data->update_lock); | ||
2281 | return count; | ||
2282 | } | ||
2283 | |||
2284 | static ssize_t | ||
2285 | show_temp_tolerance(struct device *dev, struct device_attribute *attr, | ||
2286 | char *buf) | ||
2287 | { | ||
2288 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2289 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2290 | int nr = sattr->nr; | ||
2291 | int index = sattr->index; | ||
2292 | |||
2293 | return sprintf(buf, "%d\n", data->temp_tolerance[index][nr] * 1000); | ||
2294 | } | ||
2295 | |||
2296 | static ssize_t | ||
2297 | store_temp_tolerance(struct device *dev, struct device_attribute *attr, | ||
2298 | const char *buf, size_t count) | ||
2299 | { | ||
2300 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2301 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2302 | int nr = sattr->nr; | ||
2303 | int index = sattr->index; | ||
2304 | unsigned long val; | ||
2305 | int err; | ||
2306 | |||
2307 | err = kstrtoul(buf, 10, &val); | ||
2308 | if (err < 0) | ||
2309 | return err; | ||
2310 | |||
2311 | /* Limit tolerance as needed */ | ||
2312 | val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask); | ||
2313 | |||
2314 | mutex_lock(&data->update_lock); | ||
2315 | data->temp_tolerance[index][nr] = val; | ||
2316 | if (index) | ||
2317 | pwm_update_registers(data, nr); | ||
2318 | else | ||
2319 | nct6775_write_value(data, | ||
2320 | data->REG_CRITICAL_TEMP_TOLERANCE[nr], | ||
2321 | val); | ||
2322 | mutex_unlock(&data->update_lock); | ||
2323 | return count; | ||
2324 | } | ||
2325 | |||
2326 | /* | ||
2327 | * Fan speed tolerance is a tricky beast, since the associated register is | ||
2328 | * a tick counter, but the value is reported and configured as rpm. | ||
2329 | * Compute resulting low and high rpm values and report the difference. | ||
2330 | */ | ||
2331 | static ssize_t | ||
2332 | show_speed_tolerance(struct device *dev, struct device_attribute *attr, | ||
2333 | char *buf) | ||
2334 | { | ||
2335 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2336 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2337 | int nr = sattr->index; | ||
2338 | int low = data->target_speed[nr] - data->target_speed_tolerance[nr]; | ||
2339 | int high = data->target_speed[nr] + data->target_speed_tolerance[nr]; | ||
2340 | int tolerance; | ||
2341 | |||
2342 | if (low <= 0) | ||
2343 | low = 1; | ||
2344 | if (high > 0xffff) | ||
2345 | high = 0xffff; | ||
2346 | if (high < low) | ||
2347 | high = low; | ||
2348 | |||
2349 | tolerance = (fan_from_reg16(low, data->fan_div[nr]) | ||
2350 | - fan_from_reg16(high, data->fan_div[nr])) / 2; | ||
2351 | |||
2352 | return sprintf(buf, "%d\n", tolerance); | ||
2353 | } | ||
2354 | |||
2355 | static ssize_t | ||
2356 | store_speed_tolerance(struct device *dev, struct device_attribute *attr, | ||
2357 | const char *buf, size_t count) | ||
2358 | { | ||
2359 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2360 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2361 | int nr = sattr->index; | ||
2362 | unsigned long val; | ||
2363 | int err; | ||
2364 | int low, high; | ||
2365 | |||
2366 | err = kstrtoul(buf, 10, &val); | ||
2367 | if (err < 0) | ||
2368 | return err; | ||
2369 | |||
2370 | high = fan_from_reg16(data->target_speed[nr], | ||
2371 | data->fan_div[nr]) + val; | ||
2372 | low = fan_from_reg16(data->target_speed[nr], | ||
2373 | data->fan_div[nr]) - val; | ||
2374 | if (low <= 0) | ||
2375 | low = 1; | ||
2376 | if (high < low) | ||
2377 | high = low; | ||
2378 | |||
2379 | val = (fan_to_reg(low, data->fan_div[nr]) - | ||
2380 | fan_to_reg(high, data->fan_div[nr])) / 2; | ||
2381 | |||
2382 | /* Limit tolerance as needed */ | ||
2383 | val = clamp_val(val, 0, data->speed_tolerance_limit); | ||
2384 | |||
2385 | mutex_lock(&data->update_lock); | ||
2386 | data->target_speed_tolerance[nr] = val; | ||
2387 | pwm_update_registers(data, nr); | ||
2388 | mutex_unlock(&data->update_lock); | ||
2389 | return count; | ||
2390 | } | ||
2391 | |||
2392 | static SENSOR_DEVICE_ATTR_2(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0); | ||
2393 | static SENSOR_DEVICE_ATTR_2(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 0); | ||
2394 | static SENSOR_DEVICE_ATTR_2(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 0); | ||
2395 | static SENSOR_DEVICE_ATTR_2(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 0); | ||
2396 | static SENSOR_DEVICE_ATTR_2(pwm5, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 0); | ||
2397 | |||
2398 | static SENSOR_DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode, | ||
2399 | store_pwm_mode, 0); | ||
2400 | static SENSOR_DEVICE_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode, | ||
2401 | store_pwm_mode, 1); | ||
2402 | static SENSOR_DEVICE_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode, | ||
2403 | store_pwm_mode, 2); | ||
2404 | static SENSOR_DEVICE_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode, | ||
2405 | store_pwm_mode, 3); | ||
2406 | static SENSOR_DEVICE_ATTR(pwm5_mode, S_IWUSR | S_IRUGO, show_pwm_mode, | ||
2407 | store_pwm_mode, 4); | ||
2408 | |||
2409 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable, | ||
2410 | store_pwm_enable, 0); | ||
2411 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable, | ||
2412 | store_pwm_enable, 1); | ||
2413 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable, | ||
2414 | store_pwm_enable, 2); | ||
2415 | static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable, | ||
2416 | store_pwm_enable, 3); | ||
2417 | static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_enable, | ||
2418 | store_pwm_enable, 4); | ||
2419 | |||
2420 | static SENSOR_DEVICE_ATTR(pwm1_temp_sel, S_IWUSR | S_IRUGO, | ||
2421 | show_pwm_temp_sel, store_pwm_temp_sel, 0); | ||
2422 | static SENSOR_DEVICE_ATTR(pwm2_temp_sel, S_IWUSR | S_IRUGO, | ||
2423 | show_pwm_temp_sel, store_pwm_temp_sel, 1); | ||
2424 | static SENSOR_DEVICE_ATTR(pwm3_temp_sel, S_IWUSR | S_IRUGO, | ||
2425 | show_pwm_temp_sel, store_pwm_temp_sel, 2); | ||
2426 | static SENSOR_DEVICE_ATTR(pwm4_temp_sel, S_IWUSR | S_IRUGO, | ||
2427 | show_pwm_temp_sel, store_pwm_temp_sel, 3); | ||
2428 | static SENSOR_DEVICE_ATTR(pwm5_temp_sel, S_IWUSR | S_IRUGO, | ||
2429 | show_pwm_temp_sel, store_pwm_temp_sel, 4); | ||
2430 | |||
2431 | static SENSOR_DEVICE_ATTR(pwm1_target_temp, S_IWUSR | S_IRUGO, show_target_temp, | ||
2432 | store_target_temp, 0); | ||
2433 | static SENSOR_DEVICE_ATTR(pwm2_target_temp, S_IWUSR | S_IRUGO, show_target_temp, | ||
2434 | store_target_temp, 1); | ||
2435 | static SENSOR_DEVICE_ATTR(pwm3_target_temp, S_IWUSR | S_IRUGO, show_target_temp, | ||
2436 | store_target_temp, 2); | ||
2437 | static SENSOR_DEVICE_ATTR(pwm4_target_temp, S_IWUSR | S_IRUGO, show_target_temp, | ||
2438 | store_target_temp, 3); | ||
2439 | static SENSOR_DEVICE_ATTR(pwm5_target_temp, S_IWUSR | S_IRUGO, show_target_temp, | ||
2440 | store_target_temp, 4); | ||
2441 | |||
2442 | static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, show_target_speed, | ||
2443 | store_target_speed, 0); | ||
2444 | static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, show_target_speed, | ||
2445 | store_target_speed, 1); | ||
2446 | static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, show_target_speed, | ||
2447 | store_target_speed, 2); | ||
2448 | static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, show_target_speed, | ||
2449 | store_target_speed, 3); | ||
2450 | static SENSOR_DEVICE_ATTR(fan5_target, S_IWUSR | S_IRUGO, show_target_speed, | ||
2451 | store_target_speed, 4); | ||
2452 | |||
2453 | static SENSOR_DEVICE_ATTR(fan1_tolerance, S_IWUSR | S_IRUGO, | ||
2454 | show_speed_tolerance, store_speed_tolerance, 0); | ||
2455 | static SENSOR_DEVICE_ATTR(fan2_tolerance, S_IWUSR | S_IRUGO, | ||
2456 | show_speed_tolerance, store_speed_tolerance, 1); | ||
2457 | static SENSOR_DEVICE_ATTR(fan3_tolerance, S_IWUSR | S_IRUGO, | ||
2458 | show_speed_tolerance, store_speed_tolerance, 2); | ||
2459 | static SENSOR_DEVICE_ATTR(fan4_tolerance, S_IWUSR | S_IRUGO, | ||
2460 | show_speed_tolerance, store_speed_tolerance, 3); | ||
2461 | static SENSOR_DEVICE_ATTR(fan5_tolerance, S_IWUSR | S_IRUGO, | ||
2462 | show_speed_tolerance, store_speed_tolerance, 4); | ||
2463 | |||
2464 | /* Smart Fan registers */ | ||
2465 | |||
2466 | static ssize_t | ||
2467 | show_weight_temp(struct device *dev, struct device_attribute *attr, char *buf) | ||
2468 | { | ||
2469 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2470 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2471 | int nr = sattr->nr; | ||
2472 | int index = sattr->index; | ||
2473 | |||
2474 | return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000); | ||
2475 | } | ||
2476 | |||
2477 | static ssize_t | ||
2478 | store_weight_temp(struct device *dev, struct device_attribute *attr, | ||
2479 | const char *buf, size_t count) | ||
2480 | { | ||
2481 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2482 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2483 | int nr = sattr->nr; | ||
2484 | int index = sattr->index; | ||
2485 | unsigned long val; | ||
2486 | int err; | ||
2487 | |||
2488 | err = kstrtoul(buf, 10, &val); | ||
2489 | if (err < 0) | ||
2490 | return err; | ||
2491 | |||
2492 | val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255); | ||
2493 | |||
2494 | mutex_lock(&data->update_lock); | ||
2495 | data->weight_temp[index][nr] = val; | ||
2496 | nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val); | ||
2497 | mutex_unlock(&data->update_lock); | ||
2498 | return count; | ||
2499 | } | ||
2500 | |||
2501 | static SENSOR_DEVICE_ATTR(pwm1_weight_temp_sel, S_IWUSR | S_IRUGO, | ||
2502 | show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, | ||
2503 | 0); | ||
2504 | static SENSOR_DEVICE_ATTR(pwm2_weight_temp_sel, S_IWUSR | S_IRUGO, | ||
2505 | show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, | ||
2506 | 1); | ||
2507 | static SENSOR_DEVICE_ATTR(pwm3_weight_temp_sel, S_IWUSR | S_IRUGO, | ||
2508 | show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, | ||
2509 | 2); | ||
2510 | static SENSOR_DEVICE_ATTR(pwm4_weight_temp_sel, S_IWUSR | S_IRUGO, | ||
2511 | show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, | ||
2512 | 3); | ||
2513 | static SENSOR_DEVICE_ATTR(pwm5_weight_temp_sel, S_IWUSR | S_IRUGO, | ||
2514 | show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, | ||
2515 | 4); | ||
2516 | |||
2517 | static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step, S_IWUSR | S_IRUGO, | ||
2518 | show_weight_temp, store_weight_temp, 0, 0); | ||
2519 | static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step, S_IWUSR | S_IRUGO, | ||
2520 | show_weight_temp, store_weight_temp, 1, 0); | ||
2521 | static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step, S_IWUSR | S_IRUGO, | ||
2522 | show_weight_temp, store_weight_temp, 2, 0); | ||
2523 | static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step, S_IWUSR | S_IRUGO, | ||
2524 | show_weight_temp, store_weight_temp, 3, 0); | ||
2525 | static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step, S_IWUSR | S_IRUGO, | ||
2526 | show_weight_temp, store_weight_temp, 4, 0); | ||
2527 | |||
2528 | static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_tol, S_IWUSR | S_IRUGO, | ||
2529 | show_weight_temp, store_weight_temp, 0, 1); | ||
2530 | static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_tol, S_IWUSR | S_IRUGO, | ||
2531 | show_weight_temp, store_weight_temp, 1, 1); | ||
2532 | static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_tol, S_IWUSR | S_IRUGO, | ||
2533 | show_weight_temp, store_weight_temp, 2, 1); | ||
2534 | static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_tol, S_IWUSR | S_IRUGO, | ||
2535 | show_weight_temp, store_weight_temp, 3, 1); | ||
2536 | static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_tol, S_IWUSR | S_IRUGO, | ||
2537 | show_weight_temp, store_weight_temp, 4, 1); | ||
2538 | |||
2539 | static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_base, S_IWUSR | S_IRUGO, | ||
2540 | show_weight_temp, store_weight_temp, 0, 2); | ||
2541 | static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_base, S_IWUSR | S_IRUGO, | ||
2542 | show_weight_temp, store_weight_temp, 1, 2); | ||
2543 | static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_base, S_IWUSR | S_IRUGO, | ||
2544 | show_weight_temp, store_weight_temp, 2, 2); | ||
2545 | static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_base, S_IWUSR | S_IRUGO, | ||
2546 | show_weight_temp, store_weight_temp, 3, 2); | ||
2547 | static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_base, S_IWUSR | S_IRUGO, | ||
2548 | show_weight_temp, store_weight_temp, 4, 2); | ||
2549 | |||
2550 | static SENSOR_DEVICE_ATTR_2(pwm1_weight_duty_step, S_IWUSR | S_IRUGO, | ||
2551 | show_pwm, store_pwm, 0, 5); | ||
2552 | static SENSOR_DEVICE_ATTR_2(pwm2_weight_duty_step, S_IWUSR | S_IRUGO, | ||
2553 | show_pwm, store_pwm, 1, 5); | ||
2554 | static SENSOR_DEVICE_ATTR_2(pwm3_weight_duty_step, S_IWUSR | S_IRUGO, | ||
2555 | show_pwm, store_pwm, 2, 5); | ||
2556 | static SENSOR_DEVICE_ATTR_2(pwm4_weight_duty_step, S_IWUSR | S_IRUGO, | ||
2557 | show_pwm, store_pwm, 3, 5); | ||
2558 | static SENSOR_DEVICE_ATTR_2(pwm5_weight_duty_step, S_IWUSR | S_IRUGO, | ||
2559 | show_pwm, store_pwm, 4, 5); | ||
2560 | |||
2561 | /* duty_base is not supported on all chips */ | ||
2562 | static struct sensor_device_attribute_2 sda_weight_duty_base[] = { | ||
2563 | SENSOR_ATTR_2(pwm1_weight_duty_base, S_IWUSR | S_IRUGO, | ||
2564 | show_pwm, store_pwm, 0, 6), | ||
2565 | SENSOR_ATTR_2(pwm2_weight_duty_base, S_IWUSR | S_IRUGO, | ||
2566 | show_pwm, store_pwm, 1, 6), | ||
2567 | SENSOR_ATTR_2(pwm3_weight_duty_base, S_IWUSR | S_IRUGO, | ||
2568 | show_pwm, store_pwm, 2, 6), | ||
2569 | SENSOR_ATTR_2(pwm4_weight_duty_base, S_IWUSR | S_IRUGO, | ||
2570 | show_pwm, store_pwm, 3, 6), | ||
2571 | SENSOR_ATTR_2(pwm5_weight_duty_base, S_IWUSR | S_IRUGO, | ||
2572 | show_pwm, store_pwm, 4, 6), | ||
2573 | }; | ||
2574 | |||
2575 | static ssize_t | ||
2576 | show_fan_time(struct device *dev, struct device_attribute *attr, char *buf) | ||
2577 | { | ||
2578 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2579 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2580 | int nr = sattr->nr; | ||
2581 | int index = sattr->index; | ||
2582 | |||
2583 | return sprintf(buf, "%d\n", | ||
2584 | step_time_from_reg(data->fan_time[index][nr], | ||
2585 | data->pwm_mode[nr])); | ||
2586 | } | ||
2587 | |||
2588 | static ssize_t | ||
2589 | store_fan_time(struct device *dev, struct device_attribute *attr, | ||
2590 | const char *buf, size_t count) | ||
2591 | { | ||
2592 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2593 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2594 | int nr = sattr->nr; | ||
2595 | int index = sattr->index; | ||
2596 | unsigned long val; | ||
2597 | int err; | ||
2598 | |||
2599 | err = kstrtoul(buf, 10, &val); | ||
2600 | if (err < 0) | ||
2601 | return err; | ||
2602 | |||
2603 | val = step_time_to_reg(val, data->pwm_mode[nr]); | ||
2604 | mutex_lock(&data->update_lock); | ||
2605 | data->fan_time[index][nr] = val; | ||
2606 | nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val); | ||
2607 | mutex_unlock(&data->update_lock); | ||
2608 | return count; | ||
2609 | } | ||
2610 | |||
2611 | static ssize_t | ||
2612 | show_name(struct device *dev, struct device_attribute *attr, char *buf) | ||
2613 | { | ||
2614 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2615 | |||
2616 | return sprintf(buf, "%s\n", data->name); | ||
2617 | } | ||
2618 | |||
2619 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
2620 | |||
2621 | static SENSOR_DEVICE_ATTR_2(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_time, | ||
2622 | store_fan_time, 0, 0); | ||
2623 | static SENSOR_DEVICE_ATTR_2(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_time, | ||
2624 | store_fan_time, 1, 0); | ||
2625 | static SENSOR_DEVICE_ATTR_2(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_time, | ||
2626 | store_fan_time, 2, 0); | ||
2627 | static SENSOR_DEVICE_ATTR_2(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_time, | ||
2628 | store_fan_time, 3, 0); | ||
2629 | static SENSOR_DEVICE_ATTR_2(pwm5_stop_time, S_IWUSR | S_IRUGO, show_fan_time, | ||
2630 | store_fan_time, 4, 0); | ||
2631 | |||
2632 | static SENSOR_DEVICE_ATTR_2(pwm1_step_up_time, S_IWUSR | S_IRUGO, show_fan_time, | ||
2633 | store_fan_time, 0, 1); | ||
2634 | static SENSOR_DEVICE_ATTR_2(pwm2_step_up_time, S_IWUSR | S_IRUGO, show_fan_time, | ||
2635 | store_fan_time, 1, 1); | ||
2636 | static SENSOR_DEVICE_ATTR_2(pwm3_step_up_time, S_IWUSR | S_IRUGO, show_fan_time, | ||
2637 | store_fan_time, 2, 1); | ||
2638 | static SENSOR_DEVICE_ATTR_2(pwm4_step_up_time, S_IWUSR | S_IRUGO, show_fan_time, | ||
2639 | store_fan_time, 3, 1); | ||
2640 | static SENSOR_DEVICE_ATTR_2(pwm5_step_up_time, S_IWUSR | S_IRUGO, show_fan_time, | ||
2641 | store_fan_time, 4, 1); | ||
2642 | |||
2643 | static SENSOR_DEVICE_ATTR_2(pwm1_step_down_time, S_IWUSR | S_IRUGO, | ||
2644 | show_fan_time, store_fan_time, 0, 2); | ||
2645 | static SENSOR_DEVICE_ATTR_2(pwm2_step_down_time, S_IWUSR | S_IRUGO, | ||
2646 | show_fan_time, store_fan_time, 1, 2); | ||
2647 | static SENSOR_DEVICE_ATTR_2(pwm3_step_down_time, S_IWUSR | S_IRUGO, | ||
2648 | show_fan_time, store_fan_time, 2, 2); | ||
2649 | static SENSOR_DEVICE_ATTR_2(pwm4_step_down_time, S_IWUSR | S_IRUGO, | ||
2650 | show_fan_time, store_fan_time, 3, 2); | ||
2651 | static SENSOR_DEVICE_ATTR_2(pwm5_step_down_time, S_IWUSR | S_IRUGO, | ||
2652 | show_fan_time, store_fan_time, 4, 2); | ||
2653 | |||
2654 | static SENSOR_DEVICE_ATTR_2(pwm1_start, S_IWUSR | S_IRUGO, show_pwm, | ||
2655 | store_pwm, 0, 1); | ||
2656 | static SENSOR_DEVICE_ATTR_2(pwm2_start, S_IWUSR | S_IRUGO, show_pwm, | ||
2657 | store_pwm, 1, 1); | ||
2658 | static SENSOR_DEVICE_ATTR_2(pwm3_start, S_IWUSR | S_IRUGO, show_pwm, | ||
2659 | store_pwm, 2, 1); | ||
2660 | static SENSOR_DEVICE_ATTR_2(pwm4_start, S_IWUSR | S_IRUGO, show_pwm, | ||
2661 | store_pwm, 3, 1); | ||
2662 | static SENSOR_DEVICE_ATTR_2(pwm5_start, S_IWUSR | S_IRUGO, show_pwm, | ||
2663 | store_pwm, 4, 1); | ||
2664 | |||
2665 | static SENSOR_DEVICE_ATTR_2(pwm1_floor, S_IWUSR | S_IRUGO, show_pwm, | ||
2666 | store_pwm, 0, 2); | ||
2667 | static SENSOR_DEVICE_ATTR_2(pwm2_floor, S_IWUSR | S_IRUGO, show_pwm, | ||
2668 | store_pwm, 1, 2); | ||
2669 | static SENSOR_DEVICE_ATTR_2(pwm3_floor, S_IWUSR | S_IRUGO, show_pwm, | ||
2670 | store_pwm, 2, 2); | ||
2671 | static SENSOR_DEVICE_ATTR_2(pwm4_floor, S_IWUSR | S_IRUGO, show_pwm, | ||
2672 | store_pwm, 3, 2); | ||
2673 | static SENSOR_DEVICE_ATTR_2(pwm5_floor, S_IWUSR | S_IRUGO, show_pwm, | ||
2674 | store_pwm, 4, 2); | ||
2675 | |||
2676 | static SENSOR_DEVICE_ATTR_2(pwm1_temp_tolerance, S_IWUSR | S_IRUGO, | ||
2677 | show_temp_tolerance, store_temp_tolerance, 0, 0); | ||
2678 | static SENSOR_DEVICE_ATTR_2(pwm2_temp_tolerance, S_IWUSR | S_IRUGO, | ||
2679 | show_temp_tolerance, store_temp_tolerance, 1, 0); | ||
2680 | static SENSOR_DEVICE_ATTR_2(pwm3_temp_tolerance, S_IWUSR | S_IRUGO, | ||
2681 | show_temp_tolerance, store_temp_tolerance, 2, 0); | ||
2682 | static SENSOR_DEVICE_ATTR_2(pwm4_temp_tolerance, S_IWUSR | S_IRUGO, | ||
2683 | show_temp_tolerance, store_temp_tolerance, 3, 0); | ||
2684 | static SENSOR_DEVICE_ATTR_2(pwm5_temp_tolerance, S_IWUSR | S_IRUGO, | ||
2685 | show_temp_tolerance, store_temp_tolerance, 4, 0); | ||
2686 | |||
2687 | static SENSOR_DEVICE_ATTR_2(pwm1_crit_temp_tolerance, S_IWUSR | S_IRUGO, | ||
2688 | show_temp_tolerance, store_temp_tolerance, 0, 1); | ||
2689 | static SENSOR_DEVICE_ATTR_2(pwm2_crit_temp_tolerance, S_IWUSR | S_IRUGO, | ||
2690 | show_temp_tolerance, store_temp_tolerance, 1, 1); | ||
2691 | static SENSOR_DEVICE_ATTR_2(pwm3_crit_temp_tolerance, S_IWUSR | S_IRUGO, | ||
2692 | show_temp_tolerance, store_temp_tolerance, 2, 1); | ||
2693 | static SENSOR_DEVICE_ATTR_2(pwm4_crit_temp_tolerance, S_IWUSR | S_IRUGO, | ||
2694 | show_temp_tolerance, store_temp_tolerance, 3, 1); | ||
2695 | static SENSOR_DEVICE_ATTR_2(pwm5_crit_temp_tolerance, S_IWUSR | S_IRUGO, | ||
2696 | show_temp_tolerance, store_temp_tolerance, 4, 1); | ||
2697 | |||
2698 | /* pwm_max is not supported on all chips */ | ||
2699 | static struct sensor_device_attribute_2 sda_pwm_max[] = { | ||
2700 | SENSOR_ATTR_2(pwm1_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm, | ||
2701 | 0, 3), | ||
2702 | SENSOR_ATTR_2(pwm2_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm, | ||
2703 | 1, 3), | ||
2704 | SENSOR_ATTR_2(pwm3_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm, | ||
2705 | 2, 3), | ||
2706 | SENSOR_ATTR_2(pwm4_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm, | ||
2707 | 3, 3), | ||
2708 | SENSOR_ATTR_2(pwm5_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm, | ||
2709 | 4, 3), | ||
2710 | }; | ||
2711 | |||
2712 | /* pwm_step is not supported on all chips */ | ||
2713 | static struct sensor_device_attribute_2 sda_pwm_step[] = { | ||
2714 | SENSOR_ATTR_2(pwm1_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 4), | ||
2715 | SENSOR_ATTR_2(pwm2_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 4), | ||
2716 | SENSOR_ATTR_2(pwm3_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 4), | ||
2717 | SENSOR_ATTR_2(pwm4_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 4), | ||
2718 | SENSOR_ATTR_2(pwm5_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 4), | ||
2719 | }; | ||
2720 | |||
2721 | static struct attribute *nct6775_attributes_pwm[5][20] = { | ||
2722 | { | ||
2723 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
2724 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, | ||
2725 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
2726 | &sensor_dev_attr_pwm1_temp_sel.dev_attr.attr, | ||
2727 | &sensor_dev_attr_pwm1_temp_tolerance.dev_attr.attr, | ||
2728 | &sensor_dev_attr_pwm1_crit_temp_tolerance.dev_attr.attr, | ||
2729 | &sensor_dev_attr_pwm1_target_temp.dev_attr.attr, | ||
2730 | &sensor_dev_attr_fan1_target.dev_attr.attr, | ||
2731 | &sensor_dev_attr_fan1_tolerance.dev_attr.attr, | ||
2732 | &sensor_dev_attr_pwm1_stop_time.dev_attr.attr, | ||
2733 | &sensor_dev_attr_pwm1_step_up_time.dev_attr.attr, | ||
2734 | &sensor_dev_attr_pwm1_step_down_time.dev_attr.attr, | ||
2735 | &sensor_dev_attr_pwm1_start.dev_attr.attr, | ||
2736 | &sensor_dev_attr_pwm1_floor.dev_attr.attr, | ||
2737 | &sensor_dev_attr_pwm1_weight_temp_sel.dev_attr.attr, | ||
2738 | &sensor_dev_attr_pwm1_weight_temp_step.dev_attr.attr, | ||
2739 | &sensor_dev_attr_pwm1_weight_temp_step_tol.dev_attr.attr, | ||
2740 | &sensor_dev_attr_pwm1_weight_temp_step_base.dev_attr.attr, | ||
2741 | &sensor_dev_attr_pwm1_weight_duty_step.dev_attr.attr, | ||
2742 | NULL | ||
2743 | }, | ||
2744 | { | ||
2745 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
2746 | &sensor_dev_attr_pwm2_mode.dev_attr.attr, | ||
2747 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
2748 | &sensor_dev_attr_pwm2_temp_sel.dev_attr.attr, | ||
2749 | &sensor_dev_attr_pwm2_temp_tolerance.dev_attr.attr, | ||
2750 | &sensor_dev_attr_pwm2_crit_temp_tolerance.dev_attr.attr, | ||
2751 | &sensor_dev_attr_pwm2_target_temp.dev_attr.attr, | ||
2752 | &sensor_dev_attr_fan2_target.dev_attr.attr, | ||
2753 | &sensor_dev_attr_fan2_tolerance.dev_attr.attr, | ||
2754 | &sensor_dev_attr_pwm2_stop_time.dev_attr.attr, | ||
2755 | &sensor_dev_attr_pwm2_step_up_time.dev_attr.attr, | ||
2756 | &sensor_dev_attr_pwm2_step_down_time.dev_attr.attr, | ||
2757 | &sensor_dev_attr_pwm2_start.dev_attr.attr, | ||
2758 | &sensor_dev_attr_pwm2_floor.dev_attr.attr, | ||
2759 | &sensor_dev_attr_pwm2_weight_temp_sel.dev_attr.attr, | ||
2760 | &sensor_dev_attr_pwm2_weight_temp_step.dev_attr.attr, | ||
2761 | &sensor_dev_attr_pwm2_weight_temp_step_tol.dev_attr.attr, | ||
2762 | &sensor_dev_attr_pwm2_weight_temp_step_base.dev_attr.attr, | ||
2763 | &sensor_dev_attr_pwm2_weight_duty_step.dev_attr.attr, | ||
2764 | NULL | ||
2765 | }, | ||
2766 | { | ||
2767 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
2768 | &sensor_dev_attr_pwm3_mode.dev_attr.attr, | ||
2769 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
2770 | &sensor_dev_attr_pwm3_temp_sel.dev_attr.attr, | ||
2771 | &sensor_dev_attr_pwm3_temp_tolerance.dev_attr.attr, | ||
2772 | &sensor_dev_attr_pwm3_crit_temp_tolerance.dev_attr.attr, | ||
2773 | &sensor_dev_attr_pwm3_target_temp.dev_attr.attr, | ||
2774 | &sensor_dev_attr_fan3_target.dev_attr.attr, | ||
2775 | &sensor_dev_attr_fan3_tolerance.dev_attr.attr, | ||
2776 | &sensor_dev_attr_pwm3_stop_time.dev_attr.attr, | ||
2777 | &sensor_dev_attr_pwm3_step_up_time.dev_attr.attr, | ||
2778 | &sensor_dev_attr_pwm3_step_down_time.dev_attr.attr, | ||
2779 | &sensor_dev_attr_pwm3_start.dev_attr.attr, | ||
2780 | &sensor_dev_attr_pwm3_floor.dev_attr.attr, | ||
2781 | &sensor_dev_attr_pwm3_weight_temp_sel.dev_attr.attr, | ||
2782 | &sensor_dev_attr_pwm3_weight_temp_step.dev_attr.attr, | ||
2783 | &sensor_dev_attr_pwm3_weight_temp_step_tol.dev_attr.attr, | ||
2784 | &sensor_dev_attr_pwm3_weight_temp_step_base.dev_attr.attr, | ||
2785 | &sensor_dev_attr_pwm3_weight_duty_step.dev_attr.attr, | ||
2786 | NULL | ||
2787 | }, | ||
2788 | { | ||
2789 | &sensor_dev_attr_pwm4.dev_attr.attr, | ||
2790 | &sensor_dev_attr_pwm4_mode.dev_attr.attr, | ||
2791 | &sensor_dev_attr_pwm4_enable.dev_attr.attr, | ||
2792 | &sensor_dev_attr_pwm4_temp_sel.dev_attr.attr, | ||
2793 | &sensor_dev_attr_pwm4_temp_tolerance.dev_attr.attr, | ||
2794 | &sensor_dev_attr_pwm4_crit_temp_tolerance.dev_attr.attr, | ||
2795 | &sensor_dev_attr_pwm4_target_temp.dev_attr.attr, | ||
2796 | &sensor_dev_attr_fan4_target.dev_attr.attr, | ||
2797 | &sensor_dev_attr_fan4_tolerance.dev_attr.attr, | ||
2798 | &sensor_dev_attr_pwm4_stop_time.dev_attr.attr, | ||
2799 | &sensor_dev_attr_pwm4_step_up_time.dev_attr.attr, | ||
2800 | &sensor_dev_attr_pwm4_step_down_time.dev_attr.attr, | ||
2801 | &sensor_dev_attr_pwm4_start.dev_attr.attr, | ||
2802 | &sensor_dev_attr_pwm4_floor.dev_attr.attr, | ||
2803 | &sensor_dev_attr_pwm4_weight_temp_sel.dev_attr.attr, | ||
2804 | &sensor_dev_attr_pwm4_weight_temp_step.dev_attr.attr, | ||
2805 | &sensor_dev_attr_pwm4_weight_temp_step_tol.dev_attr.attr, | ||
2806 | &sensor_dev_attr_pwm4_weight_temp_step_base.dev_attr.attr, | ||
2807 | &sensor_dev_attr_pwm4_weight_duty_step.dev_attr.attr, | ||
2808 | NULL | ||
2809 | }, | ||
2810 | { | ||
2811 | &sensor_dev_attr_pwm5.dev_attr.attr, | ||
2812 | &sensor_dev_attr_pwm5_mode.dev_attr.attr, | ||
2813 | &sensor_dev_attr_pwm5_enable.dev_attr.attr, | ||
2814 | &sensor_dev_attr_pwm5_temp_sel.dev_attr.attr, | ||
2815 | &sensor_dev_attr_pwm5_temp_tolerance.dev_attr.attr, | ||
2816 | &sensor_dev_attr_pwm5_crit_temp_tolerance.dev_attr.attr, | ||
2817 | &sensor_dev_attr_pwm5_target_temp.dev_attr.attr, | ||
2818 | &sensor_dev_attr_fan5_target.dev_attr.attr, | ||
2819 | &sensor_dev_attr_fan5_tolerance.dev_attr.attr, | ||
2820 | &sensor_dev_attr_pwm5_stop_time.dev_attr.attr, | ||
2821 | &sensor_dev_attr_pwm5_step_up_time.dev_attr.attr, | ||
2822 | &sensor_dev_attr_pwm5_step_down_time.dev_attr.attr, | ||
2823 | &sensor_dev_attr_pwm5_start.dev_attr.attr, | ||
2824 | &sensor_dev_attr_pwm5_floor.dev_attr.attr, | ||
2825 | &sensor_dev_attr_pwm5_weight_temp_sel.dev_attr.attr, | ||
2826 | &sensor_dev_attr_pwm5_weight_temp_step.dev_attr.attr, | ||
2827 | &sensor_dev_attr_pwm5_weight_temp_step_tol.dev_attr.attr, | ||
2828 | &sensor_dev_attr_pwm5_weight_temp_step_base.dev_attr.attr, | ||
2829 | &sensor_dev_attr_pwm5_weight_duty_step.dev_attr.attr, | ||
2830 | NULL | ||
2831 | }, | ||
2832 | }; | ||
2833 | |||
2834 | static const struct attribute_group nct6775_group_pwm[5] = { | ||
2835 | { .attrs = nct6775_attributes_pwm[0] }, | ||
2836 | { .attrs = nct6775_attributes_pwm[1] }, | ||
2837 | { .attrs = nct6775_attributes_pwm[2] }, | ||
2838 | { .attrs = nct6775_attributes_pwm[3] }, | ||
2839 | { .attrs = nct6775_attributes_pwm[4] }, | ||
2840 | }; | ||
2841 | |||
2842 | static ssize_t | ||
2843 | show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf) | ||
2844 | { | ||
2845 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2846 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2847 | |||
2848 | return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]); | ||
2849 | } | ||
2850 | |||
2851 | static ssize_t | ||
2852 | store_auto_pwm(struct device *dev, struct device_attribute *attr, | ||
2853 | const char *buf, size_t count) | ||
2854 | { | ||
2855 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2856 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2857 | int nr = sattr->nr; | ||
2858 | int point = sattr->index; | ||
2859 | unsigned long val; | ||
2860 | int err; | ||
2861 | u8 reg; | ||
2862 | |||
2863 | err = kstrtoul(buf, 10, &val); | ||
2864 | if (err < 0) | ||
2865 | return err; | ||
2866 | if (val > 255) | ||
2867 | return -EINVAL; | ||
2868 | |||
2869 | if (point == data->auto_pwm_num) { | ||
2870 | if (data->kind != nct6775 && !val) | ||
2871 | return -EINVAL; | ||
2872 | if (data->kind != nct6779 && val) | ||
2873 | val = 0xff; | ||
2874 | } | ||
2875 | |||
2876 | mutex_lock(&data->update_lock); | ||
2877 | data->auto_pwm[nr][point] = val; | ||
2878 | if (point < data->auto_pwm_num) { | ||
2879 | nct6775_write_value(data, | ||
2880 | NCT6775_AUTO_PWM(data, nr, point), | ||
2881 | data->auto_pwm[nr][point]); | ||
2882 | } else { | ||
2883 | switch (data->kind) { | ||
2884 | case nct6775: | ||
2885 | /* disable if needed (pwm == 0) */ | ||
2886 | reg = nct6775_read_value(data, | ||
2887 | NCT6775_REG_CRITICAL_ENAB[nr]); | ||
2888 | if (val) | ||
2889 | reg |= 0x02; | ||
2890 | else | ||
2891 | reg &= ~0x02; | ||
2892 | nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr], | ||
2893 | reg); | ||
2894 | break; | ||
2895 | case nct6776: | ||
2896 | break; /* always enabled, nothing to do */ | ||
2897 | case nct6779: | ||
2898 | nct6775_write_value(data, NCT6779_REG_CRITICAL_PWM[nr], | ||
2899 | val); | ||
2900 | reg = nct6775_read_value(data, | ||
2901 | NCT6779_REG_CRITICAL_PWM_ENABLE[nr]); | ||
2902 | if (val == 255) | ||
2903 | reg &= ~0x01; | ||
2904 | else | ||
2905 | reg |= 0x01; | ||
2906 | nct6775_write_value(data, | ||
2907 | NCT6779_REG_CRITICAL_PWM_ENABLE[nr], | ||
2908 | reg); | ||
2909 | break; | ||
2910 | } | ||
2911 | } | ||
2912 | mutex_unlock(&data->update_lock); | ||
2913 | return count; | ||
2914 | } | ||
2915 | |||
2916 | static ssize_t | ||
2917 | show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf) | ||
2918 | { | ||
2919 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2920 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2921 | int nr = sattr->nr; | ||
2922 | int point = sattr->index; | ||
2923 | |||
2924 | /* | ||
2925 | * We don't know for sure if the temperature is signed or unsigned. | ||
2926 | * Assume it is unsigned. | ||
2927 | */ | ||
2928 | return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000); | ||
2929 | } | ||
2930 | |||
2931 | static ssize_t | ||
2932 | store_auto_temp(struct device *dev, struct device_attribute *attr, | ||
2933 | const char *buf, size_t count) | ||
2934 | { | ||
2935 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2936 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2937 | int nr = sattr->nr; | ||
2938 | int point = sattr->index; | ||
2939 | unsigned long val; | ||
2940 | int err; | ||
2941 | |||
2942 | err = kstrtoul(buf, 10, &val); | ||
2943 | if (err) | ||
2944 | return err; | ||
2945 | if (val > 255000) | ||
2946 | return -EINVAL; | ||
2947 | |||
2948 | mutex_lock(&data->update_lock); | ||
2949 | data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000); | ||
2950 | if (point < data->auto_pwm_num) { | ||
2951 | nct6775_write_value(data, | ||
2952 | NCT6775_AUTO_TEMP(data, nr, point), | ||
2953 | data->auto_temp[nr][point]); | ||
2954 | } else { | ||
2955 | nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr], | ||
2956 | data->auto_temp[nr][point]); | ||
2957 | } | ||
2958 | mutex_unlock(&data->update_lock); | ||
2959 | return count; | ||
2960 | } | ||
2961 | |||
2962 | /* | ||
2963 | * The number of auto-point trip points is chip dependent. | ||
2964 | * Need to check support while generating/removing attribute files. | ||
2965 | */ | ||
2966 | static struct sensor_device_attribute_2 sda_auto_pwm_arrays[] = { | ||
2967 | SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
2968 | show_auto_pwm, store_auto_pwm, 0, 0), | ||
2969 | SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
2970 | show_auto_temp, store_auto_temp, 0, 0), | ||
2971 | SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
2972 | show_auto_pwm, store_auto_pwm, 0, 1), | ||
2973 | SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
2974 | show_auto_temp, store_auto_temp, 0, 1), | ||
2975 | SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO, | ||
2976 | show_auto_pwm, store_auto_pwm, 0, 2), | ||
2977 | SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO, | ||
2978 | show_auto_temp, store_auto_temp, 0, 2), | ||
2979 | SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO, | ||
2980 | show_auto_pwm, store_auto_pwm, 0, 3), | ||
2981 | SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO, | ||
2982 | show_auto_temp, store_auto_temp, 0, 3), | ||
2983 | SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO, | ||
2984 | show_auto_pwm, store_auto_pwm, 0, 4), | ||
2985 | SENSOR_ATTR_2(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO, | ||
2986 | show_auto_temp, store_auto_temp, 0, 4), | ||
2987 | SENSOR_ATTR_2(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO, | ||
2988 | show_auto_pwm, store_auto_pwm, 0, 5), | ||
2989 | SENSOR_ATTR_2(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO, | ||
2990 | show_auto_temp, store_auto_temp, 0, 5), | ||
2991 | SENSOR_ATTR_2(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO, | ||
2992 | show_auto_pwm, store_auto_pwm, 0, 6), | ||
2993 | SENSOR_ATTR_2(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO, | ||
2994 | show_auto_temp, store_auto_temp, 0, 6), | ||
2995 | |||
2996 | SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
2997 | show_auto_pwm, store_auto_pwm, 1, 0), | ||
2998 | SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
2999 | show_auto_temp, store_auto_temp, 1, 0), | ||
3000 | SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
3001 | show_auto_pwm, store_auto_pwm, 1, 1), | ||
3002 | SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
3003 | show_auto_temp, store_auto_temp, 1, 1), | ||
3004 | SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IWUSR | S_IRUGO, | ||
3005 | show_auto_pwm, store_auto_pwm, 1, 2), | ||
3006 | SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IWUSR | S_IRUGO, | ||
3007 | show_auto_temp, store_auto_temp, 1, 2), | ||
3008 | SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IWUSR | S_IRUGO, | ||
3009 | show_auto_pwm, store_auto_pwm, 1, 3), | ||
3010 | SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IWUSR | S_IRUGO, | ||
3011 | show_auto_temp, store_auto_temp, 1, 3), | ||
3012 | SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IWUSR | S_IRUGO, | ||
3013 | show_auto_pwm, store_auto_pwm, 1, 4), | ||
3014 | SENSOR_ATTR_2(pwm2_auto_point5_temp, S_IWUSR | S_IRUGO, | ||
3015 | show_auto_temp, store_auto_temp, 1, 4), | ||
3016 | SENSOR_ATTR_2(pwm2_auto_point6_pwm, S_IWUSR | S_IRUGO, | ||
3017 | show_auto_pwm, store_auto_pwm, 1, 5), | ||
3018 | SENSOR_ATTR_2(pwm2_auto_point6_temp, S_IWUSR | S_IRUGO, | ||
3019 | show_auto_temp, store_auto_temp, 1, 5), | ||
3020 | SENSOR_ATTR_2(pwm2_auto_point7_pwm, S_IWUSR | S_IRUGO, | ||
3021 | show_auto_pwm, store_auto_pwm, 1, 6), | ||
3022 | SENSOR_ATTR_2(pwm2_auto_point7_temp, S_IWUSR | S_IRUGO, | ||
3023 | show_auto_temp, store_auto_temp, 1, 6), | ||
3024 | |||
3025 | SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
3026 | show_auto_pwm, store_auto_pwm, 2, 0), | ||
3027 | SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
3028 | show_auto_temp, store_auto_temp, 2, 0), | ||
3029 | SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
3030 | show_auto_pwm, store_auto_pwm, 2, 1), | ||
3031 | SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
3032 | show_auto_temp, store_auto_temp, 2, 1), | ||
3033 | SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IWUSR | S_IRUGO, | ||
3034 | show_auto_pwm, store_auto_pwm, 2, 2), | ||
3035 | SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IWUSR | S_IRUGO, | ||
3036 | show_auto_temp, store_auto_temp, 2, 2), | ||
3037 | SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IWUSR | S_IRUGO, | ||
3038 | show_auto_pwm, store_auto_pwm, 2, 3), | ||
3039 | SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IWUSR | S_IRUGO, | ||
3040 | show_auto_temp, store_auto_temp, 2, 3), | ||
3041 | SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IWUSR | S_IRUGO, | ||
3042 | show_auto_pwm, store_auto_pwm, 2, 4), | ||
3043 | SENSOR_ATTR_2(pwm3_auto_point5_temp, S_IWUSR | S_IRUGO, | ||
3044 | show_auto_temp, store_auto_temp, 2, 4), | ||
3045 | SENSOR_ATTR_2(pwm3_auto_point6_pwm, S_IWUSR | S_IRUGO, | ||
3046 | show_auto_pwm, store_auto_pwm, 2, 5), | ||
3047 | SENSOR_ATTR_2(pwm3_auto_point6_temp, S_IWUSR | S_IRUGO, | ||
3048 | show_auto_temp, store_auto_temp, 2, 5), | ||
3049 | SENSOR_ATTR_2(pwm3_auto_point7_pwm, S_IWUSR | S_IRUGO, | ||
3050 | show_auto_pwm, store_auto_pwm, 2, 6), | ||
3051 | SENSOR_ATTR_2(pwm3_auto_point7_temp, S_IWUSR | S_IRUGO, | ||
3052 | show_auto_temp, store_auto_temp, 2, 6), | ||
3053 | |||
3054 | SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
3055 | show_auto_pwm, store_auto_pwm, 3, 0), | ||
3056 | SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
3057 | show_auto_temp, store_auto_temp, 3, 0), | ||
3058 | SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
3059 | show_auto_pwm, store_auto_pwm, 3, 1), | ||
3060 | SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
3061 | show_auto_temp, store_auto_temp, 3, 1), | ||
3062 | SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IWUSR | S_IRUGO, | ||
3063 | show_auto_pwm, store_auto_pwm, 3, 2), | ||
3064 | SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IWUSR | S_IRUGO, | ||
3065 | show_auto_temp, store_auto_temp, 3, 2), | ||
3066 | SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IWUSR | S_IRUGO, | ||
3067 | show_auto_pwm, store_auto_pwm, 3, 3), | ||
3068 | SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IWUSR | S_IRUGO, | ||
3069 | show_auto_temp, store_auto_temp, 3, 3), | ||
3070 | SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IWUSR | S_IRUGO, | ||
3071 | show_auto_pwm, store_auto_pwm, 3, 4), | ||
3072 | SENSOR_ATTR_2(pwm4_auto_point5_temp, S_IWUSR | S_IRUGO, | ||
3073 | show_auto_temp, store_auto_temp, 3, 4), | ||
3074 | SENSOR_ATTR_2(pwm4_auto_point6_pwm, S_IWUSR | S_IRUGO, | ||
3075 | show_auto_pwm, store_auto_pwm, 3, 5), | ||
3076 | SENSOR_ATTR_2(pwm4_auto_point6_temp, S_IWUSR | S_IRUGO, | ||
3077 | show_auto_temp, store_auto_temp, 3, 5), | ||
3078 | SENSOR_ATTR_2(pwm4_auto_point7_pwm, S_IWUSR | S_IRUGO, | ||
3079 | show_auto_pwm, store_auto_pwm, 3, 6), | ||
3080 | SENSOR_ATTR_2(pwm4_auto_point7_temp, S_IWUSR | S_IRUGO, | ||
3081 | show_auto_temp, store_auto_temp, 3, 6), | ||
3082 | |||
3083 | SENSOR_ATTR_2(pwm5_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
3084 | show_auto_pwm, store_auto_pwm, 4, 0), | ||
3085 | SENSOR_ATTR_2(pwm5_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
3086 | show_auto_temp, store_auto_temp, 4, 0), | ||
3087 | SENSOR_ATTR_2(pwm5_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
3088 | show_auto_pwm, store_auto_pwm, 4, 1), | ||
3089 | SENSOR_ATTR_2(pwm5_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
3090 | show_auto_temp, store_auto_temp, 4, 1), | ||
3091 | SENSOR_ATTR_2(pwm5_auto_point3_pwm, S_IWUSR | S_IRUGO, | ||
3092 | show_auto_pwm, store_auto_pwm, 4, 2), | ||
3093 | SENSOR_ATTR_2(pwm5_auto_point3_temp, S_IWUSR | S_IRUGO, | ||
3094 | show_auto_temp, store_auto_temp, 4, 2), | ||
3095 | SENSOR_ATTR_2(pwm5_auto_point4_pwm, S_IWUSR | S_IRUGO, | ||
3096 | show_auto_pwm, store_auto_pwm, 4, 3), | ||
3097 | SENSOR_ATTR_2(pwm5_auto_point4_temp, S_IWUSR | S_IRUGO, | ||
3098 | show_auto_temp, store_auto_temp, 4, 3), | ||
3099 | SENSOR_ATTR_2(pwm5_auto_point5_pwm, S_IWUSR | S_IRUGO, | ||
3100 | show_auto_pwm, store_auto_pwm, 4, 4), | ||
3101 | SENSOR_ATTR_2(pwm5_auto_point5_temp, S_IWUSR | S_IRUGO, | ||
3102 | show_auto_temp, store_auto_temp, 4, 4), | ||
3103 | SENSOR_ATTR_2(pwm5_auto_point6_pwm, S_IWUSR | S_IRUGO, | ||
3104 | show_auto_pwm, store_auto_pwm, 4, 5), | ||
3105 | SENSOR_ATTR_2(pwm5_auto_point6_temp, S_IWUSR | S_IRUGO, | ||
3106 | show_auto_temp, store_auto_temp, 4, 5), | ||
3107 | SENSOR_ATTR_2(pwm5_auto_point7_pwm, S_IWUSR | S_IRUGO, | ||
3108 | show_auto_pwm, store_auto_pwm, 4, 6), | ||
3109 | SENSOR_ATTR_2(pwm5_auto_point7_temp, S_IWUSR | S_IRUGO, | ||
3110 | show_auto_temp, store_auto_temp, 4, 6), | ||
3111 | }; | ||
3112 | |||
3113 | static ssize_t | ||
3114 | show_vid(struct device *dev, struct device_attribute *attr, char *buf) | ||
3115 | { | ||
3116 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
3117 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); | ||
3118 | } | ||
3119 | |||
3120 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | ||
3121 | |||
3122 | /* Case open detection */ | ||
3123 | |||
3124 | static ssize_t | ||
3125 | clear_caseopen(struct device *dev, struct device_attribute *attr, | ||
3126 | const char *buf, size_t count) | ||
3127 | { | ||
3128 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
3129 | struct nct6775_sio_data *sio_data = dev->platform_data; | ||
3130 | int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE; | ||
3131 | unsigned long val; | ||
3132 | u8 reg; | ||
3133 | int ret; | ||
3134 | |||
3135 | if (kstrtoul(buf, 10, &val) || val != 0) | ||
3136 | return -EINVAL; | ||
3137 | |||
3138 | mutex_lock(&data->update_lock); | ||
3139 | |||
3140 | /* | ||
3141 | * Use CR registers to clear caseopen status. | ||
3142 | * The CR registers are the same for all chips, and not all chips | ||
3143 | * support clearing the caseopen status through "regular" registers. | ||
3144 | */ | ||
3145 | ret = superio_enter(sio_data->sioreg); | ||
3146 | if (ret) { | ||
3147 | count = ret; | ||
3148 | goto error; | ||
3149 | } | ||
3150 | |||
3151 | superio_select(sio_data->sioreg, NCT6775_LD_ACPI); | ||
3152 | reg = superio_inb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]); | ||
3153 | reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr]; | ||
3154 | superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg); | ||
3155 | reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr]; | ||
3156 | superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg); | ||
3157 | superio_exit(sio_data->sioreg); | ||
3158 | |||
3159 | data->valid = false; /* Force cache refresh */ | ||
3160 | error: | ||
3161 | mutex_unlock(&data->update_lock); | ||
3162 | return count; | ||
3163 | } | ||
3164 | |||
3165 | static struct sensor_device_attribute sda_caseopen[] = { | ||
3166 | SENSOR_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm, | ||
3167 | clear_caseopen, INTRUSION_ALARM_BASE), | ||
3168 | SENSOR_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm, | ||
3169 | clear_caseopen, INTRUSION_ALARM_BASE + 1), | ||
3170 | }; | ||
3171 | |||
3172 | /* | ||
3173 | * Driver and device management | ||
3174 | */ | ||
3175 | |||
3176 | static void nct6775_device_remove_files(struct device *dev) | ||
3177 | { | ||
3178 | /* | ||
3179 | * some entries in the following arrays may not have been used in | ||
3180 | * device_create_file(), but device_remove_file() will ignore them | ||
3181 | */ | ||
3182 | int i; | ||
3183 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
3184 | |||
3185 | for (i = 0; i < data->pwm_num; i++) | ||
3186 | sysfs_remove_group(&dev->kobj, &nct6775_group_pwm[i]); | ||
3187 | |||
3188 | for (i = 0; i < ARRAY_SIZE(sda_pwm_max); i++) | ||
3189 | device_remove_file(dev, &sda_pwm_max[i].dev_attr); | ||
3190 | |||
3191 | for (i = 0; i < ARRAY_SIZE(sda_pwm_step); i++) | ||
3192 | device_remove_file(dev, &sda_pwm_step[i].dev_attr); | ||
3193 | |||
3194 | for (i = 0; i < ARRAY_SIZE(sda_weight_duty_base); i++) | ||
3195 | device_remove_file(dev, &sda_weight_duty_base[i].dev_attr); | ||
3196 | |||
3197 | for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) | ||
3198 | device_remove_file(dev, &sda_auto_pwm_arrays[i].dev_attr); | ||
3199 | |||
3200 | for (i = 0; i < data->in_num; i++) | ||
3201 | sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]); | ||
3202 | |||
3203 | for (i = 0; i < 5; i++) { | ||
3204 | device_remove_file(dev, &sda_fan_input[i].dev_attr); | ||
3205 | device_remove_file(dev, &sda_fan_alarm[i].dev_attr); | ||
3206 | device_remove_file(dev, &sda_fan_div[i].dev_attr); | ||
3207 | device_remove_file(dev, &sda_fan_min[i].dev_attr); | ||
3208 | device_remove_file(dev, &sda_fan_pulses[i].dev_attr); | ||
3209 | } | ||
3210 | for (i = 0; i < NUM_TEMP; i++) { | ||
3211 | if (!(data->have_temp & (1 << i))) | ||
3212 | continue; | ||
3213 | device_remove_file(dev, &sda_temp_input[i].dev_attr); | ||
3214 | device_remove_file(dev, &sda_temp_label[i].dev_attr); | ||
3215 | device_remove_file(dev, &sda_temp_max[i].dev_attr); | ||
3216 | device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr); | ||
3217 | device_remove_file(dev, &sda_temp_crit[i].dev_attr); | ||
3218 | if (!(data->have_temp_fixed & (1 << i))) | ||
3219 | continue; | ||
3220 | device_remove_file(dev, &sda_temp_type[i].dev_attr); | ||
3221 | device_remove_file(dev, &sda_temp_offset[i].dev_attr); | ||
3222 | if (i >= NUM_TEMP_ALARM) | ||
3223 | continue; | ||
3224 | device_remove_file(dev, &sda_temp_alarm[i].dev_attr); | ||
3225 | } | ||
3226 | |||
3227 | device_remove_file(dev, &sda_caseopen[0].dev_attr); | ||
3228 | device_remove_file(dev, &sda_caseopen[1].dev_attr); | ||
3229 | |||
3230 | device_remove_file(dev, &dev_attr_name); | ||
3231 | device_remove_file(dev, &dev_attr_cpu0_vid); | ||
3232 | } | ||
3233 | |||
3234 | /* Get the monitoring functions started */ | ||
3235 | static inline void nct6775_init_device(struct nct6775_data *data) | ||
3236 | { | ||
3237 | int i; | ||
3238 | u8 tmp, diode; | ||
3239 | |||
3240 | /* Start monitoring if needed */ | ||
3241 | if (data->REG_CONFIG) { | ||
3242 | tmp = nct6775_read_value(data, data->REG_CONFIG); | ||
3243 | if (!(tmp & 0x01)) | ||
3244 | nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01); | ||
3245 | } | ||
3246 | |||
3247 | /* Enable temperature sensors if needed */ | ||
3248 | for (i = 0; i < NUM_TEMP; i++) { | ||
3249 | if (!(data->have_temp & (1 << i))) | ||
3250 | continue; | ||
3251 | if (!data->reg_temp_config[i]) | ||
3252 | continue; | ||
3253 | tmp = nct6775_read_value(data, data->reg_temp_config[i]); | ||
3254 | if (tmp & 0x01) | ||
3255 | nct6775_write_value(data, data->reg_temp_config[i], | ||
3256 | tmp & 0xfe); | ||
3257 | } | ||
3258 | |||
3259 | /* Enable VBAT monitoring if needed */ | ||
3260 | tmp = nct6775_read_value(data, data->REG_VBAT); | ||
3261 | if (!(tmp & 0x01)) | ||
3262 | nct6775_write_value(data, data->REG_VBAT, tmp | 0x01); | ||
3263 | |||
3264 | diode = nct6775_read_value(data, data->REG_DIODE); | ||
3265 | |||
3266 | for (i = 0; i < data->temp_fixed_num; i++) { | ||
3267 | if (!(data->have_temp_fixed & (1 << i))) | ||
3268 | continue; | ||
3269 | if ((tmp & (0x02 << i))) /* diode */ | ||
3270 | data->temp_type[i] = 3 - ((diode >> i) & 0x02); | ||
3271 | else /* thermistor */ | ||
3272 | data->temp_type[i] = 4; | ||
3273 | } | ||
3274 | } | ||
3275 | |||
3276 | static int | ||
3277 | nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data, | ||
3278 | struct nct6775_data *data) | ||
3279 | { | ||
3280 | int regval; | ||
3281 | bool fan3pin, fan3min, fan4pin, fan4min, fan5pin; | ||
3282 | bool pwm3pin, pwm4pin, pwm5pin; | ||
3283 | int ret; | ||
3284 | |||
3285 | ret = superio_enter(sio_data->sioreg); | ||
3286 | if (ret) | ||
3287 | return ret; | ||
3288 | |||
3289 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ | ||
3290 | if (data->kind == nct6775) { | ||
3291 | regval = superio_inb(sio_data->sioreg, 0x2c); | ||
3292 | |||
3293 | fan3pin = regval & (1 << 6); | ||
3294 | fan3min = fan3pin; | ||
3295 | pwm3pin = regval & (1 << 7); | ||
3296 | |||
3297 | /* On NCT6775, fan4 shares pins with the fdc interface */ | ||
3298 | fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80); | ||
3299 | fan4min = 0; | ||
3300 | fan5pin = 0; | ||
3301 | pwm4pin = 0; | ||
3302 | pwm5pin = 0; | ||
3303 | } else if (data->kind == nct6776) { | ||
3304 | bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80; | ||
3305 | |||
3306 | superio_select(sio_data->sioreg, NCT6775_LD_HWM); | ||
3307 | regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE); | ||
3308 | |||
3309 | if (regval & 0x80) | ||
3310 | fan3pin = gpok; | ||
3311 | else | ||
3312 | fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40); | ||
3313 | |||
3314 | if (regval & 0x40) | ||
3315 | fan4pin = gpok; | ||
3316 | else | ||
3317 | fan4pin = superio_inb(sio_data->sioreg, 0x1C) & 0x01; | ||
3318 | |||
3319 | if (regval & 0x20) | ||
3320 | fan5pin = gpok; | ||
3321 | else | ||
3322 | fan5pin = superio_inb(sio_data->sioreg, 0x1C) & 0x02; | ||
3323 | |||
3324 | fan4min = fan4pin; | ||
3325 | fan3min = fan3pin; | ||
3326 | pwm3pin = fan3pin; | ||
3327 | pwm4pin = 0; | ||
3328 | pwm5pin = 0; | ||
3329 | } else { /* NCT6779D */ | ||
3330 | regval = superio_inb(sio_data->sioreg, 0x1c); | ||
3331 | |||
3332 | fan3pin = !(regval & (1 << 5)); | ||
3333 | fan4pin = !(regval & (1 << 6)); | ||
3334 | fan5pin = !(regval & (1 << 7)); | ||
3335 | |||
3336 | pwm3pin = !(regval & (1 << 0)); | ||
3337 | pwm4pin = !(regval & (1 << 1)); | ||
3338 | pwm5pin = !(regval & (1 << 2)); | ||
3339 | |||
3340 | fan3min = fan3pin; | ||
3341 | fan4min = fan4pin; | ||
3342 | } | ||
3343 | |||
3344 | superio_exit(sio_data->sioreg); | ||
3345 | |||
3346 | data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */ | ||
3347 | data->has_fan |= fan3pin << 2; | ||
3348 | data->has_fan_min |= fan3min << 2; | ||
3349 | |||
3350 | data->has_fan |= (fan4pin << 3) | (fan5pin << 4); | ||
3351 | data->has_fan_min |= (fan4min << 3) | (fan5pin << 4); | ||
3352 | |||
3353 | data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) | (pwm5pin << 4); | ||
3354 | |||
3355 | return 0; | ||
3356 | } | ||
3357 | |||
3358 | static void add_temp_sensors(struct nct6775_data *data, const u16 *regp, | ||
3359 | int *available, int *mask) | ||
3360 | { | ||
3361 | int i; | ||
3362 | u8 src; | ||
3363 | |||
3364 | for (i = 0; i < data->pwm_num && *available; i++) { | ||
3365 | int index; | ||
3366 | |||
3367 | if (!regp[i]) | ||
3368 | continue; | ||
3369 | src = nct6775_read_value(data, regp[i]); | ||
3370 | src &= 0x1f; | ||
3371 | if (!src || (*mask & (1 << src))) | ||
3372 | continue; | ||
3373 | if (src >= data->temp_label_num || | ||
3374 | !strlen(data->temp_label[src])) | ||
3375 | continue; | ||
3376 | |||
3377 | index = __ffs(*available); | ||
3378 | nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src); | ||
3379 | *available &= ~(1 << index); | ||
3380 | *mask |= 1 << src; | ||
3381 | } | ||
3382 | } | ||
3383 | |||
3384 | static int nct6775_probe(struct platform_device *pdev) | ||
3385 | { | ||
3386 | struct device *dev = &pdev->dev; | ||
3387 | struct nct6775_sio_data *sio_data = dev->platform_data; | ||
3388 | struct nct6775_data *data; | ||
3389 | struct resource *res; | ||
3390 | int i, s, err = 0; | ||
3391 | int src, mask, available; | ||
3392 | const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config; | ||
3393 | const u16 *reg_temp_alternate, *reg_temp_crit; | ||
3394 | int num_reg_temp; | ||
3395 | bool have_vid = false; | ||
3396 | u8 cr2a; | ||
3397 | |||
3398 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
3399 | if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH, | ||
3400 | DRVNAME)) | ||
3401 | return -EBUSY; | ||
3402 | |||
3403 | data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data), | ||
3404 | GFP_KERNEL); | ||
3405 | if (!data) | ||
3406 | return -ENOMEM; | ||
3407 | |||
3408 | data->kind = sio_data->kind; | ||
3409 | data->addr = res->start; | ||
3410 | mutex_init(&data->update_lock); | ||
3411 | data->name = nct6775_device_names[data->kind]; | ||
3412 | data->bank = 0xff; /* Force initial bank selection */ | ||
3413 | platform_set_drvdata(pdev, data); | ||
3414 | |||
3415 | switch (data->kind) { | ||
3416 | case nct6775: | ||
3417 | data->in_num = 9; | ||
3418 | data->pwm_num = 3; | ||
3419 | data->auto_pwm_num = 6; | ||
3420 | data->has_fan_div = true; | ||
3421 | data->temp_fixed_num = 3; | ||
3422 | |||
3423 | data->ALARM_BITS = NCT6775_ALARM_BITS; | ||
3424 | |||
3425 | data->fan_from_reg = fan_from_reg16; | ||
3426 | data->fan_from_reg_min = fan_from_reg8; | ||
3427 | data->target_temp_mask = 0x7f; | ||
3428 | data->tolerance_mask = 0x0f; | ||
3429 | data->speed_tolerance_limit = 15; | ||
3430 | |||
3431 | data->temp_label = nct6775_temp_label; | ||
3432 | data->temp_label_num = ARRAY_SIZE(nct6775_temp_label); | ||
3433 | |||
3434 | data->REG_CONFIG = NCT6775_REG_CONFIG; | ||
3435 | data->REG_VBAT = NCT6775_REG_VBAT; | ||
3436 | data->REG_DIODE = NCT6775_REG_DIODE; | ||
3437 | data->REG_VIN = NCT6775_REG_IN; | ||
3438 | data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; | ||
3439 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; | ||
3440 | data->REG_TARGET = NCT6775_REG_TARGET; | ||
3441 | data->REG_FAN = NCT6775_REG_FAN; | ||
3442 | data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; | ||
3443 | data->REG_FAN_MIN = NCT6775_REG_FAN_MIN; | ||
3444 | data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES; | ||
3445 | data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; | ||
3446 | data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; | ||
3447 | data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; | ||
3448 | data->REG_PWM[0] = NCT6775_REG_PWM; | ||
3449 | data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; | ||
3450 | data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; | ||
3451 | data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT; | ||
3452 | data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT; | ||
3453 | data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP; | ||
3454 | data->REG_PWM_READ = NCT6775_REG_PWM_READ; | ||
3455 | data->REG_PWM_MODE = NCT6775_REG_PWM_MODE; | ||
3456 | data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK; | ||
3457 | data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP; | ||
3458 | data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM; | ||
3459 | data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP; | ||
3460 | data->REG_CRITICAL_TEMP_TOLERANCE | ||
3461 | = NCT6775_REG_CRITICAL_TEMP_TOLERANCE; | ||
3462 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; | ||
3463 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; | ||
3464 | data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; | ||
3465 | data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL; | ||
3466 | data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP; | ||
3467 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; | ||
3468 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; | ||
3469 | data->REG_ALARM = NCT6775_REG_ALARM; | ||
3470 | |||
3471 | reg_temp = NCT6775_REG_TEMP; | ||
3472 | num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP); | ||
3473 | reg_temp_over = NCT6775_REG_TEMP_OVER; | ||
3474 | reg_temp_hyst = NCT6775_REG_TEMP_HYST; | ||
3475 | reg_temp_config = NCT6775_REG_TEMP_CONFIG; | ||
3476 | reg_temp_alternate = NCT6775_REG_TEMP_ALTERNATE; | ||
3477 | reg_temp_crit = NCT6775_REG_TEMP_CRIT; | ||
3478 | |||
3479 | break; | ||
3480 | case nct6776: | ||
3481 | data->in_num = 9; | ||
3482 | data->pwm_num = 3; | ||
3483 | data->auto_pwm_num = 4; | ||
3484 | data->has_fan_div = false; | ||
3485 | data->temp_fixed_num = 3; | ||
3486 | |||
3487 | data->ALARM_BITS = NCT6776_ALARM_BITS; | ||
3488 | |||
3489 | data->fan_from_reg = fan_from_reg13; | ||
3490 | data->fan_from_reg_min = fan_from_reg13; | ||
3491 | data->target_temp_mask = 0xff; | ||
3492 | data->tolerance_mask = 0x07; | ||
3493 | data->speed_tolerance_limit = 63; | ||
3494 | |||
3495 | data->temp_label = nct6776_temp_label; | ||
3496 | data->temp_label_num = ARRAY_SIZE(nct6776_temp_label); | ||
3497 | |||
3498 | data->REG_CONFIG = NCT6775_REG_CONFIG; | ||
3499 | data->REG_VBAT = NCT6775_REG_VBAT; | ||
3500 | data->REG_DIODE = NCT6775_REG_DIODE; | ||
3501 | data->REG_VIN = NCT6775_REG_IN; | ||
3502 | data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; | ||
3503 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; | ||
3504 | data->REG_TARGET = NCT6775_REG_TARGET; | ||
3505 | data->REG_FAN = NCT6775_REG_FAN; | ||
3506 | data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; | ||
3507 | data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; | ||
3508 | data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES; | ||
3509 | data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; | ||
3510 | data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; | ||
3511 | data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; | ||
3512 | data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H; | ||
3513 | data->REG_PWM[0] = NCT6775_REG_PWM; | ||
3514 | data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; | ||
3515 | data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; | ||
3516 | data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP; | ||
3517 | data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE; | ||
3518 | data->REG_PWM_READ = NCT6775_REG_PWM_READ; | ||
3519 | data->REG_PWM_MODE = NCT6776_REG_PWM_MODE; | ||
3520 | data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK; | ||
3521 | data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP; | ||
3522 | data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM; | ||
3523 | data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP; | ||
3524 | data->REG_CRITICAL_TEMP_TOLERANCE | ||
3525 | = NCT6775_REG_CRITICAL_TEMP_TOLERANCE; | ||
3526 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; | ||
3527 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; | ||
3528 | data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; | ||
3529 | data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL; | ||
3530 | data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP; | ||
3531 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; | ||
3532 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; | ||
3533 | data->REG_ALARM = NCT6775_REG_ALARM; | ||
3534 | |||
3535 | reg_temp = NCT6775_REG_TEMP; | ||
3536 | num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP); | ||
3537 | reg_temp_over = NCT6775_REG_TEMP_OVER; | ||
3538 | reg_temp_hyst = NCT6775_REG_TEMP_HYST; | ||
3539 | reg_temp_config = NCT6776_REG_TEMP_CONFIG; | ||
3540 | reg_temp_alternate = NCT6776_REG_TEMP_ALTERNATE; | ||
3541 | reg_temp_crit = NCT6776_REG_TEMP_CRIT; | ||
3542 | |||
3543 | break; | ||
3544 | case nct6779: | ||
3545 | data->in_num = 15; | ||
3546 | data->pwm_num = 5; | ||
3547 | data->auto_pwm_num = 4; | ||
3548 | data->has_fan_div = false; | ||
3549 | data->temp_fixed_num = 6; | ||
3550 | |||
3551 | data->ALARM_BITS = NCT6779_ALARM_BITS; | ||
3552 | |||
3553 | data->fan_from_reg = fan_from_reg13; | ||
3554 | data->fan_from_reg_min = fan_from_reg13; | ||
3555 | data->target_temp_mask = 0xff; | ||
3556 | data->tolerance_mask = 0x07; | ||
3557 | data->speed_tolerance_limit = 63; | ||
3558 | |||
3559 | data->temp_label = nct6779_temp_label; | ||
3560 | data->temp_label_num = ARRAY_SIZE(nct6779_temp_label); | ||
3561 | |||
3562 | data->REG_CONFIG = NCT6775_REG_CONFIG; | ||
3563 | data->REG_VBAT = NCT6775_REG_VBAT; | ||
3564 | data->REG_DIODE = NCT6775_REG_DIODE; | ||
3565 | data->REG_VIN = NCT6779_REG_IN; | ||
3566 | data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; | ||
3567 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; | ||
3568 | data->REG_TARGET = NCT6775_REG_TARGET; | ||
3569 | data->REG_FAN = NCT6779_REG_FAN; | ||
3570 | data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; | ||
3571 | data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; | ||
3572 | data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES; | ||
3573 | data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; | ||
3574 | data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; | ||
3575 | data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; | ||
3576 | data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H; | ||
3577 | data->REG_PWM[0] = NCT6775_REG_PWM; | ||
3578 | data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; | ||
3579 | data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; | ||
3580 | data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP; | ||
3581 | data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE; | ||
3582 | data->REG_PWM_READ = NCT6775_REG_PWM_READ; | ||
3583 | data->REG_PWM_MODE = NCT6776_REG_PWM_MODE; | ||
3584 | data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK; | ||
3585 | data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP; | ||
3586 | data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM; | ||
3587 | data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP; | ||
3588 | data->REG_CRITICAL_TEMP_TOLERANCE | ||
3589 | = NCT6775_REG_CRITICAL_TEMP_TOLERANCE; | ||
3590 | data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; | ||
3591 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; | ||
3592 | data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; | ||
3593 | data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL; | ||
3594 | data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP; | ||
3595 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; | ||
3596 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; | ||
3597 | data->REG_ALARM = NCT6779_REG_ALARM; | ||
3598 | |||
3599 | reg_temp = NCT6779_REG_TEMP; | ||
3600 | num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); | ||
3601 | reg_temp_over = NCT6779_REG_TEMP_OVER; | ||
3602 | reg_temp_hyst = NCT6779_REG_TEMP_HYST; | ||
3603 | reg_temp_config = NCT6779_REG_TEMP_CONFIG; | ||
3604 | reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE; | ||
3605 | reg_temp_crit = NCT6779_REG_TEMP_CRIT; | ||
3606 | |||
3607 | break; | ||
3608 | default: | ||
3609 | return -ENODEV; | ||
3610 | } | ||
3611 | data->have_in = (1 << data->in_num) - 1; | ||
3612 | data->have_temp = 0; | ||
3613 | |||
3614 | /* | ||
3615 | * On some boards, not all available temperature sources are monitored, | ||
3616 | * even though some of the monitoring registers are unused. | ||
3617 | * Get list of unused monitoring registers, then detect if any fan | ||
3618 | * controls are configured to use unmonitored temperature sources. | ||
3619 | * If so, assign the unmonitored temperature sources to available | ||
3620 | * monitoring registers. | ||
3621 | */ | ||
3622 | mask = 0; | ||
3623 | available = 0; | ||
3624 | for (i = 0; i < num_reg_temp; i++) { | ||
3625 | if (reg_temp[i] == 0) | ||
3626 | continue; | ||
3627 | |||
3628 | src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f; | ||
3629 | if (!src || (mask & (1 << src))) | ||
3630 | available |= 1 << i; | ||
3631 | |||
3632 | mask |= 1 << src; | ||
3633 | } | ||
3634 | |||
3635 | /* | ||
3636 | * Now find unmonitored temperature registers and enable monitoring | ||
3637 | * if additional monitoring registers are available. | ||
3638 | */ | ||
3639 | add_temp_sensors(data, data->REG_TEMP_SEL, &available, &mask); | ||
3640 | add_temp_sensors(data, data->REG_WEIGHT_TEMP_SEL, &available, &mask); | ||
3641 | |||
3642 | mask = 0; | ||
3643 | s = NUM_TEMP_FIXED; /* First dynamic temperature attribute */ | ||
3644 | for (i = 0; i < num_reg_temp; i++) { | ||
3645 | if (reg_temp[i] == 0) | ||
3646 | continue; | ||
3647 | |||
3648 | src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f; | ||
3649 | if (!src || (mask & (1 << src))) | ||
3650 | continue; | ||
3651 | |||
3652 | if (src >= data->temp_label_num || | ||
3653 | !strlen(data->temp_label[src])) { | ||
3654 | dev_info(dev, | ||
3655 | "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n", | ||
3656 | src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]); | ||
3657 | continue; | ||
3658 | } | ||
3659 | |||
3660 | mask |= 1 << src; | ||
3661 | |||
3662 | /* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */ | ||
3663 | if (src <= data->temp_fixed_num) { | ||
3664 | data->have_temp |= 1 << (src - 1); | ||
3665 | data->have_temp_fixed |= 1 << (src - 1); | ||
3666 | data->reg_temp[0][src - 1] = reg_temp[i]; | ||
3667 | data->reg_temp[1][src - 1] = reg_temp_over[i]; | ||
3668 | data->reg_temp[2][src - 1] = reg_temp_hyst[i]; | ||
3669 | data->reg_temp_config[src - 1] = reg_temp_config[i]; | ||
3670 | data->temp_src[src - 1] = src; | ||
3671 | continue; | ||
3672 | } | ||
3673 | |||
3674 | if (s >= NUM_TEMP) | ||
3675 | continue; | ||
3676 | |||
3677 | /* Use dynamic index for other sources */ | ||
3678 | data->have_temp |= 1 << s; | ||
3679 | data->reg_temp[0][s] = reg_temp[i]; | ||
3680 | data->reg_temp[1][s] = reg_temp_over[i]; | ||
3681 | data->reg_temp[2][s] = reg_temp_hyst[i]; | ||
3682 | data->reg_temp_config[s] = reg_temp_config[i]; | ||
3683 | if (reg_temp_crit[src - 1]) | ||
3684 | data->reg_temp[3][s] = reg_temp_crit[src - 1]; | ||
3685 | |||
3686 | data->temp_src[s] = src; | ||
3687 | s++; | ||
3688 | } | ||
3689 | |||
3690 | #ifdef USE_ALTERNATE | ||
3691 | /* | ||
3692 | * Go through the list of alternate temp registers and enable | ||
3693 | * if possible. | ||
3694 | * The temperature is already monitored if the respective bit in <mask> | ||
3695 | * is set. | ||
3696 | */ | ||
3697 | for (i = 0; i < data->temp_label_num - 1; i++) { | ||
3698 | if (!reg_temp_alternate[i]) | ||
3699 | continue; | ||
3700 | if (mask & (1 << (i + 1))) | ||
3701 | continue; | ||
3702 | if (i < data->temp_fixed_num) { | ||
3703 | if (data->have_temp & (1 << i)) | ||
3704 | continue; | ||
3705 | data->have_temp |= 1 << i; | ||
3706 | data->have_temp_fixed |= 1 << i; | ||
3707 | data->reg_temp[0][i] = reg_temp_alternate[i]; | ||
3708 | data->reg_temp[1][i] = reg_temp_over[i]; | ||
3709 | data->reg_temp[2][i] = reg_temp_hyst[i]; | ||
3710 | data->temp_src[i] = i + 1; | ||
3711 | continue; | ||
3712 | } | ||
3713 | |||
3714 | if (s >= NUM_TEMP) /* Abort if no more space */ | ||
3715 | break; | ||
3716 | |||
3717 | data->have_temp |= 1 << s; | ||
3718 | data->reg_temp[0][s] = reg_temp_alternate[i]; | ||
3719 | data->temp_src[s] = i + 1; | ||
3720 | s++; | ||
3721 | } | ||
3722 | #endif /* USE_ALTERNATE */ | ||
3723 | |||
3724 | /* Initialize the chip */ | ||
3725 | nct6775_init_device(data); | ||
3726 | |||
3727 | err = superio_enter(sio_data->sioreg); | ||
3728 | if (err) | ||
3729 | return err; | ||
3730 | |||
3731 | cr2a = superio_inb(sio_data->sioreg, 0x2a); | ||
3732 | switch (data->kind) { | ||
3733 | case nct6775: | ||
3734 | have_vid = (cr2a & 0x40); | ||
3735 | break; | ||
3736 | case nct6776: | ||
3737 | have_vid = (cr2a & 0x60) == 0x40; | ||
3738 | break; | ||
3739 | case nct6779: | ||
3740 | break; | ||
3741 | } | ||
3742 | |||
3743 | /* | ||
3744 | * Read VID value | ||
3745 | * We can get the VID input values directly at logical device D 0xe3. | ||
3746 | */ | ||
3747 | if (have_vid) { | ||
3748 | superio_select(sio_data->sioreg, NCT6775_LD_VID); | ||
3749 | data->vid = superio_inb(sio_data->sioreg, 0xe3); | ||
3750 | data->vrm = vid_which_vrm(); | ||
3751 | } | ||
3752 | |||
3753 | if (fan_debounce) { | ||
3754 | u8 tmp; | ||
3755 | |||
3756 | superio_select(sio_data->sioreg, NCT6775_LD_HWM); | ||
3757 | tmp = superio_inb(sio_data->sioreg, | ||
3758 | NCT6775_REG_CR_FAN_DEBOUNCE); | ||
3759 | switch (data->kind) { | ||
3760 | case nct6775: | ||
3761 | tmp |= 0x1e; | ||
3762 | break; | ||
3763 | case nct6776: | ||
3764 | case nct6779: | ||
3765 | tmp |= 0x3e; | ||
3766 | break; | ||
3767 | } | ||
3768 | superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE, | ||
3769 | tmp); | ||
3770 | dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n", | ||
3771 | data->name); | ||
3772 | } | ||
3773 | |||
3774 | superio_exit(sio_data->sioreg); | ||
3775 | |||
3776 | if (have_vid) { | ||
3777 | err = device_create_file(dev, &dev_attr_cpu0_vid); | ||
3778 | if (err) | ||
3779 | return err; | ||
3780 | } | ||
3781 | |||
3782 | err = nct6775_check_fan_inputs(sio_data, data); | ||
3783 | if (err) | ||
3784 | goto exit_remove; | ||
3785 | |||
3786 | /* Read fan clock dividers immediately */ | ||
3787 | nct6775_init_fan_common(dev, data); | ||
3788 | |||
3789 | /* Register sysfs hooks */ | ||
3790 | for (i = 0; i < data->pwm_num; i++) { | ||
3791 | if (!(data->has_pwm & (1 << i))) | ||
3792 | continue; | ||
3793 | |||
3794 | err = sysfs_create_group(&dev->kobj, &nct6775_group_pwm[i]); | ||
3795 | if (err) | ||
3796 | goto exit_remove; | ||
3797 | |||
3798 | if (data->REG_PWM[3]) { | ||
3799 | err = device_create_file(dev, | ||
3800 | &sda_pwm_max[i].dev_attr); | ||
3801 | if (err) | ||
3802 | goto exit_remove; | ||
3803 | } | ||
3804 | if (data->REG_PWM[4]) { | ||
3805 | err = device_create_file(dev, | ||
3806 | &sda_pwm_step[i].dev_attr); | ||
3807 | if (err) | ||
3808 | goto exit_remove; | ||
3809 | } | ||
3810 | if (data->REG_PWM[6]) { | ||
3811 | err = device_create_file(dev, | ||
3812 | &sda_weight_duty_base[i].dev_attr); | ||
3813 | if (err) | ||
3814 | goto exit_remove; | ||
3815 | } | ||
3816 | } | ||
3817 | for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) { | ||
3818 | struct sensor_device_attribute_2 *attr = | ||
3819 | &sda_auto_pwm_arrays[i]; | ||
3820 | |||
3821 | if (!(data->has_pwm & (1 << attr->nr))) | ||
3822 | continue; | ||
3823 | if (attr->index > data->auto_pwm_num) | ||
3824 | continue; | ||
3825 | err = device_create_file(dev, &attr->dev_attr); | ||
3826 | if (err) | ||
3827 | goto exit_remove; | ||
3828 | } | ||
3829 | |||
3830 | for (i = 0; i < data->in_num; i++) { | ||
3831 | if (!(data->have_in & (1 << i))) | ||
3832 | continue; | ||
3833 | err = sysfs_create_group(&dev->kobj, &nct6775_group_in[i]); | ||
3834 | if (err) | ||
3835 | goto exit_remove; | ||
3836 | } | ||
3837 | |||
3838 | for (i = 0; i < 5; i++) { | ||
3839 | if (data->has_fan & (1 << i)) { | ||
3840 | err = device_create_file(dev, | ||
3841 | &sda_fan_input[i].dev_attr); | ||
3842 | if (err) | ||
3843 | goto exit_remove; | ||
3844 | err = device_create_file(dev, | ||
3845 | &sda_fan_alarm[i].dev_attr); | ||
3846 | if (err) | ||
3847 | goto exit_remove; | ||
3848 | if (data->kind != nct6776 && | ||
3849 | data->kind != nct6779) { | ||
3850 | err = device_create_file(dev, | ||
3851 | &sda_fan_div[i].dev_attr); | ||
3852 | if (err) | ||
3853 | goto exit_remove; | ||
3854 | } | ||
3855 | if (data->has_fan_min & (1 << i)) { | ||
3856 | err = device_create_file(dev, | ||
3857 | &sda_fan_min[i].dev_attr); | ||
3858 | if (err) | ||
3859 | goto exit_remove; | ||
3860 | } | ||
3861 | err = device_create_file(dev, | ||
3862 | &sda_fan_pulses[i].dev_attr); | ||
3863 | if (err) | ||
3864 | goto exit_remove; | ||
3865 | } | ||
3866 | } | ||
3867 | |||
3868 | for (i = 0; i < NUM_TEMP; i++) { | ||
3869 | if (!(data->have_temp & (1 << i))) | ||
3870 | continue; | ||
3871 | err = device_create_file(dev, &sda_temp_input[i].dev_attr); | ||
3872 | if (err) | ||
3873 | goto exit_remove; | ||
3874 | if (data->temp_label) { | ||
3875 | err = device_create_file(dev, | ||
3876 | &sda_temp_label[i].dev_attr); | ||
3877 | if (err) | ||
3878 | goto exit_remove; | ||
3879 | } | ||
3880 | if (data->reg_temp[1][i]) { | ||
3881 | err = device_create_file(dev, | ||
3882 | &sda_temp_max[i].dev_attr); | ||
3883 | if (err) | ||
3884 | goto exit_remove; | ||
3885 | } | ||
3886 | if (data->reg_temp[2][i]) { | ||
3887 | err = device_create_file(dev, | ||
3888 | &sda_temp_max_hyst[i].dev_attr); | ||
3889 | if (err) | ||
3890 | goto exit_remove; | ||
3891 | } | ||
3892 | if (data->reg_temp[3][i]) { | ||
3893 | err = device_create_file(dev, | ||
3894 | &sda_temp_crit[i].dev_attr); | ||
3895 | if (err) | ||
3896 | goto exit_remove; | ||
3897 | } | ||
3898 | if (!(data->have_temp_fixed & (1 << i))) | ||
3899 | continue; | ||
3900 | err = device_create_file(dev, &sda_temp_type[i].dev_attr); | ||
3901 | if (err) | ||
3902 | goto exit_remove; | ||
3903 | err = device_create_file(dev, &sda_temp_offset[i].dev_attr); | ||
3904 | if (err) | ||
3905 | goto exit_remove; | ||
3906 | if (i >= NUM_TEMP_ALARM || | ||
3907 | data->ALARM_BITS[TEMP_ALARM_BASE + i] < 0) | ||
3908 | continue; | ||
3909 | err = device_create_file(dev, &sda_temp_alarm[i].dev_attr); | ||
3910 | if (err) | ||
3911 | goto exit_remove; | ||
3912 | } | ||
3913 | |||
3914 | for (i = 0; i < ARRAY_SIZE(sda_caseopen); i++) { | ||
3915 | if (data->ALARM_BITS[INTRUSION_ALARM_BASE + i] < 0) | ||
3916 | continue; | ||
3917 | err = device_create_file(dev, &sda_caseopen[i].dev_attr); | ||
3918 | if (err) | ||
3919 | goto exit_remove; | ||
3920 | } | ||
3921 | |||
3922 | err = device_create_file(dev, &dev_attr_name); | ||
3923 | if (err) | ||
3924 | goto exit_remove; | ||
3925 | |||
3926 | data->hwmon_dev = hwmon_device_register(dev); | ||
3927 | if (IS_ERR(data->hwmon_dev)) { | ||
3928 | err = PTR_ERR(data->hwmon_dev); | ||
3929 | goto exit_remove; | ||
3930 | } | ||
3931 | |||
3932 | return 0; | ||
3933 | |||
3934 | exit_remove: | ||
3935 | nct6775_device_remove_files(dev); | ||
3936 | return err; | ||
3937 | } | ||
3938 | |||
3939 | static int nct6775_remove(struct platform_device *pdev) | ||
3940 | { | ||
3941 | struct nct6775_data *data = platform_get_drvdata(pdev); | ||
3942 | |||
3943 | hwmon_device_unregister(data->hwmon_dev); | ||
3944 | nct6775_device_remove_files(&pdev->dev); | ||
3945 | |||
3946 | return 0; | ||
3947 | } | ||
3948 | |||
3949 | #ifdef CONFIG_PM | ||
3950 | static int nct6775_suspend(struct device *dev) | ||
3951 | { | ||
3952 | struct nct6775_data *data = nct6775_update_device(dev); | ||
3953 | struct nct6775_sio_data *sio_data = dev->platform_data; | ||
3954 | |||
3955 | mutex_lock(&data->update_lock); | ||
3956 | data->vbat = nct6775_read_value(data, data->REG_VBAT); | ||
3957 | if (sio_data->kind == nct6775) { | ||
3958 | data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1); | ||
3959 | data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2); | ||
3960 | } | ||
3961 | mutex_unlock(&data->update_lock); | ||
3962 | |||
3963 | return 0; | ||
3964 | } | ||
3965 | |||
3966 | static int nct6775_resume(struct device *dev) | ||
3967 | { | ||
3968 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
3969 | struct nct6775_sio_data *sio_data = dev->platform_data; | ||
3970 | int i, j; | ||
3971 | |||
3972 | mutex_lock(&data->update_lock); | ||
3973 | data->bank = 0xff; /* Force initial bank selection */ | ||
3974 | |||
3975 | /* Restore limits */ | ||
3976 | for (i = 0; i < data->in_num; i++) { | ||
3977 | if (!(data->have_in & (1 << i))) | ||
3978 | continue; | ||
3979 | |||
3980 | nct6775_write_value(data, data->REG_IN_MINMAX[0][i], | ||
3981 | data->in[i][1]); | ||
3982 | nct6775_write_value(data, data->REG_IN_MINMAX[1][i], | ||
3983 | data->in[i][2]); | ||
3984 | } | ||
3985 | |||
3986 | for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { | ||
3987 | if (!(data->has_fan_min & (1 << i))) | ||
3988 | continue; | ||
3989 | |||
3990 | nct6775_write_value(data, data->REG_FAN_MIN[i], | ||
3991 | data->fan_min[i]); | ||
3992 | } | ||
3993 | |||
3994 | for (i = 0; i < NUM_TEMP; i++) { | ||
3995 | if (!(data->have_temp & (1 << i))) | ||
3996 | continue; | ||
3997 | |||
3998 | for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++) | ||
3999 | if (data->reg_temp[j][i]) | ||
4000 | nct6775_write_temp(data, data->reg_temp[j][i], | ||
4001 | data->temp[j][i]); | ||
4002 | } | ||
4003 | |||
4004 | /* Restore other settings */ | ||
4005 | nct6775_write_value(data, data->REG_VBAT, data->vbat); | ||
4006 | if (sio_data->kind == nct6775) { | ||
4007 | nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1); | ||
4008 | nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2); | ||
4009 | } | ||
4010 | |||
4011 | /* Force re-reading all values */ | ||
4012 | data->valid = false; | ||
4013 | mutex_unlock(&data->update_lock); | ||
4014 | |||
4015 | return 0; | ||
4016 | } | ||
4017 | |||
4018 | static const struct dev_pm_ops nct6775_dev_pm_ops = { | ||
4019 | .suspend = nct6775_suspend, | ||
4020 | .resume = nct6775_resume, | ||
4021 | }; | ||
4022 | |||
4023 | #define NCT6775_DEV_PM_OPS (&nct6775_dev_pm_ops) | ||
4024 | #else | ||
4025 | #define NCT6775_DEV_PM_OPS NULL | ||
4026 | #endif /* CONFIG_PM */ | ||
4027 | |||
4028 | static struct platform_driver nct6775_driver = { | ||
4029 | .driver = { | ||
4030 | .owner = THIS_MODULE, | ||
4031 | .name = DRVNAME, | ||
4032 | .pm = NCT6775_DEV_PM_OPS, | ||
4033 | }, | ||
4034 | .probe = nct6775_probe, | ||
4035 | .remove = nct6775_remove, | ||
4036 | }; | ||
4037 | |||
4038 | static const char * const nct6775_sio_names[] __initconst = { | ||
4039 | "NCT6775F", | ||
4040 | "NCT6776D/F", | ||
4041 | "NCT6779D", | ||
4042 | }; | ||
4043 | |||
4044 | /* nct6775_find() looks for a '627 in the Super-I/O config space */ | ||
4045 | static int __init nct6775_find(int sioaddr, unsigned short *addr, | ||
4046 | struct nct6775_sio_data *sio_data) | ||
4047 | { | ||
4048 | u16 val; | ||
4049 | int err; | ||
4050 | |||
4051 | err = superio_enter(sioaddr); | ||
4052 | if (err) | ||
4053 | return err; | ||
4054 | |||
4055 | if (force_id) | ||
4056 | val = force_id; | ||
4057 | else | ||
4058 | val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | ||
4059 | | superio_inb(sioaddr, SIO_REG_DEVID + 1); | ||
4060 | switch (val & SIO_ID_MASK) { | ||
4061 | case SIO_NCT6775_ID: | ||
4062 | sio_data->kind = nct6775; | ||
4063 | break; | ||
4064 | case SIO_NCT6776_ID: | ||
4065 | sio_data->kind = nct6776; | ||
4066 | break; | ||
4067 | case SIO_NCT6779_ID: | ||
4068 | sio_data->kind = nct6779; | ||
4069 | break; | ||
4070 | default: | ||
4071 | if (val != 0xffff) | ||
4072 | pr_debug("unsupported chip ID: 0x%04x\n", val); | ||
4073 | superio_exit(sioaddr); | ||
4074 | return -ENODEV; | ||
4075 | } | ||
4076 | |||
4077 | /* We have a known chip, find the HWM I/O address */ | ||
4078 | superio_select(sioaddr, NCT6775_LD_HWM); | ||
4079 | val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8) | ||
4080 | | superio_inb(sioaddr, SIO_REG_ADDR + 1); | ||
4081 | *addr = val & IOREGION_ALIGNMENT; | ||
4082 | if (*addr == 0) { | ||
4083 | pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n"); | ||
4084 | superio_exit(sioaddr); | ||
4085 | return -ENODEV; | ||
4086 | } | ||
4087 | |||
4088 | /* Activate logical device if needed */ | ||
4089 | val = superio_inb(sioaddr, SIO_REG_ENABLE); | ||
4090 | if (!(val & 0x01)) { | ||
4091 | pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n"); | ||
4092 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); | ||
4093 | } | ||
4094 | |||
4095 | superio_exit(sioaddr); | ||
4096 | pr_info("Found %s or compatible chip at %#x\n", | ||
4097 | nct6775_sio_names[sio_data->kind], *addr); | ||
4098 | sio_data->sioreg = sioaddr; | ||
4099 | |||
4100 | return 0; | ||
4101 | } | ||
4102 | |||
4103 | /* | ||
4104 | * when Super-I/O functions move to a separate file, the Super-I/O | ||
4105 | * bus will manage the lifetime of the device and this module will only keep | ||
4106 | * track of the nct6775 driver. But since we platform_device_alloc(), we | ||
4107 | * must keep track of the device | ||
4108 | */ | ||
4109 | static struct platform_device *pdev; | ||
4110 | |||
4111 | static int __init sensors_nct6775_init(void) | ||
4112 | { | ||
4113 | int err; | ||
4114 | unsigned short address; | ||
4115 | struct resource res; | ||
4116 | struct nct6775_sio_data sio_data; | ||
4117 | |||
4118 | /* | ||
4119 | * initialize sio_data->kind and sio_data->sioreg. | ||
4120 | * | ||
4121 | * when Super-I/O functions move to a separate file, the Super-I/O | ||
4122 | * driver will probe 0x2e and 0x4e and auto-detect the presence of a | ||
4123 | * nct6775 hardware monitor, and call probe() | ||
4124 | */ | ||
4125 | if (nct6775_find(0x2e, &address, &sio_data) && | ||
4126 | nct6775_find(0x4e, &address, &sio_data)) | ||
4127 | return -ENODEV; | ||
4128 | |||
4129 | err = platform_driver_register(&nct6775_driver); | ||
4130 | if (err) | ||
4131 | goto exit; | ||
4132 | |||
4133 | pdev = platform_device_alloc(DRVNAME, address); | ||
4134 | if (!pdev) { | ||
4135 | err = -ENOMEM; | ||
4136 | pr_err("Device allocation failed\n"); | ||
4137 | goto exit_unregister; | ||
4138 | } | ||
4139 | |||
4140 | err = platform_device_add_data(pdev, &sio_data, | ||
4141 | sizeof(struct nct6775_sio_data)); | ||
4142 | if (err) { | ||
4143 | pr_err("Platform data allocation failed\n"); | ||
4144 | goto exit_device_put; | ||
4145 | } | ||
4146 | |||
4147 | memset(&res, 0, sizeof(res)); | ||
4148 | res.name = DRVNAME; | ||
4149 | res.start = address + IOREGION_OFFSET; | ||
4150 | res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; | ||
4151 | res.flags = IORESOURCE_IO; | ||
4152 | |||
4153 | err = acpi_check_resource_conflict(&res); | ||
4154 | if (err) | ||
4155 | goto exit_device_put; | ||
4156 | |||
4157 | err = platform_device_add_resources(pdev, &res, 1); | ||
4158 | if (err) { | ||
4159 | pr_err("Device resource addition failed (%d)\n", err); | ||
4160 | goto exit_device_put; | ||
4161 | } | ||
4162 | |||
4163 | /* platform_device_add calls probe() */ | ||
4164 | err = platform_device_add(pdev); | ||
4165 | if (err) { | ||
4166 | pr_err("Device addition failed (%d)\n", err); | ||
4167 | goto exit_device_put; | ||
4168 | } | ||
4169 | |||
4170 | return 0; | ||
4171 | |||
4172 | exit_device_put: | ||
4173 | platform_device_put(pdev); | ||
4174 | exit_unregister: | ||
4175 | platform_driver_unregister(&nct6775_driver); | ||
4176 | exit: | ||
4177 | return err; | ||
4178 | } | ||
4179 | |||
4180 | static void __exit sensors_nct6775_exit(void) | ||
4181 | { | ||
4182 | platform_device_unregister(pdev); | ||
4183 | platform_driver_unregister(&nct6775_driver); | ||
4184 | } | ||
4185 | |||
4186 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); | ||
4187 | MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver"); | ||
4188 | MODULE_LICENSE("GPL"); | ||
4189 | |||
4190 | module_init(sensors_nct6775_init); | ||
4191 | module_exit(sensors_nct6775_exit); | ||
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index b5f63f9c0ce1..d6d640a733d5 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c | |||
@@ -26,17 +26,33 @@ | |||
26 | #include <linux/math64.h> | 26 | #include <linux/math64.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/err.h> | 28 | #include <linux/err.h> |
29 | #include <linux/of.h> | ||
30 | #include <linux/of_device.h> | ||
29 | 31 | ||
30 | #include <linux/platform_data/ntc_thermistor.h> | 32 | #include <linux/platform_data/ntc_thermistor.h> |
31 | 33 | ||
34 | #include <linux/iio/iio.h> | ||
35 | #include <linux/iio/machine.h> | ||
36 | #include <linux/iio/driver.h> | ||
37 | #include <linux/iio/consumer.h> | ||
38 | |||
32 | #include <linux/hwmon.h> | 39 | #include <linux/hwmon.h> |
33 | #include <linux/hwmon-sysfs.h> | 40 | #include <linux/hwmon-sysfs.h> |
34 | 41 | ||
35 | struct ntc_compensation { | 42 | struct ntc_compensation { |
36 | int temp_C; | 43 | int temp_c; |
37 | unsigned int ohm; | 44 | unsigned int ohm; |
38 | }; | 45 | }; |
39 | 46 | ||
47 | static const struct platform_device_id ntc_thermistor_id[] = { | ||
48 | { "ncp15wb473", TYPE_NCPXXWB473 }, | ||
49 | { "ncp18wb473", TYPE_NCPXXWB473 }, | ||
50 | { "ncp21wb473", TYPE_NCPXXWB473 }, | ||
51 | { "ncp03wb473", TYPE_NCPXXWB473 }, | ||
52 | { "ncp15wl333", TYPE_NCPXXWL333 }, | ||
53 | { }, | ||
54 | }; | ||
55 | |||
40 | /* | 56 | /* |
41 | * A compensation table should be sorted by the values of .ohm | 57 | * A compensation table should be sorted by the values of .ohm |
42 | * in descending order. | 58 | * in descending order. |
@@ -44,76 +60,76 @@ struct ntc_compensation { | |||
44 | * Thermistors Datasheet | 60 | * Thermistors Datasheet |
45 | */ | 61 | */ |
46 | static const struct ntc_compensation ncpXXwb473[] = { | 62 | static const struct ntc_compensation ncpXXwb473[] = { |
47 | { .temp_C = -40, .ohm = 1747920 }, | 63 | { .temp_c = -40, .ohm = 1747920 }, |
48 | { .temp_C = -35, .ohm = 1245428 }, | 64 | { .temp_c = -35, .ohm = 1245428 }, |
49 | { .temp_C = -30, .ohm = 898485 }, | 65 | { .temp_c = -30, .ohm = 898485 }, |
50 | { .temp_C = -25, .ohm = 655802 }, | 66 | { .temp_c = -25, .ohm = 655802 }, |
51 | { .temp_C = -20, .ohm = 483954 }, | 67 | { .temp_c = -20, .ohm = 483954 }, |
52 | { .temp_C = -15, .ohm = 360850 }, | 68 | { .temp_c = -15, .ohm = 360850 }, |
53 | { .temp_C = -10, .ohm = 271697 }, | 69 | { .temp_c = -10, .ohm = 271697 }, |
54 | { .temp_C = -5, .ohm = 206463 }, | 70 | { .temp_c = -5, .ohm = 206463 }, |
55 | { .temp_C = 0, .ohm = 158214 }, | 71 | { .temp_c = 0, .ohm = 158214 }, |
56 | { .temp_C = 5, .ohm = 122259 }, | 72 | { .temp_c = 5, .ohm = 122259 }, |
57 | { .temp_C = 10, .ohm = 95227 }, | 73 | { .temp_c = 10, .ohm = 95227 }, |
58 | { .temp_C = 15, .ohm = 74730 }, | 74 | { .temp_c = 15, .ohm = 74730 }, |
59 | { .temp_C = 20, .ohm = 59065 }, | 75 | { .temp_c = 20, .ohm = 59065 }, |
60 | { .temp_C = 25, .ohm = 47000 }, | 76 | { .temp_c = 25, .ohm = 47000 }, |
61 | { .temp_C = 30, .ohm = 37643 }, | 77 | { .temp_c = 30, .ohm = 37643 }, |
62 | { .temp_C = 35, .ohm = 30334 }, | 78 | { .temp_c = 35, .ohm = 30334 }, |
63 | { .temp_C = 40, .ohm = 24591 }, | 79 | { .temp_c = 40, .ohm = 24591 }, |
64 | { .temp_C = 45, .ohm = 20048 }, | 80 | { .temp_c = 45, .ohm = 20048 }, |
65 | { .temp_C = 50, .ohm = 16433 }, | 81 | { .temp_c = 50, .ohm = 16433 }, |
66 | { .temp_C = 55, .ohm = 13539 }, | 82 | { .temp_c = 55, .ohm = 13539 }, |
67 | { .temp_C = 60, .ohm = 11209 }, | 83 | { .temp_c = 60, .ohm = 11209 }, |
68 | { .temp_C = 65, .ohm = 9328 }, | 84 | { .temp_c = 65, .ohm = 9328 }, |
69 | { .temp_C = 70, .ohm = 7798 }, | 85 | { .temp_c = 70, .ohm = 7798 }, |
70 | { .temp_C = 75, .ohm = 6544 }, | 86 | { .temp_c = 75, .ohm = 6544 }, |
71 | { .temp_C = 80, .ohm = 5518 }, | 87 | { .temp_c = 80, .ohm = 5518 }, |
72 | { .temp_C = 85, .ohm = 4674 }, | 88 | { .temp_c = 85, .ohm = 4674 }, |
73 | { .temp_C = 90, .ohm = 3972 }, | 89 | { .temp_c = 90, .ohm = 3972 }, |
74 | { .temp_C = 95, .ohm = 3388 }, | 90 | { .temp_c = 95, .ohm = 3388 }, |
75 | { .temp_C = 100, .ohm = 2902 }, | 91 | { .temp_c = 100, .ohm = 2902 }, |
76 | { .temp_C = 105, .ohm = 2494 }, | 92 | { .temp_c = 105, .ohm = 2494 }, |
77 | { .temp_C = 110, .ohm = 2150 }, | 93 | { .temp_c = 110, .ohm = 2150 }, |
78 | { .temp_C = 115, .ohm = 1860 }, | 94 | { .temp_c = 115, .ohm = 1860 }, |
79 | { .temp_C = 120, .ohm = 1615 }, | 95 | { .temp_c = 120, .ohm = 1615 }, |
80 | { .temp_C = 125, .ohm = 1406 }, | 96 | { .temp_c = 125, .ohm = 1406 }, |
81 | }; | 97 | }; |
82 | static const struct ntc_compensation ncpXXwl333[] = { | 98 | static const struct ntc_compensation ncpXXwl333[] = { |
83 | { .temp_C = -40, .ohm = 1610154 }, | 99 | { .temp_c = -40, .ohm = 1610154 }, |
84 | { .temp_C = -35, .ohm = 1130850 }, | 100 | { .temp_c = -35, .ohm = 1130850 }, |
85 | { .temp_C = -30, .ohm = 802609 }, | 101 | { .temp_c = -30, .ohm = 802609 }, |
86 | { .temp_C = -25, .ohm = 575385 }, | 102 | { .temp_c = -25, .ohm = 575385 }, |
87 | { .temp_C = -20, .ohm = 416464 }, | 103 | { .temp_c = -20, .ohm = 416464 }, |
88 | { .temp_C = -15, .ohm = 304219 }, | 104 | { .temp_c = -15, .ohm = 304219 }, |
89 | { .temp_C = -10, .ohm = 224193 }, | 105 | { .temp_c = -10, .ohm = 224193 }, |
90 | { .temp_C = -5, .ohm = 166623 }, | 106 | { .temp_c = -5, .ohm = 166623 }, |
91 | { .temp_C = 0, .ohm = 124850 }, | 107 | { .temp_c = 0, .ohm = 124850 }, |
92 | { .temp_C = 5, .ohm = 94287 }, | 108 | { .temp_c = 5, .ohm = 94287 }, |
93 | { .temp_C = 10, .ohm = 71747 }, | 109 | { .temp_c = 10, .ohm = 71747 }, |
94 | { .temp_C = 15, .ohm = 54996 }, | 110 | { .temp_c = 15, .ohm = 54996 }, |
95 | { .temp_C = 20, .ohm = 42455 }, | 111 | { .temp_c = 20, .ohm = 42455 }, |
96 | { .temp_C = 25, .ohm = 33000 }, | 112 | { .temp_c = 25, .ohm = 33000 }, |
97 | { .temp_C = 30, .ohm = 25822 }, | 113 | { .temp_c = 30, .ohm = 25822 }, |
98 | { .temp_C = 35, .ohm = 20335 }, | 114 | { .temp_c = 35, .ohm = 20335 }, |
99 | { .temp_C = 40, .ohm = 16115 }, | 115 | { .temp_c = 40, .ohm = 16115 }, |
100 | { .temp_C = 45, .ohm = 12849 }, | 116 | { .temp_c = 45, .ohm = 12849 }, |
101 | { .temp_C = 50, .ohm = 10306 }, | 117 | { .temp_c = 50, .ohm = 10306 }, |
102 | { .temp_C = 55, .ohm = 8314 }, | 118 | { .temp_c = 55, .ohm = 8314 }, |
103 | { .temp_C = 60, .ohm = 6746 }, | 119 | { .temp_c = 60, .ohm = 6746 }, |
104 | { .temp_C = 65, .ohm = 5503 }, | 120 | { .temp_c = 65, .ohm = 5503 }, |
105 | { .temp_C = 70, .ohm = 4513 }, | 121 | { .temp_c = 70, .ohm = 4513 }, |
106 | { .temp_C = 75, .ohm = 3721 }, | 122 | { .temp_c = 75, .ohm = 3721 }, |
107 | { .temp_C = 80, .ohm = 3084 }, | 123 | { .temp_c = 80, .ohm = 3084 }, |
108 | { .temp_C = 85, .ohm = 2569 }, | 124 | { .temp_c = 85, .ohm = 2569 }, |
109 | { .temp_C = 90, .ohm = 2151 }, | 125 | { .temp_c = 90, .ohm = 2151 }, |
110 | { .temp_C = 95, .ohm = 1809 }, | 126 | { .temp_c = 95, .ohm = 1809 }, |
111 | { .temp_C = 100, .ohm = 1529 }, | 127 | { .temp_c = 100, .ohm = 1529 }, |
112 | { .temp_C = 105, .ohm = 1299 }, | 128 | { .temp_c = 105, .ohm = 1299 }, |
113 | { .temp_C = 110, .ohm = 1108 }, | 129 | { .temp_c = 110, .ohm = 1108 }, |
114 | { .temp_C = 115, .ohm = 949 }, | 130 | { .temp_c = 115, .ohm = 949 }, |
115 | { .temp_C = 120, .ohm = 817 }, | 131 | { .temp_c = 120, .ohm = 817 }, |
116 | { .temp_C = 125, .ohm = 707 }, | 132 | { .temp_c = 125, .ohm = 707 }, |
117 | }; | 133 | }; |
118 | 134 | ||
119 | struct ntc_data { | 135 | struct ntc_data { |
@@ -125,6 +141,92 @@ struct ntc_data { | |||
125 | char name[PLATFORM_NAME_SIZE]; | 141 | char name[PLATFORM_NAME_SIZE]; |
126 | }; | 142 | }; |
127 | 143 | ||
144 | #ifdef CONFIG_OF | ||
145 | static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) | ||
146 | { | ||
147 | struct iio_channel *channel = pdata->chan; | ||
148 | unsigned int result; | ||
149 | int val, ret; | ||
150 | |||
151 | ret = iio_read_channel_raw(channel, &val); | ||
152 | if (ret < 0) { | ||
153 | pr_err("read channel() error: %d\n", ret); | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | /* unit: mV */ | ||
158 | result = pdata->pullup_uv * val; | ||
159 | result >>= 12; | ||
160 | |||
161 | return result; | ||
162 | } | ||
163 | |||
164 | static const struct of_device_id ntc_match[] = { | ||
165 | { .compatible = "ntc,ncp15wb473", | ||
166 | .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, | ||
167 | { .compatible = "ntc,ncp18wb473", | ||
168 | .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, | ||
169 | { .compatible = "ntc,ncp21wb473", | ||
170 | .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, | ||
171 | { .compatible = "ntc,ncp03wb473", | ||
172 | .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, | ||
173 | { .compatible = "ntc,ncp15wl333", | ||
174 | .data = &ntc_thermistor_id[TYPE_NCPXXWL333] }, | ||
175 | { }, | ||
176 | }; | ||
177 | MODULE_DEVICE_TABLE(of, ntc_match); | ||
178 | |||
179 | static struct ntc_thermistor_platform_data * | ||
180 | ntc_thermistor_parse_dt(struct platform_device *pdev) | ||
181 | { | ||
182 | struct iio_channel *chan; | ||
183 | struct device_node *np = pdev->dev.of_node; | ||
184 | struct ntc_thermistor_platform_data *pdata; | ||
185 | |||
186 | if (!np) | ||
187 | return NULL; | ||
188 | |||
189 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
190 | if (!pdata) | ||
191 | return ERR_PTR(-ENOMEM); | ||
192 | |||
193 | chan = iio_channel_get(&pdev->dev, NULL); | ||
194 | if (IS_ERR(chan)) | ||
195 | return ERR_CAST(chan); | ||
196 | |||
197 | if (of_property_read_u32(np, "pullup-uv", &pdata->pullup_uv)) | ||
198 | return ERR_PTR(-ENODEV); | ||
199 | if (of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm)) | ||
200 | return ERR_PTR(-ENODEV); | ||
201 | if (of_property_read_u32(np, "pulldown-ohm", &pdata->pulldown_ohm)) | ||
202 | return ERR_PTR(-ENODEV); | ||
203 | |||
204 | if (of_find_property(np, "connected-positive", NULL)) | ||
205 | pdata->connect = NTC_CONNECTED_POSITIVE; | ||
206 | else /* status change should be possible if not always on. */ | ||
207 | pdata->connect = NTC_CONNECTED_GROUND; | ||
208 | |||
209 | pdata->chan = chan; | ||
210 | pdata->read_uv = ntc_adc_iio_read; | ||
211 | |||
212 | return pdata; | ||
213 | } | ||
214 | static void ntc_iio_channel_release(struct ntc_thermistor_platform_data *pdata) | ||
215 | { | ||
216 | if (pdata->chan) | ||
217 | iio_channel_release(pdata->chan); | ||
218 | } | ||
219 | #else | ||
220 | static struct ntc_thermistor_platform_data * | ||
221 | ntc_thermistor_parse_dt(struct platform_device *pdev) | ||
222 | { | ||
223 | return NULL; | ||
224 | } | ||
225 | |||
226 | static void ntc_iio_channel_release(struct ntc_thermistor_platform_data *pdata) | ||
227 | { } | ||
228 | #endif | ||
229 | |||
128 | static inline u64 div64_u64_safe(u64 dividend, u64 divisor) | 230 | static inline u64 div64_u64_safe(u64 dividend, u64 divisor) |
129 | { | 231 | { |
130 | if (divisor == 0 && dividend == 0) | 232 | if (divisor == 0 && dividend == 0) |
@@ -134,37 +236,37 @@ static inline u64 div64_u64_safe(u64 dividend, u64 divisor) | |||
134 | return div64_u64(dividend, divisor); | 236 | return div64_u64(dividend, divisor); |
135 | } | 237 | } |
136 | 238 | ||
137 | static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uV) | 239 | static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uv) |
138 | { | 240 | { |
139 | struct ntc_thermistor_platform_data *pdata = data->pdata; | 241 | struct ntc_thermistor_platform_data *pdata = data->pdata; |
140 | u64 mV = uV / 1000; | 242 | u64 mv = uv / 1000; |
141 | u64 pmV = pdata->pullup_uV / 1000; | 243 | u64 pmv = pdata->pullup_uv / 1000; |
142 | u64 N, puO, pdO; | 244 | u64 n, puo, pdo; |
143 | puO = pdata->pullup_ohm; | 245 | puo = pdata->pullup_ohm; |
144 | pdO = pdata->pulldown_ohm; | 246 | pdo = pdata->pulldown_ohm; |
145 | 247 | ||
146 | if (mV == 0) { | 248 | if (mv == 0) { |
147 | if (pdata->connect == NTC_CONNECTED_POSITIVE) | 249 | if (pdata->connect == NTC_CONNECTED_POSITIVE) |
148 | return INT_MAX; | 250 | return INT_MAX; |
149 | return 0; | 251 | return 0; |
150 | } | 252 | } |
151 | if (mV >= pmV) | 253 | if (mv >= pmv) |
152 | return (pdata->connect == NTC_CONNECTED_POSITIVE) ? | 254 | return (pdata->connect == NTC_CONNECTED_POSITIVE) ? |
153 | 0 : INT_MAX; | 255 | 0 : INT_MAX; |
154 | 256 | ||
155 | if (pdata->connect == NTC_CONNECTED_POSITIVE && puO == 0) | 257 | if (pdata->connect == NTC_CONNECTED_POSITIVE && puo == 0) |
156 | N = div64_u64_safe(pdO * (pmV - mV), mV); | 258 | n = div64_u64_safe(pdo * (pmv - mv), mv); |
157 | else if (pdata->connect == NTC_CONNECTED_GROUND && pdO == 0) | 259 | else if (pdata->connect == NTC_CONNECTED_GROUND && pdo == 0) |
158 | N = div64_u64_safe(puO * mV, pmV - mV); | 260 | n = div64_u64_safe(puo * mv, pmv - mv); |
159 | else if (pdata->connect == NTC_CONNECTED_POSITIVE) | 261 | else if (pdata->connect == NTC_CONNECTED_POSITIVE) |
160 | N = div64_u64_safe(pdO * puO * (pmV - mV), | 262 | n = div64_u64_safe(pdo * puo * (pmv - mv), |
161 | puO * mV - pdO * (pmV - mV)); | 263 | puo * mv - pdo * (pmv - mv)); |
162 | else | 264 | else |
163 | N = div64_u64_safe(pdO * puO * mV, pdO * (pmV - mV) - puO * mV); | 265 | n = div64_u64_safe(pdo * puo * mv, pdo * (pmv - mv) - puo * mv); |
164 | 266 | ||
165 | if (N > INT_MAX) | 267 | if (n > INT_MAX) |
166 | N = INT_MAX; | 268 | n = INT_MAX; |
167 | return N; | 269 | return n; |
168 | } | 270 | } |
169 | 271 | ||
170 | static void lookup_comp(struct ntc_data *data, unsigned int ohm, | 272 | static void lookup_comp(struct ntc_data *data, unsigned int ohm, |
@@ -233,7 +335,7 @@ static void lookup_comp(struct ntc_data *data, unsigned int ohm, | |||
233 | *i_high = end - 1; | 335 | *i_high = end - 1; |
234 | } | 336 | } |
235 | 337 | ||
236 | static int get_temp_mC(struct ntc_data *data, unsigned int ohm) | 338 | static int get_temp_mc(struct ntc_data *data, unsigned int ohm) |
237 | { | 339 | { |
238 | int low, high; | 340 | int low, high; |
239 | int temp; | 341 | int temp; |
@@ -241,10 +343,10 @@ static int get_temp_mC(struct ntc_data *data, unsigned int ohm) | |||
241 | lookup_comp(data, ohm, &low, &high); | 343 | lookup_comp(data, ohm, &low, &high); |
242 | if (low == high) { | 344 | if (low == high) { |
243 | /* Unable to use linear approximation */ | 345 | /* Unable to use linear approximation */ |
244 | temp = data->comp[low].temp_C * 1000; | 346 | temp = data->comp[low].temp_c * 1000; |
245 | } else { | 347 | } else { |
246 | temp = data->comp[low].temp_C * 1000 + | 348 | temp = data->comp[low].temp_c * 1000 + |
247 | ((data->comp[high].temp_C - data->comp[low].temp_C) * | 349 | ((data->comp[high].temp_c - data->comp[low].temp_c) * |
248 | 1000 * ((int)ohm - (int)data->comp[low].ohm)) / | 350 | 1000 * ((int)ohm - (int)data->comp[low].ohm)) / |
249 | ((int)data->comp[high].ohm - (int)data->comp[low].ohm); | 351 | ((int)data->comp[high].ohm - (int)data->comp[low].ohm); |
250 | } | 352 | } |
@@ -253,16 +355,16 @@ static int get_temp_mC(struct ntc_data *data, unsigned int ohm) | |||
253 | 355 | ||
254 | static int ntc_thermistor_get_ohm(struct ntc_data *data) | 356 | static int ntc_thermistor_get_ohm(struct ntc_data *data) |
255 | { | 357 | { |
256 | int read_uV; | 358 | int read_uv; |
257 | 359 | ||
258 | if (data->pdata->read_ohm) | 360 | if (data->pdata->read_ohm) |
259 | return data->pdata->read_ohm(); | 361 | return data->pdata->read_ohm(); |
260 | 362 | ||
261 | if (data->pdata->read_uV) { | 363 | if (data->pdata->read_uv) { |
262 | read_uV = data->pdata->read_uV(); | 364 | read_uv = data->pdata->read_uv(data->pdata); |
263 | if (read_uV < 0) | 365 | if (read_uv < 0) |
264 | return read_uV; | 366 | return read_uv; |
265 | return get_ohm_of_thermistor(data, read_uV); | 367 | return get_ohm_of_thermistor(data, read_uv); |
266 | } | 368 | } |
267 | return -EINVAL; | 369 | return -EINVAL; |
268 | } | 370 | } |
@@ -291,7 +393,7 @@ static ssize_t ntc_show_temp(struct device *dev, | |||
291 | if (ohm < 0) | 393 | if (ohm < 0) |
292 | return ohm; | 394 | return ohm; |
293 | 395 | ||
294 | return sprintf(buf, "%d\n", get_temp_mC(data, ohm)); | 396 | return sprintf(buf, "%d\n", get_temp_mc(data, ohm)); |
295 | } | 397 | } |
296 | 398 | ||
297 | static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, ntc_show_type, NULL, 0); | 399 | static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, ntc_show_type, NULL, 0); |
@@ -311,9 +413,18 @@ static const struct attribute_group ntc_attr_group = { | |||
311 | 413 | ||
312 | static int ntc_thermistor_probe(struct platform_device *pdev) | 414 | static int ntc_thermistor_probe(struct platform_device *pdev) |
313 | { | 415 | { |
416 | const struct of_device_id *of_id = | ||
417 | of_match_device(of_match_ptr(ntc_match), &pdev->dev); | ||
418 | const struct platform_device_id *pdev_id; | ||
419 | struct ntc_thermistor_platform_data *pdata; | ||
314 | struct ntc_data *data; | 420 | struct ntc_data *data; |
315 | struct ntc_thermistor_platform_data *pdata = pdev->dev.platform_data; | 421 | int ret; |
316 | int ret = 0; | 422 | |
423 | pdata = ntc_thermistor_parse_dt(pdev); | ||
424 | if (IS_ERR(pdata)) | ||
425 | return PTR_ERR(pdata); | ||
426 | else if (pdata == NULL) | ||
427 | pdata = pdev->dev.platform_data; | ||
317 | 428 | ||
318 | if (!pdata) { | 429 | if (!pdata) { |
319 | dev_err(&pdev->dev, "No platform init data supplied.\n"); | 430 | dev_err(&pdev->dev, "No platform init data supplied.\n"); |
@@ -321,19 +432,19 @@ static int ntc_thermistor_probe(struct platform_device *pdev) | |||
321 | } | 432 | } |
322 | 433 | ||
323 | /* Either one of the two is required. */ | 434 | /* Either one of the two is required. */ |
324 | if (!pdata->read_uV && !pdata->read_ohm) { | 435 | if (!pdata->read_uv && !pdata->read_ohm) { |
325 | dev_err(&pdev->dev, | 436 | dev_err(&pdev->dev, |
326 | "Both read_uV and read_ohm missing. Need either one of the two.\n"); | 437 | "Both read_uv and read_ohm missing. Need either one of the two.\n"); |
327 | return -EINVAL; | 438 | return -EINVAL; |
328 | } | 439 | } |
329 | 440 | ||
330 | if (pdata->read_uV && pdata->read_ohm) { | 441 | if (pdata->read_uv && pdata->read_ohm) { |
331 | dev_warn(&pdev->dev, | 442 | dev_warn(&pdev->dev, |
332 | "Only one of read_uV and read_ohm is needed; ignoring read_uV.\n"); | 443 | "Only one of read_uv and read_ohm is needed; ignoring read_uv.\n"); |
333 | pdata->read_uV = NULL; | 444 | pdata->read_uv = NULL; |
334 | } | 445 | } |
335 | 446 | ||
336 | if (pdata->read_uV && (pdata->pullup_uV == 0 || | 447 | if (pdata->read_uv && (pdata->pullup_uv == 0 || |
337 | (pdata->pullup_ohm == 0 && pdata->connect == | 448 | (pdata->pullup_ohm == 0 && pdata->connect == |
338 | NTC_CONNECTED_GROUND) || | 449 | NTC_CONNECTED_GROUND) || |
339 | (pdata->pulldown_ohm == 0 && pdata->connect == | 450 | (pdata->pulldown_ohm == 0 && pdata->connect == |
@@ -341,7 +452,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev) | |||
341 | (pdata->connect != NTC_CONNECTED_POSITIVE && | 452 | (pdata->connect != NTC_CONNECTED_POSITIVE && |
342 | pdata->connect != NTC_CONNECTED_GROUND))) { | 453 | pdata->connect != NTC_CONNECTED_GROUND))) { |
343 | dev_err(&pdev->dev, | 454 | dev_err(&pdev->dev, |
344 | "Required data to use read_uV not supplied.\n"); | 455 | "Required data to use read_uv not supplied.\n"); |
345 | return -EINVAL; | 456 | return -EINVAL; |
346 | } | 457 | } |
347 | 458 | ||
@@ -349,11 +460,13 @@ static int ntc_thermistor_probe(struct platform_device *pdev) | |||
349 | if (!data) | 460 | if (!data) |
350 | return -ENOMEM; | 461 | return -ENOMEM; |
351 | 462 | ||
463 | pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); | ||
464 | |||
352 | data->dev = &pdev->dev; | 465 | data->dev = &pdev->dev; |
353 | data->pdata = pdata; | 466 | data->pdata = pdata; |
354 | strlcpy(data->name, pdev->id_entry->name, sizeof(data->name)); | 467 | strlcpy(data->name, pdev_id->name, sizeof(data->name)); |
355 | 468 | ||
356 | switch (pdev->id_entry->driver_data) { | 469 | switch (pdev_id->driver_data) { |
357 | case TYPE_NCPXXWB473: | 470 | case TYPE_NCPXXWB473: |
358 | data->comp = ncpXXwb473; | 471 | data->comp = ncpXXwb473; |
359 | data->n_comp = ARRAY_SIZE(ncpXXwb473); | 472 | data->n_comp = ARRAY_SIZE(ncpXXwb473); |
@@ -364,8 +477,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev) | |||
364 | break; | 477 | break; |
365 | default: | 478 | default: |
366 | dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", | 479 | dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", |
367 | pdev->id_entry->driver_data, | 480 | pdev_id->driver_data, pdev_id->name); |
368 | pdev->id_entry->name); | ||
369 | return -EINVAL; | 481 | return -EINVAL; |
370 | } | 482 | } |
371 | 483 | ||
@@ -384,39 +496,34 @@ static int ntc_thermistor_probe(struct platform_device *pdev) | |||
384 | goto err_after_sysfs; | 496 | goto err_after_sysfs; |
385 | } | 497 | } |
386 | 498 | ||
387 | dev_info(&pdev->dev, "Thermistor %s:%d (type: %s/%lu) successfully probed.\n", | 499 | dev_info(&pdev->dev, "Thermistor type: %s successfully probed.\n", |
388 | pdev->name, pdev->id, pdev->id_entry->name, | 500 | pdev->name); |
389 | pdev->id_entry->driver_data); | 501 | |
390 | return 0; | 502 | return 0; |
391 | err_after_sysfs: | 503 | err_after_sysfs: |
392 | sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); | 504 | sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); |
505 | ntc_iio_channel_release(pdata); | ||
393 | return ret; | 506 | return ret; |
394 | } | 507 | } |
395 | 508 | ||
396 | static int ntc_thermistor_remove(struct platform_device *pdev) | 509 | static int ntc_thermistor_remove(struct platform_device *pdev) |
397 | { | 510 | { |
398 | struct ntc_data *data = platform_get_drvdata(pdev); | 511 | struct ntc_data *data = platform_get_drvdata(pdev); |
512 | struct ntc_thermistor_platform_data *pdata = data->pdata; | ||
399 | 513 | ||
400 | hwmon_device_unregister(data->hwmon_dev); | 514 | hwmon_device_unregister(data->hwmon_dev); |
401 | sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); | 515 | sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); |
516 | ntc_iio_channel_release(pdata); | ||
402 | platform_set_drvdata(pdev, NULL); | 517 | platform_set_drvdata(pdev, NULL); |
403 | 518 | ||
404 | return 0; | 519 | return 0; |
405 | } | 520 | } |
406 | 521 | ||
407 | static const struct platform_device_id ntc_thermistor_id[] = { | ||
408 | { "ncp15wb473", TYPE_NCPXXWB473 }, | ||
409 | { "ncp18wb473", TYPE_NCPXXWB473 }, | ||
410 | { "ncp21wb473", TYPE_NCPXXWB473 }, | ||
411 | { "ncp03wb473", TYPE_NCPXXWB473 }, | ||
412 | { "ncp15wl333", TYPE_NCPXXWL333 }, | ||
413 | { }, | ||
414 | }; | ||
415 | |||
416 | static struct platform_driver ntc_thermistor_driver = { | 522 | static struct platform_driver ntc_thermistor_driver = { |
417 | .driver = { | 523 | .driver = { |
418 | .name = "ntc-thermistor", | 524 | .name = "ntc-thermistor", |
419 | .owner = THIS_MODULE, | 525 | .owner = THIS_MODULE, |
526 | .of_match_table = of_match_ptr(ntc_match), | ||
420 | }, | 527 | }, |
421 | .probe = ntc_thermistor_probe, | 528 | .probe = ntc_thermistor_probe, |
422 | .remove = ntc_thermistor_remove, | 529 | .remove = ntc_thermistor_remove, |
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index e35856bb79b4..aa615ba73d4b 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -1190,8 +1190,7 @@ static int __init pc87360_find(int sioaddr, u8 *devid, | |||
1190 | confreg[3] = superio_inb(sioaddr, 0x25); | 1190 | confreg[3] = superio_inb(sioaddr, 0x25); |
1191 | 1191 | ||
1192 | if (confreg[2] & 0x40) { | 1192 | if (confreg[2] & 0x40) { |
1193 | pr_info("Using thermistors for " | 1193 | pr_info("Using thermistors for temperature monitoring\n"); |
1194 | "temperature monitoring\n"); | ||
1195 | } | 1194 | } |
1196 | if (confreg[3] & 0xE0) { | 1195 | if (confreg[3] & 0xE0) { |
1197 | pr_info("VID inputs routed (mode %u)\n", | 1196 | pr_info("VID inputs routed (mode %u)\n", |
@@ -1271,9 +1270,9 @@ static int pc87360_probe(struct platform_device *pdev) | |||
1271 | if (data->address[i] | 1270 | if (data->address[i] |
1272 | && !devm_request_region(dev, extra_isa[i], PC87360_EXTENT, | 1271 | && !devm_request_region(dev, extra_isa[i], PC87360_EXTENT, |
1273 | pc87360_driver.driver.name)) { | 1272 | pc87360_driver.driver.name)) { |
1274 | dev_err(dev, "Region 0x%x-0x%x already " | 1273 | dev_err(dev, |
1275 | "in use!\n", extra_isa[i], | 1274 | "Region 0x%x-0x%x already in use!\n", |
1276 | extra_isa[i]+PC87360_EXTENT-1); | 1275 | extra_isa[i], extra_isa[i]+PC87360_EXTENT-1); |
1277 | return -EBUSY; | 1276 | return -EBUSY; |
1278 | } | 1277 | } |
1279 | } | 1278 | } |
@@ -1435,8 +1434,8 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1435 | if (init >= 2 && data->innr) { | 1434 | if (init >= 2 && data->innr) { |
1436 | reg = pc87360_read_value(data, LD_IN, NO_BANK, | 1435 | reg = pc87360_read_value(data, LD_IN, NO_BANK, |
1437 | PC87365_REG_IN_CONVRATE); | 1436 | PC87365_REG_IN_CONVRATE); |
1438 | dev_info(&pdev->dev, "VLM conversion set to " | 1437 | dev_info(&pdev->dev, |
1439 | "1s period, 160us delay\n"); | 1438 | "VLM conversion set to 1s period, 160us delay\n"); |
1440 | pc87360_write_value(data, LD_IN, NO_BANK, | 1439 | pc87360_write_value(data, LD_IN, NO_BANK, |
1441 | PC87365_REG_IN_CONVRATE, | 1440 | PC87365_REG_IN_CONVRATE, |
1442 | (reg & 0xC0) | 0x11); | 1441 | (reg & 0xC0) | 0x11); |
@@ -1450,8 +1449,8 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1450 | if (init >= init_in[i]) { | 1449 | if (init >= init_in[i]) { |
1451 | /* Forcibly enable voltage channel */ | 1450 | /* Forcibly enable voltage channel */ |
1452 | if (!(reg & CHAN_ENA)) { | 1451 | if (!(reg & CHAN_ENA)) { |
1453 | dev_dbg(&pdev->dev, "Forcibly " | 1452 | dev_dbg(&pdev->dev, "Forcibly enabling in%d\n", |
1454 | "enabling in%d\n", i); | 1453 | i); |
1455 | pc87360_write_value(data, LD_IN, i, | 1454 | pc87360_write_value(data, LD_IN, i, |
1456 | PC87365_REG_IN_STATUS, | 1455 | PC87365_REG_IN_STATUS, |
1457 | (reg & 0x68) | 0x87); | 1456 | (reg & 0x68) | 0x87); |
@@ -1575,8 +1574,8 @@ static void pc87360_autodiv(struct device *dev, int nr) | |||
1575 | data->fan_status[nr] += 0x20; | 1574 | data->fan_status[nr] += 0x20; |
1576 | data->fan_min[nr] >>= 1; | 1575 | data->fan_min[nr] >>= 1; |
1577 | data->fan[nr] >>= 1; | 1576 | data->fan[nr] >>= 1; |
1578 | dev_dbg(dev, "Increasing " | 1577 | dev_dbg(dev, |
1579 | "clock divider to %d for fan %d\n", | 1578 | "Increasing clock divider to %d for fan %d\n", |
1580 | FAN_DIV_FROM_REG(data->fan_status[nr]), nr + 1); | 1579 | FAN_DIV_FROM_REG(data->fan_status[nr]), nr + 1); |
1581 | } | 1580 | } |
1582 | } else { | 1581 | } else { |
@@ -1587,8 +1586,8 @@ static void pc87360_autodiv(struct device *dev, int nr) | |||
1587 | data->fan_status[nr] -= 0x20; | 1586 | data->fan_status[nr] -= 0x20; |
1588 | data->fan_min[nr] <<= 1; | 1587 | data->fan_min[nr] <<= 1; |
1589 | data->fan[nr] <<= 1; | 1588 | data->fan[nr] <<= 1; |
1590 | dev_dbg(dev, "Decreasing " | 1589 | dev_dbg(dev, |
1591 | "clock divider to %d for fan %d\n", | 1590 | "Decreasing clock divider to %d for fan %d\n", |
1592 | FAN_DIV_FROM_REG(data->fan_status[nr]), | 1591 | FAN_DIV_FROM_REG(data->fan_status[nr]), |
1593 | nr + 1); | 1592 | nr + 1); |
1594 | } | 1593 | } |
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 6086ad039d7d..ea606860d2b2 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c | |||
@@ -627,8 +627,9 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute | |||
627 | pc87427_readall_pwm(data, nr); | 627 | pc87427_readall_pwm(data, nr); |
628 | mode = data->pwm_enable[nr] & PWM_ENABLE_MODE_MASK; | 628 | mode = data->pwm_enable[nr] & PWM_ENABLE_MODE_MASK; |
629 | if (mode != PWM_MODE_MANUAL && mode != PWM_MODE_OFF) { | 629 | if (mode != PWM_MODE_MANUAL && mode != PWM_MODE_OFF) { |
630 | dev_notice(dev, "Can't set PWM%d duty cycle while not in " | 630 | dev_notice(dev, |
631 | "manual mode\n", nr + 1); | 631 | "Can't set PWM%d duty cycle while not in manual mode\n", |
632 | nr + 1); | ||
632 | mutex_unlock(&data->lock); | 633 | mutex_unlock(&data->lock); |
633 | return -EPERM; | 634 | return -EPERM; |
634 | } | 635 | } |
@@ -1245,16 +1246,16 @@ static int __init pc87427_find(int sioaddr, struct pc87427_sio_data *sio_data) | |||
1245 | 1246 | ||
1246 | val = superio_inb(sioaddr, SIOREG_MAP); | 1247 | val = superio_inb(sioaddr, SIOREG_MAP); |
1247 | if (val & 0x01) { | 1248 | if (val & 0x01) { |
1248 | pr_warn("Logical device 0x%02x is memory-mapped, " | 1249 | pr_warn("Logical device 0x%02x is memory-mapped, can't use\n", |
1249 | "can't use\n", logdev[i]); | 1250 | logdev[i]); |
1250 | continue; | 1251 | continue; |
1251 | } | 1252 | } |
1252 | 1253 | ||
1253 | val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8) | 1254 | val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8) |
1254 | | superio_inb(sioaddr, SIOREG_IOBASE + 1); | 1255 | | superio_inb(sioaddr, SIOREG_IOBASE + 1); |
1255 | if (!val) { | 1256 | if (!val) { |
1256 | pr_info("I/O base address not set for logical device " | 1257 | pr_info("I/O base address not set for logical device 0x%02x\n", |
1257 | "0x%02x\n", logdev[i]); | 1258 | logdev[i]); |
1258 | continue; | 1259 | continue; |
1259 | } | 1260 | } |
1260 | sio_data->address[i] = val; | 1261 | sio_data->address[i] = val; |
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 4f9eb0af5229..39cc63edfbb0 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig | |||
@@ -42,17 +42,17 @@ config SENSORS_LM25066 | |||
42 | default n | 42 | default n |
43 | help | 43 | help |
44 | If you say yes here you get hardware monitoring support for National | 44 | If you say yes here you get hardware monitoring support for National |
45 | Semiconductor LM25066, LM5064, and LM5066. | 45 | Semiconductor LM25056, LM25066, LM5064, and LM5066. |
46 | 46 | ||
47 | This driver can also be built as a module. If so, the module will | 47 | This driver can also be built as a module. If so, the module will |
48 | be called lm25066. | 48 | be called lm25066. |
49 | 49 | ||
50 | config SENSORS_LTC2978 | 50 | config SENSORS_LTC2978 |
51 | tristate "Linear Technologies LTC2978 and LTC3880" | 51 | tristate "Linear Technologies LTC2974, LTC2978, LTC3880, and LTC3883" |
52 | default n | 52 | default n |
53 | help | 53 | help |
54 | If you say yes here you get hardware monitoring support for Linear | 54 | If you say yes here you get hardware monitoring support for Linear |
55 | Technology LTC2978 and LTC3880. | 55 | Technology LTC2974, LTC2978, LTC3880, and LTC3883. |
56 | 56 | ||
57 | This driver can also be built as a module. If so, the module will | 57 | This driver can also be built as a module. If so, the module will |
58 | be called ltc2978. | 58 | be called ltc2978. |
diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index c299392716af..6a9d6edaacb3 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Hardware monitoring driver for LM25066 / LM5064 / LM5066 | 2 | * Hardware monitoring driver for LM25056 / LM25066 / LM5064 / LM5066 |
3 | * | 3 | * |
4 | * Copyright (c) 2011 Ericsson AB. | 4 | * Copyright (c) 2011 Ericsson AB. |
5 | * Copyright (c) 2013 Guenter Roeck | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -26,7 +27,7 @@ | |||
26 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
27 | #include "pmbus.h" | 28 | #include "pmbus.h" |
28 | 29 | ||
29 | enum chips { lm25066, lm5064, lm5066 }; | 30 | enum chips { lm25056, lm25066, lm5064, lm5066 }; |
30 | 31 | ||
31 | #define LM25066_READ_VAUX 0xd0 | 32 | #define LM25066_READ_VAUX 0xd0 |
32 | #define LM25066_MFR_READ_IIN 0xd1 | 33 | #define LM25066_MFR_READ_IIN 0xd1 |
@@ -43,6 +44,138 @@ enum chips { lm25066, lm5064, lm5066 }; | |||
43 | 44 | ||
44 | #define LM25066_DEV_SETUP_CL (1 << 4) /* Current limit */ | 45 | #define LM25066_DEV_SETUP_CL (1 << 4) /* Current limit */ |
45 | 46 | ||
47 | /* LM25056 only */ | ||
48 | |||
49 | #define LM25056_VAUX_OV_WARN_LIMIT 0xe3 | ||
50 | #define LM25056_VAUX_UV_WARN_LIMIT 0xe4 | ||
51 | |||
52 | #define LM25056_MFR_STS_VAUX_OV_WARN (1 << 1) | ||
53 | #define LM25056_MFR_STS_VAUX_UV_WARN (1 << 0) | ||
54 | |||
55 | struct __coeff { | ||
56 | short m, b, R; | ||
57 | }; | ||
58 | |||
59 | #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) | ||
60 | #define PSC_POWER_L (PSC_NUM_CLASSES + 1) | ||
61 | |||
62 | static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { | ||
63 | [lm25056] = { | ||
64 | [PSC_VOLTAGE_IN] = { | ||
65 | .m = 16296, | ||
66 | .R = -2, | ||
67 | }, | ||
68 | [PSC_CURRENT_IN] = { | ||
69 | .m = 13797, | ||
70 | .R = -2, | ||
71 | }, | ||
72 | [PSC_CURRENT_IN_L] = { | ||
73 | .m = 6726, | ||
74 | .R = -2, | ||
75 | }, | ||
76 | [PSC_POWER] = { | ||
77 | .m = 5501, | ||
78 | .R = -3, | ||
79 | }, | ||
80 | [PSC_POWER_L] = { | ||
81 | .m = 26882, | ||
82 | .R = -4, | ||
83 | }, | ||
84 | [PSC_TEMPERATURE] = { | ||
85 | .m = 1580, | ||
86 | .b = -14500, | ||
87 | .R = -2, | ||
88 | }, | ||
89 | }, | ||
90 | [lm25066] = { | ||
91 | [PSC_VOLTAGE_IN] = { | ||
92 | .m = 22070, | ||
93 | .R = -2, | ||
94 | }, | ||
95 | [PSC_VOLTAGE_OUT] = { | ||
96 | .m = 22070, | ||
97 | .R = -2, | ||
98 | }, | ||
99 | [PSC_CURRENT_IN] = { | ||
100 | .m = 13661, | ||
101 | .R = -2, | ||
102 | }, | ||
103 | [PSC_CURRENT_IN_L] = { | ||
104 | .m = 6852, | ||
105 | .R = -2, | ||
106 | }, | ||
107 | [PSC_POWER] = { | ||
108 | .m = 736, | ||
109 | .R = -2, | ||
110 | }, | ||
111 | [PSC_POWER_L] = { | ||
112 | .m = 369, | ||
113 | .R = -2, | ||
114 | }, | ||
115 | [PSC_TEMPERATURE] = { | ||
116 | .m = 16, | ||
117 | }, | ||
118 | }, | ||
119 | [lm5064] = { | ||
120 | [PSC_VOLTAGE_IN] = { | ||
121 | .m = 4611, | ||
122 | .R = -2, | ||
123 | }, | ||
124 | [PSC_VOLTAGE_OUT] = { | ||
125 | .m = 4621, | ||
126 | .R = -2, | ||
127 | }, | ||
128 | [PSC_CURRENT_IN] = { | ||
129 | .m = 10742, | ||
130 | .R = -2, | ||
131 | }, | ||
132 | [PSC_CURRENT_IN_L] = { | ||
133 | .m = 5456, | ||
134 | .R = -2, | ||
135 | }, | ||
136 | [PSC_POWER] = { | ||
137 | .m = 1204, | ||
138 | .R = -3, | ||
139 | }, | ||
140 | [PSC_POWER_L] = { | ||
141 | .m = 612, | ||
142 | .R = -3, | ||
143 | }, | ||
144 | [PSC_TEMPERATURE] = { | ||
145 | .m = 16, | ||
146 | }, | ||
147 | }, | ||
148 | [lm5066] = { | ||
149 | [PSC_VOLTAGE_IN] = { | ||
150 | .m = 4587, | ||
151 | .R = -2, | ||
152 | }, | ||
153 | [PSC_VOLTAGE_OUT] = { | ||
154 | .m = 4587, | ||
155 | .R = -2, | ||
156 | }, | ||
157 | [PSC_CURRENT_IN] = { | ||
158 | .m = 10753, | ||
159 | .R = -2, | ||
160 | }, | ||
161 | [PSC_CURRENT_IN_L] = { | ||
162 | .m = 5405, | ||
163 | .R = -2, | ||
164 | }, | ||
165 | [PSC_POWER] = { | ||
166 | .m = 1204, | ||
167 | .R = -3, | ||
168 | }, | ||
169 | [PSC_POWER_L] = { | ||
170 | .m = 605, | ||
171 | .R = -3, | ||
172 | }, | ||
173 | [PSC_TEMPERATURE] = { | ||
174 | .m = 16, | ||
175 | }, | ||
176 | }, | ||
177 | }; | ||
178 | |||
46 | struct lm25066_data { | 179 | struct lm25066_data { |
47 | int id; | 180 | int id; |
48 | struct pmbus_driver_info info; | 181 | struct pmbus_driver_info info; |
@@ -56,42 +189,31 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | |||
56 | const struct lm25066_data *data = to_lm25066_data(info); | 189 | const struct lm25066_data *data = to_lm25066_data(info); |
57 | int ret; | 190 | int ret; |
58 | 191 | ||
59 | if (page > 1) | 192 | switch (reg) { |
60 | return -ENXIO; | 193 | case PMBUS_VIRT_READ_VMON: |
61 | 194 | ret = pmbus_read_word_data(client, 0, LM25066_READ_VAUX); | |
62 | /* Map READ_VAUX into READ_VOUT register on page 1 */ | 195 | if (ret < 0) |
63 | if (page == 1) { | 196 | break; |
64 | switch (reg) { | 197 | /* Adjust returned value to match VIN coefficients */ |
65 | case PMBUS_READ_VOUT: | 198 | switch (data->id) { |
66 | ret = pmbus_read_word_data(client, 0, | 199 | case lm25056: |
67 | LM25066_READ_VAUX); | 200 | /* VIN: 6.14 mV VAUX: 293 uV LSB */ |
68 | if (ret < 0) | 201 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); |
69 | break; | ||
70 | /* Adjust returned value to match VOUT coefficients */ | ||
71 | switch (data->id) { | ||
72 | case lm25066: | ||
73 | /* VOUT: 4.54 mV VAUX: 283.2 uV LSB */ | ||
74 | ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); | ||
75 | break; | ||
76 | case lm5064: | ||
77 | /* VOUT: 4.53 mV VAUX: 700 uV LSB */ | ||
78 | ret = DIV_ROUND_CLOSEST(ret * 70, 453); | ||
79 | break; | ||
80 | case lm5066: | ||
81 | /* VOUT: 2.18 mV VAUX: 725 uV LSB */ | ||
82 | ret = DIV_ROUND_CLOSEST(ret * 725, 2180); | ||
83 | break; | ||
84 | } | ||
85 | break; | 202 | break; |
86 | default: | 203 | case lm25066: |
87 | /* No other valid registers on page 1 */ | 204 | /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ |
88 | ret = -ENXIO; | 205 | ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); |
206 | break; | ||
207 | case lm5064: | ||
208 | /* VIN: 4.53 mV VAUX: 700 uV LSB */ | ||
209 | ret = DIV_ROUND_CLOSEST(ret * 70, 453); | ||
210 | break; | ||
211 | case lm5066: | ||
212 | /* VIN: 2.18 mV VAUX: 725 uV LSB */ | ||
213 | ret = DIV_ROUND_CLOSEST(ret * 725, 2180); | ||
89 | break; | 214 | break; |
90 | } | 215 | } |
91 | goto done; | 216 | break; |
92 | } | ||
93 | |||
94 | switch (reg) { | ||
95 | case PMBUS_READ_IIN: | 217 | case PMBUS_READ_IIN: |
96 | ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN); | 218 | ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN); |
97 | break; | 219 | break; |
@@ -128,7 +250,58 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | |||
128 | ret = -ENODATA; | 250 | ret = -ENODATA; |
129 | break; | 251 | break; |
130 | } | 252 | } |
131 | done: | 253 | return ret; |
254 | } | ||
255 | |||
256 | static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) | ||
257 | { | ||
258 | int ret; | ||
259 | |||
260 | switch (reg) { | ||
261 | case PMBUS_VIRT_VMON_UV_WARN_LIMIT: | ||
262 | ret = pmbus_read_word_data(client, 0, | ||
263 | LM25056_VAUX_UV_WARN_LIMIT); | ||
264 | if (ret < 0) | ||
265 | break; | ||
266 | /* Adjust returned value to match VIN coefficients */ | ||
267 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); | ||
268 | break; | ||
269 | case PMBUS_VIRT_VMON_OV_WARN_LIMIT: | ||
270 | ret = pmbus_read_word_data(client, 0, | ||
271 | LM25056_VAUX_OV_WARN_LIMIT); | ||
272 | if (ret < 0) | ||
273 | break; | ||
274 | /* Adjust returned value to match VIN coefficients */ | ||
275 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); | ||
276 | break; | ||
277 | default: | ||
278 | ret = lm25066_read_word_data(client, page, reg); | ||
279 | break; | ||
280 | } | ||
281 | return ret; | ||
282 | } | ||
283 | |||
284 | static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg) | ||
285 | { | ||
286 | int ret, s; | ||
287 | |||
288 | switch (reg) { | ||
289 | case PMBUS_VIRT_STATUS_VMON: | ||
290 | ret = pmbus_read_byte_data(client, 0, | ||
291 | PMBUS_STATUS_MFR_SPECIFIC); | ||
292 | if (ret < 0) | ||
293 | break; | ||
294 | s = 0; | ||
295 | if (ret & LM25056_MFR_STS_VAUX_UV_WARN) | ||
296 | s |= PB_VOLTAGE_UV_WARNING; | ||
297 | if (ret & LM25056_MFR_STS_VAUX_OV_WARN) | ||
298 | s |= PB_VOLTAGE_OV_WARNING; | ||
299 | ret = s; | ||
300 | break; | ||
301 | default: | ||
302 | ret = -ENODATA; | ||
303 | break; | ||
304 | } | ||
132 | return ret; | 305 | return ret; |
133 | } | 306 | } |
134 | 307 | ||
@@ -137,19 +310,45 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | |||
137 | { | 310 | { |
138 | int ret; | 311 | int ret; |
139 | 312 | ||
140 | if (page > 1) | ||
141 | return -ENXIO; | ||
142 | |||
143 | switch (reg) { | 313 | switch (reg) { |
314 | case PMBUS_VOUT_UV_WARN_LIMIT: | ||
315 | case PMBUS_OT_FAULT_LIMIT: | ||
316 | case PMBUS_OT_WARN_LIMIT: | ||
317 | case PMBUS_VIN_UV_WARN_LIMIT: | ||
318 | case PMBUS_VIN_OV_WARN_LIMIT: | ||
319 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | ||
320 | ret = pmbus_write_word_data(client, 0, reg, word); | ||
321 | pmbus_clear_cache(client); | ||
322 | break; | ||
144 | case PMBUS_IIN_OC_WARN_LIMIT: | 323 | case PMBUS_IIN_OC_WARN_LIMIT: |
324 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | ||
145 | ret = pmbus_write_word_data(client, 0, | 325 | ret = pmbus_write_word_data(client, 0, |
146 | LM25066_MFR_IIN_OC_WARN_LIMIT, | 326 | LM25066_MFR_IIN_OC_WARN_LIMIT, |
147 | word); | 327 | word); |
328 | pmbus_clear_cache(client); | ||
148 | break; | 329 | break; |
149 | case PMBUS_PIN_OP_WARN_LIMIT: | 330 | case PMBUS_PIN_OP_WARN_LIMIT: |
331 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | ||
150 | ret = pmbus_write_word_data(client, 0, | 332 | ret = pmbus_write_word_data(client, 0, |
151 | LM25066_MFR_PIN_OP_WARN_LIMIT, | 333 | LM25066_MFR_PIN_OP_WARN_LIMIT, |
152 | word); | 334 | word); |
335 | pmbus_clear_cache(client); | ||
336 | break; | ||
337 | case PMBUS_VIRT_VMON_UV_WARN_LIMIT: | ||
338 | /* Adjust from VIN coefficients (for LM25056) */ | ||
339 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); | ||
340 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | ||
341 | ret = pmbus_write_word_data(client, 0, | ||
342 | LM25056_VAUX_UV_WARN_LIMIT, word); | ||
343 | pmbus_clear_cache(client); | ||
344 | break; | ||
345 | case PMBUS_VIRT_VMON_OV_WARN_LIMIT: | ||
346 | /* Adjust from VIN coefficients (for LM25056) */ | ||
347 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); | ||
348 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | ||
349 | ret = pmbus_write_word_data(client, 0, | ||
350 | LM25056_VAUX_OV_WARN_LIMIT, word); | ||
351 | pmbus_clear_cache(client); | ||
153 | break; | 352 | break; |
154 | case PMBUS_VIRT_RESET_PIN_HISTORY: | 353 | case PMBUS_VIRT_RESET_PIN_HISTORY: |
155 | ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK); | 354 | ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK); |
@@ -161,23 +360,13 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | |||
161 | return ret; | 360 | return ret; |
162 | } | 361 | } |
163 | 362 | ||
164 | static int lm25066_write_byte(struct i2c_client *client, int page, u8 value) | ||
165 | { | ||
166 | if (page > 1) | ||
167 | return -ENXIO; | ||
168 | |||
169 | if (page <= 0) | ||
170 | return pmbus_write_byte(client, page, value); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int lm25066_probe(struct i2c_client *client, | 363 | static int lm25066_probe(struct i2c_client *client, |
176 | const struct i2c_device_id *id) | 364 | const struct i2c_device_id *id) |
177 | { | 365 | { |
178 | int config; | 366 | int config; |
179 | struct lm25066_data *data; | 367 | struct lm25066_data *data; |
180 | struct pmbus_driver_info *info; | 368 | struct pmbus_driver_info *info; |
369 | struct __coeff *coeff; | ||
181 | 370 | ||
182 | if (!i2c_check_functionality(client->adapter, | 371 | if (!i2c_check_functionality(client->adapter, |
183 | I2C_FUNC_SMBUS_READ_BYTE_DATA)) | 372 | I2C_FUNC_SMBUS_READ_BYTE_DATA)) |
@@ -195,107 +384,54 @@ static int lm25066_probe(struct i2c_client *client, | |||
195 | data->id = id->driver_data; | 384 | data->id = id->driver_data; |
196 | info = &data->info; | 385 | info = &data->info; |
197 | 386 | ||
198 | info->pages = 2; | 387 | info->pages = 1; |
199 | info->format[PSC_VOLTAGE_IN] = direct; | 388 | info->format[PSC_VOLTAGE_IN] = direct; |
200 | info->format[PSC_VOLTAGE_OUT] = direct; | 389 | info->format[PSC_VOLTAGE_OUT] = direct; |
201 | info->format[PSC_CURRENT_IN] = direct; | 390 | info->format[PSC_CURRENT_IN] = direct; |
202 | info->format[PSC_TEMPERATURE] = direct; | 391 | info->format[PSC_TEMPERATURE] = direct; |
203 | info->format[PSC_POWER] = direct; | 392 | info->format[PSC_POWER] = direct; |
204 | 393 | ||
205 | info->m[PSC_TEMPERATURE] = 16; | 394 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VMON |
206 | info->b[PSC_TEMPERATURE] = 0; | 395 | | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT |
207 | info->R[PSC_TEMPERATURE] = 0; | 396 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; |
208 | 397 | ||
209 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | 398 | if (data->id == lm25056) { |
210 | | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | 399 | info->func[0] |= PMBUS_HAVE_STATUS_VMON; |
211 | | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | 400 | info->read_word_data = lm25056_read_word_data; |
212 | info->func[1] = PMBUS_HAVE_VOUT; | 401 | info->read_byte_data = lm25056_read_byte_data; |
213 | 402 | } else { | |
214 | info->read_word_data = lm25066_read_word_data; | 403 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; |
404 | info->read_word_data = lm25066_read_word_data; | ||
405 | } | ||
215 | info->write_word_data = lm25066_write_word_data; | 406 | info->write_word_data = lm25066_write_word_data; |
216 | info->write_byte = lm25066_write_byte; | 407 | |
217 | 408 | coeff = &lm25066_coeff[data->id][0]; | |
218 | switch (id->driver_data) { | 409 | info->m[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].m; |
219 | case lm25066: | 410 | info->b[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].b; |
220 | info->m[PSC_VOLTAGE_IN] = 22070; | 411 | info->R[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].R; |
221 | info->b[PSC_VOLTAGE_IN] = 0; | 412 | info->m[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].m; |
222 | info->R[PSC_VOLTAGE_IN] = -2; | 413 | info->b[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].b; |
223 | info->m[PSC_VOLTAGE_OUT] = 22070; | 414 | info->R[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].R; |
224 | info->b[PSC_VOLTAGE_OUT] = 0; | 415 | info->m[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].m; |
225 | info->R[PSC_VOLTAGE_OUT] = -2; | 416 | info->b[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].b; |
226 | 417 | info->R[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].R; | |
227 | if (config & LM25066_DEV_SETUP_CL) { | 418 | info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].b; |
228 | info->m[PSC_CURRENT_IN] = 6852; | 419 | info->R[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].R; |
229 | info->b[PSC_CURRENT_IN] = 0; | 420 | info->b[PSC_POWER] = coeff[PSC_POWER].b; |
230 | info->R[PSC_CURRENT_IN] = -2; | 421 | info->R[PSC_POWER] = coeff[PSC_POWER].R; |
231 | info->m[PSC_POWER] = 369; | 422 | if (config & LM25066_DEV_SETUP_CL) { |
232 | info->b[PSC_POWER] = 0; | 423 | info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].m; |
233 | info->R[PSC_POWER] = -2; | 424 | info->m[PSC_POWER] = coeff[PSC_POWER_L].m; |
234 | } else { | 425 | } else { |
235 | info->m[PSC_CURRENT_IN] = 13661; | 426 | info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].m; |
236 | info->b[PSC_CURRENT_IN] = 0; | 427 | info->m[PSC_POWER] = coeff[PSC_POWER].m; |
237 | info->R[PSC_CURRENT_IN] = -2; | ||
238 | info->m[PSC_POWER] = 736; | ||
239 | info->b[PSC_POWER] = 0; | ||
240 | info->R[PSC_POWER] = -2; | ||
241 | } | ||
242 | break; | ||
243 | case lm5064: | ||
244 | info->m[PSC_VOLTAGE_IN] = 22075; | ||
245 | info->b[PSC_VOLTAGE_IN] = 0; | ||
246 | info->R[PSC_VOLTAGE_IN] = -2; | ||
247 | info->m[PSC_VOLTAGE_OUT] = 22075; | ||
248 | info->b[PSC_VOLTAGE_OUT] = 0; | ||
249 | info->R[PSC_VOLTAGE_OUT] = -2; | ||
250 | |||
251 | if (config & LM25066_DEV_SETUP_CL) { | ||
252 | info->m[PSC_CURRENT_IN] = 6713; | ||
253 | info->b[PSC_CURRENT_IN] = 0; | ||
254 | info->R[PSC_CURRENT_IN] = -2; | ||
255 | info->m[PSC_POWER] = 3619; | ||
256 | info->b[PSC_POWER] = 0; | ||
257 | info->R[PSC_POWER] = -3; | ||
258 | } else { | ||
259 | info->m[PSC_CURRENT_IN] = 13426; | ||
260 | info->b[PSC_CURRENT_IN] = 0; | ||
261 | info->R[PSC_CURRENT_IN] = -2; | ||
262 | info->m[PSC_POWER] = 7238; | ||
263 | info->b[PSC_POWER] = 0; | ||
264 | info->R[PSC_POWER] = -3; | ||
265 | } | ||
266 | break; | ||
267 | case lm5066: | ||
268 | info->m[PSC_VOLTAGE_IN] = 4587; | ||
269 | info->b[PSC_VOLTAGE_IN] = 0; | ||
270 | info->R[PSC_VOLTAGE_IN] = -2; | ||
271 | info->m[PSC_VOLTAGE_OUT] = 4587; | ||
272 | info->b[PSC_VOLTAGE_OUT] = 0; | ||
273 | info->R[PSC_VOLTAGE_OUT] = -2; | ||
274 | |||
275 | if (config & LM25066_DEV_SETUP_CL) { | ||
276 | info->m[PSC_CURRENT_IN] = 10753; | ||
277 | info->b[PSC_CURRENT_IN] = 0; | ||
278 | info->R[PSC_CURRENT_IN] = -2; | ||
279 | info->m[PSC_POWER] = 1204; | ||
280 | info->b[PSC_POWER] = 0; | ||
281 | info->R[PSC_POWER] = -3; | ||
282 | } else { | ||
283 | info->m[PSC_CURRENT_IN] = 5405; | ||
284 | info->b[PSC_CURRENT_IN] = 0; | ||
285 | info->R[PSC_CURRENT_IN] = -2; | ||
286 | info->m[PSC_POWER] = 605; | ||
287 | info->b[PSC_POWER] = 0; | ||
288 | info->R[PSC_POWER] = -3; | ||
289 | } | ||
290 | break; | ||
291 | default: | ||
292 | return -ENODEV; | ||
293 | } | 428 | } |
294 | 429 | ||
295 | return pmbus_do_probe(client, id, info); | 430 | return pmbus_do_probe(client, id, info); |
296 | } | 431 | } |
297 | 432 | ||
298 | static const struct i2c_device_id lm25066_id[] = { | 433 | static const struct i2c_device_id lm25066_id[] = { |
434 | {"lm25056", lm25056}, | ||
299 | {"lm25066", lm25066}, | 435 | {"lm25066", lm25066}, |
300 | {"lm5064", lm5064}, | 436 | {"lm5064", lm5064}, |
301 | {"lm5066", lm5066}, | 437 | {"lm5066", lm5066}, |
@@ -317,5 +453,5 @@ static struct i2c_driver lm25066_driver = { | |||
317 | module_i2c_driver(lm25066_driver); | 453 | module_i2c_driver(lm25066_driver); |
318 | 454 | ||
319 | MODULE_AUTHOR("Guenter Roeck"); | 455 | MODULE_AUTHOR("Guenter Roeck"); |
320 | MODULE_DESCRIPTION("PMBus driver for LM25066/LM5064/LM5066"); | 456 | MODULE_DESCRIPTION("PMBus driver for LM25056/LM25066/LM5064/LM5066"); |
321 | MODULE_LICENSE("GPL"); | 457 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index 6d6130752f94..586a89ef9e0f 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Hardware monitoring driver for LTC2978 and LTC3880 | 2 | * Hardware monitoring driver for LTC2974, LTC2978, LTC3880, and LTC3883 |
3 | * | 3 | * |
4 | * Copyright (c) 2011 Ericsson AB. | 4 | * Copyright (c) 2011 Ericsson AB. |
5 | * Copyright (c) 2013 Guenter Roeck | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -26,28 +27,43 @@ | |||
26 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
27 | #include "pmbus.h" | 28 | #include "pmbus.h" |
28 | 29 | ||
29 | enum chips { ltc2978, ltc3880 }; | 30 | enum chips { ltc2974, ltc2978, ltc3880, ltc3883 }; |
30 | 31 | ||
31 | /* LTC2978 and LTC3880 */ | 32 | /* Common for all chips */ |
32 | #define LTC2978_MFR_VOUT_PEAK 0xdd | 33 | #define LTC2978_MFR_VOUT_PEAK 0xdd |
33 | #define LTC2978_MFR_VIN_PEAK 0xde | 34 | #define LTC2978_MFR_VIN_PEAK 0xde |
34 | #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf | 35 | #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf |
35 | #define LTC2978_MFR_SPECIAL_ID 0xe7 | 36 | #define LTC2978_MFR_SPECIAL_ID 0xe7 |
36 | 37 | ||
37 | /* LTC2978 only */ | 38 | /* LTC2974 and LTC2978 */ |
38 | #define LTC2978_MFR_VOUT_MIN 0xfb | 39 | #define LTC2978_MFR_VOUT_MIN 0xfb |
39 | #define LTC2978_MFR_VIN_MIN 0xfc | 40 | #define LTC2978_MFR_VIN_MIN 0xfc |
40 | #define LTC2978_MFR_TEMPERATURE_MIN 0xfd | 41 | #define LTC2978_MFR_TEMPERATURE_MIN 0xfd |
41 | 42 | ||
42 | /* LTC3880 only */ | 43 | /* LTC2974 only */ |
44 | #define LTC2974_MFR_IOUT_PEAK 0xd7 | ||
45 | #define LTC2974_MFR_IOUT_MIN 0xd8 | ||
46 | |||
47 | /* LTC3880 and LTC3883 */ | ||
43 | #define LTC3880_MFR_IOUT_PEAK 0xd7 | 48 | #define LTC3880_MFR_IOUT_PEAK 0xd7 |
44 | #define LTC3880_MFR_CLEAR_PEAKS 0xe3 | 49 | #define LTC3880_MFR_CLEAR_PEAKS 0xe3 |
45 | #define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4 | 50 | #define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4 |
46 | 51 | ||
52 | /* LTC3883 only */ | ||
53 | #define LTC3883_MFR_IIN_PEAK 0xe1 | ||
54 | |||
55 | #define LTC2974_ID 0x0212 | ||
47 | #define LTC2978_ID_REV1 0x0121 | 56 | #define LTC2978_ID_REV1 0x0121 |
48 | #define LTC2978_ID_REV2 0x0122 | 57 | #define LTC2978_ID_REV2 0x0122 |
49 | #define LTC3880_ID 0x4000 | 58 | #define LTC3880_ID 0x4000 |
50 | #define LTC3880_ID_MASK 0xff00 | 59 | #define LTC3880_ID_MASK 0xff00 |
60 | #define LTC3883_ID 0x4300 | ||
61 | #define LTC3883_ID_MASK 0xff00 | ||
62 | |||
63 | #define LTC2974_NUM_PAGES 4 | ||
64 | #define LTC2978_NUM_PAGES 8 | ||
65 | #define LTC3880_NUM_PAGES 2 | ||
66 | #define LTC3883_NUM_PAGES 1 | ||
51 | 67 | ||
52 | /* | 68 | /* |
53 | * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which | 69 | * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which |
@@ -56,13 +72,15 @@ enum chips { ltc2978, ltc3880 }; | |||
56 | * internal cache of measured peak data, which is only cleared if an explicit | 72 | * internal cache of measured peak data, which is only cleared if an explicit |
57 | * "clear peak" command is executed for the sensor in question. | 73 | * "clear peak" command is executed for the sensor in question. |
58 | */ | 74 | */ |
75 | |||
59 | struct ltc2978_data { | 76 | struct ltc2978_data { |
60 | enum chips id; | 77 | enum chips id; |
61 | int vin_min, vin_max; | 78 | u16 vin_min, vin_max; |
62 | int temp_min, temp_max[2]; | 79 | u16 temp_min[LTC2974_NUM_PAGES], temp_max[LTC2974_NUM_PAGES]; |
63 | int vout_min[8], vout_max[8]; | 80 | u16 vout_min[LTC2978_NUM_PAGES], vout_max[LTC2978_NUM_PAGES]; |
64 | int iout_max[2]; | 81 | u16 iout_min[LTC2974_NUM_PAGES], iout_max[LTC2974_NUM_PAGES]; |
65 | int temp2_max; | 82 | u16 iin_max; |
83 | u16 temp2_max; | ||
66 | struct pmbus_driver_info info; | 84 | struct pmbus_driver_info info; |
67 | }; | 85 | }; |
68 | 86 | ||
@@ -167,9 +185,9 @@ static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg) | |||
167 | LTC2978_MFR_TEMPERATURE_MIN); | 185 | LTC2978_MFR_TEMPERATURE_MIN); |
168 | if (ret >= 0) { | 186 | if (ret >= 0) { |
169 | if (lin11_to_val(ret) | 187 | if (lin11_to_val(ret) |
170 | < lin11_to_val(data->temp_min)) | 188 | < lin11_to_val(data->temp_min[page])) |
171 | data->temp_min = ret; | 189 | data->temp_min[page] = ret; |
172 | ret = data->temp_min; | 190 | ret = data->temp_min[page]; |
173 | } | 191 | } |
174 | break; | 192 | break; |
175 | case PMBUS_VIRT_READ_IOUT_MAX: | 193 | case PMBUS_VIRT_READ_IOUT_MAX: |
@@ -185,6 +203,41 @@ static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg) | |||
185 | return ret; | 203 | return ret; |
186 | } | 204 | } |
187 | 205 | ||
206 | static int ltc2974_read_word_data(struct i2c_client *client, int page, int reg) | ||
207 | { | ||
208 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
209 | struct ltc2978_data *data = to_ltc2978_data(info); | ||
210 | int ret; | ||
211 | |||
212 | switch (reg) { | ||
213 | case PMBUS_VIRT_READ_IOUT_MAX: | ||
214 | ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_PEAK); | ||
215 | if (ret >= 0) { | ||
216 | if (lin11_to_val(ret) | ||
217 | > lin11_to_val(data->iout_max[page])) | ||
218 | data->iout_max[page] = ret; | ||
219 | ret = data->iout_max[page]; | ||
220 | } | ||
221 | break; | ||
222 | case PMBUS_VIRT_READ_IOUT_MIN: | ||
223 | ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_MIN); | ||
224 | if (ret >= 0) { | ||
225 | if (lin11_to_val(ret) | ||
226 | < lin11_to_val(data->iout_min[page])) | ||
227 | data->iout_min[page] = ret; | ||
228 | ret = data->iout_min[page]; | ||
229 | } | ||
230 | break; | ||
231 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | ||
232 | ret = 0; | ||
233 | break; | ||
234 | default: | ||
235 | ret = ltc2978_read_word_data(client, page, reg); | ||
236 | break; | ||
237 | } | ||
238 | return ret; | ||
239 | } | ||
240 | |||
188 | static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) | 241 | static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) |
189 | { | 242 | { |
190 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | 243 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
@@ -226,15 +279,41 @@ static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) | |||
226 | return ret; | 279 | return ret; |
227 | } | 280 | } |
228 | 281 | ||
282 | static int ltc3883_read_word_data(struct i2c_client *client, int page, int reg) | ||
283 | { | ||
284 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
285 | struct ltc2978_data *data = to_ltc2978_data(info); | ||
286 | int ret; | ||
287 | |||
288 | switch (reg) { | ||
289 | case PMBUS_VIRT_READ_IIN_MAX: | ||
290 | ret = pmbus_read_word_data(client, page, LTC3883_MFR_IIN_PEAK); | ||
291 | if (ret >= 0) { | ||
292 | if (lin11_to_val(ret) | ||
293 | > lin11_to_val(data->iin_max)) | ||
294 | data->iin_max = ret; | ||
295 | ret = data->iin_max; | ||
296 | } | ||
297 | break; | ||
298 | case PMBUS_VIRT_RESET_IIN_HISTORY: | ||
299 | ret = 0; | ||
300 | break; | ||
301 | default: | ||
302 | ret = ltc3880_read_word_data(client, page, reg); | ||
303 | break; | ||
304 | } | ||
305 | return ret; | ||
306 | } | ||
307 | |||
229 | static int ltc2978_clear_peaks(struct i2c_client *client, int page, | 308 | static int ltc2978_clear_peaks(struct i2c_client *client, int page, |
230 | enum chips id) | 309 | enum chips id) |
231 | { | 310 | { |
232 | int ret; | 311 | int ret; |
233 | 312 | ||
234 | if (id == ltc2978) | 313 | if (id == ltc3880 || id == ltc3883) |
235 | ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); | ||
236 | else | ||
237 | ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS); | 314 | ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS); |
315 | else | ||
316 | ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); | ||
238 | 317 | ||
239 | return ret; | 318 | return ret; |
240 | } | 319 | } |
@@ -247,8 +326,13 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, | |||
247 | int ret; | 326 | int ret; |
248 | 327 | ||
249 | switch (reg) { | 328 | switch (reg) { |
329 | case PMBUS_VIRT_RESET_IIN_HISTORY: | ||
330 | data->iin_max = 0x7c00; | ||
331 | ret = ltc2978_clear_peaks(client, page, data->id); | ||
332 | break; | ||
250 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | 333 | case PMBUS_VIRT_RESET_IOUT_HISTORY: |
251 | data->iout_max[page] = 0x7c00; | 334 | data->iout_max[page] = 0x7c00; |
335 | data->iout_min[page] = 0xfbff; | ||
252 | ret = ltc2978_clear_peaks(client, page, data->id); | 336 | ret = ltc2978_clear_peaks(client, page, data->id); |
253 | break; | 337 | break; |
254 | case PMBUS_VIRT_RESET_TEMP2_HISTORY: | 338 | case PMBUS_VIRT_RESET_TEMP2_HISTORY: |
@@ -266,7 +350,7 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, | |||
266 | ret = ltc2978_clear_peaks(client, page, data->id); | 350 | ret = ltc2978_clear_peaks(client, page, data->id); |
267 | break; | 351 | break; |
268 | case PMBUS_VIRT_RESET_TEMP_HISTORY: | 352 | case PMBUS_VIRT_RESET_TEMP_HISTORY: |
269 | data->temp_min = 0x7bff; | 353 | data->temp_min[page] = 0x7bff; |
270 | data->temp_max[page] = 0x7c00; | 354 | data->temp_max[page] = 0x7c00; |
271 | ret = ltc2978_clear_peaks(client, page, data->id); | 355 | ret = ltc2978_clear_peaks(client, page, data->id); |
272 | break; | 356 | break; |
@@ -278,8 +362,10 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, | |||
278 | } | 362 | } |
279 | 363 | ||
280 | static const struct i2c_device_id ltc2978_id[] = { | 364 | static const struct i2c_device_id ltc2978_id[] = { |
365 | {"ltc2974", ltc2974}, | ||
281 | {"ltc2978", ltc2978}, | 366 | {"ltc2978", ltc2978}, |
282 | {"ltc3880", ltc3880}, | 367 | {"ltc3880", ltc3880}, |
368 | {"ltc3883", ltc3883}, | ||
283 | {} | 369 | {} |
284 | }; | 370 | }; |
285 | MODULE_DEVICE_TABLE(i2c, ltc2978_id); | 371 | MODULE_DEVICE_TABLE(i2c, ltc2978_id); |
@@ -304,10 +390,14 @@ static int ltc2978_probe(struct i2c_client *client, | |||
304 | if (chip_id < 0) | 390 | if (chip_id < 0) |
305 | return chip_id; | 391 | return chip_id; |
306 | 392 | ||
307 | if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) { | 393 | if (chip_id == LTC2974_ID) { |
394 | data->id = ltc2974; | ||
395 | } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) { | ||
308 | data->id = ltc2978; | 396 | data->id = ltc2978; |
309 | } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) { | 397 | } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) { |
310 | data->id = ltc3880; | 398 | data->id = ltc3880; |
399 | } else if ((chip_id & LTC3883_ID_MASK) == LTC3883_ID) { | ||
400 | data->id = ltc3883; | ||
311 | } else { | 401 | } else { |
312 | dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id); | 402 | dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id); |
313 | return -ENODEV; | 403 | return -ENODEV; |
@@ -323,26 +413,45 @@ static int ltc2978_probe(struct i2c_client *client, | |||
323 | 413 | ||
324 | data->vin_min = 0x7bff; | 414 | data->vin_min = 0x7bff; |
325 | data->vin_max = 0x7c00; | 415 | data->vin_max = 0x7c00; |
326 | data->temp_min = 0x7bff; | 416 | for (i = 0; i < ARRAY_SIZE(data->vout_min); i++) |
417 | data->vout_min[i] = 0xffff; | ||
418 | for (i = 0; i < ARRAY_SIZE(data->iout_min); i++) | ||
419 | data->iout_min[i] = 0xfbff; | ||
420 | for (i = 0; i < ARRAY_SIZE(data->iout_max); i++) | ||
421 | data->iout_max[i] = 0x7c00; | ||
422 | for (i = 0; i < ARRAY_SIZE(data->temp_min); i++) | ||
423 | data->temp_min[i] = 0x7bff; | ||
327 | for (i = 0; i < ARRAY_SIZE(data->temp_max); i++) | 424 | for (i = 0; i < ARRAY_SIZE(data->temp_max); i++) |
328 | data->temp_max[i] = 0x7c00; | 425 | data->temp_max[i] = 0x7c00; |
329 | data->temp2_max = 0x7c00; | 426 | data->temp2_max = 0x7c00; |
330 | 427 | ||
331 | switch (data->id) { | 428 | switch (data->id) { |
429 | case ltc2974: | ||
430 | info->read_word_data = ltc2974_read_word_data; | ||
431 | info->pages = LTC2974_NUM_PAGES; | ||
432 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | ||
433 | | PMBUS_HAVE_TEMP2; | ||
434 | for (i = 0; i < info->pages; i++) { | ||
435 | info->func[i] |= PMBUS_HAVE_VOUT | ||
436 | | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT | ||
437 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | ||
438 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; | ||
439 | } | ||
440 | break; | ||
332 | case ltc2978: | 441 | case ltc2978: |
333 | info->read_word_data = ltc2978_read_word_data; | 442 | info->read_word_data = ltc2978_read_word_data; |
334 | info->pages = 8; | 443 | info->pages = LTC2978_NUM_PAGES; |
335 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | 444 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
336 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 445 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
337 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | 446 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; |
338 | for (i = 1; i < 8; i++) { | 447 | for (i = 1; i < LTC2978_NUM_PAGES; i++) { |
339 | info->func[i] = PMBUS_HAVE_VOUT | 448 | info->func[i] = PMBUS_HAVE_VOUT |
340 | | PMBUS_HAVE_STATUS_VOUT; | 449 | | PMBUS_HAVE_STATUS_VOUT; |
341 | } | 450 | } |
342 | break; | 451 | break; |
343 | case ltc3880: | 452 | case ltc3880: |
344 | info->read_word_data = ltc3880_read_word_data; | 453 | info->read_word_data = ltc3880_read_word_data; |
345 | info->pages = 2; | 454 | info->pages = LTC3880_NUM_PAGES; |
346 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | 455 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN |
347 | | PMBUS_HAVE_STATUS_INPUT | 456 | | PMBUS_HAVE_STATUS_INPUT |
348 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 457 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
@@ -353,15 +462,20 @@ static int ltc2978_probe(struct i2c_client *client, | |||
353 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 462 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
354 | | PMBUS_HAVE_POUT | 463 | | PMBUS_HAVE_POUT |
355 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | 464 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; |
356 | data->iout_max[0] = 0x7c00; | 465 | break; |
357 | data->iout_max[1] = 0x7c00; | 466 | case ltc3883: |
467 | info->read_word_data = ltc3883_read_word_data; | ||
468 | info->pages = LTC3883_NUM_PAGES; | ||
469 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | ||
470 | | PMBUS_HAVE_STATUS_INPUT | ||
471 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
472 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | ||
473 | | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | ||
474 | | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; | ||
358 | break; | 475 | break; |
359 | default: | 476 | default: |
360 | return -ENODEV; | 477 | return -ENODEV; |
361 | } | 478 | } |
362 | for (i = 0; i < info->pages; i++) | ||
363 | data->vout_min[i] = 0xffff; | ||
364 | |||
365 | return pmbus_do_probe(client, id, info); | 479 | return pmbus_do_probe(client, id, info); |
366 | } | 480 | } |
367 | 481 | ||
@@ -378,5 +492,5 @@ static struct i2c_driver ltc2978_driver = { | |||
378 | module_i2c_driver(ltc2978_driver); | 492 | module_i2c_driver(ltc2978_driver); |
379 | 493 | ||
380 | MODULE_AUTHOR("Guenter Roeck"); | 494 | MODULE_AUTHOR("Guenter Roeck"); |
381 | MODULE_DESCRIPTION("PMBus driver for LTC2978 and LTC3880"); | 495 | MODULE_DESCRIPTION("PMBus driver for LTC2974, LTC2978, LTC3880, and LTC3883"); |
382 | MODULE_LICENSE("GPL"); | 496 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c index ff2ae0252a48..a9f7e804f1e4 100644 --- a/drivers/hwmon/s3c-hwmon.c +++ b/drivers/hwmon/s3c-hwmon.c | |||
@@ -107,17 +107,14 @@ static ssize_t s3c_hwmon_show_raw(struct device *dev, | |||
107 | return (ret < 0) ? ret : snprintf(buf, PAGE_SIZE, "%d\n", ret); | 107 | return (ret < 0) ? ret : snprintf(buf, PAGE_SIZE, "%d\n", ret); |
108 | } | 108 | } |
109 | 109 | ||
110 | #define DEF_ADC_ATTR(x) \ | 110 | static SENSOR_DEVICE_ATTR(adc0_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 0); |
111 | static SENSOR_DEVICE_ATTR(adc##x##_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, x) | 111 | static SENSOR_DEVICE_ATTR(adc1_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 1); |
112 | 112 | static SENSOR_DEVICE_ATTR(adc2_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 2); | |
113 | DEF_ADC_ATTR(0); | 113 | static SENSOR_DEVICE_ATTR(adc3_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 3); |
114 | DEF_ADC_ATTR(1); | 114 | static SENSOR_DEVICE_ATTR(adc4_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 4); |
115 | DEF_ADC_ATTR(2); | 115 | static SENSOR_DEVICE_ATTR(adc5_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 5); |
116 | DEF_ADC_ATTR(3); | 116 | static SENSOR_DEVICE_ATTR(adc6_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 6); |
117 | DEF_ADC_ATTR(4); | 117 | static SENSOR_DEVICE_ATTR(adc7_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 7); |
118 | DEF_ADC_ATTR(5); | ||
119 | DEF_ADC_ATTR(6); | ||
120 | DEF_ADC_ATTR(7); | ||
121 | 118 | ||
122 | static struct attribute *s3c_hwmon_attrs[9] = { | 119 | static struct attribute *s3c_hwmon_attrs[9] = { |
123 | &sensor_dev_attr_adc0_raw.dev_attr.attr, | 120 | &sensor_dev_attr_adc0_raw.dev_attr.attr, |
diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c index d00b30adc34b..738681983284 100644 --- a/drivers/hwmon/sch56xx-common.c +++ b/drivers/hwmon/sch56xx-common.c | |||
@@ -161,8 +161,8 @@ static int sch56xx_send_cmd(u16 addr, u8 cmd, u16 reg, u8 v) | |||
161 | break; | 161 | break; |
162 | } | 162 | } |
163 | if (i == max_busy_polls + max_lazy_polls) { | 163 | if (i == max_busy_polls + max_lazy_polls) { |
164 | pr_err("Max retries exceeded reading virtual " | 164 | pr_err("Max retries exceeded reading virtual register 0x%04hx (%d)\n", |
165 | "register 0x%04hx (%d)\n", reg, 1); | 165 | reg, 1); |
166 | return -EIO; | 166 | return -EIO; |
167 | } | 167 | } |
168 | 168 | ||
@@ -178,12 +178,12 @@ static int sch56xx_send_cmd(u16 addr, u8 cmd, u16 reg, u8 v) | |||
178 | break; | 178 | break; |
179 | 179 | ||
180 | if (i == 0) | 180 | if (i == 0) |
181 | pr_warn("EC reports: 0x%02x reading virtual register " | 181 | pr_warn("EC reports: 0x%02x reading virtual register 0x%04hx\n", |
182 | "0x%04hx\n", (unsigned int)val, reg); | 182 | (unsigned int)val, reg); |
183 | } | 183 | } |
184 | if (i == max_busy_polls) { | 184 | if (i == max_busy_polls) { |
185 | pr_err("Max retries exceeded reading virtual " | 185 | pr_err("Max retries exceeded reading virtual register 0x%04hx (%d)\n", |
186 | "register 0x%04hx (%d)\n", reg, 2); | 186 | reg, 2); |
187 | return -EIO; | 187 | return -EIO; |
188 | } | 188 | } |
189 | 189 | ||
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index c35847a1a0a3..1404e6319deb 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c | |||
@@ -456,8 +456,9 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, | |||
456 | data->fan_div[nr] = 3; | 456 | data->fan_div[nr] = 3; |
457 | break; | 457 | break; |
458 | default: | 458 | default: |
459 | dev_err(dev, "fan_div value %ld not " | 459 | dev_err(dev, |
460 | "supported. Choose one of 1, 2, 4 or 8!\n", val); | 460 | "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", |
461 | val); | ||
461 | mutex_unlock(&data->update_lock); | 462 | mutex_unlock(&data->update_lock); |
462 | return -EINVAL; | 463 | return -EINVAL; |
463 | } | 464 | } |
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 4b59eb53b18a..db288db7d3e9 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c | |||
@@ -41,8 +41,8 @@ enum chips { thmc50, adm1022 }; | |||
41 | static unsigned short adm1022_temp3[16]; | 41 | static unsigned short adm1022_temp3[16]; |
42 | static unsigned int adm1022_temp3_num; | 42 | static unsigned int adm1022_temp3_num; |
43 | module_param_array(adm1022_temp3, ushort, &adm1022_temp3_num, 0); | 43 | module_param_array(adm1022_temp3, ushort, &adm1022_temp3_num, 0); |
44 | MODULE_PARM_DESC(adm1022_temp3, "List of adapter,address pairs " | 44 | MODULE_PARM_DESC(adm1022_temp3, |
45 | "to enable 3rd temperature (ADM1022 only)"); | 45 | "List of adapter,address pairs to enable 3rd temperature (ADM1022 only)"); |
46 | 46 | ||
47 | /* Many THMC50 constants specified below */ | 47 | /* Many THMC50 constants specified below */ |
48 | 48 | ||
@@ -312,8 +312,7 @@ static int thmc50_detect(struct i2c_client *client, | |||
312 | const char *type_name; | 312 | const char *type_name; |
313 | 313 | ||
314 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 314 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
315 | pr_debug("thmc50: detect failed, " | 315 | pr_debug("thmc50: detect failed, smbus byte data not supported!\n"); |
316 | "smbus byte data not supported!\n"); | ||
317 | return -ENODEV; | 316 | return -ENODEV; |
318 | } | 317 | } |
319 | 318 | ||
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 523dd89ba498..d7b47abf37fe 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c | |||
@@ -155,8 +155,8 @@ static int tmp102_probe(struct i2c_client *client, | |||
155 | 155 | ||
156 | if (!i2c_check_functionality(client->adapter, | 156 | if (!i2c_check_functionality(client->adapter, |
157 | I2C_FUNC_SMBUS_WORD_DATA)) { | 157 | I2C_FUNC_SMBUS_WORD_DATA)) { |
158 | dev_err(&client->dev, "adapter doesn't support SMBus word " | 158 | dev_err(&client->dev, |
159 | "transactions\n"); | 159 | "adapter doesn't support SMBus word transactions\n"); |
160 | return -ENODEV; | 160 | return -ENODEV; |
161 | } | 161 | } |
162 | 162 | ||
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index c85f6967ccc3..a478454f690f 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c | |||
@@ -5,6 +5,9 @@ | |||
5 | * Gabriel Konat, Sander Leget, Wouter Willems | 5 | * Gabriel Konat, Sander Leget, Wouter Willems |
6 | * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de> | 6 | * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de> |
7 | * | 7 | * |
8 | * Cleanup and support for TMP431 and TMP432 by Guenter Roeck | ||
9 | * Copyright (c) 2013 Guenter Roeck <linux@roeck-us.net> | ||
10 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation; either version 2 of the License, or |
@@ -30,6 +33,7 @@ | |||
30 | 33 | ||
31 | #include <linux/module.h> | 34 | #include <linux/module.h> |
32 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/bitops.h> | ||
33 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
34 | #include <linux/jiffies.h> | 38 | #include <linux/jiffies.h> |
35 | #include <linux/i2c.h> | 39 | #include <linux/i2c.h> |
@@ -40,9 +44,9 @@ | |||
40 | #include <linux/sysfs.h> | 44 | #include <linux/sysfs.h> |
41 | 45 | ||
42 | /* Addresses to scan */ | 46 | /* Addresses to scan */ |
43 | static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; | 47 | static const unsigned short normal_i2c[] = { 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; |
44 | 48 | ||
45 | enum chips { tmp401, tmp411 }; | 49 | enum chips { tmp401, tmp411, tmp431, tmp432 }; |
46 | 50 | ||
47 | /* | 51 | /* |
48 | * The TMP401 registers, note some registers have different addresses for | 52 | * The TMP401 registers, note some registers have different addresses for |
@@ -54,42 +58,84 @@ enum chips { tmp401, tmp411 }; | |||
54 | #define TMP401_CONVERSION_RATE_READ 0x04 | 58 | #define TMP401_CONVERSION_RATE_READ 0x04 |
55 | #define TMP401_CONVERSION_RATE_WRITE 0x0A | 59 | #define TMP401_CONVERSION_RATE_WRITE 0x0A |
56 | #define TMP401_TEMP_CRIT_HYST 0x21 | 60 | #define TMP401_TEMP_CRIT_HYST 0x21 |
57 | #define TMP401_CONSECUTIVE_ALERT 0x22 | ||
58 | #define TMP401_MANUFACTURER_ID_REG 0xFE | 61 | #define TMP401_MANUFACTURER_ID_REG 0xFE |
59 | #define TMP401_DEVICE_ID_REG 0xFF | 62 | #define TMP401_DEVICE_ID_REG 0xFF |
60 | #define TMP411_N_FACTOR_REG 0x18 | 63 | |
61 | 64 | static const u8 TMP401_TEMP_MSB_READ[6][2] = { | |
62 | static const u8 TMP401_TEMP_MSB[2] = { 0x00, 0x01 }; | 65 | { 0x00, 0x01 }, /* temp */ |
63 | static const u8 TMP401_TEMP_LSB[2] = { 0x15, 0x10 }; | 66 | { 0x06, 0x08 }, /* low limit */ |
64 | static const u8 TMP401_TEMP_LOW_LIMIT_MSB_READ[2] = { 0x06, 0x08 }; | 67 | { 0x05, 0x07 }, /* high limit */ |
65 | static const u8 TMP401_TEMP_LOW_LIMIT_MSB_WRITE[2] = { 0x0C, 0x0E }; | 68 | { 0x20, 0x19 }, /* therm (crit) limit */ |
66 | static const u8 TMP401_TEMP_LOW_LIMIT_LSB[2] = { 0x17, 0x14 }; | 69 | { 0x30, 0x34 }, /* lowest */ |
67 | static const u8 TMP401_TEMP_HIGH_LIMIT_MSB_READ[2] = { 0x05, 0x07 }; | 70 | { 0x32, 0x36 }, /* highest */ |
68 | static const u8 TMP401_TEMP_HIGH_LIMIT_MSB_WRITE[2] = { 0x0B, 0x0D }; | 71 | }; |
69 | static const u8 TMP401_TEMP_HIGH_LIMIT_LSB[2] = { 0x16, 0x13 }; | 72 | |
70 | /* These are called the THERM limit / hysteresis / mask in the datasheet */ | 73 | static const u8 TMP401_TEMP_MSB_WRITE[6][2] = { |
71 | static const u8 TMP401_TEMP_CRIT_LIMIT[2] = { 0x20, 0x19 }; | 74 | { 0, 0 }, /* temp (unused) */ |
72 | 75 | { 0x0C, 0x0E }, /* low limit */ | |
73 | static const u8 TMP411_TEMP_LOWEST_MSB[2] = { 0x30, 0x34 }; | 76 | { 0x0B, 0x0D }, /* high limit */ |
74 | static const u8 TMP411_TEMP_LOWEST_LSB[2] = { 0x31, 0x35 }; | 77 | { 0x20, 0x19 }, /* therm (crit) limit */ |
75 | static const u8 TMP411_TEMP_HIGHEST_MSB[2] = { 0x32, 0x36 }; | 78 | { 0x30, 0x34 }, /* lowest */ |
76 | static const u8 TMP411_TEMP_HIGHEST_LSB[2] = { 0x33, 0x37 }; | 79 | { 0x32, 0x36 }, /* highest */ |
80 | }; | ||
81 | |||
82 | static const u8 TMP401_TEMP_LSB[6][2] = { | ||
83 | { 0x15, 0x10 }, /* temp */ | ||
84 | { 0x17, 0x14 }, /* low limit */ | ||
85 | { 0x16, 0x13 }, /* high limit */ | ||
86 | { 0, 0 }, /* therm (crit) limit (unused) */ | ||
87 | { 0x31, 0x35 }, /* lowest */ | ||
88 | { 0x33, 0x37 }, /* highest */ | ||
89 | }; | ||
90 | |||
91 | static const u8 TMP432_TEMP_MSB_READ[4][3] = { | ||
92 | { 0x00, 0x01, 0x23 }, /* temp */ | ||
93 | { 0x06, 0x08, 0x16 }, /* low limit */ | ||
94 | { 0x05, 0x07, 0x15 }, /* high limit */ | ||
95 | { 0x20, 0x19, 0x1A }, /* therm (crit) limit */ | ||
96 | }; | ||
97 | |||
98 | static const u8 TMP432_TEMP_MSB_WRITE[4][3] = { | ||
99 | { 0, 0, 0 }, /* temp - unused */ | ||
100 | { 0x0C, 0x0E, 0x16 }, /* low limit */ | ||
101 | { 0x0B, 0x0D, 0x15 }, /* high limit */ | ||
102 | { 0x20, 0x19, 0x1A }, /* therm (crit) limit */ | ||
103 | }; | ||
104 | |||
105 | static const u8 TMP432_TEMP_LSB[3][3] = { | ||
106 | { 0x29, 0x10, 0x24 }, /* temp */ | ||
107 | { 0x3E, 0x14, 0x18 }, /* low limit */ | ||
108 | { 0x3D, 0x13, 0x17 }, /* high limit */ | ||
109 | }; | ||
110 | |||
111 | /* [0] = fault, [1] = low, [2] = high, [3] = therm/crit */ | ||
112 | static const u8 TMP432_STATUS_REG[] = { | ||
113 | 0x1b, 0x36, 0x35, 0x37 }; | ||
77 | 114 | ||
78 | /* Flags */ | 115 | /* Flags */ |
79 | #define TMP401_CONFIG_RANGE 0x04 | 116 | #define TMP401_CONFIG_RANGE BIT(2) |
80 | #define TMP401_CONFIG_SHUTDOWN 0x40 | 117 | #define TMP401_CONFIG_SHUTDOWN BIT(6) |
81 | #define TMP401_STATUS_LOCAL_CRIT 0x01 | 118 | #define TMP401_STATUS_LOCAL_CRIT BIT(0) |
82 | #define TMP401_STATUS_REMOTE_CRIT 0x02 | 119 | #define TMP401_STATUS_REMOTE_CRIT BIT(1) |
83 | #define TMP401_STATUS_REMOTE_OPEN 0x04 | 120 | #define TMP401_STATUS_REMOTE_OPEN BIT(2) |
84 | #define TMP401_STATUS_REMOTE_LOW 0x08 | 121 | #define TMP401_STATUS_REMOTE_LOW BIT(3) |
85 | #define TMP401_STATUS_REMOTE_HIGH 0x10 | 122 | #define TMP401_STATUS_REMOTE_HIGH BIT(4) |
86 | #define TMP401_STATUS_LOCAL_LOW 0x20 | 123 | #define TMP401_STATUS_LOCAL_LOW BIT(5) |
87 | #define TMP401_STATUS_LOCAL_HIGH 0x40 | 124 | #define TMP401_STATUS_LOCAL_HIGH BIT(6) |
125 | |||
126 | /* On TMP432, each status has its own register */ | ||
127 | #define TMP432_STATUS_LOCAL BIT(0) | ||
128 | #define TMP432_STATUS_REMOTE1 BIT(1) | ||
129 | #define TMP432_STATUS_REMOTE2 BIT(2) | ||
88 | 130 | ||
89 | /* Manufacturer / Device ID's */ | 131 | /* Manufacturer / Device ID's */ |
90 | #define TMP401_MANUFACTURER_ID 0x55 | 132 | #define TMP401_MANUFACTURER_ID 0x55 |
91 | #define TMP401_DEVICE_ID 0x11 | 133 | #define TMP401_DEVICE_ID 0x11 |
92 | #define TMP411_DEVICE_ID 0x12 | 134 | #define TMP411A_DEVICE_ID 0x12 |
135 | #define TMP411B_DEVICE_ID 0x13 | ||
136 | #define TMP411C_DEVICE_ID 0x10 | ||
137 | #define TMP431_DEVICE_ID 0x31 | ||
138 | #define TMP432_DEVICE_ID 0x32 | ||
93 | 139 | ||
94 | /* | 140 | /* |
95 | * Driver data (common to all clients) | 141 | * Driver data (common to all clients) |
@@ -98,6 +144,8 @@ static const u8 TMP411_TEMP_HIGHEST_LSB[2] = { 0x33, 0x37 }; | |||
98 | static const struct i2c_device_id tmp401_id[] = { | 144 | static const struct i2c_device_id tmp401_id[] = { |
99 | { "tmp401", tmp401 }, | 145 | { "tmp401", tmp401 }, |
100 | { "tmp411", tmp411 }, | 146 | { "tmp411", tmp411 }, |
147 | { "tmp431", tmp431 }, | ||
148 | { "tmp432", tmp432 }, | ||
101 | { } | 149 | { } |
102 | }; | 150 | }; |
103 | MODULE_DEVICE_TABLE(i2c, tmp401_id); | 151 | MODULE_DEVICE_TABLE(i2c, tmp401_id); |
@@ -113,16 +161,13 @@ struct tmp401_data { | |||
113 | unsigned long last_updated; /* in jiffies */ | 161 | unsigned long last_updated; /* in jiffies */ |
114 | enum chips kind; | 162 | enum chips kind; |
115 | 163 | ||
164 | unsigned int update_interval; /* in milliseconds */ | ||
165 | |||
116 | /* register values */ | 166 | /* register values */ |
117 | u8 status; | 167 | u8 status[4]; |
118 | u8 config; | 168 | u8 config; |
119 | u16 temp[2]; | 169 | u16 temp[6][3]; |
120 | u16 temp_low[2]; | ||
121 | u16 temp_high[2]; | ||
122 | u8 temp_crit[2]; | ||
123 | u8 temp_crit_hyst; | 170 | u8 temp_crit_hyst; |
124 | u16 temp_lowest[2]; | ||
125 | u16 temp_highest[2]; | ||
126 | }; | 171 | }; |
127 | 172 | ||
128 | /* | 173 | /* |
@@ -136,31 +181,10 @@ static int tmp401_register_to_temp(u16 reg, u8 config) | |||
136 | if (config & TMP401_CONFIG_RANGE) | 181 | if (config & TMP401_CONFIG_RANGE) |
137 | temp -= 64 * 256; | 182 | temp -= 64 * 256; |
138 | 183 | ||
139 | return (temp * 625 + 80) / 160; | 184 | return DIV_ROUND_CLOSEST(temp * 125, 32); |
140 | } | ||
141 | |||
142 | static u16 tmp401_temp_to_register(long temp, u8 config) | ||
143 | { | ||
144 | if (config & TMP401_CONFIG_RANGE) { | ||
145 | temp = clamp_val(temp, -64000, 191000); | ||
146 | temp += 64000; | ||
147 | } else | ||
148 | temp = clamp_val(temp, 0, 127000); | ||
149 | |||
150 | return (temp * 160 + 312) / 625; | ||
151 | } | ||
152 | |||
153 | static int tmp401_crit_register_to_temp(u8 reg, u8 config) | ||
154 | { | ||
155 | int temp = reg; | ||
156 | |||
157 | if (config & TMP401_CONFIG_RANGE) | ||
158 | temp -= 64; | ||
159 | |||
160 | return temp * 1000; | ||
161 | } | 185 | } |
162 | 186 | ||
163 | static u8 tmp401_crit_temp_to_register(long temp, u8 config) | 187 | static u16 tmp401_temp_to_register(long temp, u8 config, int zbits) |
164 | { | 188 | { |
165 | if (config & TMP401_CONFIG_RANGE) { | 189 | if (config & TMP401_CONFIG_RANGE) { |
166 | temp = clamp_val(temp, -64000, 191000); | 190 | temp = clamp_val(temp, -64000, 191000); |
@@ -168,113 +192,127 @@ static u8 tmp401_crit_temp_to_register(long temp, u8 config) | |||
168 | } else | 192 | } else |
169 | temp = clamp_val(temp, 0, 127000); | 193 | temp = clamp_val(temp, 0, 127000); |
170 | 194 | ||
171 | return (temp + 500) / 1000; | 195 | return DIV_ROUND_CLOSEST(temp * (1 << (8 - zbits)), 1000) << zbits; |
172 | } | 196 | } |
173 | 197 | ||
174 | static struct tmp401_data *tmp401_update_device_reg16( | 198 | static int tmp401_update_device_reg16(struct i2c_client *client, |
175 | struct i2c_client *client, struct tmp401_data *data) | 199 | struct tmp401_data *data) |
176 | { | 200 | { |
177 | int i; | 201 | int i, j, val; |
178 | 202 | int num_regs = data->kind == tmp411 ? 6 : 4; | |
179 | for (i = 0; i < 2; i++) { | 203 | int num_sensors = data->kind == tmp432 ? 3 : 2; |
180 | /* | 204 | |
181 | * High byte must be read first immediately followed | 205 | for (i = 0; i < num_sensors; i++) { /* local / r1 / r2 */ |
182 | * by the low byte | 206 | for (j = 0; j < num_regs; j++) { /* temp / low / ... */ |
183 | */ | 207 | u8 regaddr; |
184 | data->temp[i] = i2c_smbus_read_byte_data(client, | 208 | /* |
185 | TMP401_TEMP_MSB[i]) << 8; | 209 | * High byte must be read first immediately followed |
186 | data->temp[i] |= i2c_smbus_read_byte_data(client, | 210 | * by the low byte |
187 | TMP401_TEMP_LSB[i]); | 211 | */ |
188 | data->temp_low[i] = i2c_smbus_read_byte_data(client, | 212 | regaddr = data->kind == tmp432 ? |
189 | TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8; | 213 | TMP432_TEMP_MSB_READ[j][i] : |
190 | data->temp_low[i] |= i2c_smbus_read_byte_data(client, | 214 | TMP401_TEMP_MSB_READ[j][i]; |
191 | TMP401_TEMP_LOW_LIMIT_LSB[i]); | 215 | val = i2c_smbus_read_byte_data(client, regaddr); |
192 | data->temp_high[i] = i2c_smbus_read_byte_data(client, | 216 | if (val < 0) |
193 | TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8; | 217 | return val; |
194 | data->temp_high[i] |= i2c_smbus_read_byte_data(client, | 218 | data->temp[j][i] = val << 8; |
195 | TMP401_TEMP_HIGH_LIMIT_LSB[i]); | 219 | if (j == 3) /* crit is msb only */ |
196 | data->temp_crit[i] = i2c_smbus_read_byte_data(client, | 220 | continue; |
197 | TMP401_TEMP_CRIT_LIMIT[i]); | 221 | regaddr = data->kind == tmp432 ? TMP432_TEMP_LSB[j][i] |
198 | 222 | : TMP401_TEMP_LSB[j][i]; | |
199 | if (data->kind == tmp411) { | 223 | val = i2c_smbus_read_byte_data(client, regaddr); |
200 | data->temp_lowest[i] = i2c_smbus_read_byte_data(client, | 224 | if (val < 0) |
201 | TMP411_TEMP_LOWEST_MSB[i]) << 8; | 225 | return val; |
202 | data->temp_lowest[i] |= i2c_smbus_read_byte_data( | 226 | data->temp[j][i] |= val; |
203 | client, TMP411_TEMP_LOWEST_LSB[i]); | ||
204 | |||
205 | data->temp_highest[i] = i2c_smbus_read_byte_data( | ||
206 | client, TMP411_TEMP_HIGHEST_MSB[i]) << 8; | ||
207 | data->temp_highest[i] |= i2c_smbus_read_byte_data( | ||
208 | client, TMP411_TEMP_HIGHEST_LSB[i]); | ||
209 | } | 227 | } |
210 | } | 228 | } |
211 | return data; | 229 | return 0; |
212 | } | 230 | } |
213 | 231 | ||
214 | static struct tmp401_data *tmp401_update_device(struct device *dev) | 232 | static struct tmp401_data *tmp401_update_device(struct device *dev) |
215 | { | 233 | { |
216 | struct i2c_client *client = to_i2c_client(dev); | 234 | struct i2c_client *client = to_i2c_client(dev); |
217 | struct tmp401_data *data = i2c_get_clientdata(client); | 235 | struct tmp401_data *data = i2c_get_clientdata(client); |
236 | struct tmp401_data *ret = data; | ||
237 | int i, val; | ||
238 | unsigned long next_update; | ||
218 | 239 | ||
219 | mutex_lock(&data->update_lock); | 240 | mutex_lock(&data->update_lock); |
220 | 241 | ||
221 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | 242 | next_update = data->last_updated + |
222 | data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); | 243 | msecs_to_jiffies(data->update_interval) + 1; |
223 | data->config = i2c_smbus_read_byte_data(client, | 244 | if (time_after(jiffies, next_update) || !data->valid) { |
224 | TMP401_CONFIG_READ); | 245 | if (data->kind != tmp432) { |
225 | tmp401_update_device_reg16(client, data); | 246 | /* |
247 | * The driver uses the TMP432 status format internally. | ||
248 | * Convert status to TMP432 format for other chips. | ||
249 | */ | ||
250 | val = i2c_smbus_read_byte_data(client, TMP401_STATUS); | ||
251 | if (val < 0) { | ||
252 | ret = ERR_PTR(val); | ||
253 | goto abort; | ||
254 | } | ||
255 | data->status[0] = | ||
256 | (val & TMP401_STATUS_REMOTE_OPEN) >> 1; | ||
257 | data->status[1] = | ||
258 | ((val & TMP401_STATUS_REMOTE_LOW) >> 2) | | ||
259 | ((val & TMP401_STATUS_LOCAL_LOW) >> 5); | ||
260 | data->status[2] = | ||
261 | ((val & TMP401_STATUS_REMOTE_HIGH) >> 3) | | ||
262 | ((val & TMP401_STATUS_LOCAL_HIGH) >> 6); | ||
263 | data->status[3] = val & (TMP401_STATUS_LOCAL_CRIT | ||
264 | | TMP401_STATUS_REMOTE_CRIT); | ||
265 | } else { | ||
266 | for (i = 0; i < ARRAY_SIZE(data->status); i++) { | ||
267 | val = i2c_smbus_read_byte_data(client, | ||
268 | TMP432_STATUS_REG[i]); | ||
269 | if (val < 0) { | ||
270 | ret = ERR_PTR(val); | ||
271 | goto abort; | ||
272 | } | ||
273 | data->status[i] = val; | ||
274 | } | ||
275 | } | ||
226 | 276 | ||
227 | data->temp_crit_hyst = i2c_smbus_read_byte_data(client, | 277 | val = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); |
228 | TMP401_TEMP_CRIT_HYST); | 278 | if (val < 0) { |
279 | ret = ERR_PTR(val); | ||
280 | goto abort; | ||
281 | } | ||
282 | data->config = val; | ||
283 | val = tmp401_update_device_reg16(client, data); | ||
284 | if (val < 0) { | ||
285 | ret = ERR_PTR(val); | ||
286 | goto abort; | ||
287 | } | ||
288 | val = i2c_smbus_read_byte_data(client, TMP401_TEMP_CRIT_HYST); | ||
289 | if (val < 0) { | ||
290 | ret = ERR_PTR(val); | ||
291 | goto abort; | ||
292 | } | ||
293 | data->temp_crit_hyst = val; | ||
229 | 294 | ||
230 | data->last_updated = jiffies; | 295 | data->last_updated = jiffies; |
231 | data->valid = 1; | 296 | data->valid = 1; |
232 | } | 297 | } |
233 | 298 | ||
299 | abort: | ||
234 | mutex_unlock(&data->update_lock); | 300 | mutex_unlock(&data->update_lock); |
235 | 301 | return ret; | |
236 | return data; | ||
237 | } | ||
238 | |||
239 | static ssize_t show_temp_value(struct device *dev, | ||
240 | struct device_attribute *devattr, char *buf) | ||
241 | { | ||
242 | int index = to_sensor_dev_attr(devattr)->index; | ||
243 | struct tmp401_data *data = tmp401_update_device(dev); | ||
244 | |||
245 | return sprintf(buf, "%d\n", | ||
246 | tmp401_register_to_temp(data->temp[index], data->config)); | ||
247 | } | ||
248 | |||
249 | static ssize_t show_temp_min(struct device *dev, | ||
250 | struct device_attribute *devattr, char *buf) | ||
251 | { | ||
252 | int index = to_sensor_dev_attr(devattr)->index; | ||
253 | struct tmp401_data *data = tmp401_update_device(dev); | ||
254 | |||
255 | return sprintf(buf, "%d\n", | ||
256 | tmp401_register_to_temp(data->temp_low[index], data->config)); | ||
257 | } | 302 | } |
258 | 303 | ||
259 | static ssize_t show_temp_max(struct device *dev, | 304 | static ssize_t show_temp(struct device *dev, |
260 | struct device_attribute *devattr, char *buf) | 305 | struct device_attribute *devattr, char *buf) |
261 | { | 306 | { |
262 | int index = to_sensor_dev_attr(devattr)->index; | 307 | int nr = to_sensor_dev_attr_2(devattr)->nr; |
308 | int index = to_sensor_dev_attr_2(devattr)->index; | ||
263 | struct tmp401_data *data = tmp401_update_device(dev); | 309 | struct tmp401_data *data = tmp401_update_device(dev); |
264 | 310 | ||
265 | return sprintf(buf, "%d\n", | 311 | if (IS_ERR(data)) |
266 | tmp401_register_to_temp(data->temp_high[index], data->config)); | 312 | return PTR_ERR(data); |
267 | } | ||
268 | |||
269 | static ssize_t show_temp_crit(struct device *dev, | ||
270 | struct device_attribute *devattr, char *buf) | ||
271 | { | ||
272 | int index = to_sensor_dev_attr(devattr)->index; | ||
273 | struct tmp401_data *data = tmp401_update_device(dev); | ||
274 | 313 | ||
275 | return sprintf(buf, "%d\n", | 314 | return sprintf(buf, "%d\n", |
276 | tmp401_crit_register_to_temp(data->temp_crit[index], | 315 | tmp401_register_to_temp(data->temp[nr][index], data->config)); |
277 | data->config)); | ||
278 | } | 316 | } |
279 | 317 | ||
280 | static ssize_t show_temp_crit_hyst(struct device *dev, | 318 | static ssize_t show_temp_crit_hyst(struct device *dev, |
@@ -283,122 +321,60 @@ static ssize_t show_temp_crit_hyst(struct device *dev, | |||
283 | int temp, index = to_sensor_dev_attr(devattr)->index; | 321 | int temp, index = to_sensor_dev_attr(devattr)->index; |
284 | struct tmp401_data *data = tmp401_update_device(dev); | 322 | struct tmp401_data *data = tmp401_update_device(dev); |
285 | 323 | ||
324 | if (IS_ERR(data)) | ||
325 | return PTR_ERR(data); | ||
326 | |||
286 | mutex_lock(&data->update_lock); | 327 | mutex_lock(&data->update_lock); |
287 | temp = tmp401_crit_register_to_temp(data->temp_crit[index], | 328 | temp = tmp401_register_to_temp(data->temp[3][index], data->config); |
288 | data->config); | ||
289 | temp -= data->temp_crit_hyst * 1000; | 329 | temp -= data->temp_crit_hyst * 1000; |
290 | mutex_unlock(&data->update_lock); | 330 | mutex_unlock(&data->update_lock); |
291 | 331 | ||
292 | return sprintf(buf, "%d\n", temp); | 332 | return sprintf(buf, "%d\n", temp); |
293 | } | 333 | } |
294 | 334 | ||
295 | static ssize_t show_temp_lowest(struct device *dev, | ||
296 | struct device_attribute *devattr, char *buf) | ||
297 | { | ||
298 | int index = to_sensor_dev_attr(devattr)->index; | ||
299 | struct tmp401_data *data = tmp401_update_device(dev); | ||
300 | |||
301 | return sprintf(buf, "%d\n", | ||
302 | tmp401_register_to_temp(data->temp_lowest[index], | ||
303 | data->config)); | ||
304 | } | ||
305 | |||
306 | static ssize_t show_temp_highest(struct device *dev, | ||
307 | struct device_attribute *devattr, char *buf) | ||
308 | { | ||
309 | int index = to_sensor_dev_attr(devattr)->index; | ||
310 | struct tmp401_data *data = tmp401_update_device(dev); | ||
311 | |||
312 | return sprintf(buf, "%d\n", | ||
313 | tmp401_register_to_temp(data->temp_highest[index], | ||
314 | data->config)); | ||
315 | } | ||
316 | |||
317 | static ssize_t show_status(struct device *dev, | 335 | static ssize_t show_status(struct device *dev, |
318 | struct device_attribute *devattr, char *buf) | 336 | struct device_attribute *devattr, char *buf) |
319 | { | 337 | { |
320 | int mask = to_sensor_dev_attr(devattr)->index; | 338 | int nr = to_sensor_dev_attr_2(devattr)->nr; |
321 | struct tmp401_data *data = tmp401_update_device(dev); | 339 | int mask = to_sensor_dev_attr_2(devattr)->index; |
322 | |||
323 | if (data->status & mask) | ||
324 | return sprintf(buf, "1\n"); | ||
325 | else | ||
326 | return sprintf(buf, "0\n"); | ||
327 | } | ||
328 | |||
329 | static ssize_t store_temp_min(struct device *dev, struct device_attribute | ||
330 | *devattr, const char *buf, size_t count) | ||
331 | { | ||
332 | int index = to_sensor_dev_attr(devattr)->index; | ||
333 | struct tmp401_data *data = tmp401_update_device(dev); | 340 | struct tmp401_data *data = tmp401_update_device(dev); |
334 | long val; | ||
335 | u16 reg; | ||
336 | |||
337 | if (kstrtol(buf, 10, &val)) | ||
338 | return -EINVAL; | ||
339 | |||
340 | reg = tmp401_temp_to_register(val, data->config); | ||
341 | |||
342 | mutex_lock(&data->update_lock); | ||
343 | |||
344 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
345 | TMP401_TEMP_LOW_LIMIT_MSB_WRITE[index], reg >> 8); | ||
346 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
347 | TMP401_TEMP_LOW_LIMIT_LSB[index], reg & 0xFF); | ||
348 | |||
349 | data->temp_low[index] = reg; | ||
350 | 341 | ||
351 | mutex_unlock(&data->update_lock); | 342 | if (IS_ERR(data)) |
343 | return PTR_ERR(data); | ||
352 | 344 | ||
353 | return count; | 345 | return sprintf(buf, "%d\n", !!(data->status[nr] & mask)); |
354 | } | 346 | } |
355 | 347 | ||
356 | static ssize_t store_temp_max(struct device *dev, struct device_attribute | 348 | static ssize_t store_temp(struct device *dev, struct device_attribute *devattr, |
357 | *devattr, const char *buf, size_t count) | 349 | const char *buf, size_t count) |
358 | { | 350 | { |
359 | int index = to_sensor_dev_attr(devattr)->index; | 351 | int nr = to_sensor_dev_attr_2(devattr)->nr; |
352 | int index = to_sensor_dev_attr_2(devattr)->index; | ||
353 | struct i2c_client *client = to_i2c_client(dev); | ||
360 | struct tmp401_data *data = tmp401_update_device(dev); | 354 | struct tmp401_data *data = tmp401_update_device(dev); |
361 | long val; | 355 | long val; |
362 | u16 reg; | 356 | u16 reg; |
357 | u8 regaddr; | ||
363 | 358 | ||
364 | if (kstrtol(buf, 10, &val)) | 359 | if (IS_ERR(data)) |
365 | return -EINVAL; | 360 | return PTR_ERR(data); |
366 | |||
367 | reg = tmp401_temp_to_register(val, data->config); | ||
368 | |||
369 | mutex_lock(&data->update_lock); | ||
370 | |||
371 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
372 | TMP401_TEMP_HIGH_LIMIT_MSB_WRITE[index], reg >> 8); | ||
373 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
374 | TMP401_TEMP_HIGH_LIMIT_LSB[index], reg & 0xFF); | ||
375 | |||
376 | data->temp_high[index] = reg; | ||
377 | |||
378 | mutex_unlock(&data->update_lock); | ||
379 | |||
380 | return count; | ||
381 | } | ||
382 | |||
383 | static ssize_t store_temp_crit(struct device *dev, struct device_attribute | ||
384 | *devattr, const char *buf, size_t count) | ||
385 | { | ||
386 | int index = to_sensor_dev_attr(devattr)->index; | ||
387 | struct tmp401_data *data = tmp401_update_device(dev); | ||
388 | long val; | ||
389 | u8 reg; | ||
390 | 361 | ||
391 | if (kstrtol(buf, 10, &val)) | 362 | if (kstrtol(buf, 10, &val)) |
392 | return -EINVAL; | 363 | return -EINVAL; |
393 | 364 | ||
394 | reg = tmp401_crit_temp_to_register(val, data->config); | 365 | reg = tmp401_temp_to_register(val, data->config, nr == 3 ? 8 : 4); |
395 | 366 | ||
396 | mutex_lock(&data->update_lock); | 367 | mutex_lock(&data->update_lock); |
397 | 368 | ||
398 | i2c_smbus_write_byte_data(to_i2c_client(dev), | 369 | regaddr = data->kind == tmp432 ? TMP432_TEMP_MSB_WRITE[nr][index] |
399 | TMP401_TEMP_CRIT_LIMIT[index], reg); | 370 | : TMP401_TEMP_MSB_WRITE[nr][index]; |
400 | 371 | i2c_smbus_write_byte_data(client, regaddr, reg >> 8); | |
401 | data->temp_crit[index] = reg; | 372 | if (nr != 3) { |
373 | regaddr = data->kind == tmp432 ? TMP432_TEMP_LSB[nr][index] | ||
374 | : TMP401_TEMP_LSB[nr][index]; | ||
375 | i2c_smbus_write_byte_data(client, regaddr, reg & 0xFF); | ||
376 | } | ||
377 | data->temp[nr][index] = reg; | ||
402 | 378 | ||
403 | mutex_unlock(&data->update_lock); | 379 | mutex_unlock(&data->update_lock); |
404 | 380 | ||
@@ -413,6 +389,9 @@ static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute | |||
413 | long val; | 389 | long val; |
414 | u8 reg; | 390 | u8 reg; |
415 | 391 | ||
392 | if (IS_ERR(data)) | ||
393 | return PTR_ERR(data); | ||
394 | |||
416 | if (kstrtol(buf, 10, &val)) | 395 | if (kstrtol(buf, 10, &val)) |
417 | return -EINVAL; | 396 | return -EINVAL; |
418 | 397 | ||
@@ -422,13 +401,12 @@ static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute | |||
422 | val = clamp_val(val, 0, 127000); | 401 | val = clamp_val(val, 0, 127000); |
423 | 402 | ||
424 | mutex_lock(&data->update_lock); | 403 | mutex_lock(&data->update_lock); |
425 | temp = tmp401_crit_register_to_temp(data->temp_crit[index], | 404 | temp = tmp401_register_to_temp(data->temp[3][index], data->config); |
426 | data->config); | ||
427 | val = clamp_val(val, temp - 255000, temp); | 405 | val = clamp_val(val, temp - 255000, temp); |
428 | reg = ((temp - val) + 500) / 1000; | 406 | reg = ((temp - val) + 500) / 1000; |
429 | 407 | ||
430 | i2c_smbus_write_byte_data(to_i2c_client(dev), | 408 | i2c_smbus_write_byte_data(to_i2c_client(dev), TMP401_TEMP_CRIT_HYST, |
431 | TMP401_TEMP_CRIT_HYST, reg); | 409 | reg); |
432 | 410 | ||
433 | data->temp_crit_hyst = reg; | 411 | data->temp_crit_hyst = reg; |
434 | 412 | ||
@@ -445,54 +423,130 @@ static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute | |||
445 | static ssize_t reset_temp_history(struct device *dev, | 423 | static ssize_t reset_temp_history(struct device *dev, |
446 | struct device_attribute *devattr, const char *buf, size_t count) | 424 | struct device_attribute *devattr, const char *buf, size_t count) |
447 | { | 425 | { |
426 | struct i2c_client *client = to_i2c_client(dev); | ||
427 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
448 | long val; | 428 | long val; |
449 | 429 | ||
450 | if (kstrtol(buf, 10, &val)) | 430 | if (kstrtol(buf, 10, &val)) |
451 | return -EINVAL; | 431 | return -EINVAL; |
452 | 432 | ||
453 | if (val != 1) { | 433 | if (val != 1) { |
454 | dev_err(dev, "temp_reset_history value %ld not" | 434 | dev_err(dev, |
455 | " supported. Use 1 to reset the history!\n", val); | 435 | "temp_reset_history value %ld not supported. Use 1 to reset the history!\n", |
436 | val); | ||
456 | return -EINVAL; | 437 | return -EINVAL; |
457 | } | 438 | } |
458 | i2c_smbus_write_byte_data(to_i2c_client(dev), | 439 | mutex_lock(&data->update_lock); |
459 | TMP411_TEMP_LOWEST_MSB[0], val); | 440 | i2c_smbus_write_byte_data(client, TMP401_TEMP_MSB_WRITE[5][0], val); |
441 | data->valid = 0; | ||
442 | mutex_unlock(&data->update_lock); | ||
443 | |||
444 | return count; | ||
445 | } | ||
446 | |||
447 | static ssize_t show_update_interval(struct device *dev, | ||
448 | struct device_attribute *attr, char *buf) | ||
449 | { | ||
450 | struct i2c_client *client = to_i2c_client(dev); | ||
451 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
452 | |||
453 | return sprintf(buf, "%u\n", data->update_interval); | ||
454 | } | ||
455 | |||
456 | static ssize_t set_update_interval(struct device *dev, | ||
457 | struct device_attribute *attr, | ||
458 | const char *buf, size_t count) | ||
459 | { | ||
460 | struct i2c_client *client = to_i2c_client(dev); | ||
461 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
462 | unsigned long val; | ||
463 | int err, rate; | ||
464 | |||
465 | err = kstrtoul(buf, 10, &val); | ||
466 | if (err) | ||
467 | return err; | ||
468 | |||
469 | /* | ||
470 | * For valid rates, interval can be calculated as | ||
471 | * interval = (1 << (7 - rate)) * 125; | ||
472 | * Rounded rate is therefore | ||
473 | * rate = 7 - __fls(interval * 4 / (125 * 3)); | ||
474 | * Use clamp_val() to avoid overflows, and to ensure valid input | ||
475 | * for __fls. | ||
476 | */ | ||
477 | val = clamp_val(val, 125, 16000); | ||
478 | rate = 7 - __fls(val * 4 / (125 * 3)); | ||
479 | mutex_lock(&data->update_lock); | ||
480 | i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, rate); | ||
481 | data->update_interval = (1 << (7 - rate)) * 125; | ||
482 | mutex_unlock(&data->update_lock); | ||
460 | 483 | ||
461 | return count; | 484 | return count; |
462 | } | 485 | } |
463 | 486 | ||
464 | static struct sensor_device_attribute tmp401_attr[] = { | 487 | static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0); |
465 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0), | 488 | static SENSOR_DEVICE_ATTR_2(temp1_min, S_IWUSR | S_IRUGO, show_temp, |
466 | SENSOR_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, | 489 | store_temp, 1, 0); |
467 | store_temp_min, 0), | 490 | static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp, |
468 | SENSOR_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | 491 | store_temp, 2, 0); |
469 | store_temp_max, 0), | 492 | static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IWUSR | S_IRUGO, show_temp, |
470 | SENSOR_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_crit, | 493 | store_temp, 3, 0); |
471 | store_temp_crit, 0), | 494 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, |
472 | SENSOR_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_crit_hyst, | 495 | show_temp_crit_hyst, store_temp_crit_hyst, 0); |
473 | store_temp_crit_hyst, 0), | 496 | static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, show_status, NULL, |
474 | SENSOR_ATTR(temp1_min_alarm, S_IRUGO, show_status, NULL, | 497 | 1, TMP432_STATUS_LOCAL); |
475 | TMP401_STATUS_LOCAL_LOW), | 498 | static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, show_status, NULL, |
476 | SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_status, NULL, | 499 | 2, TMP432_STATUS_LOCAL); |
477 | TMP401_STATUS_LOCAL_HIGH), | 500 | static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, show_status, NULL, |
478 | SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_status, NULL, | 501 | 3, TMP432_STATUS_LOCAL); |
479 | TMP401_STATUS_LOCAL_CRIT), | 502 | static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1); |
480 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1), | 503 | static SENSOR_DEVICE_ATTR_2(temp2_min, S_IWUSR | S_IRUGO, show_temp, |
481 | SENSOR_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, | 504 | store_temp, 1, 1); |
482 | store_temp_min, 1), | 505 | static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp, |
483 | SENSOR_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, | 506 | store_temp, 2, 1); |
484 | store_temp_max, 1), | 507 | static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IWUSR | S_IRUGO, show_temp, |
485 | SENSOR_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit, | 508 | store_temp, 3, 1); |
486 | store_temp_crit, 1), | 509 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, |
487 | SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1), | 510 | NULL, 1); |
488 | SENSOR_ATTR(temp2_fault, S_IRUGO, show_status, NULL, | 511 | static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_status, NULL, |
489 | TMP401_STATUS_REMOTE_OPEN), | 512 | 0, TMP432_STATUS_REMOTE1); |
490 | SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_status, NULL, | 513 | static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, show_status, NULL, |
491 | TMP401_STATUS_REMOTE_LOW), | 514 | 1, TMP432_STATUS_REMOTE1); |
492 | SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_status, NULL, | 515 | static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, show_status, NULL, |
493 | TMP401_STATUS_REMOTE_HIGH), | 516 | 2, TMP432_STATUS_REMOTE1); |
494 | SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_status, NULL, | 517 | static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, show_status, NULL, |
495 | TMP401_STATUS_REMOTE_CRIT), | 518 | 3, TMP432_STATUS_REMOTE1); |
519 | |||
520 | static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, | ||
521 | set_update_interval); | ||
522 | |||
523 | static struct attribute *tmp401_attributes[] = { | ||
524 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
525 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
526 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
527 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
528 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, | ||
529 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
530 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
531 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
532 | |||
533 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
534 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
535 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
536 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
537 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, | ||
538 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
539 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | ||
540 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | ||
541 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | ||
542 | |||
543 | &dev_attr_update_interval.attr, | ||
544 | |||
545 | NULL | ||
546 | }; | ||
547 | |||
548 | static const struct attribute_group tmp401_group = { | ||
549 | .attrs = tmp401_attributes, | ||
496 | }; | 550 | }; |
497 | 551 | ||
498 | /* | 552 | /* |
@@ -502,12 +556,60 @@ static struct sensor_device_attribute tmp401_attr[] = { | |||
502 | * minimum and maximum register reset for both the local | 556 | * minimum and maximum register reset for both the local |
503 | * and remote channels. | 557 | * and remote channels. |
504 | */ | 558 | */ |
505 | static struct sensor_device_attribute tmp411_attr[] = { | 559 | static SENSOR_DEVICE_ATTR_2(temp1_lowest, S_IRUGO, show_temp, NULL, 4, 0); |
506 | SENSOR_ATTR(temp1_highest, S_IRUGO, show_temp_highest, NULL, 0), | 560 | static SENSOR_DEVICE_ATTR_2(temp1_highest, S_IRUGO, show_temp, NULL, 5, 0); |
507 | SENSOR_ATTR(temp1_lowest, S_IRUGO, show_temp_lowest, NULL, 0), | 561 | static SENSOR_DEVICE_ATTR_2(temp2_lowest, S_IRUGO, show_temp, NULL, 4, 1); |
508 | SENSOR_ATTR(temp2_highest, S_IRUGO, show_temp_highest, NULL, 1), | 562 | static SENSOR_DEVICE_ATTR_2(temp2_highest, S_IRUGO, show_temp, NULL, 5, 1); |
509 | SENSOR_ATTR(temp2_lowest, S_IRUGO, show_temp_lowest, NULL, 1), | 563 | static SENSOR_DEVICE_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history, |
510 | SENSOR_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history, 0), | 564 | 0); |
565 | |||
566 | static struct attribute *tmp411_attributes[] = { | ||
567 | &sensor_dev_attr_temp1_highest.dev_attr.attr, | ||
568 | &sensor_dev_attr_temp1_lowest.dev_attr.attr, | ||
569 | &sensor_dev_attr_temp2_highest.dev_attr.attr, | ||
570 | &sensor_dev_attr_temp2_lowest.dev_attr.attr, | ||
571 | &sensor_dev_attr_temp_reset_history.dev_attr.attr, | ||
572 | NULL | ||
573 | }; | ||
574 | |||
575 | static const struct attribute_group tmp411_group = { | ||
576 | .attrs = tmp411_attributes, | ||
577 | }; | ||
578 | |||
579 | static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2); | ||
580 | static SENSOR_DEVICE_ATTR_2(temp3_min, S_IWUSR | S_IRUGO, show_temp, | ||
581 | store_temp, 1, 2); | ||
582 | static SENSOR_DEVICE_ATTR_2(temp3_max, S_IWUSR | S_IRUGO, show_temp, | ||
583 | store_temp, 2, 2); | ||
584 | static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IWUSR | S_IRUGO, show_temp, | ||
585 | store_temp, 3, 2); | ||
586 | static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, | ||
587 | NULL, 2); | ||
588 | static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_status, NULL, | ||
589 | 0, TMP432_STATUS_REMOTE2); | ||
590 | static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, show_status, NULL, | ||
591 | 1, TMP432_STATUS_REMOTE2); | ||
592 | static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, show_status, NULL, | ||
593 | 2, TMP432_STATUS_REMOTE2); | ||
594 | static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, show_status, NULL, | ||
595 | 3, TMP432_STATUS_REMOTE2); | ||
596 | |||
597 | static struct attribute *tmp432_attributes[] = { | ||
598 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
599 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
600 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
601 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | ||
602 | &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, | ||
603 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
604 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | ||
605 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, | ||
606 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | ||
607 | |||
608 | NULL | ||
609 | }; | ||
610 | |||
611 | static const struct attribute_group tmp432_group = { | ||
612 | .attrs = tmp432_attributes, | ||
511 | }; | 613 | }; |
512 | 614 | ||
513 | /* | 615 | /* |
@@ -517,9 +619,11 @@ static struct sensor_device_attribute tmp411_attr[] = { | |||
517 | static void tmp401_init_client(struct i2c_client *client) | 619 | static void tmp401_init_client(struct i2c_client *client) |
518 | { | 620 | { |
519 | int config, config_orig; | 621 | int config, config_orig; |
622 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
520 | 623 | ||
521 | /* Set the conversion rate to 2 Hz */ | 624 | /* Set the conversion rate to 2 Hz */ |
522 | i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5); | 625 | i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5); |
626 | data->update_interval = 500; | ||
523 | 627 | ||
524 | /* Start conversions (disable shutdown if necessary) */ | 628 | /* Start conversions (disable shutdown if necessary) */ |
525 | config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); | 629 | config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); |
@@ -554,11 +658,35 @@ static int tmp401_detect(struct i2c_client *client, | |||
554 | 658 | ||
555 | switch (reg) { | 659 | switch (reg) { |
556 | case TMP401_DEVICE_ID: | 660 | case TMP401_DEVICE_ID: |
661 | if (client->addr != 0x4c) | ||
662 | return -ENODEV; | ||
557 | kind = tmp401; | 663 | kind = tmp401; |
558 | break; | 664 | break; |
559 | case TMP411_DEVICE_ID: | 665 | case TMP411A_DEVICE_ID: |
666 | if (client->addr != 0x4c) | ||
667 | return -ENODEV; | ||
668 | kind = tmp411; | ||
669 | break; | ||
670 | case TMP411B_DEVICE_ID: | ||
671 | if (client->addr != 0x4d) | ||
672 | return -ENODEV; | ||
560 | kind = tmp411; | 673 | kind = tmp411; |
561 | break; | 674 | break; |
675 | case TMP411C_DEVICE_ID: | ||
676 | if (client->addr != 0x4e) | ||
677 | return -ENODEV; | ||
678 | kind = tmp411; | ||
679 | break; | ||
680 | case TMP431_DEVICE_ID: | ||
681 | if (client->addr == 0x4e) | ||
682 | return -ENODEV; | ||
683 | kind = tmp431; | ||
684 | break; | ||
685 | case TMP432_DEVICE_ID: | ||
686 | if (client->addr == 0x4e) | ||
687 | return -ENODEV; | ||
688 | kind = tmp432; | ||
689 | break; | ||
562 | default: | 690 | default: |
563 | return -ENODEV; | 691 | return -ENODEV; |
564 | } | 692 | } |
@@ -579,20 +707,19 @@ static int tmp401_detect(struct i2c_client *client, | |||
579 | 707 | ||
580 | static int tmp401_remove(struct i2c_client *client) | 708 | static int tmp401_remove(struct i2c_client *client) |
581 | { | 709 | { |
710 | struct device *dev = &client->dev; | ||
582 | struct tmp401_data *data = i2c_get_clientdata(client); | 711 | struct tmp401_data *data = i2c_get_clientdata(client); |
583 | int i; | ||
584 | 712 | ||
585 | if (data->hwmon_dev) | 713 | if (data->hwmon_dev) |
586 | hwmon_device_unregister(data->hwmon_dev); | 714 | hwmon_device_unregister(data->hwmon_dev); |
587 | 715 | ||
588 | for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) | 716 | sysfs_remove_group(&dev->kobj, &tmp401_group); |
589 | device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); | ||
590 | 717 | ||
591 | if (data->kind == tmp411) { | 718 | if (data->kind == tmp411) |
592 | for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) | 719 | sysfs_remove_group(&dev->kobj, &tmp411_group); |
593 | device_remove_file(&client->dev, | 720 | |
594 | &tmp411_attr[i].dev_attr); | 721 | if (data->kind == tmp432) |
595 | } | 722 | sysfs_remove_group(&dev->kobj, &tmp432_group); |
596 | 723 | ||
597 | return 0; | 724 | return 0; |
598 | } | 725 | } |
@@ -600,12 +727,12 @@ static int tmp401_remove(struct i2c_client *client) | |||
600 | static int tmp401_probe(struct i2c_client *client, | 727 | static int tmp401_probe(struct i2c_client *client, |
601 | const struct i2c_device_id *id) | 728 | const struct i2c_device_id *id) |
602 | { | 729 | { |
603 | int i, err = 0; | 730 | struct device *dev = &client->dev; |
731 | int err; | ||
604 | struct tmp401_data *data; | 732 | struct tmp401_data *data; |
605 | const char *names[] = { "TMP401", "TMP411" }; | 733 | const char *names[] = { "TMP401", "TMP411", "TMP431", "TMP432" }; |
606 | 734 | ||
607 | data = devm_kzalloc(&client->dev, sizeof(struct tmp401_data), | 735 | data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL); |
608 | GFP_KERNEL); | ||
609 | if (!data) | 736 | if (!data) |
610 | return -ENOMEM; | 737 | return -ENOMEM; |
611 | 738 | ||
@@ -617,31 +744,32 @@ static int tmp401_probe(struct i2c_client *client, | |||
617 | tmp401_init_client(client); | 744 | tmp401_init_client(client); |
618 | 745 | ||
619 | /* Register sysfs hooks */ | 746 | /* Register sysfs hooks */ |
620 | for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) { | 747 | err = sysfs_create_group(&dev->kobj, &tmp401_group); |
621 | err = device_create_file(&client->dev, | 748 | if (err) |
622 | &tmp401_attr[i].dev_attr); | 749 | return err; |
750 | |||
751 | /* Register additional tmp411 sysfs hooks */ | ||
752 | if (data->kind == tmp411) { | ||
753 | err = sysfs_create_group(&dev->kobj, &tmp411_group); | ||
623 | if (err) | 754 | if (err) |
624 | goto exit_remove; | 755 | goto exit_remove; |
625 | } | 756 | } |
626 | 757 | ||
627 | /* Register additional tmp411 sysfs hooks */ | 758 | /* Register additional tmp432 sysfs hooks */ |
628 | if (data->kind == tmp411) { | 759 | if (data->kind == tmp432) { |
629 | for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) { | 760 | err = sysfs_create_group(&dev->kobj, &tmp432_group); |
630 | err = device_create_file(&client->dev, | 761 | if (err) |
631 | &tmp411_attr[i].dev_attr); | 762 | goto exit_remove; |
632 | if (err) | ||
633 | goto exit_remove; | ||
634 | } | ||
635 | } | 763 | } |
636 | 764 | ||
637 | data->hwmon_dev = hwmon_device_register(&client->dev); | 765 | data->hwmon_dev = hwmon_device_register(dev); |
638 | if (IS_ERR(data->hwmon_dev)) { | 766 | if (IS_ERR(data->hwmon_dev)) { |
639 | err = PTR_ERR(data->hwmon_dev); | 767 | err = PTR_ERR(data->hwmon_dev); |
640 | data->hwmon_dev = NULL; | 768 | data->hwmon_dev = NULL; |
641 | goto exit_remove; | 769 | goto exit_remove; |
642 | } | 770 | } |
643 | 771 | ||
644 | dev_info(&client->dev, "Detected TI %s chip\n", names[data->kind]); | 772 | dev_info(dev, "Detected TI %s chip\n", names[data->kind]); |
645 | 773 | ||
646 | return 0; | 774 | return 0; |
647 | 775 | ||
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index 6a8ded29f1ed..964c1d688274 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c | |||
@@ -208,8 +208,8 @@ static int tmp421_init_client(struct i2c_client *client) | |||
208 | /* Start conversions (disable shutdown if necessary) */ | 208 | /* Start conversions (disable shutdown if necessary) */ |
209 | config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1); | 209 | config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1); |
210 | if (config < 0) { | 210 | if (config < 0) { |
211 | dev_err(&client->dev, "Could not read configuration" | 211 | dev_err(&client->dev, |
212 | " register (%d)\n", config); | 212 | "Could not read configuration register (%d)\n", config); |
213 | return -ENODEV; | 213 | return -ENODEV; |
214 | } | 214 | } |
215 | 215 | ||
@@ -322,6 +322,5 @@ static struct i2c_driver tmp421_driver = { | |||
322 | module_i2c_driver(tmp421_driver); | 322 | module_i2c_driver(tmp421_driver); |
323 | 323 | ||
324 | MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>"); | 324 | MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>"); |
325 | MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor" | 325 | MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor driver"); |
326 | " driver"); | ||
327 | MODULE_LICENSE("GPL"); | 326 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 3123b30208c5..c9dcce8c3dc3 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -125,7 +125,7 @@ static const u8 VIA686A_REG_TEMP_HYST[] = { 0x3a, 0x3e, 0x1e }; | |||
125 | * (These conversions were contributed by Jonathan Teh Soon Yew | 125 | * (These conversions were contributed by Jonathan Teh Soon Yew |
126 | * <j.teh@iname.com>) | 126 | * <j.teh@iname.com>) |
127 | */ | 127 | */ |
128 | static inline u8 IN_TO_REG(long val, int inNum) | 128 | static inline u8 IN_TO_REG(long val, int in_num) |
129 | { | 129 | { |
130 | /* | 130 | /* |
131 | * To avoid floating point, we multiply constants by 10 (100 for +12V). | 131 | * To avoid floating point, we multiply constants by 10 (100 for +12V). |
@@ -134,29 +134,29 @@ static inline u8 IN_TO_REG(long val, int inNum) | |||
134 | * by an additional 10000 (100000 for +12V): 1000 for val and 10 (100) | 134 | * by an additional 10000 (100000 for +12V): 1000 for val and 10 (100) |
135 | * for the constants. | 135 | * for the constants. |
136 | */ | 136 | */ |
137 | if (inNum <= 1) | 137 | if (in_num <= 1) |
138 | return (u8) clamp_val((val * 21024 - 1205000) / 250000, 0, 255); | 138 | return (u8) clamp_val((val * 21024 - 1205000) / 250000, 0, 255); |
139 | else if (inNum == 2) | 139 | else if (in_num == 2) |
140 | return (u8) clamp_val((val * 15737 - 1205000) / 250000, 0, 255); | 140 | return (u8) clamp_val((val * 15737 - 1205000) / 250000, 0, 255); |
141 | else if (inNum == 3) | 141 | else if (in_num == 3) |
142 | return (u8) clamp_val((val * 10108 - 1205000) / 250000, 0, 255); | 142 | return (u8) clamp_val((val * 10108 - 1205000) / 250000, 0, 255); |
143 | else | 143 | else |
144 | return (u8) clamp_val((val * 41714 - 12050000) / 2500000, 0, | 144 | return (u8) clamp_val((val * 41714 - 12050000) / 2500000, 0, |
145 | 255); | 145 | 255); |
146 | } | 146 | } |
147 | 147 | ||
148 | static inline long IN_FROM_REG(u8 val, int inNum) | 148 | static inline long IN_FROM_REG(u8 val, int in_num) |
149 | { | 149 | { |
150 | /* | 150 | /* |
151 | * To avoid floating point, we multiply constants by 10 (100 for +12V). | 151 | * To avoid floating point, we multiply constants by 10 (100 for +12V). |
152 | * We also multiply them by 1000 because we want 0.001V/bit for the | 152 | * We also multiply them by 1000 because we want 0.001V/bit for the |
153 | * output value. Rounding is done. | 153 | * output value. Rounding is done. |
154 | */ | 154 | */ |
155 | if (inNum <= 1) | 155 | if (in_num <= 1) |
156 | return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024); | 156 | return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024); |
157 | else if (inNum == 2) | 157 | else if (in_num == 2) |
158 | return (long) ((250000 * val + 1330000 + 15737 / 2) / 15737); | 158 | return (long) ((250000 * val + 1330000 + 15737 / 2) / 15737); |
159 | else if (inNum == 3) | 159 | else if (in_num == 3) |
160 | return (long) ((250000 * val + 1330000 + 10108 / 2) / 10108); | 160 | return (long) ((250000 * val + 1330000 + 10108 / 2) / 10108); |
161 | else | 161 | else |
162 | return (long) ((2500000 * val + 13300000 + 41714 / 2) / 41714); | 162 | return (long) ((2500000 * val + 13300000 + 41714 / 2) / 41714); |
@@ -210,10 +210,10 @@ static inline u8 FAN_TO_REG(long rpm, int div) | |||
210 | * VIA register values 0-255. I *10 before rounding, so we get tenth-degree | 210 | * VIA register values 0-255. I *10 before rounding, so we get tenth-degree |
211 | * precision. (I could have done all 1024 values for our 10-bit readings, | 211 | * precision. (I could have done all 1024 values for our 10-bit readings, |
212 | * but the function is very linear in the useful range (0-80 deg C), so | 212 | * but the function is very linear in the useful range (0-80 deg C), so |
213 | * we'll just use linear interpolation for 10-bit readings.) So, tempLUT | 213 | * we'll just use linear interpolation for 10-bit readings.) So, temp_lut |
214 | * is the temp at via register values 0-255: | 214 | * is the temp at via register values 0-255: |
215 | */ | 215 | */ |
216 | static const s16 tempLUT[] = { | 216 | static const s16 temp_lut[] = { |
217 | -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519, | 217 | -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519, |
218 | -503, -487, -471, -456, -442, -428, -414, -400, -387, -375, | 218 | -503, -487, -471, -456, -442, -428, -414, -400, -387, -375, |
219 | -362, -350, -339, -327, -316, -305, -295, -285, -275, -265, | 219 | -362, -350, -339, -327, -316, -305, -295, -285, -275, -265, |
@@ -261,7 +261,7 @@ static const s16 tempLUT[] = { | |||
261 | * - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01) | 261 | * - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01) |
262 | * Note that n=161: | 262 | * Note that n=161: |
263 | */ | 263 | */ |
264 | static const u8 viaLUT[] = { | 264 | static const u8 via_lut[] = { |
265 | 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23, | 265 | 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23, |
266 | 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40, | 266 | 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40, |
267 | 41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66, | 267 | 41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66, |
@@ -284,26 +284,26 @@ static const u8 viaLUT[] = { | |||
284 | */ | 284 | */ |
285 | static inline u8 TEMP_TO_REG(long val) | 285 | static inline u8 TEMP_TO_REG(long val) |
286 | { | 286 | { |
287 | return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 : | 287 | return via_lut[val <= -50000 ? 0 : val >= 110000 ? 160 : |
288 | (val < 0 ? val - 500 : val + 500) / 1000 + 50]; | 288 | (val < 0 ? val - 500 : val + 500) / 1000 + 50]; |
289 | } | 289 | } |
290 | 290 | ||
291 | /* for 8-bit temperature hyst and over registers */ | 291 | /* for 8-bit temperature hyst and over registers */ |
292 | #define TEMP_FROM_REG(val) ((long)tempLUT[val] * 100) | 292 | #define TEMP_FROM_REG(val) ((long)temp_lut[val] * 100) |
293 | 293 | ||
294 | /* for 10-bit temperature readings */ | 294 | /* for 10-bit temperature readings */ |
295 | static inline long TEMP_FROM_REG10(u16 val) | 295 | static inline long TEMP_FROM_REG10(u16 val) |
296 | { | 296 | { |
297 | u16 eightBits = val >> 2; | 297 | u16 eight_bits = val >> 2; |
298 | u16 twoBits = val & 3; | 298 | u16 two_bits = val & 3; |
299 | 299 | ||
300 | /* no interpolation for these */ | 300 | /* no interpolation for these */ |
301 | if (twoBits == 0 || eightBits == 255) | 301 | if (two_bits == 0 || eight_bits == 255) |
302 | return TEMP_FROM_REG(eightBits); | 302 | return TEMP_FROM_REG(eight_bits); |
303 | 303 | ||
304 | /* do some linear interpolation */ | 304 | /* do some linear interpolation */ |
305 | return (tempLUT[eightBits] * (4 - twoBits) + | 305 | return (temp_lut[eight_bits] * (4 - two_bits) + |
306 | tempLUT[eightBits + 1] * twoBits) * 25; | 306 | temp_lut[eight_bits + 1] * two_bits) * 25; |
307 | } | 307 | } |
308 | 308 | ||
309 | #define DIV_FROM_REG(val) (1 << (val)) | 309 | #define DIV_FROM_REG(val) (1 << (val)) |
@@ -889,8 +889,8 @@ static int via686a_pci_probe(struct pci_dev *dev, | |||
889 | 889 | ||
890 | address = val & ~(VIA686A_EXTENT - 1); | 890 | address = val & ~(VIA686A_EXTENT - 1); |
891 | if (address == 0) { | 891 | if (address == 0) { |
892 | dev_err(&dev->dev, "base address not set - upgrade BIOS " | 892 | dev_err(&dev->dev, |
893 | "or use force_addr=0xaddr\n"); | 893 | "base address not set - upgrade BIOS or use force_addr=0xaddr\n"); |
894 | return -ENODEV; | 894 | return -ENODEV; |
895 | } | 895 | } |
896 | 896 | ||
@@ -899,8 +899,9 @@ static int via686a_pci_probe(struct pci_dev *dev, | |||
899 | return -ENODEV; | 899 | return -ENODEV; |
900 | if (!(val & 0x0001)) { | 900 | if (!(val & 0x0001)) { |
901 | if (!force_addr) { | 901 | if (!force_addr) { |
902 | dev_warn(&dev->dev, "Sensors disabled, enable " | 902 | dev_warn(&dev->dev, |
903 | "with force_addr=0x%x\n", address); | 903 | "Sensors disabled, enable with force_addr=0x%x\n", |
904 | address); | ||
904 | return -ENODEV; | 905 | return -ENODEV; |
905 | } | 906 | } |
906 | 907 | ||
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index dcc62f80f67b..6b2f1a42b3ff 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c | |||
@@ -571,8 +571,9 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | |||
571 | break; | 571 | break; |
572 | default: | 572 | default: |
573 | count = -EINVAL; | 573 | count = -EINVAL; |
574 | dev_warn(dev, "fan div value %ld not supported. " | 574 | dev_warn(dev, |
575 | "Choose one of 1, 2, 4, or 8.\n", val); | 575 | "fan div value %ld not supported. Choose one of 1, 2, 4, or 8.\n", |
576 | val); | ||
576 | goto EXIT; | 577 | goto EXIT; |
577 | } | 578 | } |
578 | vt1211_write8(data, VT1211_REG_FAN_DIV, | 579 | vt1211_write8(data, VT1211_REG_FAN_DIV, |
@@ -674,8 +675,9 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
674 | break; | 675 | break; |
675 | default: | 676 | default: |
676 | count = -EINVAL; | 677 | count = -EINVAL; |
677 | dev_warn(dev, "pwm mode %ld not supported. " | 678 | dev_warn(dev, |
678 | "Choose one of 0 or 2.\n", val); | 679 | "pwm mode %ld not supported. Choose one of 0 or 2.\n", |
680 | val); | ||
679 | goto EXIT; | 681 | goto EXIT; |
680 | } | 682 | } |
681 | vt1211_write8(data, VT1211_REG_PWM_CTL, | 683 | vt1211_write8(data, VT1211_REG_PWM_CTL, |
@@ -700,8 +702,9 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
700 | case SHOW_SET_PWM_AUTO_CHANNELS_TEMP: | 702 | case SHOW_SET_PWM_AUTO_CHANNELS_TEMP: |
701 | if (val < 1 || val > 7) { | 703 | if (val < 1 || val > 7) { |
702 | count = -EINVAL; | 704 | count = -EINVAL; |
703 | dev_warn(dev, "temp channel %ld not supported. " | 705 | dev_warn(dev, |
704 | "Choose a value between 1 and 7.\n", val); | 706 | "temp channel %ld not supported. Choose a value between 1 and 7.\n", |
707 | val); | ||
705 | goto EXIT; | 708 | goto EXIT; |
706 | } | 709 | } |
707 | if (!ISTEMP(val - 1, data->uch_config)) { | 710 | if (!ISTEMP(val - 1, data->uch_config)) { |
@@ -1325,15 +1328,15 @@ static int __init vt1211_init(void) | |||
1325 | 1328 | ||
1326 | if ((uch_config < -1) || (uch_config > 31)) { | 1329 | if ((uch_config < -1) || (uch_config > 31)) { |
1327 | err = -EINVAL; | 1330 | err = -EINVAL; |
1328 | pr_warn("Invalid UCH configuration %d. " | 1331 | pr_warn("Invalid UCH configuration %d. Choose a value between 0 and 31.\n", |
1329 | "Choose a value between 0 and 31.\n", uch_config); | 1332 | uch_config); |
1330 | goto EXIT; | 1333 | goto EXIT; |
1331 | } | 1334 | } |
1332 | 1335 | ||
1333 | if ((int_mode < -1) || (int_mode > 0)) { | 1336 | if ((int_mode < -1) || (int_mode > 0)) { |
1334 | err = -EINVAL; | 1337 | err = -EINVAL; |
1335 | pr_warn("Invalid interrupt mode %d. " | 1338 | pr_warn("Invalid interrupt mode %d. Only mode 0 is supported.\n", |
1336 | "Only mode 0 is supported.\n", int_mode); | 1339 | int_mode); |
1337 | goto EXIT; | 1340 | goto EXIT; |
1338 | } | 1341 | } |
1339 | 1342 | ||
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 988a2a796764..0e7017841f7d 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c | |||
@@ -573,8 +573,9 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
573 | data->fan_div[nr] = 3; | 573 | data->fan_div[nr] = 3; |
574 | break; | 574 | break; |
575 | default: | 575 | default: |
576 | dev_err(dev, "fan_div value %ld not supported. " | 576 | dev_err(dev, |
577 | "Choose one of 1, 2, 4 or 8!\n", val); | 577 | "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", |
578 | val); | ||
578 | mutex_unlock(&data->update_lock); | 579 | mutex_unlock(&data->update_lock); |
579 | return -EINVAL; | 580 | return -EINVAL; |
580 | } | 581 | } |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 0a89211c25f6..016027229e81 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -840,8 +840,8 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
840 | && (reg >= 0xff || (sio_data->kind == nct6775 | 840 | && (reg >= 0xff || (sio_data->kind == nct6775 |
841 | && reg == 0x00)) | 841 | && reg == 0x00)) |
842 | && data->fan_div[i] < 0x07) { | 842 | && data->fan_div[i] < 0x07) { |
843 | dev_dbg(dev, "Increasing fan%d " | 843 | dev_dbg(dev, |
844 | "clock divider from %u to %u\n", | 844 | "Increasing fan%d clock divider from %u to %u\n", |
845 | i + 1, div_from_reg(data->fan_div[i]), | 845 | i + 1, div_from_reg(data->fan_div[i]), |
846 | div_from_reg(data->fan_div[i] + 1)); | 846 | div_from_reg(data->fan_div[i] + 1)); |
847 | data->fan_div[i]++; | 847 | data->fan_div[i]++; |
@@ -1110,9 +1110,9 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
1110 | */ | 1110 | */ |
1111 | data->fan_min[nr] = 254; | 1111 | data->fan_min[nr] = 254; |
1112 | new_div = 7; /* 128 == (1 << 7) */ | 1112 | new_div = 7; /* 128 == (1 << 7) */ |
1113 | dev_warn(dev, "fan%u low limit %lu below minimum %u, set to " | 1113 | dev_warn(dev, |
1114 | "minimum\n", nr + 1, val, | 1114 | "fan%u low limit %lu below minimum %u, set to minimum\n", |
1115 | data->fan_from_reg_min(254, 7)); | 1115 | nr + 1, val, data->fan_from_reg_min(254, 7)); |
1116 | } else if (!reg) { | 1116 | } else if (!reg) { |
1117 | /* | 1117 | /* |
1118 | * Speed above this value cannot possibly be represented, | 1118 | * Speed above this value cannot possibly be represented, |
@@ -1120,9 +1120,9 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
1120 | */ | 1120 | */ |
1121 | data->fan_min[nr] = 1; | 1121 | data->fan_min[nr] = 1; |
1122 | new_div = 0; /* 1 == (1 << 0) */ | 1122 | new_div = 0; /* 1 == (1 << 0) */ |
1123 | dev_warn(dev, "fan%u low limit %lu above maximum %u, set to " | 1123 | dev_warn(dev, |
1124 | "maximum\n", nr + 1, val, | 1124 | "fan%u low limit %lu above maximum %u, set to maximum\n", |
1125 | data->fan_from_reg_min(1, 0)); | 1125 | nr + 1, val, data->fan_from_reg_min(1, 0)); |
1126 | } else { | 1126 | } else { |
1127 | /* | 1127 | /* |
1128 | * Automatically pick the best divider, i.e. the one such | 1128 | * Automatically pick the best divider, i.e. the one such |
@@ -2396,15 +2396,15 @@ static int w83627ehf_probe(struct platform_device *pdev) | |||
2396 | en_vrm10 = superio_inb(sio_data->sioreg, | 2396 | en_vrm10 = superio_inb(sio_data->sioreg, |
2397 | SIO_REG_EN_VRM10); | 2397 | SIO_REG_EN_VRM10); |
2398 | if ((en_vrm10 & 0x08) && data->vrm == 90) { | 2398 | if ((en_vrm10 & 0x08) && data->vrm == 90) { |
2399 | dev_warn(dev, "Setting VID input " | 2399 | dev_warn(dev, |
2400 | "voltage to TTL\n"); | 2400 | "Setting VID input voltage to TTL\n"); |
2401 | superio_outb(sio_data->sioreg, | 2401 | superio_outb(sio_data->sioreg, |
2402 | SIO_REG_EN_VRM10, | 2402 | SIO_REG_EN_VRM10, |
2403 | en_vrm10 & ~0x08); | 2403 | en_vrm10 & ~0x08); |
2404 | } else if (!(en_vrm10 & 0x08) | 2404 | } else if (!(en_vrm10 & 0x08) |
2405 | && data->vrm == 100) { | 2405 | && data->vrm == 100) { |
2406 | dev_warn(dev, "Setting VID input " | 2406 | dev_warn(dev, |
2407 | "voltage to VRM10\n"); | 2407 | "Setting VID input voltage to VRM10\n"); |
2408 | superio_outb(sio_data->sioreg, | 2408 | superio_outb(sio_data->sioreg, |
2409 | SIO_REG_EN_VRM10, | 2409 | SIO_REG_EN_VRM10, |
2410 | en_vrm10 | 0x08); | 2410 | en_vrm10 | 0x08); |
@@ -2420,8 +2420,8 @@ static int w83627ehf_probe(struct platform_device *pdev) | |||
2420 | if (err) | 2420 | if (err) |
2421 | goto exit_release; | 2421 | goto exit_release; |
2422 | } else { | 2422 | } else { |
2423 | dev_info(dev, "VID pins in output mode, CPU VID not " | 2423 | dev_info(dev, |
2424 | "available\n"); | 2424 | "VID pins in output mode, CPU VID not available\n"); |
2425 | } | 2425 | } |
2426 | } | 2426 | } |
2427 | 2427 | ||
@@ -2795,8 +2795,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | |||
2795 | /* Activate logical device if needed */ | 2795 | /* Activate logical device if needed */ |
2796 | val = superio_inb(sioaddr, SIO_REG_ENABLE); | 2796 | val = superio_inb(sioaddr, SIO_REG_ENABLE); |
2797 | if (!(val & 0x01)) { | 2797 | if (!(val & 0x01)) { |
2798 | pr_warn("Forcibly enabling Super-I/O. " | 2798 | pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n"); |
2799 | "Sensor is probably unusable.\n"); | ||
2800 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); | 2799 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); |
2801 | } | 2800 | } |
2802 | 2801 | ||
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index aeec5b1d81c9..f9d513949a38 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -64,8 +64,8 @@ enum chips { w83781d, w83782d, w83783s, as99127f }; | |||
64 | /* Insmod parameters */ | 64 | /* Insmod parameters */ |
65 | static unsigned short force_subclients[4]; | 65 | static unsigned short force_subclients[4]; |
66 | module_param_array(force_subclients, short, NULL, 0); | 66 | module_param_array(force_subclients, short, NULL, 0); |
67 | MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " | 67 | MODULE_PARM_DESC(force_subclients, |
68 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); | 68 | "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); |
69 | 69 | ||
70 | static bool reset; | 70 | static bool reset; |
71 | module_param(reset, bool, 0); | 71 | module_param(reset, bool, 0); |
@@ -826,8 +826,9 @@ store_sensor(struct device *dev, struct device_attribute *da, | |||
826 | data->sens[nr] = val; | 826 | data->sens[nr] = val; |
827 | break; | 827 | break; |
828 | case W83781D_DEFAULT_BETA: | 828 | case W83781D_DEFAULT_BETA: |
829 | dev_warn(dev, "Sensor type %d is deprecated, please use 4 " | 829 | dev_warn(dev, |
830 | "instead\n", W83781D_DEFAULT_BETA); | 830 | "Sensor type %d is deprecated, please use 4 instead\n", |
831 | W83781D_DEFAULT_BETA); | ||
831 | /* fall through */ | 832 | /* fall through */ |
832 | case 4: /* thermistor */ | 833 | case 4: /* thermistor */ |
833 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); | 834 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); |
@@ -874,8 +875,8 @@ w83781d_detect_subclients(struct i2c_client *new_client) | |||
874 | for (i = 2; i <= 3; i++) { | 875 | for (i = 2; i <= 3; i++) { |
875 | if (force_subclients[i] < 0x48 || | 876 | if (force_subclients[i] < 0x48 || |
876 | force_subclients[i] > 0x4f) { | 877 | force_subclients[i] > 0x4f) { |
877 | dev_err(&new_client->dev, "Invalid subclient " | 878 | dev_err(&new_client->dev, |
878 | "address %d; must be 0x48-0x4f\n", | 879 | "Invalid subclient address %d; must be 0x48-0x4f\n", |
879 | force_subclients[i]); | 880 | force_subclients[i]); |
880 | err = -EINVAL; | 881 | err = -EINVAL; |
881 | goto ERROR_SC_1; | 882 | goto ERROR_SC_1; |
@@ -910,9 +911,9 @@ w83781d_detect_subclients(struct i2c_client *new_client) | |||
910 | for (i = 0; i < num_sc; i++) { | 911 | for (i = 0; i < num_sc; i++) { |
911 | data->lm75[i] = i2c_new_dummy(adapter, sc_addr[i]); | 912 | data->lm75[i] = i2c_new_dummy(adapter, sc_addr[i]); |
912 | if (!data->lm75[i]) { | 913 | if (!data->lm75[i]) { |
913 | dev_err(&new_client->dev, "Subclient %d " | 914 | dev_err(&new_client->dev, |
914 | "registration at address 0x%x " | 915 | "Subclient %d registration at address 0x%x failed.\n", |
915 | "failed.\n", i, sc_addr[i]); | 916 | i, sc_addr[i]); |
916 | err = -ENOMEM; | 917 | err = -ENOMEM; |
917 | if (i == 1) | 918 | if (i == 1) |
918 | goto ERROR_SC_3; | 919 | goto ERROR_SC_3; |
@@ -1176,8 +1177,9 @@ w83781d_detect(struct i2c_client *client, struct i2c_board_info *info) | |||
1176 | goto err_nodev; | 1177 | goto err_nodev; |
1177 | 1178 | ||
1178 | if (val1 <= 0x30 && w83781d_alias_detect(client, val1)) { | 1179 | if (val1 <= 0x30 && w83781d_alias_detect(client, val1)) { |
1179 | dev_dbg(&adapter->dev, "Device at 0x%02x appears to " | 1180 | dev_dbg(&adapter->dev, |
1180 | "be the same as ISA device\n", address); | 1181 | "Device at 0x%02x appears to be the same as ISA device\n", |
1182 | address); | ||
1181 | goto err_nodev; | 1183 | goto err_nodev; |
1182 | } | 1184 | } |
1183 | 1185 | ||
@@ -1367,8 +1369,8 @@ w83781d_init_device(struct device *dev) | |||
1367 | * as I see very little reason why this would be needed at | 1369 | * as I see very little reason why this would be needed at |
1368 | * all. | 1370 | * all. |
1369 | */ | 1371 | */ |
1370 | dev_info(dev, "If reset=1 solved a problem you were " | 1372 | dev_info(dev, |
1371 | "having, please report!\n"); | 1373 | "If reset=1 solved a problem you were having, please report!\n"); |
1372 | 1374 | ||
1373 | /* save these registers */ | 1375 | /* save these registers */ |
1374 | i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); | 1376 | i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); |
@@ -1425,8 +1427,8 @@ w83781d_init_device(struct device *dev) | |||
1425 | /* Enable temp2 */ | 1427 | /* Enable temp2 */ |
1426 | tmp = w83781d_read_value(data, W83781D_REG_TEMP2_CONFIG); | 1428 | tmp = w83781d_read_value(data, W83781D_REG_TEMP2_CONFIG); |
1427 | if (tmp & 0x01) { | 1429 | if (tmp & 0x01) { |
1428 | dev_warn(dev, "Enabling temp2, readings " | 1430 | dev_warn(dev, |
1429 | "might not make sense\n"); | 1431 | "Enabling temp2, readings might not make sense\n"); |
1430 | w83781d_write_value(data, W83781D_REG_TEMP2_CONFIG, | 1432 | w83781d_write_value(data, W83781D_REG_TEMP2_CONFIG, |
1431 | tmp & 0xfe); | 1433 | tmp & 0xfe); |
1432 | } | 1434 | } |
@@ -1436,8 +1438,8 @@ w83781d_init_device(struct device *dev) | |||
1436 | tmp = w83781d_read_value(data, | 1438 | tmp = w83781d_read_value(data, |
1437 | W83781D_REG_TEMP3_CONFIG); | 1439 | W83781D_REG_TEMP3_CONFIG); |
1438 | if (tmp & 0x01) { | 1440 | if (tmp & 0x01) { |
1439 | dev_warn(dev, "Enabling temp3, " | 1441 | dev_warn(dev, |
1440 | "readings might not make sense\n"); | 1442 | "Enabling temp3, readings might not make sense\n"); |
1441 | w83781d_write_value(data, | 1443 | w83781d_write_value(data, |
1442 | W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); | 1444 | W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); |
1443 | } | 1445 | } |
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 38dddddf8875..a3feee332e20 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
@@ -56,8 +56,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, | |||
56 | 56 | ||
57 | static unsigned short force_subclients[4]; | 57 | static unsigned short force_subclients[4]; |
58 | module_param_array(force_subclients, short, NULL, 0); | 58 | module_param_array(force_subclients, short, NULL, 0); |
59 | MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " | 59 | MODULE_PARM_DESC(force_subclients, |
60 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); | 60 | "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); |
61 | 61 | ||
62 | static bool reset; | 62 | static bool reset; |
63 | module_param(reset, bool, 0); | 63 | module_param(reset, bool, 0); |
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 5cb83ddf2cc6..0b804895be43 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -54,8 +54,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, | |||
54 | 54 | ||
55 | static unsigned short force_subclients[4]; | 55 | static unsigned short force_subclients[4]; |
56 | module_param_array(force_subclients, short, NULL, 0); | 56 | module_param_array(force_subclients, short, NULL, 0); |
57 | MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " | 57 | MODULE_PARM_DESC(force_subclients, |
58 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); | 58 | "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); |
59 | 59 | ||
60 | static bool init; | 60 | static bool init; |
61 | module_param(init, bool, 0); | 61 | module_param(init, bool, 0); |
@@ -951,8 +951,8 @@ w83792d_detect_subclients(struct i2c_client *new_client) | |||
951 | for (i = 2; i <= 3; i++) { | 951 | for (i = 2; i <= 3; i++) { |
952 | if (force_subclients[i] < 0x48 || | 952 | if (force_subclients[i] < 0x48 || |
953 | force_subclients[i] > 0x4f) { | 953 | force_subclients[i] > 0x4f) { |
954 | dev_err(&new_client->dev, "invalid subclient " | 954 | dev_err(&new_client->dev, |
955 | "address %d; must be 0x48-0x4f\n", | 955 | "invalid subclient address %d; must be 0x48-0x4f\n", |
956 | force_subclients[i]); | 956 | force_subclients[i]); |
957 | err = -ENODEV; | 957 | err = -ENODEV; |
958 | goto ERROR_SC_0; | 958 | goto ERROR_SC_0; |
@@ -969,8 +969,9 @@ w83792d_detect_subclients(struct i2c_client *new_client) | |||
969 | if (!(val & 0x80)) { | 969 | if (!(val & 0x80)) { |
970 | if ((data->lm75[0] != NULL) && | 970 | if ((data->lm75[0] != NULL) && |
971 | ((val & 0x7) == ((val >> 4) & 0x7))) { | 971 | ((val & 0x7) == ((val >> 4) & 0x7))) { |
972 | dev_err(&new_client->dev, "duplicate addresses 0x%x, " | 972 | dev_err(&new_client->dev, |
973 | "use force_subclient\n", data->lm75[0]->addr); | 973 | "duplicate addresses 0x%x, use force_subclient\n", |
974 | data->lm75[0]->addr); | ||
974 | err = -ENODEV; | 975 | err = -ENODEV; |
975 | goto ERROR_SC_1; | 976 | goto ERROR_SC_1; |
976 | } | 977 | } |
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 660427520c53..b0c30a546ff2 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c | |||
@@ -59,8 +59,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, | |||
59 | 59 | ||
60 | static unsigned short force_subclients[4]; | 60 | static unsigned short force_subclients[4]; |
61 | module_param_array(force_subclients, short, NULL, 0); | 61 | module_param_array(force_subclients, short, NULL, 0); |
62 | MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " | 62 | MODULE_PARM_DESC(force_subclients, |
63 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); | 63 | "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); |
64 | 64 | ||
65 | static bool reset; | 65 | static bool reset; |
66 | module_param(reset, bool, 0); | 66 | module_param(reset, bool, 0); |
@@ -1921,8 +1921,8 @@ static int w83793_probe(struct i2c_client *client, | |||
1921 | } | 1921 | } |
1922 | if (i == ARRAY_SIZE(watchdog_minors)) { | 1922 | if (i == ARRAY_SIZE(watchdog_minors)) { |
1923 | data->watchdog_miscdev.minor = 0; | 1923 | data->watchdog_miscdev.minor = 0; |
1924 | dev_warn(&client->dev, "Couldn't register watchdog chardev " | 1924 | dev_warn(&client->dev, |
1925 | "(due to no free minor)\n"); | 1925 | "Couldn't register watchdog chardev (due to no free minor)\n"); |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | mutex_unlock(&watchdog_data_mutex); | 1928 | mutex_unlock(&watchdog_data_mutex); |
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index e226096148eb..908209d24664 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c | |||
@@ -2120,11 +2120,12 @@ static void w83795_check_dynamic_in_limits(struct i2c_client *client) | |||
2120 | &w83795_in[i][3].dev_attr.attr, | 2120 | &w83795_in[i][3].dev_attr.attr, |
2121 | S_IRUGO); | 2121 | S_IRUGO); |
2122 | if (err_max || err_min) | 2122 | if (err_max || err_min) |
2123 | dev_warn(&client->dev, "Failed to set in%d limits " | 2123 | dev_warn(&client->dev, |
2124 | "read-only (%d, %d)\n", i, err_max, err_min); | 2124 | "Failed to set in%d limits read-only (%d, %d)\n", |
2125 | i, err_max, err_min); | ||
2125 | else | 2126 | else |
2126 | dev_info(&client->dev, "in%d limits set dynamically " | 2127 | dev_info(&client->dev, |
2127 | "from VID\n", i); | 2128 | "in%d limits set dynamically from VID\n", i); |
2128 | } | 2129 | } |
2129 | } | 2130 | } |
2130 | 2131 | ||