mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
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:
parent
2df6d81157
commit
32c82a9347
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
®_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)
|
||||
|
Loading…
Reference in New Issue
Block a user