diff options
Diffstat (limited to 'drivers/hwmon/adm1025.c')
-rw-r--r-- | drivers/hwmon/adm1025.c | 85 |
1 files changed, 24 insertions, 61 deletions
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index 4db04d603ec9..251b63165e2a 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * adm1025.c | 2 | * adm1025.c |
3 | * | 3 | * |
4 | * Copyright (C) 2000 Chen-Yuan Wu <gwu@esoft.com> | 4 | * Copyright (C) 2000 Chen-Yuan Wu <gwu@esoft.com> |
5 | * Copyright (C) 2003-2008 Jean Delvare <khali@linux-fr.org> | 5 | * Copyright (C) 2003-2009 Jean Delvare <khali@linux-fr.org> |
6 | * | 6 | * |
7 | * The ADM1025 is a sensor chip made by Analog Devices. It reports up to 6 | 7 | * The ADM1025 is a sensor chip made by Analog Devices. It reports up to 6 |
8 | * voltages (including its own power source) and up to two temperatures | 8 | * voltages (including its own power source) and up to two temperatures |
@@ -64,11 +64,7 @@ | |||
64 | 64 | ||
65 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; | 65 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; |
66 | 66 | ||
67 | /* | 67 | enum chips { adm1025, ne1619 }; |
68 | * Insmod parameters | ||
69 | */ | ||
70 | |||
71 | I2C_CLIENT_INSMOD_2(adm1025, ne1619); | ||
72 | 68 | ||
73 | /* | 69 | /* |
74 | * The ADM1025 registers | 70 | * The ADM1025 registers |
@@ -111,7 +107,7 @@ static const int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 }; | |||
111 | 107 | ||
112 | static int adm1025_probe(struct i2c_client *client, | 108 | static int adm1025_probe(struct i2c_client *client, |
113 | const struct i2c_device_id *id); | 109 | const struct i2c_device_id *id); |
114 | static int adm1025_detect(struct i2c_client *client, int kind, | 110 | static int adm1025_detect(struct i2c_client *client, |
115 | struct i2c_board_info *info); | 111 | struct i2c_board_info *info); |
116 | static void adm1025_init_client(struct i2c_client *client); | 112 | static void adm1025_init_client(struct i2c_client *client); |
117 | static int adm1025_remove(struct i2c_client *client); | 113 | static int adm1025_remove(struct i2c_client *client); |
@@ -137,7 +133,7 @@ static struct i2c_driver adm1025_driver = { | |||
137 | .remove = adm1025_remove, | 133 | .remove = adm1025_remove, |
138 | .id_table = adm1025_id, | 134 | .id_table = adm1025_id, |
139 | .detect = adm1025_detect, | 135 | .detect = adm1025_detect, |
140 | .address_data = &addr_data, | 136 | .address_list = normal_i2c, |
141 | }; | 137 | }; |
142 | 138 | ||
143 | /* | 139 | /* |
@@ -409,71 +405,38 @@ static const struct attribute_group adm1025_group_in4 = { | |||
409 | }; | 405 | }; |
410 | 406 | ||
411 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 407 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
412 | static int adm1025_detect(struct i2c_client *client, int kind, | 408 | static int adm1025_detect(struct i2c_client *client, |
413 | struct i2c_board_info *info) | 409 | struct i2c_board_info *info) |
414 | { | 410 | { |
415 | struct i2c_adapter *adapter = client->adapter; | 411 | struct i2c_adapter *adapter = client->adapter; |
416 | const char *name = ""; | 412 | const char *name; |
417 | u8 config; | 413 | u8 man_id, chip_id; |
418 | 414 | ||
419 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 415 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
420 | return -ENODEV; | 416 | return -ENODEV; |
421 | 417 | ||
422 | /* | 418 | /* Check for unused bits */ |
423 | * Now we do the remaining detection. A negative kind means that | 419 | if ((i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG) & 0x80) |
424 | * the driver was loaded with no force parameter (default), so we | 420 | || (i2c_smbus_read_byte_data(client, ADM1025_REG_STATUS1) & 0xC0) |
425 | * must both detect and identify the chip. A zero kind means that | 421 | || (i2c_smbus_read_byte_data(client, ADM1025_REG_STATUS2) & 0xBC)) { |
426 | * the driver was loaded with the force parameter, the detection | 422 | dev_dbg(&adapter->dev, "ADM1025 detection failed at 0x%02x\n", |
427 | * step shall be skipped. A positive kind means that the driver | 423 | client->addr); |
428 | * was loaded with the force parameter and a given kind of chip is | 424 | return -ENODEV; |
429 | * requested, so both the detection and the identification steps | ||
430 | * are skipped. | ||
431 | */ | ||
432 | config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG); | ||
433 | if (kind < 0) { /* detection */ | ||
434 | if ((config & 0x80) != 0x00 | ||
435 | || (i2c_smbus_read_byte_data(client, | ||
436 | ADM1025_REG_STATUS1) & 0xC0) != 0x00 | ||
437 | || (i2c_smbus_read_byte_data(client, | ||
438 | ADM1025_REG_STATUS2) & 0xBC) != 0x00) { | ||
439 | dev_dbg(&adapter->dev, | ||
440 | "ADM1025 detection failed at 0x%02x.\n", | ||
441 | client->addr); | ||
442 | return -ENODEV; | ||
443 | } | ||
444 | } | 425 | } |
445 | 426 | ||
446 | if (kind <= 0) { /* identification */ | 427 | /* Identification */ |
447 | u8 man_id, chip_id; | 428 | chip_id = i2c_smbus_read_byte_data(client, ADM1025_REG_CHIP_ID); |
448 | 429 | if ((chip_id & 0xF0) != 0x20) | |
449 | man_id = i2c_smbus_read_byte_data(client, ADM1025_REG_MAN_ID); | 430 | return -ENODEV; |
450 | chip_id = i2c_smbus_read_byte_data(client, ADM1025_REG_CHIP_ID); | ||
451 | |||
452 | if (man_id == 0x41) { /* Analog Devices */ | ||
453 | if ((chip_id & 0xF0) == 0x20) { /* ADM1025/ADM1025A */ | ||
454 | kind = adm1025; | ||
455 | } | ||
456 | } else | ||
457 | if (man_id == 0xA1) { /* Philips */ | ||
458 | if (client->addr != 0x2E | ||
459 | && (chip_id & 0xF0) == 0x20) { /* NE1619 */ | ||
460 | kind = ne1619; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | if (kind <= 0) { /* identification failed */ | ||
465 | dev_info(&adapter->dev, | ||
466 | "Unsupported chip (man_id=0x%02X, " | ||
467 | "chip_id=0x%02X).\n", man_id, chip_id); | ||
468 | return -ENODEV; | ||
469 | } | ||
470 | } | ||
471 | 431 | ||
472 | if (kind == adm1025) { | 432 | man_id = i2c_smbus_read_byte_data(client, ADM1025_REG_MAN_ID); |
433 | if (man_id == 0x41) | ||
473 | name = "adm1025"; | 434 | name = "adm1025"; |
474 | } else if (kind == ne1619) { | 435 | else if (man_id == 0xA1 && client->addr != 0x2E) |
475 | name = "ne1619"; | 436 | name = "ne1619"; |
476 | } | 437 | else |
438 | return -ENODEV; | ||
439 | |||
477 | strlcpy(info->type, name, I2C_NAME_SIZE); | 440 | strlcpy(info->type, name, I2C_NAME_SIZE); |
478 | 441 | ||
479 | return 0; | 442 | return 0; |