diff options
Diffstat (limited to 'drivers/hwmon')
61 files changed, 4795 insertions, 918 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 192953b29b28..b8854b94807f 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -30,7 +30,7 @@ config HWMON_VID | |||
30 | 30 | ||
31 | config SENSORS_ABITUGURU | 31 | config SENSORS_ABITUGURU |
32 | tristate "Abit uGuru (rev 1 & 2)" | 32 | tristate "Abit uGuru (rev 1 & 2)" |
33 | depends on EXPERIMENTAL | 33 | depends on X86 && EXPERIMENTAL |
34 | help | 34 | help |
35 | If you say yes here you get support for the sensor part of the first | 35 | If you say yes here you get support for the sensor part of the first |
36 | and second revision of the Abit uGuru chip. The voltage and frequency | 36 | and second revision of the Abit uGuru chip. The voltage and frequency |
@@ -45,7 +45,7 @@ config SENSORS_ABITUGURU | |||
45 | 45 | ||
46 | config SENSORS_ABITUGURU3 | 46 | config SENSORS_ABITUGURU3 |
47 | tristate "Abit uGuru (rev 3)" | 47 | tristate "Abit uGuru (rev 3)" |
48 | depends on HWMON && EXPERIMENTAL | 48 | depends on X86 && EXPERIMENTAL |
49 | help | 49 | help |
50 | If you say yes here you get support for the sensor part of the | 50 | If you say yes here you get support for the sensor part of the |
51 | third revision of the Abit uGuru chip. Only reading the sensors | 51 | third revision of the Abit uGuru chip. Only reading the sensors |
@@ -133,6 +133,16 @@ config SENSORS_ADM9240 | |||
133 | This driver can also be built as a module. If so, the module | 133 | This driver can also be built as a module. If so, the module |
134 | will be called adm9240. | 134 | will be called adm9240. |
135 | 135 | ||
136 | config SENSORS_ADT7470 | ||
137 | tristate "Analog Devices ADT7470" | ||
138 | depends on I2C && EXPERIMENTAL | ||
139 | help | ||
140 | If you say yes here you get support for the Analog Devices | ||
141 | ADT7470 temperature monitoring chips. | ||
142 | |||
143 | This driver can also be built as a module. If so, the module | ||
144 | will be called adt7470. | ||
145 | |||
136 | config SENSORS_K8TEMP | 146 | config SENSORS_K8TEMP |
137 | tristate "AMD Athlon64/FX or Opteron temperature sensor" | 147 | tristate "AMD Athlon64/FX or Opteron temperature sensor" |
138 | depends on X86 && PCI && EXPERIMENTAL | 148 | depends on X86 && PCI && EXPERIMENTAL |
@@ -172,7 +182,7 @@ config SENSORS_AMS_I2C | |||
172 | 182 | ||
173 | config SENSORS_ASB100 | 183 | config SENSORS_ASB100 |
174 | tristate "Asus ASB100 Bach" | 184 | tristate "Asus ASB100 Bach" |
175 | depends on I2C && EXPERIMENTAL | 185 | depends on X86 && I2C && EXPERIMENTAL |
176 | select HWMON_VID | 186 | select HWMON_VID |
177 | help | 187 | help |
178 | If you say yes here you get support for the ASB100 Bach sensor | 188 | If you say yes here you get support for the ASB100 Bach sensor |
@@ -206,19 +216,39 @@ config SENSORS_DS1621 | |||
206 | will be called ds1621. | 216 | will be called ds1621. |
207 | 217 | ||
208 | config SENSORS_F71805F | 218 | config SENSORS_F71805F |
209 | tristate "Fintek F71805F/FG and F71872F/FG" | 219 | tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG" |
210 | depends on EXPERIMENTAL | 220 | depends on EXPERIMENTAL |
211 | help | 221 | help |
212 | If you say yes here you get support for hardware monitoring | 222 | If you say yes here you get support for hardware monitoring |
213 | features of the Fintek F71805F/FG and F71872F/FG Super-I/O | 223 | features of the Fintek F71805F/FG, F71806F/FG and F71872F/FG |
214 | chips. | 224 | Super-I/O chips. |
215 | 225 | ||
216 | This driver can also be built as a module. If so, the module | 226 | This driver can also be built as a module. If so, the module |
217 | will be called f71805f. | 227 | will be called f71805f. |
218 | 228 | ||
229 | config SENSORS_F71882FG | ||
230 | tristate "Fintek F71882FG and F71883FG" | ||
231 | depends on EXPERIMENTAL | ||
232 | help | ||
233 | If you say yes here you get support for hardware monitoring | ||
234 | features of the Fintek F71882FG and F71883FG Super-I/O chips. | ||
235 | |||
236 | This driver can also be built as a module. If so, the module | ||
237 | will be called f71882fg. | ||
238 | |||
239 | config SENSORS_F75375S | ||
240 | tristate "Fintek F75375S/SP and F75373"; | ||
241 | depends on I2C && EXPERIMENTAL | ||
242 | help | ||
243 | If you say yes here you get support for hardware monitoring | ||
244 | features of the Fintek F75375S/SP and F75373 | ||
245 | |||
246 | This driver can also be built as a module. If so, the module | ||
247 | will be called f75375s. | ||
248 | |||
219 | config SENSORS_FSCHER | 249 | config SENSORS_FSCHER |
220 | tristate "FSC Hermes" | 250 | tristate "FSC Hermes" |
221 | depends on I2C | 251 | depends on X86 && I2C |
222 | help | 252 | help |
223 | If you say yes here you get support for Fujitsu Siemens | 253 | If you say yes here you get support for Fujitsu Siemens |
224 | Computers Hermes sensor chips. | 254 | Computers Hermes sensor chips. |
@@ -228,7 +258,7 @@ config SENSORS_FSCHER | |||
228 | 258 | ||
229 | config SENSORS_FSCPOS | 259 | config SENSORS_FSCPOS |
230 | tristate "FSC Poseidon" | 260 | tristate "FSC Poseidon" |
231 | depends on I2C | 261 | depends on X86 && I2C |
232 | help | 262 | help |
233 | If you say yes here you get support for Fujitsu Siemens | 263 | If you say yes here you get support for Fujitsu Siemens |
234 | Computers Poseidon sensor chips. | 264 | Computers Poseidon sensor chips. |
@@ -265,6 +295,19 @@ config SENSORS_CORETEMP | |||
265 | sensor inside your CPU. Supported all are all known variants | 295 | sensor inside your CPU. Supported all are all known variants |
266 | of Intel Core family. | 296 | of Intel Core family. |
267 | 297 | ||
298 | config SENSORS_IBMPEX | ||
299 | tristate "IBM PowerExecutive temperature/power sensors" | ||
300 | select IPMI_SI | ||
301 | depends on IPMI_HANDLER | ||
302 | help | ||
303 | If you say yes here you get support for the temperature and | ||
304 | power sensors in various IBM System X servers that support | ||
305 | PowerExecutive. So far this includes the x3550, x3650, x3655, | ||
306 | x3755, and certain HS20 blades. | ||
307 | |||
308 | This driver can also be built as a module. If so, the module | ||
309 | will be called ibmpex. | ||
310 | |||
268 | config SENSORS_IT87 | 311 | config SENSORS_IT87 |
269 | tristate "ITE IT87xx and compatibles" | 312 | tristate "ITE IT87xx and compatibles" |
270 | select HWMON_VID | 313 | select HWMON_VID |
@@ -401,7 +444,7 @@ config SENSORS_LM92 | |||
401 | 444 | ||
402 | config SENSORS_LM93 | 445 | config SENSORS_LM93 |
403 | tristate "National Semiconductor LM93 and compatibles" | 446 | tristate "National Semiconductor LM93 and compatibles" |
404 | depends on HWMON && I2C | 447 | depends on I2C |
405 | select HWMON_VID | 448 | select HWMON_VID |
406 | help | 449 | help |
407 | If you say yes here you get support for National Semiconductor LM93 | 450 | If you say yes here you get support for National Semiconductor LM93 |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index d04f90031ebf..2f592e2e01b3 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o | |||
22 | obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o | 22 | obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o |
23 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o | 23 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o |
24 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o | 24 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o |
25 | obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o | ||
25 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o | 26 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o |
26 | obj-$(CONFIG_SENSORS_AMS) += ams/ | 27 | obj-$(CONFIG_SENSORS_AMS) += ams/ |
27 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | 28 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o |
@@ -29,11 +30,14 @@ obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o | |||
29 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o | 30 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o |
30 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | 31 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o |
31 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o | 32 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o |
33 | obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o | ||
34 | obj-$(CONFIG_SENSORS_F75375S) += f75375s.o | ||
32 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o | 35 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o |
33 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o | 36 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o |
34 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o | 37 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o |
35 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o | 38 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o |
36 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o | 39 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o |
40 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o | ||
37 | obj-$(CONFIG_SENSORS_IT87) += it87.o | 41 | obj-$(CONFIG_SENSORS_IT87) += it87.o |
38 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o | 42 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o |
39 | obj-$(CONFIG_SENSORS_LM63) += lm63.o | 43 | obj-$(CONFIG_SENSORS_LM63) += lm63.o |
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index d575ee958de5..719151a92fec 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c | |||
@@ -176,7 +176,7 @@ MODULE_PARM_DESC(verbose, "How verbose should the driver be? (0-3):\n" | |||
176 | The structure is dynamically allocated, at the same time when a new | 176 | The structure is dynamically allocated, at the same time when a new |
177 | abituguru device is allocated. */ | 177 | abituguru device is allocated. */ |
178 | struct abituguru_data { | 178 | struct abituguru_data { |
179 | struct class_device *class_dev; /* hwmon registered device */ | 179 | struct device *hwmon_dev; /* hwmon registered device */ |
180 | struct mutex update_lock; /* protect access to data and uGuru */ | 180 | struct mutex update_lock; /* protect access to data and uGuru */ |
181 | unsigned long last_updated; /* In jiffies */ | 181 | unsigned long last_updated; /* In jiffies */ |
182 | unsigned short addr; /* uguru base address */ | 182 | unsigned short addr; /* uguru base address */ |
@@ -1287,11 +1287,11 @@ static int __devinit abituguru_probe(struct platform_device *pdev) | |||
1287 | &abituguru_sysfs_attr[i].dev_attr)) | 1287 | &abituguru_sysfs_attr[i].dev_attr)) |
1288 | goto abituguru_probe_error; | 1288 | goto abituguru_probe_error; |
1289 | 1289 | ||
1290 | data->class_dev = hwmon_device_register(&pdev->dev); | 1290 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
1291 | if (!IS_ERR(data->class_dev)) | 1291 | if (!IS_ERR(data->hwmon_dev)) |
1292 | return 0; /* success */ | 1292 | return 0; /* success */ |
1293 | 1293 | ||
1294 | res = PTR_ERR(data->class_dev); | 1294 | res = PTR_ERR(data->hwmon_dev); |
1295 | abituguru_probe_error: | 1295 | abituguru_probe_error: |
1296 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | 1296 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) |
1297 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | 1297 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); |
@@ -1308,7 +1308,7 @@ static int __devexit abituguru_remove(struct platform_device *pdev) | |||
1308 | int i; | 1308 | int i; |
1309 | struct abituguru_data *data = platform_get_drvdata(pdev); | 1309 | struct abituguru_data *data = platform_get_drvdata(pdev); |
1310 | 1310 | ||
1311 | hwmon_device_unregister(data->class_dev); | 1311 | hwmon_device_unregister(data->hwmon_dev); |
1312 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | 1312 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) |
1313 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | 1313 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); |
1314 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) | 1314 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index cdd8b6dea16d..cb2331bfd9d5 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c | |||
@@ -124,7 +124,7 @@ struct abituguru3_motherboard_info { | |||
124 | The structure is dynamically allocated, at the same time when a new | 124 | The structure is dynamically allocated, at the same time when a new |
125 | abituguru3 device is allocated. */ | 125 | abituguru3 device is allocated. */ |
126 | struct abituguru3_data { | 126 | struct abituguru3_data { |
127 | struct class_device *class_dev; /* hwmon registered device */ | 127 | struct device *hwmon_dev; /* hwmon registered device */ |
128 | struct mutex update_lock; /* protect access to data and uGuru */ | 128 | struct mutex update_lock; /* protect access to data and uGuru */ |
129 | unsigned short addr; /* uguru base address */ | 129 | unsigned short addr; /* uguru base address */ |
130 | char valid; /* !=0 if following fields are valid */ | 130 | char valid; /* !=0 if following fields are valid */ |
@@ -933,9 +933,9 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) | |||
933 | &abituguru3_sysfs_attr[i].dev_attr)) | 933 | &abituguru3_sysfs_attr[i].dev_attr)) |
934 | goto abituguru3_probe_error; | 934 | goto abituguru3_probe_error; |
935 | 935 | ||
936 | data->class_dev = hwmon_device_register(&pdev->dev); | 936 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
937 | if (IS_ERR(data->class_dev)) { | 937 | if (IS_ERR(data->hwmon_dev)) { |
938 | res = PTR_ERR(data->class_dev); | 938 | res = PTR_ERR(data->hwmon_dev); |
939 | goto abituguru3_probe_error; | 939 | goto abituguru3_probe_error; |
940 | } | 940 | } |
941 | 941 | ||
@@ -957,7 +957,7 @@ static int __devexit abituguru3_remove(struct platform_device *pdev) | |||
957 | struct abituguru3_data *data = platform_get_drvdata(pdev); | 957 | struct abituguru3_data *data = platform_get_drvdata(pdev); |
958 | 958 | ||
959 | platform_set_drvdata(pdev, NULL); | 959 | platform_set_drvdata(pdev, NULL); |
960 | hwmon_device_unregister(data->class_dev); | 960 | hwmon_device_unregister(data->hwmon_dev); |
961 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | 961 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) |
962 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | 962 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); |
963 | for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) | 963 | for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) |
diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c index cc8b624a1e51..fcd7fe78f3f9 100644 --- a/drivers/hwmon/ad7418.c +++ b/drivers/hwmon/ad7418.c | |||
@@ -47,7 +47,7 @@ static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN, | |||
47 | 47 | ||
48 | struct ad7418_data { | 48 | struct ad7418_data { |
49 | struct i2c_client client; | 49 | struct i2c_client client; |
50 | struct class_device *class_dev; | 50 | struct device *hwmon_dev; |
51 | struct attribute_group attrs; | 51 | struct attribute_group attrs; |
52 | enum chips type; | 52 | enum chips type; |
53 | struct mutex lock; | 53 | struct mutex lock; |
@@ -172,7 +172,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, | |||
172 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 172 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
173 | struct i2c_client *client = to_i2c_client(dev); | 173 | struct i2c_client *client = to_i2c_client(dev); |
174 | struct ad7418_data *data = i2c_get_clientdata(client); | 174 | struct ad7418_data *data = i2c_get_clientdata(client); |
175 | int temp = simple_strtol(buf, NULL, 10); | 175 | long temp = simple_strtol(buf, NULL, 10); |
176 | 176 | ||
177 | mutex_lock(&data->lock); | 177 | mutex_lock(&data->lock); |
178 | data->temp[attr->index] = LM75_TEMP_TO_REG(temp); | 178 | data->temp[attr->index] = LM75_TEMP_TO_REG(temp); |
@@ -326,9 +326,9 @@ static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind) | |||
326 | if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) | 326 | if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) |
327 | goto exit_detach; | 327 | goto exit_detach; |
328 | 328 | ||
329 | data->class_dev = hwmon_device_register(&client->dev); | 329 | data->hwmon_dev = hwmon_device_register(&client->dev); |
330 | if (IS_ERR(data->class_dev)) { | 330 | if (IS_ERR(data->hwmon_dev)) { |
331 | err = PTR_ERR(data->class_dev); | 331 | err = PTR_ERR(data->hwmon_dev); |
332 | goto exit_remove; | 332 | goto exit_remove; |
333 | } | 333 | } |
334 | 334 | ||
@@ -347,7 +347,7 @@ exit: | |||
347 | static int ad7418_detach_client(struct i2c_client *client) | 347 | static int ad7418_detach_client(struct i2c_client *client) |
348 | { | 348 | { |
349 | struct ad7418_data *data = i2c_get_clientdata(client); | 349 | struct ad7418_data *data = i2c_get_clientdata(client); |
350 | hwmon_device_unregister(data->class_dev); | 350 | hwmon_device_unregister(data->hwmon_dev); |
351 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | 351 | sysfs_remove_group(&client->dev.kobj, &data->attrs); |
352 | i2c_detach_client(client); | 352 | i2c_detach_client(client); |
353 | kfree(data); | 353 | kfree(data); |
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index c466329b2ef4..ebdc6d7db231 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | adm1021.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | adm1021.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | monitoring | 3 | monitoring |
4 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and | 4 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and |
5 | Philip Edelbrock <phil@netroedge.com> | 5 | Philip Edelbrock <phil@netroedge.com> |
6 | 6 | ||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/jiffies.h> | 25 | #include <linux/jiffies.h> |
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/hwmon.h> | 27 | #include <linux/hwmon.h> |
28 | #include <linux/hwmon-sysfs.h> | ||
28 | #include <linux/err.h> | 29 | #include <linux/err.h> |
29 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
30 | 31 | ||
@@ -32,93 +33,77 @@ | |||
32 | /* Addresses to scan */ | 33 | /* Addresses to scan */ |
33 | static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, | 34 | static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, |
34 | 0x29, 0x2a, 0x2b, | 35 | 0x29, 0x2a, 0x2b, |
35 | 0x4c, 0x4d, 0x4e, | 36 | 0x4c, 0x4d, 0x4e, |
36 | I2C_CLIENT_END }; | 37 | I2C_CLIENT_END }; |
37 | 38 | ||
38 | /* Insmod parameters */ | 39 | /* Insmod parameters */ |
39 | I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1066); | 40 | I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, |
41 | mc1066); | ||
40 | 42 | ||
41 | /* adm1021 constants specified below */ | 43 | /* adm1021 constants specified below */ |
42 | 44 | ||
43 | /* The adm1021 registers */ | 45 | /* The adm1021 registers */ |
44 | /* Read-only */ | 46 | /* Read-only */ |
45 | #define ADM1021_REG_TEMP 0x00 | 47 | /* For nr in 0-1 */ |
46 | #define ADM1021_REG_REMOTE_TEMP 0x01 | 48 | #define ADM1021_REG_TEMP(nr) (nr) |
47 | #define ADM1021_REG_STATUS 0x02 | 49 | #define ADM1021_REG_STATUS 0x02 |
48 | #define ADM1021_REG_MAN_ID 0x0FE /* 0x41 = AMD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi*/ | 50 | /* 0x41 = AD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi */ |
49 | #define ADM1021_REG_DEV_ID 0x0FF /* ADM1021 = 0x0X, ADM1023 = 0x3X */ | 51 | #define ADM1021_REG_MAN_ID 0xFE |
50 | #define ADM1021_REG_DIE_CODE 0x0FF /* MAX1617A */ | 52 | /* ADM1021 = 0x0X, ADM1023 = 0x3X */ |
53 | #define ADM1021_REG_DEV_ID 0xFF | ||
51 | /* These use different addresses for reading/writing */ | 54 | /* These use different addresses for reading/writing */ |
52 | #define ADM1021_REG_CONFIG_R 0x03 | 55 | #define ADM1021_REG_CONFIG_R 0x03 |
53 | #define ADM1021_REG_CONFIG_W 0x09 | 56 | #define ADM1021_REG_CONFIG_W 0x09 |
54 | #define ADM1021_REG_CONV_RATE_R 0x04 | 57 | #define ADM1021_REG_CONV_RATE_R 0x04 |
55 | #define ADM1021_REG_CONV_RATE_W 0x0A | 58 | #define ADM1021_REG_CONV_RATE_W 0x0A |
56 | /* These are for the ADM1023's additional precision on the remote temp sensor */ | 59 | /* These are for the ADM1023's additional precision on the remote temp sensor */ |
57 | #define ADM1021_REG_REM_TEMP_PREC 0x010 | 60 | #define ADM1023_REG_REM_TEMP_PREC 0x10 |
58 | #define ADM1021_REG_REM_OFFSET 0x011 | 61 | #define ADM1023_REG_REM_OFFSET 0x11 |
59 | #define ADM1021_REG_REM_OFFSET_PREC 0x012 | 62 | #define ADM1023_REG_REM_OFFSET_PREC 0x12 |
60 | #define ADM1021_REG_REM_TOS_PREC 0x013 | 63 | #define ADM1023_REG_REM_TOS_PREC 0x13 |
61 | #define ADM1021_REG_REM_THYST_PREC 0x014 | 64 | #define ADM1023_REG_REM_THYST_PREC 0x14 |
62 | /* limits */ | 65 | /* limits */ |
63 | #define ADM1021_REG_TOS_R 0x05 | 66 | /* For nr in 0-1 */ |
64 | #define ADM1021_REG_TOS_W 0x0B | 67 | #define ADM1021_REG_TOS_R(nr) (0x05 + 2 * (nr)) |
65 | #define ADM1021_REG_REMOTE_TOS_R 0x07 | 68 | #define ADM1021_REG_TOS_W(nr) (0x0B + 2 * (nr)) |
66 | #define ADM1021_REG_REMOTE_TOS_W 0x0D | 69 | #define ADM1021_REG_THYST_R(nr) (0x06 + 2 * (nr)) |
67 | #define ADM1021_REG_THYST_R 0x06 | 70 | #define ADM1021_REG_THYST_W(nr) (0x0C + 2 * (nr)) |
68 | #define ADM1021_REG_THYST_W 0x0C | ||
69 | #define ADM1021_REG_REMOTE_THYST_R 0x08 | ||
70 | #define ADM1021_REG_REMOTE_THYST_W 0x0E | ||
71 | /* write-only */ | 71 | /* write-only */ |
72 | #define ADM1021_REG_ONESHOT 0x0F | 72 | #define ADM1021_REG_ONESHOT 0x0F |
73 | 73 | ||
74 | |||
75 | /* Conversions. Rounding and limit checking is only done on the TO_REG | ||
76 | variants. Note that you should be a bit careful with which arguments | ||
77 | these macros are called: arguments may be evaluated more than once. | ||
78 | Fixing this is just not worth it. */ | ||
79 | /* Conversions note: 1021 uses normal integer signed-byte format*/ | ||
80 | #define TEMP_FROM_REG(val) (val > 127 ? (val-256)*1000 : val*1000) | ||
81 | #define TEMP_TO_REG(val) (SENSORS_LIMIT((val < 0 ? (val/1000)+256 : val/1000),0,255)) | ||
82 | |||
83 | /* Initial values */ | 74 | /* Initial values */ |
84 | 75 | ||
85 | /* Note: Even though I left the low and high limits named os and hyst, | 76 | /* Note: Even though I left the low and high limits named os and hyst, |
86 | they don't quite work like a thermostat the way the LM75 does. I.e., | 77 | they don't quite work like a thermostat the way the LM75 does. I.e., |
87 | a lower temp than THYST actually triggers an alarm instead of | 78 | a lower temp than THYST actually triggers an alarm instead of |
88 | clearing it. Weird, ey? --Phil */ | 79 | clearing it. Weird, ey? --Phil */ |
89 | 80 | ||
90 | /* Each client has this additional data */ | 81 | /* Each client has this additional data */ |
91 | struct adm1021_data { | 82 | struct adm1021_data { |
92 | struct i2c_client client; | 83 | struct i2c_client client; |
93 | struct class_device *class_dev; | 84 | struct device *hwmon_dev; |
94 | enum chips type; | 85 | enum chips type; |
95 | 86 | ||
96 | struct mutex update_lock; | 87 | struct mutex update_lock; |
97 | char valid; /* !=0 if following fields are valid */ | 88 | char valid; /* !=0 if following fields are valid */ |
98 | unsigned long last_updated; /* In jiffies */ | 89 | unsigned long last_updated; /* In jiffies */ |
99 | 90 | ||
100 | u8 temp_max; /* Register values */ | 91 | s8 temp_max[2]; /* Register values */ |
101 | u8 temp_hyst; | 92 | s8 temp_min[2]; |
102 | u8 temp_input; | 93 | s8 temp[2]; |
103 | u8 remote_temp_max; | 94 | u8 alarms; |
104 | u8 remote_temp_hyst; | 95 | /* Special values for ADM1023 only */ |
105 | u8 remote_temp_input; | 96 | u8 remote_temp_prec; |
106 | u8 alarms; | 97 | u8 remote_temp_os_prec; |
107 | /* Special values for ADM1023 only */ | 98 | u8 remote_temp_hyst_prec; |
108 | u8 remote_temp_prec; | 99 | u8 remote_temp_offset; |
109 | u8 remote_temp_os_prec; | 100 | u8 remote_temp_offset_prec; |
110 | u8 remote_temp_hyst_prec; | ||
111 | u8 remote_temp_offset; | ||
112 | u8 remote_temp_offset_prec; | ||
113 | }; | 101 | }; |
114 | 102 | ||
115 | static int adm1021_attach_adapter(struct i2c_adapter *adapter); | 103 | static int adm1021_attach_adapter(struct i2c_adapter *adapter); |
116 | static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind); | 104 | static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind); |
117 | static void adm1021_init_client(struct i2c_client *client); | 105 | static void adm1021_init_client(struct i2c_client *client); |
118 | static int adm1021_detach_client(struct i2c_client *client); | 106 | static int adm1021_detach_client(struct i2c_client *client); |
119 | static int adm1021_read_value(struct i2c_client *client, u8 reg); | ||
120 | static int adm1021_write_value(struct i2c_client *client, u8 reg, | ||
121 | u16 value); | ||
122 | static struct adm1021_data *adm1021_update_device(struct device *dev); | 107 | static struct adm1021_data *adm1021_update_device(struct device *dev); |
123 | 108 | ||
124 | /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ | 109 | /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ |
@@ -135,53 +120,104 @@ static struct i2c_driver adm1021_driver = { | |||
135 | .detach_client = adm1021_detach_client, | 120 | .detach_client = adm1021_detach_client, |
136 | }; | 121 | }; |
137 | 122 | ||
138 | #define show(value) \ | 123 | static ssize_t show_temp(struct device *dev, |
139 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ | 124 | struct device_attribute *devattr, char *buf) |
140 | { \ | 125 | { |
141 | struct adm1021_data *data = adm1021_update_device(dev); \ | 126 | int index = to_sensor_dev_attr(devattr)->index; |
142 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \ | 127 | struct adm1021_data *data = adm1021_update_device(dev); |
128 | |||
129 | return sprintf(buf, "%d\n", 1000 * data->temp[index]); | ||
143 | } | 130 | } |
144 | show(temp_max); | 131 | |
145 | show(temp_hyst); | 132 | static ssize_t show_temp_max(struct device *dev, |
146 | show(temp_input); | 133 | struct device_attribute *devattr, char *buf) |
147 | show(remote_temp_max); | 134 | { |
148 | show(remote_temp_hyst); | 135 | int index = to_sensor_dev_attr(devattr)->index; |
149 | show(remote_temp_input); | 136 | struct adm1021_data *data = adm1021_update_device(dev); |
150 | 137 | ||
151 | #define show2(value) \ | 138 | return sprintf(buf, "%d\n", 1000 * data->temp_max[index]); |
152 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
153 | { \ | ||
154 | struct adm1021_data *data = adm1021_update_device(dev); \ | ||
155 | return sprintf(buf, "%d\n", data->value); \ | ||
156 | } | 139 | } |
157 | show2(alarms); | 140 | |
158 | 141 | static ssize_t show_temp_min(struct device *dev, | |
159 | #define set(value, reg) \ | 142 | struct device_attribute *devattr, char *buf) |
160 | static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | 143 | { |
161 | { \ | 144 | int index = to_sensor_dev_attr(devattr)->index; |
162 | struct i2c_client *client = to_i2c_client(dev); \ | 145 | struct adm1021_data *data = adm1021_update_device(dev); |
163 | struct adm1021_data *data = i2c_get_clientdata(client); \ | 146 | |
164 | int temp = simple_strtoul(buf, NULL, 10); \ | 147 | return sprintf(buf, "%d\n", 1000 * data->temp_min[index]); |
165 | \ | 148 | } |
166 | mutex_lock(&data->update_lock); \ | 149 | |
167 | data->value = TEMP_TO_REG(temp); \ | 150 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, |
168 | adm1021_write_value(client, reg, data->value); \ | 151 | char *buf) |
169 | mutex_unlock(&data->update_lock); \ | 152 | { |
170 | return count; \ | 153 | int index = to_sensor_dev_attr(attr)->index; |
154 | struct adm1021_data *data = adm1021_update_device(dev); | ||
155 | return sprintf(buf, "%u\n", (data->alarms >> index) & 1); | ||
156 | } | ||
157 | |||
158 | static ssize_t show_alarms(struct device *dev, | ||
159 | struct device_attribute *attr, | ||
160 | char *buf) | ||
161 | { | ||
162 | struct adm1021_data *data = adm1021_update_device(dev); | ||
163 | return sprintf(buf, "%u\n", data->alarms); | ||
171 | } | 164 | } |
172 | set(temp_max, ADM1021_REG_TOS_W); | ||
173 | set(temp_hyst, ADM1021_REG_THYST_W); | ||
174 | set(remote_temp_max, ADM1021_REG_REMOTE_TOS_W); | ||
175 | set(remote_temp_hyst, ADM1021_REG_REMOTE_THYST_W); | ||
176 | |||
177 | static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); | ||
178 | static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst); | ||
179 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL); | ||
180 | static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_remote_temp_max, set_remote_temp_max); | ||
181 | static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_remote_temp_hyst, set_remote_temp_hyst); | ||
182 | static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote_temp_input, NULL); | ||
183 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
184 | 165 | ||
166 | static ssize_t set_temp_max(struct device *dev, | ||
167 | struct device_attribute *devattr, | ||
168 | const char *buf, size_t count) | ||
169 | { | ||
170 | int index = to_sensor_dev_attr(devattr)->index; | ||
171 | struct i2c_client *client = to_i2c_client(dev); | ||
172 | struct adm1021_data *data = i2c_get_clientdata(client); | ||
173 | long temp = simple_strtol(buf, NULL, 10) / 1000; | ||
174 | |||
175 | mutex_lock(&data->update_lock); | ||
176 | data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127); | ||
177 | if (!read_only) | ||
178 | i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index), | ||
179 | data->temp_max[index]); | ||
180 | mutex_unlock(&data->update_lock); | ||
181 | |||
182 | return count; | ||
183 | } | ||
184 | |||
185 | static ssize_t set_temp_min(struct device *dev, | ||
186 | struct device_attribute *devattr, | ||
187 | const char *buf, size_t count) | ||
188 | { | ||
189 | int index = to_sensor_dev_attr(devattr)->index; | ||
190 | struct i2c_client *client = to_i2c_client(dev); | ||
191 | struct adm1021_data *data = i2c_get_clientdata(client); | ||
192 | long temp = simple_strtol(buf, NULL, 10) / 1000; | ||
193 | |||
194 | mutex_lock(&data->update_lock); | ||
195 | data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127); | ||
196 | if (!read_only) | ||
197 | i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index), | ||
198 | data->temp_min[index]); | ||
199 | mutex_unlock(&data->update_lock); | ||
200 | |||
201 | return count; | ||
202 | } | ||
203 | |||
204 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
205 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
206 | set_temp_max, 0); | ||
207 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
208 | set_temp_min, 0); | ||
209 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
210 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
211 | set_temp_max, 1); | ||
212 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
213 | set_temp_min, 1); | ||
214 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
215 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
216 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
217 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
218 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); | ||
219 | |||
220 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
185 | 221 | ||
186 | static int adm1021_attach_adapter(struct i2c_adapter *adapter) | 222 | static int adm1021_attach_adapter(struct i2c_adapter *adapter) |
187 | { | 223 | { |
@@ -191,12 +227,17 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter) | |||
191 | } | 227 | } |
192 | 228 | ||
193 | static struct attribute *adm1021_attributes[] = { | 229 | static struct attribute *adm1021_attributes[] = { |
194 | &dev_attr_temp1_max.attr, | 230 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
195 | &dev_attr_temp1_min.attr, | 231 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
196 | &dev_attr_temp1_input.attr, | 232 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
197 | &dev_attr_temp2_max.attr, | 233 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
198 | &dev_attr_temp2_min.attr, | 234 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
199 | &dev_attr_temp2_input.attr, | 235 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
236 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
237 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
238 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | ||
239 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | ||
240 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
200 | &dev_attr_alarms.attr, | 241 | &dev_attr_alarms.attr, |
201 | NULL | 242 | NULL |
202 | }; | 243 | }; |
@@ -208,35 +249,44 @@ static const struct attribute_group adm1021_group = { | |||
208 | static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) | 249 | static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) |
209 | { | 250 | { |
210 | int i; | 251 | int i; |
211 | struct i2c_client *new_client; | 252 | struct i2c_client *client; |
212 | struct adm1021_data *data; | 253 | struct adm1021_data *data; |
213 | int err = 0; | 254 | int err = 0; |
214 | const char *type_name = ""; | 255 | const char *type_name = ""; |
256 | int conv_rate, status, config; | ||
215 | 257 | ||
216 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 258 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
259 | pr_debug("adm1021: detect failed, " | ||
260 | "smbus byte data not supported!\n"); | ||
217 | goto error0; | 261 | goto error0; |
262 | } | ||
218 | 263 | ||
219 | /* OK. For now, we presume we have a valid client. We now create the | 264 | /* OK. For now, we presume we have a valid client. We now create the |
220 | client structure, even though we cannot fill it completely yet. | 265 | client structure, even though we cannot fill it completely yet. |
221 | But it allows us to access adm1021_{read,write}_value. */ | 266 | But it allows us to access adm1021 register values. */ |
222 | 267 | ||
223 | if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) { | 268 | if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) { |
269 | pr_debug("adm1021: detect failed, kzalloc failed!\n"); | ||
224 | err = -ENOMEM; | 270 | err = -ENOMEM; |
225 | goto error0; | 271 | goto error0; |
226 | } | 272 | } |
227 | 273 | ||
228 | new_client = &data->client; | 274 | client = &data->client; |
229 | i2c_set_clientdata(new_client, data); | 275 | i2c_set_clientdata(client, data); |
230 | new_client->addr = address; | 276 | client->addr = address; |
231 | new_client->adapter = adapter; | 277 | client->adapter = adapter; |
232 | new_client->driver = &adm1021_driver; | 278 | client->driver = &adm1021_driver; |
233 | new_client->flags = 0; | 279 | status = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS); |
280 | conv_rate = i2c_smbus_read_byte_data(client, | ||
281 | ADM1021_REG_CONV_RATE_R); | ||
282 | config = i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R); | ||
234 | 283 | ||
235 | /* Now, we do the remaining detection. */ | 284 | /* Now, we do the remaining detection. */ |
236 | if (kind < 0) { | 285 | if (kind < 0) { |
237 | if ((adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0x03) != 0x00 | 286 | if ((status & 0x03) != 0x00 || (config & 0x3F) != 0x00 |
238 | || (adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x3F) != 0x00 | 287 | || (conv_rate & 0xF8) != 0x00) { |
239 | || (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) & 0xF8) != 0x00) { | 288 | pr_debug("adm1021: detect failed, " |
289 | "chip not detected!\n"); | ||
240 | err = -ENODEV; | 290 | err = -ENODEV; |
241 | goto error1; | 291 | goto error1; |
242 | } | 292 | } |
@@ -244,9 +294,10 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) | |||
244 | 294 | ||
245 | /* Determine the chip type. */ | 295 | /* Determine the chip type. */ |
246 | if (kind <= 0) { | 296 | if (kind <= 0) { |
247 | i = adm1021_read_value(new_client, ADM1021_REG_MAN_ID); | 297 | i = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID); |
248 | if (i == 0x41) | 298 | if (i == 0x41) |
249 | if ((adm1021_read_value(new_client, ADM1021_REG_DEV_ID) & 0x0F0) == 0x030) | 299 | if ((i2c_smbus_read_byte_data(client, |
300 | ADM1021_REG_DEV_ID) & 0xF0) == 0x30) | ||
250 | kind = adm1023; | 301 | kind = adm1023; |
251 | else | 302 | else |
252 | kind = adm1021; | 303 | kind = adm1021; |
@@ -255,15 +306,16 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) | |||
255 | else if (i == 0x23) | 306 | else if (i == 0x23) |
256 | kind = gl523sm; | 307 | kind = gl523sm; |
257 | else if ((i == 0x4d) && | 308 | else if ((i == 0x4d) && |
258 | (adm1021_read_value(new_client, ADM1021_REG_DEV_ID) == 0x01)) | 309 | (i2c_smbus_read_byte_data(client, |
310 | ADM1021_REG_DEV_ID) == 0x01)) | ||
259 | kind = max1617a; | 311 | kind = max1617a; |
260 | else if (i == 0x54) | 312 | else if (i == 0x54) |
261 | kind = mc1066; | 313 | kind = mc1066; |
262 | /* LM84 Mfr ID in a different place, and it has more unused bits */ | 314 | /* LM84 Mfr ID in a different place, and it has more unused bits */ |
263 | else if (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) == 0x00 | 315 | else if (conv_rate == 0x00 |
264 | && (kind == 0 /* skip extra detection */ | 316 | && (kind == 0 /* skip extra detection */ |
265 | || ((adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x7F) == 0x00 | 317 | || ((config & 0x7F) == 0x00 |
266 | && (adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0xAB) == 0x00))) | 318 | && (status & 0xAB) == 0x00))) |
267 | kind = lm84; | 319 | kind = lm84; |
268 | else | 320 | else |
269 | kind = max1617; | 321 | kind = max1617; |
@@ -286,37 +338,38 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) | |||
286 | } else if (kind == mc1066) { | 338 | } else if (kind == mc1066) { |
287 | type_name = "mc1066"; | 339 | type_name = "mc1066"; |
288 | } | 340 | } |
341 | pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n", | ||
342 | type_name, i2c_adapter_id(adapter), address); | ||
289 | 343 | ||
290 | /* Fill in the remaining client fields and put it into the global list */ | 344 | /* Fill in the remaining client fields */ |
291 | strlcpy(new_client->name, type_name, I2C_NAME_SIZE); | 345 | strlcpy(client->name, type_name, I2C_NAME_SIZE); |
292 | data->type = kind; | 346 | data->type = kind; |
293 | data->valid = 0; | ||
294 | mutex_init(&data->update_lock); | 347 | mutex_init(&data->update_lock); |
295 | 348 | ||
296 | /* Tell the I2C layer a new client has arrived */ | 349 | /* Tell the I2C layer a new client has arrived */ |
297 | if ((err = i2c_attach_client(new_client))) | 350 | if ((err = i2c_attach_client(client))) |
298 | goto error1; | 351 | goto error1; |
299 | 352 | ||
300 | /* Initialize the ADM1021 chip */ | 353 | /* Initialize the ADM1021 chip */ |
301 | if (kind != lm84) | 354 | if (kind != lm84 && !read_only) |
302 | adm1021_init_client(new_client); | 355 | adm1021_init_client(client); |
303 | 356 | ||
304 | /* Register sysfs hooks */ | 357 | /* Register sysfs hooks */ |
305 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1021_group))) | 358 | if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group))) |
306 | goto error2; | 359 | goto error2; |
307 | 360 | ||
308 | data->class_dev = hwmon_device_register(&new_client->dev); | 361 | data->hwmon_dev = hwmon_device_register(&client->dev); |
309 | if (IS_ERR(data->class_dev)) { | 362 | if (IS_ERR(data->hwmon_dev)) { |
310 | err = PTR_ERR(data->class_dev); | 363 | err = PTR_ERR(data->hwmon_dev); |
311 | goto error3; | 364 | goto error3; |
312 | } | 365 | } |
313 | 366 | ||
314 | return 0; | 367 | return 0; |
315 | 368 | ||
316 | error3: | 369 | error3: |
317 | sysfs_remove_group(&new_client->dev.kobj, &adm1021_group); | 370 | sysfs_remove_group(&client->dev.kobj, &adm1021_group); |
318 | error2: | 371 | error2: |
319 | i2c_detach_client(new_client); | 372 | i2c_detach_client(client); |
320 | error1: | 373 | error1: |
321 | kfree(data); | 374 | kfree(data); |
322 | error0: | 375 | error0: |
@@ -326,10 +379,10 @@ error0: | |||
326 | static void adm1021_init_client(struct i2c_client *client) | 379 | static void adm1021_init_client(struct i2c_client *client) |
327 | { | 380 | { |
328 | /* Enable ADC and disable suspend mode */ | 381 | /* Enable ADC and disable suspend mode */ |
329 | adm1021_write_value(client, ADM1021_REG_CONFIG_W, | 382 | i2c_smbus_write_byte_data(client, ADM1021_REG_CONFIG_W, |
330 | adm1021_read_value(client, ADM1021_REG_CONFIG_R) & 0xBF); | 383 | i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R) & 0xBF); |
331 | /* Set Conversion rate to 1/sec (this can be tinkered with) */ | 384 | /* Set Conversion rate to 1/sec (this can be tinkered with) */ |
332 | adm1021_write_value(client, ADM1021_REG_CONV_RATE_W, 0x04); | 385 | i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04); |
333 | } | 386 | } |
334 | 387 | ||
335 | static int adm1021_detach_client(struct i2c_client *client) | 388 | static int adm1021_detach_client(struct i2c_client *client) |
@@ -337,7 +390,7 @@ static int adm1021_detach_client(struct i2c_client *client) | |||
337 | struct adm1021_data *data = i2c_get_clientdata(client); | 390 | struct adm1021_data *data = i2c_get_clientdata(client); |
338 | int err; | 391 | int err; |
339 | 392 | ||
340 | hwmon_device_unregister(data->class_dev); | 393 | hwmon_device_unregister(data->hwmon_dev); |
341 | sysfs_remove_group(&client->dev.kobj, &adm1021_group); | 394 | sysfs_remove_group(&client->dev.kobj, &adm1021_group); |
342 | 395 | ||
343 | if ((err = i2c_detach_client(client))) | 396 | if ((err = i2c_detach_client(client))) |
@@ -347,19 +400,6 @@ static int adm1021_detach_client(struct i2c_client *client) | |||
347 | return 0; | 400 | return 0; |
348 | } | 401 | } |
349 | 402 | ||
350 | /* All registers are byte-sized */ | ||
351 | static int adm1021_read_value(struct i2c_client *client, u8 reg) | ||
352 | { | ||
353 | return i2c_smbus_read_byte_data(client, reg); | ||
354 | } | ||
355 | |||
356 | static int adm1021_write_value(struct i2c_client *client, u8 reg, u16 value) | ||
357 | { | ||
358 | if (!read_only) | ||
359 | return i2c_smbus_write_byte_data(client, reg, value); | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static struct adm1021_data *adm1021_update_device(struct device *dev) | 403 | static struct adm1021_data *adm1021_update_device(struct device *dev) |
364 | { | 404 | { |
365 | struct i2c_client *client = to_i2c_client(dev); | 405 | struct i2c_client *client = to_i2c_client(dev); |
@@ -369,21 +409,36 @@ static struct adm1021_data *adm1021_update_device(struct device *dev) | |||
369 | 409 | ||
370 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | 410 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) |
371 | || !data->valid) { | 411 | || !data->valid) { |
412 | int i; | ||
413 | |||
372 | dev_dbg(&client->dev, "Starting adm1021 update\n"); | 414 | dev_dbg(&client->dev, "Starting adm1021 update\n"); |
373 | 415 | ||
374 | data->temp_input = adm1021_read_value(client, ADM1021_REG_TEMP); | 416 | for (i = 0; i < 2; i++) { |
375 | data->temp_max = adm1021_read_value(client, ADM1021_REG_TOS_R); | 417 | data->temp[i] = i2c_smbus_read_byte_data(client, |
376 | data->temp_hyst = adm1021_read_value(client, ADM1021_REG_THYST_R); | 418 | ADM1021_REG_TEMP(i)); |
377 | data->remote_temp_input = adm1021_read_value(client, ADM1021_REG_REMOTE_TEMP); | 419 | data->temp_max[i] = i2c_smbus_read_byte_data(client, |
378 | data->remote_temp_max = adm1021_read_value(client, ADM1021_REG_REMOTE_TOS_R); | 420 | ADM1021_REG_TOS_R(i)); |
379 | data->remote_temp_hyst = adm1021_read_value(client, ADM1021_REG_REMOTE_THYST_R); | 421 | data->temp_min[i] = i2c_smbus_read_byte_data(client, |
380 | data->alarms = adm1021_read_value(client, ADM1021_REG_STATUS) & 0x7c; | 422 | ADM1021_REG_THYST_R(i)); |
423 | } | ||
424 | data->alarms = i2c_smbus_read_byte_data(client, | ||
425 | ADM1021_REG_STATUS) & 0x7c; | ||
381 | if (data->type == adm1023) { | 426 | if (data->type == adm1023) { |
382 | data->remote_temp_prec = adm1021_read_value(client, ADM1021_REG_REM_TEMP_PREC); | 427 | data->remote_temp_prec = |
383 | data->remote_temp_os_prec = adm1021_read_value(client, ADM1021_REG_REM_TOS_PREC); | 428 | i2c_smbus_read_byte_data(client, |
384 | data->remote_temp_hyst_prec = adm1021_read_value(client, ADM1021_REG_REM_THYST_PREC); | 429 | ADM1023_REG_REM_TEMP_PREC); |
385 | data->remote_temp_offset = adm1021_read_value(client, ADM1021_REG_REM_OFFSET); | 430 | data->remote_temp_os_prec = |
386 | data->remote_temp_offset_prec = adm1021_read_value(client, ADM1021_REG_REM_OFFSET_PREC); | 431 | i2c_smbus_read_byte_data(client, |
432 | ADM1023_REG_REM_TOS_PREC); | ||
433 | data->remote_temp_hyst_prec = | ||
434 | i2c_smbus_read_byte_data(client, | ||
435 | ADM1023_REG_REM_THYST_PREC); | ||
436 | data->remote_temp_offset = | ||
437 | i2c_smbus_read_byte_data(client, | ||
438 | ADM1023_REG_REM_OFFSET); | ||
439 | data->remote_temp_offset_prec = | ||
440 | i2c_smbus_read_byte_data(client, | ||
441 | ADM1023_REG_REM_OFFSET_PREC); | ||
387 | } | 442 | } |
388 | data->last_updated = jiffies; | 443 | data->last_updated = jiffies; |
389 | data->valid = 1; | 444 | data->valid = 1; |
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index 8c562885b54b..041ecb0bdf48 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c | |||
@@ -133,7 +133,7 @@ static struct i2c_driver adm1025_driver = { | |||
133 | 133 | ||
134 | struct adm1025_data { | 134 | struct adm1025_data { |
135 | struct i2c_client client; | 135 | struct i2c_client client; |
136 | struct class_device *class_dev; | 136 | struct device *hwmon_dev; |
137 | struct mutex update_lock; | 137 | struct mutex update_lock; |
138 | char valid; /* zero until following fields are valid */ | 138 | char valid; /* zero until following fields are valid */ |
139 | unsigned long last_updated; /* in jiffies */ | 139 | unsigned long last_updated; /* in jiffies */ |
@@ -292,7 +292,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | |||
292 | 292 | ||
293 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) | 293 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) |
294 | { | 294 | { |
295 | struct adm1025_data *data = adm1025_update_device(dev); | 295 | struct adm1025_data *data = dev_get_drvdata(dev); |
296 | return sprintf(buf, "%u\n", data->vrm); | 296 | return sprintf(buf, "%u\n", data->vrm); |
297 | } | 297 | } |
298 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 298 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
@@ -472,9 +472,9 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) | |||
472 | goto exit_remove; | 472 | goto exit_remove; |
473 | } | 473 | } |
474 | 474 | ||
475 | data->class_dev = hwmon_device_register(&new_client->dev); | 475 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
476 | if (IS_ERR(data->class_dev)) { | 476 | if (IS_ERR(data->hwmon_dev)) { |
477 | err = PTR_ERR(data->class_dev); | 477 | err = PTR_ERR(data->hwmon_dev); |
478 | goto exit_remove; | 478 | goto exit_remove; |
479 | } | 479 | } |
480 | 480 | ||
@@ -538,7 +538,7 @@ static int adm1025_detach_client(struct i2c_client *client) | |||
538 | struct adm1025_data *data = i2c_get_clientdata(client); | 538 | struct adm1025_data *data = i2c_get_clientdata(client); |
539 | int err; | 539 | int err; |
540 | 540 | ||
541 | hwmon_device_unregister(data->class_dev); | 541 | hwmon_device_unregister(data->hwmon_dev); |
542 | sysfs_remove_group(&client->dev.kobj, &adm1025_group); | 542 | sysfs_remove_group(&client->dev.kobj, &adm1025_group); |
543 | sysfs_remove_group(&client->dev.kobj, &adm1025_group_opt); | 543 | sysfs_remove_group(&client->dev.kobj, &adm1025_group_opt); |
544 | 544 | ||
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index ba80cd3258c6..aa875ca50d9b 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -260,7 +260,7 @@ struct pwm_data { | |||
260 | 260 | ||
261 | struct adm1026_data { | 261 | struct adm1026_data { |
262 | struct i2c_client client; | 262 | struct i2c_client client; |
263 | struct class_device *class_dev; | 263 | struct device *hwmon_dev; |
264 | enum chips type; | 264 | enum chips type; |
265 | 265 | ||
266 | struct mutex update_lock; | 266 | struct mutex update_lock; |
@@ -1221,7 +1221,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | |||
1221 | 1221 | ||
1222 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 1222 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
1223 | { | 1223 | { |
1224 | struct adm1026_data *data = adm1026_update_device(dev); | 1224 | struct adm1026_data *data = dev_get_drvdata(dev); |
1225 | return sprintf(buf,"%d\n", data->vrm); | 1225 | return sprintf(buf,"%d\n", data->vrm); |
1226 | } | 1226 | } |
1227 | static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, | 1227 | static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, |
@@ -1676,9 +1676,9 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, | |||
1676 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1026_group))) | 1676 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1026_group))) |
1677 | goto exitdetach; | 1677 | goto exitdetach; |
1678 | 1678 | ||
1679 | data->class_dev = hwmon_device_register(&new_client->dev); | 1679 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
1680 | if (IS_ERR(data->class_dev)) { | 1680 | if (IS_ERR(data->hwmon_dev)) { |
1681 | err = PTR_ERR(data->class_dev); | 1681 | err = PTR_ERR(data->hwmon_dev); |
1682 | goto exitremove; | 1682 | goto exitremove; |
1683 | } | 1683 | } |
1684 | 1684 | ||
@@ -1698,7 +1698,7 @@ exit: | |||
1698 | static int adm1026_detach_client(struct i2c_client *client) | 1698 | static int adm1026_detach_client(struct i2c_client *client) |
1699 | { | 1699 | { |
1700 | struct adm1026_data *data = i2c_get_clientdata(client); | 1700 | struct adm1026_data *data = i2c_get_clientdata(client); |
1701 | hwmon_device_unregister(data->class_dev); | 1701 | hwmon_device_unregister(data->hwmon_dev); |
1702 | sysfs_remove_group(&client->dev.kobj, &adm1026_group); | 1702 | sysfs_remove_group(&client->dev.kobj, &adm1026_group); |
1703 | i2c_detach_client(client); | 1703 | i2c_detach_client(client); |
1704 | kfree(data); | 1704 | kfree(data); |
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 73ce31b31511..0bc897dffa27 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c | |||
@@ -141,7 +141,7 @@ static struct i2c_driver adm1029_driver = { | |||
141 | 141 | ||
142 | struct adm1029_data { | 142 | struct adm1029_data { |
143 | struct i2c_client client; | 143 | struct i2c_client client; |
144 | struct class_device *class_dev; | 144 | struct device *hwmon_dev; |
145 | struct mutex update_lock; | 145 | struct mutex update_lock; |
146 | char valid; /* zero until following fields are valid */ | 146 | char valid; /* zero until following fields are valid */ |
147 | unsigned long last_updated; /* in jiffies */ | 147 | unsigned long last_updated; /* in jiffies */ |
@@ -391,9 +391,9 @@ static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind) | |||
391 | if ((err = sysfs_create_group(&client->dev.kobj, &adm1029_group))) | 391 | if ((err = sysfs_create_group(&client->dev.kobj, &adm1029_group))) |
392 | goto exit_detach; | 392 | goto exit_detach; |
393 | 393 | ||
394 | data->class_dev = hwmon_device_register(&client->dev); | 394 | data->hwmon_dev = hwmon_device_register(&client->dev); |
395 | if (IS_ERR(data->class_dev)) { | 395 | if (IS_ERR(data->hwmon_dev)) { |
396 | err = PTR_ERR(data->class_dev); | 396 | err = PTR_ERR(data->hwmon_dev); |
397 | goto exit_remove_files; | 397 | goto exit_remove_files; |
398 | } | 398 | } |
399 | 399 | ||
@@ -431,7 +431,7 @@ static int adm1029_detach_client(struct i2c_client *client) | |||
431 | struct adm1029_data *data = i2c_get_clientdata(client); | 431 | struct adm1029_data *data = i2c_get_clientdata(client); |
432 | int err; | 432 | int err; |
433 | 433 | ||
434 | hwmon_device_unregister(data->class_dev); | 434 | hwmon_device_unregister(data->hwmon_dev); |
435 | sysfs_remove_group(&client->dev.kobj, &adm1029_group); | 435 | sysfs_remove_group(&client->dev.kobj, &adm1029_group); |
436 | 436 | ||
437 | if ((err = i2c_detach_client(client))) | 437 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 122683fc91d0..37cfc101da5e 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c | |||
@@ -70,7 +70,7 @@ typedef u8 auto_chan_table_t[8][2]; | |||
70 | /* Each client has this additional data */ | 70 | /* Each client has this additional data */ |
71 | struct adm1031_data { | 71 | struct adm1031_data { |
72 | struct i2c_client client; | 72 | struct i2c_client client; |
73 | struct class_device *class_dev; | 73 | struct device *hwmon_dev; |
74 | struct mutex update_lock; | 74 | struct mutex update_lock; |
75 | int chip_type; | 75 | int chip_type; |
76 | char valid; /* !=0 if following fields are valid */ | 76 | char valid; /* !=0 if following fields are valid */ |
@@ -853,9 +853,9 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) | |||
853 | goto exit_remove; | 853 | goto exit_remove; |
854 | } | 854 | } |
855 | 855 | ||
856 | data->class_dev = hwmon_device_register(&new_client->dev); | 856 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
857 | if (IS_ERR(data->class_dev)) { | 857 | if (IS_ERR(data->hwmon_dev)) { |
858 | err = PTR_ERR(data->class_dev); | 858 | err = PTR_ERR(data->hwmon_dev); |
859 | goto exit_remove; | 859 | goto exit_remove; |
860 | } | 860 | } |
861 | 861 | ||
@@ -877,7 +877,7 @@ static int adm1031_detach_client(struct i2c_client *client) | |||
877 | struct adm1031_data *data = i2c_get_clientdata(client); | 877 | struct adm1031_data *data = i2c_get_clientdata(client); |
878 | int ret; | 878 | int ret; |
879 | 879 | ||
880 | hwmon_device_unregister(data->class_dev); | 880 | hwmon_device_unregister(data->hwmon_dev); |
881 | sysfs_remove_group(&client->dev.kobj, &adm1031_group); | 881 | sysfs_remove_group(&client->dev.kobj, &adm1031_group); |
882 | sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt); | 882 | sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt); |
883 | if ((ret = i2c_detach_client(client)) != 0) { | 883 | if ((ret = i2c_detach_client(client)) != 0) { |
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index aad594adf0c7..c17d0b6b3283 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -150,7 +150,7 @@ static struct i2c_driver adm9240_driver = { | |||
150 | struct adm9240_data { | 150 | struct adm9240_data { |
151 | enum chips type; | 151 | enum chips type; |
152 | struct i2c_client client; | 152 | struct i2c_client client; |
153 | struct class_device *class_dev; | 153 | struct device *hwmon_dev; |
154 | struct mutex update_lock; | 154 | struct mutex update_lock; |
155 | char valid; | 155 | char valid; |
156 | unsigned long last_updated_measure; | 156 | unsigned long last_updated_measure; |
@@ -590,9 +590,9 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
590 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group))) | 590 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group))) |
591 | goto exit_detach; | 591 | goto exit_detach; |
592 | 592 | ||
593 | data->class_dev = hwmon_device_register(&new_client->dev); | 593 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
594 | if (IS_ERR(data->class_dev)) { | 594 | if (IS_ERR(data->hwmon_dev)) { |
595 | err = PTR_ERR(data->class_dev); | 595 | err = PTR_ERR(data->hwmon_dev); |
596 | goto exit_remove; | 596 | goto exit_remove; |
597 | } | 597 | } |
598 | 598 | ||
@@ -620,7 +620,7 @@ static int adm9240_detach_client(struct i2c_client *client) | |||
620 | struct adm9240_data *data = i2c_get_clientdata(client); | 620 | struct adm9240_data *data = i2c_get_clientdata(client); |
621 | int err; | 621 | int err; |
622 | 622 | ||
623 | hwmon_device_unregister(data->class_dev); | 623 | hwmon_device_unregister(data->hwmon_dev); |
624 | sysfs_remove_group(&client->dev.kobj, &adm9240_group); | 624 | sysfs_remove_group(&client->dev.kobj, &adm9240_group); |
625 | 625 | ||
626 | if ((err = i2c_detach_client(client))) | 626 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c new file mode 100644 index 000000000000..9810aaa0489d --- /dev/null +++ b/drivers/hwmon/adt7470.c | |||
@@ -0,0 +1,1050 @@ | |||
1 | /* | ||
2 | * A hwmon driver for the Analog Devices ADT7470 | ||
3 | * Copyright (C) 2007 IBM | ||
4 | * | ||
5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.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/delay.h> | ||
30 | #include <linux/log2.h> | ||
31 | |||
32 | /* Addresses to scan */ | ||
33 | static unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; | ||
34 | |||
35 | /* Insmod parameters */ | ||
36 | I2C_CLIENT_INSMOD_1(adt7470); | ||
37 | |||
38 | /* ADT7470 registers */ | ||
39 | #define ADT7470_REG_BASE_ADDR 0x20 | ||
40 | #define ADT7470_REG_TEMP_BASE_ADDR 0x20 | ||
41 | #define ADT7470_REG_TEMP_MAX_ADDR 0x29 | ||
42 | #define ADT7470_REG_FAN_BASE_ADDR 0x2A | ||
43 | #define ADT7470_REG_FAN_MAX_ADDR 0x31 | ||
44 | #define ADT7470_REG_PWM_BASE_ADDR 0x32 | ||
45 | #define ADT7470_REG_PWM_MAX_ADDR 0x35 | ||
46 | #define ADT7470_REG_PWM_MAX_BASE_ADDR 0x38 | ||
47 | #define ADT7470_REG_PWM_MAX_MAX_ADDR 0x3B | ||
48 | #define ADT7470_REG_CFG 0x40 | ||
49 | #define ADT7470_FSPD_MASK 0x04 | ||
50 | #define ADT7470_REG_ALARM1 0x41 | ||
51 | #define ADT7470_REG_ALARM2 0x42 | ||
52 | #define ADT7470_REG_TEMP_LIMITS_BASE_ADDR 0x44 | ||
53 | #define ADT7470_REG_TEMP_LIMITS_MAX_ADDR 0x57 | ||
54 | #define ADT7470_REG_FAN_MIN_BASE_ADDR 0x58 | ||
55 | #define ADT7470_REG_FAN_MIN_MAX_ADDR 0x5F | ||
56 | #define ADT7470_REG_FAN_MAX_BASE_ADDR 0x60 | ||
57 | #define ADT7470_REG_FAN_MAX_MAX_ADDR 0x67 | ||
58 | #define ADT7470_REG_PWM_CFG_BASE_ADDR 0x68 | ||
59 | #define ADT7470_REG_PWM12_CFG 0x68 | ||
60 | #define ADT7470_PWM2_AUTO_MASK 0x40 | ||
61 | #define ADT7470_PWM1_AUTO_MASK 0x80 | ||
62 | #define ADT7470_REG_PWM34_CFG 0x69 | ||
63 | #define ADT7470_PWM3_AUTO_MASK 0x40 | ||
64 | #define ADT7470_PWM4_AUTO_MASK 0x80 | ||
65 | #define ADT7470_REG_PWM_MIN_BASE_ADDR 0x6A | ||
66 | #define ADT7470_REG_PWM_MIN_MAX_ADDR 0x6D | ||
67 | #define ADT7470_REG_PWM_TEMP_MIN_BASE_ADDR 0x6E | ||
68 | #define ADT7470_REG_PWM_TEMP_MIN_MAX_ADDR 0x71 | ||
69 | #define ADT7470_REG_ACOUSTICS12 0x75 | ||
70 | #define ADT7470_REG_ACOUSTICS34 0x76 | ||
71 | #define ADT7470_REG_DEVICE 0x3D | ||
72 | #define ADT7470_REG_VENDOR 0x3E | ||
73 | #define ADT7470_REG_REVISION 0x3F | ||
74 | #define ADT7470_REG_ALARM1_MASK 0x72 | ||
75 | #define ADT7470_REG_ALARM2_MASK 0x73 | ||
76 | #define ADT7470_REG_PWM_AUTO_TEMP_BASE_ADDR 0x7C | ||
77 | #define ADT7470_REG_PWM_AUTO_TEMP_MAX_ADDR 0x7D | ||
78 | #define ADT7470_REG_MAX_ADDR 0x81 | ||
79 | |||
80 | #define ADT7470_TEMP_COUNT 10 | ||
81 | #define ADT7470_TEMP_REG(x) (ADT7470_REG_TEMP_BASE_ADDR + (x)) | ||
82 | #define ADT7470_TEMP_MIN_REG(x) (ADT7470_REG_TEMP_LIMITS_BASE_ADDR + ((x) * 2)) | ||
83 | #define ADT7470_TEMP_MAX_REG(x) (ADT7470_REG_TEMP_LIMITS_BASE_ADDR + \ | ||
84 | ((x) * 2) + 1) | ||
85 | |||
86 | #define ADT7470_FAN_COUNT 4 | ||
87 | #define ADT7470_REG_FAN(x) (ADT7470_REG_FAN_BASE_ADDR + ((x) * 2)) | ||
88 | #define ADT7470_REG_FAN_MIN(x) (ADT7470_REG_FAN_MIN_BASE_ADDR + ((x) * 2)) | ||
89 | #define ADT7470_REG_FAN_MAX(x) (ADT7470_REG_FAN_MAX_BASE_ADDR + ((x) * 2)) | ||
90 | |||
91 | #define ADT7470_PWM_COUNT 4 | ||
92 | #define ADT7470_REG_PWM(x) (ADT7470_REG_PWM_BASE_ADDR + (x)) | ||
93 | #define ADT7470_REG_PWM_MAX(x) (ADT7470_REG_PWM_MAX_BASE_ADDR + (x)) | ||
94 | #define ADT7470_REG_PWM_MIN(x) (ADT7470_REG_PWM_MIN_BASE_ADDR + (x)) | ||
95 | #define ADT7470_REG_PWM_TMIN(x) (ADT7470_REG_PWM_TEMP_MIN_BASE_ADDR + (x)) | ||
96 | #define ADT7470_REG_PWM_CFG(x) (ADT7470_REG_PWM_CFG_BASE_ADDR + ((x) / 2)) | ||
97 | #define ADT7470_REG_PWM_AUTO_TEMP(x) (ADT7470_REG_PWM_AUTO_TEMP_BASE_ADDR + \ | ||
98 | ((x) / 2)) | ||
99 | |||
100 | #define ADT7470_VENDOR 0x41 | ||
101 | #define ADT7470_DEVICE 0x70 | ||
102 | /* datasheet only mentions a revision 2 */ | ||
103 | #define ADT7470_REVISION 0x02 | ||
104 | |||
105 | /* "all temps" according to hwmon sysfs interface spec */ | ||
106 | #define ADT7470_PWM_ALL_TEMPS 0x3FF | ||
107 | |||
108 | /* How often do we reread sensors values? (In jiffies) */ | ||
109 | #define SENSOR_REFRESH_INTERVAL (5 * HZ) | ||
110 | |||
111 | /* How often do we reread sensor limit values? (In jiffies) */ | ||
112 | #define LIMIT_REFRESH_INTERVAL (60 * HZ) | ||
113 | |||
114 | /* sleep 1s while gathering temperature data */ | ||
115 | #define TEMP_COLLECTION_TIME 1000 | ||
116 | |||
117 | #define power_of_2(x) (((x) & ((x) - 1)) == 0) | ||
118 | |||
119 | /* datasheet says to divide this number by the fan reading to get fan rpm */ | ||
120 | #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) | ||
121 | #define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM | ||
122 | #define FAN_PERIOD_INVALID 65535 | ||
123 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | ||
124 | |||
125 | struct adt7470_data { | ||
126 | struct i2c_client client; | ||
127 | struct device *hwmon_dev; | ||
128 | struct attribute_group attrs; | ||
129 | struct mutex lock; | ||
130 | char sensors_valid; | ||
131 | char limits_valid; | ||
132 | unsigned long sensors_last_updated; /* In jiffies */ | ||
133 | unsigned long limits_last_updated; /* In jiffies */ | ||
134 | |||
135 | s8 temp[ADT7470_TEMP_COUNT]; | ||
136 | s8 temp_min[ADT7470_TEMP_COUNT]; | ||
137 | s8 temp_max[ADT7470_TEMP_COUNT]; | ||
138 | u16 fan[ADT7470_FAN_COUNT]; | ||
139 | u16 fan_min[ADT7470_FAN_COUNT]; | ||
140 | u16 fan_max[ADT7470_FAN_COUNT]; | ||
141 | u16 alarms, alarms_mask; | ||
142 | u8 force_pwm_max; | ||
143 | u8 pwm[ADT7470_PWM_COUNT]; | ||
144 | u8 pwm_max[ADT7470_PWM_COUNT]; | ||
145 | u8 pwm_automatic[ADT7470_PWM_COUNT]; | ||
146 | u8 pwm_min[ADT7470_PWM_COUNT]; | ||
147 | s8 pwm_tmin[ADT7470_PWM_COUNT]; | ||
148 | u8 pwm_auto_temp[ADT7470_PWM_COUNT]; | ||
149 | }; | ||
150 | |||
151 | static int adt7470_attach_adapter(struct i2c_adapter *adapter); | ||
152 | static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind); | ||
153 | static int adt7470_detach_client(struct i2c_client *client); | ||
154 | |||
155 | static struct i2c_driver adt7470_driver = { | ||
156 | .driver = { | ||
157 | .name = "adt7470", | ||
158 | }, | ||
159 | .attach_adapter = adt7470_attach_adapter, | ||
160 | .detach_client = adt7470_detach_client, | ||
161 | }; | ||
162 | |||
163 | /* | ||
164 | * 16-bit registers on the ADT7470 are low-byte first. The data sheet says | ||
165 | * that the low byte must be read before the high byte. | ||
166 | */ | ||
167 | static inline int adt7470_read_word_data(struct i2c_client *client, u8 reg) | ||
168 | { | ||
169 | u16 foo; | ||
170 | foo = i2c_smbus_read_byte_data(client, reg); | ||
171 | foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8); | ||
172 | return foo; | ||
173 | } | ||
174 | |||
175 | static inline int adt7470_write_word_data(struct i2c_client *client, u8 reg, | ||
176 | u16 value) | ||
177 | { | ||
178 | return i2c_smbus_write_byte_data(client, reg, value & 0xFF) | ||
179 | && i2c_smbus_write_byte_data(client, reg + 1, value >> 8); | ||
180 | } | ||
181 | |||
182 | static void adt7470_init_client(struct i2c_client *client) | ||
183 | { | ||
184 | int reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | ||
185 | |||
186 | if (reg < 0) { | ||
187 | dev_err(&client->dev, "cannot read configuration register\n"); | ||
188 | } else { | ||
189 | /* start monitoring (and do a self-test) */ | ||
190 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg | 3); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | static struct adt7470_data *adt7470_update_device(struct device *dev) | ||
195 | { | ||
196 | struct i2c_client *client = to_i2c_client(dev); | ||
197 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
198 | unsigned long local_jiffies = jiffies; | ||
199 | u8 cfg; | ||
200 | int i; | ||
201 | |||
202 | mutex_lock(&data->lock); | ||
203 | if (time_before(local_jiffies, data->sensors_last_updated + | ||
204 | SENSOR_REFRESH_INTERVAL) | ||
205 | && data->sensors_valid) | ||
206 | goto no_sensor_update; | ||
207 | |||
208 | /* start reading temperature sensors */ | ||
209 | cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | ||
210 | cfg |= 0x80; | ||
211 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); | ||
212 | |||
213 | /* | ||
214 | * Delay is 200ms * number of tmp05 sensors. Too bad | ||
215 | * there's no way to figure out how many are connected. | ||
216 | * For now, assume 1s will work. | ||
217 | */ | ||
218 | msleep(TEMP_COLLECTION_TIME); | ||
219 | |||
220 | /* done reading temperature sensors */ | ||
221 | cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | ||
222 | cfg &= ~0x80; | ||
223 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); | ||
224 | |||
225 | for (i = 0; i < ADT7470_TEMP_COUNT; i++) | ||
226 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
227 | ADT7470_TEMP_REG(i)); | ||
228 | |||
229 | for (i = 0; i < ADT7470_FAN_COUNT; i++) | ||
230 | data->fan[i] = adt7470_read_word_data(client, | ||
231 | ADT7470_REG_FAN(i)); | ||
232 | |||
233 | for (i = 0; i < ADT7470_PWM_COUNT; i++) { | ||
234 | int reg; | ||
235 | int reg_mask; | ||
236 | |||
237 | data->pwm[i] = i2c_smbus_read_byte_data(client, | ||
238 | ADT7470_REG_PWM(i)); | ||
239 | |||
240 | if (i % 2) | ||
241 | reg_mask = ADT7470_PWM2_AUTO_MASK; | ||
242 | else | ||
243 | reg_mask = ADT7470_PWM1_AUTO_MASK; | ||
244 | |||
245 | reg = ADT7470_REG_PWM_CFG(i); | ||
246 | if (i2c_smbus_read_byte_data(client, reg) & reg_mask) | ||
247 | data->pwm_automatic[i] = 1; | ||
248 | else | ||
249 | data->pwm_automatic[i] = 0; | ||
250 | |||
251 | reg = ADT7470_REG_PWM_AUTO_TEMP(i); | ||
252 | cfg = i2c_smbus_read_byte_data(client, reg); | ||
253 | if (!(i % 2)) | ||
254 | data->pwm_auto_temp[i] = cfg >> 4; | ||
255 | else | ||
256 | data->pwm_auto_temp[i] = cfg & 0xF; | ||
257 | } | ||
258 | |||
259 | if (i2c_smbus_read_byte_data(client, ADT7470_REG_CFG) & | ||
260 | ADT7470_FSPD_MASK) | ||
261 | data->force_pwm_max = 1; | ||
262 | else | ||
263 | data->force_pwm_max = 0; | ||
264 | |||
265 | data->alarms = adt7470_read_word_data(client, ADT7470_REG_ALARM1); | ||
266 | data->alarms_mask = adt7470_read_word_data(client, | ||
267 | ADT7470_REG_ALARM1_MASK); | ||
268 | |||
269 | data->sensors_last_updated = local_jiffies; | ||
270 | data->sensors_valid = 1; | ||
271 | |||
272 | no_sensor_update: | ||
273 | if (time_before(local_jiffies, data->limits_last_updated + | ||
274 | LIMIT_REFRESH_INTERVAL) | ||
275 | && data->limits_valid) | ||
276 | goto out; | ||
277 | |||
278 | for (i = 0; i < ADT7470_TEMP_COUNT; i++) { | ||
279 | data->temp_min[i] = i2c_smbus_read_byte_data(client, | ||
280 | ADT7470_TEMP_MIN_REG(i)); | ||
281 | data->temp_max[i] = i2c_smbus_read_byte_data(client, | ||
282 | ADT7470_TEMP_MAX_REG(i)); | ||
283 | } | ||
284 | |||
285 | for (i = 0; i < ADT7470_FAN_COUNT; i++) { | ||
286 | data->fan_min[i] = adt7470_read_word_data(client, | ||
287 | ADT7470_REG_FAN_MIN(i)); | ||
288 | data->fan_max[i] = adt7470_read_word_data(client, | ||
289 | ADT7470_REG_FAN_MAX(i)); | ||
290 | } | ||
291 | |||
292 | for (i = 0; i < ADT7470_PWM_COUNT; i++) { | ||
293 | data->pwm_max[i] = i2c_smbus_read_byte_data(client, | ||
294 | ADT7470_REG_PWM_MAX(i)); | ||
295 | data->pwm_min[i] = i2c_smbus_read_byte_data(client, | ||
296 | ADT7470_REG_PWM_MIN(i)); | ||
297 | data->pwm_tmin[i] = i2c_smbus_read_byte_data(client, | ||
298 | ADT7470_REG_PWM_TMIN(i)); | ||
299 | } | ||
300 | |||
301 | data->limits_last_updated = local_jiffies; | ||
302 | data->limits_valid = 1; | ||
303 | |||
304 | out: | ||
305 | mutex_unlock(&data->lock); | ||
306 | return data; | ||
307 | } | ||
308 | |||
309 | static ssize_t show_temp_min(struct device *dev, | ||
310 | struct device_attribute *devattr, | ||
311 | char *buf) | ||
312 | { | ||
313 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
314 | struct adt7470_data *data = adt7470_update_device(dev); | ||
315 | return sprintf(buf, "%d\n", 1000 * data->temp_min[attr->index]); | ||
316 | } | ||
317 | |||
318 | static ssize_t set_temp_min(struct device *dev, | ||
319 | struct device_attribute *devattr, | ||
320 | const char *buf, | ||
321 | size_t count) | ||
322 | { | ||
323 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
324 | struct i2c_client *client = to_i2c_client(dev); | ||
325 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
326 | int temp = simple_strtol(buf, NULL, 10) / 1000; | ||
327 | |||
328 | mutex_lock(&data->lock); | ||
329 | data->temp_min[attr->index] = temp; | ||
330 | i2c_smbus_write_byte_data(client, ADT7470_TEMP_MIN_REG(attr->index), | ||
331 | temp); | ||
332 | mutex_unlock(&data->lock); | ||
333 | |||
334 | return count; | ||
335 | } | ||
336 | |||
337 | static ssize_t show_temp_max(struct device *dev, | ||
338 | struct device_attribute *devattr, | ||
339 | char *buf) | ||
340 | { | ||
341 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
342 | struct adt7470_data *data = adt7470_update_device(dev); | ||
343 | return sprintf(buf, "%d\n", 1000 * data->temp_max[attr->index]); | ||
344 | } | ||
345 | |||
346 | static ssize_t set_temp_max(struct device *dev, | ||
347 | struct device_attribute *devattr, | ||
348 | const char *buf, | ||
349 | size_t count) | ||
350 | { | ||
351 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
352 | struct i2c_client *client = to_i2c_client(dev); | ||
353 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
354 | int temp = simple_strtol(buf, NULL, 10) / 1000; | ||
355 | |||
356 | mutex_lock(&data->lock); | ||
357 | data->temp_max[attr->index] = temp; | ||
358 | i2c_smbus_write_byte_data(client, ADT7470_TEMP_MAX_REG(attr->index), | ||
359 | temp); | ||
360 | mutex_unlock(&data->lock); | ||
361 | |||
362 | return count; | ||
363 | } | ||
364 | |||
365 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
366 | char *buf) | ||
367 | { | ||
368 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
369 | struct adt7470_data *data = adt7470_update_device(dev); | ||
370 | return sprintf(buf, "%d\n", 1000 * data->temp[attr->index]); | ||
371 | } | ||
372 | |||
373 | static ssize_t show_alarms(struct device *dev, | ||
374 | struct device_attribute *devattr, | ||
375 | char *buf) | ||
376 | { | ||
377 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
378 | struct adt7470_data *data = adt7470_update_device(dev); | ||
379 | |||
380 | if (attr->index) | ||
381 | return sprintf(buf, "%x\n", data->alarms); | ||
382 | else | ||
383 | return sprintf(buf, "%x\n", data->alarms_mask); | ||
384 | } | ||
385 | |||
386 | static ssize_t show_fan_max(struct device *dev, | ||
387 | struct device_attribute *devattr, | ||
388 | char *buf) | ||
389 | { | ||
390 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
391 | struct adt7470_data *data = adt7470_update_device(dev); | ||
392 | |||
393 | if (FAN_DATA_VALID(data->fan_max[attr->index])) | ||
394 | return sprintf(buf, "%d\n", | ||
395 | FAN_PERIOD_TO_RPM(data->fan_max[attr->index])); | ||
396 | else | ||
397 | return sprintf(buf, "0\n"); | ||
398 | } | ||
399 | |||
400 | static ssize_t set_fan_max(struct device *dev, | ||
401 | struct device_attribute *devattr, | ||
402 | const char *buf, size_t count) | ||
403 | { | ||
404 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
405 | struct i2c_client *client = to_i2c_client(dev); | ||
406 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
407 | int temp = simple_strtol(buf, NULL, 10); | ||
408 | |||
409 | if (!temp) | ||
410 | return -EINVAL; | ||
411 | temp = FAN_RPM_TO_PERIOD(temp); | ||
412 | |||
413 | mutex_lock(&data->lock); | ||
414 | data->fan_max[attr->index] = temp; | ||
415 | adt7470_write_word_data(client, ADT7470_REG_FAN_MAX(attr->index), temp); | ||
416 | mutex_unlock(&data->lock); | ||
417 | |||
418 | return count; | ||
419 | } | ||
420 | |||
421 | static ssize_t show_fan_min(struct device *dev, | ||
422 | struct device_attribute *devattr, | ||
423 | char *buf) | ||
424 | { | ||
425 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
426 | struct adt7470_data *data = adt7470_update_device(dev); | ||
427 | |||
428 | if (FAN_DATA_VALID(data->fan_min[attr->index])) | ||
429 | return sprintf(buf, "%d\n", | ||
430 | FAN_PERIOD_TO_RPM(data->fan_min[attr->index])); | ||
431 | else | ||
432 | return sprintf(buf, "0\n"); | ||
433 | } | ||
434 | |||
435 | static ssize_t set_fan_min(struct device *dev, | ||
436 | struct device_attribute *devattr, | ||
437 | const char *buf, size_t count) | ||
438 | { | ||
439 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
440 | struct i2c_client *client = to_i2c_client(dev); | ||
441 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
442 | int temp = simple_strtol(buf, NULL, 10); | ||
443 | |||
444 | if (!temp) | ||
445 | return -EINVAL; | ||
446 | temp = FAN_RPM_TO_PERIOD(temp); | ||
447 | |||
448 | mutex_lock(&data->lock); | ||
449 | data->fan_min[attr->index] = temp; | ||
450 | adt7470_write_word_data(client, ADT7470_REG_FAN_MIN(attr->index), temp); | ||
451 | mutex_unlock(&data->lock); | ||
452 | |||
453 | return count; | ||
454 | } | ||
455 | |||
456 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
457 | char *buf) | ||
458 | { | ||
459 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
460 | struct adt7470_data *data = adt7470_update_device(dev); | ||
461 | |||
462 | if (FAN_DATA_VALID(data->fan[attr->index])) | ||
463 | return sprintf(buf, "%d\n", | ||
464 | FAN_PERIOD_TO_RPM(data->fan[attr->index])); | ||
465 | else | ||
466 | return sprintf(buf, "0\n"); | ||
467 | } | ||
468 | |||
469 | static ssize_t show_force_pwm_max(struct device *dev, | ||
470 | struct device_attribute *devattr, | ||
471 | char *buf) | ||
472 | { | ||
473 | struct adt7470_data *data = adt7470_update_device(dev); | ||
474 | return sprintf(buf, "%d\n", data->force_pwm_max); | ||
475 | } | ||
476 | |||
477 | static ssize_t set_force_pwm_max(struct device *dev, | ||
478 | struct device_attribute *devattr, | ||
479 | const char *buf, | ||
480 | size_t count) | ||
481 | { | ||
482 | struct i2c_client *client = to_i2c_client(dev); | ||
483 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
484 | int temp = simple_strtol(buf, NULL, 10); | ||
485 | u8 reg; | ||
486 | |||
487 | mutex_lock(&data->lock); | ||
488 | data->force_pwm_max = temp; | ||
489 | reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | ||
490 | if (temp) | ||
491 | reg |= ADT7470_FSPD_MASK; | ||
492 | else | ||
493 | reg &= ~ADT7470_FSPD_MASK; | ||
494 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg); | ||
495 | mutex_unlock(&data->lock); | ||
496 | |||
497 | return count; | ||
498 | } | ||
499 | |||
500 | static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, | ||
501 | char *buf) | ||
502 | { | ||
503 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
504 | struct adt7470_data *data = adt7470_update_device(dev); | ||
505 | return sprintf(buf, "%d\n", data->pwm[attr->index]); | ||
506 | } | ||
507 | |||
508 | static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | ||
509 | const char *buf, size_t count) | ||
510 | { | ||
511 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
512 | struct i2c_client *client = to_i2c_client(dev); | ||
513 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
514 | int temp = simple_strtol(buf, NULL, 10); | ||
515 | |||
516 | mutex_lock(&data->lock); | ||
517 | data->pwm[attr->index] = temp; | ||
518 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM(attr->index), temp); | ||
519 | mutex_unlock(&data->lock); | ||
520 | |||
521 | return count; | ||
522 | } | ||
523 | |||
524 | static ssize_t show_pwm_max(struct device *dev, | ||
525 | struct device_attribute *devattr, | ||
526 | char *buf) | ||
527 | { | ||
528 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
529 | struct adt7470_data *data = adt7470_update_device(dev); | ||
530 | return sprintf(buf, "%d\n", data->pwm_max[attr->index]); | ||
531 | } | ||
532 | |||
533 | static ssize_t set_pwm_max(struct device *dev, | ||
534 | struct device_attribute *devattr, | ||
535 | const char *buf, | ||
536 | size_t count) | ||
537 | { | ||
538 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
539 | struct i2c_client *client = to_i2c_client(dev); | ||
540 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
541 | int temp = simple_strtol(buf, NULL, 10); | ||
542 | |||
543 | mutex_lock(&data->lock); | ||
544 | data->pwm_max[attr->index] = temp; | ||
545 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_MAX(attr->index), | ||
546 | temp); | ||
547 | mutex_unlock(&data->lock); | ||
548 | |||
549 | return count; | ||
550 | } | ||
551 | |||
552 | static ssize_t show_pwm_min(struct device *dev, | ||
553 | struct device_attribute *devattr, | ||
554 | char *buf) | ||
555 | { | ||
556 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
557 | struct adt7470_data *data = adt7470_update_device(dev); | ||
558 | return sprintf(buf, "%d\n", data->pwm_min[attr->index]); | ||
559 | } | ||
560 | |||
561 | static ssize_t set_pwm_min(struct device *dev, | ||
562 | struct device_attribute *devattr, | ||
563 | const char *buf, | ||
564 | size_t count) | ||
565 | { | ||
566 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
567 | struct i2c_client *client = to_i2c_client(dev); | ||
568 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
569 | int temp = simple_strtol(buf, NULL, 10); | ||
570 | |||
571 | mutex_lock(&data->lock); | ||
572 | data->pwm_min[attr->index] = temp; | ||
573 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_MIN(attr->index), | ||
574 | temp); | ||
575 | mutex_unlock(&data->lock); | ||
576 | |||
577 | return count; | ||
578 | } | ||
579 | |||
580 | static ssize_t show_pwm_tmax(struct device *dev, | ||
581 | struct device_attribute *devattr, | ||
582 | char *buf) | ||
583 | { | ||
584 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
585 | struct adt7470_data *data = adt7470_update_device(dev); | ||
586 | /* the datasheet says that tmax = tmin + 20C */ | ||
587 | return sprintf(buf, "%d\n", 1000 * (20 + data->pwm_tmin[attr->index])); | ||
588 | } | ||
589 | |||
590 | static ssize_t show_pwm_tmin(struct device *dev, | ||
591 | struct device_attribute *devattr, | ||
592 | char *buf) | ||
593 | { | ||
594 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
595 | struct adt7470_data *data = adt7470_update_device(dev); | ||
596 | return sprintf(buf, "%d\n", 1000 * data->pwm_tmin[attr->index]); | ||
597 | } | ||
598 | |||
599 | static ssize_t set_pwm_tmin(struct device *dev, | ||
600 | struct device_attribute *devattr, | ||
601 | const char *buf, | ||
602 | size_t count) | ||
603 | { | ||
604 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
605 | struct i2c_client *client = to_i2c_client(dev); | ||
606 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
607 | int temp = simple_strtol(buf, NULL, 10) / 1000; | ||
608 | |||
609 | mutex_lock(&data->lock); | ||
610 | data->pwm_tmin[attr->index] = temp; | ||
611 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_TMIN(attr->index), | ||
612 | temp); | ||
613 | mutex_unlock(&data->lock); | ||
614 | |||
615 | return count; | ||
616 | } | ||
617 | |||
618 | static ssize_t show_pwm_auto(struct device *dev, | ||
619 | struct device_attribute *devattr, | ||
620 | char *buf) | ||
621 | { | ||
622 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
623 | struct adt7470_data *data = adt7470_update_device(dev); | ||
624 | return sprintf(buf, "%d\n", 1 + data->pwm_automatic[attr->index]); | ||
625 | } | ||
626 | |||
627 | static ssize_t set_pwm_auto(struct device *dev, | ||
628 | struct device_attribute *devattr, | ||
629 | const char *buf, | ||
630 | size_t count) | ||
631 | { | ||
632 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
633 | struct i2c_client *client = to_i2c_client(dev); | ||
634 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
635 | int temp = simple_strtol(buf, NULL, 10); | ||
636 | int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index); | ||
637 | int pwm_auto_reg_mask; | ||
638 | u8 reg; | ||
639 | |||
640 | if (attr->index % 2) | ||
641 | pwm_auto_reg_mask = ADT7470_PWM2_AUTO_MASK; | ||
642 | else | ||
643 | pwm_auto_reg_mask = ADT7470_PWM1_AUTO_MASK; | ||
644 | |||
645 | if (temp != 2 && temp != 1) | ||
646 | return -EINVAL; | ||
647 | temp--; | ||
648 | |||
649 | mutex_lock(&data->lock); | ||
650 | data->pwm_automatic[attr->index] = temp; | ||
651 | reg = i2c_smbus_read_byte_data(client, pwm_auto_reg); | ||
652 | if (temp) | ||
653 | reg |= pwm_auto_reg_mask; | ||
654 | else | ||
655 | reg &= ~pwm_auto_reg_mask; | ||
656 | i2c_smbus_write_byte_data(client, pwm_auto_reg, reg); | ||
657 | mutex_unlock(&data->lock); | ||
658 | |||
659 | return count; | ||
660 | } | ||
661 | |||
662 | static ssize_t show_pwm_auto_temp(struct device *dev, | ||
663 | struct device_attribute *devattr, | ||
664 | char *buf) | ||
665 | { | ||
666 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
667 | struct adt7470_data *data = adt7470_update_device(dev); | ||
668 | u8 ctrl = data->pwm_auto_temp[attr->index]; | ||
669 | |||
670 | if (ctrl) | ||
671 | return sprintf(buf, "%d\n", 1 << (ctrl - 1)); | ||
672 | else | ||
673 | return sprintf(buf, "%d\n", ADT7470_PWM_ALL_TEMPS); | ||
674 | } | ||
675 | |||
676 | static int cvt_auto_temp(int input) | ||
677 | { | ||
678 | if (input == ADT7470_PWM_ALL_TEMPS) | ||
679 | return 0; | ||
680 | if (input < 1 || !power_of_2(input)) | ||
681 | return -EINVAL; | ||
682 | return ilog2(input) + 1; | ||
683 | } | ||
684 | |||
685 | static ssize_t set_pwm_auto_temp(struct device *dev, | ||
686 | struct device_attribute *devattr, | ||
687 | const char *buf, | ||
688 | size_t count) | ||
689 | { | ||
690 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
691 | struct i2c_client *client = to_i2c_client(dev); | ||
692 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
693 | int temp = cvt_auto_temp(simple_strtol(buf, NULL, 10)); | ||
694 | int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index); | ||
695 | u8 reg; | ||
696 | |||
697 | if (temp < 0) | ||
698 | return temp; | ||
699 | |||
700 | mutex_lock(&data->lock); | ||
701 | data->pwm_automatic[attr->index] = temp; | ||
702 | reg = i2c_smbus_read_byte_data(client, pwm_auto_reg); | ||
703 | |||
704 | if (!(attr->index % 2)) { | ||
705 | reg &= 0xF; | ||
706 | reg |= (temp << 4) & 0xF0; | ||
707 | } else { | ||
708 | reg &= 0xF0; | ||
709 | reg |= temp & 0xF; | ||
710 | } | ||
711 | |||
712 | i2c_smbus_write_byte_data(client, pwm_auto_reg, reg); | ||
713 | mutex_unlock(&data->lock); | ||
714 | |||
715 | return count; | ||
716 | } | ||
717 | |||
718 | static SENSOR_DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL, 0); | ||
719 | static SENSOR_DEVICE_ATTR(alarm_mask, S_IRUGO, show_alarms, NULL, 1); | ||
720 | |||
721 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
722 | set_temp_max, 0); | ||
723 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
724 | set_temp_max, 1); | ||
725 | static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
726 | set_temp_max, 2); | ||
727 | static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
728 | set_temp_max, 3); | ||
729 | static SENSOR_DEVICE_ATTR(temp5_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
730 | set_temp_max, 4); | ||
731 | static SENSOR_DEVICE_ATTR(temp6_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
732 | set_temp_max, 5); | ||
733 | static SENSOR_DEVICE_ATTR(temp7_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
734 | set_temp_max, 6); | ||
735 | static SENSOR_DEVICE_ATTR(temp8_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
736 | set_temp_max, 7); | ||
737 | static SENSOR_DEVICE_ATTR(temp9_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
738 | set_temp_max, 8); | ||
739 | static SENSOR_DEVICE_ATTR(temp10_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
740 | set_temp_max, 9); | ||
741 | |||
742 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
743 | set_temp_min, 0); | ||
744 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
745 | set_temp_min, 1); | ||
746 | static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
747 | set_temp_min, 2); | ||
748 | static SENSOR_DEVICE_ATTR(temp4_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
749 | set_temp_min, 3); | ||
750 | static SENSOR_DEVICE_ATTR(temp5_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
751 | set_temp_min, 4); | ||
752 | static SENSOR_DEVICE_ATTR(temp6_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
753 | set_temp_min, 5); | ||
754 | static SENSOR_DEVICE_ATTR(temp7_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
755 | set_temp_min, 6); | ||
756 | static SENSOR_DEVICE_ATTR(temp8_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
757 | set_temp_min, 7); | ||
758 | static SENSOR_DEVICE_ATTR(temp9_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
759 | set_temp_min, 8); | ||
760 | static SENSOR_DEVICE_ATTR(temp10_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
761 | set_temp_min, 9); | ||
762 | |||
763 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
764 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
765 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); | ||
766 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); | ||
767 | static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4); | ||
768 | static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_temp, NULL, 5); | ||
769 | static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_temp, NULL, 6); | ||
770 | static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_temp, NULL, 7); | ||
771 | static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_temp, NULL, 8); | ||
772 | static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, show_temp, NULL, 9); | ||
773 | |||
774 | static SENSOR_DEVICE_ATTR(fan1_max, S_IWUSR | S_IRUGO, show_fan_max, | ||
775 | set_fan_max, 0); | ||
776 | static SENSOR_DEVICE_ATTR(fan2_max, S_IWUSR | S_IRUGO, show_fan_max, | ||
777 | set_fan_max, 1); | ||
778 | static SENSOR_DEVICE_ATTR(fan3_max, S_IWUSR | S_IRUGO, show_fan_max, | ||
779 | set_fan_max, 2); | ||
780 | static SENSOR_DEVICE_ATTR(fan4_max, S_IWUSR | S_IRUGO, show_fan_max, | ||
781 | set_fan_max, 3); | ||
782 | |||
783 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
784 | set_fan_min, 0); | ||
785 | static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
786 | set_fan_min, 1); | ||
787 | static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
788 | set_fan_min, 2); | ||
789 | static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
790 | set_fan_min, 3); | ||
791 | |||
792 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); | ||
793 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); | ||
794 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); | ||
795 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); | ||
796 | |||
797 | static SENSOR_DEVICE_ATTR(force_pwm_max, S_IWUSR | S_IRUGO, | ||
798 | show_force_pwm_max, set_force_pwm_max, 0); | ||
799 | |||
800 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); | ||
801 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); | ||
802 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); | ||
803 | static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); | ||
804 | |||
805 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
806 | show_pwm_min, set_pwm_min, 0); | ||
807 | static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
808 | show_pwm_min, set_pwm_min, 1); | ||
809 | static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
810 | show_pwm_min, set_pwm_min, 2); | ||
811 | static SENSOR_DEVICE_ATTR(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
812 | show_pwm_min, set_pwm_min, 3); | ||
813 | |||
814 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
815 | show_pwm_max, set_pwm_max, 0); | ||
816 | static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
817 | show_pwm_max, set_pwm_max, 1); | ||
818 | static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
819 | show_pwm_max, set_pwm_max, 2); | ||
820 | static SENSOR_DEVICE_ATTR(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
821 | show_pwm_max, set_pwm_max, 3); | ||
822 | |||
823 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
824 | show_pwm_tmin, set_pwm_tmin, 0); | ||
825 | static SENSOR_DEVICE_ATTR(pwm2_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
826 | show_pwm_tmin, set_pwm_tmin, 1); | ||
827 | static SENSOR_DEVICE_ATTR(pwm3_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
828 | show_pwm_tmin, set_pwm_tmin, 2); | ||
829 | static SENSOR_DEVICE_ATTR(pwm4_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
830 | show_pwm_tmin, set_pwm_tmin, 3); | ||
831 | |||
832 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IRUGO, show_pwm_tmax, | ||
833 | NULL, 0); | ||
834 | static SENSOR_DEVICE_ATTR(pwm2_auto_point2_temp, S_IRUGO, show_pwm_tmax, | ||
835 | NULL, 1); | ||
836 | static SENSOR_DEVICE_ATTR(pwm3_auto_point2_temp, S_IRUGO, show_pwm_tmax, | ||
837 | NULL, 2); | ||
838 | static SENSOR_DEVICE_ATTR(pwm4_auto_point2_temp, S_IRUGO, show_pwm_tmax, | ||
839 | NULL, 3); | ||
840 | |||
841 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
842 | set_pwm_auto, 0); | ||
843 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
844 | set_pwm_auto, 1); | ||
845 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
846 | set_pwm_auto, 2); | ||
847 | static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
848 | set_pwm_auto, 3); | ||
849 | |||
850 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
851 | show_pwm_auto_temp, set_pwm_auto_temp, 0); | ||
852 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
853 | show_pwm_auto_temp, set_pwm_auto_temp, 1); | ||
854 | static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
855 | show_pwm_auto_temp, set_pwm_auto_temp, 2); | ||
856 | static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
857 | show_pwm_auto_temp, set_pwm_auto_temp, 3); | ||
858 | |||
859 | static struct attribute *adt7470_attr[] = | ||
860 | { | ||
861 | &sensor_dev_attr_alarms.dev_attr.attr, | ||
862 | &sensor_dev_attr_alarm_mask.dev_attr.attr, | ||
863 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
864 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
865 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
866 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
867 | &sensor_dev_attr_temp5_max.dev_attr.attr, | ||
868 | &sensor_dev_attr_temp6_max.dev_attr.attr, | ||
869 | &sensor_dev_attr_temp7_max.dev_attr.attr, | ||
870 | &sensor_dev_attr_temp8_max.dev_attr.attr, | ||
871 | &sensor_dev_attr_temp9_max.dev_attr.attr, | ||
872 | &sensor_dev_attr_temp10_max.dev_attr.attr, | ||
873 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
874 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
875 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
876 | &sensor_dev_attr_temp4_min.dev_attr.attr, | ||
877 | &sensor_dev_attr_temp5_min.dev_attr.attr, | ||
878 | &sensor_dev_attr_temp6_min.dev_attr.attr, | ||
879 | &sensor_dev_attr_temp7_min.dev_attr.attr, | ||
880 | &sensor_dev_attr_temp8_min.dev_attr.attr, | ||
881 | &sensor_dev_attr_temp9_min.dev_attr.attr, | ||
882 | &sensor_dev_attr_temp10_min.dev_attr.attr, | ||
883 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
884 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
885 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
886 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
887 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
888 | &sensor_dev_attr_temp6_input.dev_attr.attr, | ||
889 | &sensor_dev_attr_temp7_input.dev_attr.attr, | ||
890 | &sensor_dev_attr_temp8_input.dev_attr.attr, | ||
891 | &sensor_dev_attr_temp9_input.dev_attr.attr, | ||
892 | &sensor_dev_attr_temp10_input.dev_attr.attr, | ||
893 | &sensor_dev_attr_fan1_max.dev_attr.attr, | ||
894 | &sensor_dev_attr_fan2_max.dev_attr.attr, | ||
895 | &sensor_dev_attr_fan3_max.dev_attr.attr, | ||
896 | &sensor_dev_attr_fan4_max.dev_attr.attr, | ||
897 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
898 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
899 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
900 | &sensor_dev_attr_fan4_min.dev_attr.attr, | ||
901 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
902 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
903 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
904 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
905 | &sensor_dev_attr_force_pwm_max.dev_attr.attr, | ||
906 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
907 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
908 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
909 | &sensor_dev_attr_pwm4.dev_attr.attr, | ||
910 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | ||
911 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, | ||
912 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, | ||
913 | &sensor_dev_attr_pwm4_auto_point1_pwm.dev_attr.attr, | ||
914 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, | ||
915 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, | ||
916 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, | ||
917 | &sensor_dev_attr_pwm4_auto_point2_pwm.dev_attr.attr, | ||
918 | &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, | ||
919 | &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr, | ||
920 | &sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr, | ||
921 | &sensor_dev_attr_pwm4_auto_point1_temp.dev_attr.attr, | ||
922 | &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, | ||
923 | &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr, | ||
924 | &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr, | ||
925 | &sensor_dev_attr_pwm4_auto_point2_temp.dev_attr.attr, | ||
926 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
927 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
928 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
929 | &sensor_dev_attr_pwm4_enable.dev_attr.attr, | ||
930 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, | ||
931 | &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, | ||
932 | &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, | ||
933 | &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr, | ||
934 | NULL | ||
935 | }; | ||
936 | |||
937 | static int adt7470_attach_adapter(struct i2c_adapter *adapter) | ||
938 | { | ||
939 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
940 | return 0; | ||
941 | return i2c_probe(adapter, &addr_data, adt7470_detect); | ||
942 | } | ||
943 | |||
944 | static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind) | ||
945 | { | ||
946 | struct i2c_client *client; | ||
947 | struct adt7470_data *data; | ||
948 | int err = 0; | ||
949 | |||
950 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
951 | goto exit; | ||
952 | |||
953 | if (!(data = kzalloc(sizeof(struct adt7470_data), GFP_KERNEL))) { | ||
954 | err = -ENOMEM; | ||
955 | goto exit; | ||
956 | } | ||
957 | |||
958 | client = &data->client; | ||
959 | client->addr = address; | ||
960 | client->adapter = adapter; | ||
961 | client->driver = &adt7470_driver; | ||
962 | |||
963 | i2c_set_clientdata(client, data); | ||
964 | |||
965 | mutex_init(&data->lock); | ||
966 | |||
967 | if (kind <= 0) { | ||
968 | int vendor, device, revision; | ||
969 | |||
970 | vendor = i2c_smbus_read_byte_data(client, ADT7470_REG_VENDOR); | ||
971 | if (vendor != ADT7470_VENDOR) { | ||
972 | err = -ENODEV; | ||
973 | goto exit_free; | ||
974 | } | ||
975 | |||
976 | device = i2c_smbus_read_byte_data(client, ADT7470_REG_DEVICE); | ||
977 | if (device != ADT7470_DEVICE) { | ||
978 | err = -ENODEV; | ||
979 | goto exit_free; | ||
980 | } | ||
981 | |||
982 | revision = i2c_smbus_read_byte_data(client, | ||
983 | ADT7470_REG_REVISION); | ||
984 | if (revision != ADT7470_REVISION) { | ||
985 | err = -ENODEV; | ||
986 | goto exit_free; | ||
987 | } | ||
988 | } else | ||
989 | dev_dbg(&adapter->dev, "detection forced\n"); | ||
990 | |||
991 | strlcpy(client->name, "adt7470", I2C_NAME_SIZE); | ||
992 | |||
993 | if ((err = i2c_attach_client(client))) | ||
994 | goto exit_free; | ||
995 | |||
996 | dev_info(&client->dev, "%s chip found\n", client->name); | ||
997 | |||
998 | /* Initialize the ADT7470 chip */ | ||
999 | adt7470_init_client(client); | ||
1000 | |||
1001 | /* Register sysfs hooks */ | ||
1002 | data->attrs.attrs = adt7470_attr; | ||
1003 | if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) | ||
1004 | goto exit_detach; | ||
1005 | |||
1006 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
1007 | if (IS_ERR(data->hwmon_dev)) { | ||
1008 | err = PTR_ERR(data->hwmon_dev); | ||
1009 | goto exit_remove; | ||
1010 | } | ||
1011 | |||
1012 | return 0; | ||
1013 | |||
1014 | exit_remove: | ||
1015 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | ||
1016 | exit_detach: | ||
1017 | i2c_detach_client(client); | ||
1018 | exit_free: | ||
1019 | kfree(data); | ||
1020 | exit: | ||
1021 | return err; | ||
1022 | } | ||
1023 | |||
1024 | static int adt7470_detach_client(struct i2c_client *client) | ||
1025 | { | ||
1026 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
1027 | |||
1028 | hwmon_device_unregister(data->hwmon_dev); | ||
1029 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | ||
1030 | i2c_detach_client(client); | ||
1031 | kfree(data); | ||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | static int __init adt7470_init(void) | ||
1036 | { | ||
1037 | return i2c_add_driver(&adt7470_driver); | ||
1038 | } | ||
1039 | |||
1040 | static void __exit adt7470_exit(void) | ||
1041 | { | ||
1042 | i2c_del_driver(&adt7470_driver); | ||
1043 | } | ||
1044 | |||
1045 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
1046 | MODULE_DESCRIPTION("ADT7470 driver"); | ||
1047 | MODULE_LICENSE("GPL"); | ||
1048 | |||
1049 | module_init(adt7470_init); | ||
1050 | module_exit(adt7470_exit); | ||
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 941729a131f5..21ff8e126889 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -127,7 +127,7 @@ static s16 rest_x; | |||
127 | static s16 rest_y; | 127 | static s16 rest_y; |
128 | static struct timer_list applesmc_timer; | 128 | static struct timer_list applesmc_timer; |
129 | static struct input_dev *applesmc_idev; | 129 | static struct input_dev *applesmc_idev; |
130 | static struct class_device *hwmon_class_dev; | 130 | static struct device *hwmon_dev; |
131 | 131 | ||
132 | /* Indicates whether this computer has an accelerometer. */ | 132 | /* Indicates whether this computer has an accelerometer. */ |
133 | static unsigned int applesmc_accelerometer; | 133 | static unsigned int applesmc_accelerometer; |
@@ -1287,9 +1287,9 @@ static int __init applesmc_init(void) | |||
1287 | goto out_light_wq; | 1287 | goto out_light_wq; |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | hwmon_class_dev = hwmon_device_register(&pdev->dev); | 1290 | hwmon_dev = hwmon_device_register(&pdev->dev); |
1291 | if (IS_ERR(hwmon_class_dev)) { | 1291 | if (IS_ERR(hwmon_dev)) { |
1292 | ret = PTR_ERR(hwmon_class_dev); | 1292 | ret = PTR_ERR(hwmon_dev); |
1293 | goto out_light_ledclass; | 1293 | goto out_light_ledclass; |
1294 | } | 1294 | } |
1295 | 1295 | ||
@@ -1331,7 +1331,7 @@ out: | |||
1331 | 1331 | ||
1332 | static void __exit applesmc_exit(void) | 1332 | static void __exit applesmc_exit(void) |
1333 | { | 1333 | { |
1334 | hwmon_device_unregister(hwmon_class_dev); | 1334 | hwmon_device_unregister(hwmon_dev); |
1335 | if (applesmc_light) { | 1335 | if (applesmc_light) { |
1336 | led_classdev_unregister(&applesmc_backlight); | 1336 | led_classdev_unregister(&applesmc_backlight); |
1337 | destroy_workqueue(applesmc_led_wq); | 1337 | destroy_workqueue(applesmc_led_wq); |
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 57b1c7b7ac3f..9460dba4cf74 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c | |||
@@ -143,7 +143,7 @@ static int FAN_FROM_REG(u8 val, int div) | |||
143 | 143 | ||
144 | /* TEMP: 0.001C/bit (-128C to +127C) | 144 | /* TEMP: 0.001C/bit (-128C to +127C) |
145 | REG: 1C/bit, two's complement */ | 145 | REG: 1C/bit, two's complement */ |
146 | static u8 TEMP_TO_REG(int temp) | 146 | static u8 TEMP_TO_REG(long temp) |
147 | { | 147 | { |
148 | int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX); | 148 | int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX); |
149 | ntemp += (ntemp<0 ? -500 : 500); | 149 | ntemp += (ntemp<0 ? -500 : 500); |
@@ -182,7 +182,7 @@ static u8 DIV_TO_REG(long val) | |||
182 | dynamically allocated, at the same time the client itself is allocated. */ | 182 | dynamically allocated, at the same time the client itself is allocated. */ |
183 | struct asb100_data { | 183 | struct asb100_data { |
184 | struct i2c_client client; | 184 | struct i2c_client client; |
185 | struct class_device *class_dev; | 185 | struct device *hwmon_dev; |
186 | struct mutex lock; | 186 | struct mutex lock; |
187 | enum chips type; | 187 | enum chips type; |
188 | 188 | ||
@@ -448,7 +448,7 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \ | |||
448 | { \ | 448 | { \ |
449 | struct i2c_client *client = to_i2c_client(dev); \ | 449 | struct i2c_client *client = to_i2c_client(dev); \ |
450 | struct asb100_data *data = i2c_get_clientdata(client); \ | 450 | struct asb100_data *data = i2c_get_clientdata(client); \ |
451 | unsigned long val = simple_strtoul(buf, NULL, 10); \ | 451 | long val = simple_strtol(buf, NULL, 10); \ |
452 | \ | 452 | \ |
453 | mutex_lock(&data->update_lock); \ | 453 | mutex_lock(&data->update_lock); \ |
454 | switch (nr) { \ | 454 | switch (nr) { \ |
@@ -514,7 +514,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | |||
514 | /* VRM */ | 514 | /* VRM */ |
515 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) | 515 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) |
516 | { | 516 | { |
517 | struct asb100_data *data = asb100_update_device(dev); | 517 | struct asb100_data *data = dev_get_drvdata(dev); |
518 | return sprintf(buf, "%d\n", data->vrm); | 518 | return sprintf(buf, "%d\n", data->vrm); |
519 | } | 519 | } |
520 | 520 | ||
@@ -844,9 +844,9 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) | |||
844 | if ((err = sysfs_create_group(&new_client->dev.kobj, &asb100_group))) | 844 | if ((err = sysfs_create_group(&new_client->dev.kobj, &asb100_group))) |
845 | goto ERROR3; | 845 | goto ERROR3; |
846 | 846 | ||
847 | data->class_dev = hwmon_device_register(&new_client->dev); | 847 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
848 | if (IS_ERR(data->class_dev)) { | 848 | if (IS_ERR(data->hwmon_dev)) { |
849 | err = PTR_ERR(data->class_dev); | 849 | err = PTR_ERR(data->hwmon_dev); |
850 | goto ERROR4; | 850 | goto ERROR4; |
851 | } | 851 | } |
852 | 852 | ||
@@ -874,7 +874,7 @@ static int asb100_detach_client(struct i2c_client *client) | |||
874 | 874 | ||
875 | /* main client */ | 875 | /* main client */ |
876 | if (data) { | 876 | if (data) { |
877 | hwmon_device_unregister(data->class_dev); | 877 | hwmon_device_unregister(data->hwmon_dev); |
878 | sysfs_remove_group(&client->dev.kobj, &asb100_group); | 878 | sysfs_remove_group(&client->dev.kobj, &asb100_group); |
879 | } | 879 | } |
880 | 880 | ||
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 0ccdd0750c44..cce3350e539e 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c | |||
@@ -61,7 +61,7 @@ static struct i2c_driver atxp1_driver = { | |||
61 | 61 | ||
62 | struct atxp1_data { | 62 | struct atxp1_data { |
63 | struct i2c_client client; | 63 | struct i2c_client client; |
64 | struct class_device *class_dev; | 64 | struct device *hwmon_dev; |
65 | struct mutex update_lock; | 65 | struct mutex update_lock; |
66 | unsigned long last_updated; | 66 | unsigned long last_updated; |
67 | u8 valid; | 67 | u8 valid; |
@@ -335,9 +335,9 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) | |||
335 | if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) | 335 | if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) |
336 | goto exit_detach; | 336 | goto exit_detach; |
337 | 337 | ||
338 | data->class_dev = hwmon_device_register(&new_client->dev); | 338 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
339 | if (IS_ERR(data->class_dev)) { | 339 | if (IS_ERR(data->hwmon_dev)) { |
340 | err = PTR_ERR(data->class_dev); | 340 | err = PTR_ERR(data->hwmon_dev); |
341 | goto exit_remove_files; | 341 | goto exit_remove_files; |
342 | } | 342 | } |
343 | 343 | ||
@@ -361,7 +361,7 @@ static int atxp1_detach_client(struct i2c_client * client) | |||
361 | struct atxp1_data * data = i2c_get_clientdata(client); | 361 | struct atxp1_data * data = i2c_get_clientdata(client); |
362 | int err; | 362 | int err; |
363 | 363 | ||
364 | hwmon_device_unregister(data->class_dev); | 364 | hwmon_device_unregister(data->hwmon_dev); |
365 | sysfs_remove_group(&client->dev.kobj, &atxp1_group); | 365 | sysfs_remove_group(&client->dev.kobj, &atxp1_group); |
366 | 366 | ||
367 | err = i2c_detach_client(client); | 367 | err = i2c_detach_client(client); |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 7c1795225b06..6f66551d9e51 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -47,7 +47,7 @@ typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW; | |||
47 | static struct coretemp_data *coretemp_update_device(struct device *dev); | 47 | static struct coretemp_data *coretemp_update_device(struct device *dev); |
48 | 48 | ||
49 | struct coretemp_data { | 49 | struct coretemp_data { |
50 | struct class_device *class_dev; | 50 | struct device *hwmon_dev; |
51 | struct mutex update_lock; | 51 | struct mutex update_lock; |
52 | const char *name; | 52 | const char *name; |
53 | u32 id; | 53 | u32 id; |
@@ -58,8 +58,6 @@ struct coretemp_data { | |||
58 | u8 alarm; | 58 | u8 alarm; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct coretemp_data *coretemp_update_device(struct device *dev); | ||
62 | |||
63 | /* | 61 | /* |
64 | * Sysfs stuff | 62 | * Sysfs stuff |
65 | */ | 63 | */ |
@@ -228,9 +226,9 @@ static int __devinit coretemp_probe(struct platform_device *pdev) | |||
228 | if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group))) | 226 | if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group))) |
229 | goto exit_free; | 227 | goto exit_free; |
230 | 228 | ||
231 | data->class_dev = hwmon_device_register(&pdev->dev); | 229 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
232 | if (IS_ERR(data->class_dev)) { | 230 | if (IS_ERR(data->hwmon_dev)) { |
233 | err = PTR_ERR(data->class_dev); | 231 | err = PTR_ERR(data->hwmon_dev); |
234 | dev_err(&pdev->dev, "Class registration failed (%d)\n", | 232 | dev_err(&pdev->dev, "Class registration failed (%d)\n", |
235 | err); | 233 | err); |
236 | goto exit_class; | 234 | goto exit_class; |
@@ -250,7 +248,7 @@ static int __devexit coretemp_remove(struct platform_device *pdev) | |||
250 | { | 248 | { |
251 | struct coretemp_data *data = platform_get_drvdata(pdev); | 249 | struct coretemp_data *data = platform_get_drvdata(pdev); |
252 | 250 | ||
253 | hwmon_device_unregister(data->class_dev); | 251 | hwmon_device_unregister(data->hwmon_dev); |
254 | sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); | 252 | sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); |
255 | platform_set_drvdata(pdev, NULL); | 253 | platform_set_drvdata(pdev, NULL); |
256 | kfree(data); | 254 | kfree(data); |
@@ -350,7 +348,7 @@ static int coretemp_cpu_callback(struct notifier_block *nfb, | |||
350 | return NOTIFY_OK; | 348 | return NOTIFY_OK; |
351 | } | 349 | } |
352 | 350 | ||
353 | static struct notifier_block __cpuinitdata coretemp_cpu_notifier = { | 351 | static struct notifier_block coretemp_cpu_notifier = { |
354 | .notifier_call = coretemp_cpu_callback, | 352 | .notifier_call = coretemp_cpu_callback, |
355 | }; | 353 | }; |
356 | #endif /* !CONFIG_HOTPLUG_CPU */ | 354 | #endif /* !CONFIG_HOTPLUG_CPU */ |
@@ -371,9 +369,10 @@ static int __init coretemp_init(void) | |||
371 | for_each_online_cpu(i) { | 369 | for_each_online_cpu(i) { |
372 | struct cpuinfo_x86 *c = &(cpu_data)[i]; | 370 | struct cpuinfo_x86 *c = &(cpu_data)[i]; |
373 | 371 | ||
374 | /* check if family 6, models e, f */ | 372 | /* check if family 6, models e, f, 16 */ |
375 | if ((c->cpuid_level < 0) || (c->x86 != 0x6) || | 373 | if ((c->cpuid_level < 0) || (c->x86 != 0x6) || |
376 | !((c->x86_model == 0xe) || (c->x86_model == 0xf))) { | 374 | !((c->x86_model == 0xe) || (c->x86_model == 0xf) || |
375 | (c->x86_model == 0x16))) { | ||
377 | 376 | ||
378 | /* supported CPU not found, but report the unknown | 377 | /* supported CPU not found, but report the unknown |
379 | family 6 CPU */ | 378 | family 6 CPU */ |
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 63cee3b6f9bf..ec8edd2a8cbd 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
@@ -155,7 +155,7 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | |||
155 | 155 | ||
156 | struct dme1737_data { | 156 | struct dme1737_data { |
157 | struct i2c_client client; | 157 | struct i2c_client client; |
158 | struct class_device *class_dev; | 158 | struct device *hwmon_dev; |
159 | 159 | ||
160 | struct mutex update_lock; | 160 | struct mutex update_lock; |
161 | int valid; /* !=0 if following fields are valid */ | 161 | int valid; /* !=0 if following fields are valid */ |
@@ -2041,10 +2041,10 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, | |||
2041 | } | 2041 | } |
2042 | 2042 | ||
2043 | /* Register device */ | 2043 | /* Register device */ |
2044 | data->class_dev = hwmon_device_register(dev); | 2044 | data->hwmon_dev = hwmon_device_register(dev); |
2045 | if (IS_ERR(data->class_dev)) { | 2045 | if (IS_ERR(data->hwmon_dev)) { |
2046 | dev_err(dev, "Failed to register device.\n"); | 2046 | dev_err(dev, "Failed to register device.\n"); |
2047 | err = PTR_ERR(data->class_dev); | 2047 | err = PTR_ERR(data->hwmon_dev); |
2048 | goto exit_remove; | 2048 | goto exit_remove; |
2049 | } | 2049 | } |
2050 | 2050 | ||
@@ -2074,7 +2074,7 @@ static int dme1737_i2c_detach_client(struct i2c_client *client) | |||
2074 | struct dme1737_data *data = i2c_get_clientdata(client); | 2074 | struct dme1737_data *data = i2c_get_clientdata(client); |
2075 | int err; | 2075 | int err; |
2076 | 2076 | ||
2077 | hwmon_device_unregister(data->class_dev); | 2077 | hwmon_device_unregister(data->hwmon_dev); |
2078 | dme1737_remove_files(&client->dev); | 2078 | dme1737_remove_files(&client->dev); |
2079 | 2079 | ||
2080 | if ((err = i2c_detach_client(client))) { | 2080 | if ((err = i2c_detach_client(client))) { |
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 1212d6b7f316..b7bd000b130f 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c | |||
@@ -73,7 +73,7 @@ static const u8 DS1621_REG_TEMP[3] = { | |||
73 | /* Each client has this additional data */ | 73 | /* Each client has this additional data */ |
74 | struct ds1621_data { | 74 | struct ds1621_data { |
75 | struct i2c_client client; | 75 | struct i2c_client client; |
76 | struct class_device *class_dev; | 76 | struct device *hwmon_dev; |
77 | struct mutex update_lock; | 77 | struct mutex update_lock; |
78 | char valid; /* !=0 if following fields are valid */ | 78 | char valid; /* !=0 if following fields are valid */ |
79 | unsigned long last_updated; /* In jiffies */ | 79 | unsigned long last_updated; /* In jiffies */ |
@@ -151,7 +151,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, | |||
151 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 151 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
152 | struct i2c_client *client = to_i2c_client(dev); | 152 | struct i2c_client *client = to_i2c_client(dev); |
153 | struct ds1621_data *data = ds1621_update_client(dev); | 153 | struct ds1621_data *data = ds1621_update_client(dev); |
154 | u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); | 154 | u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10)); |
155 | 155 | ||
156 | mutex_lock(&data->update_lock); | 156 | mutex_lock(&data->update_lock); |
157 | data->temp[attr->index] = val; | 157 | data->temp[attr->index] = val; |
@@ -266,9 +266,9 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, | |||
266 | if ((err = sysfs_create_group(&client->dev.kobj, &ds1621_group))) | 266 | if ((err = sysfs_create_group(&client->dev.kobj, &ds1621_group))) |
267 | goto exit_detach; | 267 | goto exit_detach; |
268 | 268 | ||
269 | data->class_dev = hwmon_device_register(&client->dev); | 269 | data->hwmon_dev = hwmon_device_register(&client->dev); |
270 | if (IS_ERR(data->class_dev)) { | 270 | if (IS_ERR(data->hwmon_dev)) { |
271 | err = PTR_ERR(data->class_dev); | 271 | err = PTR_ERR(data->hwmon_dev); |
272 | goto exit_remove_files; | 272 | goto exit_remove_files; |
273 | } | 273 | } |
274 | 274 | ||
@@ -289,7 +289,7 @@ static int ds1621_detach_client(struct i2c_client *client) | |||
289 | struct ds1621_data *data = i2c_get_clientdata(client); | 289 | struct ds1621_data *data = i2c_get_clientdata(client); |
290 | int err; | 290 | int err; |
291 | 291 | ||
292 | hwmon_device_unregister(data->class_dev); | 292 | hwmon_device_unregister(data->hwmon_dev); |
293 | sysfs_remove_group(&client->dev.kobj, &ds1621_group); | 293 | sysfs_remove_group(&client->dev.kobj, &ds1621_group); |
294 | 294 | ||
295 | if ((err = i2c_detach_client(client))) | 295 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 6f60715f34f8..5d9d5cc816a2 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c | |||
@@ -10,6 +10,9 @@ | |||
10 | * The F71872F/FG is almost the same, with two more voltages monitored, | 10 | * The F71872F/FG is almost the same, with two more voltages monitored, |
11 | * and 6 VID inputs. | 11 | * and 6 VID inputs. |
12 | * | 12 | * |
13 | * The F71806F/FG is essentially the same as the F71872F/FG. It even has | ||
14 | * the same chip ID, so the driver can't differentiate between. | ||
15 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
15 | * the Free Software Foundation; either version 2 of the License, or | 18 | * the Free Software Foundation; either version 2 of the License, or |
@@ -159,7 +162,7 @@ struct f71805f_auto_point { | |||
159 | struct f71805f_data { | 162 | struct f71805f_data { |
160 | unsigned short addr; | 163 | unsigned short addr; |
161 | const char *name; | 164 | const char *name; |
162 | struct class_device *class_dev; | 165 | struct device *hwmon_dev; |
163 | 166 | ||
164 | struct mutex update_lock; | 167 | struct mutex update_lock; |
165 | char valid; /* !=0 if following fields are valid */ | 168 | char valid; /* !=0 if following fields are valid */ |
@@ -1378,9 +1381,9 @@ static int __devinit f71805f_probe(struct platform_device *pdev) | |||
1378 | } | 1381 | } |
1379 | } | 1382 | } |
1380 | 1383 | ||
1381 | data->class_dev = hwmon_device_register(&pdev->dev); | 1384 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
1382 | if (IS_ERR(data->class_dev)) { | 1385 | if (IS_ERR(data->hwmon_dev)) { |
1383 | err = PTR_ERR(data->class_dev); | 1386 | err = PTR_ERR(data->hwmon_dev); |
1384 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); | 1387 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); |
1385 | goto exit_remove_files; | 1388 | goto exit_remove_files; |
1386 | } | 1389 | } |
@@ -1407,7 +1410,7 @@ static int __devexit f71805f_remove(struct platform_device *pdev) | |||
1407 | struct resource *res; | 1410 | struct resource *res; |
1408 | int i; | 1411 | int i; |
1409 | 1412 | ||
1410 | hwmon_device_unregister(data->class_dev); | 1413 | hwmon_device_unregister(data->hwmon_dev); |
1411 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); | 1414 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); |
1412 | for (i = 0; i < 4; i++) | 1415 | for (i = 0; i < 4; i++) |
1413 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); | 1416 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); |
@@ -1485,7 +1488,7 @@ static int __init f71805f_find(int sioaddr, unsigned short *address, | |||
1485 | 1488 | ||
1486 | static const char *names[] = { | 1489 | static const char *names[] = { |
1487 | "F71805F/FG", | 1490 | "F71805F/FG", |
1488 | "F71872F/FG", | 1491 | "F71872F/FG or F71806F/FG", |
1489 | }; | 1492 | }; |
1490 | 1493 | ||
1491 | superio_enter(sioaddr); | 1494 | superio_enter(sioaddr); |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c new file mode 100644 index 000000000000..6db74434a02e --- /dev/null +++ b/drivers/hwmon/f71882fg.c | |||
@@ -0,0 +1,950 @@ | |||
1 | /*************************************************************************** | ||
2 | * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * | ||
3 | * Copyright (C) 2007 by Hans de Goede <j.w.r.degoede@hhs.nl> * | ||
4 | * * | ||
5 | * This program is free software; you can redistribute it and/or modify * | ||
6 | * it under the terms of the GNU General Public License as published by * | ||
7 | * the Free Software Foundation; either version 2 of the License, or * | ||
8 | * (at your option) any later version. * | ||
9 | * * | ||
10 | * This program is distributed in the hope that it will be useful, * | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
13 | * GNU General Public License for more details. * | ||
14 | * * | ||
15 | * You should have received a copy of the GNU General Public License * | ||
16 | * along with this program; if not, write to the * | ||
17 | * Free Software Foundation, Inc., * | ||
18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
19 | ***************************************************************************/ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/jiffies.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/hwmon.h> | ||
27 | #include <linux/hwmon-sysfs.h> | ||
28 | #include <linux/err.h> | ||
29 | #include <linux/mutex.h> | ||
30 | #include <asm/io.h> | ||
31 | |||
32 | #define DRVNAME "f71882fg" | ||
33 | |||
34 | #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device*/ | ||
35 | #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ | ||
36 | #define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ | ||
37 | |||
38 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | ||
39 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | ||
40 | #define SIO_REG_DEVREV 0x22 /* Device revision */ | ||
41 | #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ | ||
42 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | ||
43 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | ||
44 | |||
45 | #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ | ||
46 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ | ||
47 | |||
48 | #define REGION_LENGTH 8 | ||
49 | #define ADDR_REG_OFFSET 5 | ||
50 | #define DATA_REG_OFFSET 6 | ||
51 | |||
52 | #define F71882FG_REG_PECI 0x0A | ||
53 | |||
54 | #define F71882FG_REG_IN_STATUS 0x12 | ||
55 | #define F71882FG_REG_IN_BEEP 0x13 | ||
56 | #define F71882FG_REG_IN(nr) (0x20 + (nr)) | ||
57 | #define F71882FG_REG_IN1_HIGH 0x32 | ||
58 | |||
59 | #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) | ||
60 | #define F71882FG_REG_FAN_STATUS 0x92 | ||
61 | #define F71882FG_REG_FAN_BEEP 0x93 | ||
62 | |||
63 | #define F71882FG_REG_TEMP(nr) (0x72 + 2 * (nr)) | ||
64 | #define F71882FG_REG_TEMP_OVT(nr) (0x82 + 2 * (nr)) | ||
65 | #define F71882FG_REG_TEMP_HIGH(nr) (0x83 + 2 * (nr)) | ||
66 | #define F71882FG_REG_TEMP_STATUS 0x62 | ||
67 | #define F71882FG_REG_TEMP_BEEP 0x63 | ||
68 | #define F71882FG_REG_TEMP_HYST1 0x6C | ||
69 | #define F71882FG_REG_TEMP_HYST23 0x6D | ||
70 | #define F71882FG_REG_TEMP_TYPE 0x6B | ||
71 | #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F | ||
72 | |||
73 | #define F71882FG_REG_START 0x01 | ||
74 | |||
75 | #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ | ||
76 | |||
77 | static struct platform_device *f71882fg_pdev = NULL; | ||
78 | |||
79 | /* Super-I/O Function prototypes */ | ||
80 | static inline int superio_inb(int base, int reg); | ||
81 | static inline int superio_inw(int base, int reg); | ||
82 | static inline void superio_enter(int base); | ||
83 | static inline void superio_select(int base, int ld); | ||
84 | static inline void superio_exit(int base); | ||
85 | |||
86 | static inline u16 fan_from_reg ( u16 reg ); | ||
87 | |||
88 | struct f71882fg_data { | ||
89 | unsigned short addr; | ||
90 | struct device *hwmon_dev; | ||
91 | |||
92 | struct mutex update_lock; | ||
93 | char valid; /* !=0 if following fields are valid */ | ||
94 | unsigned long last_updated; /* In jiffies */ | ||
95 | unsigned long last_limits; /* In jiffies */ | ||
96 | |||
97 | /* Register Values */ | ||
98 | u8 in[9]; | ||
99 | u8 in1_max; | ||
100 | u8 in_status; | ||
101 | u8 in_beep; | ||
102 | u16 fan[4]; | ||
103 | u8 fan_status; | ||
104 | u8 fan_beep; | ||
105 | u8 temp[3]; | ||
106 | u8 temp_ovt[3]; | ||
107 | u8 temp_high[3]; | ||
108 | u8 temp_hyst[3]; | ||
109 | u8 temp_type[3]; | ||
110 | u8 temp_status; | ||
111 | u8 temp_beep; | ||
112 | u8 temp_diode_open; | ||
113 | }; | ||
114 | |||
115 | static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg); | ||
116 | static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg); | ||
117 | static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val); | ||
118 | |||
119 | /* Sysfs in*/ | ||
120 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, | ||
121 | char *buf); | ||
122 | static ssize_t show_in_max(struct device *dev, struct device_attribute | ||
123 | *devattr, char *buf); | ||
124 | static ssize_t store_in_max(struct device *dev, struct device_attribute | ||
125 | *devattr, const char *buf, size_t count); | ||
126 | static ssize_t show_in_beep(struct device *dev, struct device_attribute | ||
127 | *devattr, char *buf); | ||
128 | static ssize_t store_in_beep(struct device *dev, struct device_attribute | ||
129 | *devattr, const char *buf, size_t count); | ||
130 | static ssize_t show_in_alarm(struct device *dev, struct device_attribute | ||
131 | *devattr, char *buf); | ||
132 | /* Sysfs Fan */ | ||
133 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
134 | char *buf); | ||
135 | static ssize_t show_fan_beep(struct device *dev, struct device_attribute | ||
136 | *devattr, char *buf); | ||
137 | static ssize_t store_fan_beep(struct device *dev, struct device_attribute | ||
138 | *devattr, const char *buf, size_t count); | ||
139 | static ssize_t show_fan_alarm(struct device *dev, struct device_attribute | ||
140 | *devattr, char *buf); | ||
141 | /* Sysfs Temp */ | ||
142 | static ssize_t show_temp(struct device *dev, struct device_attribute | ||
143 | *devattr, char *buf); | ||
144 | static ssize_t show_temp_max(struct device *dev, struct device_attribute | ||
145 | *devattr, char *buf); | ||
146 | static ssize_t store_temp_max(struct device *dev, struct device_attribute | ||
147 | *devattr, const char *buf, size_t count); | ||
148 | static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute | ||
149 | *devattr, char *buf); | ||
150 | static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute | ||
151 | *devattr, const char *buf, size_t count); | ||
152 | static ssize_t show_temp_crit(struct device *dev, struct device_attribute | ||
153 | *devattr, char *buf); | ||
154 | static ssize_t store_temp_crit(struct device *dev, struct device_attribute | ||
155 | *devattr, const char *buf, size_t count); | ||
156 | static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute | ||
157 | *devattr, char *buf); | ||
158 | static ssize_t show_temp_type(struct device *dev, struct device_attribute | ||
159 | *devattr, char *buf); | ||
160 | static ssize_t show_temp_beep(struct device *dev, struct device_attribute | ||
161 | *devattr, char *buf); | ||
162 | static ssize_t store_temp_beep(struct device *dev, struct device_attribute | ||
163 | *devattr, const char *buf, size_t count); | ||
164 | static ssize_t show_temp_alarm(struct device *dev, struct device_attribute | ||
165 | *devattr, char *buf); | ||
166 | static ssize_t show_temp_fault(struct device *dev, struct device_attribute | ||
167 | *devattr, char *buf); | ||
168 | /* Sysfs misc */ | ||
169 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | ||
170 | char *buf); | ||
171 | |||
172 | static int __devinit f71882fg_probe(struct platform_device * pdev); | ||
173 | static int __devexit f71882fg_remove(struct platform_device *pdev); | ||
174 | static int __init f71882fg_init(void); | ||
175 | static int __init f71882fg_find(int sioaddr, unsigned short *address); | ||
176 | static int __init f71882fg_device_add(unsigned short address); | ||
177 | static void __exit f71882fg_exit(void); | ||
178 | |||
179 | static struct platform_driver f71882fg_driver = { | ||
180 | .driver = { | ||
181 | .owner = THIS_MODULE, | ||
182 | .name = DRVNAME, | ||
183 | }, | ||
184 | .probe = f71882fg_probe, | ||
185 | .remove = __devexit_p(f71882fg_remove), | ||
186 | }; | ||
187 | |||
188 | static struct device_attribute f71882fg_dev_attr[] = | ||
189 | { | ||
190 | __ATTR( name, S_IRUGO, show_name, NULL ), | ||
191 | }; | ||
192 | |||
193 | static struct sensor_device_attribute f71882fg_in_temp_attr[] = | ||
194 | { | ||
195 | SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), | ||
196 | SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), | ||
197 | SENSOR_ATTR(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 1), | ||
198 | SENSOR_ATTR(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, 1), | ||
199 | SENSOR_ATTR(in1_alarm, S_IRUGO, show_in_alarm, NULL, 1), | ||
200 | SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), | ||
201 | SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), | ||
202 | SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), | ||
203 | SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), | ||
204 | SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), | ||
205 | SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), | ||
206 | SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), | ||
207 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0), | ||
208 | SENSOR_ATTR(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, | ||
209 | store_temp_max, 0), | ||
210 | SENSOR_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, | ||
211 | store_temp_max_hyst, 0), | ||
212 | SENSOR_ATTR(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, | ||
213 | store_temp_crit, 0), | ||
214 | SENSOR_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 0), | ||
215 | SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), | ||
216 | SENSOR_ATTR(temp1_beep, S_IRUGO|S_IWUSR, show_temp_beep, | ||
217 | store_temp_beep, 0), | ||
218 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0), | ||
219 | SENSOR_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0), | ||
220 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1), | ||
221 | SENSOR_ATTR(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, | ||
222 | store_temp_max, 1), | ||
223 | SENSOR_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, | ||
224 | store_temp_max_hyst, 1), | ||
225 | SENSOR_ATTR(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit, | ||
226 | store_temp_crit, 1), | ||
227 | SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1), | ||
228 | SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), | ||
229 | SENSOR_ATTR(temp2_beep, S_IRUGO|S_IWUSR, show_temp_beep, | ||
230 | store_temp_beep, 1), | ||
231 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1), | ||
232 | SENSOR_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1), | ||
233 | SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2), | ||
234 | SENSOR_ATTR(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, | ||
235 | store_temp_max, 2), | ||
236 | SENSOR_ATTR(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, | ||
237 | store_temp_max_hyst, 2), | ||
238 | SENSOR_ATTR(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit, | ||
239 | store_temp_crit, 2), | ||
240 | SENSOR_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 2), | ||
241 | SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), | ||
242 | SENSOR_ATTR(temp3_beep, S_IRUGO|S_IWUSR, show_temp_beep, | ||
243 | store_temp_beep, 2), | ||
244 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2), | ||
245 | SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2) | ||
246 | }; | ||
247 | |||
248 | static struct sensor_device_attribute f71882fg_fan_attr[] = | ||
249 | { | ||
250 | SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), | ||
251 | SENSOR_ATTR(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
252 | store_fan_beep, 0), | ||
253 | SENSOR_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0), | ||
254 | SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), | ||
255 | SENSOR_ATTR(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
256 | store_fan_beep, 1), | ||
257 | SENSOR_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1), | ||
258 | SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), | ||
259 | SENSOR_ATTR(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
260 | store_fan_beep, 2), | ||
261 | SENSOR_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2), | ||
262 | SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), | ||
263 | SENSOR_ATTR(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
264 | store_fan_beep, 3), | ||
265 | SENSOR_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3) | ||
266 | }; | ||
267 | |||
268 | |||
269 | /* Super I/O functions */ | ||
270 | static inline int superio_inb(int base, int reg) | ||
271 | { | ||
272 | outb(reg, base); | ||
273 | return inb(base + 1); | ||
274 | } | ||
275 | |||
276 | static int superio_inw(int base, int reg) | ||
277 | { | ||
278 | int val; | ||
279 | outb(reg++, base); | ||
280 | val = inb(base + 1) << 8; | ||
281 | outb(reg, base); | ||
282 | val |= inb(base + 1); | ||
283 | return val; | ||
284 | } | ||
285 | |||
286 | static inline void superio_enter(int base) | ||
287 | { | ||
288 | /* according to the datasheet the key must be send twice! */ | ||
289 | outb( SIO_UNLOCK_KEY, base); | ||
290 | outb( SIO_UNLOCK_KEY, base); | ||
291 | } | ||
292 | |||
293 | static inline void superio_select( int base, int ld) | ||
294 | { | ||
295 | outb(SIO_REG_LDSEL, base); | ||
296 | outb(ld, base + 1); | ||
297 | } | ||
298 | |||
299 | static inline void superio_exit(int base) | ||
300 | { | ||
301 | outb(SIO_LOCK_KEY, base); | ||
302 | } | ||
303 | |||
304 | static inline u16 fan_from_reg(u16 reg) | ||
305 | { | ||
306 | return reg ? (1500000 / reg) : 0; | ||
307 | } | ||
308 | |||
309 | static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg) | ||
310 | { | ||
311 | u8 val; | ||
312 | |||
313 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
314 | val = inb(data->addr + DATA_REG_OFFSET); | ||
315 | |||
316 | return val; | ||
317 | } | ||
318 | |||
319 | static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg) | ||
320 | { | ||
321 | u16 val; | ||
322 | |||
323 | outb(reg++, data->addr + ADDR_REG_OFFSET); | ||
324 | val = inb(data->addr + DATA_REG_OFFSET) << 8; | ||
325 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
326 | val |= inb(data->addr + DATA_REG_OFFSET); | ||
327 | |||
328 | return val; | ||
329 | } | ||
330 | |||
331 | static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val) | ||
332 | { | ||
333 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
334 | outb(val, data->addr + DATA_REG_OFFSET); | ||
335 | } | ||
336 | |||
337 | static struct f71882fg_data *f71882fg_update_device(struct device * dev) | ||
338 | { | ||
339 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
340 | int nr, reg, reg2; | ||
341 | |||
342 | mutex_lock(&data->update_lock); | ||
343 | |||
344 | /* Update once every 60 seconds */ | ||
345 | if ( time_after(jiffies, data->last_limits + 60 * HZ ) || | ||
346 | !data->valid) { | ||
347 | data->in1_max = f71882fg_read8(data, F71882FG_REG_IN1_HIGH); | ||
348 | data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); | ||
349 | |||
350 | /* Get High & boundary temps*/ | ||
351 | for (nr = 0; nr < 3; nr++) { | ||
352 | data->temp_ovt[nr] = f71882fg_read8(data, | ||
353 | F71882FG_REG_TEMP_OVT(nr)); | ||
354 | data->temp_high[nr] = f71882fg_read8(data, | ||
355 | F71882FG_REG_TEMP_HIGH(nr)); | ||
356 | } | ||
357 | |||
358 | /* Have to hardcode hyst*/ | ||
359 | data->temp_hyst[0] = f71882fg_read8(data, | ||
360 | F71882FG_REG_TEMP_HYST1) >> 4; | ||
361 | /* Hyst temps 2 & 3 stored in same register */ | ||
362 | reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST23); | ||
363 | data->temp_hyst[1] = reg & 0x0F; | ||
364 | data->temp_hyst[2] = reg >> 4; | ||
365 | |||
366 | /* Have to hardcode type, because temp1 is special */ | ||
367 | reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); | ||
368 | reg2 = f71882fg_read8(data, F71882FG_REG_PECI); | ||
369 | if ((reg2 & 0x03) == 0x01) | ||
370 | data->temp_type[0] = 6 /* PECI */; | ||
371 | else if ((reg2 & 0x03) == 0x02) | ||
372 | data->temp_type[0] = 5 /* AMDSI */; | ||
373 | else | ||
374 | data->temp_type[0] = (reg & 0x02) ? 2 : 4; | ||
375 | |||
376 | data->temp_type[1] = (reg & 0x04) ? 2 : 4; | ||
377 | data->temp_type[2] = (reg & 0x08) ? 2 : 4; | ||
378 | |||
379 | data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); | ||
380 | |||
381 | data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); | ||
382 | |||
383 | data->last_limits = jiffies; | ||
384 | } | ||
385 | |||
386 | /* Update every second */ | ||
387 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
388 | data->temp_status = f71882fg_read8(data, | ||
389 | F71882FG_REG_TEMP_STATUS); | ||
390 | data->temp_diode_open = f71882fg_read8(data, | ||
391 | F71882FG_REG_TEMP_DIODE_OPEN); | ||
392 | for (nr = 0; nr < 3; nr++) | ||
393 | data->temp[nr] = f71882fg_read8(data, | ||
394 | F71882FG_REG_TEMP(nr)); | ||
395 | |||
396 | data->fan_status = f71882fg_read8(data, | ||
397 | F71882FG_REG_FAN_STATUS); | ||
398 | for (nr = 0; nr < 4; nr++) | ||
399 | data->fan[nr] = f71882fg_read16(data, | ||
400 | F71882FG_REG_FAN(nr)); | ||
401 | |||
402 | data->in_status = f71882fg_read8(data, | ||
403 | F71882FG_REG_IN_STATUS); | ||
404 | for (nr = 0; nr < 9; nr++) | ||
405 | data->in[nr] = f71882fg_read8(data, | ||
406 | F71882FG_REG_IN(nr)); | ||
407 | |||
408 | data->last_updated = jiffies; | ||
409 | data->valid = 1; | ||
410 | } | ||
411 | |||
412 | mutex_unlock(&data->update_lock); | ||
413 | |||
414 | return data; | ||
415 | } | ||
416 | |||
417 | /* Sysfs Interface */ | ||
418 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
419 | char *buf) | ||
420 | { | ||
421 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
422 | int nr = to_sensor_dev_attr(devattr)->index; | ||
423 | int speed = fan_from_reg(data->fan[nr]); | ||
424 | |||
425 | if (speed == FAN_MIN_DETECT) | ||
426 | speed = 0; | ||
427 | |||
428 | return sprintf(buf, "%d\n", speed); | ||
429 | } | ||
430 | |||
431 | static ssize_t show_fan_beep(struct device *dev, struct device_attribute | ||
432 | *devattr, char *buf) | ||
433 | { | ||
434 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
435 | int nr = to_sensor_dev_attr(devattr)->index; | ||
436 | |||
437 | if (data->fan_beep & (1 << nr)) | ||
438 | return sprintf(buf, "1\n"); | ||
439 | else | ||
440 | return sprintf(buf, "0\n"); | ||
441 | } | ||
442 | |||
443 | static ssize_t store_fan_beep(struct device *dev, struct device_attribute | ||
444 | *devattr, const char *buf, size_t count) | ||
445 | { | ||
446 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
447 | int nr = to_sensor_dev_attr(devattr)->index; | ||
448 | int val = simple_strtoul(buf, NULL, 10); | ||
449 | |||
450 | mutex_lock(&data->update_lock); | ||
451 | if (val) | ||
452 | data->fan_beep |= 1 << nr; | ||
453 | else | ||
454 | data->fan_beep &= ~(1 << nr); | ||
455 | |||
456 | f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep); | ||
457 | mutex_unlock(&data->update_lock); | ||
458 | |||
459 | return count; | ||
460 | } | ||
461 | |||
462 | static ssize_t show_fan_alarm(struct device *dev, struct device_attribute | ||
463 | *devattr, char *buf) | ||
464 | { | ||
465 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
466 | int nr = to_sensor_dev_attr(devattr)->index; | ||
467 | |||
468 | if (data->fan_status & (1 << nr)) | ||
469 | return sprintf(buf, "1\n"); | ||
470 | else | ||
471 | return sprintf(buf, "0\n"); | ||
472 | } | ||
473 | |||
474 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, | ||
475 | char *buf) | ||
476 | { | ||
477 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
478 | int nr = to_sensor_dev_attr(devattr)->index; | ||
479 | |||
480 | return sprintf(buf, "%d\n", data->in[nr] * 8); | ||
481 | } | ||
482 | |||
483 | static ssize_t show_in_max(struct device *dev, struct device_attribute | ||
484 | *devattr, char *buf) | ||
485 | { | ||
486 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
487 | |||
488 | return sprintf(buf, "%d\n", data->in1_max * 8); | ||
489 | } | ||
490 | |||
491 | static ssize_t store_in_max(struct device *dev, struct device_attribute | ||
492 | *devattr, const char *buf, size_t count) | ||
493 | { | ||
494 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
495 | int val = simple_strtoul(buf, NULL, 10) / 8; | ||
496 | |||
497 | if (val > 255) | ||
498 | val = 255; | ||
499 | |||
500 | mutex_lock(&data->update_lock); | ||
501 | f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val); | ||
502 | data->in1_max = val; | ||
503 | mutex_unlock(&data->update_lock); | ||
504 | |||
505 | return count; | ||
506 | } | ||
507 | |||
508 | static ssize_t show_in_beep(struct device *dev, struct device_attribute | ||
509 | *devattr, char *buf) | ||
510 | { | ||
511 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
512 | int nr = to_sensor_dev_attr(devattr)->index; | ||
513 | |||
514 | if (data->in_beep & (1 << nr)) | ||
515 | return sprintf(buf, "1\n"); | ||
516 | else | ||
517 | return sprintf(buf, "0\n"); | ||
518 | } | ||
519 | |||
520 | static ssize_t store_in_beep(struct device *dev, struct device_attribute | ||
521 | *devattr, const char *buf, size_t count) | ||
522 | { | ||
523 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
524 | int nr = to_sensor_dev_attr(devattr)->index; | ||
525 | int val = simple_strtoul(buf, NULL, 10); | ||
526 | |||
527 | mutex_lock(&data->update_lock); | ||
528 | if (val) | ||
529 | data->in_beep |= 1 << nr; | ||
530 | else | ||
531 | data->in_beep &= ~(1 << nr); | ||
532 | |||
533 | f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep); | ||
534 | mutex_unlock(&data->update_lock); | ||
535 | |||
536 | return count; | ||
537 | } | ||
538 | |||
539 | static ssize_t show_in_alarm(struct device *dev, struct device_attribute | ||
540 | *devattr, char *buf) | ||
541 | { | ||
542 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
543 | int nr = to_sensor_dev_attr(devattr)->index; | ||
544 | |||
545 | if (data->in_status & (1 << nr)) | ||
546 | return sprintf(buf, "1\n"); | ||
547 | else | ||
548 | return sprintf(buf, "0\n"); | ||
549 | } | ||
550 | |||
551 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
552 | char *buf) | ||
553 | { | ||
554 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
555 | int nr = to_sensor_dev_attr(devattr)->index; | ||
556 | |||
557 | return sprintf(buf, "%d\n", data->temp[nr] * 1000); | ||
558 | } | ||
559 | |||
560 | static ssize_t show_temp_max(struct device *dev, struct device_attribute | ||
561 | *devattr, char *buf) | ||
562 | { | ||
563 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
564 | int nr = to_sensor_dev_attr(devattr)->index; | ||
565 | |||
566 | return sprintf(buf, "%d\n", data->temp_high[nr] * 1000); | ||
567 | } | ||
568 | |||
569 | static ssize_t store_temp_max(struct device *dev, struct device_attribute | ||
570 | *devattr, const char *buf, size_t count) | ||
571 | { | ||
572 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
573 | int nr = to_sensor_dev_attr(devattr)->index; | ||
574 | int val = simple_strtoul(buf, NULL, 10) / 1000; | ||
575 | |||
576 | if (val > 255) | ||
577 | val = 255; | ||
578 | |||
579 | mutex_lock(&data->update_lock); | ||
580 | f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val); | ||
581 | data->temp_high[nr] = val; | ||
582 | mutex_unlock(&data->update_lock); | ||
583 | |||
584 | return count; | ||
585 | } | ||
586 | |||
587 | static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute | ||
588 | *devattr, char *buf) | ||
589 | { | ||
590 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
591 | int nr = to_sensor_dev_attr(devattr)->index; | ||
592 | |||
593 | return sprintf(buf, "%d\n", | ||
594 | (data->temp_high[nr] - data->temp_hyst[nr]) * 1000); | ||
595 | } | ||
596 | |||
597 | static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute | ||
598 | *devattr, const char *buf, size_t count) | ||
599 | { | ||
600 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
601 | int nr = to_sensor_dev_attr(devattr)->index; | ||
602 | int val = simple_strtoul(buf, NULL, 10) / 1000; | ||
603 | ssize_t ret = count; | ||
604 | |||
605 | mutex_lock(&data->update_lock); | ||
606 | |||
607 | /* convert abs to relative and check */ | ||
608 | val = data->temp_high[nr] - val; | ||
609 | if (val < 0 || val > 15) { | ||
610 | ret = -EINVAL; | ||
611 | goto store_temp_max_hyst_exit; | ||
612 | } | ||
613 | |||
614 | data->temp_hyst[nr] = val; | ||
615 | |||
616 | /* convert value to register contents */ | ||
617 | switch (nr) { | ||
618 | case 0: | ||
619 | val = val << 4; | ||
620 | break; | ||
621 | case 1: | ||
622 | val = val | (data->temp_hyst[2] << 4); | ||
623 | break; | ||
624 | case 2: | ||
625 | val = data->temp_hyst[1] | (val << 4); | ||
626 | break; | ||
627 | } | ||
628 | |||
629 | f71882fg_write8(data, nr ? F71882FG_REG_TEMP_HYST23 : | ||
630 | F71882FG_REG_TEMP_HYST1, val); | ||
631 | |||
632 | store_temp_max_hyst_exit: | ||
633 | mutex_unlock(&data->update_lock); | ||
634 | return ret; | ||
635 | } | ||
636 | |||
637 | static ssize_t show_temp_crit(struct device *dev, struct device_attribute | ||
638 | *devattr, char *buf) | ||
639 | { | ||
640 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
641 | int nr = to_sensor_dev_attr(devattr)->index; | ||
642 | |||
643 | return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000); | ||
644 | } | ||
645 | |||
646 | static ssize_t store_temp_crit(struct device *dev, struct device_attribute | ||
647 | *devattr, const char *buf, size_t count) | ||
648 | { | ||
649 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
650 | int nr = to_sensor_dev_attr(devattr)->index; | ||
651 | int val = simple_strtoul(buf, NULL, 10) / 1000; | ||
652 | |||
653 | if (val > 255) | ||
654 | val = 255; | ||
655 | |||
656 | mutex_lock(&data->update_lock); | ||
657 | f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val); | ||
658 | data->temp_ovt[nr] = val; | ||
659 | mutex_unlock(&data->update_lock); | ||
660 | |||
661 | return count; | ||
662 | } | ||
663 | |||
664 | static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute | ||
665 | *devattr, char *buf) | ||
666 | { | ||
667 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
668 | int nr = to_sensor_dev_attr(devattr)->index; | ||
669 | |||
670 | return sprintf(buf, "%d\n", | ||
671 | (data->temp_ovt[nr] - data->temp_hyst[nr]) * 1000); | ||
672 | } | ||
673 | |||
674 | static ssize_t show_temp_type(struct device *dev, struct device_attribute | ||
675 | *devattr, char *buf) | ||
676 | { | ||
677 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
678 | int nr = to_sensor_dev_attr(devattr)->index; | ||
679 | |||
680 | return sprintf(buf, "%d\n", data->temp_type[nr]); | ||
681 | } | ||
682 | |||
683 | static ssize_t show_temp_beep(struct device *dev, struct device_attribute | ||
684 | *devattr, char *buf) | ||
685 | { | ||
686 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
687 | int nr = to_sensor_dev_attr(devattr)->index; | ||
688 | |||
689 | if (data->temp_beep & (1 << (nr + 1))) | ||
690 | return sprintf(buf, "1\n"); | ||
691 | else | ||
692 | return sprintf(buf, "0\n"); | ||
693 | } | ||
694 | |||
695 | static ssize_t store_temp_beep(struct device *dev, struct device_attribute | ||
696 | *devattr, const char *buf, size_t count) | ||
697 | { | ||
698 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
699 | int nr = to_sensor_dev_attr(devattr)->index; | ||
700 | int val = simple_strtoul(buf, NULL, 10); | ||
701 | |||
702 | mutex_lock(&data->update_lock); | ||
703 | if (val) | ||
704 | data->temp_beep |= 1 << (nr + 1); | ||
705 | else | ||
706 | data->temp_beep &= ~(1 << (nr + 1)); | ||
707 | |||
708 | f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep); | ||
709 | mutex_unlock(&data->update_lock); | ||
710 | |||
711 | return count; | ||
712 | } | ||
713 | |||
714 | static ssize_t show_temp_alarm(struct device *dev, struct device_attribute | ||
715 | *devattr, char *buf) | ||
716 | { | ||
717 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
718 | int nr = to_sensor_dev_attr(devattr)->index; | ||
719 | |||
720 | if (data->temp_status & (1 << (nr + 1))) | ||
721 | return sprintf(buf, "1\n"); | ||
722 | else | ||
723 | return sprintf(buf, "0\n"); | ||
724 | } | ||
725 | |||
726 | static ssize_t show_temp_fault(struct device *dev, struct device_attribute | ||
727 | *devattr, char *buf) | ||
728 | { | ||
729 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
730 | int nr = to_sensor_dev_attr(devattr)->index; | ||
731 | |||
732 | if (data->temp_diode_open & (1 << (nr + 1))) | ||
733 | return sprintf(buf, "1\n"); | ||
734 | else | ||
735 | return sprintf(buf, "0\n"); | ||
736 | } | ||
737 | |||
738 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | ||
739 | char *buf) | ||
740 | { | ||
741 | return sprintf(buf, DRVNAME "\n"); | ||
742 | } | ||
743 | |||
744 | |||
745 | static int __devinit f71882fg_probe(struct platform_device * pdev) | ||
746 | { | ||
747 | struct f71882fg_data *data; | ||
748 | int err, i; | ||
749 | u8 start_reg; | ||
750 | |||
751 | if (!(data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL))) | ||
752 | return -ENOMEM; | ||
753 | |||
754 | data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; | ||
755 | mutex_init(&data->update_lock); | ||
756 | platform_set_drvdata(pdev, data); | ||
757 | |||
758 | /* Register sysfs interface files */ | ||
759 | for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) { | ||
760 | err = device_create_file(&pdev->dev, &f71882fg_dev_attr[i]); | ||
761 | if (err) | ||
762 | goto exit_unregister_sysfs; | ||
763 | } | ||
764 | |||
765 | start_reg = f71882fg_read8(data, F71882FG_REG_START); | ||
766 | if (start_reg & 0x01) { | ||
767 | for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) { | ||
768 | err = device_create_file(&pdev->dev, | ||
769 | &f71882fg_in_temp_attr[i].dev_attr); | ||
770 | if (err) | ||
771 | goto exit_unregister_sysfs; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | if (start_reg & 0x02) { | ||
776 | for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) { | ||
777 | err = device_create_file(&pdev->dev, | ||
778 | &f71882fg_fan_attr[i].dev_attr); | ||
779 | if (err) | ||
780 | goto exit_unregister_sysfs; | ||
781 | } | ||
782 | } | ||
783 | |||
784 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | ||
785 | if (IS_ERR(data->hwmon_dev)) { | ||
786 | err = PTR_ERR(data->hwmon_dev); | ||
787 | goto exit_unregister_sysfs; | ||
788 | } | ||
789 | |||
790 | return 0; | ||
791 | |||
792 | exit_unregister_sysfs: | ||
793 | for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) | ||
794 | device_remove_file(&pdev->dev, &f71882fg_dev_attr[i]); | ||
795 | |||
796 | for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) | ||
797 | device_remove_file(&pdev->dev, | ||
798 | &f71882fg_in_temp_attr[i].dev_attr); | ||
799 | |||
800 | for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) | ||
801 | device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr); | ||
802 | |||
803 | kfree(data); | ||
804 | |||
805 | return err; | ||
806 | } | ||
807 | |||
808 | static int __devexit f71882fg_remove(struct platform_device *pdev) | ||
809 | { | ||
810 | int i; | ||
811 | struct f71882fg_data *data = platform_get_drvdata(pdev); | ||
812 | |||
813 | platform_set_drvdata(pdev, NULL); | ||
814 | hwmon_device_unregister(data->hwmon_dev); | ||
815 | |||
816 | for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) | ||
817 | device_remove_file(&pdev->dev, &f71882fg_dev_attr[i]); | ||
818 | |||
819 | for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) | ||
820 | device_remove_file(&pdev->dev, | ||
821 | &f71882fg_in_temp_attr[i].dev_attr); | ||
822 | |||
823 | for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) | ||
824 | device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr); | ||
825 | |||
826 | kfree(data); | ||
827 | |||
828 | return 0; | ||
829 | } | ||
830 | |||
831 | static int __init f71882fg_find(int sioaddr, unsigned short *address) | ||
832 | { | ||
833 | int err = -ENODEV; | ||
834 | u16 devid; | ||
835 | u8 start_reg; | ||
836 | struct f71882fg_data data; | ||
837 | |||
838 | superio_enter(sioaddr); | ||
839 | |||
840 | devid = superio_inw(sioaddr, SIO_REG_MANID); | ||
841 | if (devid != SIO_FINTEK_ID) { | ||
842 | printk(KERN_INFO DRVNAME ": Not a Fintek device\n"); | ||
843 | goto exit; | ||
844 | } | ||
845 | |||
846 | devid = superio_inw(sioaddr, SIO_REG_DEVID); | ||
847 | if (devid != SIO_F71882_ID) { | ||
848 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n"); | ||
849 | goto exit; | ||
850 | } | ||
851 | |||
852 | superio_select(sioaddr, SIO_F71882FG_LD_HWM); | ||
853 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | ||
854 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); | ||
855 | goto exit; | ||
856 | } | ||
857 | |||
858 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | ||
859 | if (*address == 0) | ||
860 | { | ||
861 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); | ||
862 | goto exit; | ||
863 | } | ||
864 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ | ||
865 | |||
866 | data.addr = *address; | ||
867 | start_reg = f71882fg_read8(&data, F71882FG_REG_START); | ||
868 | if (!(start_reg & 0x03)) { | ||
869 | printk(KERN_WARNING DRVNAME | ||
870 | ": Hardware monitoring not activated\n"); | ||
871 | goto exit; | ||
872 | } | ||
873 | |||
874 | err = 0; | ||
875 | printk(KERN_INFO DRVNAME ": Found F71882FG chip at %#x, revision %d\n", | ||
876 | (unsigned int)*address, | ||
877 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); | ||
878 | exit: | ||
879 | superio_exit(sioaddr); | ||
880 | return err; | ||
881 | } | ||
882 | |||
883 | static int __init f71882fg_device_add(unsigned short address) | ||
884 | { | ||
885 | struct resource res = { | ||
886 | .start = address, | ||
887 | .end = address + REGION_LENGTH - 1, | ||
888 | .flags = IORESOURCE_IO, | ||
889 | }; | ||
890 | int err; | ||
891 | |||
892 | f71882fg_pdev = platform_device_alloc(DRVNAME, address); | ||
893 | if (!f71882fg_pdev) | ||
894 | return -ENOMEM; | ||
895 | |||
896 | res.name = f71882fg_pdev->name; | ||
897 | err = platform_device_add_resources(f71882fg_pdev, &res, 1); | ||
898 | if (err) { | ||
899 | printk(KERN_ERR DRVNAME ": Device resource addition failed\n"); | ||
900 | goto exit_device_put; | ||
901 | } | ||
902 | |||
903 | err = platform_device_add(f71882fg_pdev); | ||
904 | if (err) { | ||
905 | printk(KERN_ERR DRVNAME ": Device addition failed\n"); | ||
906 | goto exit_device_put; | ||
907 | } | ||
908 | |||
909 | return 0; | ||
910 | |||
911 | exit_device_put: | ||
912 | platform_device_put(f71882fg_pdev); | ||
913 | |||
914 | return err; | ||
915 | } | ||
916 | |||
917 | static int __init f71882fg_init(void) | ||
918 | { | ||
919 | int err = -ENODEV; | ||
920 | unsigned short address; | ||
921 | |||
922 | if (f71882fg_find(0x2e, &address) && f71882fg_find(0x4e, &address)) | ||
923 | goto exit; | ||
924 | |||
925 | if ((err = platform_driver_register(&f71882fg_driver))) | ||
926 | goto exit; | ||
927 | |||
928 | if ((err = f71882fg_device_add(address))) | ||
929 | goto exit_driver; | ||
930 | |||
931 | return 0; | ||
932 | |||
933 | exit_driver: | ||
934 | platform_driver_unregister(&f71882fg_driver); | ||
935 | exit: | ||
936 | return err; | ||
937 | } | ||
938 | |||
939 | static void __exit f71882fg_exit(void) | ||
940 | { | ||
941 | platform_device_unregister(f71882fg_pdev); | ||
942 | platform_driver_unregister(&f71882fg_driver); | ||
943 | } | ||
944 | |||
945 | MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver"); | ||
946 | MODULE_AUTHOR("Hans Edgington (hans@edgington.nl)"); | ||
947 | MODULE_LICENSE("GPL"); | ||
948 | |||
949 | module_init(f71882fg_init); | ||
950 | module_exit(f71882fg_exit); | ||
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c new file mode 100644 index 000000000000..13a041326a04 --- /dev/null +++ b/drivers/hwmon/f75375s.c | |||
@@ -0,0 +1,691 @@ | |||
1 | /* | ||
2 | * f75375s.c - driver for the Fintek F75375/SP and F75373 | ||
3 | * hardware monitoring features | ||
4 | * Copyright (C) 2006-2007 Riku Voipio <riku.voipio@movial.fi> | ||
5 | * | ||
6 | * Datasheets available at: | ||
7 | * | ||
8 | * f75375: | ||
9 | * http://www.fintek.com.tw/files/productfiles/2005111152950.pdf | ||
10 | * | ||
11 | * f75373: | ||
12 | * http://www.fintek.com.tw/files/productfiles/2005111153128.pdf | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/jiffies.h> | ||
32 | #include <linux/hwmon.h> | ||
33 | #include <linux/hwmon-sysfs.h> | ||
34 | #include <linux/i2c.h> | ||
35 | #include <linux/err.h> | ||
36 | #include <linux/mutex.h> | ||
37 | |||
38 | /* Addresses to scan */ | ||
39 | static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; | ||
40 | |||
41 | /* Insmod parameters */ | ||
42 | I2C_CLIENT_INSMOD_2(f75373, f75375); | ||
43 | |||
44 | /* Fintek F75375 registers */ | ||
45 | #define F75375_REG_CONFIG0 0x0 | ||
46 | #define F75375_REG_CONFIG1 0x1 | ||
47 | #define F75375_REG_CONFIG2 0x2 | ||
48 | #define F75375_REG_CONFIG3 0x3 | ||
49 | #define F75375_REG_ADDR 0x4 | ||
50 | #define F75375_REG_INTR 0x31 | ||
51 | #define F75375_CHIP_ID 0x5A | ||
52 | #define F75375_REG_VERSION 0x5C | ||
53 | #define F75375_REG_VENDOR 0x5D | ||
54 | #define F75375_REG_FAN_TIMER 0x60 | ||
55 | |||
56 | #define F75375_REG_VOLT(nr) (0x10 + (nr)) | ||
57 | #define F75375_REG_VOLT_HIGH(nr) (0x20 + (nr) * 2) | ||
58 | #define F75375_REG_VOLT_LOW(nr) (0x21 + (nr) * 2) | ||
59 | |||
60 | #define F75375_REG_TEMP(nr) (0x14 + (nr)) | ||
61 | #define F75375_REG_TEMP_HIGH(nr) (0x28 + (nr) * 2) | ||
62 | #define F75375_REG_TEMP_HYST(nr) (0x29 + (nr) * 2) | ||
63 | |||
64 | #define F75375_REG_FAN(nr) (0x16 + (nr) * 2) | ||
65 | #define F75375_REG_FAN_MIN(nr) (0x2C + (nr) * 2) | ||
66 | #define F75375_REG_FAN_FULL(nr) (0x70 + (nr) * 0x10) | ||
67 | #define F75375_REG_FAN_PWM_DUTY(nr) (0x76 + (nr) * 0x10) | ||
68 | #define F75375_REG_FAN_PWM_CLOCK(nr) (0x7D + (nr) * 0x10) | ||
69 | |||
70 | #define F75375_REG_FAN_EXP(nr) (0x74 + (nr) * 0x10) | ||
71 | #define F75375_REG_FAN_B_TEMP(nr, step) ((0xA0 + (nr) * 0x10) + (step)) | ||
72 | #define F75375_REG_FAN_B_SPEED(nr, step) \ | ||
73 | ((0xA5 + (nr) * 0x10) + (step) * 2) | ||
74 | |||
75 | #define F75375_REG_PWM1_RAISE_DUTY 0x69 | ||
76 | #define F75375_REG_PWM2_RAISE_DUTY 0x6A | ||
77 | #define F75375_REG_PWM1_DROP_DUTY 0x6B | ||
78 | #define F75375_REG_PWM2_DROP_DUTY 0x6C | ||
79 | |||
80 | #define FAN_CTRL_LINEAR(nr) (4 + nr) | ||
81 | #define FAN_CTRL_MODE(nr) (5 + ((nr) * 2)) | ||
82 | |||
83 | /* | ||
84 | * Data structures and manipulation thereof | ||
85 | */ | ||
86 | |||
87 | struct f75375_data { | ||
88 | unsigned short addr; | ||
89 | struct i2c_client client; | ||
90 | struct device *hwmon_dev; | ||
91 | |||
92 | const char *name; | ||
93 | int kind; | ||
94 | struct mutex update_lock; /* protect register access */ | ||
95 | char valid; | ||
96 | unsigned long last_updated; /* In jiffies */ | ||
97 | unsigned long last_limits; /* In jiffies */ | ||
98 | |||
99 | /* Register values */ | ||
100 | u8 in[4]; | ||
101 | u8 in_max[4]; | ||
102 | u8 in_min[4]; | ||
103 | u16 fan[2]; | ||
104 | u16 fan_min[2]; | ||
105 | u16 fan_full[2]; | ||
106 | u16 fan_exp[2]; | ||
107 | u8 fan_timer; | ||
108 | u8 pwm[2]; | ||
109 | u8 pwm_mode[2]; | ||
110 | u8 pwm_enable[2]; | ||
111 | s8 temp[2]; | ||
112 | s8 temp_high[2]; | ||
113 | s8 temp_max_hyst[2]; | ||
114 | }; | ||
115 | |||
116 | static int f75375_attach_adapter(struct i2c_adapter *adapter); | ||
117 | static int f75375_detect(struct i2c_adapter *adapter, int address, int kind); | ||
118 | static int f75375_detach_client(struct i2c_client *client); | ||
119 | |||
120 | static struct i2c_driver f75375_driver = { | ||
121 | .driver = { | ||
122 | .name = "f75375", | ||
123 | }, | ||
124 | .attach_adapter = f75375_attach_adapter, | ||
125 | .detach_client = f75375_detach_client, | ||
126 | }; | ||
127 | |||
128 | static inline int f75375_read8(struct i2c_client *client, u8 reg) | ||
129 | { | ||
130 | return i2c_smbus_read_byte_data(client, reg); | ||
131 | } | ||
132 | |||
133 | /* in most cases, should be called while holding update_lock */ | ||
134 | static inline u16 f75375_read16(struct i2c_client *client, u8 reg) | ||
135 | { | ||
136 | return ((i2c_smbus_read_byte_data(client, reg) << 8) | ||
137 | | i2c_smbus_read_byte_data(client, reg + 1)); | ||
138 | } | ||
139 | |||
140 | static inline void f75375_write8(struct i2c_client *client, u8 reg, | ||
141 | u8 value) | ||
142 | { | ||
143 | i2c_smbus_write_byte_data(client, reg, value); | ||
144 | } | ||
145 | |||
146 | static inline void f75375_write16(struct i2c_client *client, u8 reg, | ||
147 | u16 value) | ||
148 | { | ||
149 | int err = i2c_smbus_write_byte_data(client, reg, (value << 8)); | ||
150 | if (err) | ||
151 | return; | ||
152 | i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF)); | ||
153 | } | ||
154 | |||
155 | static struct f75375_data *f75375_update_device(struct device *dev) | ||
156 | { | ||
157 | struct i2c_client *client = to_i2c_client(dev); | ||
158 | struct f75375_data *data = i2c_get_clientdata(client); | ||
159 | int nr; | ||
160 | |||
161 | mutex_lock(&data->update_lock); | ||
162 | |||
163 | /* Limit registers cache is refreshed after 60 seconds */ | ||
164 | if (time_after(jiffies, data->last_limits + 60 * HZ) | ||
165 | || !data->valid) { | ||
166 | for (nr = 0; nr < 2; nr++) { | ||
167 | data->temp_high[nr] = | ||
168 | f75375_read8(client, F75375_REG_TEMP_HIGH(nr)); | ||
169 | data->temp_max_hyst[nr] = | ||
170 | f75375_read8(client, F75375_REG_TEMP_HYST(nr)); | ||
171 | data->fan_full[nr] = | ||
172 | f75375_read16(client, F75375_REG_FAN_FULL(nr)); | ||
173 | data->fan_min[nr] = | ||
174 | f75375_read16(client, F75375_REG_FAN_MIN(nr)); | ||
175 | data->fan_exp[nr] = | ||
176 | f75375_read16(client, F75375_REG_FAN_EXP(nr)); | ||
177 | data->pwm[nr] = f75375_read8(client, | ||
178 | F75375_REG_FAN_PWM_DUTY(nr)); | ||
179 | |||
180 | } | ||
181 | for (nr = 0; nr < 4; nr++) { | ||
182 | data->in_max[nr] = | ||
183 | f75375_read8(client, F75375_REG_VOLT_HIGH(nr)); | ||
184 | data->in_min[nr] = | ||
185 | f75375_read8(client, F75375_REG_VOLT_LOW(nr)); | ||
186 | } | ||
187 | data->fan_timer = f75375_read8(client, F75375_REG_FAN_TIMER); | ||
188 | data->last_limits = jiffies; | ||
189 | } | ||
190 | |||
191 | /* Measurement registers cache is refreshed after 2 second */ | ||
192 | if (time_after(jiffies, data->last_updated + 2 * HZ) | ||
193 | || !data->valid) { | ||
194 | for (nr = 0; nr < 2; nr++) { | ||
195 | data->temp[nr] = | ||
196 | f75375_read8(client, F75375_REG_TEMP(nr)); | ||
197 | data->fan[nr] = | ||
198 | f75375_read16(client, F75375_REG_FAN(nr)); | ||
199 | } | ||
200 | for (nr = 0; nr < 4; nr++) | ||
201 | data->in[nr] = | ||
202 | f75375_read8(client, F75375_REG_VOLT(nr)); | ||
203 | |||
204 | data->last_updated = jiffies; | ||
205 | data->valid = 1; | ||
206 | } | ||
207 | |||
208 | mutex_unlock(&data->update_lock); | ||
209 | return data; | ||
210 | } | ||
211 | |||
212 | static inline u16 rpm_from_reg(u16 reg) | ||
213 | { | ||
214 | if (reg == 0 || reg == 0xffff) | ||
215 | return 0; | ||
216 | return (1500000 / reg); | ||
217 | } | ||
218 | |||
219 | static inline u16 rpm_to_reg(int rpm) | ||
220 | { | ||
221 | if (rpm < 367 || rpm > 0xffff) | ||
222 | return 0xffff; | ||
223 | return (1500000 / rpm); | ||
224 | } | ||
225 | |||
226 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | ||
227 | const char *buf, size_t count) | ||
228 | { | ||
229 | int nr = to_sensor_dev_attr(attr)->index; | ||
230 | struct i2c_client *client = to_i2c_client(dev); | ||
231 | struct f75375_data *data = i2c_get_clientdata(client); | ||
232 | int val = simple_strtoul(buf, NULL, 10); | ||
233 | |||
234 | mutex_lock(&data->update_lock); | ||
235 | data->fan_min[nr] = rpm_to_reg(val); | ||
236 | f75375_write16(client, F75375_REG_FAN_MIN(nr), data->fan_min[nr]); | ||
237 | mutex_unlock(&data->update_lock); | ||
238 | return count; | ||
239 | } | ||
240 | |||
241 | static ssize_t set_fan_exp(struct device *dev, struct device_attribute *attr, | ||
242 | const char *buf, size_t count) | ||
243 | { | ||
244 | int nr = to_sensor_dev_attr(attr)->index; | ||
245 | struct i2c_client *client = to_i2c_client(dev); | ||
246 | struct f75375_data *data = i2c_get_clientdata(client); | ||
247 | int val = simple_strtoul(buf, NULL, 10); | ||
248 | |||
249 | mutex_lock(&data->update_lock); | ||
250 | data->fan_exp[nr] = rpm_to_reg(val); | ||
251 | f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_exp[nr]); | ||
252 | mutex_unlock(&data->update_lock); | ||
253 | return count; | ||
254 | } | ||
255 | |||
256 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | ||
257 | const char *buf, size_t count) | ||
258 | { | ||
259 | int nr = to_sensor_dev_attr(attr)->index; | ||
260 | struct i2c_client *client = to_i2c_client(dev); | ||
261 | struct f75375_data *data = i2c_get_clientdata(client); | ||
262 | int val = simple_strtoul(buf, NULL, 10); | ||
263 | |||
264 | mutex_lock(&data->update_lock); | ||
265 | data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); | ||
266 | f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), data->pwm[nr]); | ||
267 | mutex_unlock(&data->update_lock); | ||
268 | return count; | ||
269 | } | ||
270 | |||
271 | static ssize_t show_pwm_enable(struct device *dev, struct device_attribute | ||
272 | *attr, char *buf) | ||
273 | { | ||
274 | int nr = to_sensor_dev_attr(attr)->index; | ||
275 | struct f75375_data *data = f75375_update_device(dev); | ||
276 | return sprintf(buf, "%d\n", data->pwm_enable[nr]); | ||
277 | } | ||
278 | |||
279 | static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, | ||
280 | const char *buf, size_t count) | ||
281 | { | ||
282 | int nr = to_sensor_dev_attr(attr)->index; | ||
283 | struct i2c_client *client = to_i2c_client(dev); | ||
284 | struct f75375_data *data = i2c_get_clientdata(client); | ||
285 | int val = simple_strtoul(buf, NULL, 10); | ||
286 | u8 fanmode; | ||
287 | |||
288 | if (val < 0 || val > 4) | ||
289 | return -EINVAL; | ||
290 | |||
291 | mutex_lock(&data->update_lock); | ||
292 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); | ||
293 | fanmode = ~(3 << FAN_CTRL_MODE(nr)); | ||
294 | |||
295 | switch (val) { | ||
296 | case 0: /* Full speed */ | ||
297 | fanmode |= (3 << FAN_CTRL_MODE(nr)); | ||
298 | data->pwm[nr] = 255; | ||
299 | f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), | ||
300 | data->pwm[nr]); | ||
301 | break; | ||
302 | case 1: /* PWM */ | ||
303 | fanmode |= (3 << FAN_CTRL_MODE(nr)); | ||
304 | break; | ||
305 | case 2: /* AUTOMATIC*/ | ||
306 | fanmode |= (2 << FAN_CTRL_MODE(nr)); | ||
307 | break; | ||
308 | case 3: /* fan speed */ | ||
309 | break; | ||
310 | } | ||
311 | f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); | ||
312 | data->pwm_enable[nr] = val; | ||
313 | mutex_unlock(&data->update_lock); | ||
314 | return count; | ||
315 | } | ||
316 | |||
317 | static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, | ||
318 | const char *buf, size_t count) | ||
319 | { | ||
320 | int nr = to_sensor_dev_attr(attr)->index; | ||
321 | struct i2c_client *client = to_i2c_client(dev); | ||
322 | struct f75375_data *data = i2c_get_clientdata(client); | ||
323 | int val = simple_strtoul(buf, NULL, 10); | ||
324 | u8 conf = 0; | ||
325 | |||
326 | if (val != 0 || val != 1 || data->kind == f75373) | ||
327 | return -EINVAL; | ||
328 | |||
329 | mutex_lock(&data->update_lock); | ||
330 | conf = f75375_read8(client, F75375_REG_CONFIG1); | ||
331 | conf = ~(1 << FAN_CTRL_LINEAR(nr)); | ||
332 | |||
333 | if (val == 0) | ||
334 | conf |= (1 << FAN_CTRL_LINEAR(nr)) ; | ||
335 | |||
336 | f75375_write8(client, F75375_REG_CONFIG1, conf); | ||
337 | data->pwm_mode[nr] = val; | ||
338 | mutex_unlock(&data->update_lock); | ||
339 | return count; | ||
340 | } | ||
341 | |||
342 | static ssize_t show_pwm(struct device *dev, struct device_attribute | ||
343 | *attr, char *buf) | ||
344 | { | ||
345 | int nr = to_sensor_dev_attr(attr)->index; | ||
346 | struct f75375_data *data = f75375_update_device(dev); | ||
347 | return sprintf(buf, "%d\n", data->pwm[nr]); | ||
348 | } | ||
349 | |||
350 | static ssize_t show_pwm_mode(struct device *dev, struct device_attribute | ||
351 | *attr, char *buf) | ||
352 | { | ||
353 | int nr = to_sensor_dev_attr(attr)->index; | ||
354 | struct f75375_data *data = f75375_update_device(dev); | ||
355 | return sprintf(buf, "%d\n", data->pwm_mode[nr]); | ||
356 | } | ||
357 | |||
358 | #define VOLT_FROM_REG(val) ((val) * 8) | ||
359 | #define VOLT_TO_REG(val) ((val) / 8) | ||
360 | |||
361 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | ||
362 | char *buf) | ||
363 | { | ||
364 | int nr = to_sensor_dev_attr(attr)->index; | ||
365 | struct f75375_data *data = f75375_update_device(dev); | ||
366 | return sprintf(buf, "%d\n", VOLT_FROM_REG(data->in[nr])); | ||
367 | } | ||
368 | |||
369 | static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, | ||
370 | char *buf) | ||
371 | { | ||
372 | int nr = to_sensor_dev_attr(attr)->index; | ||
373 | struct f75375_data *data = f75375_update_device(dev); | ||
374 | return sprintf(buf, "%d\n", VOLT_FROM_REG(data->in_max[nr])); | ||
375 | } | ||
376 | |||
377 | static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, | ||
378 | char *buf) | ||
379 | { | ||
380 | int nr = to_sensor_dev_attr(attr)->index; | ||
381 | struct f75375_data *data = f75375_update_device(dev); | ||
382 | return sprintf(buf, "%d\n", VOLT_FROM_REG(data->in_min[nr])); | ||
383 | } | ||
384 | |||
385 | static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | ||
386 | const char *buf, size_t count) | ||
387 | { | ||
388 | int nr = to_sensor_dev_attr(attr)->index; | ||
389 | struct i2c_client *client = to_i2c_client(dev); | ||
390 | struct f75375_data *data = i2c_get_clientdata(client); | ||
391 | int val = simple_strtoul(buf, NULL, 10); | ||
392 | val = SENSORS_LIMIT(VOLT_TO_REG(val), 0, 0xff); | ||
393 | mutex_lock(&data->update_lock); | ||
394 | data->in_max[nr] = val; | ||
395 | f75375_write8(client, F75375_REG_VOLT_HIGH(nr), data->in_max[nr]); | ||
396 | mutex_unlock(&data->update_lock); | ||
397 | return count; | ||
398 | } | ||
399 | |||
400 | static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | ||
401 | const char *buf, size_t count) | ||
402 | { | ||
403 | int nr = to_sensor_dev_attr(attr)->index; | ||
404 | struct i2c_client *client = to_i2c_client(dev); | ||
405 | struct f75375_data *data = i2c_get_clientdata(client); | ||
406 | int val = simple_strtoul(buf, NULL, 10); | ||
407 | val = SENSORS_LIMIT(VOLT_TO_REG(val), 0, 0xff); | ||
408 | mutex_lock(&data->update_lock); | ||
409 | data->in_min[nr] = val; | ||
410 | f75375_write8(client, F75375_REG_VOLT_LOW(nr), data->in_min[nr]); | ||
411 | mutex_unlock(&data->update_lock); | ||
412 | return count; | ||
413 | } | ||
414 | #define TEMP_FROM_REG(val) ((val) * 1000) | ||
415 | #define TEMP_TO_REG(val) ((val) / 1000) | ||
416 | |||
417 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | ||
418 | char *buf) | ||
419 | { | ||
420 | int nr = to_sensor_dev_attr(attr)->index; | ||
421 | struct f75375_data *data = f75375_update_device(dev); | ||
422 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); | ||
423 | } | ||
424 | |||
425 | static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, | ||
426 | char *buf) | ||
427 | { | ||
428 | int nr = to_sensor_dev_attr(attr)->index; | ||
429 | struct f75375_data *data = f75375_update_device(dev); | ||
430 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr])); | ||
431 | } | ||
432 | |||
433 | static ssize_t show_temp_max_hyst(struct device *dev, | ||
434 | struct device_attribute *attr, char *buf) | ||
435 | { | ||
436 | int nr = to_sensor_dev_attr(attr)->index; | ||
437 | struct f75375_data *data = f75375_update_device(dev); | ||
438 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max_hyst[nr])); | ||
439 | } | ||
440 | |||
441 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | ||
442 | const char *buf, size_t count) | ||
443 | { | ||
444 | int nr = to_sensor_dev_attr(attr)->index; | ||
445 | struct i2c_client *client = to_i2c_client(dev); | ||
446 | struct f75375_data *data = i2c_get_clientdata(client); | ||
447 | int val = simple_strtol(buf, NULL, 10); | ||
448 | val = SENSORS_LIMIT(TEMP_TO_REG(val), 0, 127); | ||
449 | mutex_lock(&data->update_lock); | ||
450 | data->temp_high[nr] = val; | ||
451 | f75375_write8(client, F75375_REG_TEMP_HIGH(nr), data->temp_high[nr]); | ||
452 | mutex_unlock(&data->update_lock); | ||
453 | return count; | ||
454 | } | ||
455 | |||
456 | static ssize_t set_temp_max_hyst(struct device *dev, | ||
457 | struct device_attribute *attr, const char *buf, size_t count) | ||
458 | { | ||
459 | int nr = to_sensor_dev_attr(attr)->index; | ||
460 | struct i2c_client *client = to_i2c_client(dev); | ||
461 | struct f75375_data *data = i2c_get_clientdata(client); | ||
462 | int val = simple_strtol(buf, NULL, 10); | ||
463 | val = SENSORS_LIMIT(TEMP_TO_REG(val), 0, 127); | ||
464 | mutex_lock(&data->update_lock); | ||
465 | data->temp_max_hyst[nr] = val; | ||
466 | f75375_write8(client, F75375_REG_TEMP_HYST(nr), | ||
467 | data->temp_max_hyst[nr]); | ||
468 | mutex_unlock(&data->update_lock); | ||
469 | return count; | ||
470 | } | ||
471 | |||
472 | #define show_fan(thing) \ | ||
473 | static ssize_t show_##thing(struct device *dev, struct device_attribute *attr, \ | ||
474 | char *buf)\ | ||
475 | {\ | ||
476 | int nr = to_sensor_dev_attr(attr)->index;\ | ||
477 | struct f75375_data *data = f75375_update_device(dev); \ | ||
478 | return sprintf(buf, "%d\n", rpm_from_reg(data->thing[nr])); \ | ||
479 | } | ||
480 | |||
481 | show_fan(fan); | ||
482 | show_fan(fan_min); | ||
483 | show_fan(fan_full); | ||
484 | show_fan(fan_exp); | ||
485 | |||
486 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0); | ||
487 | static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO|S_IWUSR, | ||
488 | show_in_max, set_in_max, 0); | ||
489 | static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO|S_IWUSR, | ||
490 | show_in_min, set_in_min, 0); | ||
491 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1); | ||
492 | static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO|S_IWUSR, | ||
493 | show_in_max, set_in_max, 1); | ||
494 | static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO|S_IWUSR, | ||
495 | show_in_min, set_in_min, 1); | ||
496 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2); | ||
497 | static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO|S_IWUSR, | ||
498 | show_in_max, set_in_max, 2); | ||
499 | static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO|S_IWUSR, | ||
500 | show_in_min, set_in_min, 2); | ||
501 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3); | ||
502 | static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO|S_IWUSR, | ||
503 | show_in_max, set_in_max, 3); | ||
504 | static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO|S_IWUSR, | ||
505 | show_in_min, set_in_min, 3); | ||
506 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
507 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR, | ||
508 | show_temp_max_hyst, set_temp_max_hyst, 0); | ||
509 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO|S_IWUSR, | ||
510 | show_temp_max, set_temp_max, 0); | ||
511 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
512 | static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR, | ||
513 | show_temp_max_hyst, set_temp_max_hyst, 1); | ||
514 | static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO|S_IWUSR, | ||
515 | show_temp_max, set_temp_max, 1); | ||
516 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); | ||
517 | static SENSOR_DEVICE_ATTR(fan1_full, S_IRUGO, show_fan_full, NULL, 0); | ||
518 | static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO|S_IWUSR, | ||
519 | show_fan_min, set_fan_min, 0); | ||
520 | static SENSOR_DEVICE_ATTR(fan1_exp, S_IRUGO|S_IWUSR, | ||
521 | show_fan_exp, set_fan_exp, 0); | ||
522 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); | ||
523 | static SENSOR_DEVICE_ATTR(fan2_full, S_IRUGO, show_fan_full, NULL, 1); | ||
524 | static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO|S_IWUSR, | ||
525 | show_fan_min, set_fan_min, 1); | ||
526 | static SENSOR_DEVICE_ATTR(fan2_exp, S_IRUGO|S_IWUSR, | ||
527 | show_fan_exp, set_fan_exp, 1); | ||
528 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR, | ||
529 | show_pwm, set_pwm, 0); | ||
530 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, | ||
531 | show_pwm_enable, set_pwm_enable, 0); | ||
532 | static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO|S_IWUSR, | ||
533 | show_pwm_mode, set_pwm_mode, 0); | ||
534 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, | ||
535 | show_pwm, set_pwm, 1); | ||
536 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR, | ||
537 | show_pwm_enable, set_pwm_enable, 1); | ||
538 | static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO|S_IWUSR, | ||
539 | show_pwm_mode, set_pwm_mode, 1); | ||
540 | |||
541 | static struct attribute *f75375_attributes[] = { | ||
542 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
543 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
544 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | ||
545 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
546 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
547 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, | ||
548 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
549 | &sensor_dev_attr_fan1_full.dev_attr.attr, | ||
550 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
551 | &sensor_dev_attr_fan1_exp.dev_attr.attr, | ||
552 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
553 | &sensor_dev_attr_fan2_full.dev_attr.attr, | ||
554 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
555 | &sensor_dev_attr_fan2_exp.dev_attr.attr, | ||
556 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
557 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
558 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, | ||
559 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
560 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
561 | &sensor_dev_attr_pwm2_mode.dev_attr.attr, | ||
562 | &sensor_dev_attr_in0_input.dev_attr.attr, | ||
563 | &sensor_dev_attr_in0_max.dev_attr.attr, | ||
564 | &sensor_dev_attr_in0_min.dev_attr.attr, | ||
565 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
566 | &sensor_dev_attr_in1_max.dev_attr.attr, | ||
567 | &sensor_dev_attr_in1_min.dev_attr.attr, | ||
568 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
569 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
570 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
571 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
572 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
573 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
574 | NULL | ||
575 | }; | ||
576 | |||
577 | static const struct attribute_group f75375_group = { | ||
578 | .attrs = f75375_attributes, | ||
579 | }; | ||
580 | |||
581 | static int f75375_detach_client(struct i2c_client *client) | ||
582 | { | ||
583 | struct f75375_data *data = i2c_get_clientdata(client); | ||
584 | int err; | ||
585 | |||
586 | hwmon_device_unregister(data->hwmon_dev); | ||
587 | sysfs_remove_group(&client->dev.kobj, &f75375_group); | ||
588 | |||
589 | err = i2c_detach_client(client); | ||
590 | if (err) { | ||
591 | dev_err(&client->dev, | ||
592 | "Client deregistration failed, " | ||
593 | "client not detached.\n"); | ||
594 | return err; | ||
595 | } | ||
596 | kfree(data); | ||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | static int f75375_attach_adapter(struct i2c_adapter *adapter) | ||
601 | { | ||
602 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
603 | return 0; | ||
604 | return i2c_probe(adapter, &addr_data, f75375_detect); | ||
605 | } | ||
606 | |||
607 | /* This function is called by i2c_probe */ | ||
608 | static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) | ||
609 | { | ||
610 | struct i2c_client *client; | ||
611 | struct f75375_data *data; | ||
612 | u8 version = 0; | ||
613 | int err = 0; | ||
614 | const char *name = ""; | ||
615 | |||
616 | if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL))) { | ||
617 | err = -ENOMEM; | ||
618 | goto exit; | ||
619 | } | ||
620 | client = &data->client; | ||
621 | i2c_set_clientdata(client, data); | ||
622 | client->addr = address; | ||
623 | client->adapter = adapter; | ||
624 | client->driver = &f75375_driver; | ||
625 | |||
626 | if (kind < 0) { | ||
627 | u16 vendid = f75375_read16(client, F75375_REG_VENDOR); | ||
628 | u16 chipid = f75375_read16(client, F75375_CHIP_ID); | ||
629 | version = f75375_read8(client, F75375_REG_VERSION); | ||
630 | if (chipid == 0x0306 && vendid == 0x1934) { | ||
631 | kind = f75375; | ||
632 | } else if (chipid == 0x0204 && vendid == 0x1934) { | ||
633 | kind = f75373; | ||
634 | } else { | ||
635 | dev_err(&adapter->dev, | ||
636 | "failed,%02X,%02X,%02X\n", | ||
637 | chipid, version, vendid); | ||
638 | goto exit_free; | ||
639 | } | ||
640 | } | ||
641 | |||
642 | if (kind == f75375) { | ||
643 | name = "f75375"; | ||
644 | } else if (kind == f75373) { | ||
645 | name = "f75373"; | ||
646 | } | ||
647 | |||
648 | dev_info(&adapter->dev, "found %s version: %02X\n", name, version); | ||
649 | strlcpy(client->name, name, I2C_NAME_SIZE); | ||
650 | data->kind = kind; | ||
651 | mutex_init(&data->update_lock); | ||
652 | if ((err = i2c_attach_client(client))) | ||
653 | goto exit_free; | ||
654 | |||
655 | if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group))) | ||
656 | goto exit_detach; | ||
657 | |||
658 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
659 | if (IS_ERR(data->hwmon_dev)) { | ||
660 | err = PTR_ERR(data->hwmon_dev); | ||
661 | goto exit_remove; | ||
662 | } | ||
663 | |||
664 | return 0; | ||
665 | |||
666 | exit_remove: | ||
667 | sysfs_remove_group(&client->dev.kobj, &f75375_group); | ||
668 | exit_detach: | ||
669 | i2c_detach_client(client); | ||
670 | exit_free: | ||
671 | kfree(data); | ||
672 | exit: | ||
673 | return err; | ||
674 | } | ||
675 | |||
676 | static int __init sensors_f75375_init(void) | ||
677 | { | ||
678 | return i2c_add_driver(&f75375_driver); | ||
679 | } | ||
680 | |||
681 | static void __exit sensors_f75375_exit(void) | ||
682 | { | ||
683 | i2c_del_driver(&f75375_driver); | ||
684 | } | ||
685 | |||
686 | MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>"); | ||
687 | MODULE_LICENSE("GPL"); | ||
688 | MODULE_DESCRIPTION("F75373/F75375 hardware monitoring driver"); | ||
689 | |||
690 | module_init(sensors_f75375_init); | ||
691 | module_exit(sensors_f75375_exit); | ||
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index b34b546c68b8..e67c36953b2d 100644 --- a/drivers/hwmon/fscher.c +++ b/drivers/hwmon/fscher.c | |||
@@ -134,7 +134,7 @@ static struct i2c_driver fscher_driver = { | |||
134 | 134 | ||
135 | struct fscher_data { | 135 | struct fscher_data { |
136 | struct i2c_client client; | 136 | struct i2c_client client; |
137 | struct class_device *class_dev; | 137 | struct device *hwmon_dev; |
138 | struct mutex update_lock; | 138 | struct mutex update_lock; |
139 | char valid; /* zero until following fields are valid */ | 139 | char valid; /* zero until following fields are valid */ |
140 | unsigned long last_updated; /* in jiffies */ | 140 | unsigned long last_updated; /* in jiffies */ |
@@ -344,9 +344,9 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) | |||
344 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group))) | 344 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group))) |
345 | goto exit_detach; | 345 | goto exit_detach; |
346 | 346 | ||
347 | data->class_dev = hwmon_device_register(&new_client->dev); | 347 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
348 | if (IS_ERR(data->class_dev)) { | 348 | if (IS_ERR(data->hwmon_dev)) { |
349 | err = PTR_ERR(data->class_dev); | 349 | err = PTR_ERR(data->hwmon_dev); |
350 | goto exit_remove_files; | 350 | goto exit_remove_files; |
351 | } | 351 | } |
352 | 352 | ||
@@ -367,7 +367,7 @@ static int fscher_detach_client(struct i2c_client *client) | |||
367 | struct fscher_data *data = i2c_get_clientdata(client); | 367 | struct fscher_data *data = i2c_get_clientdata(client); |
368 | int err; | 368 | int err; |
369 | 369 | ||
370 | hwmon_device_unregister(data->class_dev); | 370 | hwmon_device_unregister(data->hwmon_dev); |
371 | sysfs_remove_group(&client->dev.kobj, &fscher_group); | 371 | sysfs_remove_group(&client->dev.kobj, &fscher_group); |
372 | 372 | ||
373 | if ((err = i2c_detach_client(client))) | 373 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index ea506a77f9c9..92c9703d0ac0 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c | |||
@@ -115,7 +115,7 @@ static struct i2c_driver fscpos_driver = { | |||
115 | */ | 115 | */ |
116 | struct fscpos_data { | 116 | struct fscpos_data { |
117 | struct i2c_client client; | 117 | struct i2c_client client; |
118 | struct class_device *class_dev; | 118 | struct device *hwmon_dev; |
119 | struct mutex update_lock; | 119 | struct mutex update_lock; |
120 | char valid; /* 0 until following fields are valid */ | 120 | char valid; /* 0 until following fields are valid */ |
121 | unsigned long last_updated; /* In jiffies */ | 121 | unsigned long last_updated; /* In jiffies */ |
@@ -539,9 +539,9 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) | |||
539 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group))) | 539 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group))) |
540 | goto exit_detach; | 540 | goto exit_detach; |
541 | 541 | ||
542 | data->class_dev = hwmon_device_register(&new_client->dev); | 542 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
543 | if (IS_ERR(data->class_dev)) { | 543 | if (IS_ERR(data->hwmon_dev)) { |
544 | err = PTR_ERR(data->class_dev); | 544 | err = PTR_ERR(data->hwmon_dev); |
545 | goto exit_remove_files; | 545 | goto exit_remove_files; |
546 | } | 546 | } |
547 | 547 | ||
@@ -562,7 +562,7 @@ static int fscpos_detach_client(struct i2c_client *client) | |||
562 | struct fscpos_data *data = i2c_get_clientdata(client); | 562 | struct fscpos_data *data = i2c_get_clientdata(client); |
563 | int err; | 563 | int err; |
564 | 564 | ||
565 | hwmon_device_unregister(data->class_dev); | 565 | hwmon_device_unregister(data->hwmon_dev); |
566 | sysfs_remove_group(&client->dev.kobj, &fscpos_group); | 566 | sysfs_remove_group(&client->dev.kobj, &fscpos_group); |
567 | 567 | ||
568 | if ((err = i2c_detach_client(client))) | 568 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index c103640455a3..bb58d9866a37 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c | |||
@@ -119,7 +119,7 @@ static inline u8 FAN_TO_REG(long rpm, int div) | |||
119 | /* Each client has this additional data */ | 119 | /* Each client has this additional data */ |
120 | struct gl518_data { | 120 | struct gl518_data { |
121 | struct i2c_client client; | 121 | struct i2c_client client; |
122 | struct class_device *class_dev; | 122 | struct device *hwmon_dev; |
123 | enum chips type; | 123 | enum chips type; |
124 | 124 | ||
125 | struct mutex update_lock; | 125 | struct mutex update_lock; |
@@ -460,9 +460,9 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) | |||
460 | if ((err = sysfs_create_group(&new_client->dev.kobj, &gl518_group))) | 460 | if ((err = sysfs_create_group(&new_client->dev.kobj, &gl518_group))) |
461 | goto exit_detach; | 461 | goto exit_detach; |
462 | 462 | ||
463 | data->class_dev = hwmon_device_register(&new_client->dev); | 463 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
464 | if (IS_ERR(data->class_dev)) { | 464 | if (IS_ERR(data->hwmon_dev)) { |
465 | err = PTR_ERR(data->class_dev); | 465 | err = PTR_ERR(data->hwmon_dev); |
466 | goto exit_remove_files; | 466 | goto exit_remove_files; |
467 | } | 467 | } |
468 | 468 | ||
@@ -502,7 +502,7 @@ static int gl518_detach_client(struct i2c_client *client) | |||
502 | struct gl518_data *data = i2c_get_clientdata(client); | 502 | struct gl518_data *data = i2c_get_clientdata(client); |
503 | int err; | 503 | int err; |
504 | 504 | ||
505 | hwmon_device_unregister(data->class_dev); | 505 | hwmon_device_unregister(data->hwmon_dev); |
506 | sysfs_remove_group(&client->dev.kobj, &gl518_group); | 506 | sysfs_remove_group(&client->dev.kobj, &gl518_group); |
507 | 507 | ||
508 | if ((err = i2c_detach_client(client))) | 508 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index ebe7b9aaa916..a3b56c816e11 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c | |||
@@ -122,7 +122,7 @@ static struct i2c_driver gl520_driver = { | |||
122 | /* Client data */ | 122 | /* Client data */ |
123 | struct gl520_data { | 123 | struct gl520_data { |
124 | struct i2c_client client; | 124 | struct i2c_client client; |
125 | struct class_device *class_dev; | 125 | struct device *hwmon_dev; |
126 | struct mutex update_lock; | 126 | struct mutex update_lock; |
127 | char valid; /* zero until the following fields are valid */ | 127 | char valid; /* zero until the following fields are valid */ |
128 | unsigned long last_updated; /* in jiffies */ | 128 | unsigned long last_updated; /* in jiffies */ |
@@ -622,9 +622,9 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) | |||
622 | } | 622 | } |
623 | 623 | ||
624 | 624 | ||
625 | data->class_dev = hwmon_device_register(&new_client->dev); | 625 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
626 | if (IS_ERR(data->class_dev)) { | 626 | if (IS_ERR(data->hwmon_dev)) { |
627 | err = PTR_ERR(data->class_dev); | 627 | err = PTR_ERR(data->hwmon_dev); |
628 | goto exit_remove_files; | 628 | goto exit_remove_files; |
629 | } | 629 | } |
630 | 630 | ||
@@ -685,7 +685,7 @@ static int gl520_detach_client(struct i2c_client *client) | |||
685 | struct gl520_data *data = i2c_get_clientdata(client); | 685 | struct gl520_data *data = i2c_get_clientdata(client); |
686 | int err; | 686 | int err; |
687 | 687 | ||
688 | hwmon_device_unregister(data->class_dev); | 688 | hwmon_device_unregister(data->hwmon_dev); |
689 | sysfs_remove_group(&client->dev.kobj, &gl520_group); | 689 | sysfs_remove_group(&client->dev.kobj, &gl520_group); |
690 | sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); | 690 | sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); |
691 | 691 | ||
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index affcc00764d3..3db28450a3b3 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
@@ -28,17 +28,17 @@ static DEFINE_IDR(hwmon_idr); | |||
28 | static DEFINE_SPINLOCK(idr_lock); | 28 | static DEFINE_SPINLOCK(idr_lock); |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * hwmon_device_register - register w/ hwmon sysfs class | 31 | * hwmon_device_register - register w/ hwmon |
32 | * @dev: the device to register | 32 | * @dev: the device to register |
33 | * | 33 | * |
34 | * hwmon_device_unregister() must be called when the class device is no | 34 | * hwmon_device_unregister() must be called when the device is no |
35 | * longer needed. | 35 | * longer needed. |
36 | * | 36 | * |
37 | * Returns the pointer to the new struct class device. | 37 | * Returns the pointer to the new device. |
38 | */ | 38 | */ |
39 | struct class_device *hwmon_device_register(struct device *dev) | 39 | struct device *hwmon_device_register(struct device *dev) |
40 | { | 40 | { |
41 | struct class_device *cdev; | 41 | struct device *hwdev; |
42 | int id, err; | 42 | int id, err; |
43 | 43 | ||
44 | again: | 44 | again: |
@@ -55,34 +55,33 @@ again: | |||
55 | return ERR_PTR(err); | 55 | return ERR_PTR(err); |
56 | 56 | ||
57 | id = id & MAX_ID_MASK; | 57 | id = id & MAX_ID_MASK; |
58 | cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev, | 58 | hwdev = device_create(hwmon_class, dev, MKDEV(0,0), HWMON_ID_FORMAT, id); |
59 | HWMON_ID_FORMAT, id); | ||
60 | 59 | ||
61 | if (IS_ERR(cdev)) { | 60 | if (IS_ERR(hwdev)) { |
62 | spin_lock(&idr_lock); | 61 | spin_lock(&idr_lock); |
63 | idr_remove(&hwmon_idr, id); | 62 | idr_remove(&hwmon_idr, id); |
64 | spin_unlock(&idr_lock); | 63 | spin_unlock(&idr_lock); |
65 | } | 64 | } |
66 | 65 | ||
67 | return cdev; | 66 | return hwdev; |
68 | } | 67 | } |
69 | 68 | ||
70 | /** | 69 | /** |
71 | * hwmon_device_unregister - removes the previously registered class device | 70 | * hwmon_device_unregister - removes the previously registered class device |
72 | * | 71 | * |
73 | * @cdev: the class device to destroy | 72 | * @dev: the class device to destroy |
74 | */ | 73 | */ |
75 | void hwmon_device_unregister(struct class_device *cdev) | 74 | void hwmon_device_unregister(struct device *dev) |
76 | { | 75 | { |
77 | int id; | 76 | int id; |
78 | 77 | ||
79 | if (likely(sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1)) { | 78 | if (likely(sscanf(dev->bus_id, HWMON_ID_FORMAT, &id) == 1)) { |
80 | class_device_unregister(cdev); | 79 | device_unregister(dev); |
81 | spin_lock(&idr_lock); | 80 | spin_lock(&idr_lock); |
82 | idr_remove(&hwmon_idr, id); | 81 | idr_remove(&hwmon_idr, id); |
83 | spin_unlock(&idr_lock); | 82 | spin_unlock(&idr_lock); |
84 | } else | 83 | } else |
85 | dev_dbg(cdev->dev, | 84 | dev_dbg(dev->parent, |
86 | "hwmon_device_unregister() failed: bad class ID!\n"); | 85 | "hwmon_device_unregister() failed: bad class ID!\n"); |
87 | } | 86 | } |
88 | 87 | ||
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c new file mode 100644 index 000000000000..fe2c2616c6b1 --- /dev/null +++ b/drivers/hwmon/ibmpex.c | |||
@@ -0,0 +1,608 @@ | |||
1 | /* | ||
2 | * A hwmon driver for the IBM PowerExecutive temperature/power sensors | ||
3 | * Copyright (C) 2007 IBM | ||
4 | * | ||
5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/ipmi.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/hwmon.h> | ||
25 | #include <linux/hwmon-sysfs.h> | ||
26 | #include <linux/jiffies.h> | ||
27 | #include <linux/mutex.h> | ||
28 | |||
29 | #define REFRESH_INTERVAL (2 * HZ) | ||
30 | #define DRVNAME "ibmpex" | ||
31 | |||
32 | #define PEX_GET_VERSION 1 | ||
33 | #define PEX_GET_SENSOR_COUNT 2 | ||
34 | #define PEX_GET_SENSOR_NAME 3 | ||
35 | #define PEX_RESET_HIGH_LOW 4 | ||
36 | #define PEX_GET_SENSOR_DATA 6 | ||
37 | |||
38 | #define PEX_NET_FUNCTION 0x3A | ||
39 | #define PEX_COMMAND 0x3C | ||
40 | |||
41 | static inline u16 extract_value(const char *data, int offset) | ||
42 | { | ||
43 | return be16_to_cpup((u16 *)&data[offset]); | ||
44 | } | ||
45 | |||
46 | #define TEMP_SENSOR 1 | ||
47 | #define POWER_SENSOR 2 | ||
48 | |||
49 | #define PEX_SENSOR_TYPE_LEN 3 | ||
50 | static u8 const power_sensor_sig[] = {0x70, 0x77, 0x72}; | ||
51 | static u8 const temp_sensor_sig[] = {0x74, 0x65, 0x6D}; | ||
52 | |||
53 | #define PEX_MULT_LEN 2 | ||
54 | static u8 const watt_sensor_sig[] = {0x41, 0x43}; | ||
55 | |||
56 | #define PEX_NUM_SENSOR_FUNCS 3 | ||
57 | static char const * const power_sensor_name_templates[] = { | ||
58 | "%s%d_average", | ||
59 | "%s%d_average_lowest", | ||
60 | "%s%d_average_highest" | ||
61 | }; | ||
62 | static char const * const temp_sensor_name_templates[] = { | ||
63 | "%s%d_input", | ||
64 | "%s%d_input_lowest", | ||
65 | "%s%d_input_highest" | ||
66 | }; | ||
67 | |||
68 | static void ibmpex_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); | ||
69 | static void ibmpex_register_bmc(int iface, struct device *dev); | ||
70 | static void ibmpex_bmc_gone(int iface); | ||
71 | |||
72 | struct ibmpex_sensor_data { | ||
73 | int in_use; | ||
74 | s16 values[PEX_NUM_SENSOR_FUNCS]; | ||
75 | int multiplier; | ||
76 | |||
77 | struct sensor_device_attribute_2 attr[PEX_NUM_SENSOR_FUNCS]; | ||
78 | }; | ||
79 | |||
80 | struct ibmpex_bmc_data { | ||
81 | struct list_head list; | ||
82 | struct device *hwmon_dev; | ||
83 | struct device *bmc_device; | ||
84 | struct mutex lock; | ||
85 | char valid; | ||
86 | unsigned long last_updated; /* In jiffies */ | ||
87 | |||
88 | struct ipmi_addr address; | ||
89 | struct completion read_complete; | ||
90 | ipmi_user_t user; | ||
91 | int interface; | ||
92 | |||
93 | struct kernel_ipmi_msg tx_message; | ||
94 | unsigned char tx_msg_data[IPMI_MAX_MSG_LENGTH]; | ||
95 | long tx_msgid; | ||
96 | |||
97 | unsigned char rx_msg_data[IPMI_MAX_MSG_LENGTH]; | ||
98 | unsigned long rx_msg_len; | ||
99 | unsigned char rx_result; | ||
100 | int rx_recv_type; | ||
101 | |||
102 | unsigned char sensor_major; | ||
103 | unsigned char sensor_minor; | ||
104 | |||
105 | unsigned char num_sensors; | ||
106 | struct ibmpex_sensor_data *sensors; | ||
107 | }; | ||
108 | |||
109 | struct ibmpex_driver_data { | ||
110 | struct list_head bmc_data; | ||
111 | struct ipmi_smi_watcher bmc_events; | ||
112 | struct ipmi_user_hndl ipmi_hndlrs; | ||
113 | }; | ||
114 | |||
115 | static struct ibmpex_driver_data driver_data = { | ||
116 | .bmc_data = LIST_HEAD_INIT(driver_data.bmc_data), | ||
117 | .bmc_events = { | ||
118 | .owner = THIS_MODULE, | ||
119 | .new_smi = ibmpex_register_bmc, | ||
120 | .smi_gone = ibmpex_bmc_gone, | ||
121 | }, | ||
122 | .ipmi_hndlrs = { | ||
123 | .ipmi_recv_hndl = ibmpex_msg_handler, | ||
124 | }, | ||
125 | }; | ||
126 | |||
127 | static int ibmpex_send_message(struct ibmpex_bmc_data *data) | ||
128 | { | ||
129 | int err; | ||
130 | |||
131 | err = ipmi_validate_addr(&data->address, sizeof(data->address)); | ||
132 | if (err) | ||
133 | goto out; | ||
134 | |||
135 | data->tx_msgid++; | ||
136 | err = ipmi_request_settime(data->user, &data->address, data->tx_msgid, | ||
137 | &data->tx_message, data, 0, 0, 0); | ||
138 | if (err) | ||
139 | goto out1; | ||
140 | |||
141 | return 0; | ||
142 | out1: | ||
143 | printk(KERN_ERR "%s: request_settime=%x\n", __FUNCTION__, err); | ||
144 | return err; | ||
145 | out: | ||
146 | printk(KERN_ERR "%s: validate_addr=%x\n", __FUNCTION__, err); | ||
147 | return err; | ||
148 | } | ||
149 | |||
150 | static int ibmpex_ver_check(struct ibmpex_bmc_data *data) | ||
151 | { | ||
152 | data->tx_msg_data[0] = PEX_GET_VERSION; | ||
153 | data->tx_message.data_len = 1; | ||
154 | ibmpex_send_message(data); | ||
155 | |||
156 | wait_for_completion(&data->read_complete); | ||
157 | |||
158 | if (data->rx_result || data->rx_msg_len != 6) | ||
159 | return -ENOENT; | ||
160 | |||
161 | data->sensor_major = data->rx_msg_data[0]; | ||
162 | data->sensor_minor = data->rx_msg_data[1]; | ||
163 | |||
164 | printk(KERN_INFO DRVNAME ": Found BMC with sensor interface " | ||
165 | "v%d.%d %d-%02d-%02d on interface %d\n", | ||
166 | data->sensor_major, | ||
167 | data->sensor_minor, | ||
168 | extract_value(data->rx_msg_data, 2), | ||
169 | data->rx_msg_data[4], | ||
170 | data->rx_msg_data[5], | ||
171 | data->interface); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static int ibmpex_query_sensor_count(struct ibmpex_bmc_data *data) | ||
177 | { | ||
178 | data->tx_msg_data[0] = PEX_GET_SENSOR_COUNT; | ||
179 | data->tx_message.data_len = 1; | ||
180 | ibmpex_send_message(data); | ||
181 | |||
182 | wait_for_completion(&data->read_complete); | ||
183 | |||
184 | if (data->rx_result || data->rx_msg_len != 1) | ||
185 | return -ENOENT; | ||
186 | |||
187 | return data->rx_msg_data[0]; | ||
188 | } | ||
189 | |||
190 | static int ibmpex_query_sensor_name(struct ibmpex_bmc_data *data, int sensor) | ||
191 | { | ||
192 | data->tx_msg_data[0] = PEX_GET_SENSOR_NAME; | ||
193 | data->tx_msg_data[1] = sensor; | ||
194 | data->tx_message.data_len = 2; | ||
195 | ibmpex_send_message(data); | ||
196 | |||
197 | wait_for_completion(&data->read_complete); | ||
198 | |||
199 | if (data->rx_result || data->rx_msg_len < 1) | ||
200 | return -ENOENT; | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int ibmpex_query_sensor_data(struct ibmpex_bmc_data *data, int sensor) | ||
206 | { | ||
207 | data->tx_msg_data[0] = PEX_GET_SENSOR_DATA; | ||
208 | data->tx_msg_data[1] = sensor; | ||
209 | data->tx_message.data_len = 2; | ||
210 | ibmpex_send_message(data); | ||
211 | |||
212 | wait_for_completion(&data->read_complete); | ||
213 | |||
214 | if (data->rx_result || data->rx_msg_len < 26) { | ||
215 | printk(KERN_ERR "Error reading sensor %d, please check.\n", | ||
216 | sensor); | ||
217 | return -ENOENT; | ||
218 | } | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static int ibmpex_reset_high_low_data(struct ibmpex_bmc_data *data) | ||
224 | { | ||
225 | data->tx_msg_data[0] = PEX_RESET_HIGH_LOW; | ||
226 | data->tx_message.data_len = 1; | ||
227 | ibmpex_send_message(data); | ||
228 | |||
229 | wait_for_completion(&data->read_complete); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static void ibmpex_update_device(struct ibmpex_bmc_data *data) | ||
235 | { | ||
236 | int i, err; | ||
237 | |||
238 | mutex_lock(&data->lock); | ||
239 | if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) && | ||
240 | data->valid) | ||
241 | goto out; | ||
242 | |||
243 | for (i = 0; i < data->num_sensors; i++) { | ||
244 | if (!data->sensors[i].in_use) | ||
245 | continue; | ||
246 | err = ibmpex_query_sensor_data(data, i); | ||
247 | if (err) | ||
248 | continue; | ||
249 | data->sensors[i].values[0] = | ||
250 | extract_value(data->rx_msg_data, 16); | ||
251 | data->sensors[i].values[1] = | ||
252 | extract_value(data->rx_msg_data, 18); | ||
253 | data->sensors[i].values[2] = | ||
254 | extract_value(data->rx_msg_data, 20); | ||
255 | } | ||
256 | |||
257 | data->last_updated = jiffies; | ||
258 | data->valid = 1; | ||
259 | |||
260 | out: | ||
261 | mutex_unlock(&data->lock); | ||
262 | } | ||
263 | |||
264 | static struct ibmpex_bmc_data *get_bmc_data(int iface) | ||
265 | { | ||
266 | struct ibmpex_bmc_data *p, *next; | ||
267 | |||
268 | list_for_each_entry_safe(p, next, &driver_data.bmc_data, list) | ||
269 | if (p->interface == iface) | ||
270 | return p; | ||
271 | |||
272 | return NULL; | ||
273 | } | ||
274 | |||
275 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | ||
276 | char *buf) | ||
277 | { | ||
278 | return sprintf(buf, "%s\n", DRVNAME); | ||
279 | } | ||
280 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); | ||
281 | |||
282 | static ssize_t ibmpex_show_sensor(struct device *dev, | ||
283 | struct device_attribute *devattr, | ||
284 | char *buf) | ||
285 | { | ||
286 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
287 | struct ibmpex_bmc_data *data = dev_get_drvdata(dev); | ||
288 | int mult = data->sensors[attr->index].multiplier; | ||
289 | ibmpex_update_device(data); | ||
290 | |||
291 | return sprintf(buf, "%d\n", | ||
292 | data->sensors[attr->index].values[attr->nr] * mult); | ||
293 | } | ||
294 | |||
295 | static ssize_t ibmpex_reset_high_low(struct device *dev, | ||
296 | struct device_attribute *devattr, | ||
297 | const char *buf, | ||
298 | size_t count) | ||
299 | { | ||
300 | struct ibmpex_bmc_data *data = dev_get_drvdata(dev); | ||
301 | |||
302 | ibmpex_reset_high_low_data(data); | ||
303 | |||
304 | return count; | ||
305 | } | ||
306 | |||
307 | static SENSOR_DEVICE_ATTR(reset_high_low, S_IWUSR, NULL, | ||
308 | ibmpex_reset_high_low, 0); | ||
309 | |||
310 | static int is_power_sensor(const char *sensor_id, int len) | ||
311 | { | ||
312 | if (len < PEX_SENSOR_TYPE_LEN) | ||
313 | return 0; | ||
314 | |||
315 | if (!memcmp(sensor_id, power_sensor_sig, PEX_SENSOR_TYPE_LEN)) | ||
316 | return 1; | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int is_temp_sensor(const char *sensor_id, int len) | ||
321 | { | ||
322 | if (len < PEX_SENSOR_TYPE_LEN) | ||
323 | return 0; | ||
324 | |||
325 | if (!memcmp(sensor_id, temp_sensor_sig, PEX_SENSOR_TYPE_LEN)) | ||
326 | return 1; | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int power_sensor_multiplier(const char *sensor_id, int len) | ||
331 | { | ||
332 | int i; | ||
333 | |||
334 | for (i = PEX_SENSOR_TYPE_LEN; i < len - 1; i++) | ||
335 | if (!memcmp(&sensor_id[i], watt_sensor_sig, PEX_MULT_LEN)) | ||
336 | return 1000000; | ||
337 | |||
338 | return 100000; | ||
339 | } | ||
340 | |||
341 | static int create_sensor(struct ibmpex_bmc_data *data, int type, | ||
342 | int counter, int sensor, int func) | ||
343 | { | ||
344 | int err; | ||
345 | char *n; | ||
346 | |||
347 | n = kmalloc(32, GFP_KERNEL); | ||
348 | if (!n) | ||
349 | return -ENOMEM; | ||
350 | |||
351 | if (type == TEMP_SENSOR) | ||
352 | sprintf(n, temp_sensor_name_templates[func], "temp", counter); | ||
353 | else if (type == POWER_SENSOR) | ||
354 | sprintf(n, power_sensor_name_templates[func], "power", counter); | ||
355 | |||
356 | data->sensors[sensor].attr[func].dev_attr.attr.name = n; | ||
357 | data->sensors[sensor].attr[func].dev_attr.attr.mode = S_IRUGO; | ||
358 | data->sensors[sensor].attr[func].dev_attr.show = ibmpex_show_sensor; | ||
359 | data->sensors[sensor].attr[func].index = sensor; | ||
360 | data->sensors[sensor].attr[func].nr = func; | ||
361 | |||
362 | err = device_create_file(data->bmc_device, | ||
363 | &data->sensors[sensor].attr[func].dev_attr); | ||
364 | if (err) { | ||
365 | data->sensors[sensor].attr[func].dev_attr.attr.name = NULL; | ||
366 | kfree(n); | ||
367 | return err; | ||
368 | } | ||
369 | |||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static int ibmpex_find_sensors(struct ibmpex_bmc_data *data) | ||
374 | { | ||
375 | int i, j, err; | ||
376 | int sensor_type; | ||
377 | int sensor_counter; | ||
378 | int num_power = 0; | ||
379 | int num_temp = 0; | ||
380 | |||
381 | err = ibmpex_query_sensor_count(data); | ||
382 | if (err <= 0) | ||
383 | return -ENOENT; | ||
384 | data->num_sensors = err; | ||
385 | |||
386 | data->sensors = kzalloc(data->num_sensors * sizeof(*data->sensors), | ||
387 | GFP_KERNEL); | ||
388 | if (!data->sensors) | ||
389 | return -ENOMEM; | ||
390 | |||
391 | for (i = 0; i < data->num_sensors; i++) { | ||
392 | err = ibmpex_query_sensor_name(data, i); | ||
393 | if (err) | ||
394 | continue; | ||
395 | |||
396 | if (is_power_sensor(data->rx_msg_data, data->rx_msg_len)) { | ||
397 | sensor_type = POWER_SENSOR; | ||
398 | num_power++; | ||
399 | sensor_counter = num_power; | ||
400 | data->sensors[i].multiplier = | ||
401 | power_sensor_multiplier(data->rx_msg_data, | ||
402 | data->rx_msg_len); | ||
403 | } else if (is_temp_sensor(data->rx_msg_data, | ||
404 | data->rx_msg_len)) { | ||
405 | sensor_type = TEMP_SENSOR; | ||
406 | num_temp++; | ||
407 | sensor_counter = num_temp; | ||
408 | data->sensors[i].multiplier = 1; | ||
409 | } else | ||
410 | continue; | ||
411 | |||
412 | data->sensors[i].in_use = 1; | ||
413 | |||
414 | /* Create attributes */ | ||
415 | for (j = 0; j < PEX_NUM_SENSOR_FUNCS; j++) { | ||
416 | err = create_sensor(data, sensor_type, sensor_counter, | ||
417 | i, j); | ||
418 | if (err) | ||
419 | goto exit_remove; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | err = device_create_file(data->bmc_device, | ||
424 | &sensor_dev_attr_reset_high_low.dev_attr); | ||
425 | if (err) | ||
426 | goto exit_remove; | ||
427 | |||
428 | err = device_create_file(data->bmc_device, | ||
429 | &sensor_dev_attr_name.dev_attr); | ||
430 | if (err) | ||
431 | goto exit_remove; | ||
432 | |||
433 | return 0; | ||
434 | |||
435 | exit_remove: | ||
436 | device_remove_file(data->bmc_device, | ||
437 | &sensor_dev_attr_reset_high_low.dev_attr); | ||
438 | device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); | ||
439 | for (i = 0; i < data->num_sensors; i++) | ||
440 | for (j = 0; j < PEX_NUM_SENSOR_FUNCS; j++) { | ||
441 | if (!data->sensors[i].attr[j].dev_attr.attr.name) | ||
442 | continue; | ||
443 | device_remove_file(data->bmc_device, | ||
444 | &data->sensors[i].attr[j].dev_attr); | ||
445 | kfree(data->sensors[i].attr[j].dev_attr.attr.name); | ||
446 | } | ||
447 | |||
448 | kfree(data->sensors); | ||
449 | return err; | ||
450 | } | ||
451 | |||
452 | static void ibmpex_register_bmc(int iface, struct device *dev) | ||
453 | { | ||
454 | struct ibmpex_bmc_data *data; | ||
455 | int err; | ||
456 | |||
457 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
458 | if (!data) { | ||
459 | printk(KERN_ERR DRVNAME ": Insufficient memory for BMC " | ||
460 | "interface %d.\n", data->interface); | ||
461 | return; | ||
462 | } | ||
463 | |||
464 | data->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
465 | data->address.channel = IPMI_BMC_CHANNEL; | ||
466 | data->address.data[0] = 0; | ||
467 | data->interface = iface; | ||
468 | data->bmc_device = dev; | ||
469 | |||
470 | /* Create IPMI messaging interface user */ | ||
471 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, | ||
472 | data, &data->user); | ||
473 | if (err < 0) { | ||
474 | printk(KERN_ERR DRVNAME ": Error, unable to register user with " | ||
475 | "ipmi interface %d\n", | ||
476 | data->interface); | ||
477 | goto out; | ||
478 | } | ||
479 | |||
480 | mutex_init(&data->lock); | ||
481 | |||
482 | /* Initialize message */ | ||
483 | data->tx_msgid = 0; | ||
484 | init_completion(&data->read_complete); | ||
485 | data->tx_message.netfn = PEX_NET_FUNCTION; | ||
486 | data->tx_message.cmd = PEX_COMMAND; | ||
487 | data->tx_message.data = data->tx_msg_data; | ||
488 | |||
489 | /* Does this BMC support PowerExecutive? */ | ||
490 | err = ibmpex_ver_check(data); | ||
491 | if (err) | ||
492 | goto out_user; | ||
493 | |||
494 | /* Register the BMC as a HWMON class device */ | ||
495 | data->hwmon_dev = hwmon_device_register(data->bmc_device); | ||
496 | |||
497 | if (IS_ERR(data->hwmon_dev)) { | ||
498 | printk(KERN_ERR DRVNAME ": Error, unable to register hwmon " | ||
499 | "class device for interface %d\n", | ||
500 | data->interface); | ||
501 | kfree(data); | ||
502 | return; | ||
503 | } | ||
504 | |||
505 | /* finally add the new bmc data to the bmc data list */ | ||
506 | dev_set_drvdata(dev, data); | ||
507 | list_add_tail(&data->list, &driver_data.bmc_data); | ||
508 | |||
509 | /* Now go find all the sensors */ | ||
510 | err = ibmpex_find_sensors(data); | ||
511 | if (err) { | ||
512 | printk(KERN_ERR "Error %d allocating memory\n", err); | ||
513 | goto out_register; | ||
514 | } | ||
515 | |||
516 | return; | ||
517 | |||
518 | out_register: | ||
519 | hwmon_device_unregister(data->hwmon_dev); | ||
520 | out_user: | ||
521 | ipmi_destroy_user(data->user); | ||
522 | out: | ||
523 | kfree(data); | ||
524 | } | ||
525 | |||
526 | static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) | ||
527 | { | ||
528 | int i, j; | ||
529 | |||
530 | device_remove_file(data->bmc_device, | ||
531 | &sensor_dev_attr_reset_high_low.dev_attr); | ||
532 | device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); | ||
533 | for (i = 0; i < data->num_sensors; i++) | ||
534 | for (j = 0; j < PEX_NUM_SENSOR_FUNCS; j++) { | ||
535 | if (!data->sensors[i].attr[j].dev_attr.attr.name) | ||
536 | continue; | ||
537 | device_remove_file(data->bmc_device, | ||
538 | &data->sensors[i].attr[j].dev_attr); | ||
539 | kfree(data->sensors[i].attr[j].dev_attr.attr.name); | ||
540 | } | ||
541 | |||
542 | list_del(&data->list); | ||
543 | dev_set_drvdata(data->bmc_device, NULL); | ||
544 | hwmon_device_unregister(data->hwmon_dev); | ||
545 | ipmi_destroy_user(data->user); | ||
546 | kfree(data->sensors); | ||
547 | kfree(data); | ||
548 | } | ||
549 | |||
550 | static void ibmpex_bmc_gone(int iface) | ||
551 | { | ||
552 | struct ibmpex_bmc_data *data = get_bmc_data(iface); | ||
553 | |||
554 | if (!data) | ||
555 | return; | ||
556 | |||
557 | ibmpex_bmc_delete(data); | ||
558 | } | ||
559 | |||
560 | static void ibmpex_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | ||
561 | { | ||
562 | struct ibmpex_bmc_data *data = (struct ibmpex_bmc_data *)user_msg_data; | ||
563 | |||
564 | if (msg->msgid != data->tx_msgid) { | ||
565 | printk(KERN_ERR "Received msgid (%02x) and transmitted " | ||
566 | "msgid (%02x) mismatch!\n", | ||
567 | (int)msg->msgid, | ||
568 | (int)data->tx_msgid); | ||
569 | ipmi_free_recv_msg(msg); | ||
570 | return; | ||
571 | } | ||
572 | |||
573 | data->rx_recv_type = msg->recv_type; | ||
574 | if (msg->msg.data_len > 0) | ||
575 | data->rx_result = msg->msg.data[0]; | ||
576 | else | ||
577 | data->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; | ||
578 | |||
579 | if (msg->msg.data_len > 1) { | ||
580 | data->rx_msg_len = msg->msg.data_len - 1; | ||
581 | memcpy(data->rx_msg_data, msg->msg.data + 1, data->rx_msg_len); | ||
582 | } else | ||
583 | data->rx_msg_len = 0; | ||
584 | |||
585 | ipmi_free_recv_msg(msg); | ||
586 | complete(&data->read_complete); | ||
587 | } | ||
588 | |||
589 | static int __init ibmpex_init(void) | ||
590 | { | ||
591 | return ipmi_smi_watcher_register(&driver_data.bmc_events); | ||
592 | } | ||
593 | |||
594 | static void __exit ibmpex_exit(void) | ||
595 | { | ||
596 | struct ibmpex_bmc_data *p, *next; | ||
597 | |||
598 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); | ||
599 | list_for_each_entry_safe(p, next, &driver_data.bmc_data, list) | ||
600 | ibmpex_bmc_delete(p); | ||
601 | } | ||
602 | |||
603 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
604 | MODULE_DESCRIPTION("IBM PowerExecutive power/temperature sensor driver"); | ||
605 | MODULE_LICENSE("GPL"); | ||
606 | |||
607 | module_init(ibmpex_init); | ||
608 | module_exit(ibmpex_exit); | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index d75dba9b810b..6a182e14cf58 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -141,10 +141,10 @@ static int fix_pwm_polarity; | |||
141 | 141 | ||
142 | /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ | 142 | /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ |
143 | 143 | ||
144 | #define IT87_REG_FAN(nr) (0x0d + (nr)) | 144 | static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82 }; |
145 | #define IT87_REG_FAN_MIN(nr) (0x10 + (nr)) | 145 | static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86 }; |
146 | #define IT87_REG_FANX(nr) (0x18 + (nr)) | 146 | static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83 }; |
147 | #define IT87_REG_FANX_MIN(nr) (0x1b + (nr)) | 147 | static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; |
148 | #define IT87_REG_FAN_MAIN_CTRL 0x13 | 148 | #define IT87_REG_FAN_MAIN_CTRL 0x13 |
149 | #define IT87_REG_FAN_CTL 0x14 | 149 | #define IT87_REG_FAN_CTL 0x14 |
150 | #define IT87_REG_PWM(nr) (0x15 + (nr)) | 150 | #define IT87_REG_PWM(nr) (0x15 + (nr)) |
@@ -222,7 +222,7 @@ struct it87_sio_data { | |||
222 | /* For each registered chip, we need to keep some data in memory. | 222 | /* For each registered chip, we need to keep some data in memory. |
223 | The structure is dynamically allocated. */ | 223 | The structure is dynamically allocated. */ |
224 | struct it87_data { | 224 | struct it87_data { |
225 | struct class_device *class_dev; | 225 | struct device *hwmon_dev; |
226 | enum chips type; | 226 | enum chips type; |
227 | 227 | ||
228 | unsigned short addr; | 228 | unsigned short addr; |
@@ -235,8 +235,8 @@ struct it87_data { | |||
235 | u8 in_max[8]; /* Register value */ | 235 | u8 in_max[8]; /* Register value */ |
236 | u8 in_min[8]; /* Register value */ | 236 | u8 in_min[8]; /* Register value */ |
237 | u8 has_fan; /* Bitfield, fans enabled */ | 237 | u8 has_fan; /* Bitfield, fans enabled */ |
238 | u16 fan[3]; /* Register values, possibly combined */ | 238 | u16 fan[5]; /* Register values, possibly combined */ |
239 | u16 fan_min[3]; /* Register values, possibly combined */ | 239 | u16 fan_min[5]; /* Register values, possibly combined */ |
240 | u8 temp[3]; /* Register value */ | 240 | u8 temp[3]; /* Register value */ |
241 | u8 temp_high[3]; /* Register value */ | 241 | u8 temp_high[3]; /* Register value */ |
242 | u8 temp_low[3]; /* Register value */ | 242 | u8 temp_low[3]; /* Register value */ |
@@ -555,7 +555,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
555 | } | 555 | } |
556 | 556 | ||
557 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 557 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
558 | it87_write_value(data, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); | 558 | it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan_min[nr]); |
559 | mutex_unlock(&data->update_lock); | 559 | mutex_unlock(&data->update_lock); |
560 | return count; | 560 | return count; |
561 | } | 561 | } |
@@ -596,7 +596,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
596 | 596 | ||
597 | /* Restore fan min limit */ | 597 | /* Restore fan min limit */ |
598 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 598 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
599 | it87_write_value(data, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); | 599 | it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan_min[nr]); |
600 | 600 | ||
601 | mutex_unlock(&data->update_lock); | 601 | mutex_unlock(&data->update_lock); |
602 | return count; | 602 | return count; |
@@ -729,9 +729,9 @@ static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr, | |||
729 | 729 | ||
730 | mutex_lock(&data->update_lock); | 730 | mutex_lock(&data->update_lock); |
731 | data->fan_min[nr] = FAN16_TO_REG(val); | 731 | data->fan_min[nr] = FAN16_TO_REG(val); |
732 | it87_write_value(data, IT87_REG_FAN_MIN(nr), | 732 | it87_write_value(data, IT87_REG_FAN_MIN[nr], |
733 | data->fan_min[nr] & 0xff); | 733 | data->fan_min[nr] & 0xff); |
734 | it87_write_value(data, IT87_REG_FANX_MIN(nr), | 734 | it87_write_value(data, IT87_REG_FANX_MIN[nr], |
735 | data->fan_min[nr] >> 8); | 735 | data->fan_min[nr] >> 8); |
736 | mutex_unlock(&data->update_lock); | 736 | mutex_unlock(&data->update_lock); |
737 | return count; | 737 | return count; |
@@ -751,6 +751,8 @@ static struct sensor_device_attribute sensor_dev_attr_fan##offset##_min16 \ | |||
751 | show_fan16_offset(1); | 751 | show_fan16_offset(1); |
752 | show_fan16_offset(2); | 752 | show_fan16_offset(2); |
753 | show_fan16_offset(3); | 753 | show_fan16_offset(3); |
754 | show_fan16_offset(4); | ||
755 | show_fan16_offset(5); | ||
754 | 756 | ||
755 | /* Alarms */ | 757 | /* Alarms */ |
756 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) | 758 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -763,7 +765,7 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | |||
763 | static ssize_t | 765 | static ssize_t |
764 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 766 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
765 | { | 767 | { |
766 | struct it87_data *data = it87_update_device(dev); | 768 | struct it87_data *data = dev_get_drvdata(dev); |
767 | return sprintf(buf, "%u\n", data->vrm); | 769 | return sprintf(buf, "%u\n", data->vrm); |
768 | } | 770 | } |
769 | static ssize_t | 771 | static ssize_t |
@@ -851,6 +853,10 @@ static struct attribute *it87_attributes_opt[] = { | |||
851 | &sensor_dev_attr_fan2_min16.dev_attr.attr, | 853 | &sensor_dev_attr_fan2_min16.dev_attr.attr, |
852 | &sensor_dev_attr_fan3_input16.dev_attr.attr, | 854 | &sensor_dev_attr_fan3_input16.dev_attr.attr, |
853 | &sensor_dev_attr_fan3_min16.dev_attr.attr, | 855 | &sensor_dev_attr_fan3_min16.dev_attr.attr, |
856 | &sensor_dev_attr_fan4_input16.dev_attr.attr, | ||
857 | &sensor_dev_attr_fan4_min16.dev_attr.attr, | ||
858 | &sensor_dev_attr_fan5_input16.dev_attr.attr, | ||
859 | &sensor_dev_attr_fan5_min16.dev_attr.attr, | ||
854 | 860 | ||
855 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 861 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
856 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 862 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
@@ -1024,6 +1030,20 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1024 | &sensor_dev_attr_fan3_min16.dev_attr))) | 1030 | &sensor_dev_attr_fan3_min16.dev_attr))) |
1025 | goto ERROR4; | 1031 | goto ERROR4; |
1026 | } | 1032 | } |
1033 | if (data->has_fan & (1 << 3)) { | ||
1034 | if ((err = device_create_file(dev, | ||
1035 | &sensor_dev_attr_fan4_input16.dev_attr)) | ||
1036 | || (err = device_create_file(dev, | ||
1037 | &sensor_dev_attr_fan4_min16.dev_attr))) | ||
1038 | goto ERROR4; | ||
1039 | } | ||
1040 | if (data->has_fan & (1 << 4)) { | ||
1041 | if ((err = device_create_file(dev, | ||
1042 | &sensor_dev_attr_fan5_input16.dev_attr)) | ||
1043 | || (err = device_create_file(dev, | ||
1044 | &sensor_dev_attr_fan5_min16.dev_attr))) | ||
1045 | goto ERROR4; | ||
1046 | } | ||
1027 | } else { | 1047 | } else { |
1028 | /* 8-bit tachometers with clock divider */ | 1048 | /* 8-bit tachometers with clock divider */ |
1029 | if (data->has_fan & (1 << 0)) { | 1049 | if (data->has_fan & (1 << 0)) { |
@@ -1089,9 +1109,9 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1089 | goto ERROR4; | 1109 | goto ERROR4; |
1090 | } | 1110 | } |
1091 | 1111 | ||
1092 | data->class_dev = hwmon_device_register(dev); | 1112 | data->hwmon_dev = hwmon_device_register(dev); |
1093 | if (IS_ERR(data->class_dev)) { | 1113 | if (IS_ERR(data->hwmon_dev)) { |
1094 | err = PTR_ERR(data->class_dev); | 1114 | err = PTR_ERR(data->hwmon_dev); |
1095 | goto ERROR4; | 1115 | goto ERROR4; |
1096 | } | 1116 | } |
1097 | 1117 | ||
@@ -1113,7 +1133,7 @@ static int __devexit it87_remove(struct platform_device *pdev) | |||
1113 | { | 1133 | { |
1114 | struct it87_data *data = platform_get_drvdata(pdev); | 1134 | struct it87_data *data = platform_get_drvdata(pdev); |
1115 | 1135 | ||
1116 | hwmon_device_unregister(data->class_dev); | 1136 | hwmon_device_unregister(data->hwmon_dev); |
1117 | sysfs_remove_group(&pdev->dev.kobj, &it87_group); | 1137 | sysfs_remove_group(&pdev->dev.kobj, &it87_group); |
1118 | sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt); | 1138 | sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt); |
1119 | 1139 | ||
@@ -1260,6 +1280,10 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
1260 | it87_write_value(data, IT87_REG_FAN_16BIT, | 1280 | it87_write_value(data, IT87_REG_FAN_16BIT, |
1261 | tmp | 0x07); | 1281 | tmp | 0x07); |
1262 | } | 1282 | } |
1283 | if (tmp & (1 << 4)) | ||
1284 | data->has_fan |= (1 << 3); /* fan4 enabled */ | ||
1285 | if (tmp & (1 << 5)) | ||
1286 | data->has_fan |= (1 << 4); /* fan5 enabled */ | ||
1263 | } | 1287 | } |
1264 | 1288 | ||
1265 | /* Set current fan mode registers and the default settings for the | 1289 | /* Set current fan mode registers and the default settings for the |
@@ -1314,21 +1338,21 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1314 | data->in[8] = | 1338 | data->in[8] = |
1315 | it87_read_value(data, IT87_REG_VIN(8)); | 1339 | it87_read_value(data, IT87_REG_VIN(8)); |
1316 | 1340 | ||
1317 | for (i = 0; i < 3; i++) { | 1341 | for (i = 0; i < 5; i++) { |
1318 | /* Skip disabled fans */ | 1342 | /* Skip disabled fans */ |
1319 | if (!(data->has_fan & (1 << i))) | 1343 | if (!(data->has_fan & (1 << i))) |
1320 | continue; | 1344 | continue; |
1321 | 1345 | ||
1322 | data->fan_min[i] = | 1346 | data->fan_min[i] = |
1323 | it87_read_value(data, IT87_REG_FAN_MIN(i)); | 1347 | it87_read_value(data, IT87_REG_FAN_MIN[i]); |
1324 | data->fan[i] = it87_read_value(data, | 1348 | data->fan[i] = it87_read_value(data, |
1325 | IT87_REG_FAN(i)); | 1349 | IT87_REG_FAN[i]); |
1326 | /* Add high byte if in 16-bit mode */ | 1350 | /* Add high byte if in 16-bit mode */ |
1327 | if (data->type == it8716 || data->type == it8718) { | 1351 | if (data->type == it8716 || data->type == it8718) { |
1328 | data->fan[i] |= it87_read_value(data, | 1352 | data->fan[i] |= it87_read_value(data, |
1329 | IT87_REG_FANX(i)) << 8; | 1353 | IT87_REG_FANX[i]) << 8; |
1330 | data->fan_min[i] |= it87_read_value(data, | 1354 | data->fan_min[i] |= it87_read_value(data, |
1331 | IT87_REG_FANX_MIN(i)) << 8; | 1355 | IT87_REG_FANX_MIN[i]) << 8; |
1332 | } | 1356 | } |
1333 | } | 1357 | } |
1334 | for (i = 0; i < 3; i++) { | 1358 | for (i = 0; i < 3; i++) { |
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 5d8d0ca08fa9..bd2bde0ef95e 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #define SEL_CORE 0x04 | 38 | #define SEL_CORE 0x04 |
39 | 39 | ||
40 | struct k8temp_data { | 40 | struct k8temp_data { |
41 | struct class_device *class_dev; | 41 | struct device *hwmon_dev; |
42 | struct mutex update_lock; | 42 | struct mutex update_lock; |
43 | const char *name; | 43 | const char *name; |
44 | char valid; /* zero until following fields are valid */ | 44 | char valid; /* zero until following fields are valid */ |
@@ -225,10 +225,10 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, | |||
225 | if (err) | 225 | if (err) |
226 | goto exit_remove; | 226 | goto exit_remove; |
227 | 227 | ||
228 | data->class_dev = hwmon_device_register(&pdev->dev); | 228 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
229 | 229 | ||
230 | if (IS_ERR(data->class_dev)) { | 230 | if (IS_ERR(data->hwmon_dev)) { |
231 | err = PTR_ERR(data->class_dev); | 231 | err = PTR_ERR(data->hwmon_dev); |
232 | goto exit_remove; | 232 | goto exit_remove; |
233 | } | 233 | } |
234 | 234 | ||
@@ -255,7 +255,7 @@ static void __devexit k8temp_remove(struct pci_dev *pdev) | |||
255 | { | 255 | { |
256 | struct k8temp_data *data = dev_get_drvdata(&pdev->dev); | 256 | struct k8temp_data *data = dev_get_drvdata(&pdev->dev); |
257 | 257 | ||
258 | hwmon_device_unregister(data->class_dev); | 258 | hwmon_device_unregister(data->hwmon_dev); |
259 | device_remove_file(&pdev->dev, | 259 | device_remove_file(&pdev->dev, |
260 | &sensor_dev_attr_temp1_input.dev_attr); | 260 | &sensor_dev_attr_temp1_input.dev_attr); |
261 | device_remove_file(&pdev->dev, | 261 | device_remove_file(&pdev->dev, |
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 2162d69a8c06..f207434730de 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
@@ -154,7 +154,7 @@ static struct i2c_driver lm63_driver = { | |||
154 | 154 | ||
155 | struct lm63_data { | 155 | struct lm63_data { |
156 | struct i2c_client client; | 156 | struct i2c_client client; |
157 | struct class_device *class_dev; | 157 | struct device *hwmon_dev; |
158 | struct mutex update_lock; | 158 | struct mutex update_lock; |
159 | char valid; /* zero until following fields are valid */ | 159 | char valid; /* zero until following fields are valid */ |
160 | unsigned long last_updated; /* in jiffies */ | 160 | unsigned long last_updated; /* in jiffies */ |
@@ -502,9 +502,9 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) | |||
502 | goto exit_remove_files; | 502 | goto exit_remove_files; |
503 | } | 503 | } |
504 | 504 | ||
505 | data->class_dev = hwmon_device_register(&new_client->dev); | 505 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
506 | if (IS_ERR(data->class_dev)) { | 506 | if (IS_ERR(data->hwmon_dev)) { |
507 | err = PTR_ERR(data->class_dev); | 507 | err = PTR_ERR(data->hwmon_dev); |
508 | goto exit_remove_files; | 508 | goto exit_remove_files; |
509 | } | 509 | } |
510 | 510 | ||
@@ -561,7 +561,7 @@ static int lm63_detach_client(struct i2c_client *client) | |||
561 | struct lm63_data *data = i2c_get_clientdata(client); | 561 | struct lm63_data *data = i2c_get_clientdata(client); |
562 | int err; | 562 | int err; |
563 | 563 | ||
564 | hwmon_device_unregister(data->class_dev); | 564 | hwmon_device_unregister(data->hwmon_dev); |
565 | sysfs_remove_group(&client->dev.kobj, &lm63_group); | 565 | sysfs_remove_group(&client->dev.kobj, &lm63_group); |
566 | sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); | 566 | sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); |
567 | 567 | ||
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index 275d392eca61..dd366889ce9b 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #define DRVNAME "lm70" | 37 | #define DRVNAME "lm70" |
38 | 38 | ||
39 | struct lm70 { | 39 | struct lm70 { |
40 | struct class_device *cdev; | 40 | struct device *hwmon_dev; |
41 | struct semaphore sem; | 41 | struct semaphore sem; |
42 | }; | 42 | }; |
43 | 43 | ||
@@ -81,7 +81,7 @@ static ssize_t lm70_sense_temp(struct device *dev, | |||
81 | * So it's equivalent to multiplying by 0.25 * 1000 = 250. | 81 | * So it's equivalent to multiplying by 0.25 * 1000 = 250. |
82 | */ | 82 | */ |
83 | val = ((int)raw/32) * 250; | 83 | val = ((int)raw/32) * 250; |
84 | status = sprintf(buf, "%+d\n", val); /* millidegrees Celsius */ | 84 | status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */ |
85 | out: | 85 | out: |
86 | up(&p_lm70->sem); | 86 | up(&p_lm70->sem); |
87 | return status; | 87 | return status; |
@@ -89,6 +89,14 @@ out: | |||
89 | 89 | ||
90 | static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL); | 90 | static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL); |
91 | 91 | ||
92 | static ssize_t lm70_show_name(struct device *dev, struct device_attribute | ||
93 | *devattr, char *buf) | ||
94 | { | ||
95 | return sprintf(buf, "lm70\n"); | ||
96 | } | ||
97 | |||
98 | static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL); | ||
99 | |||
92 | /*----------------------------------------------------------------------*/ | 100 | /*----------------------------------------------------------------------*/ |
93 | 101 | ||
94 | static int __devinit lm70_probe(struct spi_device *spi) | 102 | static int __devinit lm70_probe(struct spi_device *spi) |
@@ -107,15 +115,16 @@ static int __devinit lm70_probe(struct spi_device *spi) | |||
107 | init_MUTEX(&p_lm70->sem); | 115 | init_MUTEX(&p_lm70->sem); |
108 | 116 | ||
109 | /* sysfs hook */ | 117 | /* sysfs hook */ |
110 | p_lm70->cdev = hwmon_device_register(&spi->dev); | 118 | p_lm70->hwmon_dev = hwmon_device_register(&spi->dev); |
111 | if (IS_ERR(p_lm70->cdev)) { | 119 | if (IS_ERR(p_lm70->hwmon_dev)) { |
112 | dev_dbg(&spi->dev, "hwmon_device_register failed.\n"); | 120 | dev_dbg(&spi->dev, "hwmon_device_register failed.\n"); |
113 | status = PTR_ERR(p_lm70->cdev); | 121 | status = PTR_ERR(p_lm70->hwmon_dev); |
114 | goto out_dev_reg_failed; | 122 | goto out_dev_reg_failed; |
115 | } | 123 | } |
116 | dev_set_drvdata(&spi->dev, p_lm70); | 124 | dev_set_drvdata(&spi->dev, p_lm70); |
117 | 125 | ||
118 | if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input))) { | 126 | if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input)) |
127 | || (status = device_create_file(&spi->dev, &dev_attr_name))) { | ||
119 | dev_dbg(&spi->dev, "device_create_file failure.\n"); | 128 | dev_dbg(&spi->dev, "device_create_file failure.\n"); |
120 | goto out_dev_create_file_failed; | 129 | goto out_dev_create_file_failed; |
121 | } | 130 | } |
@@ -123,7 +132,8 @@ static int __devinit lm70_probe(struct spi_device *spi) | |||
123 | return 0; | 132 | return 0; |
124 | 133 | ||
125 | out_dev_create_file_failed: | 134 | out_dev_create_file_failed: |
126 | hwmon_device_unregister(p_lm70->cdev); | 135 | device_remove_file(&spi->dev, &dev_attr_temp1_input); |
136 | hwmon_device_unregister(p_lm70->hwmon_dev); | ||
127 | out_dev_reg_failed: | 137 | out_dev_reg_failed: |
128 | dev_set_drvdata(&spi->dev, NULL); | 138 | dev_set_drvdata(&spi->dev, NULL); |
129 | kfree(p_lm70); | 139 | kfree(p_lm70); |
@@ -135,7 +145,8 @@ static int __devexit lm70_remove(struct spi_device *spi) | |||
135 | struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); | 145 | struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); |
136 | 146 | ||
137 | device_remove_file(&spi->dev, &dev_attr_temp1_input); | 147 | device_remove_file(&spi->dev, &dev_attr_temp1_input); |
138 | hwmon_device_unregister(p_lm70->cdev); | 148 | device_remove_file(&spi->dev, &dev_attr_name); |
149 | hwmon_device_unregister(p_lm70->hwmon_dev); | ||
139 | dev_set_drvdata(&spi->dev, NULL); | 150 | dev_set_drvdata(&spi->dev, NULL); |
140 | kfree(p_lm70); | 151 | kfree(p_lm70); |
141 | 152 | ||
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index a40166ffad12..37a8cc032ffa 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -50,7 +50,7 @@ static const u8 LM75_REG_TEMP[3] = { | |||
50 | /* Each client has this additional data */ | 50 | /* Each client has this additional data */ |
51 | struct lm75_data { | 51 | struct lm75_data { |
52 | struct i2c_client client; | 52 | struct i2c_client client; |
53 | struct class_device *class_dev; | 53 | struct device *hwmon_dev; |
54 | struct mutex update_lock; | 54 | struct mutex update_lock; |
55 | char valid; /* !=0 if following fields are valid */ | 55 | char valid; /* !=0 if following fields are valid */ |
56 | unsigned long last_updated; /* In jiffies */ | 56 | unsigned long last_updated; /* In jiffies */ |
@@ -95,7 +95,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, | |||
95 | struct i2c_client *client = to_i2c_client(dev); | 95 | struct i2c_client *client = to_i2c_client(dev); |
96 | struct lm75_data *data = i2c_get_clientdata(client); | 96 | struct lm75_data *data = i2c_get_clientdata(client); |
97 | int nr = attr->index; | 97 | int nr = attr->index; |
98 | unsigned long temp = simple_strtoul(buf, NULL, 10); | 98 | long temp = simple_strtol(buf, NULL, 10); |
99 | 99 | ||
100 | mutex_lock(&data->update_lock); | 100 | mutex_lock(&data->update_lock); |
101 | data->temp[nr] = LM75_TEMP_TO_REG(temp); | 101 | data->temp[nr] = LM75_TEMP_TO_REG(temp); |
@@ -219,9 +219,9 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) | |||
219 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group))) | 219 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group))) |
220 | goto exit_detach; | 220 | goto exit_detach; |
221 | 221 | ||
222 | data->class_dev = hwmon_device_register(&new_client->dev); | 222 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
223 | if (IS_ERR(data->class_dev)) { | 223 | if (IS_ERR(data->hwmon_dev)) { |
224 | err = PTR_ERR(data->class_dev); | 224 | err = PTR_ERR(data->hwmon_dev); |
225 | goto exit_remove; | 225 | goto exit_remove; |
226 | } | 226 | } |
227 | 227 | ||
@@ -240,7 +240,7 @@ exit: | |||
240 | static int lm75_detach_client(struct i2c_client *client) | 240 | static int lm75_detach_client(struct i2c_client *client) |
241 | { | 241 | { |
242 | struct lm75_data *data = i2c_get_clientdata(client); | 242 | struct lm75_data *data = i2c_get_clientdata(client); |
243 | hwmon_device_unregister(data->class_dev); | 243 | hwmon_device_unregister(data->hwmon_dev); |
244 | sysfs_remove_group(&client->dev.kobj, &lm75_group); | 244 | sysfs_remove_group(&client->dev.kobj, &lm75_group); |
245 | i2c_detach_client(client); | 245 | i2c_detach_client(client); |
246 | kfree(data); | 246 | kfree(data); |
diff --git a/drivers/hwmon/lm75.h b/drivers/hwmon/lm75.h index af7dc650ee15..7c93454bb4e3 100644 --- a/drivers/hwmon/lm75.h +++ b/drivers/hwmon/lm75.h | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | /* TEMP: 0.001C/bit (-55C to +125C) | 34 | /* TEMP: 0.001C/bit (-55C to +125C) |
35 | REG: (0.5C/bit, two's complement) << 7 */ | 35 | REG: (0.5C/bit, two's complement) << 7 */ |
36 | static inline u16 LM75_TEMP_TO_REG(int temp) | 36 | static inline u16 LM75_TEMP_TO_REG(long temp) |
37 | { | 37 | { |
38 | int ntemp = SENSORS_LIMIT(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); | 38 | int ntemp = SENSORS_LIMIT(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); |
39 | ntemp += (ntemp<0 ? -250 : 250); | 39 | ntemp += (ntemp<0 ? -250 : 250); |
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index dd969f1e8415..cee5c2e8cfad 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c | |||
@@ -51,7 +51,7 @@ I2C_CLIENT_INSMOD_1(lm77); | |||
51 | /* Each client has this additional data */ | 51 | /* Each client has this additional data */ |
52 | struct lm77_data { | 52 | struct lm77_data { |
53 | struct i2c_client client; | 53 | struct i2c_client client; |
54 | struct class_device *class_dev; | 54 | struct device *hwmon_dev; |
55 | struct mutex update_lock; | 55 | struct mutex update_lock; |
56 | char valid; | 56 | char valid; |
57 | unsigned long last_updated; /* In jiffies */ | 57 | unsigned long last_updated; /* In jiffies */ |
@@ -138,7 +138,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co | |||
138 | { \ | 138 | { \ |
139 | struct i2c_client *client = to_i2c_client(dev); \ | 139 | struct i2c_client *client = to_i2c_client(dev); \ |
140 | struct lm77_data *data = i2c_get_clientdata(client); \ | 140 | struct lm77_data *data = i2c_get_clientdata(client); \ |
141 | long val = simple_strtoul(buf, NULL, 10); \ | 141 | long val = simple_strtol(buf, NULL, 10); \ |
142 | \ | 142 | \ |
143 | mutex_lock(&data->update_lock); \ | 143 | mutex_lock(&data->update_lock); \ |
144 | data->value = val; \ | 144 | data->value = val; \ |
@@ -337,9 +337,9 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) | |||
337 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group))) | 337 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group))) |
338 | goto exit_detach; | 338 | goto exit_detach; |
339 | 339 | ||
340 | data->class_dev = hwmon_device_register(&new_client->dev); | 340 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
341 | if (IS_ERR(data->class_dev)) { | 341 | if (IS_ERR(data->hwmon_dev)) { |
342 | err = PTR_ERR(data->class_dev); | 342 | err = PTR_ERR(data->hwmon_dev); |
343 | goto exit_remove; | 343 | goto exit_remove; |
344 | } | 344 | } |
345 | 345 | ||
@@ -358,7 +358,7 @@ exit: | |||
358 | static int lm77_detach_client(struct i2c_client *client) | 358 | static int lm77_detach_client(struct i2c_client *client) |
359 | { | 359 | { |
360 | struct lm77_data *data = i2c_get_clientdata(client); | 360 | struct lm77_data *data = i2c_get_clientdata(client); |
361 | hwmon_device_unregister(data->class_dev); | 361 | hwmon_device_unregister(data->hwmon_dev); |
362 | sysfs_remove_group(&client->dev.kobj, &lm77_group); | 362 | sysfs_remove_group(&client->dev.kobj, &lm77_group); |
363 | i2c_detach_client(client); | 363 | i2c_detach_client(client); |
364 | kfree(data); | 364 | kfree(data); |
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 6eea3476b90c..3f7055ee679f 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
@@ -131,7 +131,7 @@ static inline int TEMP_FROM_REG(s8 val) | |||
131 | the driver field to differentiate between I2C and ISA chips. */ | 131 | the driver field to differentiate between I2C and ISA chips. */ |
132 | struct lm78_data { | 132 | struct lm78_data { |
133 | struct i2c_client client; | 133 | struct i2c_client client; |
134 | struct class_device *class_dev; | 134 | struct device *hwmon_dev; |
135 | struct mutex lock; | 135 | struct mutex lock; |
136 | enum chips type; | 136 | enum chips type; |
137 | 137 | ||
@@ -438,6 +438,25 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *da, | |||
438 | } | 438 | } |
439 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 439 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
440 | 440 | ||
441 | static ssize_t show_alarm(struct device *dev, struct device_attribute *da, | ||
442 | char *buf) | ||
443 | { | ||
444 | struct lm78_data *data = lm78_update_device(dev); | ||
445 | int nr = to_sensor_dev_attr(da)->index; | ||
446 | return sprintf(buf, "%u\n", (data->alarms >> nr) & 1); | ||
447 | } | ||
448 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
449 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
450 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
451 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
452 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
453 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
454 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10); | ||
455 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
456 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
457 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
458 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
459 | |||
441 | /* This function is called when: | 460 | /* This function is called when: |
442 | * lm78_driver is inserted (when this module is loaded), for each | 461 | * lm78_driver is inserted (when this module is loaded), for each |
443 | available adapter | 462 | available adapter |
@@ -453,36 +472,47 @@ static struct attribute *lm78_attributes[] = { | |||
453 | &sensor_dev_attr_in0_input.dev_attr.attr, | 472 | &sensor_dev_attr_in0_input.dev_attr.attr, |
454 | &sensor_dev_attr_in0_min.dev_attr.attr, | 473 | &sensor_dev_attr_in0_min.dev_attr.attr, |
455 | &sensor_dev_attr_in0_max.dev_attr.attr, | 474 | &sensor_dev_attr_in0_max.dev_attr.attr, |
475 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | ||
456 | &sensor_dev_attr_in1_input.dev_attr.attr, | 476 | &sensor_dev_attr_in1_input.dev_attr.attr, |
457 | &sensor_dev_attr_in1_min.dev_attr.attr, | 477 | &sensor_dev_attr_in1_min.dev_attr.attr, |
458 | &sensor_dev_attr_in1_max.dev_attr.attr, | 478 | &sensor_dev_attr_in1_max.dev_attr.attr, |
479 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
459 | &sensor_dev_attr_in2_input.dev_attr.attr, | 480 | &sensor_dev_attr_in2_input.dev_attr.attr, |
460 | &sensor_dev_attr_in2_min.dev_attr.attr, | 481 | &sensor_dev_attr_in2_min.dev_attr.attr, |
461 | &sensor_dev_attr_in2_max.dev_attr.attr, | 482 | &sensor_dev_attr_in2_max.dev_attr.attr, |
483 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
462 | &sensor_dev_attr_in3_input.dev_attr.attr, | 484 | &sensor_dev_attr_in3_input.dev_attr.attr, |
463 | &sensor_dev_attr_in3_min.dev_attr.attr, | 485 | &sensor_dev_attr_in3_min.dev_attr.attr, |
464 | &sensor_dev_attr_in3_max.dev_attr.attr, | 486 | &sensor_dev_attr_in3_max.dev_attr.attr, |
487 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
465 | &sensor_dev_attr_in4_input.dev_attr.attr, | 488 | &sensor_dev_attr_in4_input.dev_attr.attr, |
466 | &sensor_dev_attr_in4_min.dev_attr.attr, | 489 | &sensor_dev_attr_in4_min.dev_attr.attr, |
467 | &sensor_dev_attr_in4_max.dev_attr.attr, | 490 | &sensor_dev_attr_in4_max.dev_attr.attr, |
491 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
468 | &sensor_dev_attr_in5_input.dev_attr.attr, | 492 | &sensor_dev_attr_in5_input.dev_attr.attr, |
469 | &sensor_dev_attr_in5_min.dev_attr.attr, | 493 | &sensor_dev_attr_in5_min.dev_attr.attr, |
470 | &sensor_dev_attr_in5_max.dev_attr.attr, | 494 | &sensor_dev_attr_in5_max.dev_attr.attr, |
495 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
471 | &sensor_dev_attr_in6_input.dev_attr.attr, | 496 | &sensor_dev_attr_in6_input.dev_attr.attr, |
472 | &sensor_dev_attr_in6_min.dev_attr.attr, | 497 | &sensor_dev_attr_in6_min.dev_attr.attr, |
473 | &sensor_dev_attr_in6_max.dev_attr.attr, | 498 | &sensor_dev_attr_in6_max.dev_attr.attr, |
499 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
474 | &dev_attr_temp1_input.attr, | 500 | &dev_attr_temp1_input.attr, |
475 | &dev_attr_temp1_max.attr, | 501 | &dev_attr_temp1_max.attr, |
476 | &dev_attr_temp1_max_hyst.attr, | 502 | &dev_attr_temp1_max_hyst.attr, |
503 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
477 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 504 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
478 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 505 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
479 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 506 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
507 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
480 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 508 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
481 | &sensor_dev_attr_fan2_min.dev_attr.attr, | 509 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
482 | &sensor_dev_attr_fan2_div.dev_attr.attr, | 510 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
511 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
483 | &sensor_dev_attr_fan3_input.dev_attr.attr, | 512 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
484 | &sensor_dev_attr_fan3_min.dev_attr.attr, | 513 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
485 | &sensor_dev_attr_fan3_div.dev_attr.attr, | 514 | &sensor_dev_attr_fan3_div.dev_attr.attr, |
515 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | ||
486 | &dev_attr_alarms.attr, | 516 | &dev_attr_alarms.attr, |
487 | &dev_attr_cpu0_vid.attr, | 517 | &dev_attr_cpu0_vid.attr, |
488 | 518 | ||
@@ -585,9 +615,9 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) | |||
585 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group))) | 615 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group))) |
586 | goto ERROR3; | 616 | goto ERROR3; |
587 | 617 | ||
588 | data->class_dev = hwmon_device_register(&new_client->dev); | 618 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
589 | if (IS_ERR(data->class_dev)) { | 619 | if (IS_ERR(data->hwmon_dev)) { |
590 | err = PTR_ERR(data->class_dev); | 620 | err = PTR_ERR(data->hwmon_dev); |
591 | goto ERROR4; | 621 | goto ERROR4; |
592 | } | 622 | } |
593 | 623 | ||
@@ -608,7 +638,7 @@ static int lm78_detach_client(struct i2c_client *client) | |||
608 | struct lm78_data *data = i2c_get_clientdata(client); | 638 | struct lm78_data *data = i2c_get_clientdata(client); |
609 | int err; | 639 | int err; |
610 | 640 | ||
611 | hwmon_device_unregister(data->class_dev); | 641 | hwmon_device_unregister(data->hwmon_dev); |
612 | sysfs_remove_group(&client->dev.kobj, &lm78_group); | 642 | sysfs_remove_group(&client->dev.kobj, &lm78_group); |
613 | 643 | ||
614 | if ((err = i2c_detach_client(client))) | 644 | if ((err = i2c_detach_client(client))) |
@@ -659,9 +689,9 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) | |||
659 | || (err = device_create_file(&pdev->dev, &dev_attr_name))) | 689 | || (err = device_create_file(&pdev->dev, &dev_attr_name))) |
660 | goto exit_remove_files; | 690 | goto exit_remove_files; |
661 | 691 | ||
662 | data->class_dev = hwmon_device_register(&pdev->dev); | 692 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
663 | if (IS_ERR(data->class_dev)) { | 693 | if (IS_ERR(data->hwmon_dev)) { |
664 | err = PTR_ERR(data->class_dev); | 694 | err = PTR_ERR(data->hwmon_dev); |
665 | goto exit_remove_files; | 695 | goto exit_remove_files; |
666 | } | 696 | } |
667 | 697 | ||
@@ -681,7 +711,7 @@ static int __devexit lm78_isa_remove(struct platform_device *pdev) | |||
681 | { | 711 | { |
682 | struct lm78_data *data = platform_get_drvdata(pdev); | 712 | struct lm78_data *data = platform_get_drvdata(pdev); |
683 | 713 | ||
684 | hwmon_device_unregister(data->class_dev); | 714 | hwmon_device_unregister(data->hwmon_dev); |
685 | sysfs_remove_group(&pdev->dev.kobj, &lm78_group); | 715 | sysfs_remove_group(&pdev->dev.kobj, &lm78_group); |
686 | device_remove_file(&pdev->dev, &dev_attr_name); | 716 | device_remove_file(&pdev->dev, &dev_attr_name); |
687 | release_region(data->client.addr, LM78_EXTENT); | 717 | release_region(data->client.addr, LM78_EXTENT); |
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index 064516d824ad..063cdba00a88 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c | |||
@@ -108,7 +108,7 @@ static inline long TEMP_FROM_REG(u16 temp) | |||
108 | 108 | ||
109 | struct lm80_data { | 109 | struct lm80_data { |
110 | struct i2c_client client; | 110 | struct i2c_client client; |
111 | struct class_device *class_dev; | 111 | struct device *hwmon_dev; |
112 | struct mutex update_lock; | 112 | struct mutex update_lock; |
113 | char valid; /* !=0 if following fields are valid */ | 113 | char valid; /* !=0 if following fields are valid */ |
114 | unsigned long last_updated; /* In jiffies */ | 114 | unsigned long last_updated; /* In jiffies */ |
@@ -497,9 +497,9 @@ static int lm80_detect(struct i2c_adapter *adapter, int address, int kind) | |||
497 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm80_group))) | 497 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm80_group))) |
498 | goto error_detach; | 498 | goto error_detach; |
499 | 499 | ||
500 | data->class_dev = hwmon_device_register(&new_client->dev); | 500 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
501 | if (IS_ERR(data->class_dev)) { | 501 | if (IS_ERR(data->hwmon_dev)) { |
502 | err = PTR_ERR(data->class_dev); | 502 | err = PTR_ERR(data->hwmon_dev); |
503 | goto error_remove; | 503 | goto error_remove; |
504 | } | 504 | } |
505 | 505 | ||
@@ -520,7 +520,7 @@ static int lm80_detach_client(struct i2c_client *client) | |||
520 | struct lm80_data *data = i2c_get_clientdata(client); | 520 | struct lm80_data *data = i2c_get_clientdata(client); |
521 | int err; | 521 | int err; |
522 | 522 | ||
523 | hwmon_device_unregister(data->class_dev); | 523 | hwmon_device_unregister(data->hwmon_dev); |
524 | sysfs_remove_group(&client->dev.kobj, &lm80_group); | 524 | sysfs_remove_group(&client->dev.kobj, &lm80_group); |
525 | if ((err = i2c_detach_client(client))) | 525 | if ((err = i2c_detach_client(client))) |
526 | return err; | 526 | return err; |
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 654c0f73464d..0336b4572a61 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c | |||
@@ -144,7 +144,7 @@ static struct i2c_driver lm83_driver = { | |||
144 | 144 | ||
145 | struct lm83_data { | 145 | struct lm83_data { |
146 | struct i2c_client client; | 146 | struct i2c_client client; |
147 | struct class_device *class_dev; | 147 | struct device *hwmon_dev; |
148 | struct mutex update_lock; | 148 | struct mutex update_lock; |
149 | char valid; /* zero until following fields are valid */ | 149 | char valid; /* zero until following fields are valid */ |
150 | unsigned long last_updated; /* in jiffies */ | 150 | unsigned long last_updated; /* in jiffies */ |
@@ -400,9 +400,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) | |||
400 | goto exit_remove_files; | 400 | goto exit_remove_files; |
401 | } | 401 | } |
402 | 402 | ||
403 | data->class_dev = hwmon_device_register(&new_client->dev); | 403 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
404 | if (IS_ERR(data->class_dev)) { | 404 | if (IS_ERR(data->hwmon_dev)) { |
405 | err = PTR_ERR(data->class_dev); | 405 | err = PTR_ERR(data->hwmon_dev); |
406 | goto exit_remove_files; | 406 | goto exit_remove_files; |
407 | } | 407 | } |
408 | 408 | ||
@@ -424,7 +424,7 @@ static int lm83_detach_client(struct i2c_client *client) | |||
424 | struct lm83_data *data = i2c_get_clientdata(client); | 424 | struct lm83_data *data = i2c_get_clientdata(client); |
425 | int err; | 425 | int err; |
426 | 426 | ||
427 | hwmon_device_unregister(data->class_dev); | 427 | hwmon_device_unregister(data->hwmon_dev); |
428 | sysfs_remove_group(&client->dev.kobj, &lm83_group); | 428 | sysfs_remove_group(&client->dev.kobj, &lm83_group); |
429 | sysfs_remove_group(&client->dev.kobj, &lm83_group_opt); | 429 | sysfs_remove_group(&client->dev.kobj, &lm83_group_opt); |
430 | 430 | ||
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 20a8c648280d..a02480be65f2 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
31 | #include <linux/hwmon.h> | 31 | #include <linux/hwmon.h> |
32 | #include <linux/hwmon-vid.h> | 32 | #include <linux/hwmon-vid.h> |
33 | #include <linux/hwmon-sysfs.h> | ||
33 | #include <linux/err.h> | 34 | #include <linux/err.h> |
34 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
35 | 36 | ||
@@ -122,23 +123,6 @@ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | |||
122 | #define EMC6D102_REG_EXTEND_ADC3 0x87 | 123 | #define EMC6D102_REG_EXTEND_ADC3 0x87 |
123 | #define EMC6D102_REG_EXTEND_ADC4 0x88 | 124 | #define EMC6D102_REG_EXTEND_ADC4 0x88 |
124 | 125 | ||
125 | #define LM85_ALARM_IN0 0x0001 | ||
126 | #define LM85_ALARM_IN1 0x0002 | ||
127 | #define LM85_ALARM_IN2 0x0004 | ||
128 | #define LM85_ALARM_IN3 0x0008 | ||
129 | #define LM85_ALARM_TEMP1 0x0010 | ||
130 | #define LM85_ALARM_TEMP2 0x0020 | ||
131 | #define LM85_ALARM_TEMP3 0x0040 | ||
132 | #define LM85_ALARM_ALARM2 0x0080 | ||
133 | #define LM85_ALARM_IN4 0x0100 | ||
134 | #define LM85_ALARM_RESERVED 0x0200 | ||
135 | #define LM85_ALARM_FAN1 0x0400 | ||
136 | #define LM85_ALARM_FAN2 0x0800 | ||
137 | #define LM85_ALARM_FAN3 0x1000 | ||
138 | #define LM85_ALARM_FAN4 0x2000 | ||
139 | #define LM85_ALARM_TEMP1_FAULT 0x4000 | ||
140 | #define LM85_ALARM_TEMP3_FAULT 0x8000 | ||
141 | |||
142 | 126 | ||
143 | /* Conversions. Rounding and limit checking is only done on the TO_REG | 127 | /* Conversions. Rounding and limit checking is only done on the TO_REG |
144 | variants. Note that you should be a bit careful with which arguments | 128 | variants. Note that you should be a bit careful with which arguments |
@@ -155,22 +139,26 @@ static int lm85_scaling[] = { /* .001 Volts */ | |||
155 | #define INS_TO_REG(n,val) \ | 139 | #define INS_TO_REG(n,val) \ |
156 | SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255) | 140 | SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255) |
157 | 141 | ||
158 | #define INSEXT_FROM_REG(n,val,ext,scale) \ | 142 | #define INSEXT_FROM_REG(n,val,ext) \ |
159 | SCALE((val)*(scale) + (ext),192*(scale),lm85_scaling[n]) | 143 | SCALE(((val) << 4) + (ext), 192 << 4, lm85_scaling[n]) |
160 | 144 | ||
161 | #define INS_FROM_REG(n,val) INSEXT_FROM_REG(n,val,0,1) | 145 | #define INS_FROM_REG(n,val) SCALE((val), 192, lm85_scaling[n]) |
162 | 146 | ||
163 | /* FAN speed is measured using 90kHz clock */ | 147 | /* FAN speed is measured using 90kHz clock */ |
164 | #define FAN_TO_REG(val) (SENSORS_LIMIT( (val)<=0?0: 5400000/(val),0,65534)) | 148 | static inline u16 FAN_TO_REG(unsigned long val) |
149 | { | ||
150 | if (!val) | ||
151 | return 0xffff; | ||
152 | return SENSORS_LIMIT(5400000 / val, 1, 0xfffe); | ||
153 | } | ||
165 | #define FAN_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:5400000/(val)) | 154 | #define FAN_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:5400000/(val)) |
166 | 155 | ||
167 | /* Temperature is reported in .001 degC increments */ | 156 | /* Temperature is reported in .001 degC increments */ |
168 | #define TEMP_TO_REG(val) \ | 157 | #define TEMP_TO_REG(val) \ |
169 | SENSORS_LIMIT(SCALE(val,1000,1),-127,127) | 158 | SENSORS_LIMIT(SCALE(val,1000,1),-127,127) |
170 | #define TEMPEXT_FROM_REG(val,ext,scale) \ | 159 | #define TEMPEXT_FROM_REG(val,ext) \ |
171 | SCALE((val)*scale + (ext),scale,1000) | 160 | SCALE(((val) << 4) + (ext), 16, 1000) |
172 | #define TEMP_FROM_REG(val) \ | 161 | #define TEMP_FROM_REG(val) ((val) * 1000) |
173 | TEMPEXT_FROM_REG(val,0,1) | ||
174 | 162 | ||
175 | #define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255)) | 163 | #define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255)) |
176 | #define PWM_FROM_REG(val) (val) | 164 | #define PWM_FROM_REG(val) (val) |
@@ -328,7 +316,7 @@ struct lm85_autofan { | |||
328 | The structure is dynamically allocated. */ | 316 | The structure is dynamically allocated. */ |
329 | struct lm85_data { | 317 | struct lm85_data { |
330 | struct i2c_client client; | 318 | struct i2c_client client; |
331 | struct class_device *class_dev; | 319 | struct device *hwmon_dev; |
332 | enum chips type; | 320 | enum chips type; |
333 | 321 | ||
334 | struct mutex update_lock; | 322 | struct mutex update_lock; |
@@ -350,7 +338,6 @@ struct lm85_data { | |||
350 | u8 tach_mode; /* Register encoding, combined */ | 338 | u8 tach_mode; /* Register encoding, combined */ |
351 | u8 temp_ext[3]; /* Decoded values */ | 339 | u8 temp_ext[3]; /* Decoded values */ |
352 | u8 in_ext[8]; /* Decoded values */ | 340 | u8 in_ext[8]; /* Decoded values */ |
353 | u8 adc_scale; /* ADC Extended bits scaling factor */ | ||
354 | u8 fan_ppr; /* Register value */ | 341 | u8 fan_ppr; /* Register value */ |
355 | u8 smooth[3]; /* Register encoding */ | 342 | u8 smooth[3]; /* Register encoding */ |
356 | u8 vid; /* Register value */ | 343 | u8 vid; /* Register value */ |
@@ -387,22 +374,29 @@ static struct i2c_driver lm85_driver = { | |||
387 | 374 | ||
388 | 375 | ||
389 | /* 4 Fans */ | 376 | /* 4 Fans */ |
390 | static ssize_t show_fan(struct device *dev, char *buf, int nr) | 377 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, |
378 | char *buf) | ||
391 | { | 379 | { |
380 | int nr = to_sensor_dev_attr(attr)->index; | ||
392 | struct lm85_data *data = lm85_update_device(dev); | 381 | struct lm85_data *data = lm85_update_device(dev); |
393 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr]) ); | 382 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr]) ); |
394 | } | 383 | } |
395 | static ssize_t show_fan_min(struct device *dev, char *buf, int nr) | 384 | |
385 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, | ||
386 | char *buf) | ||
396 | { | 387 | { |
388 | int nr = to_sensor_dev_attr(attr)->index; | ||
397 | struct lm85_data *data = lm85_update_device(dev); | 389 | struct lm85_data *data = lm85_update_device(dev); |
398 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr]) ); | 390 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr]) ); |
399 | } | 391 | } |
400 | static ssize_t set_fan_min(struct device *dev, const char *buf, | 392 | |
401 | size_t count, int nr) | 393 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, |
394 | const char *buf, size_t count) | ||
402 | { | 395 | { |
396 | int nr = to_sensor_dev_attr(attr)->index; | ||
403 | struct i2c_client *client = to_i2c_client(dev); | 397 | struct i2c_client *client = to_i2c_client(dev); |
404 | struct lm85_data *data = i2c_get_clientdata(client); | 398 | struct lm85_data *data = i2c_get_clientdata(client); |
405 | long val = simple_strtol(buf, NULL, 10); | 399 | unsigned long val = simple_strtoul(buf, NULL, 10); |
406 | 400 | ||
407 | mutex_lock(&data->update_lock); | 401 | mutex_lock(&data->update_lock); |
408 | data->fan_min[nr] = FAN_TO_REG(val); | 402 | data->fan_min[nr] = FAN_TO_REG(val); |
@@ -412,23 +406,10 @@ static ssize_t set_fan_min(struct device *dev, const char *buf, | |||
412 | } | 406 | } |
413 | 407 | ||
414 | #define show_fan_offset(offset) \ | 408 | #define show_fan_offset(offset) \ |
415 | static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 409 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ |
416 | { \ | 410 | show_fan, NULL, offset - 1); \ |
417 | return show_fan(dev, buf, offset - 1); \ | 411 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ |
418 | } \ | 412 | show_fan_min, set_fan_min, offset - 1) |
419 | static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
420 | { \ | ||
421 | return show_fan_min(dev, buf, offset - 1); \ | ||
422 | } \ | ||
423 | static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
424 | const char *buf, size_t count) \ | ||
425 | { \ | ||
426 | return set_fan_min(dev, buf, count, offset - 1); \ | ||
427 | } \ | ||
428 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, \ | ||
429 | NULL); \ | ||
430 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
431 | show_fan_##offset##_min, set_fan_##offset##_min); | ||
432 | 413 | ||
433 | show_fan_offset(1); | 414 | show_fan_offset(1); |
434 | show_fan_offset(2); | 415 | show_fan_offset(2); |
@@ -457,7 +438,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | |||
457 | 438 | ||
458 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 439 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
459 | { | 440 | { |
460 | struct lm85_data *data = lm85_update_device(dev); | 441 | struct lm85_data *data = dev_get_drvdata(dev); |
461 | return sprintf(buf, "%ld\n", (long) data->vrm); | 442 | return sprintf(buf, "%ld\n", (long) data->vrm); |
462 | } | 443 | } |
463 | 444 | ||
@@ -482,16 +463,46 @@ static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr | |||
482 | 463 | ||
483 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); | 464 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); |
484 | 465 | ||
466 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
467 | char *buf) | ||
468 | { | ||
469 | int nr = to_sensor_dev_attr(attr)->index; | ||
470 | struct lm85_data *data = lm85_update_device(dev); | ||
471 | return sprintf(buf, "%u\n", (data->alarms >> nr) & 1); | ||
472 | } | ||
473 | |||
474 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
475 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
476 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
477 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
478 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
479 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 18); | ||
480 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 16); | ||
481 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 17); | ||
482 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
483 | static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_alarm, NULL, 14); | ||
484 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
485 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
486 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15); | ||
487 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 10); | ||
488 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
489 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 12); | ||
490 | static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 13); | ||
491 | |||
485 | /* pwm */ | 492 | /* pwm */ |
486 | 493 | ||
487 | static ssize_t show_pwm(struct device *dev, char *buf, int nr) | 494 | static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, |
495 | char *buf) | ||
488 | { | 496 | { |
497 | int nr = to_sensor_dev_attr(attr)->index; | ||
489 | struct lm85_data *data = lm85_update_device(dev); | 498 | struct lm85_data *data = lm85_update_device(dev); |
490 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm[nr]) ); | 499 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm[nr]) ); |
491 | } | 500 | } |
492 | static ssize_t set_pwm(struct device *dev, const char *buf, | 501 | |
493 | size_t count, int nr) | 502 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, |
503 | const char *buf, size_t count) | ||
494 | { | 504 | { |
505 | int nr = to_sensor_dev_attr(attr)->index; | ||
495 | struct i2c_client *client = to_i2c_client(dev); | 506 | struct i2c_client *client = to_i2c_client(dev); |
496 | struct lm85_data *data = i2c_get_clientdata(client); | 507 | struct lm85_data *data = i2c_get_clientdata(client); |
497 | long val = simple_strtol(buf, NULL, 10); | 508 | long val = simple_strtol(buf, NULL, 10); |
@@ -502,8 +513,11 @@ static ssize_t set_pwm(struct device *dev, const char *buf, | |||
502 | mutex_unlock(&data->update_lock); | 513 | mutex_unlock(&data->update_lock); |
503 | return count; | 514 | return count; |
504 | } | 515 | } |
505 | static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr) | 516 | |
517 | static ssize_t show_pwm_enable(struct device *dev, struct device_attribute | ||
518 | *attr, char *buf) | ||
506 | { | 519 | { |
520 | int nr = to_sensor_dev_attr(attr)->index; | ||
507 | struct lm85_data *data = lm85_update_device(dev); | 521 | struct lm85_data *data = lm85_update_device(dev); |
508 | int pwm_zone; | 522 | int pwm_zone; |
509 | 523 | ||
@@ -512,23 +526,10 @@ static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr) | |||
512 | } | 526 | } |
513 | 527 | ||
514 | #define show_pwm_reg(offset) \ | 528 | #define show_pwm_reg(offset) \ |
515 | static ssize_t show_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 529 | static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ |
516 | { \ | 530 | show_pwm, set_pwm, offset - 1); \ |
517 | return show_pwm(dev, buf, offset - 1); \ | 531 | static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO, \ |
518 | } \ | 532 | show_pwm_enable, NULL, offset - 1) |
519 | static ssize_t set_pwm_##offset (struct device *dev, struct device_attribute *attr, \ | ||
520 | const char *buf, size_t count) \ | ||
521 | { \ | ||
522 | return set_pwm(dev, buf, count, offset - 1); \ | ||
523 | } \ | ||
524 | static ssize_t show_pwm_enable##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
525 | { \ | ||
526 | return show_pwm_enable(dev, buf, offset - 1); \ | ||
527 | } \ | ||
528 | static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ | ||
529 | show_pwm_##offset, set_pwm_##offset); \ | ||
530 | static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO, \ | ||
531 | show_pwm_enable##offset, NULL); | ||
532 | 533 | ||
533 | show_pwm_reg(1); | 534 | show_pwm_reg(1); |
534 | show_pwm_reg(2); | 535 | show_pwm_reg(2); |
@@ -536,22 +537,28 @@ show_pwm_reg(3); | |||
536 | 537 | ||
537 | /* Voltages */ | 538 | /* Voltages */ |
538 | 539 | ||
539 | static ssize_t show_in(struct device *dev, char *buf, int nr) | 540 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, |
541 | char *buf) | ||
540 | { | 542 | { |
543 | int nr = to_sensor_dev_attr(attr)->index; | ||
541 | struct lm85_data *data = lm85_update_device(dev); | 544 | struct lm85_data *data = lm85_update_device(dev); |
542 | return sprintf( buf, "%d\n", INSEXT_FROM_REG(nr, | 545 | return sprintf( buf, "%d\n", INSEXT_FROM_REG(nr, |
543 | data->in[nr], | 546 | data->in[nr], |
544 | data->in_ext[nr], | 547 | data->in_ext[nr])); |
545 | data->adc_scale) ); | ||
546 | } | 548 | } |
547 | static ssize_t show_in_min(struct device *dev, char *buf, int nr) | 549 | |
550 | static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, | ||
551 | char *buf) | ||
548 | { | 552 | { |
553 | int nr = to_sensor_dev_attr(attr)->index; | ||
549 | struct lm85_data *data = lm85_update_device(dev); | 554 | struct lm85_data *data = lm85_update_device(dev); |
550 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]) ); | 555 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]) ); |
551 | } | 556 | } |
552 | static ssize_t set_in_min(struct device *dev, const char *buf, | 557 | |
553 | size_t count, int nr) | 558 | static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, |
559 | const char *buf, size_t count) | ||
554 | { | 560 | { |
561 | int nr = to_sensor_dev_attr(attr)->index; | ||
555 | struct i2c_client *client = to_i2c_client(dev); | 562 | struct i2c_client *client = to_i2c_client(dev); |
556 | struct lm85_data *data = i2c_get_clientdata(client); | 563 | struct lm85_data *data = i2c_get_clientdata(client); |
557 | long val = simple_strtol(buf, NULL, 10); | 564 | long val = simple_strtol(buf, NULL, 10); |
@@ -562,14 +569,19 @@ static ssize_t set_in_min(struct device *dev, const char *buf, | |||
562 | mutex_unlock(&data->update_lock); | 569 | mutex_unlock(&data->update_lock); |
563 | return count; | 570 | return count; |
564 | } | 571 | } |
565 | static ssize_t show_in_max(struct device *dev, char *buf, int nr) | 572 | |
573 | static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, | ||
574 | char *buf) | ||
566 | { | 575 | { |
576 | int nr = to_sensor_dev_attr(attr)->index; | ||
567 | struct lm85_data *data = lm85_update_device(dev); | 577 | struct lm85_data *data = lm85_update_device(dev); |
568 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]) ); | 578 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]) ); |
569 | } | 579 | } |
570 | static ssize_t set_in_max(struct device *dev, const char *buf, | 580 | |
571 | size_t count, int nr) | 581 | static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, |
582 | const char *buf, size_t count) | ||
572 | { | 583 | { |
584 | int nr = to_sensor_dev_attr(attr)->index; | ||
573 | struct i2c_client *client = to_i2c_client(dev); | 585 | struct i2c_client *client = to_i2c_client(dev); |
574 | struct lm85_data *data = i2c_get_clientdata(client); | 586 | struct lm85_data *data = i2c_get_clientdata(client); |
575 | long val = simple_strtol(buf, NULL, 10); | 587 | long val = simple_strtol(buf, NULL, 10); |
@@ -580,59 +592,47 @@ static ssize_t set_in_max(struct device *dev, const char *buf, | |||
580 | mutex_unlock(&data->update_lock); | 592 | mutex_unlock(&data->update_lock); |
581 | return count; | 593 | return count; |
582 | } | 594 | } |
595 | |||
583 | #define show_in_reg(offset) \ | 596 | #define show_in_reg(offset) \ |
584 | static ssize_t show_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 597 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ |
585 | { \ | 598 | show_in, NULL, offset); \ |
586 | return show_in(dev, buf, offset); \ | 599 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ |
587 | } \ | 600 | show_in_min, set_in_min, offset); \ |
588 | static ssize_t show_in_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | 601 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ |
589 | { \ | 602 | show_in_max, set_in_max, offset) |
590 | return show_in_min(dev, buf, offset); \ | ||
591 | } \ | ||
592 | static ssize_t show_in_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
593 | { \ | ||
594 | return show_in_max(dev, buf, offset); \ | ||
595 | } \ | ||
596 | static ssize_t set_in_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
597 | const char *buf, size_t count) \ | ||
598 | { \ | ||
599 | return set_in_min(dev, buf, count, offset); \ | ||
600 | } \ | ||
601 | static ssize_t set_in_##offset##_max (struct device *dev, struct device_attribute *attr, \ | ||
602 | const char *buf, size_t count) \ | ||
603 | { \ | ||
604 | return set_in_max(dev, buf, count, offset); \ | ||
605 | } \ | ||
606 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, \ | ||
607 | NULL); \ | ||
608 | static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
609 | show_in_##offset##_min, set_in_##offset##_min); \ | ||
610 | static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
611 | show_in_##offset##_max, set_in_##offset##_max); | ||
612 | 603 | ||
613 | show_in_reg(0); | 604 | show_in_reg(0); |
614 | show_in_reg(1); | 605 | show_in_reg(1); |
615 | show_in_reg(2); | 606 | show_in_reg(2); |
616 | show_in_reg(3); | 607 | show_in_reg(3); |
617 | show_in_reg(4); | 608 | show_in_reg(4); |
609 | show_in_reg(5); | ||
610 | show_in_reg(6); | ||
611 | show_in_reg(7); | ||
618 | 612 | ||
619 | /* Temps */ | 613 | /* Temps */ |
620 | 614 | ||
621 | static ssize_t show_temp(struct device *dev, char *buf, int nr) | 615 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, |
616 | char *buf) | ||
622 | { | 617 | { |
618 | int nr = to_sensor_dev_attr(attr)->index; | ||
623 | struct lm85_data *data = lm85_update_device(dev); | 619 | struct lm85_data *data = lm85_update_device(dev); |
624 | return sprintf(buf,"%d\n", TEMPEXT_FROM_REG(data->temp[nr], | 620 | return sprintf(buf,"%d\n", TEMPEXT_FROM_REG(data->temp[nr], |
625 | data->temp_ext[nr], | 621 | data->temp_ext[nr])); |
626 | data->adc_scale) ); | ||
627 | } | 622 | } |
628 | static ssize_t show_temp_min(struct device *dev, char *buf, int nr) | 623 | |
624 | static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, | ||
625 | char *buf) | ||
629 | { | 626 | { |
627 | int nr = to_sensor_dev_attr(attr)->index; | ||
630 | struct lm85_data *data = lm85_update_device(dev); | 628 | struct lm85_data *data = lm85_update_device(dev); |
631 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]) ); | 629 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]) ); |
632 | } | 630 | } |
633 | static ssize_t set_temp_min(struct device *dev, const char *buf, | 631 | |
634 | size_t count, int nr) | 632 | static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, |
633 | const char *buf, size_t count) | ||
635 | { | 634 | { |
635 | int nr = to_sensor_dev_attr(attr)->index; | ||
636 | struct i2c_client *client = to_i2c_client(dev); | 636 | struct i2c_client *client = to_i2c_client(dev); |
637 | struct lm85_data *data = i2c_get_clientdata(client); | 637 | struct lm85_data *data = i2c_get_clientdata(client); |
638 | long val = simple_strtol(buf, NULL, 10); | 638 | long val = simple_strtol(buf, NULL, 10); |
@@ -643,14 +643,19 @@ static ssize_t set_temp_min(struct device *dev, const char *buf, | |||
643 | mutex_unlock(&data->update_lock); | 643 | mutex_unlock(&data->update_lock); |
644 | return count; | 644 | return count; |
645 | } | 645 | } |
646 | static ssize_t show_temp_max(struct device *dev, char *buf, int nr) | 646 | |
647 | static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, | ||
648 | char *buf) | ||
647 | { | 649 | { |
650 | int nr = to_sensor_dev_attr(attr)->index; | ||
648 | struct lm85_data *data = lm85_update_device(dev); | 651 | struct lm85_data *data = lm85_update_device(dev); |
649 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]) ); | 652 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]) ); |
650 | } | 653 | } |
651 | static ssize_t set_temp_max(struct device *dev, const char *buf, | 654 | |
652 | size_t count, int nr) | 655 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, |
656 | const char *buf, size_t count) | ||
653 | { | 657 | { |
658 | int nr = to_sensor_dev_attr(attr)->index; | ||
654 | struct i2c_client *client = to_i2c_client(dev); | 659 | struct i2c_client *client = to_i2c_client(dev); |
655 | struct lm85_data *data = i2c_get_clientdata(client); | 660 | struct lm85_data *data = i2c_get_clientdata(client); |
656 | long val = simple_strtol(buf, NULL, 10); | 661 | long val = simple_strtol(buf, NULL, 10); |
@@ -661,35 +666,14 @@ static ssize_t set_temp_max(struct device *dev, const char *buf, | |||
661 | mutex_unlock(&data->update_lock); | 666 | mutex_unlock(&data->update_lock); |
662 | return count; | 667 | return count; |
663 | } | 668 | } |
669 | |||
664 | #define show_temp_reg(offset) \ | 670 | #define show_temp_reg(offset) \ |
665 | static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 671 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
666 | { \ | 672 | show_temp, NULL, offset - 1); \ |
667 | return show_temp(dev, buf, offset - 1); \ | 673 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ |
668 | } \ | 674 | show_temp_min, set_temp_min, offset - 1); \ |
669 | static ssize_t show_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | 675 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ |
670 | { \ | 676 | show_temp_max, set_temp_max, offset - 1); |
671 | return show_temp_min(dev, buf, offset - 1); \ | ||
672 | } \ | ||
673 | static ssize_t show_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
674 | { \ | ||
675 | return show_temp_max(dev, buf, offset - 1); \ | ||
676 | } \ | ||
677 | static ssize_t set_temp_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
678 | const char *buf, size_t count) \ | ||
679 | { \ | ||
680 | return set_temp_min(dev, buf, count, offset - 1); \ | ||
681 | } \ | ||
682 | static ssize_t set_temp_##offset##_max (struct device *dev, struct device_attribute *attr, \ | ||
683 | const char *buf, size_t count) \ | ||
684 | { \ | ||
685 | return set_temp_max(dev, buf, count, offset - 1); \ | ||
686 | } \ | ||
687 | static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, \ | ||
688 | NULL); \ | ||
689 | static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ | ||
690 | show_temp_##offset##_min, set_temp_##offset##_min); \ | ||
691 | static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | ||
692 | show_temp_##offset##_max, set_temp_##offset##_max); | ||
693 | 677 | ||
694 | show_temp_reg(1); | 678 | show_temp_reg(1); |
695 | show_temp_reg(2); | 679 | show_temp_reg(2); |
@@ -698,14 +682,18 @@ show_temp_reg(3); | |||
698 | 682 | ||
699 | /* Automatic PWM control */ | 683 | /* Automatic PWM control */ |
700 | 684 | ||
701 | static ssize_t show_pwm_auto_channels(struct device *dev, char *buf, int nr) | 685 | static ssize_t show_pwm_auto_channels(struct device *dev, |
686 | struct device_attribute *attr, char *buf) | ||
702 | { | 687 | { |
688 | int nr = to_sensor_dev_attr(attr)->index; | ||
703 | struct lm85_data *data = lm85_update_device(dev); | 689 | struct lm85_data *data = lm85_update_device(dev); |
704 | return sprintf(buf,"%d\n", ZONE_FROM_REG(data->autofan[nr].config)); | 690 | return sprintf(buf,"%d\n", ZONE_FROM_REG(data->autofan[nr].config)); |
705 | } | 691 | } |
706 | static ssize_t set_pwm_auto_channels(struct device *dev, const char *buf, | 692 | |
707 | size_t count, int nr) | 693 | static ssize_t set_pwm_auto_channels(struct device *dev, |
694 | struct device_attribute *attr, const char *buf, size_t count) | ||
708 | { | 695 | { |
696 | int nr = to_sensor_dev_attr(attr)->index; | ||
709 | struct i2c_client *client = to_i2c_client(dev); | 697 | struct i2c_client *client = to_i2c_client(dev); |
710 | struct lm85_data *data = i2c_get_clientdata(client); | 698 | struct lm85_data *data = i2c_get_clientdata(client); |
711 | long val = simple_strtol(buf, NULL, 10); | 699 | long val = simple_strtol(buf, NULL, 10); |
@@ -718,14 +706,19 @@ static ssize_t set_pwm_auto_channels(struct device *dev, const char *buf, | |||
718 | mutex_unlock(&data->update_lock); | 706 | mutex_unlock(&data->update_lock); |
719 | return count; | 707 | return count; |
720 | } | 708 | } |
721 | static ssize_t show_pwm_auto_pwm_min(struct device *dev, char *buf, int nr) | 709 | |
710 | static ssize_t show_pwm_auto_pwm_min(struct device *dev, | ||
711 | struct device_attribute *attr, char *buf) | ||
722 | { | 712 | { |
713 | int nr = to_sensor_dev_attr(attr)->index; | ||
723 | struct lm85_data *data = lm85_update_device(dev); | 714 | struct lm85_data *data = lm85_update_device(dev); |
724 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm)); | 715 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm)); |
725 | } | 716 | } |
726 | static ssize_t set_pwm_auto_pwm_min(struct device *dev, const char *buf, | 717 | |
727 | size_t count, int nr) | 718 | static ssize_t set_pwm_auto_pwm_min(struct device *dev, |
719 | struct device_attribute *attr, const char *buf, size_t count) | ||
728 | { | 720 | { |
721 | int nr = to_sensor_dev_attr(attr)->index; | ||
729 | struct i2c_client *client = to_i2c_client(dev); | 722 | struct i2c_client *client = to_i2c_client(dev); |
730 | struct lm85_data *data = i2c_get_clientdata(client); | 723 | struct lm85_data *data = i2c_get_clientdata(client); |
731 | long val = simple_strtol(buf, NULL, 10); | 724 | long val = simple_strtol(buf, NULL, 10); |
@@ -737,14 +730,19 @@ static ssize_t set_pwm_auto_pwm_min(struct device *dev, const char *buf, | |||
737 | mutex_unlock(&data->update_lock); | 730 | mutex_unlock(&data->update_lock); |
738 | return count; | 731 | return count; |
739 | } | 732 | } |
740 | static ssize_t show_pwm_auto_pwm_minctl(struct device *dev, char *buf, int nr) | 733 | |
734 | static ssize_t show_pwm_auto_pwm_minctl(struct device *dev, | ||
735 | struct device_attribute *attr, char *buf) | ||
741 | { | 736 | { |
737 | int nr = to_sensor_dev_attr(attr)->index; | ||
742 | struct lm85_data *data = lm85_update_device(dev); | 738 | struct lm85_data *data = lm85_update_device(dev); |
743 | return sprintf(buf,"%d\n", data->autofan[nr].min_off); | 739 | return sprintf(buf,"%d\n", data->autofan[nr].min_off); |
744 | } | 740 | } |
745 | static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, const char *buf, | 741 | |
746 | size_t count, int nr) | 742 | static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, |
743 | struct device_attribute *attr, const char *buf, size_t count) | ||
747 | { | 744 | { |
745 | int nr = to_sensor_dev_attr(attr)->index; | ||
748 | struct i2c_client *client = to_i2c_client(dev); | 746 | struct i2c_client *client = to_i2c_client(dev); |
749 | struct lm85_data *data = i2c_get_clientdata(client); | 747 | struct lm85_data *data = i2c_get_clientdata(client); |
750 | long val = simple_strtol(buf, NULL, 10); | 748 | long val = simple_strtol(buf, NULL, 10); |
@@ -760,14 +758,19 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, const char *buf, | |||
760 | mutex_unlock(&data->update_lock); | 758 | mutex_unlock(&data->update_lock); |
761 | return count; | 759 | return count; |
762 | } | 760 | } |
763 | static ssize_t show_pwm_auto_pwm_freq(struct device *dev, char *buf, int nr) | 761 | |
762 | static ssize_t show_pwm_auto_pwm_freq(struct device *dev, | ||
763 | struct device_attribute *attr, char *buf) | ||
764 | { | 764 | { |
765 | int nr = to_sensor_dev_attr(attr)->index; | ||
765 | struct lm85_data *data = lm85_update_device(dev); | 766 | struct lm85_data *data = lm85_update_device(dev); |
766 | return sprintf(buf,"%d\n", FREQ_FROM_REG(data->autofan[nr].freq)); | 767 | return sprintf(buf,"%d\n", FREQ_FROM_REG(data->autofan[nr].freq)); |
767 | } | 768 | } |
768 | static ssize_t set_pwm_auto_pwm_freq(struct device *dev, const char *buf, | 769 | |
769 | size_t count, int nr) | 770 | static ssize_t set_pwm_auto_pwm_freq(struct device *dev, |
771 | struct device_attribute *attr, const char *buf, size_t count) | ||
770 | { | 772 | { |
773 | int nr = to_sensor_dev_attr(attr)->index; | ||
771 | struct i2c_client *client = to_i2c_client(dev); | 774 | struct i2c_client *client = to_i2c_client(dev); |
772 | struct lm85_data *data = i2c_get_clientdata(client); | 775 | struct lm85_data *data = i2c_get_clientdata(client); |
773 | long val = simple_strtol(buf, NULL, 10); | 776 | long val = simple_strtol(buf, NULL, 10); |
@@ -781,74 +784,40 @@ static ssize_t set_pwm_auto_pwm_freq(struct device *dev, const char *buf, | |||
781 | mutex_unlock(&data->update_lock); | 784 | mutex_unlock(&data->update_lock); |
782 | return count; | 785 | return count; |
783 | } | 786 | } |
787 | |||
784 | #define pwm_auto(offset) \ | 788 | #define pwm_auto(offset) \ |
785 | static ssize_t show_pwm##offset##_auto_channels (struct device *dev, struct device_attribute *attr, \ | 789 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels, \ |
786 | char *buf) \ | 790 | S_IRUGO | S_IWUSR, show_pwm_auto_channels, \ |
787 | { \ | 791 | set_pwm_auto_channels, offset - 1); \ |
788 | return show_pwm_auto_channels(dev, buf, offset - 1); \ | 792 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_min, \ |
789 | } \ | 793 | S_IRUGO | S_IWUSR, show_pwm_auto_pwm_min, \ |
790 | static ssize_t set_pwm##offset##_auto_channels (struct device *dev, struct device_attribute *attr, \ | 794 | set_pwm_auto_pwm_min, offset - 1); \ |
791 | const char *buf, size_t count) \ | 795 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, \ |
792 | { \ | 796 | S_IRUGO | S_IWUSR, show_pwm_auto_pwm_minctl, \ |
793 | return set_pwm_auto_channels(dev, buf, count, offset - 1); \ | 797 | set_pwm_auto_pwm_minctl, offset - 1); \ |
794 | } \ | 798 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_freq, \ |
795 | static ssize_t show_pwm##offset##_auto_pwm_min (struct device *dev, struct device_attribute *attr, \ | 799 | S_IRUGO | S_IWUSR, show_pwm_auto_pwm_freq, \ |
796 | char *buf) \ | 800 | set_pwm_auto_pwm_freq, offset - 1); |
797 | { \ | 801 | |
798 | return show_pwm_auto_pwm_min(dev, buf, offset - 1); \ | ||
799 | } \ | ||
800 | static ssize_t set_pwm##offset##_auto_pwm_min (struct device *dev, struct device_attribute *attr, \ | ||
801 | const char *buf, size_t count) \ | ||
802 | { \ | ||
803 | return set_pwm_auto_pwm_min(dev, buf, count, offset - 1); \ | ||
804 | } \ | ||
805 | static ssize_t show_pwm##offset##_auto_pwm_minctl (struct device *dev, struct device_attribute *attr, \ | ||
806 | char *buf) \ | ||
807 | { \ | ||
808 | return show_pwm_auto_pwm_minctl(dev, buf, offset - 1); \ | ||
809 | } \ | ||
810 | static ssize_t set_pwm##offset##_auto_pwm_minctl (struct device *dev, struct device_attribute *attr, \ | ||
811 | const char *buf, size_t count) \ | ||
812 | { \ | ||
813 | return set_pwm_auto_pwm_minctl(dev, buf, count, offset - 1); \ | ||
814 | } \ | ||
815 | static ssize_t show_pwm##offset##_auto_pwm_freq (struct device *dev, struct device_attribute *attr, \ | ||
816 | char *buf) \ | ||
817 | { \ | ||
818 | return show_pwm_auto_pwm_freq(dev, buf, offset - 1); \ | ||
819 | } \ | ||
820 | static ssize_t set_pwm##offset##_auto_pwm_freq(struct device *dev, struct device_attribute *attr, \ | ||
821 | const char *buf, size_t count) \ | ||
822 | { \ | ||
823 | return set_pwm_auto_pwm_freq(dev, buf, count, offset - 1); \ | ||
824 | } \ | ||
825 | static DEVICE_ATTR(pwm##offset##_auto_channels, S_IRUGO | S_IWUSR, \ | ||
826 | show_pwm##offset##_auto_channels, \ | ||
827 | set_pwm##offset##_auto_channels); \ | ||
828 | static DEVICE_ATTR(pwm##offset##_auto_pwm_min, S_IRUGO | S_IWUSR, \ | ||
829 | show_pwm##offset##_auto_pwm_min, \ | ||
830 | set_pwm##offset##_auto_pwm_min); \ | ||
831 | static DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, S_IRUGO | S_IWUSR, \ | ||
832 | show_pwm##offset##_auto_pwm_minctl, \ | ||
833 | set_pwm##offset##_auto_pwm_minctl); \ | ||
834 | static DEVICE_ATTR(pwm##offset##_auto_pwm_freq, S_IRUGO | S_IWUSR, \ | ||
835 | show_pwm##offset##_auto_pwm_freq, \ | ||
836 | set_pwm##offset##_auto_pwm_freq); | ||
837 | pwm_auto(1); | 802 | pwm_auto(1); |
838 | pwm_auto(2); | 803 | pwm_auto(2); |
839 | pwm_auto(3); | 804 | pwm_auto(3); |
840 | 805 | ||
841 | /* Temperature settings for automatic PWM control */ | 806 | /* Temperature settings for automatic PWM control */ |
842 | 807 | ||
843 | static ssize_t show_temp_auto_temp_off(struct device *dev, char *buf, int nr) | 808 | static ssize_t show_temp_auto_temp_off(struct device *dev, |
809 | struct device_attribute *attr, char *buf) | ||
844 | { | 810 | { |
811 | int nr = to_sensor_dev_attr(attr)->index; | ||
845 | struct lm85_data *data = lm85_update_device(dev); | 812 | struct lm85_data *data = lm85_update_device(dev); |
846 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) - | 813 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) - |
847 | HYST_FROM_REG(data->zone[nr].hyst)); | 814 | HYST_FROM_REG(data->zone[nr].hyst)); |
848 | } | 815 | } |
849 | static ssize_t set_temp_auto_temp_off(struct device *dev, const char *buf, | 816 | |
850 | size_t count, int nr) | 817 | static ssize_t set_temp_auto_temp_off(struct device *dev, |
818 | struct device_attribute *attr, const char *buf, size_t count) | ||
851 | { | 819 | { |
820 | int nr = to_sensor_dev_attr(attr)->index; | ||
852 | struct i2c_client *client = to_i2c_client(dev); | 821 | struct i2c_client *client = to_i2c_client(dev); |
853 | struct lm85_data *data = i2c_get_clientdata(client); | 822 | struct lm85_data *data = i2c_get_clientdata(client); |
854 | int min; | 823 | int min; |
@@ -871,14 +840,19 @@ static ssize_t set_temp_auto_temp_off(struct device *dev, const char *buf, | |||
871 | mutex_unlock(&data->update_lock); | 840 | mutex_unlock(&data->update_lock); |
872 | return count; | 841 | return count; |
873 | } | 842 | } |
874 | static ssize_t show_temp_auto_temp_min(struct device *dev, char *buf, int nr) | 843 | |
844 | static ssize_t show_temp_auto_temp_min(struct device *dev, | ||
845 | struct device_attribute *attr, char *buf) | ||
875 | { | 846 | { |
847 | int nr = to_sensor_dev_attr(attr)->index; | ||
876 | struct lm85_data *data = lm85_update_device(dev); | 848 | struct lm85_data *data = lm85_update_device(dev); |
877 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) ); | 849 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) ); |
878 | } | 850 | } |
879 | static ssize_t set_temp_auto_temp_min(struct device *dev, const char *buf, | 851 | |
880 | size_t count, int nr) | 852 | static ssize_t set_temp_auto_temp_min(struct device *dev, |
853 | struct device_attribute *attr, const char *buf, size_t count) | ||
881 | { | 854 | { |
855 | int nr = to_sensor_dev_attr(attr)->index; | ||
882 | struct i2c_client *client = to_i2c_client(dev); | 856 | struct i2c_client *client = to_i2c_client(dev); |
883 | struct lm85_data *data = i2c_get_clientdata(client); | 857 | struct lm85_data *data = i2c_get_clientdata(client); |
884 | long val = simple_strtol(buf, NULL, 10); | 858 | long val = simple_strtol(buf, NULL, 10); |
@@ -913,15 +887,20 @@ static ssize_t set_temp_auto_temp_min(struct device *dev, const char *buf, | |||
913 | mutex_unlock(&data->update_lock); | 887 | mutex_unlock(&data->update_lock); |
914 | return count; | 888 | return count; |
915 | } | 889 | } |
916 | static ssize_t show_temp_auto_temp_max(struct device *dev, char *buf, int nr) | 890 | |
891 | static ssize_t show_temp_auto_temp_max(struct device *dev, | ||
892 | struct device_attribute *attr, char *buf) | ||
917 | { | 893 | { |
894 | int nr = to_sensor_dev_attr(attr)->index; | ||
918 | struct lm85_data *data = lm85_update_device(dev); | 895 | struct lm85_data *data = lm85_update_device(dev); |
919 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) + | 896 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) + |
920 | RANGE_FROM_REG(data->zone[nr].range)); | 897 | RANGE_FROM_REG(data->zone[nr].range)); |
921 | } | 898 | } |
922 | static ssize_t set_temp_auto_temp_max(struct device *dev, const char *buf, | 899 | |
923 | size_t count, int nr) | 900 | static ssize_t set_temp_auto_temp_max(struct device *dev, |
901 | struct device_attribute *attr, const char *buf, size_t count) | ||
924 | { | 902 | { |
903 | int nr = to_sensor_dev_attr(attr)->index; | ||
925 | struct i2c_client *client = to_i2c_client(dev); | 904 | struct i2c_client *client = to_i2c_client(dev); |
926 | struct lm85_data *data = i2c_get_clientdata(client); | 905 | struct lm85_data *data = i2c_get_clientdata(client); |
927 | int min; | 906 | int min; |
@@ -938,14 +917,19 @@ static ssize_t set_temp_auto_temp_max(struct device *dev, const char *buf, | |||
938 | mutex_unlock(&data->update_lock); | 917 | mutex_unlock(&data->update_lock); |
939 | return count; | 918 | return count; |
940 | } | 919 | } |
941 | static ssize_t show_temp_auto_temp_crit(struct device *dev, char *buf, int nr) | 920 | |
921 | static ssize_t show_temp_auto_temp_crit(struct device *dev, | ||
922 | struct device_attribute *attr, char *buf) | ||
942 | { | 923 | { |
924 | int nr = to_sensor_dev_attr(attr)->index; | ||
943 | struct lm85_data *data = lm85_update_device(dev); | 925 | struct lm85_data *data = lm85_update_device(dev); |
944 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].critical)); | 926 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].critical)); |
945 | } | 927 | } |
946 | static ssize_t set_temp_auto_temp_crit(struct device *dev, const char *buf, | 928 | |
947 | size_t count, int nr) | 929 | static ssize_t set_temp_auto_temp_crit(struct device *dev, |
930 | struct device_attribute *attr,const char *buf, size_t count) | ||
948 | { | 931 | { |
932 | int nr = to_sensor_dev_attr(attr)->index; | ||
949 | struct i2c_client *client = to_i2c_client(dev); | 933 | struct i2c_client *client = to_i2c_client(dev); |
950 | struct lm85_data *data = i2c_get_clientdata(client); | 934 | struct lm85_data *data = i2c_get_clientdata(client); |
951 | long val = simple_strtol(buf, NULL, 10); | 935 | long val = simple_strtol(buf, NULL, 10); |
@@ -957,59 +941,21 @@ static ssize_t set_temp_auto_temp_crit(struct device *dev, const char *buf, | |||
957 | mutex_unlock(&data->update_lock); | 941 | mutex_unlock(&data->update_lock); |
958 | return count; | 942 | return count; |
959 | } | 943 | } |
944 | |||
960 | #define temp_auto(offset) \ | 945 | #define temp_auto(offset) \ |
961 | static ssize_t show_temp##offset##_auto_temp_off (struct device *dev, struct device_attribute *attr, \ | 946 | static SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_off, \ |
962 | char *buf) \ | 947 | S_IRUGO | S_IWUSR, show_temp_auto_temp_off, \ |
963 | { \ | 948 | set_temp_auto_temp_off, offset - 1); \ |
964 | return show_temp_auto_temp_off(dev, buf, offset - 1); \ | 949 | static SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_min, \ |
965 | } \ | 950 | S_IRUGO | S_IWUSR, show_temp_auto_temp_min, \ |
966 | static ssize_t set_temp##offset##_auto_temp_off (struct device *dev, struct device_attribute *attr, \ | 951 | set_temp_auto_temp_min, offset - 1); \ |
967 | const char *buf, size_t count) \ | 952 | static SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_max, \ |
968 | { \ | 953 | S_IRUGO | S_IWUSR, show_temp_auto_temp_max, \ |
969 | return set_temp_auto_temp_off(dev, buf, count, offset - 1); \ | 954 | set_temp_auto_temp_max, offset - 1); \ |
970 | } \ | 955 | static SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_crit, \ |
971 | static ssize_t show_temp##offset##_auto_temp_min (struct device *dev, struct device_attribute *attr, \ | 956 | S_IRUGO | S_IWUSR, show_temp_auto_temp_crit, \ |
972 | char *buf) \ | 957 | set_temp_auto_temp_crit, offset - 1); |
973 | { \ | 958 | |
974 | return show_temp_auto_temp_min(dev, buf, offset - 1); \ | ||
975 | } \ | ||
976 | static ssize_t set_temp##offset##_auto_temp_min (struct device *dev, struct device_attribute *attr, \ | ||
977 | const char *buf, size_t count) \ | ||
978 | { \ | ||
979 | return set_temp_auto_temp_min(dev, buf, count, offset - 1); \ | ||
980 | } \ | ||
981 | static ssize_t show_temp##offset##_auto_temp_max (struct device *dev, struct device_attribute *attr, \ | ||
982 | char *buf) \ | ||
983 | { \ | ||
984 | return show_temp_auto_temp_max(dev, buf, offset - 1); \ | ||
985 | } \ | ||
986 | static ssize_t set_temp##offset##_auto_temp_max (struct device *dev, struct device_attribute *attr, \ | ||
987 | const char *buf, size_t count) \ | ||
988 | { \ | ||
989 | return set_temp_auto_temp_max(dev, buf, count, offset - 1); \ | ||
990 | } \ | ||
991 | static ssize_t show_temp##offset##_auto_temp_crit (struct device *dev, struct device_attribute *attr, \ | ||
992 | char *buf) \ | ||
993 | { \ | ||
994 | return show_temp_auto_temp_crit(dev, buf, offset - 1); \ | ||
995 | } \ | ||
996 | static ssize_t set_temp##offset##_auto_temp_crit (struct device *dev, struct device_attribute *attr, \ | ||
997 | const char *buf, size_t count) \ | ||
998 | { \ | ||
999 | return set_temp_auto_temp_crit(dev, buf, count, offset - 1); \ | ||
1000 | } \ | ||
1001 | static DEVICE_ATTR(temp##offset##_auto_temp_off, S_IRUGO | S_IWUSR, \ | ||
1002 | show_temp##offset##_auto_temp_off, \ | ||
1003 | set_temp##offset##_auto_temp_off); \ | ||
1004 | static DEVICE_ATTR(temp##offset##_auto_temp_min, S_IRUGO | S_IWUSR, \ | ||
1005 | show_temp##offset##_auto_temp_min, \ | ||
1006 | set_temp##offset##_auto_temp_min); \ | ||
1007 | static DEVICE_ATTR(temp##offset##_auto_temp_max, S_IRUGO | S_IWUSR, \ | ||
1008 | show_temp##offset##_auto_temp_max, \ | ||
1009 | set_temp##offset##_auto_temp_max); \ | ||
1010 | static DEVICE_ATTR(temp##offset##_auto_temp_crit, S_IRUGO | S_IWUSR, \ | ||
1011 | show_temp##offset##_auto_temp_crit, \ | ||
1012 | set_temp##offset##_auto_temp_crit); | ||
1013 | temp_auto(1); | 959 | temp_auto(1); |
1014 | temp_auto(2); | 960 | temp_auto(2); |
1015 | temp_auto(3); | 961 | temp_auto(3); |
@@ -1022,69 +968,87 @@ static int lm85_attach_adapter(struct i2c_adapter *adapter) | |||
1022 | } | 968 | } |
1023 | 969 | ||
1024 | static struct attribute *lm85_attributes[] = { | 970 | static struct attribute *lm85_attributes[] = { |
1025 | &dev_attr_fan1_input.attr, | 971 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
1026 | &dev_attr_fan2_input.attr, | 972 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
1027 | &dev_attr_fan3_input.attr, | 973 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
1028 | &dev_attr_fan4_input.attr, | 974 | &sensor_dev_attr_fan4_input.dev_attr.attr, |
1029 | &dev_attr_fan1_min.attr, | 975 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
1030 | &dev_attr_fan2_min.attr, | 976 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
1031 | &dev_attr_fan3_min.attr, | 977 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
1032 | &dev_attr_fan4_min.attr, | 978 | &sensor_dev_attr_fan4_min.dev_attr.attr, |
1033 | &dev_attr_pwm1.attr, | 979 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, |
1034 | &dev_attr_pwm2.attr, | 980 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, |
1035 | &dev_attr_pwm3.attr, | 981 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, |
1036 | &dev_attr_pwm1_enable.attr, | 982 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, |
1037 | &dev_attr_pwm2_enable.attr, | 983 | |
1038 | &dev_attr_pwm3_enable.attr, | 984 | &sensor_dev_attr_pwm1.dev_attr.attr, |
1039 | &dev_attr_in0_input.attr, | 985 | &sensor_dev_attr_pwm2.dev_attr.attr, |
1040 | &dev_attr_in1_input.attr, | 986 | &sensor_dev_attr_pwm3.dev_attr.attr, |
1041 | &dev_attr_in2_input.attr, | 987 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, |
1042 | &dev_attr_in3_input.attr, | 988 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, |
1043 | &dev_attr_in0_min.attr, | 989 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, |
1044 | &dev_attr_in1_min.attr, | 990 | |
1045 | &dev_attr_in2_min.attr, | 991 | &sensor_dev_attr_in0_input.dev_attr.attr, |
1046 | &dev_attr_in3_min.attr, | 992 | &sensor_dev_attr_in1_input.dev_attr.attr, |
1047 | &dev_attr_in0_max.attr, | 993 | &sensor_dev_attr_in2_input.dev_attr.attr, |
1048 | &dev_attr_in1_max.attr, | 994 | &sensor_dev_attr_in3_input.dev_attr.attr, |
1049 | &dev_attr_in2_max.attr, | 995 | &sensor_dev_attr_in0_min.dev_attr.attr, |
1050 | &dev_attr_in3_max.attr, | 996 | &sensor_dev_attr_in1_min.dev_attr.attr, |
1051 | &dev_attr_temp1_input.attr, | 997 | &sensor_dev_attr_in2_min.dev_attr.attr, |
1052 | &dev_attr_temp2_input.attr, | 998 | &sensor_dev_attr_in3_min.dev_attr.attr, |
1053 | &dev_attr_temp3_input.attr, | 999 | &sensor_dev_attr_in0_max.dev_attr.attr, |
1054 | &dev_attr_temp1_min.attr, | 1000 | &sensor_dev_attr_in1_max.dev_attr.attr, |
1055 | &dev_attr_temp2_min.attr, | 1001 | &sensor_dev_attr_in2_max.dev_attr.attr, |
1056 | &dev_attr_temp3_min.attr, | 1002 | &sensor_dev_attr_in3_max.dev_attr.attr, |
1057 | &dev_attr_temp1_max.attr, | 1003 | &sensor_dev_attr_in0_alarm.dev_attr.attr, |
1058 | &dev_attr_temp2_max.attr, | 1004 | &sensor_dev_attr_in1_alarm.dev_attr.attr, |
1059 | &dev_attr_temp3_max.attr, | 1005 | &sensor_dev_attr_in2_alarm.dev_attr.attr, |
1006 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
1007 | |||
1008 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
1009 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
1010 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
1011 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
1012 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
1013 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
1014 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
1015 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
1016 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
1017 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
1018 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
1019 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
1020 | &sensor_dev_attr_temp1_fault.dev_attr.attr, | ||
1021 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
1022 | |||
1023 | &sensor_dev_attr_pwm1_auto_channels.dev_attr.attr, | ||
1024 | &sensor_dev_attr_pwm2_auto_channels.dev_attr.attr, | ||
1025 | &sensor_dev_attr_pwm3_auto_channels.dev_attr.attr, | ||
1026 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, | ||
1027 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, | ||
1028 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, | ||
1029 | &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, | ||
1030 | &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, | ||
1031 | &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, | ||
1032 | &sensor_dev_attr_pwm1_auto_pwm_freq.dev_attr.attr, | ||
1033 | &sensor_dev_attr_pwm2_auto_pwm_freq.dev_attr.attr, | ||
1034 | &sensor_dev_attr_pwm3_auto_pwm_freq.dev_attr.attr, | ||
1035 | |||
1036 | &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, | ||
1037 | &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, | ||
1038 | &sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr, | ||
1039 | &sensor_dev_attr_temp1_auto_temp_min.dev_attr.attr, | ||
1040 | &sensor_dev_attr_temp2_auto_temp_min.dev_attr.attr, | ||
1041 | &sensor_dev_attr_temp3_auto_temp_min.dev_attr.attr, | ||
1042 | &sensor_dev_attr_temp1_auto_temp_max.dev_attr.attr, | ||
1043 | &sensor_dev_attr_temp2_auto_temp_max.dev_attr.attr, | ||
1044 | &sensor_dev_attr_temp3_auto_temp_max.dev_attr.attr, | ||
1045 | &sensor_dev_attr_temp1_auto_temp_crit.dev_attr.attr, | ||
1046 | &sensor_dev_attr_temp2_auto_temp_crit.dev_attr.attr, | ||
1047 | &sensor_dev_attr_temp3_auto_temp_crit.dev_attr.attr, | ||
1048 | |||
1060 | &dev_attr_vrm.attr, | 1049 | &dev_attr_vrm.attr, |
1061 | &dev_attr_cpu0_vid.attr, | 1050 | &dev_attr_cpu0_vid.attr, |
1062 | &dev_attr_alarms.attr, | 1051 | &dev_attr_alarms.attr, |
1063 | &dev_attr_pwm1_auto_channels.attr, | ||
1064 | &dev_attr_pwm2_auto_channels.attr, | ||
1065 | &dev_attr_pwm3_auto_channels.attr, | ||
1066 | &dev_attr_pwm1_auto_pwm_min.attr, | ||
1067 | &dev_attr_pwm2_auto_pwm_min.attr, | ||
1068 | &dev_attr_pwm3_auto_pwm_min.attr, | ||
1069 | &dev_attr_pwm1_auto_pwm_minctl.attr, | ||
1070 | &dev_attr_pwm2_auto_pwm_minctl.attr, | ||
1071 | &dev_attr_pwm3_auto_pwm_minctl.attr, | ||
1072 | &dev_attr_pwm1_auto_pwm_freq.attr, | ||
1073 | &dev_attr_pwm2_auto_pwm_freq.attr, | ||
1074 | &dev_attr_pwm3_auto_pwm_freq.attr, | ||
1075 | &dev_attr_temp1_auto_temp_off.attr, | ||
1076 | &dev_attr_temp2_auto_temp_off.attr, | ||
1077 | &dev_attr_temp3_auto_temp_off.attr, | ||
1078 | &dev_attr_temp1_auto_temp_min.attr, | ||
1079 | &dev_attr_temp2_auto_temp_min.attr, | ||
1080 | &dev_attr_temp3_auto_temp_min.attr, | ||
1081 | &dev_attr_temp1_auto_temp_max.attr, | ||
1082 | &dev_attr_temp2_auto_temp_max.attr, | ||
1083 | &dev_attr_temp3_auto_temp_max.attr, | ||
1084 | &dev_attr_temp1_auto_temp_crit.attr, | ||
1085 | &dev_attr_temp2_auto_temp_crit.attr, | ||
1086 | &dev_attr_temp3_auto_temp_crit.attr, | ||
1087 | |||
1088 | NULL | 1052 | NULL |
1089 | }; | 1053 | }; |
1090 | 1054 | ||
@@ -1092,16 +1056,36 @@ static const struct attribute_group lm85_group = { | |||
1092 | .attrs = lm85_attributes, | 1056 | .attrs = lm85_attributes, |
1093 | }; | 1057 | }; |
1094 | 1058 | ||
1095 | static struct attribute *lm85_attributes_opt[] = { | 1059 | static struct attribute *lm85_attributes_in4[] = { |
1096 | &dev_attr_in4_input.attr, | 1060 | &sensor_dev_attr_in4_input.dev_attr.attr, |
1097 | &dev_attr_in4_min.attr, | 1061 | &sensor_dev_attr_in4_min.dev_attr.attr, |
1098 | &dev_attr_in4_max.attr, | 1062 | &sensor_dev_attr_in4_max.dev_attr.attr, |
1063 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
1064 | NULL | ||
1065 | }; | ||
1066 | |||
1067 | static const struct attribute_group lm85_group_in4 = { | ||
1068 | .attrs = lm85_attributes_in4, | ||
1069 | }; | ||
1099 | 1070 | ||
1071 | static struct attribute *lm85_attributes_in567[] = { | ||
1072 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
1073 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
1074 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
1075 | &sensor_dev_attr_in5_min.dev_attr.attr, | ||
1076 | &sensor_dev_attr_in6_min.dev_attr.attr, | ||
1077 | &sensor_dev_attr_in7_min.dev_attr.attr, | ||
1078 | &sensor_dev_attr_in5_max.dev_attr.attr, | ||
1079 | &sensor_dev_attr_in6_max.dev_attr.attr, | ||
1080 | &sensor_dev_attr_in7_max.dev_attr.attr, | ||
1081 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
1082 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
1083 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
1100 | NULL | 1084 | NULL |
1101 | }; | 1085 | }; |
1102 | 1086 | ||
1103 | static const struct attribute_group lm85_group_opt = { | 1087 | static const struct attribute_group lm85_group_in567 = { |
1104 | .attrs = lm85_attributes_opt, | 1088 | .attrs = lm85_attributes_in567, |
1105 | }; | 1089 | }; |
1106 | 1090 | ||
1107 | static int lm85_detect(struct i2c_adapter *adapter, int address, | 1091 | static int lm85_detect(struct i2c_adapter *adapter, int address, |
@@ -1249,17 +1233,19 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, | |||
1249 | as a sixth digital VID input rather than an analog input. */ | 1233 | as a sixth digital VID input rather than an analog input. */ |
1250 | data->vid = lm85_read_value(new_client, LM85_REG_VID); | 1234 | data->vid = lm85_read_value(new_client, LM85_REG_VID); |
1251 | if (!(kind == adt7463 && (data->vid & 0x80))) | 1235 | if (!(kind == adt7463 && (data->vid & 0x80))) |
1252 | if ((err = device_create_file(&new_client->dev, | 1236 | if ((err = sysfs_create_group(&new_client->dev.kobj, |
1253 | &dev_attr_in4_input)) | 1237 | &lm85_group_in4))) |
1254 | || (err = device_create_file(&new_client->dev, | ||
1255 | &dev_attr_in4_min)) | ||
1256 | || (err = device_create_file(&new_client->dev, | ||
1257 | &dev_attr_in4_max))) | ||
1258 | goto ERROR3; | 1238 | goto ERROR3; |
1259 | 1239 | ||
1260 | data->class_dev = hwmon_device_register(&new_client->dev); | 1240 | /* The EMC6D100 has 3 additional voltage inputs */ |
1261 | if (IS_ERR(data->class_dev)) { | 1241 | if (kind == emc6d100) |
1262 | err = PTR_ERR(data->class_dev); | 1242 | if ((err = sysfs_create_group(&new_client->dev.kobj, |
1243 | &lm85_group_in567))) | ||
1244 | goto ERROR3; | ||
1245 | |||
1246 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
1247 | if (IS_ERR(data->hwmon_dev)) { | ||
1248 | err = PTR_ERR(data->hwmon_dev); | ||
1263 | goto ERROR3; | 1249 | goto ERROR3; |
1264 | } | 1250 | } |
1265 | 1251 | ||
@@ -1268,7 +1254,9 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, | |||
1268 | /* Error out and cleanup code */ | 1254 | /* Error out and cleanup code */ |
1269 | ERROR3: | 1255 | ERROR3: |
1270 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group); | 1256 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group); |
1271 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group_opt); | 1257 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group_in4); |
1258 | if (kind == emc6d100) | ||
1259 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group_in567); | ||
1272 | ERROR2: | 1260 | ERROR2: |
1273 | i2c_detach_client(new_client); | 1261 | i2c_detach_client(new_client); |
1274 | ERROR1: | 1262 | ERROR1: |
@@ -1280,9 +1268,11 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, | |||
1280 | static int lm85_detach_client(struct i2c_client *client) | 1268 | static int lm85_detach_client(struct i2c_client *client) |
1281 | { | 1269 | { |
1282 | struct lm85_data *data = i2c_get_clientdata(client); | 1270 | struct lm85_data *data = i2c_get_clientdata(client); |
1283 | hwmon_device_unregister(data->class_dev); | 1271 | hwmon_device_unregister(data->hwmon_dev); |
1284 | sysfs_remove_group(&client->dev.kobj, &lm85_group); | 1272 | sysfs_remove_group(&client->dev.kobj, &lm85_group); |
1285 | sysfs_remove_group(&client->dev.kobj, &lm85_group_opt); | 1273 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in4); |
1274 | if (data->type == emc6d100) | ||
1275 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in567); | ||
1286 | i2c_detach_client(client); | 1276 | i2c_detach_client(client); |
1287 | kfree(data); | 1277 | kfree(data); |
1288 | return 0; | 1278 | return 0; |
@@ -1405,6 +1395,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1405 | 1395 | ||
1406 | /* Have to read extended bits first to "freeze" the | 1396 | /* Have to read extended bits first to "freeze" the |
1407 | * more significant bits that are read later. | 1397 | * more significant bits that are read later. |
1398 | * There are 2 additional resolution bits per channel and we | ||
1399 | * have room for 4, so we shift them to the left. | ||
1408 | */ | 1400 | */ |
1409 | if ( (data->type == adm1027) || (data->type == adt7463) ) { | 1401 | if ( (data->type == adm1027) || (data->type == adt7463) ) { |
1410 | int ext1 = lm85_read_value(client, | 1402 | int ext1 = lm85_read_value(client, |
@@ -1414,18 +1406,12 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1414 | int val = (ext1 << 8) + ext2; | 1406 | int val = (ext1 << 8) + ext2; |
1415 | 1407 | ||
1416 | for(i = 0; i <= 4; i++) | 1408 | for(i = 0; i <= 4; i++) |
1417 | data->in_ext[i] = (val>>(i * 2))&0x03; | 1409 | data->in_ext[i] = ((val>>(i * 2))&0x03) << 2; |
1418 | 1410 | ||
1419 | for(i = 0; i <= 2; i++) | 1411 | for(i = 0; i <= 2; i++) |
1420 | data->temp_ext[i] = (val>>((i + 5) * 2))&0x03; | 1412 | data->temp_ext[i] = (val>>((i + 4) * 2))&0x0c; |
1421 | } | 1413 | } |
1422 | 1414 | ||
1423 | /* adc_scale is 2^(number of LSBs). There are 4 extra bits in | ||
1424 | the emc6d102 and 2 in the adt7463 and adm1027. In all | ||
1425 | other chips ext is always 0 and the value of scale is | ||
1426 | irrelevant. So it is left in 4*/ | ||
1427 | data->adc_scale = (data->type == emc6d102 ) ? 16 : 4; | ||
1428 | |||
1429 | data->vid = lm85_read_value(client, LM85_REG_VID); | 1415 | data->vid = lm85_read_value(client, LM85_REG_VID); |
1430 | 1416 | ||
1431 | for (i = 0; i <= 3; ++i) { | 1417 | for (i = 0; i <= 3; ++i) { |
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index 988ae1c4aada..28cdff0c556b 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/jiffies.h> | 58 | #include <linux/jiffies.h> |
59 | #include <linux/i2c.h> | 59 | #include <linux/i2c.h> |
60 | #include <linux/hwmon.h> | 60 | #include <linux/hwmon.h> |
61 | #include <linux/hwmon-sysfs.h> | ||
61 | #include <linux/hwmon-vid.h> | 62 | #include <linux/hwmon-vid.h> |
62 | #include <linux/err.h> | 63 | #include <linux/err.h> |
63 | #include <linux/mutex.h> | 64 | #include <linux/mutex.h> |
@@ -129,7 +130,7 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C }; | |||
129 | (((val) < 0 ? (val)-500 : (val)+500) / 1000)) | 130 | (((val) < 0 ? (val)-500 : (val)+500) / 1000)) |
130 | 131 | ||
131 | #define FAN_FROM_REG(reg,div) ((reg) == 255 || (reg) == 0 ? 0 : \ | 132 | #define FAN_FROM_REG(reg,div) ((reg) == 255 || (reg) == 0 ? 0 : \ |
132 | 1350000 + (reg)*(div) / 2) / ((reg)*(div)) | 133 | (1350000 + (reg)*(div) / 2) / ((reg)*(div))) |
133 | #define FAN_TO_REG(val,div) ((val)*(div) * 255 <= 1350000 ? 255 : \ | 134 | #define FAN_TO_REG(val,div) ((val)*(div) * 255 <= 1350000 ? 255 : \ |
134 | (1350000 + (val)*(div) / 2) / ((val)*(div))) | 135 | (1350000 + (val)*(div) / 2) / ((val)*(div))) |
135 | 136 | ||
@@ -145,7 +146,7 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C }; | |||
145 | #define CHAN_NO_FAN(nr) (1 << (nr)) | 146 | #define CHAN_NO_FAN(nr) (1 << (nr)) |
146 | #define CHAN_TEMP3 (1 << 2) | 147 | #define CHAN_TEMP3 (1 << 2) |
147 | #define CHAN_VCC_5V (1 << 3) | 148 | #define CHAN_VCC_5V (1 << 3) |
148 | #define CHAN_NO_VID (1 << 8) | 149 | #define CHAN_NO_VID (1 << 7) |
149 | 150 | ||
150 | /* | 151 | /* |
151 | * Functions declaration | 152 | * Functions declaration |
@@ -176,7 +177,7 @@ static struct i2c_driver lm87_driver = { | |||
176 | 177 | ||
177 | struct lm87_data { | 178 | struct lm87_data { |
178 | struct i2c_client client; | 179 | struct i2c_client client; |
179 | struct class_device *class_dev; | 180 | struct device *hwmon_dev; |
180 | struct mutex update_lock; | 181 | struct mutex update_lock; |
181 | char valid; /* zero until following fields are valid */ | 182 | char valid; /* zero until following fields are valid */ |
182 | unsigned long last_updated; /* In jiffies */ | 183 | unsigned long last_updated; /* In jiffies */ |
@@ -500,7 +501,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | |||
500 | 501 | ||
501 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) | 502 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) |
502 | { | 503 | { |
503 | struct lm87_data *data = lm87_update_device(dev); | 504 | struct lm87_data *data = dev_get_drvdata(dev); |
504 | return sprintf(buf, "%d\n", data->vrm); | 505 | return sprintf(buf, "%d\n", data->vrm); |
505 | } | 506 | } |
506 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 507 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
@@ -531,6 +532,29 @@ static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const | |||
531 | } | 532 | } |
532 | static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); | 533 | static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); |
533 | 534 | ||
535 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
536 | char *buf) | ||
537 | { | ||
538 | struct lm87_data *data = lm87_update_device(dev); | ||
539 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
540 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); | ||
541 | } | ||
542 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
543 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
544 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
545 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
546 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
547 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
548 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
549 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
550 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
551 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
552 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
553 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
554 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
555 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 14); | ||
556 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15); | ||
557 | |||
534 | /* | 558 | /* |
535 | * Real code | 559 | * Real code |
536 | */ | 560 | */ |
@@ -546,24 +570,31 @@ static struct attribute *lm87_attributes[] = { | |||
546 | &dev_attr_in1_input.attr, | 570 | &dev_attr_in1_input.attr, |
547 | &dev_attr_in1_min.attr, | 571 | &dev_attr_in1_min.attr, |
548 | &dev_attr_in1_max.attr, | 572 | &dev_attr_in1_max.attr, |
573 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
549 | &dev_attr_in2_input.attr, | 574 | &dev_attr_in2_input.attr, |
550 | &dev_attr_in2_min.attr, | 575 | &dev_attr_in2_min.attr, |
551 | &dev_attr_in2_max.attr, | 576 | &dev_attr_in2_max.attr, |
577 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
552 | &dev_attr_in3_input.attr, | 578 | &dev_attr_in3_input.attr, |
553 | &dev_attr_in3_min.attr, | 579 | &dev_attr_in3_min.attr, |
554 | &dev_attr_in3_max.attr, | 580 | &dev_attr_in3_max.attr, |
581 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
555 | &dev_attr_in4_input.attr, | 582 | &dev_attr_in4_input.attr, |
556 | &dev_attr_in4_min.attr, | 583 | &dev_attr_in4_min.attr, |
557 | &dev_attr_in4_max.attr, | 584 | &dev_attr_in4_max.attr, |
585 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
558 | 586 | ||
559 | &dev_attr_temp1_input.attr, | 587 | &dev_attr_temp1_input.attr, |
560 | &dev_attr_temp1_max.attr, | 588 | &dev_attr_temp1_max.attr, |
561 | &dev_attr_temp1_min.attr, | 589 | &dev_attr_temp1_min.attr, |
562 | &dev_attr_temp1_crit.attr, | 590 | &dev_attr_temp1_crit.attr, |
591 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
563 | &dev_attr_temp2_input.attr, | 592 | &dev_attr_temp2_input.attr, |
564 | &dev_attr_temp2_max.attr, | 593 | &dev_attr_temp2_max.attr, |
565 | &dev_attr_temp2_min.attr, | 594 | &dev_attr_temp2_min.attr, |
566 | &dev_attr_temp2_crit.attr, | 595 | &dev_attr_temp2_crit.attr, |
596 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
597 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
567 | 598 | ||
568 | &dev_attr_alarms.attr, | 599 | &dev_attr_alarms.attr, |
569 | &dev_attr_aout_output.attr, | 600 | &dev_attr_aout_output.attr, |
@@ -579,30 +610,38 @@ static struct attribute *lm87_attributes_opt[] = { | |||
579 | &dev_attr_in6_input.attr, | 610 | &dev_attr_in6_input.attr, |
580 | &dev_attr_in6_min.attr, | 611 | &dev_attr_in6_min.attr, |
581 | &dev_attr_in6_max.attr, | 612 | &dev_attr_in6_max.attr, |
613 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
582 | 614 | ||
583 | &dev_attr_fan1_input.attr, | 615 | &dev_attr_fan1_input.attr, |
584 | &dev_attr_fan1_min.attr, | 616 | &dev_attr_fan1_min.attr, |
585 | &dev_attr_fan1_div.attr, | 617 | &dev_attr_fan1_div.attr, |
618 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
586 | 619 | ||
587 | &dev_attr_in7_input.attr, | 620 | &dev_attr_in7_input.attr, |
588 | &dev_attr_in7_min.attr, | 621 | &dev_attr_in7_min.attr, |
589 | &dev_attr_in7_max.attr, | 622 | &dev_attr_in7_max.attr, |
623 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
590 | 624 | ||
591 | &dev_attr_fan2_input.attr, | 625 | &dev_attr_fan2_input.attr, |
592 | &dev_attr_fan2_min.attr, | 626 | &dev_attr_fan2_min.attr, |
593 | &dev_attr_fan2_div.attr, | 627 | &dev_attr_fan2_div.attr, |
628 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
594 | 629 | ||
595 | &dev_attr_temp3_input.attr, | 630 | &dev_attr_temp3_input.attr, |
596 | &dev_attr_temp3_max.attr, | 631 | &dev_attr_temp3_max.attr, |
597 | &dev_attr_temp3_min.attr, | 632 | &dev_attr_temp3_min.attr, |
598 | &dev_attr_temp3_crit.attr, | 633 | &dev_attr_temp3_crit.attr, |
634 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
635 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
599 | 636 | ||
600 | &dev_attr_in0_input.attr, | 637 | &dev_attr_in0_input.attr, |
601 | &dev_attr_in0_min.attr, | 638 | &dev_attr_in0_min.attr, |
602 | &dev_attr_in0_max.attr, | 639 | &dev_attr_in0_max.attr, |
640 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | ||
603 | &dev_attr_in5_input.attr, | 641 | &dev_attr_in5_input.attr, |
604 | &dev_attr_in5_min.attr, | 642 | &dev_attr_in5_min.attr, |
605 | &dev_attr_in5_max.attr, | 643 | &dev_attr_in5_max.attr, |
644 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
606 | 645 | ||
607 | &dev_attr_cpu0_vid.attr, | 646 | &dev_attr_cpu0_vid.attr, |
608 | &dev_attr_vrm.attr, | 647 | &dev_attr_vrm.attr, |
@@ -690,7 +729,9 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
690 | || (err = device_create_file(&new_client->dev, | 729 | || (err = device_create_file(&new_client->dev, |
691 | &dev_attr_in6_min)) | 730 | &dev_attr_in6_min)) |
692 | || (err = device_create_file(&new_client->dev, | 731 | || (err = device_create_file(&new_client->dev, |
693 | &dev_attr_in6_max))) | 732 | &dev_attr_in6_max)) |
733 | || (err = device_create_file(&new_client->dev, | ||
734 | &sensor_dev_attr_in6_alarm.dev_attr))) | ||
694 | goto exit_remove; | 735 | goto exit_remove; |
695 | } else { | 736 | } else { |
696 | if ((err = device_create_file(&new_client->dev, | 737 | if ((err = device_create_file(&new_client->dev, |
@@ -698,7 +739,9 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
698 | || (err = device_create_file(&new_client->dev, | 739 | || (err = device_create_file(&new_client->dev, |
699 | &dev_attr_fan1_min)) | 740 | &dev_attr_fan1_min)) |
700 | || (err = device_create_file(&new_client->dev, | 741 | || (err = device_create_file(&new_client->dev, |
701 | &dev_attr_fan1_div))) | 742 | &dev_attr_fan1_div)) |
743 | || (err = device_create_file(&new_client->dev, | ||
744 | &sensor_dev_attr_fan1_alarm.dev_attr))) | ||
702 | goto exit_remove; | 745 | goto exit_remove; |
703 | } | 746 | } |
704 | 747 | ||
@@ -708,7 +751,9 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
708 | || (err = device_create_file(&new_client->dev, | 751 | || (err = device_create_file(&new_client->dev, |
709 | &dev_attr_in7_min)) | 752 | &dev_attr_in7_min)) |
710 | || (err = device_create_file(&new_client->dev, | 753 | || (err = device_create_file(&new_client->dev, |
711 | &dev_attr_in7_max))) | 754 | &dev_attr_in7_max)) |
755 | || (err = device_create_file(&new_client->dev, | ||
756 | &sensor_dev_attr_in7_alarm.dev_attr))) | ||
712 | goto exit_remove; | 757 | goto exit_remove; |
713 | } else { | 758 | } else { |
714 | if ((err = device_create_file(&new_client->dev, | 759 | if ((err = device_create_file(&new_client->dev, |
@@ -716,7 +761,9 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
716 | || (err = device_create_file(&new_client->dev, | 761 | || (err = device_create_file(&new_client->dev, |
717 | &dev_attr_fan2_min)) | 762 | &dev_attr_fan2_min)) |
718 | || (err = device_create_file(&new_client->dev, | 763 | || (err = device_create_file(&new_client->dev, |
719 | &dev_attr_fan2_div))) | 764 | &dev_attr_fan2_div)) |
765 | || (err = device_create_file(&new_client->dev, | ||
766 | &sensor_dev_attr_fan2_alarm.dev_attr))) | ||
720 | goto exit_remove; | 767 | goto exit_remove; |
721 | } | 768 | } |
722 | 769 | ||
@@ -728,7 +775,11 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
728 | || (err = device_create_file(&new_client->dev, | 775 | || (err = device_create_file(&new_client->dev, |
729 | &dev_attr_temp3_min)) | 776 | &dev_attr_temp3_min)) |
730 | || (err = device_create_file(&new_client->dev, | 777 | || (err = device_create_file(&new_client->dev, |
731 | &dev_attr_temp3_crit))) | 778 | &dev_attr_temp3_crit)) |
779 | || (err = device_create_file(&new_client->dev, | ||
780 | &sensor_dev_attr_temp3_alarm.dev_attr)) | ||
781 | || (err = device_create_file(&new_client->dev, | ||
782 | &sensor_dev_attr_temp3_fault.dev_attr))) | ||
732 | goto exit_remove; | 783 | goto exit_remove; |
733 | } else { | 784 | } else { |
734 | if ((err = device_create_file(&new_client->dev, | 785 | if ((err = device_create_file(&new_client->dev, |
@@ -738,11 +789,15 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
738 | || (err = device_create_file(&new_client->dev, | 789 | || (err = device_create_file(&new_client->dev, |
739 | &dev_attr_in0_max)) | 790 | &dev_attr_in0_max)) |
740 | || (err = device_create_file(&new_client->dev, | 791 | || (err = device_create_file(&new_client->dev, |
792 | &sensor_dev_attr_in0_alarm.dev_attr)) | ||
793 | || (err = device_create_file(&new_client->dev, | ||
741 | &dev_attr_in5_input)) | 794 | &dev_attr_in5_input)) |
742 | || (err = device_create_file(&new_client->dev, | 795 | || (err = device_create_file(&new_client->dev, |
743 | &dev_attr_in5_min)) | 796 | &dev_attr_in5_min)) |
744 | || (err = device_create_file(&new_client->dev, | 797 | || (err = device_create_file(&new_client->dev, |
745 | &dev_attr_in5_max))) | 798 | &dev_attr_in5_max)) |
799 | || (err = device_create_file(&new_client->dev, | ||
800 | &sensor_dev_attr_in5_alarm.dev_attr))) | ||
746 | goto exit_remove; | 801 | goto exit_remove; |
747 | } | 802 | } |
748 | 803 | ||
@@ -755,9 +810,9 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
755 | goto exit_remove; | 810 | goto exit_remove; |
756 | } | 811 | } |
757 | 812 | ||
758 | data->class_dev = hwmon_device_register(&new_client->dev); | 813 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
759 | if (IS_ERR(data->class_dev)) { | 814 | if (IS_ERR(data->hwmon_dev)) { |
760 | err = PTR_ERR(data->class_dev); | 815 | err = PTR_ERR(data->hwmon_dev); |
761 | goto exit_remove; | 816 | goto exit_remove; |
762 | } | 817 | } |
763 | 818 | ||
@@ -816,7 +871,7 @@ static int lm87_detach_client(struct i2c_client *client) | |||
816 | struct lm87_data *data = i2c_get_clientdata(client); | 871 | struct lm87_data *data = i2c_get_clientdata(client); |
817 | int err; | 872 | int err; |
818 | 873 | ||
819 | hwmon_device_unregister(data->class_dev); | 874 | hwmon_device_unregister(data->hwmon_dev); |
820 | sysfs_remove_group(&client->dev.kobj, &lm87_group); | 875 | sysfs_remove_group(&client->dev.kobj, &lm87_group); |
821 | sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); | 876 | sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); |
822 | 877 | ||
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index af541d67245d..960df9fa75af 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 | 41 | * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 |
42 | * Note that there is no easy way to differentiate between the three | 42 | * Note that there is no easy way to differentiate between the three |
43 | * variants. The extra address and features of the MAX6659 are not | 43 | * variants. The extra address and features of the MAX6659 are not |
44 | * supported by this driver. | 44 | * supported by this driver. These chips lack the remote temperature |
45 | * offset feature. | ||
45 | * | 46 | * |
46 | * This driver also supports the MAX6680 and MAX6681, two other sensor | 47 | * This driver also supports the MAX6680 and MAX6681, two other sensor |
47 | * chips made by Maxim. These are quite similar to the other Maxim | 48 | * chips made by Maxim. These are quite similar to the other Maxim |
@@ -214,7 +215,7 @@ static struct i2c_driver lm90_driver = { | |||
214 | 215 | ||
215 | struct lm90_data { | 216 | struct lm90_data { |
216 | struct i2c_client client; | 217 | struct i2c_client client; |
217 | struct class_device *class_dev; | 218 | struct device *hwmon_dev; |
218 | struct mutex update_lock; | 219 | struct mutex update_lock; |
219 | char valid; /* zero until following fields are valid */ | 220 | char valid; /* zero until following fields are valid */ |
220 | unsigned long last_updated; /* in jiffies */ | 221 | unsigned long last_updated; /* in jiffies */ |
@@ -226,9 +227,10 @@ struct lm90_data { | |||
226 | 2: local high limit | 227 | 2: local high limit |
227 | 3: local critical limit | 228 | 3: local critical limit |
228 | 4: remote critical limit */ | 229 | 4: remote critical limit */ |
229 | s16 temp11[3]; /* 0: remote input | 230 | s16 temp11[4]; /* 0: remote input |
230 | 1: remote low limit | 231 | 1: remote low limit |
231 | 2: remote high limit */ | 232 | 2: remote high limit |
233 | 3: remote offset (except max6657) */ | ||
232 | u8 temp_hyst; | 234 | u8 temp_hyst; |
233 | u8 alarms; /* bitvector */ | 235 | u8 alarms; /* bitvector */ |
234 | }; | 236 | }; |
@@ -282,11 +284,13 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, | |||
282 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | 284 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, |
283 | const char *buf, size_t count) | 285 | const char *buf, size_t count) |
284 | { | 286 | { |
285 | static const u8 reg[4] = { | 287 | static const u8 reg[6] = { |
286 | LM90_REG_W_REMOTE_LOWH, | 288 | LM90_REG_W_REMOTE_LOWH, |
287 | LM90_REG_W_REMOTE_LOWL, | 289 | LM90_REG_W_REMOTE_LOWL, |
288 | LM90_REG_W_REMOTE_HIGHH, | 290 | LM90_REG_W_REMOTE_HIGHH, |
289 | LM90_REG_W_REMOTE_HIGHL, | 291 | LM90_REG_W_REMOTE_HIGHL, |
292 | LM90_REG_W_REMOTE_OFFSH, | ||
293 | LM90_REG_W_REMOTE_OFFSL, | ||
290 | }; | 294 | }; |
291 | 295 | ||
292 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 296 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
@@ -367,6 +371,8 @@ static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, | |||
367 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, | 371 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, |
368 | set_temphyst, 3); | 372 | set_temphyst, 3); |
369 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); | 373 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); |
374 | static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, | ||
375 | set_temp11, 3); | ||
370 | 376 | ||
371 | /* Individual alarm files */ | 377 | /* Individual alarm files */ |
372 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); | 378 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); |
@@ -652,10 +658,15 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
652 | &dev_attr_pec))) | 658 | &dev_attr_pec))) |
653 | goto exit_remove_files; | 659 | goto exit_remove_files; |
654 | } | 660 | } |
661 | if (data->kind != max6657) { | ||
662 | if ((err = device_create_file(&new_client->dev, | ||
663 | &sensor_dev_attr_temp2_offset.dev_attr))) | ||
664 | goto exit_remove_files; | ||
665 | } | ||
655 | 666 | ||
656 | data->class_dev = hwmon_device_register(&new_client->dev); | 667 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
657 | if (IS_ERR(data->class_dev)) { | 668 | if (IS_ERR(data->hwmon_dev)) { |
658 | err = PTR_ERR(data->class_dev); | 669 | err = PTR_ERR(data->hwmon_dev); |
659 | goto exit_remove_files; | 670 | goto exit_remove_files; |
660 | } | 671 | } |
661 | 672 | ||
@@ -707,9 +718,12 @@ static int lm90_detach_client(struct i2c_client *client) | |||
707 | struct lm90_data *data = i2c_get_clientdata(client); | 718 | struct lm90_data *data = i2c_get_clientdata(client); |
708 | int err; | 719 | int err; |
709 | 720 | ||
710 | hwmon_device_unregister(data->class_dev); | 721 | hwmon_device_unregister(data->hwmon_dev); |
711 | sysfs_remove_group(&client->dev.kobj, &lm90_group); | 722 | sysfs_remove_group(&client->dev.kobj, &lm90_group); |
712 | device_remove_file(&client->dev, &dev_attr_pec); | 723 | device_remove_file(&client->dev, &dev_attr_pec); |
724 | if (data->kind != max6657) | ||
725 | device_remove_file(&client->dev, | ||
726 | &sensor_dev_attr_temp2_offset.dev_attr); | ||
713 | 727 | ||
714 | if ((err = i2c_detach_client(client))) | 728 | if ((err = i2c_detach_client(client))) |
715 | return err; | 729 | return err; |
@@ -763,6 +777,13 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
763 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0 | 777 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0 |
764 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) | 778 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) |
765 | data->temp11[2] = (newh << 8) | l; | 779 | data->temp11[2] = (newh << 8) | l; |
780 | if (data->kind != max6657) { | ||
781 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, | ||
782 | &newh) == 0 | ||
783 | && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, | ||
784 | &l) == 0) | ||
785 | data->temp11[3] = (newh << 8) | l; | ||
786 | } | ||
766 | lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); | 787 | lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); |
767 | 788 | ||
768 | data->last_updated = jiffies; | 789 | data->last_updated = jiffies; |
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index 30b536333f14..61d1bd1d5b6e 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c | |||
@@ -96,7 +96,7 @@ static struct i2c_driver lm92_driver; | |||
96 | /* Client data (each client gets its own) */ | 96 | /* Client data (each client gets its own) */ |
97 | struct lm92_data { | 97 | struct lm92_data { |
98 | struct i2c_client client; | 98 | struct i2c_client client; |
99 | struct class_device *class_dev; | 99 | struct device *hwmon_dev; |
100 | struct mutex update_lock; | 100 | struct mutex update_lock; |
101 | char valid; /* zero until following fields are valid */ | 101 | char valid; /* zero until following fields are valid */ |
102 | unsigned long last_updated; /* in jiffies */ | 102 | unsigned long last_updated; /* in jiffies */ |
@@ -379,9 +379,9 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) | |||
379 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group))) | 379 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group))) |
380 | goto exit_detach; | 380 | goto exit_detach; |
381 | 381 | ||
382 | data->class_dev = hwmon_device_register(&new_client->dev); | 382 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
383 | if (IS_ERR(data->class_dev)) { | 383 | if (IS_ERR(data->hwmon_dev)) { |
384 | err = PTR_ERR(data->class_dev); | 384 | err = PTR_ERR(data->hwmon_dev); |
385 | goto exit_remove; | 385 | goto exit_remove; |
386 | } | 386 | } |
387 | 387 | ||
@@ -409,7 +409,7 @@ static int lm92_detach_client(struct i2c_client *client) | |||
409 | struct lm92_data *data = i2c_get_clientdata(client); | 409 | struct lm92_data *data = i2c_get_clientdata(client); |
410 | int err; | 410 | int err; |
411 | 411 | ||
412 | hwmon_device_unregister(data->class_dev); | 412 | hwmon_device_unregister(data->hwmon_dev); |
413 | sysfs_remove_group(&client->dev.kobj, &lm92_group); | 413 | sysfs_remove_group(&client->dev.kobj, &lm92_group); |
414 | 414 | ||
415 | if ((err = i2c_detach_client(client))) | 415 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index d84f8bf6f284..ea61946a4bf7 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c | |||
@@ -201,7 +201,7 @@ struct block1_t { | |||
201 | */ | 201 | */ |
202 | struct lm93_data { | 202 | struct lm93_data { |
203 | struct i2c_client client; | 203 | struct i2c_client client; |
204 | struct class_device *class_dev; | 204 | struct device *hwmon_dev; |
205 | 205 | ||
206 | struct mutex update_lock; | 206 | struct mutex update_lock; |
207 | unsigned long last_updated; /* In jiffies */ | 207 | unsigned long last_updated; /* In jiffies */ |
@@ -413,7 +413,7 @@ static int LM93_TEMP_FROM_REG(u8 reg) | |||
413 | 413 | ||
414 | /* TEMP: 1/1000 degrees C (-128C to +127C) | 414 | /* TEMP: 1/1000 degrees C (-128C to +127C) |
415 | REG: 1C/bit, two's complement */ | 415 | REG: 1C/bit, two's complement */ |
416 | static u8 LM93_TEMP_TO_REG(int temp) | 416 | static u8 LM93_TEMP_TO_REG(long temp) |
417 | { | 417 | { |
418 | int ntemp = SENSORS_LIMIT(temp, LM93_TEMP_MIN, LM93_TEMP_MAX); | 418 | int ntemp = SENSORS_LIMIT(temp, LM93_TEMP_MIN, LM93_TEMP_MAX); |
419 | ntemp += (ntemp<0 ? -500 : 500); | 419 | ntemp += (ntemp<0 ? -500 : 500); |
@@ -1268,7 +1268,7 @@ static ssize_t store_temp_min(struct device *dev, struct device_attribute *attr, | |||
1268 | int nr = (to_sensor_dev_attr(attr))->index; | 1268 | int nr = (to_sensor_dev_attr(attr))->index; |
1269 | struct i2c_client *client = to_i2c_client(dev); | 1269 | struct i2c_client *client = to_i2c_client(dev); |
1270 | struct lm93_data *data = i2c_get_clientdata(client); | 1270 | struct lm93_data *data = i2c_get_clientdata(client); |
1271 | u32 val = simple_strtoul(buf, NULL, 10); | 1271 | long val = simple_strtol(buf, NULL, 10); |
1272 | 1272 | ||
1273 | mutex_lock(&data->update_lock); | 1273 | mutex_lock(&data->update_lock); |
1274 | data->temp_lim[nr].min = LM93_TEMP_TO_REG(val); | 1274 | data->temp_lim[nr].min = LM93_TEMP_TO_REG(val); |
@@ -1298,7 +1298,7 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute *attr, | |||
1298 | int nr = (to_sensor_dev_attr(attr))->index; | 1298 | int nr = (to_sensor_dev_attr(attr))->index; |
1299 | struct i2c_client *client = to_i2c_client(dev); | 1299 | struct i2c_client *client = to_i2c_client(dev); |
1300 | struct lm93_data *data = i2c_get_clientdata(client); | 1300 | struct lm93_data *data = i2c_get_clientdata(client); |
1301 | u32 val = simple_strtoul(buf, NULL, 10); | 1301 | long val = simple_strtol(buf, NULL, 10); |
1302 | 1302 | ||
1303 | mutex_lock(&data->update_lock); | 1303 | mutex_lock(&data->update_lock); |
1304 | data->temp_lim[nr].max = LM93_TEMP_TO_REG(val); | 1304 | data->temp_lim[nr].max = LM93_TEMP_TO_REG(val); |
@@ -1329,7 +1329,7 @@ static ssize_t store_temp_auto_base(struct device *dev, | |||
1329 | int nr = (to_sensor_dev_attr(attr))->index; | 1329 | int nr = (to_sensor_dev_attr(attr))->index; |
1330 | struct i2c_client *client = to_i2c_client(dev); | 1330 | struct i2c_client *client = to_i2c_client(dev); |
1331 | struct lm93_data *data = i2c_get_clientdata(client); | 1331 | struct lm93_data *data = i2c_get_clientdata(client); |
1332 | u32 val = simple_strtoul(buf, NULL, 10); | 1332 | long val = simple_strtol(buf, NULL, 10); |
1333 | 1333 | ||
1334 | mutex_lock(&data->update_lock); | 1334 | mutex_lock(&data->update_lock); |
1335 | data->block10.base[nr] = LM93_TEMP_TO_REG(val); | 1335 | data->block10.base[nr] = LM93_TEMP_TO_REG(val); |
@@ -1360,7 +1360,7 @@ static ssize_t store_temp_auto_boost(struct device *dev, | |||
1360 | int nr = (to_sensor_dev_attr(attr))->index; | 1360 | int nr = (to_sensor_dev_attr(attr))->index; |
1361 | struct i2c_client *client = to_i2c_client(dev); | 1361 | struct i2c_client *client = to_i2c_client(dev); |
1362 | struct lm93_data *data = i2c_get_clientdata(client); | 1362 | struct lm93_data *data = i2c_get_clientdata(client); |
1363 | u32 val = simple_strtoul(buf, NULL, 10); | 1363 | long val = simple_strtol(buf, NULL, 10); |
1364 | 1364 | ||
1365 | mutex_lock(&data->update_lock); | 1365 | mutex_lock(&data->update_lock); |
1366 | data->boost[nr] = LM93_TEMP_TO_REG(val); | 1366 | data->boost[nr] = LM93_TEMP_TO_REG(val); |
@@ -2078,8 +2078,8 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, | |||
2078 | return sprintf(buf,"%d\n",LM93_VID_FROM_REG(data->vid[nr])); | 2078 | return sprintf(buf,"%d\n",LM93_VID_FROM_REG(data->vid[nr])); |
2079 | } | 2079 | } |
2080 | 2080 | ||
2081 | static SENSOR_DEVICE_ATTR(vid1, S_IRUGO, show_vid, NULL, 0); | 2081 | static SENSOR_DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL, 0); |
2082 | static SENSOR_DEVICE_ATTR(vid2, S_IRUGO, show_vid, NULL, 1); | 2082 | static SENSOR_DEVICE_ATTR(cpu1_vid, S_IRUGO, show_vid, NULL, 1); |
2083 | 2083 | ||
2084 | static ssize_t show_prochot(struct device *dev, struct device_attribute *attr, | 2084 | static ssize_t show_prochot(struct device *dev, struct device_attribute *attr, |
2085 | char *buf) | 2085 | char *buf) |
@@ -2431,8 +2431,8 @@ static struct attribute *lm93_attrs[] = { | |||
2431 | &sensor_dev_attr_pwm2_auto_spinup_time.dev_attr.attr, | 2431 | &sensor_dev_attr_pwm2_auto_spinup_time.dev_attr.attr, |
2432 | &dev_attr_pwm_auto_prochot_ramp.attr, | 2432 | &dev_attr_pwm_auto_prochot_ramp.attr, |
2433 | &dev_attr_pwm_auto_vrdhot_ramp.attr, | 2433 | &dev_attr_pwm_auto_vrdhot_ramp.attr, |
2434 | &sensor_dev_attr_vid1.dev_attr.attr, | 2434 | &sensor_dev_attr_cpu0_vid.dev_attr.attr, |
2435 | &sensor_dev_attr_vid2.dev_attr.attr, | 2435 | &sensor_dev_attr_cpu1_vid.dev_attr.attr, |
2436 | &sensor_dev_attr_prochot1.dev_attr.attr, | 2436 | &sensor_dev_attr_prochot1.dev_attr.attr, |
2437 | &sensor_dev_attr_prochot2.dev_attr.attr, | 2437 | &sensor_dev_attr_prochot2.dev_attr.attr, |
2438 | &sensor_dev_attr_prochot1_avg.dev_attr.attr, | 2438 | &sensor_dev_attr_prochot1_avg.dev_attr.attr, |
@@ -2590,11 +2590,11 @@ static int lm93_detect(struct i2c_adapter *adapter, int address, int kind) | |||
2590 | goto err_detach; | 2590 | goto err_detach; |
2591 | 2591 | ||
2592 | /* Register hwmon driver class */ | 2592 | /* Register hwmon driver class */ |
2593 | data->class_dev = hwmon_device_register(&client->dev); | 2593 | data->hwmon_dev = hwmon_device_register(&client->dev); |
2594 | if ( !IS_ERR(data->class_dev)) | 2594 | if ( !IS_ERR(data->hwmon_dev)) |
2595 | return 0; | 2595 | return 0; |
2596 | 2596 | ||
2597 | err = PTR_ERR(data->class_dev); | 2597 | err = PTR_ERR(data->hwmon_dev); |
2598 | dev_err(&client->dev, "error registering hwmon device.\n"); | 2598 | dev_err(&client->dev, "error registering hwmon device.\n"); |
2599 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); | 2599 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); |
2600 | err_detach: | 2600 | err_detach: |
@@ -2619,7 +2619,7 @@ static int lm93_detach_client(struct i2c_client *client) | |||
2619 | struct lm93_data *data = i2c_get_clientdata(client); | 2619 | struct lm93_data *data = i2c_get_clientdata(client); |
2620 | int err = 0; | 2620 | int err = 0; |
2621 | 2621 | ||
2622 | hwmon_device_unregister(data->class_dev); | 2622 | hwmon_device_unregister(data->hwmon_dev); |
2623 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); | 2623 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); |
2624 | 2624 | ||
2625 | err = i2c_detach_client(client); | 2625 | err = i2c_detach_client(client); |
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 2f58f651f03a..38a44c3d6cee 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c | |||
@@ -105,7 +105,7 @@ static struct i2c_driver max1619_driver = { | |||
105 | 105 | ||
106 | struct max1619_data { | 106 | struct max1619_data { |
107 | struct i2c_client client; | 107 | struct i2c_client client; |
108 | struct class_device *class_dev; | 108 | struct device *hwmon_dev; |
109 | struct mutex update_lock; | 109 | struct mutex update_lock; |
110 | char valid; /* zero until following fields are valid */ | 110 | char valid; /* zero until following fields are valid */ |
111 | unsigned long last_updated; /* in jiffies */ | 111 | unsigned long last_updated; /* in jiffies */ |
@@ -293,9 +293,9 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) | |||
293 | if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) | 293 | if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) |
294 | goto exit_detach; | 294 | goto exit_detach; |
295 | 295 | ||
296 | data->class_dev = hwmon_device_register(&new_client->dev); | 296 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
297 | if (IS_ERR(data->class_dev)) { | 297 | if (IS_ERR(data->hwmon_dev)) { |
298 | err = PTR_ERR(data->class_dev); | 298 | err = PTR_ERR(data->hwmon_dev); |
299 | goto exit_remove_files; | 299 | goto exit_remove_files; |
300 | } | 300 | } |
301 | 301 | ||
@@ -331,7 +331,7 @@ static int max1619_detach_client(struct i2c_client *client) | |||
331 | struct max1619_data *data = i2c_get_clientdata(client); | 331 | struct max1619_data *data = i2c_get_clientdata(client); |
332 | int err; | 332 | int err; |
333 | 333 | ||
334 | hwmon_device_unregister(data->class_dev); | 334 | hwmon_device_unregister(data->hwmon_dev); |
335 | sysfs_remove_group(&client->dev.kobj, &max1619_group); | 335 | sysfs_remove_group(&client->dev.kobj, &max1619_group); |
336 | 336 | ||
337 | if ((err = i2c_detach_client(client))) | 337 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 8415664f33c2..755570c1f4eb 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
@@ -128,7 +128,7 @@ static struct i2c_driver max6650_driver = { | |||
128 | struct max6650_data | 128 | struct max6650_data |
129 | { | 129 | { |
130 | struct i2c_client client; | 130 | struct i2c_client client; |
131 | struct class_device *class_dev; | 131 | struct device *hwmon_dev; |
132 | struct mutex update_lock; | 132 | struct mutex update_lock; |
133 | char valid; /* zero until following fields are valid */ | 133 | char valid; /* zero until following fields are valid */ |
134 | unsigned long last_updated; /* in jiffies */ | 134 | unsigned long last_updated; /* in jiffies */ |
@@ -523,11 +523,11 @@ static int max6650_detect(struct i2c_adapter *adapter, int address, int kind) | |||
523 | if (err) | 523 | if (err) |
524 | goto err_detach; | 524 | goto err_detach; |
525 | 525 | ||
526 | data->class_dev = hwmon_device_register(&client->dev); | 526 | data->hwmon_dev = hwmon_device_register(&client->dev); |
527 | if (!IS_ERR(data->class_dev)) | 527 | if (!IS_ERR(data->hwmon_dev)) |
528 | return 0; | 528 | return 0; |
529 | 529 | ||
530 | err = PTR_ERR(data->class_dev); | 530 | err = PTR_ERR(data->hwmon_dev); |
531 | dev_err(&client->dev, "error registering hwmon device.\n"); | 531 | dev_err(&client->dev, "error registering hwmon device.\n"); |
532 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); | 532 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); |
533 | err_detach: | 533 | err_detach: |
@@ -543,7 +543,7 @@ static int max6650_detach_client(struct i2c_client *client) | |||
543 | int err; | 543 | int err; |
544 | 544 | ||
545 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); | 545 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); |
546 | hwmon_device_unregister(data->class_dev); | 546 | hwmon_device_unregister(data->hwmon_dev); |
547 | err = i2c_detach_client(client); | 547 | err = i2c_detach_client(client); |
548 | if (!err) | 548 | if (!err) |
549 | kfree(data); | 549 | kfree(data); |
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index f57c75d59a5b..9d660133d517 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -180,7 +180,7 @@ static inline u8 PWM_TO_REG(int val, int inv) | |||
180 | 180 | ||
181 | struct pc87360_data { | 181 | struct pc87360_data { |
182 | const char *name; | 182 | const char *name; |
183 | struct class_device *class_dev; | 183 | struct device *hwmon_dev; |
184 | struct mutex lock; | 184 | struct mutex lock; |
185 | struct mutex update_lock; | 185 | struct mutex update_lock; |
186 | char valid; /* !=0 if following fields are valid */ | 186 | char valid; /* !=0 if following fields are valid */ |
@@ -500,7 +500,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | |||
500 | 500 | ||
501 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) | 501 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) |
502 | { | 502 | { |
503 | struct pc87360_data *data = pc87360_update_device(dev); | 503 | struct pc87360_data *data = dev_get_drvdata(dev); |
504 | return sprintf(buf, "%u\n", data->vrm); | 504 | return sprintf(buf, "%u\n", data->vrm); |
505 | } | 505 | } |
506 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 506 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
@@ -1054,9 +1054,9 @@ static int __devinit pc87360_probe(struct platform_device *pdev) | |||
1054 | if ((err = device_create_file(dev, &dev_attr_name))) | 1054 | if ((err = device_create_file(dev, &dev_attr_name))) |
1055 | goto ERROR3; | 1055 | goto ERROR3; |
1056 | 1056 | ||
1057 | data->class_dev = hwmon_device_register(dev); | 1057 | data->hwmon_dev = hwmon_device_register(dev); |
1058 | if (IS_ERR(data->class_dev)) { | 1058 | if (IS_ERR(data->hwmon_dev)) { |
1059 | err = PTR_ERR(data->class_dev); | 1059 | err = PTR_ERR(data->hwmon_dev); |
1060 | goto ERROR3; | 1060 | goto ERROR3; |
1061 | } | 1061 | } |
1062 | return 0; | 1062 | return 0; |
@@ -1083,7 +1083,7 @@ static int __devexit pc87360_remove(struct platform_device *pdev) | |||
1083 | struct pc87360_data *data = platform_get_drvdata(pdev); | 1083 | struct pc87360_data *data = platform_get_drvdata(pdev); |
1084 | int i; | 1084 | int i; |
1085 | 1085 | ||
1086 | hwmon_device_unregister(data->class_dev); | 1086 | hwmon_device_unregister(data->hwmon_dev); |
1087 | 1087 | ||
1088 | device_remove_file(&pdev->dev, &dev_attr_name); | 1088 | device_remove_file(&pdev->dev, &dev_attr_name); |
1089 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_temp_group); | 1089 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_temp_group); |
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 2915bc4ad0d5..d40509ad6ae6 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c | |||
@@ -42,7 +42,7 @@ static struct platform_device *pdev; | |||
42 | device is using banked registers) and the register cache (needed to keep | 42 | device is using banked registers) and the register cache (needed to keep |
43 | the data in the registers and the cache in sync at any time). */ | 43 | the data in the registers and the cache in sync at any time). */ |
44 | struct pc87427_data { | 44 | struct pc87427_data { |
45 | struct class_device *class_dev; | 45 | struct device *hwmon_dev; |
46 | struct mutex lock; | 46 | struct mutex lock; |
47 | int address[2]; | 47 | int address[2]; |
48 | const char *name; | 48 | const char *name; |
@@ -454,9 +454,9 @@ static int __devinit pc87427_probe(struct platform_device *pdev) | |||
454 | goto exit_remove_files; | 454 | goto exit_remove_files; |
455 | } | 455 | } |
456 | 456 | ||
457 | data->class_dev = hwmon_device_register(&pdev->dev); | 457 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
458 | if (IS_ERR(data->class_dev)) { | 458 | if (IS_ERR(data->hwmon_dev)) { |
459 | err = PTR_ERR(data->class_dev); | 459 | err = PTR_ERR(data->hwmon_dev); |
460 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); | 460 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); |
461 | goto exit_remove_files; | 461 | goto exit_remove_files; |
462 | } | 462 | } |
@@ -484,7 +484,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev) | |||
484 | struct resource *res; | 484 | struct resource *res; |
485 | int i; | 485 | int i; |
486 | 486 | ||
487 | hwmon_device_unregister(data->class_dev); | 487 | hwmon_device_unregister(data->hwmon_dev); |
488 | device_remove_file(&pdev->dev, &dev_attr_name); | 488 | device_remove_file(&pdev->dev, &dev_attr_name); |
489 | for (i = 0; i < 8; i++) { | 489 | for (i = 0; i < 8; i++) { |
490 | if (!(data->fan_enabled & (1 << i))) | 490 | if (!(data->fan_enabled & (1 << i))) |
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 92956eb3f3c1..79a5376a8d81 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c | |||
@@ -163,7 +163,7 @@ static inline u8 DIV_TO_REG(int val) | |||
163 | struct sis5595_data { | 163 | struct sis5595_data { |
164 | unsigned short addr; | 164 | unsigned short addr; |
165 | const char *name; | 165 | const char *name; |
166 | struct class_device *class_dev; | 166 | struct device *hwmon_dev; |
167 | struct mutex lock; | 167 | struct mutex lock; |
168 | 168 | ||
169 | struct mutex update_lock; | 169 | struct mutex update_lock; |
@@ -517,7 +517,7 @@ static int __devinit sis5595_probe(struct platform_device *pdev) | |||
517 | platform_set_drvdata(pdev, data); | 517 | platform_set_drvdata(pdev, data); |
518 | 518 | ||
519 | /* Check revision and pin registers to determine whether 4 or 5 voltages */ | 519 | /* Check revision and pin registers to determine whether 4 or 5 voltages */ |
520 | pci_read_config_byte(s_bridge, PCI_REVISION_ID, &data->revision); | 520 | data->revision = s_bridge->revision; |
521 | /* 4 voltages, 1 temp */ | 521 | /* 4 voltages, 1 temp */ |
522 | data->maxins = 3; | 522 | data->maxins = 3; |
523 | if (data->revision >= REV2MIN) { | 523 | if (data->revision >= REV2MIN) { |
@@ -557,9 +557,9 @@ static int __devinit sis5595_probe(struct platform_device *pdev) | |||
557 | goto exit_remove_files; | 557 | goto exit_remove_files; |
558 | } | 558 | } |
559 | 559 | ||
560 | data->class_dev = hwmon_device_register(&pdev->dev); | 560 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
561 | if (IS_ERR(data->class_dev)) { | 561 | if (IS_ERR(data->hwmon_dev)) { |
562 | err = PTR_ERR(data->class_dev); | 562 | err = PTR_ERR(data->hwmon_dev); |
563 | goto exit_remove_files; | 563 | goto exit_remove_files; |
564 | } | 564 | } |
565 | 565 | ||
@@ -580,7 +580,7 @@ static int __devexit sis5595_remove(struct platform_device *pdev) | |||
580 | { | 580 | { |
581 | struct sis5595_data *data = platform_get_drvdata(pdev); | 581 | struct sis5595_data *data = platform_get_drvdata(pdev); |
582 | 582 | ||
583 | hwmon_device_unregister(data->class_dev); | 583 | hwmon_device_unregister(data->hwmon_dev); |
584 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); | 584 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); |
585 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt); | 585 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt); |
586 | 586 | ||
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 45266b30ce1d..0b57d2ea2cf7 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c | |||
@@ -94,7 +94,7 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80}; | |||
94 | struct smsc47b397_data { | 94 | struct smsc47b397_data { |
95 | unsigned short addr; | 95 | unsigned short addr; |
96 | const char *name; | 96 | const char *name; |
97 | struct class_device *class_dev; | 97 | struct device *hwmon_dev; |
98 | struct mutex lock; | 98 | struct mutex lock; |
99 | 99 | ||
100 | struct mutex update_lock; | 100 | struct mutex update_lock; |
@@ -222,7 +222,7 @@ static int __devexit smsc47b397_remove(struct platform_device *pdev) | |||
222 | struct smsc47b397_data *data = platform_get_drvdata(pdev); | 222 | struct smsc47b397_data *data = platform_get_drvdata(pdev); |
223 | struct resource *res; | 223 | struct resource *res; |
224 | 224 | ||
225 | hwmon_device_unregister(data->class_dev); | 225 | hwmon_device_unregister(data->hwmon_dev); |
226 | sysfs_remove_group(&pdev->dev.kobj, &smsc47b397_group); | 226 | sysfs_remove_group(&pdev->dev.kobj, &smsc47b397_group); |
227 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 227 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
228 | release_region(res->start, SMSC_EXTENT); | 228 | release_region(res->start, SMSC_EXTENT); |
@@ -272,9 +272,9 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev) | |||
272 | if ((err = sysfs_create_group(&dev->kobj, &smsc47b397_group))) | 272 | if ((err = sysfs_create_group(&dev->kobj, &smsc47b397_group))) |
273 | goto error_free; | 273 | goto error_free; |
274 | 274 | ||
275 | data->class_dev = hwmon_device_register(dev); | 275 | data->hwmon_dev = hwmon_device_register(dev); |
276 | if (IS_ERR(data->class_dev)) { | 276 | if (IS_ERR(data->hwmon_dev)) { |
277 | err = PTR_ERR(data->class_dev); | 277 | err = PTR_ERR(data->hwmon_dev); |
278 | goto error_remove; | 278 | goto error_remove; |
279 | } | 279 | } |
280 | 280 | ||
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index d3181967f167..a10a380868e2 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -116,7 +116,7 @@ struct smsc47m1_data { | |||
116 | unsigned short addr; | 116 | unsigned short addr; |
117 | const char *name; | 117 | const char *name; |
118 | enum chips type; | 118 | enum chips type; |
119 | struct class_device *class_dev; | 119 | struct device *hwmon_dev; |
120 | 120 | ||
121 | struct mutex update_lock; | 121 | struct mutex update_lock; |
122 | unsigned long last_updated; /* In jiffies */ | 122 | unsigned long last_updated; /* In jiffies */ |
@@ -553,7 +553,7 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) | |||
553 | || (err = device_create_file(dev, | 553 | || (err = device_create_file(dev, |
554 | &sensor_dev_attr_fan3_div.dev_attr))) | 554 | &sensor_dev_attr_fan3_div.dev_attr))) |
555 | goto error_remove_files; | 555 | goto error_remove_files; |
556 | } else | 556 | } else if (data->type == smsc47m2) |
557 | dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n"); | 557 | dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n"); |
558 | 558 | ||
559 | if (pwm1) { | 559 | if (pwm1) { |
@@ -580,7 +580,7 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) | |||
580 | || (err = device_create_file(dev, | 580 | || (err = device_create_file(dev, |
581 | &sensor_dev_attr_pwm3_enable.dev_attr))) | 581 | &sensor_dev_attr_pwm3_enable.dev_attr))) |
582 | goto error_remove_files; | 582 | goto error_remove_files; |
583 | } else | 583 | } else if (data->type == smsc47m2) |
584 | dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n"); | 584 | dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n"); |
585 | 585 | ||
586 | if ((err = device_create_file(dev, &dev_attr_alarms))) | 586 | if ((err = device_create_file(dev, &dev_attr_alarms))) |
@@ -588,9 +588,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) | |||
588 | if ((err = device_create_file(dev, &dev_attr_name))) | 588 | if ((err = device_create_file(dev, &dev_attr_name))) |
589 | goto error_remove_files; | 589 | goto error_remove_files; |
590 | 590 | ||
591 | data->class_dev = hwmon_device_register(dev); | 591 | data->hwmon_dev = hwmon_device_register(dev); |
592 | if (IS_ERR(data->class_dev)) { | 592 | if (IS_ERR(data->hwmon_dev)) { |
593 | err = PTR_ERR(data->class_dev); | 593 | err = PTR_ERR(data->hwmon_dev); |
594 | goto error_remove_files; | 594 | goto error_remove_files; |
595 | } | 595 | } |
596 | 596 | ||
@@ -611,7 +611,7 @@ static int __devexit smsc47m1_remove(struct platform_device *pdev) | |||
611 | struct smsc47m1_data *data = platform_get_drvdata(pdev); | 611 | struct smsc47m1_data *data = platform_get_drvdata(pdev); |
612 | struct resource *res; | 612 | struct resource *res; |
613 | 613 | ||
614 | hwmon_device_unregister(data->class_dev); | 614 | hwmon_device_unregister(data->hwmon_dev); |
615 | sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); | 615 | sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); |
616 | 616 | ||
617 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 617 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index d3a3ba04cb0f..b87552652588 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c | |||
@@ -97,7 +97,7 @@ static inline int TEMP_FROM_REG(s8 val) | |||
97 | 97 | ||
98 | struct smsc47m192_data { | 98 | struct smsc47m192_data { |
99 | struct i2c_client client; | 99 | struct i2c_client client; |
100 | struct class_device *class_dev; | 100 | struct device *hwmon_dev; |
101 | struct mutex update_lock; | 101 | struct mutex update_lock; |
102 | char valid; /* !=0 if following fields are valid */ | 102 | char valid; /* !=0 if following fields are valid */ |
103 | unsigned long last_updated; /* In jiffies */ | 103 | unsigned long last_updated; /* In jiffies */ |
@@ -334,7 +334,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | |||
334 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, | 334 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, |
335 | char *buf) | 335 | char *buf) |
336 | { | 336 | { |
337 | struct smsc47m192_data *data = smsc47m192_update_device(dev); | 337 | struct smsc47m192_data *data = dev_get_drvdata(dev); |
338 | return sprintf(buf, "%d\n", data->vrm); | 338 | return sprintf(buf, "%d\n", data->vrm); |
339 | } | 339 | } |
340 | 340 | ||
@@ -553,9 +553,9 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address, | |||
553 | goto exit_remove_files; | 553 | goto exit_remove_files; |
554 | } | 554 | } |
555 | 555 | ||
556 | data->class_dev = hwmon_device_register(&client->dev); | 556 | data->hwmon_dev = hwmon_device_register(&client->dev); |
557 | if (IS_ERR(data->class_dev)) { | 557 | if (IS_ERR(data->hwmon_dev)) { |
558 | err = PTR_ERR(data->class_dev); | 558 | err = PTR_ERR(data->hwmon_dev); |
559 | goto exit_remove_files; | 559 | goto exit_remove_files; |
560 | } | 560 | } |
561 | 561 | ||
@@ -577,7 +577,7 @@ static int smsc47m192_detach_client(struct i2c_client *client) | |||
577 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 577 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
578 | int err; | 578 | int err; |
579 | 579 | ||
580 | hwmon_device_unregister(data->class_dev); | 580 | hwmon_device_unregister(data->hwmon_dev); |
581 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); | 581 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); |
582 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); | 582 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); |
583 | 583 | ||
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 9395b52d9b99..04dd7699b3ac 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c | |||
@@ -46,6 +46,11 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs " | |||
46 | #define THMC50_REG_COMPANY_ID 0x3E | 46 | #define THMC50_REG_COMPANY_ID 0x3E |
47 | #define THMC50_REG_DIE_CODE 0x3F | 47 | #define THMC50_REG_DIE_CODE 0x3F |
48 | #define THMC50_REG_ANALOG_OUT 0x19 | 48 | #define THMC50_REG_ANALOG_OUT 0x19 |
49 | /* | ||
50 | * The mirror status register cannot be used as | ||
51 | * reading it does not clear alarms. | ||
52 | */ | ||
53 | #define THMC50_REG_INTR 0x41 | ||
49 | 54 | ||
50 | const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; | 55 | const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; |
51 | const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; | 56 | const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; |
@@ -56,7 +61,7 @@ const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; | |||
56 | /* Each client has this additional data */ | 61 | /* Each client has this additional data */ |
57 | struct thmc50_data { | 62 | struct thmc50_data { |
58 | struct i2c_client client; | 63 | struct i2c_client client; |
59 | struct class_device *class_dev; | 64 | struct device *hwmon_dev; |
60 | 65 | ||
61 | struct mutex update_lock; | 66 | struct mutex update_lock; |
62 | enum chips type; | 67 | enum chips type; |
@@ -69,6 +74,7 @@ struct thmc50_data { | |||
69 | s8 temp_max[3]; | 74 | s8 temp_max[3]; |
70 | s8 temp_min[3]; | 75 | s8 temp_min[3]; |
71 | u8 analog_out; | 76 | u8 analog_out; |
77 | u8 alarms; | ||
72 | }; | 78 | }; |
73 | 79 | ||
74 | static int thmc50_attach_adapter(struct i2c_adapter *adapter); | 80 | static int thmc50_attach_adapter(struct i2c_adapter *adapter); |
@@ -180,6 +186,15 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
180 | return count; | 186 | return count; |
181 | } | 187 | } |
182 | 188 | ||
189 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
190 | char *buf) | ||
191 | { | ||
192 | int index = to_sensor_dev_attr(attr)->index; | ||
193 | struct thmc50_data *data = thmc50_update_device(dev); | ||
194 | |||
195 | return sprintf(buf, "%u\n", (data->alarms >> index) & 1); | ||
196 | } | ||
197 | |||
183 | #define temp_reg(offset) \ | 198 | #define temp_reg(offset) \ |
184 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \ | 199 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \ |
185 | NULL, offset - 1); \ | 200 | NULL, offset - 1); \ |
@@ -192,6 +207,12 @@ temp_reg(1); | |||
192 | temp_reg(2); | 207 | temp_reg(2); |
193 | temp_reg(3); | 208 | temp_reg(3); |
194 | 209 | ||
210 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
211 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
212 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
213 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 7); | ||
214 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 2); | ||
215 | |||
195 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_analog_out, | 216 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_analog_out, |
196 | set_analog_out, 0); | 217 | set_analog_out, 0); |
197 | static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0); | 218 | static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0); |
@@ -200,9 +221,12 @@ static struct attribute *thmc50_attributes[] = { | |||
200 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 221 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
201 | &sensor_dev_attr_temp1_min.dev_attr.attr, | 222 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
202 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 223 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
224 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
203 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 225 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
204 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 226 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
205 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 227 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
228 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
229 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
206 | &sensor_dev_attr_pwm1.dev_attr.attr, | 230 | &sensor_dev_attr_pwm1.dev_attr.attr, |
207 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, | 231 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, |
208 | NULL | 232 | NULL |
@@ -213,15 +237,17 @@ static const struct attribute_group thmc50_group = { | |||
213 | }; | 237 | }; |
214 | 238 | ||
215 | /* for ADM1022 3rd temperature mode */ | 239 | /* for ADM1022 3rd temperature mode */ |
216 | static struct attribute *adm1022_attributes[] = { | 240 | static struct attribute *temp3_attributes[] = { |
217 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 241 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
218 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 242 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
219 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 243 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
244 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
245 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
220 | NULL | 246 | NULL |
221 | }; | 247 | }; |
222 | 248 | ||
223 | static const struct attribute_group adm1022_group = { | 249 | static const struct attribute_group temp3_group = { |
224 | .attrs = adm1022_attributes, | 250 | .attrs = temp3_attributes, |
225 | }; | 251 | }; |
226 | 252 | ||
227 | static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) | 253 | static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) |
@@ -233,7 +259,7 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) | |||
233 | struct thmc50_data *data; | 259 | struct thmc50_data *data; |
234 | struct device *dev; | 260 | struct device *dev; |
235 | int err = 0; | 261 | int err = 0; |
236 | const char *type_name = ""; | 262 | const char *type_name; |
237 | 263 | ||
238 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 264 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
239 | pr_debug("thmc50: detect failed, " | 265 | pr_debug("thmc50: detect failed, " |
@@ -283,13 +309,9 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) | |||
283 | pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n"); | 309 | pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n"); |
284 | goto exit_free; | 310 | goto exit_free; |
285 | } | 311 | } |
286 | pr_debug("thmc50: Detected %s (version %x, revision %x)\n", | ||
287 | type_name, (revision >> 4) - 0xc, revision & 0xf); | ||
288 | data->type = kind; | 312 | data->type = kind; |
289 | 313 | ||
290 | if (kind == thmc50) | 314 | if (kind == adm1022) { |
291 | type_name = "thmc50"; | ||
292 | else if (kind == adm1022) { | ||
293 | int id = i2c_adapter_id(client->adapter); | 315 | int id = i2c_adapter_id(client->adapter); |
294 | int i; | 316 | int i; |
295 | 317 | ||
@@ -302,7 +324,11 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) | |||
302 | data->has_temp3 = 1; | 324 | data->has_temp3 = 1; |
303 | break; | 325 | break; |
304 | } | 326 | } |
327 | } else { | ||
328 | type_name = "thmc50"; | ||
305 | } | 329 | } |
330 | pr_debug("thmc50: Detected %s (version %x, revision %x)\n", | ||
331 | type_name, (revision >> 4) - 0xc, revision & 0xf); | ||
306 | 332 | ||
307 | /* Fill in the remaining client fields & put it into the global list */ | 333 | /* Fill in the remaining client fields & put it into the global list */ |
308 | strlcpy(client->name, type_name, I2C_NAME_SIZE); | 334 | strlcpy(client->name, type_name, I2C_NAME_SIZE); |
@@ -319,23 +345,23 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) | |||
319 | goto exit_detach; | 345 | goto exit_detach; |
320 | 346 | ||
321 | /* Register ADM1022 sysfs hooks */ | 347 | /* Register ADM1022 sysfs hooks */ |
322 | if (data->type == adm1022) | 348 | if (data->has_temp3) |
323 | if ((err = sysfs_create_group(&client->dev.kobj, | 349 | if ((err = sysfs_create_group(&client->dev.kobj, |
324 | &adm1022_group))) | 350 | &temp3_group))) |
325 | goto exit_remove_sysfs_thmc50; | 351 | goto exit_remove_sysfs_thmc50; |
326 | 352 | ||
327 | /* Register a new directory entry with module sensors */ | 353 | /* Register a new directory entry with module sensors */ |
328 | data->class_dev = hwmon_device_register(&client->dev); | 354 | data->hwmon_dev = hwmon_device_register(&client->dev); |
329 | if (IS_ERR(data->class_dev)) { | 355 | if (IS_ERR(data->hwmon_dev)) { |
330 | err = PTR_ERR(data->class_dev); | 356 | err = PTR_ERR(data->hwmon_dev); |
331 | goto exit_remove_sysfs; | 357 | goto exit_remove_sysfs; |
332 | } | 358 | } |
333 | 359 | ||
334 | return 0; | 360 | return 0; |
335 | 361 | ||
336 | exit_remove_sysfs: | 362 | exit_remove_sysfs: |
337 | if (data->type == adm1022) | 363 | if (data->has_temp3) |
338 | sysfs_remove_group(&client->dev.kobj, &adm1022_group); | 364 | sysfs_remove_group(&client->dev.kobj, &temp3_group); |
339 | exit_remove_sysfs_thmc50: | 365 | exit_remove_sysfs_thmc50: |
340 | sysfs_remove_group(&client->dev.kobj, &thmc50_group); | 366 | sysfs_remove_group(&client->dev.kobj, &thmc50_group); |
341 | exit_detach: | 367 | exit_detach: |
@@ -358,10 +384,10 @@ static int thmc50_detach_client(struct i2c_client *client) | |||
358 | struct thmc50_data *data = i2c_get_clientdata(client); | 384 | struct thmc50_data *data = i2c_get_clientdata(client); |
359 | int err; | 385 | int err; |
360 | 386 | ||
361 | hwmon_device_unregister(data->class_dev); | 387 | hwmon_device_unregister(data->hwmon_dev); |
362 | sysfs_remove_group(&client->dev.kobj, &thmc50_group); | 388 | sysfs_remove_group(&client->dev.kobj, &thmc50_group); |
363 | if (data->type == adm1022) | 389 | if (data->has_temp3) |
364 | sysfs_remove_group(&client->dev.kobj, &adm1022_group); | 390 | sysfs_remove_group(&client->dev.kobj, &temp3_group); |
365 | 391 | ||
366 | if ((err = i2c_detach_client(client))) | 392 | if ((err = i2c_detach_client(client))) |
367 | return err; | 393 | return err; |
@@ -414,6 +440,8 @@ static struct thmc50_data *thmc50_update_device(struct device *dev) | |||
414 | } | 440 | } |
415 | data->analog_out = | 441 | data->analog_out = |
416 | i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT); | 442 | i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT); |
443 | data->alarms = | ||
444 | i2c_smbus_read_byte_data(client, THMC50_REG_INTR); | ||
417 | data->last_updated = jiffies; | 445 | data->last_updated = jiffies; |
418 | data->valid = 1; | 446 | data->valid = 1; |
419 | } | 447 | } |
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 696c8a2e5374..8f63dada6019 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -294,7 +294,7 @@ static inline long TEMP_FROM_REG10(u16 val) | |||
294 | struct via686a_data { | 294 | struct via686a_data { |
295 | unsigned short addr; | 295 | unsigned short addr; |
296 | const char *name; | 296 | const char *name; |
297 | struct class_device *class_dev; | 297 | struct device *hwmon_dev; |
298 | struct mutex update_lock; | 298 | struct mutex update_lock; |
299 | char valid; /* !=0 if following fields are valid */ | 299 | char valid; /* !=0 if following fields are valid */ |
300 | unsigned long last_updated; /* In jiffies */ | 300 | unsigned long last_updated; /* In jiffies */ |
@@ -627,9 +627,9 @@ static int __devinit via686a_probe(struct platform_device *pdev) | |||
627 | if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group))) | 627 | if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group))) |
628 | goto exit_free; | 628 | goto exit_free; |
629 | 629 | ||
630 | data->class_dev = hwmon_device_register(&pdev->dev); | 630 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
631 | if (IS_ERR(data->class_dev)) { | 631 | if (IS_ERR(data->hwmon_dev)) { |
632 | err = PTR_ERR(data->class_dev); | 632 | err = PTR_ERR(data->hwmon_dev); |
633 | goto exit_remove_files; | 633 | goto exit_remove_files; |
634 | } | 634 | } |
635 | 635 | ||
@@ -648,7 +648,7 @@ static int __devexit via686a_remove(struct platform_device *pdev) | |||
648 | { | 648 | { |
649 | struct via686a_data *data = platform_get_drvdata(pdev); | 649 | struct via686a_data *data = platform_get_drvdata(pdev); |
650 | 650 | ||
651 | hwmon_device_unregister(data->class_dev); | 651 | hwmon_device_unregister(data->hwmon_dev); |
652 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); | 652 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); |
653 | 653 | ||
654 | release_region(data->addr, VIA686A_EXTENT); | 654 | release_region(data->addr, VIA686A_EXTENT); |
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index 9f3e332c5b7f..e69416465e6d 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c | |||
@@ -108,7 +108,7 @@ static const u8 bitalarmfan[] = {6, 7}; | |||
108 | struct vt1211_data { | 108 | struct vt1211_data { |
109 | unsigned short addr; | 109 | unsigned short addr; |
110 | const char *name; | 110 | const char *name; |
111 | struct class_device *class_dev; | 111 | struct device *hwmon_dev; |
112 | 112 | ||
113 | struct mutex update_lock; | 113 | struct mutex update_lock; |
114 | char valid; /* !=0 if following fields are valid */ | 114 | char valid; /* !=0 if following fields are valid */ |
@@ -1191,9 +1191,9 @@ static int __devinit vt1211_probe(struct platform_device *pdev) | |||
1191 | } | 1191 | } |
1192 | 1192 | ||
1193 | /* Register device */ | 1193 | /* Register device */ |
1194 | data->class_dev = hwmon_device_register(dev); | 1194 | data->hwmon_dev = hwmon_device_register(dev); |
1195 | if (IS_ERR(data->class_dev)) { | 1195 | if (IS_ERR(data->hwmon_dev)) { |
1196 | err = PTR_ERR(data->class_dev); | 1196 | err = PTR_ERR(data->hwmon_dev); |
1197 | dev_err(dev, "Class registration failed (%d)\n", err); | 1197 | dev_err(dev, "Class registration failed (%d)\n", err); |
1198 | goto EXIT_DEV_REMOVE_SILENT; | 1198 | goto EXIT_DEV_REMOVE_SILENT; |
1199 | } | 1199 | } |
@@ -1217,7 +1217,7 @@ static int __devexit vt1211_remove(struct platform_device *pdev) | |||
1217 | struct vt1211_data *data = platform_get_drvdata(pdev); | 1217 | struct vt1211_data *data = platform_get_drvdata(pdev); |
1218 | struct resource *res; | 1218 | struct resource *res; |
1219 | 1219 | ||
1220 | hwmon_device_unregister(data->class_dev); | 1220 | hwmon_device_unregister(data->hwmon_dev); |
1221 | vt1211_remove_sysfs(pdev); | 1221 | vt1211_remove_sysfs(pdev); |
1222 | platform_set_drvdata(pdev, NULL); | 1222 | platform_set_drvdata(pdev, NULL); |
1223 | kfree(data); | 1223 | kfree(data); |
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 3e63eaf19041..8806302b5f30 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c | |||
@@ -148,7 +148,7 @@ struct vt8231_data { | |||
148 | const char *name; | 148 | const char *name; |
149 | 149 | ||
150 | struct mutex update_lock; | 150 | struct mutex update_lock; |
151 | struct class_device *class_dev; | 151 | struct device *hwmon_dev; |
152 | char valid; /* !=0 if following fields are valid */ | 152 | char valid; /* !=0 if following fields are valid */ |
153 | unsigned long last_updated; /* In jiffies */ | 153 | unsigned long last_updated; /* In jiffies */ |
154 | 154 | ||
@@ -726,9 +726,9 @@ int vt8231_probe(struct platform_device *pdev) | |||
726 | } | 726 | } |
727 | } | 727 | } |
728 | 728 | ||
729 | data->class_dev = hwmon_device_register(&pdev->dev); | 729 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
730 | if (IS_ERR(data->class_dev)) { | 730 | if (IS_ERR(data->hwmon_dev)) { |
731 | err = PTR_ERR(data->class_dev); | 731 | err = PTR_ERR(data->hwmon_dev); |
732 | goto exit_remove_files; | 732 | goto exit_remove_files; |
733 | } | 733 | } |
734 | return 0; | 734 | return 0; |
@@ -756,7 +756,7 @@ static int __devexit vt8231_remove(struct platform_device *pdev) | |||
756 | struct vt8231_data *data = platform_get_drvdata(pdev); | 756 | struct vt8231_data *data = platform_get_drvdata(pdev); |
757 | int i; | 757 | int i; |
758 | 758 | ||
759 | hwmon_device_unregister(data->class_dev); | 759 | hwmon_device_unregister(data->hwmon_dev); |
760 | 760 | ||
761 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) | 761 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) |
762 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_volts[i]); | 762 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_volts[i]); |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index d9a9ec7dd84a..b15c6a998b72 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -223,7 +223,7 @@ temp1_from_reg(s8 reg) | |||
223 | } | 223 | } |
224 | 224 | ||
225 | static inline s8 | 225 | static inline s8 |
226 | temp1_to_reg(int temp, int min, int max) | 226 | temp1_to_reg(long temp, int min, int max) |
227 | { | 227 | { |
228 | if (temp <= min) | 228 | if (temp <= min) |
229 | return min / 1000; | 229 | return min / 1000; |
@@ -256,7 +256,7 @@ struct w83627ehf_data { | |||
256 | int addr; /* IO base of hw monitor block */ | 256 | int addr; /* IO base of hw monitor block */ |
257 | const char *name; | 257 | const char *name; |
258 | 258 | ||
259 | struct class_device *class_dev; | 259 | struct device *hwmon_dev; |
260 | struct mutex lock; | 260 | struct mutex lock; |
261 | 261 | ||
262 | struct mutex update_lock; | 262 | struct mutex update_lock; |
@@ -805,7 +805,7 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ | |||
805 | const char *buf, size_t count) \ | 805 | const char *buf, size_t count) \ |
806 | { \ | 806 | { \ |
807 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ | 807 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
808 | u32 val = simple_strtoul(buf, NULL, 10); \ | 808 | long val = simple_strtol(buf, NULL, 10); \ |
809 | \ | 809 | \ |
810 | mutex_lock(&data->update_lock); \ | 810 | mutex_lock(&data->update_lock); \ |
811 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ | 811 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ |
@@ -840,7 +840,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ | |||
840 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ | 840 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
841 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 841 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
842 | int nr = sensor_attr->index; \ | 842 | int nr = sensor_attr->index; \ |
843 | u32 val = simple_strtoul(buf, NULL, 10); \ | 843 | long val = simple_strtol(buf, NULL, 10); \ |
844 | \ | 844 | \ |
845 | mutex_lock(&data->update_lock); \ | 845 | mutex_lock(&data->update_lock); \ |
846 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ | 846 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ |
@@ -1384,9 +1384,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1384 | goto exit_remove; | 1384 | goto exit_remove; |
1385 | } | 1385 | } |
1386 | 1386 | ||
1387 | data->class_dev = hwmon_device_register(dev); | 1387 | data->hwmon_dev = hwmon_device_register(dev); |
1388 | if (IS_ERR(data->class_dev)) { | 1388 | if (IS_ERR(data->hwmon_dev)) { |
1389 | err = PTR_ERR(data->class_dev); | 1389 | err = PTR_ERR(data->hwmon_dev); |
1390 | goto exit_remove; | 1390 | goto exit_remove; |
1391 | } | 1391 | } |
1392 | 1392 | ||
@@ -1406,7 +1406,7 @@ static int __devexit w83627ehf_remove(struct platform_device *pdev) | |||
1406 | { | 1406 | { |
1407 | struct w83627ehf_data *data = platform_get_drvdata(pdev); | 1407 | struct w83627ehf_data *data = platform_get_drvdata(pdev); |
1408 | 1408 | ||
1409 | hwmon_device_unregister(data->class_dev); | 1409 | hwmon_device_unregister(data->hwmon_dev); |
1410 | w83627ehf_device_remove_files(&pdev->dev); | 1410 | w83627ehf_device_remove_files(&pdev->dev); |
1411 | release_region(data->addr, IOREGION_LENGTH); | 1411 | release_region(data->addr, IOREGION_LENGTH); |
1412 | platform_set_drvdata(pdev, NULL); | 1412 | platform_set_drvdata(pdev, NULL); |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 7a4a15f4bf8b..a2ccf93521c1 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -263,7 +263,7 @@ static inline u8 FAN_TO_REG(long rpm, int div) | |||
263 | 263 | ||
264 | /* TEMP: 0.001C/bit (-128C to +127C) | 264 | /* TEMP: 0.001C/bit (-128C to +127C) |
265 | REG: 1C/bit, two's complement */ | 265 | REG: 1C/bit, two's complement */ |
266 | static u8 TEMP_TO_REG(int temp) | 266 | static u8 TEMP_TO_REG(long temp) |
267 | { | 267 | { |
268 | int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX); | 268 | int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX); |
269 | ntemp += (ntemp<0 ? -500 : 500); | 269 | ntemp += (ntemp<0 ? -500 : 500); |
@@ -346,7 +346,7 @@ static inline u8 DIV_TO_REG(long val) | |||
346 | struct w83627hf_data { | 346 | struct w83627hf_data { |
347 | unsigned short addr; | 347 | unsigned short addr; |
348 | const char *name; | 348 | const char *name; |
349 | struct class_device *class_dev; | 349 | struct device *hwmon_dev; |
350 | struct mutex lock; | 350 | struct mutex lock; |
351 | enum chips type; | 351 | enum chips type; |
352 | 352 | ||
@@ -372,11 +372,8 @@ struct w83627hf_data { | |||
372 | u8 beep_enable; /* Boolean */ | 372 | u8 beep_enable; /* Boolean */ |
373 | u8 pwm[3]; /* Register value */ | 373 | u8 pwm[3]; /* Register value */ |
374 | u8 pwm_freq[3]; /* Register value */ | 374 | u8 pwm_freq[3]; /* Register value */ |
375 | u16 sens[3]; /* 782D/783S only. | 375 | u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; |
376 | 1 = pentium diode; 2 = 3904 diode; | 376 | 4 = thermistor */ |
377 | 3000-5000 = thermistor beta. | ||
378 | Default = 3435. | ||
379 | Other Betas unimplemented */ | ||
380 | u8 vrm; | 377 | u8 vrm; |
381 | u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ | 378 | u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ |
382 | }; | 379 | }; |
@@ -642,9 +639,9 @@ static ssize_t \ | |||
642 | store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | 639 | store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ |
643 | { \ | 640 | { \ |
644 | struct w83627hf_data *data = dev_get_drvdata(dev); \ | 641 | struct w83627hf_data *data = dev_get_drvdata(dev); \ |
645 | u32 val; \ | 642 | long val; \ |
646 | \ | 643 | \ |
647 | val = simple_strtoul(buf, NULL, 10); \ | 644 | val = simple_strtol(buf, NULL, 10); \ |
648 | \ | 645 | \ |
649 | mutex_lock(&data->update_lock); \ | 646 | mutex_lock(&data->update_lock); \ |
650 | \ | 647 | \ |
@@ -706,7 +703,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | |||
706 | static ssize_t | 703 | static ssize_t |
707 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 704 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
708 | { | 705 | { |
709 | struct w83627hf_data *data = w83627hf_update_device(dev); | 706 | struct w83627hf_data *data = dev_get_drvdata(dev); |
710 | return sprintf(buf, "%ld\n", (long) data->vrm); | 707 | return sprintf(buf, "%ld\n", (long) data->vrm); |
711 | } | 708 | } |
712 | static ssize_t | 709 | static ssize_t |
@@ -1001,7 +998,11 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
1001 | tmp & ~BIT_SCFG2[nr - 1]); | 998 | tmp & ~BIT_SCFG2[nr - 1]); |
1002 | data->sens[nr - 1] = val; | 999 | data->sens[nr - 1] = val; |
1003 | break; | 1000 | break; |
1004 | case W83781D_DEFAULT_BETA: /* thermistor */ | 1001 | case W83781D_DEFAULT_BETA: |
1002 | dev_warn(dev, "Sensor type %d is deprecated, please use 4 " | ||
1003 | "instead\n", W83781D_DEFAULT_BETA); | ||
1004 | /* fall through */ | ||
1005 | case 4: /* thermistor */ | ||
1005 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); | 1006 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); |
1006 | w83627hf_write_value(data, W83781D_REG_SCFG1, | 1007 | w83627hf_write_value(data, W83781D_REG_SCFG1, |
1007 | tmp & ~BIT_SCFG1[nr - 1]); | 1008 | tmp & ~BIT_SCFG1[nr - 1]); |
@@ -1009,8 +1010,8 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
1009 | break; | 1010 | break; |
1010 | default: | 1011 | default: |
1011 | dev_err(dev, | 1012 | dev_err(dev, |
1012 | "Invalid sensor type %ld; must be 1, 2, or %d\n", | 1013 | "Invalid sensor type %ld; must be 1, 2, or 4\n", |
1013 | (long) val, W83781D_DEFAULT_BETA); | 1014 | (long) val); |
1014 | break; | 1015 | break; |
1015 | } | 1016 | } |
1016 | 1017 | ||
@@ -1294,9 +1295,9 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1294 | || (err = device_create_file(dev, &dev_attr_pwm3_freq))) | 1295 | || (err = device_create_file(dev, &dev_attr_pwm3_freq))) |
1295 | goto ERROR4; | 1296 | goto ERROR4; |
1296 | 1297 | ||
1297 | data->class_dev = hwmon_device_register(dev); | 1298 | data->hwmon_dev = hwmon_device_register(dev); |
1298 | if (IS_ERR(data->class_dev)) { | 1299 | if (IS_ERR(data->hwmon_dev)) { |
1299 | err = PTR_ERR(data->class_dev); | 1300 | err = PTR_ERR(data->hwmon_dev); |
1300 | goto ERROR4; | 1301 | goto ERROR4; |
1301 | } | 1302 | } |
1302 | 1303 | ||
@@ -1319,7 +1320,7 @@ static int __devexit w83627hf_remove(struct platform_device *pdev) | |||
1319 | struct w83627hf_data *data = platform_get_drvdata(pdev); | 1320 | struct w83627hf_data *data = platform_get_drvdata(pdev); |
1320 | struct resource *res; | 1321 | struct resource *res; |
1321 | 1322 | ||
1322 | hwmon_device_unregister(data->class_dev); | 1323 | hwmon_device_unregister(data->hwmon_dev); |
1323 | 1324 | ||
1324 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); | 1325 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); |
1325 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); | 1326 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); |
@@ -1513,7 +1514,7 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev) | |||
1513 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); | 1514 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); |
1514 | for (i = 1; i <= 3; i++) { | 1515 | for (i = 1; i <= 3; i++) { |
1515 | if (!(tmp & BIT_SCFG1[i - 1])) { | 1516 | if (!(tmp & BIT_SCFG1[i - 1])) { |
1516 | data->sens[i - 1] = W83781D_DEFAULT_BETA; | 1517 | data->sens[i - 1] = 4; |
1517 | } else { | 1518 | } else { |
1518 | if (w83627hf_read_value | 1519 | if (w83627hf_read_value |
1519 | (data, | 1520 | (data, |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index dcc941a5aaff..a6a1edfe7614 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -220,7 +220,7 @@ DIV_TO_REG(long val, enum chips type) | |||
220 | the driver field to differentiate between I2C and ISA chips. */ | 220 | the driver field to differentiate between I2C and ISA chips. */ |
221 | struct w83781d_data { | 221 | struct w83781d_data { |
222 | struct i2c_client client; | 222 | struct i2c_client client; |
223 | struct class_device *class_dev; | 223 | struct device *hwmon_dev; |
224 | struct mutex lock; | 224 | struct mutex lock; |
225 | enum chips type; | 225 | enum chips type; |
226 | 226 | ||
@@ -251,9 +251,7 @@ struct w83781d_data { | |||
251 | u8 pwm2_enable; /* Boolean */ | 251 | u8 pwm2_enable; /* Boolean */ |
252 | u16 sens[3]; /* 782D/783S only. | 252 | u16 sens[3]; /* 782D/783S only. |
253 | 1 = pentium diode; 2 = 3904 diode; | 253 | 1 = pentium diode; 2 = 3904 diode; |
254 | 3000-5000 = thermistor beta. | 254 | 4 = thermistor */ |
255 | Default = 3435. | ||
256 | Other Betas unimplemented */ | ||
257 | u8 vrm; | 255 | u8 vrm; |
258 | }; | 256 | }; |
259 | 257 | ||
@@ -410,7 +408,7 @@ static ssize_t store_temp_##reg (struct device *dev, \ | |||
410 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ | 408 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ |
411 | struct w83781d_data *data = dev_get_drvdata(dev); \ | 409 | struct w83781d_data *data = dev_get_drvdata(dev); \ |
412 | int nr = attr->index; \ | 410 | int nr = attr->index; \ |
413 | s32 val; \ | 411 | long val; \ |
414 | \ | 412 | \ |
415 | val = simple_strtol(buf, NULL, 10); \ | 413 | val = simple_strtol(buf, NULL, 10); \ |
416 | \ | 414 | \ |
@@ -456,7 +454,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | |||
456 | static ssize_t | 454 | static ssize_t |
457 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 455 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
458 | { | 456 | { |
459 | struct w83781d_data *data = w83781d_update_device(dev); | 457 | struct w83781d_data *data = dev_get_drvdata(dev); |
460 | return sprintf(buf, "%ld\n", (long) data->vrm); | 458 | return sprintf(buf, "%ld\n", (long) data->vrm); |
461 | } | 459 | } |
462 | 460 | ||
@@ -483,6 +481,39 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
483 | 481 | ||
484 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); | 482 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); |
485 | 483 | ||
484 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
485 | char *buf) | ||
486 | { | ||
487 | struct w83781d_data *data = w83781d_update_device(dev); | ||
488 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
489 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); | ||
490 | } | ||
491 | |||
492 | /* The W83781D has a single alarm bit for temp2 and temp3 */ | ||
493 | static ssize_t show_temp3_alarm(struct device *dev, | ||
494 | struct device_attribute *attr, char *buf) | ||
495 | { | ||
496 | struct w83781d_data *data = w83781d_update_device(dev); | ||
497 | int bitnr = (data->type == w83781d) ? 5 : 13; | ||
498 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); | ||
499 | } | ||
500 | |||
501 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
502 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
503 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
504 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
505 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
506 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
507 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10); | ||
508 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16); | ||
509 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17); | ||
510 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
511 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
512 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
513 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
514 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
515 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_temp3_alarm, NULL, 0); | ||
516 | |||
486 | static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr, char *buf) | 517 | static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr, char *buf) |
487 | { | 518 | { |
488 | struct w83781d_data *data = w83781d_update_device(dev); | 519 | struct w83781d_data *data = w83781d_update_device(dev); |
@@ -546,6 +577,100 @@ static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR, | |||
546 | static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, | 577 | static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, |
547 | show_beep_enable, store_beep_enable); | 578 | show_beep_enable, store_beep_enable); |
548 | 579 | ||
580 | static ssize_t show_beep(struct device *dev, struct device_attribute *attr, | ||
581 | char *buf) | ||
582 | { | ||
583 | struct w83781d_data *data = w83781d_update_device(dev); | ||
584 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
585 | return sprintf(buf, "%u\n", (data->beep_mask >> bitnr) & 1); | ||
586 | } | ||
587 | |||
588 | static ssize_t | ||
589 | store_beep(struct device *dev, struct device_attribute *attr, | ||
590 | const char *buf, size_t count) | ||
591 | { | ||
592 | struct w83781d_data *data = dev_get_drvdata(dev); | ||
593 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
594 | unsigned long bit; | ||
595 | u8 reg; | ||
596 | |||
597 | bit = simple_strtoul(buf, NULL, 10); | ||
598 | if (bit & ~1) | ||
599 | return -EINVAL; | ||
600 | |||
601 | mutex_lock(&data->update_lock); | ||
602 | if (bit) | ||
603 | data->beep_mask |= (1 << bitnr); | ||
604 | else | ||
605 | data->beep_mask &= ~(1 << bitnr); | ||
606 | |||
607 | if (bitnr < 8) { | ||
608 | reg = w83781d_read_value(data, W83781D_REG_BEEP_INTS1); | ||
609 | if (bit) | ||
610 | reg |= (1 << bitnr); | ||
611 | else | ||
612 | reg &= ~(1 << bitnr); | ||
613 | w83781d_write_value(data, W83781D_REG_BEEP_INTS1, reg); | ||
614 | } else if (bitnr < 16) { | ||
615 | reg = w83781d_read_value(data, W83781D_REG_BEEP_INTS2); | ||
616 | if (bit) | ||
617 | reg |= (1 << (bitnr - 8)); | ||
618 | else | ||
619 | reg &= ~(1 << (bitnr - 8)); | ||
620 | w83781d_write_value(data, W83781D_REG_BEEP_INTS2, reg); | ||
621 | } else { | ||
622 | reg = w83781d_read_value(data, W83781D_REG_BEEP_INTS3); | ||
623 | if (bit) | ||
624 | reg |= (1 << (bitnr - 16)); | ||
625 | else | ||
626 | reg &= ~(1 << (bitnr - 16)); | ||
627 | w83781d_write_value(data, W83781D_REG_BEEP_INTS3, reg); | ||
628 | } | ||
629 | mutex_unlock(&data->update_lock); | ||
630 | |||
631 | return count; | ||
632 | } | ||
633 | |||
634 | /* The W83781D has a single beep bit for temp2 and temp3 */ | ||
635 | static ssize_t show_temp3_beep(struct device *dev, | ||
636 | struct device_attribute *attr, char *buf) | ||
637 | { | ||
638 | struct w83781d_data *data = w83781d_update_device(dev); | ||
639 | int bitnr = (data->type == w83781d) ? 5 : 13; | ||
640 | return sprintf(buf, "%u\n", (data->beep_mask >> bitnr) & 1); | ||
641 | } | ||
642 | |||
643 | static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR, | ||
644 | show_beep, store_beep, 0); | ||
645 | static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO | S_IWUSR, | ||
646 | show_beep, store_beep, 1); | ||
647 | static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO | S_IWUSR, | ||
648 | show_beep, store_beep, 2); | ||
649 | static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO | S_IWUSR, | ||
650 | show_beep, store_beep, 3); | ||
651 | static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO | S_IWUSR, | ||
652 | show_beep, store_beep, 8); | ||
653 | static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO | S_IWUSR, | ||
654 | show_beep, store_beep, 9); | ||
655 | static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO | S_IWUSR, | ||
656 | show_beep, store_beep, 10); | ||
657 | static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO | S_IWUSR, | ||
658 | show_beep, store_beep, 16); | ||
659 | static SENSOR_DEVICE_ATTR(in8_beep, S_IRUGO | S_IWUSR, | ||
660 | show_beep, store_beep, 17); | ||
661 | static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO | S_IWUSR, | ||
662 | show_beep, store_beep, 6); | ||
663 | static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO | S_IWUSR, | ||
664 | show_beep, store_beep, 7); | ||
665 | static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO | S_IWUSR, | ||
666 | show_beep, store_beep, 11); | ||
667 | static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR, | ||
668 | show_beep, store_beep, 4); | ||
669 | static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO | S_IWUSR, | ||
670 | show_beep, store_beep, 5); | ||
671 | static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, | ||
672 | show_temp3_beep, store_beep, 13); | ||
673 | |||
549 | static ssize_t | 674 | static ssize_t |
550 | show_fan_div(struct device *dev, struct device_attribute *da, char *buf) | 675 | show_fan_div(struct device *dev, struct device_attribute *da, char *buf) |
551 | { | 676 | { |
@@ -721,15 +846,19 @@ store_sensor(struct device *dev, struct device_attribute *da, | |||
721 | tmp & ~BIT_SCFG2[nr]); | 846 | tmp & ~BIT_SCFG2[nr]); |
722 | data->sens[nr] = val; | 847 | data->sens[nr] = val; |
723 | break; | 848 | break; |
724 | case W83781D_DEFAULT_BETA: /* thermistor */ | 849 | case W83781D_DEFAULT_BETA: |
850 | dev_warn(dev, "Sensor type %d is deprecated, please use 4 " | ||
851 | "instead\n", W83781D_DEFAULT_BETA); | ||
852 | /* fall through */ | ||
853 | case 4: /* thermistor */ | ||
725 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); | 854 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); |
726 | w83781d_write_value(data, W83781D_REG_SCFG1, | 855 | w83781d_write_value(data, W83781D_REG_SCFG1, |
727 | tmp & ~BIT_SCFG1[nr]); | 856 | tmp & ~BIT_SCFG1[nr]); |
728 | data->sens[nr] = val; | 857 | data->sens[nr] = val; |
729 | break; | 858 | break; |
730 | default: | 859 | default: |
731 | dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or %d\n", | 860 | dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or 4\n", |
732 | (long) val, W83781D_DEFAULT_BETA); | 861 | (long) val); |
733 | break; | 862 | break; |
734 | } | 863 | } |
735 | 864 | ||
@@ -875,17 +1004,23 @@ ERROR_SC_0: | |||
875 | #define IN_UNIT_ATTRS(X) \ | 1004 | #define IN_UNIT_ATTRS(X) \ |
876 | &sensor_dev_attr_in##X##_input.dev_attr.attr, \ | 1005 | &sensor_dev_attr_in##X##_input.dev_attr.attr, \ |
877 | &sensor_dev_attr_in##X##_min.dev_attr.attr, \ | 1006 | &sensor_dev_attr_in##X##_min.dev_attr.attr, \ |
878 | &sensor_dev_attr_in##X##_max.dev_attr.attr | 1007 | &sensor_dev_attr_in##X##_max.dev_attr.attr, \ |
1008 | &sensor_dev_attr_in##X##_alarm.dev_attr.attr, \ | ||
1009 | &sensor_dev_attr_in##X##_beep.dev_attr.attr | ||
879 | 1010 | ||
880 | #define FAN_UNIT_ATTRS(X) \ | 1011 | #define FAN_UNIT_ATTRS(X) \ |
881 | &sensor_dev_attr_fan##X##_input.dev_attr.attr, \ | 1012 | &sensor_dev_attr_fan##X##_input.dev_attr.attr, \ |
882 | &sensor_dev_attr_fan##X##_min.dev_attr.attr, \ | 1013 | &sensor_dev_attr_fan##X##_min.dev_attr.attr, \ |
883 | &sensor_dev_attr_fan##X##_div.dev_attr.attr | 1014 | &sensor_dev_attr_fan##X##_div.dev_attr.attr, \ |
1015 | &sensor_dev_attr_fan##X##_alarm.dev_attr.attr, \ | ||
1016 | &sensor_dev_attr_fan##X##_beep.dev_attr.attr | ||
884 | 1017 | ||
885 | #define TEMP_UNIT_ATTRS(X) \ | 1018 | #define TEMP_UNIT_ATTRS(X) \ |
886 | &sensor_dev_attr_temp##X##_input.dev_attr.attr, \ | 1019 | &sensor_dev_attr_temp##X##_input.dev_attr.attr, \ |
887 | &sensor_dev_attr_temp##X##_max.dev_attr.attr, \ | 1020 | &sensor_dev_attr_temp##X##_max.dev_attr.attr, \ |
888 | &sensor_dev_attr_temp##X##_max_hyst.dev_attr.attr | 1021 | &sensor_dev_attr_temp##X##_max_hyst.dev_attr.attr, \ |
1022 | &sensor_dev_attr_temp##X##_alarm.dev_attr.attr, \ | ||
1023 | &sensor_dev_attr_temp##X##_beep.dev_attr.attr | ||
889 | 1024 | ||
890 | static struct attribute* w83781d_attributes[] = { | 1025 | static struct attribute* w83781d_attributes[] = { |
891 | IN_UNIT_ATTRS(0), | 1026 | IN_UNIT_ATTRS(0), |
@@ -944,7 +1079,11 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) | |||
944 | || (err = device_create_file(dev, | 1079 | || (err = device_create_file(dev, |
945 | &sensor_dev_attr_in1_min.dev_attr)) | 1080 | &sensor_dev_attr_in1_min.dev_attr)) |
946 | || (err = device_create_file(dev, | 1081 | || (err = device_create_file(dev, |
947 | &sensor_dev_attr_in1_max.dev_attr))) | 1082 | &sensor_dev_attr_in1_max.dev_attr)) |
1083 | || (err = device_create_file(dev, | ||
1084 | &sensor_dev_attr_in1_alarm.dev_attr)) | ||
1085 | || (err = device_create_file(dev, | ||
1086 | &sensor_dev_attr_in1_beep.dev_attr))) | ||
948 | return err; | 1087 | return err; |
949 | } | 1088 | } |
950 | if (kind != as99127f && kind != w83781d && kind != w83783s) { | 1089 | if (kind != as99127f && kind != w83781d && kind != w83783s) { |
@@ -955,11 +1094,19 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) | |||
955 | || (err = device_create_file(dev, | 1094 | || (err = device_create_file(dev, |
956 | &sensor_dev_attr_in7_max.dev_attr)) | 1095 | &sensor_dev_attr_in7_max.dev_attr)) |
957 | || (err = device_create_file(dev, | 1096 | || (err = device_create_file(dev, |
1097 | &sensor_dev_attr_in7_alarm.dev_attr)) | ||
1098 | || (err = device_create_file(dev, | ||
1099 | &sensor_dev_attr_in7_beep.dev_attr)) | ||
1100 | || (err = device_create_file(dev, | ||
958 | &sensor_dev_attr_in8_input.dev_attr)) | 1101 | &sensor_dev_attr_in8_input.dev_attr)) |
959 | || (err = device_create_file(dev, | 1102 | || (err = device_create_file(dev, |
960 | &sensor_dev_attr_in8_min.dev_attr)) | 1103 | &sensor_dev_attr_in8_min.dev_attr)) |
961 | || (err = device_create_file(dev, | 1104 | || (err = device_create_file(dev, |
962 | &sensor_dev_attr_in8_max.dev_attr))) | 1105 | &sensor_dev_attr_in8_max.dev_attr)) |
1106 | || (err = device_create_file(dev, | ||
1107 | &sensor_dev_attr_in8_alarm.dev_attr)) | ||
1108 | || (err = device_create_file(dev, | ||
1109 | &sensor_dev_attr_in8_beep.dev_attr))) | ||
963 | return err; | 1110 | return err; |
964 | } | 1111 | } |
965 | if (kind != w83783s) { | 1112 | if (kind != w83783s) { |
@@ -968,8 +1115,19 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) | |||
968 | || (err = device_create_file(dev, | 1115 | || (err = device_create_file(dev, |
969 | &sensor_dev_attr_temp3_max.dev_attr)) | 1116 | &sensor_dev_attr_temp3_max.dev_attr)) |
970 | || (err = device_create_file(dev, | 1117 | || (err = device_create_file(dev, |
971 | &sensor_dev_attr_temp3_max_hyst.dev_attr))) | 1118 | &sensor_dev_attr_temp3_max_hyst.dev_attr)) |
1119 | || (err = device_create_file(dev, | ||
1120 | &sensor_dev_attr_temp3_alarm.dev_attr)) | ||
1121 | || (err = device_create_file(dev, | ||
1122 | &sensor_dev_attr_temp3_beep.dev_attr))) | ||
972 | return err; | 1123 | return err; |
1124 | |||
1125 | if (kind != w83781d) | ||
1126 | err = sysfs_chmod_file(&dev->kobj, | ||
1127 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
1128 | S_IRUGO | S_IWUSR); | ||
1129 | if (err) | ||
1130 | return err; | ||
973 | } | 1131 | } |
974 | 1132 | ||
975 | if (kind != w83781d && kind != as99127f) { | 1133 | if (kind != w83781d && kind != as99127f) { |
@@ -1156,9 +1314,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1156 | if (err) | 1314 | if (err) |
1157 | goto ERROR4; | 1315 | goto ERROR4; |
1158 | 1316 | ||
1159 | data->class_dev = hwmon_device_register(dev); | 1317 | data->hwmon_dev = hwmon_device_register(dev); |
1160 | if (IS_ERR(data->class_dev)) { | 1318 | if (IS_ERR(data->hwmon_dev)) { |
1161 | err = PTR_ERR(data->class_dev); | 1319 | err = PTR_ERR(data->hwmon_dev); |
1162 | goto ERROR4; | 1320 | goto ERROR4; |
1163 | } | 1321 | } |
1164 | 1322 | ||
@@ -1192,7 +1350,7 @@ w83781d_detach_client(struct i2c_client *client) | |||
1192 | 1350 | ||
1193 | /* main client */ | 1351 | /* main client */ |
1194 | if (data) { | 1352 | if (data) { |
1195 | hwmon_device_unregister(data->class_dev); | 1353 | hwmon_device_unregister(data->hwmon_dev); |
1196 | sysfs_remove_group(&client->dev.kobj, &w83781d_group); | 1354 | sysfs_remove_group(&client->dev.kobj, &w83781d_group); |
1197 | sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt); | 1355 | sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt); |
1198 | } | 1356 | } |
@@ -1259,9 +1417,9 @@ w83781d_isa_probe(struct platform_device *pdev) | |||
1259 | if (err) | 1417 | if (err) |
1260 | goto exit_remove_files; | 1418 | goto exit_remove_files; |
1261 | 1419 | ||
1262 | data->class_dev = hwmon_device_register(&pdev->dev); | 1420 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
1263 | if (IS_ERR(data->class_dev)) { | 1421 | if (IS_ERR(data->hwmon_dev)) { |
1264 | err = PTR_ERR(data->class_dev); | 1422 | err = PTR_ERR(data->hwmon_dev); |
1265 | goto exit_remove_files; | 1423 | goto exit_remove_files; |
1266 | } | 1424 | } |
1267 | 1425 | ||
@@ -1283,7 +1441,7 @@ w83781d_isa_remove(struct platform_device *pdev) | |||
1283 | { | 1441 | { |
1284 | struct w83781d_data *data = platform_get_drvdata(pdev); | 1442 | struct w83781d_data *data = platform_get_drvdata(pdev); |
1285 | 1443 | ||
1286 | hwmon_device_unregister(data->class_dev); | 1444 | hwmon_device_unregister(data->hwmon_dev); |
1287 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); | 1445 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); |
1288 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); | 1446 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); |
1289 | device_remove_file(&pdev->dev, &dev_attr_name); | 1447 | device_remove_file(&pdev->dev, &dev_attr_name); |
@@ -1485,7 +1643,7 @@ w83781d_init_device(struct device *dev) | |||
1485 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); | 1643 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); |
1486 | for (i = 1; i <= 3; i++) { | 1644 | for (i = 1; i <= 3; i++) { |
1487 | if (!(tmp & BIT_SCFG1[i - 1])) { | 1645 | if (!(tmp & BIT_SCFG1[i - 1])) { |
1488 | data->sens[i - 1] = W83781D_DEFAULT_BETA; | 1646 | data->sens[i - 1] = 4; |
1489 | } else { | 1647 | } else { |
1490 | if (w83781d_read_value | 1648 | if (w83781d_read_value |
1491 | (data, | 1649 | (data, |
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 9e5f885368b4..b6f2ebf9f9cf 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
@@ -2,7 +2,7 @@ | |||
2 | w83791d.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | w83791d.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | monitoring | 3 | monitoring |
4 | 4 | ||
5 | Copyright (C) 2006 Charles Spirakis <bezaur@gmail.com> | 5 | Copyright (C) 2006-2007 Charles Spirakis <bezaur@gmail.com> |
6 | 6 | ||
7 | 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 |
8 | 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 |
@@ -247,7 +247,7 @@ static u8 div_to_reg(int nr, long val) | |||
247 | 247 | ||
248 | struct w83791d_data { | 248 | struct w83791d_data { |
249 | struct i2c_client client; | 249 | struct i2c_client client; |
250 | struct class_device *class_dev; | 250 | struct device *hwmon_dev; |
251 | struct mutex update_lock; | 251 | struct mutex update_lock; |
252 | 252 | ||
253 | char valid; /* !=0 if following fields are valid */ | 253 | char valid; /* !=0 if following fields are valid */ |
@@ -384,6 +384,85 @@ static struct sensor_device_attribute sda_in_max[] = { | |||
384 | SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), | 384 | SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), |
385 | }; | 385 | }; |
386 | 386 | ||
387 | |||
388 | static ssize_t show_beep(struct device *dev, struct device_attribute *attr, | ||
389 | char *buf) | ||
390 | { | ||
391 | struct sensor_device_attribute *sensor_attr = | ||
392 | to_sensor_dev_attr(attr); | ||
393 | struct w83791d_data *data = w83791d_update_device(dev); | ||
394 | int bitnr = sensor_attr->index; | ||
395 | |||
396 | return sprintf(buf, "%d\n", (data->beep_mask >> bitnr) & 1); | ||
397 | } | ||
398 | |||
399 | static ssize_t store_beep(struct device *dev, struct device_attribute *attr, | ||
400 | const char *buf, size_t count) | ||
401 | { | ||
402 | struct sensor_device_attribute *sensor_attr = | ||
403 | to_sensor_dev_attr(attr); | ||
404 | struct i2c_client *client = to_i2c_client(dev); | ||
405 | struct w83791d_data *data = i2c_get_clientdata(client); | ||
406 | int bitnr = sensor_attr->index; | ||
407 | int bytenr = bitnr / 8; | ||
408 | long val = simple_strtol(buf, NULL, 10) ? 1 : 0; | ||
409 | |||
410 | mutex_lock(&data->update_lock); | ||
411 | |||
412 | data->beep_mask &= ~(0xff << (bytenr * 8)); | ||
413 | data->beep_mask |= w83791d_read(client, W83791D_REG_BEEP_CTRL[bytenr]) | ||
414 | << (bytenr * 8); | ||
415 | |||
416 | data->beep_mask &= ~(1 << bitnr); | ||
417 | data->beep_mask |= val << bitnr; | ||
418 | |||
419 | w83791d_write(client, W83791D_REG_BEEP_CTRL[bytenr], | ||
420 | (data->beep_mask >> (bytenr * 8)) & 0xff); | ||
421 | |||
422 | mutex_unlock(&data->update_lock); | ||
423 | |||
424 | return count; | ||
425 | } | ||
426 | |||
427 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
428 | char *buf) | ||
429 | { | ||
430 | struct sensor_device_attribute *sensor_attr = | ||
431 | to_sensor_dev_attr(attr); | ||
432 | struct w83791d_data *data = w83791d_update_device(dev); | ||
433 | int bitnr = sensor_attr->index; | ||
434 | |||
435 | return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); | ||
436 | } | ||
437 | |||
438 | /* Note: The bitmask for the beep enable/disable is different than | ||
439 | the bitmask for the alarm. */ | ||
440 | static struct sensor_device_attribute sda_in_beep[] = { | ||
441 | SENSOR_ATTR(in0_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 0), | ||
442 | SENSOR_ATTR(in1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 13), | ||
443 | SENSOR_ATTR(in2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 2), | ||
444 | SENSOR_ATTR(in3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 3), | ||
445 | SENSOR_ATTR(in4_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 8), | ||
446 | SENSOR_ATTR(in5_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 9), | ||
447 | SENSOR_ATTR(in6_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 10), | ||
448 | SENSOR_ATTR(in7_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 16), | ||
449 | SENSOR_ATTR(in8_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 17), | ||
450 | SENSOR_ATTR(in9_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 14), | ||
451 | }; | ||
452 | |||
453 | static struct sensor_device_attribute sda_in_alarm[] = { | ||
454 | SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0), | ||
455 | SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1), | ||
456 | SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2), | ||
457 | SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3), | ||
458 | SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8), | ||
459 | SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9), | ||
460 | SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10), | ||
461 | SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 19), | ||
462 | SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 20), | ||
463 | SENSOR_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 14), | ||
464 | }; | ||
465 | |||
387 | #define show_fan_reg(reg) \ | 466 | #define show_fan_reg(reg) \ |
388 | static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ | 467 | static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ |
389 | char *buf) \ | 468 | char *buf) \ |
@@ -536,6 +615,22 @@ static struct sensor_device_attribute sda_fan_div[] = { | |||
536 | show_fan_div, store_fan_div, 4), | 615 | show_fan_div, store_fan_div, 4), |
537 | }; | 616 | }; |
538 | 617 | ||
618 | static struct sensor_device_attribute sda_fan_beep[] = { | ||
619 | SENSOR_ATTR(fan1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 6), | ||
620 | SENSOR_ATTR(fan2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 7), | ||
621 | SENSOR_ATTR(fan3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 11), | ||
622 | SENSOR_ATTR(fan4_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 21), | ||
623 | SENSOR_ATTR(fan5_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 22), | ||
624 | }; | ||
625 | |||
626 | static struct sensor_device_attribute sda_fan_alarm[] = { | ||
627 | SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6), | ||
628 | SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7), | ||
629 | SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11), | ||
630 | SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 21), | ||
631 | SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22), | ||
632 | }; | ||
633 | |||
539 | /* read/write the temperature1, includes measured value and limits */ | 634 | /* read/write the temperature1, includes measured value and limits */ |
540 | static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, | 635 | static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, |
541 | char *buf) | 636 | char *buf) |
@@ -618,6 +713,19 @@ static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { | |||
618 | show_temp23, store_temp23, 1, 2), | 713 | show_temp23, store_temp23, 1, 2), |
619 | }; | 714 | }; |
620 | 715 | ||
716 | /* Note: The bitmask for the beep enable/disable is different than | ||
717 | the bitmask for the alarm. */ | ||
718 | static struct sensor_device_attribute sda_temp_beep[] = { | ||
719 | SENSOR_ATTR(temp1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 4), | ||
720 | SENSOR_ATTR(temp2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 5), | ||
721 | SENSOR_ATTR(temp3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 1), | ||
722 | }; | ||
723 | |||
724 | static struct sensor_device_attribute sda_temp_alarm[] = { | ||
725 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), | ||
726 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), | ||
727 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), | ||
728 | }; | ||
621 | 729 | ||
622 | /* get reatime status of all sensors items: voltage, temp, fan */ | 730 | /* get reatime status of all sensors items: voltage, temp, fan */ |
623 | static ssize_t show_alarms_reg(struct device *dev, | 731 | static ssize_t show_alarms_reg(struct device *dev, |
@@ -724,7 +832,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | |||
724 | static ssize_t show_vrm_reg(struct device *dev, | 832 | static ssize_t show_vrm_reg(struct device *dev, |
725 | struct device_attribute *attr, char *buf) | 833 | struct device_attribute *attr, char *buf) |
726 | { | 834 | { |
727 | struct w83791d_data *data = w83791d_update_device(dev); | 835 | struct w83791d_data *data = dev_get_drvdata(dev); |
728 | return sprintf(buf, "%d\n", data->vrm); | 836 | return sprintf(buf, "%d\n", data->vrm); |
729 | } | 837 | } |
730 | 838 | ||
@@ -749,17 +857,23 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); | |||
749 | #define IN_UNIT_ATTRS(X) \ | 857 | #define IN_UNIT_ATTRS(X) \ |
750 | &sda_in_input[X].dev_attr.attr, \ | 858 | &sda_in_input[X].dev_attr.attr, \ |
751 | &sda_in_min[X].dev_attr.attr, \ | 859 | &sda_in_min[X].dev_attr.attr, \ |
752 | &sda_in_max[X].dev_attr.attr | 860 | &sda_in_max[X].dev_attr.attr, \ |
861 | &sda_in_beep[X].dev_attr.attr, \ | ||
862 | &sda_in_alarm[X].dev_attr.attr | ||
753 | 863 | ||
754 | #define FAN_UNIT_ATTRS(X) \ | 864 | #define FAN_UNIT_ATTRS(X) \ |
755 | &sda_fan_input[X].dev_attr.attr, \ | 865 | &sda_fan_input[X].dev_attr.attr, \ |
756 | &sda_fan_min[X].dev_attr.attr, \ | 866 | &sda_fan_min[X].dev_attr.attr, \ |
757 | &sda_fan_div[X].dev_attr.attr | 867 | &sda_fan_div[X].dev_attr.attr, \ |
868 | &sda_fan_beep[X].dev_attr.attr, \ | ||
869 | &sda_fan_alarm[X].dev_attr.attr | ||
758 | 870 | ||
759 | #define TEMP_UNIT_ATTRS(X) \ | 871 | #define TEMP_UNIT_ATTRS(X) \ |
760 | &sda_temp_input[X].dev_attr.attr, \ | 872 | &sda_temp_input[X].dev_attr.attr, \ |
761 | &sda_temp_max[X].dev_attr.attr, \ | 873 | &sda_temp_max[X].dev_attr.attr, \ |
762 | &sda_temp_max_hyst[X].dev_attr.attr | 874 | &sda_temp_max_hyst[X].dev_attr.attr, \ |
875 | &sda_temp_beep[X].dev_attr.attr, \ | ||
876 | &sda_temp_alarm[X].dev_attr.attr | ||
763 | 877 | ||
764 | static struct attribute *w83791d_attributes[] = { | 878 | static struct attribute *w83791d_attributes[] = { |
765 | IN_UNIT_ATTRS(0), | 879 | IN_UNIT_ATTRS(0), |
@@ -1017,9 +1131,9 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1017 | goto error3; | 1131 | goto error3; |
1018 | 1132 | ||
1019 | /* Everything is ready, now register the working device */ | 1133 | /* Everything is ready, now register the working device */ |
1020 | data->class_dev = hwmon_device_register(dev); | 1134 | data->hwmon_dev = hwmon_device_register(dev); |
1021 | if (IS_ERR(data->class_dev)) { | 1135 | if (IS_ERR(data->hwmon_dev)) { |
1022 | err = PTR_ERR(data->class_dev); | 1136 | err = PTR_ERR(data->hwmon_dev); |
1023 | goto error4; | 1137 | goto error4; |
1024 | } | 1138 | } |
1025 | 1139 | ||
@@ -1051,7 +1165,7 @@ static int w83791d_detach_client(struct i2c_client *client) | |||
1051 | 1165 | ||
1052 | /* main client */ | 1166 | /* main client */ |
1053 | if (data) { | 1167 | if (data) { |
1054 | hwmon_device_unregister(data->class_dev); | 1168 | hwmon_device_unregister(data->hwmon_dev); |
1055 | sysfs_remove_group(&client->dev.kobj, &w83791d_group); | 1169 | sysfs_remove_group(&client->dev.kobj, &w83791d_group); |
1056 | } | 1170 | } |
1057 | 1171 | ||
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index b0fa296740d1..f836198b705c 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -267,7 +267,7 @@ DIV_TO_REG(long val) | |||
267 | 267 | ||
268 | struct w83792d_data { | 268 | struct w83792d_data { |
269 | struct i2c_client client; | 269 | struct i2c_client client; |
270 | struct class_device *class_dev; | 270 | struct device *hwmon_dev; |
271 | enum chips type; | 271 | enum chips type; |
272 | 272 | ||
273 | struct mutex update_lock; | 273 | struct mutex update_lock; |
@@ -540,6 +540,15 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
540 | return sprintf(buf, "%d\n", data->alarms); | 540 | return sprintf(buf, "%d\n", data->alarms); |
541 | } | 541 | } |
542 | 542 | ||
543 | static ssize_t show_alarm(struct device *dev, | ||
544 | struct device_attribute *attr, char *buf) | ||
545 | { | ||
546 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
547 | int nr = sensor_attr->index; | ||
548 | struct w83792d_data *data = w83792d_update_device(dev); | ||
549 | return sprintf(buf, "%d\n", (data->alarms >> nr) & 1); | ||
550 | } | ||
551 | |||
543 | static ssize_t | 552 | static ssize_t |
544 | show_pwm(struct device *dev, struct device_attribute *attr, | 553 | show_pwm(struct device *dev, struct device_attribute *attr, |
545 | char *buf) | 554 | char *buf) |
@@ -1015,6 +1024,25 @@ static SENSOR_DEVICE_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, | |||
1015 | static SENSOR_DEVICE_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, | 1024 | static SENSOR_DEVICE_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, |
1016 | show_temp23, store_temp23, 1, 4); | 1025 | show_temp23, store_temp23, 1, 4); |
1017 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); | 1026 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); |
1027 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
1028 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
1029 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
1030 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
1031 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
1032 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
1033 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
1034 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
1035 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
1036 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
1037 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 10); | ||
1038 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
1039 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 12); | ||
1040 | static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_alarm, NULL, 15); | ||
1041 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 19); | ||
1042 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 20); | ||
1043 | static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 21); | ||
1044 | static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22); | ||
1045 | static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 23); | ||
1018 | static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); | 1046 | static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); |
1019 | static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, | 1047 | static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, |
1020 | show_chassis_clear, store_chassis_clear); | 1048 | show_chassis_clear, store_chassis_clear); |
@@ -1123,26 +1151,30 @@ static SENSOR_DEVICE_ATTR(fan6_div, S_IWUSR | S_IRUGO, | |||
1123 | static SENSOR_DEVICE_ATTR(fan7_div, S_IWUSR | S_IRUGO, | 1151 | static SENSOR_DEVICE_ATTR(fan7_div, S_IWUSR | S_IRUGO, |
1124 | show_fan_div, store_fan_div, 7); | 1152 | show_fan_div, store_fan_div, 7); |
1125 | 1153 | ||
1126 | static struct attribute *w83792d_attributes_fan[4][4] = { | 1154 | static struct attribute *w83792d_attributes_fan[4][5] = { |
1127 | { | 1155 | { |
1128 | &sensor_dev_attr_fan4_input.dev_attr.attr, | 1156 | &sensor_dev_attr_fan4_input.dev_attr.attr, |
1129 | &sensor_dev_attr_fan4_min.dev_attr.attr, | 1157 | &sensor_dev_attr_fan4_min.dev_attr.attr, |
1130 | &sensor_dev_attr_fan4_div.dev_attr.attr, | 1158 | &sensor_dev_attr_fan4_div.dev_attr.attr, |
1159 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, | ||
1131 | NULL | 1160 | NULL |
1132 | }, { | 1161 | }, { |
1133 | &sensor_dev_attr_fan5_input.dev_attr.attr, | 1162 | &sensor_dev_attr_fan5_input.dev_attr.attr, |
1134 | &sensor_dev_attr_fan5_min.dev_attr.attr, | 1163 | &sensor_dev_attr_fan5_min.dev_attr.attr, |
1135 | &sensor_dev_attr_fan5_div.dev_attr.attr, | 1164 | &sensor_dev_attr_fan5_div.dev_attr.attr, |
1165 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, | ||
1136 | NULL | 1166 | NULL |
1137 | }, { | 1167 | }, { |
1138 | &sensor_dev_attr_fan6_input.dev_attr.attr, | 1168 | &sensor_dev_attr_fan6_input.dev_attr.attr, |
1139 | &sensor_dev_attr_fan6_min.dev_attr.attr, | 1169 | &sensor_dev_attr_fan6_min.dev_attr.attr, |
1140 | &sensor_dev_attr_fan6_div.dev_attr.attr, | 1170 | &sensor_dev_attr_fan6_div.dev_attr.attr, |
1171 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, | ||
1141 | NULL | 1172 | NULL |
1142 | }, { | 1173 | }, { |
1143 | &sensor_dev_attr_fan7_input.dev_attr.attr, | 1174 | &sensor_dev_attr_fan7_input.dev_attr.attr, |
1144 | &sensor_dev_attr_fan7_min.dev_attr.attr, | 1175 | &sensor_dev_attr_fan7_min.dev_attr.attr, |
1145 | &sensor_dev_attr_fan7_div.dev_attr.attr, | 1176 | &sensor_dev_attr_fan7_div.dev_attr.attr, |
1177 | &sensor_dev_attr_fan7_alarm.dev_attr.attr, | ||
1146 | NULL | 1178 | NULL |
1147 | } | 1179 | } |
1148 | }; | 1180 | }; |
@@ -1182,6 +1214,15 @@ static struct attribute *w83792d_attributes[] = { | |||
1182 | &sensor_dev_attr_in8_input.dev_attr.attr, | 1214 | &sensor_dev_attr_in8_input.dev_attr.attr, |
1183 | &sensor_dev_attr_in8_max.dev_attr.attr, | 1215 | &sensor_dev_attr_in8_max.dev_attr.attr, |
1184 | &sensor_dev_attr_in8_min.dev_attr.attr, | 1216 | &sensor_dev_attr_in8_min.dev_attr.attr, |
1217 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | ||
1218 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
1219 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
1220 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
1221 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
1222 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
1223 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
1224 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
1225 | &sensor_dev_attr_in8_alarm.dev_attr.attr, | ||
1185 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 1226 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
1186 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 1227 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
1187 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | 1228 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
@@ -1191,6 +1232,9 @@ static struct attribute *w83792d_attributes[] = { | |||
1191 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 1232 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
1192 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 1233 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
1193 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, | 1234 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, |
1235 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
1236 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
1237 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
1194 | &sensor_dev_attr_pwm1.dev_attr.attr, | 1238 | &sensor_dev_attr_pwm1.dev_attr.attr, |
1195 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, | 1239 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, |
1196 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | 1240 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, |
@@ -1233,12 +1277,15 @@ static struct attribute *w83792d_attributes[] = { | |||
1233 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 1277 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
1234 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 1278 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
1235 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 1279 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
1280 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
1236 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 1281 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
1237 | &sensor_dev_attr_fan2_min.dev_attr.attr, | 1282 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
1238 | &sensor_dev_attr_fan2_div.dev_attr.attr, | 1283 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
1284 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
1239 | &sensor_dev_attr_fan3_input.dev_attr.attr, | 1285 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
1240 | &sensor_dev_attr_fan3_min.dev_attr.attr, | 1286 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
1241 | &sensor_dev_attr_fan3_div.dev_attr.attr, | 1287 | &sensor_dev_attr_fan3_div.dev_attr.attr, |
1288 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | ||
1242 | NULL | 1289 | NULL |
1243 | }; | 1290 | }; |
1244 | 1291 | ||
@@ -1396,9 +1443,9 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1396 | &w83792d_group_fan[3]))) | 1443 | &w83792d_group_fan[3]))) |
1397 | goto exit_remove_files; | 1444 | goto exit_remove_files; |
1398 | 1445 | ||
1399 | data->class_dev = hwmon_device_register(dev); | 1446 | data->hwmon_dev = hwmon_device_register(dev); |
1400 | if (IS_ERR(data->class_dev)) { | 1447 | if (IS_ERR(data->hwmon_dev)) { |
1401 | err = PTR_ERR(data->class_dev); | 1448 | err = PTR_ERR(data->hwmon_dev); |
1402 | goto exit_remove_files; | 1449 | goto exit_remove_files; |
1403 | } | 1450 | } |
1404 | 1451 | ||
@@ -1433,7 +1480,7 @@ w83792d_detach_client(struct i2c_client *client) | |||
1433 | 1480 | ||
1434 | /* main client */ | 1481 | /* main client */ |
1435 | if (data) { | 1482 | if (data) { |
1436 | hwmon_device_unregister(data->class_dev); | 1483 | hwmon_device_unregister(data->hwmon_dev); |
1437 | sysfs_remove_group(&client->dev.kobj, &w83792d_group); | 1484 | sysfs_remove_group(&client->dev.kobj, &w83792d_group); |
1438 | for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) | 1485 | for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) |
1439 | sysfs_remove_group(&client->dev.kobj, | 1486 | sysfs_remove_group(&client->dev.kobj, |
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 253ffaf1568a..48599e1cc554 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c | |||
@@ -179,7 +179,7 @@ static inline s8 TEMP_TO_REG(long val, s8 min, s8 max) | |||
179 | struct w83793_data { | 179 | struct w83793_data { |
180 | struct i2c_client client; | 180 | struct i2c_client client; |
181 | struct i2c_client *lm75[2]; | 181 | struct i2c_client *lm75[2]; |
182 | struct class_device *class_dev; | 182 | struct device *hwmon_dev; |
183 | struct mutex update_lock; | 183 | struct mutex update_lock; |
184 | char valid; /* !=0 if following fields are valid */ | 184 | char valid; /* !=0 if following fields are valid */ |
185 | unsigned long last_updated; /* In jiffies */ | 185 | unsigned long last_updated; /* In jiffies */ |
@@ -1075,7 +1075,7 @@ static int w83793_detach_client(struct i2c_client *client) | |||
1075 | 1075 | ||
1076 | /* main client */ | 1076 | /* main client */ |
1077 | if (data) { | 1077 | if (data) { |
1078 | hwmon_device_unregister(data->class_dev); | 1078 | hwmon_device_unregister(data->hwmon_dev); |
1079 | 1079 | ||
1080 | for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) | 1080 | for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) |
1081 | device_remove_file(dev, | 1081 | device_remove_file(dev, |
@@ -1434,9 +1434,9 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1434 | } | 1434 | } |
1435 | } | 1435 | } |
1436 | 1436 | ||
1437 | data->class_dev = hwmon_device_register(dev); | 1437 | data->hwmon_dev = hwmon_device_register(dev); |
1438 | if (IS_ERR(data->class_dev)) { | 1438 | if (IS_ERR(data->hwmon_dev)) { |
1439 | err = PTR_ERR(data->class_dev); | 1439 | err = PTR_ERR(data->hwmon_dev); |
1440 | goto exit_remove; | 1440 | goto exit_remove; |
1441 | } | 1441 | } |
1442 | 1442 | ||
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index a3fcace412f0..b5db354e2f19 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c | |||
@@ -107,7 +107,7 @@ static struct i2c_driver w83l785ts_driver = { | |||
107 | 107 | ||
108 | struct w83l785ts_data { | 108 | struct w83l785ts_data { |
109 | struct i2c_client client; | 109 | struct i2c_client client; |
110 | struct class_device *class_dev; | 110 | struct device *hwmon_dev; |
111 | struct mutex update_lock; | 111 | struct mutex update_lock; |
112 | char valid; /* zero until following fields are valid */ | 112 | char valid; /* zero until following fields are valid */ |
113 | unsigned long last_updated; /* in jiffies */ | 113 | unsigned long last_updated; /* in jiffies */ |
@@ -247,9 +247,9 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) | |||
247 | goto exit_remove; | 247 | goto exit_remove; |
248 | 248 | ||
249 | /* Register sysfs hooks */ | 249 | /* Register sysfs hooks */ |
250 | data->class_dev = hwmon_device_register(&new_client->dev); | 250 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
251 | if (IS_ERR(data->class_dev)) { | 251 | if (IS_ERR(data->hwmon_dev)) { |
252 | err = PTR_ERR(data->class_dev); | 252 | err = PTR_ERR(data->hwmon_dev); |
253 | goto exit_remove; | 253 | goto exit_remove; |
254 | } | 254 | } |
255 | 255 | ||
@@ -272,7 +272,7 @@ static int w83l785ts_detach_client(struct i2c_client *client) | |||
272 | struct w83l785ts_data *data = i2c_get_clientdata(client); | 272 | struct w83l785ts_data *data = i2c_get_clientdata(client); |
273 | int err; | 273 | int err; |
274 | 274 | ||
275 | hwmon_device_unregister(data->class_dev); | 275 | hwmon_device_unregister(data->hwmon_dev); |
276 | device_remove_file(&client->dev, | 276 | device_remove_file(&client->dev, |
277 | &sensor_dev_attr_temp1_input.dev_attr); | 277 | &sensor_dev_attr_temp1_input.dev_attr); |
278 | device_remove_file(&client->dev, | 278 | device_remove_file(&client->dev, |