Commit c0a68601 authored by Andrew F. Davis's avatar Andrew F. Davis Committed by Guenter Roeck

hwmon: (tmp401) Add support for TI TMP461

Signed-off-by: default avatarAndrew F. Davis <afd@ti.com>
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent 7c84f7f8
...@@ -22,6 +22,9 @@ Supported chips: ...@@ -22,6 +22,9 @@ Supported chips:
Prefix: 'tmp435' Prefix: 'tmp435'
Addresses scanned: I2C 0x48 - 0x4f Addresses scanned: I2C 0x48 - 0x4f
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html
* Texas Instruments TMP461
Prefix: 'tmp461'
Datasheet: http://www.ti.com/product/tmp461
Authors: Authors:
Hans de Goede <hdegoede@redhat.com> Hans de Goede <hdegoede@redhat.com>
...@@ -31,8 +34,8 @@ Description ...@@ -31,8 +34,8 @@ Description
----------- -----------
This driver implements support for Texas Instruments TMP401, TMP411, This driver implements support for Texas Instruments TMP401, TMP411,
TMP431, TMP432 and TMP435 chips. These chips implement one or two remote TMP431, TMP432, TMP435, and TMP461 chips. These chips implement one or two
and one local temperature sensors. Temperature is measured in degrees remote and one local temperature sensors. Temperature is measured in degrees
Celsius. Resolution of the remote sensor is 0.0625 degree. Local Celsius. Resolution of the remote sensor is 0.0625 degree. Local
sensor resolution can be set to 0.5, 0.25, 0.125 or 0.0625 degree (not sensor resolution can be set to 0.5, 0.25, 0.125 or 0.0625 degree (not
supported by the driver so far, so using the default resolution of 0.5 supported by the driver so far, so using the default resolution of 0.5
...@@ -55,3 +58,10 @@ some additional features. ...@@ -55,3 +58,10 @@ some additional features.
TMP432 is compatible with TMP401 and TMP431. It supports two external TMP432 is compatible with TMP401 and TMP431. It supports two external
temperature sensors. temperature sensors.
TMP461 is compatible with TMP401. It supports offset correction
that is applied to the remote sensor.
* Sensor offset values are temperature values
Exported via sysfs attribute tempX_offset
...@@ -1572,7 +1572,7 @@ config SENSORS_TMP401 ...@@ -1572,7 +1572,7 @@ config SENSORS_TMP401
depends on I2C depends on I2C
help help
If you say yes here you get support for Texas Instruments TMP401, If you say yes here you get support for Texas Instruments TMP401,
TMP411, TMP431, TMP432 and TMP435 temperature sensor chips. TMP411, TMP431, TMP432, TMP435, and TMP461 temperature 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 tmp401. will be called tmp401.
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d,
0x4e, 0x4f, I2C_CLIENT_END }; 0x4e, 0x4f, I2C_CLIENT_END };
enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; enum chips { tmp401, tmp411, tmp431, tmp432, tmp435, tmp461 };
/* /*
* The TMP401 registers, note some registers have different addresses for * The TMP401 registers, note some registers have different addresses for
...@@ -62,31 +62,34 @@ enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; ...@@ -62,31 +62,34 @@ enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 };
#define TMP401_MANUFACTURER_ID_REG 0xFE #define TMP401_MANUFACTURER_ID_REG 0xFE
#define TMP401_DEVICE_ID_REG 0xFF #define TMP401_DEVICE_ID_REG 0xFF
static const u8 TMP401_TEMP_MSB_READ[6][2] = { static const u8 TMP401_TEMP_MSB_READ[7][2] = {
{ 0x00, 0x01 }, /* temp */ { 0x00, 0x01 }, /* temp */
{ 0x06, 0x08 }, /* low limit */ { 0x06, 0x08 }, /* low limit */
{ 0x05, 0x07 }, /* high limit */ { 0x05, 0x07 }, /* high limit */
{ 0x20, 0x19 }, /* therm (crit) limit */ { 0x20, 0x19 }, /* therm (crit) limit */
{ 0x30, 0x34 }, /* lowest */ { 0x30, 0x34 }, /* lowest */
{ 0x32, 0x36 }, /* highest */ { 0x32, 0x36 }, /* highest */
{ 0, 0x11 }, /* offset */
}; };
static const u8 TMP401_TEMP_MSB_WRITE[6][2] = { static const u8 TMP401_TEMP_MSB_WRITE[7][2] = {
{ 0, 0 }, /* temp (unused) */ { 0, 0 }, /* temp (unused) */
{ 0x0C, 0x0E }, /* low limit */ { 0x0C, 0x0E }, /* low limit */
{ 0x0B, 0x0D }, /* high limit */ { 0x0B, 0x0D }, /* high limit */
{ 0x20, 0x19 }, /* therm (crit) limit */ { 0x20, 0x19 }, /* therm (crit) limit */
{ 0x30, 0x34 }, /* lowest */ { 0x30, 0x34 }, /* lowest */
{ 0x32, 0x36 }, /* highest */ { 0x32, 0x36 }, /* highest */
{ 0, 0x11 }, /* offset */
}; };
static const u8 TMP401_TEMP_LSB[6][2] = { static const u8 TMP401_TEMP_LSB[7][2] = {
{ 0x15, 0x10 }, /* temp */ { 0x15, 0x10 }, /* temp */
{ 0x17, 0x14 }, /* low limit */ { 0x17, 0x14 }, /* low limit */
{ 0x16, 0x13 }, /* high limit */ { 0x16, 0x13 }, /* high limit */
{ 0, 0 }, /* therm (crit) limit (unused) */ { 0, 0 }, /* therm (crit) limit (unused) */
{ 0x31, 0x35 }, /* lowest */ { 0x31, 0x35 }, /* lowest */
{ 0x33, 0x37 }, /* highest */ { 0x33, 0x37 }, /* highest */
{ 0, 0x12 }, /* offset */
}; };
static const u8 TMP432_TEMP_MSB_READ[4][3] = { static const u8 TMP432_TEMP_MSB_READ[4][3] = {
...@@ -149,6 +152,7 @@ static const struct i2c_device_id tmp401_id[] = { ...@@ -149,6 +152,7 @@ static const struct i2c_device_id tmp401_id[] = {
{ "tmp431", tmp431 }, { "tmp431", tmp431 },
{ "tmp432", tmp432 }, { "tmp432", tmp432 },
{ "tmp435", tmp435 }, { "tmp435", tmp435 },
{ "tmp461", tmp461 },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, tmp401_id); MODULE_DEVICE_TABLE(i2c, tmp401_id);
...@@ -170,7 +174,7 @@ struct tmp401_data { ...@@ -170,7 +174,7 @@ struct tmp401_data {
/* register values */ /* register values */
u8 status[4]; u8 status[4];
u8 config; u8 config;
u16 temp[6][3]; u16 temp[7][3];
u8 temp_crit_hyst; u8 temp_crit_hyst;
}; };
...@@ -612,6 +616,22 @@ static const struct attribute_group tmp432_group = { ...@@ -612,6 +616,22 @@ static const struct attribute_group tmp432_group = {
.attrs = tmp432_attributes, .attrs = tmp432_attributes,
}; };
/*
* Additional features of the TMP461 chip.
* The TMP461 temperature offset for the remote channel.
*/
static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IWUSR | S_IRUGO, show_temp,
store_temp, 6, 1);
static struct attribute *tmp461_attributes[] = {
&sensor_dev_attr_temp2_offset.dev_attr.attr,
NULL
};
static const struct attribute_group tmp461_group = {
.attrs = tmp461_attributes,
};
/* /*
* Begin non sysfs callback code (aka Real code) * Begin non sysfs callback code (aka Real code)
*/ */
...@@ -714,7 +734,7 @@ static int tmp401_probe(struct i2c_client *client, ...@@ -714,7 +734,7 @@ static int tmp401_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
static const char * const names[] = { static const char * const names[] = {
"TMP401", "TMP411", "TMP431", "TMP432", "TMP435" "TMP401", "TMP411", "TMP431", "TMP432", "TMP435", "TMP461"
}; };
struct device *dev = &client->dev; struct device *dev = &client->dev;
struct device *hwmon_dev; struct device *hwmon_dev;
...@@ -745,6 +765,9 @@ static int tmp401_probe(struct i2c_client *client, ...@@ -745,6 +765,9 @@ static int tmp401_probe(struct i2c_client *client,
if (data->kind == tmp432) if (data->kind == tmp432)
data->groups[groups++] = &tmp432_group; data->groups[groups++] = &tmp432_group;
if (data->kind == tmp461)
data->groups[groups++] = &tmp461_group;
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data, data->groups); data, data->groups);
if (IS_ERR(hwmon_dev)) if (IS_ERR(hwmon_dev))
......
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