aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/w83792d.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/w83792d.c')
-rw-r--r--drivers/hwmon/w83792d.c70
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 */
53I2C_CLIENT_INSMOD_1(w83792d);
54 53
55static unsigned short force_subclients[4]; 54static unsigned short force_subclients[4];
56module_param_array(force_subclients, short, NULL, 0); 55module_param_array(force_subclients, short, NULL, 0);
@@ -302,7 +301,7 @@ struct w83792d_data {
302 301
303static int w83792d_probe(struct i2c_client *client, 302static int w83792d_probe(struct i2c_client *client,
304 const struct i2c_device_id *id); 303 const struct i2c_device_id *id);
305static int w83792d_detect(struct i2c_client *client, int kind, 304static int w83792d_detect(struct i2c_client *client,
306 struct i2c_board_info *info); 305 struct i2c_board_info *info);
307static int w83792d_remove(struct i2c_client *client); 306static int w83792d_remove(struct i2c_client *client);
308static struct w83792d_data *w83792d_update_device(struct device *dev); 307static 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);
314static void w83792d_init_client(struct i2c_client *client); 313static void w83792d_init_client(struct i2c_client *client);
315 314
316static const struct i2c_device_id w83792d_id[] = { 315static const struct i2c_device_id w83792d_id[] = {
317 { "w83792d", w83792d }, 316 { "w83792d", 0 },
318 { } 317 { }
319}; 318};
320MODULE_DEVICE_TABLE(i2c, w83792d_id); 319MODULE_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
334static inline long in_count_from_reg(int nr, struct w83792d_data *data) 333static 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 */
1265static int 1264static int
1266w83792d_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) 1265w83792d_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