diff options
Diffstat (limited to 'drivers/hwmon/w83781d.c')
-rw-r--r-- | drivers/hwmon/w83781d.c | 90 |
1 files changed, 69 insertions, 21 deletions
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 0bb131ce09eb..4c43337ca780 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -38,8 +38,10 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/jiffies.h> | 39 | #include <linux/jiffies.h> |
40 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
41 | #include <linux/i2c-sensor.h> | 41 | #include <linux/i2c-isa.h> |
42 | #include <linux/i2c-vid.h> | 42 | #include <linux/hwmon.h> |
43 | #include <linux/hwmon-vid.h> | ||
44 | #include <linux/err.h> | ||
43 | #include <asm/io.h> | 45 | #include <asm/io.h> |
44 | #include "lm75.h" | 46 | #include "lm75.h" |
45 | 47 | ||
@@ -47,10 +49,10 @@ | |||
47 | static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, | 49 | static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, |
48 | 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, | 50 | 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, |
49 | 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; | 51 | 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; |
50 | static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END }; | 52 | static unsigned short isa_address = 0x290; |
51 | 53 | ||
52 | /* Insmod parameters */ | 54 | /* Insmod parameters */ |
53 | SENSORS_INSMOD_5(w83781d, w83782d, w83783s, w83627hf, as99127f); | 55 | I2C_CLIENT_INSMOD_5(w83781d, w83782d, w83783s, w83627hf, as99127f); |
54 | I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " | 56 | I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " |
55 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); | 57 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); |
56 | 58 | ||
@@ -218,6 +220,7 @@ DIV_TO_REG(long val, enum chips type) | |||
218 | allocated. */ | 220 | allocated. */ |
219 | struct w83781d_data { | 221 | struct w83781d_data { |
220 | struct i2c_client client; | 222 | struct i2c_client client; |
223 | struct class_device *class_dev; | ||
221 | struct semaphore lock; | 224 | struct semaphore lock; |
222 | enum chips type; | 225 | enum chips type; |
223 | 226 | ||
@@ -255,6 +258,7 @@ struct w83781d_data { | |||
255 | }; | 258 | }; |
256 | 259 | ||
257 | static int w83781d_attach_adapter(struct i2c_adapter *adapter); | 260 | static int w83781d_attach_adapter(struct i2c_adapter *adapter); |
261 | static int w83781d_isa_attach_adapter(struct i2c_adapter *adapter); | ||
258 | static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind); | 262 | static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind); |
259 | static int w83781d_detach_client(struct i2c_client *client); | 263 | static int w83781d_detach_client(struct i2c_client *client); |
260 | 264 | ||
@@ -273,6 +277,14 @@ static struct i2c_driver w83781d_driver = { | |||
273 | .detach_client = w83781d_detach_client, | 277 | .detach_client = w83781d_detach_client, |
274 | }; | 278 | }; |
275 | 279 | ||
280 | static struct i2c_driver w83781d_isa_driver = { | ||
281 | .owner = THIS_MODULE, | ||
282 | .name = "w83781d-isa", | ||
283 | .attach_adapter = w83781d_isa_attach_adapter, | ||
284 | .detach_client = w83781d_detach_client, | ||
285 | }; | ||
286 | |||
287 | |||
276 | /* following are the sysfs callback functions */ | 288 | /* following are the sysfs callback functions */ |
277 | #define show_in_reg(reg) \ | 289 | #define show_in_reg(reg) \ |
278 | static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ | 290 | static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ |
@@ -856,7 +868,13 @@ w83781d_attach_adapter(struct i2c_adapter *adapter) | |||
856 | { | 868 | { |
857 | if (!(adapter->class & I2C_CLASS_HWMON)) | 869 | if (!(adapter->class & I2C_CLASS_HWMON)) |
858 | return 0; | 870 | return 0; |
859 | return i2c_detect(adapter, &addr_data, w83781d_detect); | 871 | return i2c_probe(adapter, &addr_data, w83781d_detect); |
872 | } | ||
873 | |||
874 | static int | ||
875 | w83781d_isa_attach_adapter(struct i2c_adapter *adapter) | ||
876 | { | ||
877 | return w83781d_detect(adapter, isa_address, -1); | ||
860 | } | 878 | } |
861 | 879 | ||
862 | /* Assumes that adapter is of I2C, not ISA variety. | 880 | /* Assumes that adapter is of I2C, not ISA variety. |
@@ -961,10 +979,10 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, | |||
961 | ERROR_SC_3: | 979 | ERROR_SC_3: |
962 | i2c_detach_client(data->lm75[0]); | 980 | i2c_detach_client(data->lm75[0]); |
963 | ERROR_SC_2: | 981 | ERROR_SC_2: |
964 | if (NULL != data->lm75[1]) | 982 | if (data->lm75[1]) |
965 | kfree(data->lm75[1]); | 983 | kfree(data->lm75[1]); |
966 | ERROR_SC_1: | 984 | ERROR_SC_1: |
967 | if (NULL != data->lm75[0]) | 985 | if (data->lm75[0]) |
968 | kfree(data->lm75[0]); | 986 | kfree(data->lm75[0]); |
969 | ERROR_SC_0: | 987 | ERROR_SC_0: |
970 | return err; | 988 | return err; |
@@ -999,7 +1017,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
999 | 1017 | ||
1000 | if (is_isa) | 1018 | if (is_isa) |
1001 | if (!request_region(address, W83781D_EXTENT, | 1019 | if (!request_region(address, W83781D_EXTENT, |
1002 | w83781d_driver.name)) { | 1020 | w83781d_isa_driver.name)) { |
1003 | dev_dbg(&adapter->dev, "Request of region " | 1021 | dev_dbg(&adapter->dev, "Request of region " |
1004 | "0x%x-0x%x for w83781d failed\n", address, | 1022 | "0x%x-0x%x for w83781d failed\n", address, |
1005 | address + W83781D_EXTENT - 1); | 1023 | address + W83781D_EXTENT - 1); |
@@ -1057,7 +1075,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1057 | new_client->addr = address; | 1075 | new_client->addr = address; |
1058 | init_MUTEX(&data->lock); | 1076 | init_MUTEX(&data->lock); |
1059 | new_client->adapter = adapter; | 1077 | new_client->adapter = adapter; |
1060 | new_client->driver = &w83781d_driver; | 1078 | new_client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver; |
1061 | new_client->flags = 0; | 1079 | new_client->flags = 0; |
1062 | 1080 | ||
1063 | /* Now, we do the remaining detection. */ | 1081 | /* Now, we do the remaining detection. */ |
@@ -1189,6 +1207,12 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1189 | data->pwmenable[i] = 1; | 1207 | data->pwmenable[i] = 1; |
1190 | 1208 | ||
1191 | /* Register sysfs hooks */ | 1209 | /* Register sysfs hooks */ |
1210 | data->class_dev = hwmon_device_register(&new_client->dev); | ||
1211 | if (IS_ERR(data->class_dev)) { | ||
1212 | err = PTR_ERR(data->class_dev); | ||
1213 | goto ERROR4; | ||
1214 | } | ||
1215 | |||
1192 | device_create_file_in(new_client, 0); | 1216 | device_create_file_in(new_client, 0); |
1193 | if (kind != w83783s) | 1217 | if (kind != w83783s) |
1194 | device_create_file_in(new_client, 1); | 1218 | device_create_file_in(new_client, 1); |
@@ -1241,6 +1265,15 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1241 | 1265 | ||
1242 | return 0; | 1266 | return 0; |
1243 | 1267 | ||
1268 | ERROR4: | ||
1269 | if (data->lm75[1]) { | ||
1270 | i2c_detach_client(data->lm75[1]); | ||
1271 | kfree(data->lm75[1]); | ||
1272 | } | ||
1273 | if (data->lm75[0]) { | ||
1274 | i2c_detach_client(data->lm75[0]); | ||
1275 | kfree(data->lm75[0]); | ||
1276 | } | ||
1244 | ERROR3: | 1277 | ERROR3: |
1245 | i2c_detach_client(new_client); | 1278 | i2c_detach_client(new_client); |
1246 | ERROR2: | 1279 | ERROR2: |
@@ -1255,24 +1288,26 @@ ERROR0: | |||
1255 | static int | 1288 | static int |
1256 | w83781d_detach_client(struct i2c_client *client) | 1289 | w83781d_detach_client(struct i2c_client *client) |
1257 | { | 1290 | { |
1291 | struct w83781d_data *data = i2c_get_clientdata(client); | ||
1258 | int err; | 1292 | int err; |
1259 | 1293 | ||
1294 | /* main client */ | ||
1295 | if (data) | ||
1296 | hwmon_device_unregister(data->class_dev); | ||
1297 | |||
1260 | if (i2c_is_isa_client(client)) | 1298 | if (i2c_is_isa_client(client)) |
1261 | release_region(client->addr, W83781D_EXTENT); | 1299 | release_region(client->addr, W83781D_EXTENT); |
1262 | 1300 | ||
1263 | if ((err = i2c_detach_client(client))) { | 1301 | if ((err = i2c_detach_client(client))) |
1264 | dev_err(&client->dev, | ||
1265 | "Client deregistration failed, client not detached.\n"); | ||
1266 | return err; | 1302 | return err; |
1267 | } | ||
1268 | 1303 | ||
1269 | if (i2c_get_clientdata(client)==NULL) { | 1304 | /* main client */ |
1270 | /* subclients */ | 1305 | if (data) |
1306 | kfree(data); | ||
1307 | |||
1308 | /* subclient */ | ||
1309 | else | ||
1271 | kfree(client); | 1310 | kfree(client); |
1272 | } else { | ||
1273 | /* main client */ | ||
1274 | kfree(i2c_get_clientdata(client)); | ||
1275 | } | ||
1276 | 1311 | ||
1277 | return 0; | 1312 | return 0; |
1278 | } | 1313 | } |
@@ -1443,7 +1478,7 @@ w83781d_init_client(struct i2c_client *client) | |||
1443 | w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0); | 1478 | w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0); |
1444 | } | 1479 | } |
1445 | 1480 | ||
1446 | data->vrm = i2c_which_vrm(); | 1481 | data->vrm = vid_which_vrm(); |
1447 | 1482 | ||
1448 | if ((type != w83781d) && (type != as99127f)) { | 1483 | if ((type != w83781d) && (type != as99127f)) { |
1449 | tmp = w83781d_read_value(client, W83781D_REG_SCFG1); | 1484 | tmp = w83781d_read_value(client, W83781D_REG_SCFG1); |
@@ -1613,12 +1648,25 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1613 | static int __init | 1648 | static int __init |
1614 | sensors_w83781d_init(void) | 1649 | sensors_w83781d_init(void) |
1615 | { | 1650 | { |
1616 | return i2c_add_driver(&w83781d_driver); | 1651 | int res; |
1652 | |||
1653 | res = i2c_add_driver(&w83781d_driver); | ||
1654 | if (res) | ||
1655 | return res; | ||
1656 | |||
1657 | res = i2c_isa_add_driver(&w83781d_isa_driver); | ||
1658 | if (res) { | ||
1659 | i2c_del_driver(&w83781d_driver); | ||
1660 | return res; | ||
1661 | } | ||
1662 | |||
1663 | return 0; | ||
1617 | } | 1664 | } |
1618 | 1665 | ||
1619 | static void __exit | 1666 | static void __exit |
1620 | sensors_w83781d_exit(void) | 1667 | sensors_w83781d_exit(void) |
1621 | { | 1668 | { |
1669 | i2c_isa_del_driver(&w83781d_isa_driver); | ||
1622 | i2c_del_driver(&w83781d_driver); | 1670 | i2c_del_driver(&w83781d_driver); |
1623 | } | 1671 | } |
1624 | 1672 | ||