Commit 32c82a93 authored by Rainer Birkenmaier's avatar Rainer Birkenmaier Committed by Mark M. Hoffman

hwmon/lm90: Add support for the Maxim MAX6680/MAX6681

Signed-off-by: default avatarRainer Birkenmaier <rainer.birkenmaier@siemens.com>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent 2df6d811
...@@ -48,6 +48,18 @@ Supported chips: ...@@ -48,6 +48,18 @@ Supported chips:
Addresses scanned: I2C 0x4c, 0x4d (unsupported 0x4e) Addresses scanned: I2C 0x4c, 0x4d (unsupported 0x4e)
Datasheet: Publicly available at the Maxim website Datasheet: Publicly available at the Maxim website
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
* Maxim MAX6680
Prefix: 'max6680'
Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b,
0x4c, 0x4d and 0x4e
Datasheet: Publicly available at the Maxim website
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370
* Maxim MAX6681
Prefix: 'max6680'
Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b,
0x4c, 0x4d and 0x4e
Datasheet: Publicly available at the Maxim website
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370
Author: Jean Delvare <khali@linux-fr.org> Author: Jean Delvare <khali@linux-fr.org>
...@@ -59,11 +71,15 @@ Description ...@@ -59,11 +71,15 @@ Description
The LM90 is a digital temperature sensor. It senses its own temperature as The LM90 is a digital temperature sensor. It senses its own temperature as
well as the temperature of up to one external diode. It is compatible well as the temperature of up to one external diode. It is compatible
with many other devices such as the LM86, the LM89, the LM99, the ADM1032, with many other devices such as the LM86, the LM89, the LM99, the ADM1032,
the MAX6657, MAX6658 and the MAX6659 all of which are supported by this driver. the MAX6657, MAX6658, MAX6659, MAX6680 and the MAX6681 all of which are
Note that there is no easy way to differentiate between the last three supported by this driver.
variants. The extra address and features of the MAX6659 are not supported by
this driver. Additionally, the ADT7461 is supported if found in ADM1032 Note that there is no easy way to differentiate between the MAX6657,
compatibility mode. MAX6658 and MAX6659 variants. The extra address and features of the
MAX6659 are not supported by this driver. The MAX6680 and MAX6681 only
differ in their pinout, therefore they obviously can't (and don't need to)
be distinguished. Additionally, the ADT7461 is supported if found in
ADM1032 compatibility mode.
The specificity of this family of chipsets over the ADM1021/LM84 The specificity of this family of chipsets over the ADM1021/LM84
family is that it features critical limits with hysteresis, and an family is that it features critical limits with hysteresis, and an
...@@ -93,18 +109,22 @@ ADM1032: ...@@ -93,18 +109,22 @@ ADM1032:
* ALERT is triggered by open remote sensor. * ALERT is triggered by open remote sensor.
* SMBus PEC support for Write Byte and Receive Byte transactions. * SMBus PEC support for Write Byte and Receive Byte transactions.
ADT7461 ADT7461:
* Extended temperature range (breaks compatibility) * Extended temperature range (breaks compatibility)
* Lower resolution for remote temperature * Lower resolution for remote temperature
MAX6657 and MAX6658: MAX6657 and MAX6658:
* Remote sensor type selection * Remote sensor type selection
MAX6659 MAX6659:
* Selectable address * Selectable address
* Second critical temperature limit * Second critical temperature limit
* Remote sensor type selection * Remote sensor type selection
MAX6680 and MAX6681:
* Selectable address
* Remote sensor type selection
All temperature values are given in degrees Celsius. Resolution All temperature values are given in degrees Celsius. Resolution
is 1.0 degree for the local temperature, 0.125 degree for the remote is 1.0 degree for the local temperature, 0.125 degree for the remote
temperature. temperature.
......
...@@ -365,8 +365,8 @@ config SENSORS_LM90 ...@@ -365,8 +365,8 @@ config SENSORS_LM90
depends on I2C depends on I2C
help help
If you say yes here you get support for National Semiconductor LM90, If you say yes here you get support for National Semiconductor LM90,
LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657,
MAX6658 sensor chips. MAX6658, MAX6659, MAX6680 and MAX6681 sensor chips.
The Analog Devices ADT7461 sensor chip is also supported, but only The Analog Devices ADT7461 sensor chip is also supported, but only
if found in ADM1032 compatibility mode. if found in ADM1032 compatibility mode.
......
...@@ -43,6 +43,13 @@ ...@@ -43,6 +43,13 @@
* variants. The extra address and features of the MAX6659 are not * variants. The extra address and features of the MAX6659 are not
* supported by this driver. * 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 * This driver also supports the ADT7461 chip from Analog Devices but
* only in its "compatability mode". If an ADT7461 chip is found but * only in its "compatability mode". If an ADT7461 chip is found but
* is configured in non-compatible mode (where its temperature * is configured in non-compatible mode (where its temperature
...@@ -84,20 +91,25 @@ ...@@ -84,20 +91,25 @@
/* /*
* Addresses to scan * Addresses to scan
* Address is fully defined internally and cannot be changed except for * 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 * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658
* have address 0x4c. * have address 0x4c.
* ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d. * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d.
* MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). * 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 * 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 * The LM90 registers
...@@ -525,7 +537,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -525,7 +537,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
&reg_convrate) < 0) &reg_convrate) < 0)
goto exit_free; goto exit_free;
if (man_id == 0x01) { /* National Semiconductor */ if ((address == 0x4C || address == 0x4D)
&& man_id == 0x01) { /* National Semiconductor */
u8 reg_config2; u8 reg_config2;
if (lm90_read_reg(new_client, LM90_REG_R_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) ...@@ -548,7 +561,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
} }
} }
} else } else
if (man_id == 0x41) { /* Analog Devices */ if ((address == 0x4C || address == 0x4D)
&& man_id == 0x41) { /* Analog Devices */
if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
&& (reg_config1 & 0x3F) == 0x00 && (reg_config1 & 0x3F) == 0x00
&& reg_convrate <= 0x0A) { && reg_convrate <= 0x0A) {
...@@ -562,18 +576,30 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -562,18 +576,30 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
} else } else
if (man_id == 0x4D) { /* Maxim */ if (man_id == 0x4D) { /* Maxim */
/* /*
* The Maxim variants do NOT have a chip_id register. * The MAX6657, MAX6658 and MAX6659 do NOT have a
* Reading from that address will return the last read * chip_id register. Reading from that address will
* value, which in our case is those of the man_id * return the last read value, which in our case is
* register. Likewise, the config1 register seems to * those of the man_id register. Likewise, the config1
* lack a low nibble, so the value will be those of the * register seems to lack a low nibble, so the value
* previous read, so in our case those of the man_id * will be those of the previous read, so in our case
* register. * those of the man_id register.
*/ */
if (chip_id == man_id if (chip_id == man_id
&& (address == 0x4F || address == 0x4D)
&& (reg_config1 & 0x1F) == (man_id & 0x0F) && (reg_config1 & 0x1F) == (man_id & 0x0F)
&& reg_convrate <= 0x09) { && reg_convrate <= 0x09) {
kind = max6657; 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) ...@@ -599,6 +625,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
name = "lm86"; name = "lm86";
} else if (kind == max6657) { } else if (kind == max6657) {
name = "max6657"; name = "max6657";
} else if (kind == max6680) {
name = "max6680";
} else if (kind == adt7461) { } else if (kind == adt7461) {
name = "adt7461"; name = "adt7461";
} }
...@@ -646,7 +674,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -646,7 +674,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
static void lm90_init_client(struct i2c_client *client) 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. * Start the conversions.
...@@ -657,9 +686,20 @@ static void lm90_init_client(struct i2c_client *client) ...@@ -657,9 +686,20 @@ static void lm90_init_client(struct i2c_client *client)
dev_warn(&client->dev, "Initialization failed!\n"); dev_warn(&client->dev, "Initialization failed!\n");
return; return;
} }
if (config & 0x40) config_orig = config;
i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
config & 0xBF); /* run */ /*
* 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) static int lm90_detach_client(struct i2c_client *client)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment