summaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lm90.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/lm90.c')
-rw-r--r--drivers/hwmon/lm90.c78
1 files changed, 59 insertions, 19 deletions
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 6882ce75fee..48833fff492 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -43,6 +43,13 @@
* variants. The extra address and features of the MAX6659 are not
* supported by this driver.
*
+ * This driver also supports the MAX6680 and MAX6681, two other sensor
+ * chips made by Maxim. These are quite similar to the other Maxim
+ * chips. Complete datasheet can be obtained at:
+ * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370
+ * The MAX6680 and MAX6681 only differ in the pinout so they can be
+ * treated identically.
+ *
* This driver also supports the ADT7461 chip from Analog Devices but
* only in its "compatability mode". If an ADT7461 chip is found but
* is configured in non-compatible mode (where its temperature
@@ -84,20 +91,25 @@
/*
* Addresses to scan
* Address is fully defined internally and cannot be changed except for
- * MAX6659.
+ * MAX6659, MAX6680 and MAX6681.
* LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658
* have address 0x4c.
* ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d.
* MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported).
+ * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b,
+ * 0x4c, 0x4d or 0x4e.
*/
-static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
+ 0x29, 0x2a, 0x2b,
+ 0x4c, 0x4d, 0x4e,
+ I2C_CLIENT_END };
/*
* Insmod parameters
*/
-I2C_CLIENT_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461);
+I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680);
/*
* The LM90 registers
@@ -359,7 +371,7 @@ static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4);
/* Individual alarm files */
static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0);
static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1);
-static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2);
static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3);
static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5);
@@ -381,7 +393,7 @@ static struct attribute *lm90_attributes[] = {
&sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
&sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
- &sensor_dev_attr_temp2_input_fault.dev_attr.attr,
+ &sensor_dev_attr_temp2_fault.dev_attr.attr,
&sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
@@ -429,7 +441,7 @@ static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec);
*/
/* The ADM1032 supports PEC but not on write byte transactions, so we need
- to explicitely ask for a transaction without PEC. */
+ to explicitly ask for a transaction without PEC. */
static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
{
return i2c_smbus_xfer(client->adapter, client->addr,
@@ -525,7 +537,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
&reg_convrate) < 0)
goto exit_free;
- if (man_id == 0x01) { /* National Semiconductor */
+ if ((address == 0x4C || address == 0x4D)
+ && man_id == 0x01) { /* National Semiconductor */
u8 reg_config2;
if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2,
@@ -548,7 +561,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
}
}
} else
- if (man_id == 0x41) { /* Analog Devices */
+ if ((address == 0x4C || address == 0x4D)
+ && man_id == 0x41) { /* Analog Devices */
if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
&& (reg_config1 & 0x3F) == 0x00
&& reg_convrate <= 0x0A) {
@@ -562,18 +576,30 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
} else
if (man_id == 0x4D) { /* Maxim */
/*
- * The Maxim variants do NOT have a chip_id register.
- * Reading from that address will return the last read
- * value, which in our case is those of the man_id
- * register. Likewise, the config1 register seems to
- * lack a low nibble, so the value will be those of the
- * previous read, so in our case those of the man_id
- * register.
+ * The MAX6657, MAX6658 and MAX6659 do NOT have a
+ * chip_id register. Reading from that address will
+ * return the last read value, which in our case is
+ * those of the man_id register. Likewise, the config1
+ * register seems to lack a low nibble, so the value
+ * will be those of the previous read, so in our case
+ * those of the man_id register.
*/
if (chip_id == man_id
+ && (address == 0x4F || address == 0x4D)
&& (reg_config1 & 0x1F) == (man_id & 0x0F)
&& reg_convrate <= 0x09) {
kind = max6657;
+ } else
+ /* The chip_id register of the MAX6680 and MAX6681
+ * holds the revision of the chip.
+ * the lowest bit of the config1 register is unused
+ * and should return zero when read, so should the
+ * second to last bit of config1 (software reset)
+ */
+ if (chip_id == 0x01
+ && (reg_config1 & 0x03) == 0x00
+ && reg_convrate <= 0x07) {
+ kind = max6680;
}
}
@@ -599,6 +625,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
name = "lm86";
} else if (kind == max6657) {
name = "max6657";
+ } else if (kind == max6680) {
+ name = "max6680";
} else if (kind == adt7461) {
name = "adt7461";
}
@@ -646,7 +674,8 @@ exit:
static void lm90_init_client(struct i2c_client *client)
{
- u8 config;
+ u8 config, config_orig;
+ struct lm90_data *data = i2c_get_clientdata(client);
/*
* Start the conversions.
@@ -657,9 +686,20 @@ static void lm90_init_client(struct i2c_client *client)
dev_warn(&client->dev, "Initialization failed!\n");
return;
}
- if (config & 0x40)
- i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
- config & 0xBF); /* run */
+ config_orig = config;
+
+ /*
+ * Put MAX6680/MAX8881 into extended resolution (bit 0x10,
+ * 0.125 degree resolution) and range (0x08, extend range
+ * to -64 degree) mode for the remote temperature sensor.
+ */
+ if (data->kind == max6680) {
+ config |= 0x18;
+ }
+
+ config &= 0xBF; /* run */
+ if (config != config_orig) /* Only write if changed */
+ i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
}
static int lm90_detach_client(struct i2c_client *client)