diff options
Diffstat (limited to 'drivers/hwmon/w83792d.c')
-rw-r--r-- | drivers/hwmon/w83792d.c | 70 |
1 files changed, 22 insertions, 48 deletions
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 2be16194ddf3..679718e6b017 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -50,7 +50,6 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, | |||
50 | I2C_CLIENT_END }; | 50 | I2C_CLIENT_END }; |
51 | 51 | ||
52 | /* Insmod parameters */ | 52 | /* Insmod parameters */ |
53 | I2C_CLIENT_INSMOD_1(w83792d); | ||
54 | 53 | ||
55 | static unsigned short force_subclients[4]; | 54 | static unsigned short force_subclients[4]; |
56 | module_param_array(force_subclients, short, NULL, 0); | 55 | module_param_array(force_subclients, short, NULL, 0); |
@@ -302,7 +301,7 @@ struct w83792d_data { | |||
302 | 301 | ||
303 | static int w83792d_probe(struct i2c_client *client, | 302 | static int w83792d_probe(struct i2c_client *client, |
304 | const struct i2c_device_id *id); | 303 | const struct i2c_device_id *id); |
305 | static int w83792d_detect(struct i2c_client *client, int kind, | 304 | static int w83792d_detect(struct i2c_client *client, |
306 | struct i2c_board_info *info); | 305 | struct i2c_board_info *info); |
307 | static int w83792d_remove(struct i2c_client *client); | 306 | static int w83792d_remove(struct i2c_client *client); |
308 | static struct w83792d_data *w83792d_update_device(struct device *dev); | 307 | static struct w83792d_data *w83792d_update_device(struct device *dev); |
@@ -314,7 +313,7 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev); | |||
314 | static void w83792d_init_client(struct i2c_client *client); | 313 | static void w83792d_init_client(struct i2c_client *client); |
315 | 314 | ||
316 | static const struct i2c_device_id w83792d_id[] = { | 315 | static const struct i2c_device_id w83792d_id[] = { |
317 | { "w83792d", w83792d }, | 316 | { "w83792d", 0 }, |
318 | { } | 317 | { } |
319 | }; | 318 | }; |
320 | MODULE_DEVICE_TABLE(i2c, w83792d_id); | 319 | MODULE_DEVICE_TABLE(i2c, w83792d_id); |
@@ -328,7 +327,7 @@ static struct i2c_driver w83792d_driver = { | |||
328 | .remove = w83792d_remove, | 327 | .remove = w83792d_remove, |
329 | .id_table = w83792d_id, | 328 | .id_table = w83792d_id, |
330 | .detect = w83792d_detect, | 329 | .detect = w83792d_detect, |
331 | .address_data = &addr_data, | 330 | .address_list = normal_i2c, |
332 | }; | 331 | }; |
333 | 332 | ||
334 | static inline long in_count_from_reg(int nr, struct w83792d_data *data) | 333 | static inline long in_count_from_reg(int nr, struct w83792d_data *data) |
@@ -1263,7 +1262,7 @@ static const struct attribute_group w83792d_group = { | |||
1263 | 1262 | ||
1264 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 1263 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
1265 | static int | 1264 | static int |
1266 | w83792d_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) | 1265 | w83792d_detect(struct i2c_client *client, struct i2c_board_info *info) |
1267 | { | 1266 | { |
1268 | struct i2c_adapter *adapter = client->adapter; | 1267 | struct i2c_adapter *adapter = client->adapter; |
1269 | int val1, val2; | 1268 | int val1, val2; |
@@ -1273,58 +1272,33 @@ w83792d_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) | |||
1273 | return -ENODEV; | 1272 | return -ENODEV; |
1274 | } | 1273 | } |
1275 | 1274 | ||
1276 | /* The w83792d may be stuck in some other bank than bank 0. This may | 1275 | if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) |
1277 | make reading other information impossible. Specify a force=... or | 1276 | return -ENODEV; |
1278 | force_*=... parameter, and the Winbond will be reset to the right | 1277 | |
1279 | bank. */ | 1278 | val1 = w83792d_read_value(client, W83792D_REG_BANK); |
1280 | if (kind < 0) { | 1279 | val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN); |
1281 | if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) { | 1280 | /* Check for Winbond ID if in bank 0 */ |
1282 | return -ENODEV; | 1281 | if (!(val1 & 0x07)) { /* is Bank0 */ |
1283 | } | 1282 | if ((!(val1 & 0x80) && val2 != 0xa3) || |
1284 | val1 = w83792d_read_value(client, W83792D_REG_BANK); | 1283 | ( (val1 & 0x80) && val2 != 0x5c)) |
1285 | val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN); | ||
1286 | /* Check for Winbond ID if in bank 0 */ | ||
1287 | if (!(val1 & 0x07)) { /* is Bank0 */ | ||
1288 | if (((!(val1 & 0x80)) && (val2 != 0xa3)) || | ||
1289 | ((val1 & 0x80) && (val2 != 0x5c))) { | ||
1290 | return -ENODEV; | ||
1291 | } | ||
1292 | } | ||
1293 | /* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR | ||
1294 | should match */ | ||
1295 | if (w83792d_read_value(client, | ||
1296 | W83792D_REG_I2C_ADDR) != address) { | ||
1297 | return -ENODEV; | 1284 | return -ENODEV; |
1298 | } | ||
1299 | } | 1285 | } |
1286 | /* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR | ||
1287 | should match */ | ||
1288 | if (w83792d_read_value(client, W83792D_REG_I2C_ADDR) != address) | ||
1289 | return -ENODEV; | ||
1300 | 1290 | ||
1301 | /* We have either had a force parameter, or we have already detected the | 1291 | /* Put it now into bank 0 and Vendor ID High Byte */ |
1302 | Winbond. Put it now into bank 0 and Vendor ID High Byte */ | ||
1303 | w83792d_write_value(client, | 1292 | w83792d_write_value(client, |
1304 | W83792D_REG_BANK, | 1293 | W83792D_REG_BANK, |
1305 | (w83792d_read_value(client, | 1294 | (w83792d_read_value(client, |
1306 | W83792D_REG_BANK) & 0x78) | 0x80); | 1295 | W83792D_REG_BANK) & 0x78) | 0x80); |
1307 | 1296 | ||
1308 | /* Determine the chip type. */ | 1297 | /* Determine the chip type. */ |
1309 | if (kind <= 0) { | 1298 | val1 = w83792d_read_value(client, W83792D_REG_WCHIPID); |
1310 | /* get vendor ID */ | 1299 | val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN); |
1311 | val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN); | 1300 | if (val1 != 0x7a || val2 != 0x5c) |
1312 | if (val2 != 0x5c) { /* the vendor is NOT Winbond */ | 1301 | return -ENODEV; |
1313 | return -ENODEV; | ||
1314 | } | ||
1315 | val1 = w83792d_read_value(client, W83792D_REG_WCHIPID); | ||
1316 | if (val1 == 0x7a) { | ||
1317 | kind = w83792d; | ||
1318 | } else { | ||
1319 | if (kind == 0) | ||
1320 | dev_warn(&adapter->dev, | ||
1321 | "w83792d: Ignoring 'force' parameter for" | ||
1322 | " unknown chip at adapter %d, address" | ||
1323 | " 0x%02x\n", i2c_adapter_id(adapter), | ||
1324 | address); | ||
1325 | return -ENODEV; | ||
1326 | } | ||
1327 | } | ||
1328 | 1302 | ||
1329 | strlcpy(info->type, "w83792d", I2C_NAME_SIZE); | 1303 | strlcpy(info->type, "w83792d", I2C_NAME_SIZE); |
1330 | 1304 | ||