aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/adm1021.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/adm1021.c')
-rw-r--r--drivers/hwmon/adm1021.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index c45046241a1c..2dc45e958730 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -72,7 +72,7 @@ struct adm1021_data {
const struct attribute_group *groups[3];
struct mutex update_lock;
- char valid; /* !=0 if following fields are valid */
+ bool valid; /* true if following fields are valid */
char low_power; /* !=0 if device in low power mode */
unsigned long last_updated; /* In jiffies */
@@ -135,7 +135,7 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
ADM1023_REG_REM_OFFSET_PREC);
}
data->last_updated = jiffies;
- data->valid = 1;
+ data->valid = true;
}
mutex_unlock(&data->update_lock);
@@ -324,7 +324,7 @@ static int adm1021_detect(struct i2c_client *client,
{
struct i2c_adapter *adapter = client->adapter;
const char *type_name;
- int conv_rate, status, config, man_id, dev_id;
+ int reg, conv_rate, status, config, man_id, dev_id;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
pr_debug("detect failed, smbus byte data not supported!\n");
@@ -349,9 +349,19 @@ static int adm1021_detect(struct i2c_client *client,
if (man_id < 0 || dev_id < 0)
return -ENODEV;
- if (man_id == 0x4d && dev_id == 0x01)
+ if (man_id == 0x4d && dev_id == 0x01) {
+ /*
+ * dev_id 0x01 matches MAX6680, MAX6695, MAX6696, and possibly
+ * others. Read register which is unsupported on MAX1617 but
+ * exists on all those chips and compare with the dev_id
+ * register. If it matches, it may be a MAX1617A.
+ */
+ reg = i2c_smbus_read_byte_data(client,
+ ADM1023_REG_REM_TEMP_PREC);
+ if (reg != dev_id)
+ return -ENODEV;
type_name = "max1617a";
- else if (man_id == 0x41) {
+ } else if (man_id == 0x41) {
if ((dev_id & 0xF0) == 0x30)
type_name = "adm1023";
else if ((dev_id & 0xF0) == 0x00)
@@ -395,13 +405,18 @@ static int adm1021_detect(struct i2c_client *client,
/*
* LM84 Mfr ID is in a different place,
- * and it has more unused bits.
+ * and it has more unused bits. Registers at 0xfe and 0xff
+ * are undefined and return the most recently read value,
+ * here the value of the configuration register.
*/
if (conv_rate == 0x00
+ && man_id == config && dev_id == config
&& (config & 0x7F) == 0x00
&& (status & 0xAB) == 0x00) {
type_name = "lm84";
} else {
+ if ((config & 0x3f) || (status & 0x03))
+ return -ENODEV;
/* fail if low limits are larger than high limits */
if ((s8)llo > lhi || (s8)rlo > rhi)
return -ENODEV;
@@ -411,7 +426,7 @@ static int adm1021_detect(struct i2c_client *client,
pr_debug("Detected chip %s at adapter %d, address 0x%02x.\n",
type_name, i2c_adapter_id(adapter), client->addr);
- strlcpy(info->type, type_name, I2C_NAME_SIZE);
+ strscpy(info->type, type_name, I2C_NAME_SIZE);
return 0;
}
@@ -425,8 +440,9 @@ static void adm1021_init_client(struct i2c_client *client)
i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
}
-static int adm1021_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static const struct i2c_device_id adm1021_id[];
+
+static int adm1021_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct adm1021_data *data;
@@ -437,7 +453,7 @@ static int adm1021_probe(struct i2c_client *client,
return -ENOMEM;
data->client = client;
- data->type = id->driver_data;
+ data->type = i2c_match_id(adm1021_id, client)->driver_data;
mutex_init(&data->update_lock);
/* Initialize the ADM1021 chip */
@@ -472,7 +488,7 @@ static struct i2c_driver adm1021_driver = {
.driver = {
.name = "adm1021",
},
- .probe = adm1021_probe,
+ .probe_new = adm1021_probe,
.id_table = adm1021_id,
.detect = adm1021_detect,
.address_list = normal_i2c,