diff options
author | Andrew F. Davis <afd@ti.com> | 2016-06-08 13:00:54 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2016-06-27 21:58:03 -0400 |
commit | c0a68601804dcb4ee8a141e42e1e6893b6b0610c (patch) | |
tree | 7ae376294c5bdd533986f2e3002ac49b79008253 | |
parent | 7c84f7f80d6fcea36246b793d06c3555ca53ddcd (diff) |
hwmon: (tmp401) Add support for TI TMP461
Signed-off-by: Andrew F. Davis <afd@ti.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | Documentation/hwmon/tmp401 | 14 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 2 | ||||
-rw-r--r-- | drivers/hwmon/tmp401.c | 35 |
3 files changed, 42 insertions, 9 deletions
diff --git a/Documentation/hwmon/tmp401 b/Documentation/hwmon/tmp401 index 711f75e189eb..2d9ca42213cf 100644 --- a/Documentation/hwmon/tmp401 +++ b/Documentation/hwmon/tmp401 | |||
@@ -22,6 +22,9 @@ Supported chips: | |||
22 | Prefix: 'tmp435' | 22 | Prefix: 'tmp435' |
23 | Addresses scanned: I2C 0x48 - 0x4f | 23 | Addresses scanned: I2C 0x48 - 0x4f |
24 | Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html | 24 | Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html |
25 | * Texas Instruments TMP461 | ||
26 | Prefix: 'tmp461' | ||
27 | Datasheet: http://www.ti.com/product/tmp461 | ||
25 | 28 | ||
26 | Authors: | 29 | Authors: |
27 | Hans de Goede <hdegoede@redhat.com> | 30 | Hans de Goede <hdegoede@redhat.com> |
@@ -31,8 +34,8 @@ Description | |||
31 | ----------- | 34 | ----------- |
32 | 35 | ||
33 | This driver implements support for Texas Instruments TMP401, TMP411, | 36 | This driver implements support for Texas Instruments TMP401, TMP411, |
34 | TMP431, TMP432 and TMP435 chips. These chips implement one or two remote | 37 | TMP431, TMP432, TMP435, and TMP461 chips. These chips implement one or two |
35 | and one local temperature sensors. Temperature is measured in degrees | 38 | remote and one local temperature sensors. Temperature is measured in degrees |
36 | Celsius. Resolution of the remote sensor is 0.0625 degree. Local | 39 | Celsius. Resolution of the remote sensor is 0.0625 degree. Local |
37 | sensor resolution can be set to 0.5, 0.25, 0.125 or 0.0625 degree (not | 40 | sensor resolution can be set to 0.5, 0.25, 0.125 or 0.0625 degree (not |
38 | supported by the driver so far, so using the default resolution of 0.5 | 41 | supported by the driver so far, so using the default resolution of 0.5 |
@@ -55,3 +58,10 @@ some additional features. | |||
55 | 58 | ||
56 | TMP432 is compatible with TMP401 and TMP431. It supports two external | 59 | TMP432 is compatible with TMP401 and TMP431. It supports two external |
57 | temperature sensors. | 60 | temperature sensors. |
61 | |||
62 | TMP461 is compatible with TMP401. It supports offset correction | ||
63 | that is applied to the remote sensor. | ||
64 | |||
65 | * Sensor offset values are temperature values | ||
66 | |||
67 | Exported via sysfs attribute tempX_offset | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index e0be99a4615c..be63b140a976 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -1572,7 +1572,7 @@ config SENSORS_TMP401 | |||
1572 | depends on I2C | 1572 | depends on I2C |
1573 | help | 1573 | help |
1574 | If you say yes here you get support for Texas Instruments TMP401, | 1574 | If you say yes here you get support for Texas Instruments TMP401, |
1575 | TMP411, TMP431, TMP432 and TMP435 temperature sensor chips. | 1575 | TMP411, TMP431, TMP432, TMP435, and TMP461 temperature sensor chips. |
1576 | 1576 | ||
1577 | This driver can also be built as a module. If so, the module | 1577 | This driver can also be built as a module. If so, the module |
1578 | will be called tmp401. | 1578 | will be called tmp401. |
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index ccf4cffe0ee1..eeeed2c7d081 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c | |||
@@ -47,7 +47,7 @@ | |||
47 | static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, | 47 | static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, |
48 | 0x4e, 0x4f, I2C_CLIENT_END }; | 48 | 0x4e, 0x4f, I2C_CLIENT_END }; |
49 | 49 | ||
50 | enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; | 50 | enum chips { tmp401, tmp411, tmp431, tmp432, tmp435, tmp461 }; |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * The TMP401 registers, note some registers have different addresses for | 53 | * The TMP401 registers, note some registers have different addresses for |
@@ -62,31 +62,34 @@ enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; | |||
62 | #define TMP401_MANUFACTURER_ID_REG 0xFE | 62 | #define TMP401_MANUFACTURER_ID_REG 0xFE |
63 | #define TMP401_DEVICE_ID_REG 0xFF | 63 | #define TMP401_DEVICE_ID_REG 0xFF |
64 | 64 | ||
65 | static const u8 TMP401_TEMP_MSB_READ[6][2] = { | 65 | static const u8 TMP401_TEMP_MSB_READ[7][2] = { |
66 | { 0x00, 0x01 }, /* temp */ | 66 | { 0x00, 0x01 }, /* temp */ |
67 | { 0x06, 0x08 }, /* low limit */ | 67 | { 0x06, 0x08 }, /* low limit */ |
68 | { 0x05, 0x07 }, /* high limit */ | 68 | { 0x05, 0x07 }, /* high limit */ |
69 | { 0x20, 0x19 }, /* therm (crit) limit */ | 69 | { 0x20, 0x19 }, /* therm (crit) limit */ |
70 | { 0x30, 0x34 }, /* lowest */ | 70 | { 0x30, 0x34 }, /* lowest */ |
71 | { 0x32, 0x36 }, /* highest */ | 71 | { 0x32, 0x36 }, /* highest */ |
72 | { 0, 0x11 }, /* offset */ | ||
72 | }; | 73 | }; |
73 | 74 | ||
74 | static const u8 TMP401_TEMP_MSB_WRITE[6][2] = { | 75 | static const u8 TMP401_TEMP_MSB_WRITE[7][2] = { |
75 | { 0, 0 }, /* temp (unused) */ | 76 | { 0, 0 }, /* temp (unused) */ |
76 | { 0x0C, 0x0E }, /* low limit */ | 77 | { 0x0C, 0x0E }, /* low limit */ |
77 | { 0x0B, 0x0D }, /* high limit */ | 78 | { 0x0B, 0x0D }, /* high limit */ |
78 | { 0x20, 0x19 }, /* therm (crit) limit */ | 79 | { 0x20, 0x19 }, /* therm (crit) limit */ |
79 | { 0x30, 0x34 }, /* lowest */ | 80 | { 0x30, 0x34 }, /* lowest */ |
80 | { 0x32, 0x36 }, /* highest */ | 81 | { 0x32, 0x36 }, /* highest */ |
82 | { 0, 0x11 }, /* offset */ | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | static const u8 TMP401_TEMP_LSB[6][2] = { | 85 | static const u8 TMP401_TEMP_LSB[7][2] = { |
84 | { 0x15, 0x10 }, /* temp */ | 86 | { 0x15, 0x10 }, /* temp */ |
85 | { 0x17, 0x14 }, /* low limit */ | 87 | { 0x17, 0x14 }, /* low limit */ |
86 | { 0x16, 0x13 }, /* high limit */ | 88 | { 0x16, 0x13 }, /* high limit */ |
87 | { 0, 0 }, /* therm (crit) limit (unused) */ | 89 | { 0, 0 }, /* therm (crit) limit (unused) */ |
88 | { 0x31, 0x35 }, /* lowest */ | 90 | { 0x31, 0x35 }, /* lowest */ |
89 | { 0x33, 0x37 }, /* highest */ | 91 | { 0x33, 0x37 }, /* highest */ |
92 | { 0, 0x12 }, /* offset */ | ||
90 | }; | 93 | }; |
91 | 94 | ||
92 | static const u8 TMP432_TEMP_MSB_READ[4][3] = { | 95 | static const u8 TMP432_TEMP_MSB_READ[4][3] = { |
@@ -149,6 +152,7 @@ static const struct i2c_device_id tmp401_id[] = { | |||
149 | { "tmp431", tmp431 }, | 152 | { "tmp431", tmp431 }, |
150 | { "tmp432", tmp432 }, | 153 | { "tmp432", tmp432 }, |
151 | { "tmp435", tmp435 }, | 154 | { "tmp435", tmp435 }, |
155 | { "tmp461", tmp461 }, | ||
152 | { } | 156 | { } |
153 | }; | 157 | }; |
154 | MODULE_DEVICE_TABLE(i2c, tmp401_id); | 158 | MODULE_DEVICE_TABLE(i2c, tmp401_id); |
@@ -170,7 +174,7 @@ struct tmp401_data { | |||
170 | /* register values */ | 174 | /* register values */ |
171 | u8 status[4]; | 175 | u8 status[4]; |
172 | u8 config; | 176 | u8 config; |
173 | u16 temp[6][3]; | 177 | u16 temp[7][3]; |
174 | u8 temp_crit_hyst; | 178 | u8 temp_crit_hyst; |
175 | }; | 179 | }; |
176 | 180 | ||
@@ -613,6 +617,22 @@ static const struct attribute_group tmp432_group = { | |||
613 | }; | 617 | }; |
614 | 618 | ||
615 | /* | 619 | /* |
620 | * Additional features of the TMP461 chip. | ||
621 | * The TMP461 temperature offset for the remote channel. | ||
622 | */ | ||
623 | static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IWUSR | S_IRUGO, show_temp, | ||
624 | store_temp, 6, 1); | ||
625 | |||
626 | static struct attribute *tmp461_attributes[] = { | ||
627 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | ||
628 | NULL | ||
629 | }; | ||
630 | |||
631 | static const struct attribute_group tmp461_group = { | ||
632 | .attrs = tmp461_attributes, | ||
633 | }; | ||
634 | |||
635 | /* | ||
616 | * Begin non sysfs callback code (aka Real code) | 636 | * Begin non sysfs callback code (aka Real code) |
617 | */ | 637 | */ |
618 | 638 | ||
@@ -714,7 +734,7 @@ static int tmp401_probe(struct i2c_client *client, | |||
714 | const struct i2c_device_id *id) | 734 | const struct i2c_device_id *id) |
715 | { | 735 | { |
716 | static const char * const names[] = { | 736 | static const char * const names[] = { |
717 | "TMP401", "TMP411", "TMP431", "TMP432", "TMP435" | 737 | "TMP401", "TMP411", "TMP431", "TMP432", "TMP435", "TMP461" |
718 | }; | 738 | }; |
719 | struct device *dev = &client->dev; | 739 | struct device *dev = &client->dev; |
720 | struct device *hwmon_dev; | 740 | struct device *hwmon_dev; |
@@ -745,6 +765,9 @@ static int tmp401_probe(struct i2c_client *client, | |||
745 | if (data->kind == tmp432) | 765 | if (data->kind == tmp432) |
746 | data->groups[groups++] = &tmp432_group; | 766 | data->groups[groups++] = &tmp432_group; |
747 | 767 | ||
768 | if (data->kind == tmp461) | ||
769 | data->groups[groups++] = &tmp461_group; | ||
770 | |||
748 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 771 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, |
749 | data, data->groups); | 772 | data, data->groups); |
750 | if (IS_ERR(hwmon_dev)) | 773 | if (IS_ERR(hwmon_dev)) |