aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lm80.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2012-01-31 09:27:11 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2012-03-18 21:27:43 -0400
commit9908ad4cd4bc3e6620e1819e7f9b43f109650e1b (patch)
treea1fd79fa9119c908e05a74f8207ba23f94566c24 /drivers/hwmon/lm80.c
parent0e190b7fa330f19afed9e12d551432b8659886c7 (diff)
hwmon: (lm80) Add detection of NatSemi/TI LM96080
Add detection of the National Semiconductor (now Texas Instruments) LM96080. It is functionally compatible with the LM80 but detection is completely different. Signed-off-by: Jean Delvare <khali@linux-fr.org> Cc: Guenter Roeck <guenter.roeck@ericsson.com> Cc: Frans Meulenbroeks <fransmeulenbroeks@gmail.com> Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon/lm80.c')
-rw-r--r--drivers/hwmon/lm80.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c
index a996f2795db0..e2c43e1774be 100644
--- a/drivers/hwmon/lm80.c
+++ b/drivers/hwmon/lm80.c
@@ -60,6 +60,10 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
60#define LM80_REG_FANDIV 0x05 60#define LM80_REG_FANDIV 0x05
61#define LM80_REG_RES 0x06 61#define LM80_REG_RES 0x06
62 62
63#define LM96080_REG_CONV_RATE 0x07
64#define LM96080_REG_MAN_ID 0x3e
65#define LM96080_REG_DEV_ID 0x3f
66
63 67
64/* 68/*
65 * Conversions. Rounding and limit checking is only done on the TO_REG 69 * Conversions. Rounding and limit checking is only done on the TO_REG
@@ -147,6 +151,7 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value);
147 151
148static const struct i2c_device_id lm80_id[] = { 152static const struct i2c_device_id lm80_id[] = {
149 { "lm80", 0 }, 153 { "lm80", 0 },
154 { "lm96080", 1 },
150 { } 155 { }
151}; 156};
152MODULE_DEVICE_TABLE(i2c, lm80_id); 157MODULE_DEVICE_TABLE(i2c, lm80_id);
@@ -490,23 +495,44 @@ static const struct attribute_group lm80_group = {
490static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info) 495static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info)
491{ 496{
492 struct i2c_adapter *adapter = client->adapter; 497 struct i2c_adapter *adapter = client->adapter;
493 int i, cur; 498 int i, cur, man_id, dev_id;
499 const char *name = NULL;
494 500
495 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 501 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
496 return -ENODEV; 502 return -ENODEV;
497 503
498 /* Now, we do the remaining detection. It is lousy. */ 504 /* First check for unused bits, common to both chip types */
499 if (lm80_read_value(client, LM80_REG_ALARM2) & 0xc0) 505 if ((lm80_read_value(client, LM80_REG_ALARM2) & 0xc0)
506 || (lm80_read_value(client, LM80_REG_CONFIG) & 0x80))
500 return -ENODEV; 507 return -ENODEV;
501 for (i = 0x2a; i <= 0x3d; i++) { 508
502 cur = i2c_smbus_read_byte_data(client, i); 509 /*
503 if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur) 510 * The LM96080 has manufacturer and stepping/die rev registers so we
504 || (i2c_smbus_read_byte_data(client, i + 0x80) != cur) 511 * can just check that. The LM80 does not have such registers so we
505 || (i2c_smbus_read_byte_data(client, i + 0xc0) != cur)) 512 * have to use a more expensive trick.
513 */
514 man_id = lm80_read_value(client, LM96080_REG_MAN_ID);
515 dev_id = lm80_read_value(client, LM96080_REG_DEV_ID);
516 if (man_id == 0x01 && dev_id == 0x08) {
517 /* Check more unused bits for confirmation */
518 if (lm80_read_value(client, LM96080_REG_CONV_RATE) & 0xfe)
506 return -ENODEV; 519 return -ENODEV;
520
521 name = "lm96080";
522 } else {
523 /* Check 6-bit addressing */
524 for (i = 0x2a; i <= 0x3d; i++) {
525 cur = i2c_smbus_read_byte_data(client, i);
526 if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur)
527 || (i2c_smbus_read_byte_data(client, i + 0x80) != cur)
528 || (i2c_smbus_read_byte_data(client, i + 0xc0) != cur))
529 return -ENODEV;
530 }
531
532 name = "lm80";
507 } 533 }
508 534
509 strlcpy(info->type, "lm80", I2C_NAME_SIZE); 535 strlcpy(info->type, name, I2C_NAME_SIZE);
510 536
511 return 0; 537 return 0;
512} 538}