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

Signed-off-by: Rainer Birkenmaier <rainer.birkenmaier@siemens.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
This commit is contained in:
Rainer Birkenmaier 2007-06-09 10:11:16 -04:00 committed by Mark M. Hoffman
parent 2df6d81157
commit 32c82a9347
3 changed files with 85 additions and 25 deletions

View file

@ -48,6 +48,18 @@ Supported chips:
Addresses scanned: I2C 0x4c, 0x4d (unsupported 0x4e)
Datasheet: Publicly available at the Maxim website
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>
@ -59,11 +71,15 @@ Description
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
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.
Note that there is no easy way to differentiate between the last three
variants. The extra address and features of the MAX6659 are not supported by
this driver. Additionally, the ADT7461 is supported if found in ADM1032
compatibility mode.
the MAX6657, MAX6658, MAX6659, MAX6680 and the MAX6681 all of which are
supported by this driver.
Note that there is no easy way to differentiate between the MAX6657,
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
family is that it features critical limits with hysteresis, and an
@ -93,18 +109,22 @@ ADM1032:
* ALERT is triggered by open remote sensor.
* SMBus PEC support for Write Byte and Receive Byte transactions.
ADT7461
ADT7461:
* Extended temperature range (breaks compatibility)
* Lower resolution for remote temperature
MAX6657 and MAX6658:
* Remote sensor type selection
MAX6659
MAX6659:
* Selectable address
* Second critical temperature limit
* Remote sensor type selection
MAX6680 and MAX6681:
* Selectable address
* Remote sensor type selection
All temperature values are given in degrees Celsius. Resolution
is 1.0 degree for the local temperature, 0.125 degree for the remote
temperature.

View file

@ -365,8 +365,8 @@ config SENSORS_LM90
depends on I2C
help
If you say yes here you get support for National Semiconductor LM90,
LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and
MAX6658 sensor chips.
LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657,
MAX6658, MAX6659, MAX6680 and MAX6681 sensor chips.
The Analog Devices ADT7461 sensor chip is also supported, but only
if found in ADM1032 compatibility mode.

View file

@ -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
@ -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)