Commit 82f6ee75 authored by Jean Delvare's avatar Jean Delvare Committed by Greg Kroah-Hartman

[PATCH] I2C: Add support for LM86, MAX6657 and MAX6658 to lm90

This adds support for the LM86, MAX6657 and MAX6658 sensor chips to the
lm90 driver. These are less popular than the LM90 and ADM1032 but
several users have reported to use these, so I added support to the lm90
driver. All these chips are fully compatible so that's just a matter of
accepting the new chip ids. I also slightly simplified the detection
code.


Signed-off-by: Jean Delvare <khali at linux-fr dot org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 290939b3
...@@ -150,7 +150,8 @@ config SENSORS_LM90 ...@@ -150,7 +150,8 @@ config SENSORS_LM90
select I2C_SENSOR select I2C_SENSOR
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,
LM89 and LM99, and Analog Devices ADM1032 sensor chips. LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and
MAX6658 sensor chips.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called lm90. will be called lm90.
......
...@@ -21,11 +21,26 @@ ...@@ -21,11 +21,26 @@
* http://www.national.com/pf/LM/LM99.html * http://www.national.com/pf/LM/LM99.html
* Note that there is no way to differenciate between both chips. * Note that there is no way to differenciate between both chips.
* *
* This driver also supports the LM86, another sensor chip made by
* National Semiconductor. It is exactly similar to the LM90 except it
* has a higher accuracy.
* Complete datasheet can be obtained from National's website at:
* http://www.national.com/pf/LM/LM86.html
*
* This driver also supports the ADM1032, a sensor chip made by Analog * This driver also supports the ADM1032, a sensor chip made by Analog
* Devices. That chip is similar to the LM90, with a few differences * Devices. That chip is similar to the LM90, with a few differences
* that are not handled by this driver. Complete datasheet can be * that are not handled by this driver. Complete datasheet can be
* obtained from Analog's website at: * obtained from Analog's website at:
* http://products.analog.com/products/info.asp?product=ADM1032 * http://products.analog.com/products/info.asp?product=ADM1032
* Among others, it has a higher accuracy than the LM90, much like the
* LM86 does.
*
* This driver also supports the MAX6657 and MAX6658, sensor chips made
* by Maxim. These chips are similar to the LM86. Complete datasheet
* can be obtained at Maxim's website at:
* http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
* Note that there is no way to differenciate between both chips (but
* no need either).
* *
* Since the LM90 was the first chipset supported by this driver, most * Since the LM90 was the first chipset supported by this driver, most
* comments will refer to this chipset, but are actually general and * comments will refer to this chipset, but are actually general and
...@@ -56,7 +71,7 @@ ...@@ -56,7 +71,7 @@
/* /*
* Addresses to scan * Addresses to scan
* Address is fully defined internally and cannot be changed. * Address is fully defined internally and cannot be changed.
* LM89, LM90, LM99 and ADM1032 have address 0x4c. * LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c.
* LM89-1, and LM99-1 have address 0x4d. * LM89-1, and LM99-1 have address 0x4d.
*/ */
...@@ -69,7 +84,7 @@ static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END }; ...@@ -69,7 +84,7 @@ static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END };
* Insmod parameters * Insmod parameters
*/ */
SENSORS_INSMOD_3(lm90, adm1032, lm99); SENSORS_INSMOD_5(lm90, adm1032, lm99, lm86, max6657);
/* /*
* The LM90 registers * The LM90 registers
...@@ -289,7 +304,6 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -289,7 +304,6 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
struct lm90_data *data; struct lm90_data *data;
int err = 0; int err = 0;
const char *name = ""; const char *name = "";
u8 reg_config1=0, reg_convrate=0;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit; goto exit;
...@@ -319,28 +333,22 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -319,28 +333,22 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
* requested, so both the detection and the identification steps * requested, so both the detection and the identification steps
* are skipped. * are skipped.
*/ */
if (kind < 0) { /* detection */
reg_config1 = i2c_smbus_read_byte_data(new_client,
LM90_REG_R_CONFIG1);
reg_convrate = i2c_smbus_read_byte_data(new_client,
LM90_REG_R_CONVRATE);
if ((reg_config1 & 0x2A) != 0x00 /* Default to an LM90 if forced */
|| reg_convrate > 0x0A) { if (kind == 0)
dev_dbg(&adapter->dev, kind = lm90;
"LM90 detection failed at 0x%02x.\n",
address);
goto exit_free;
}
}
if (kind <= 0) { /* identification */ if (kind < 0) { /* detection and identification */
u8 man_id, chip_id; u8 man_id, chip_id, reg_config1, reg_convrate;
man_id = i2c_smbus_read_byte_data(new_client, man_id = i2c_smbus_read_byte_data(new_client,
LM90_REG_R_MAN_ID); LM90_REG_R_MAN_ID);
chip_id = i2c_smbus_read_byte_data(new_client, chip_id = i2c_smbus_read_byte_data(new_client,
LM90_REG_R_CHIP_ID); LM90_REG_R_CHIP_ID);
reg_config1 = i2c_smbus_read_byte_data(new_client,
LM90_REG_R_CONFIG1);
reg_convrate = i2c_smbus_read_byte_data(new_client,
LM90_REG_R_CONVRATE);
if (man_id == 0x01) { /* National Semiconductor */ if (man_id == 0x01) { /* National Semiconductor */
u8 reg_config2; u8 reg_config2;
...@@ -348,25 +356,36 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -348,25 +356,36 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
reg_config2 = i2c_smbus_read_byte_data(new_client, reg_config2 = i2c_smbus_read_byte_data(new_client,
LM90_REG_R_CONFIG2); LM90_REG_R_CONFIG2);
if (kind == 0 /* skip detection */ if ((reg_config1 & 0x2A) == 0x00
|| ((reg_config2 & 0xF8) == 0x00 && (reg_config2 & 0xF8) == 0x00
&& reg_convrate <= 0x09)) { && reg_convrate <= 0x09) {
if (address == 0x4C if (address == 0x4C
&& (chip_id & 0xF0) == 0x20) { /* LM90 */ && (chip_id & 0xF0) == 0x20) { /* LM90 */
kind = lm90; kind = lm90;
} else } else
if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */ if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */
kind = lm99; kind = lm99;
} else
if (address == 0x4C
&& (chip_id & 0xF0) == 0x10) { /* LM86 */
kind = lm86;
} }
} }
} else } else
if (man_id == 0x41) { /* Analog Devices */ if (man_id == 0x41) { /* Analog Devices */
if (address == 0x4C if (address == 0x4C
&& (chip_id & 0xF0) == 0x40 /* ADM1032 */ && (chip_id & 0xF0) == 0x40 /* ADM1032 */
&& (kind == 0 /* skip detection */ && (reg_config1 & 0x3F) == 0x00
|| (reg_config1 & 0x3F) == 0x00)) { && reg_convrate <= 0x0A) {
kind = adm1032; kind = adm1032;
} }
} else
if (man_id == 0x4D) { /* Maxim */
if (address == 0x4C
&& (reg_config1 & 0x1F) == 0
&& reg_convrate <= 0x09) {
kind = max6657;
}
} }
if (kind <= 0) { /* identification failed */ if (kind <= 0) { /* identification failed */
...@@ -383,6 +402,10 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -383,6 +402,10 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
name = "adm1032"; name = "adm1032";
} else if (kind == lm99) { } else if (kind == lm99) {
name = "lm99"; name = "lm99";
} else if (kind == lm86) {
name = "lm86";
} else if (kind == max6657) {
name = "max6657";
} }
/* We can fill in the remaining client fields */ /* We can fill in the remaining client fields */
......
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