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:
Родитель
2df6d81157
Коммит
32c82a9347
|
@ -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
|
||||||
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:
|
||||||
* 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
|
||||||
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 @@
|
||||||
* 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 @@
|
||||||
/*
|
/*
|
||||||
* 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)
|
||||||
®_convrate) < 0)
|
®_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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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)
|
||||||
} 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)
|
||||||
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 @@ exit:
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче