aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2009-12-09 14:36:05 -0500
committerJean Delvare <khali@linux-fr.org>2009-12-09 14:36:05 -0500
commit3d849981711741e76e501e4b9e3e7b792f2b0fd5 (patch)
tree0948d147f41b9d637cd2b2ef9afb044983dcd59f
parentd656b6fde2531a13c4e68a3ce6b9f12bc19d96bb (diff)
hwmon: (adt7475) Add support for the ADT7490
Add support for the Analog Devices ADT7490 chip. This chip is largely compatible with the ADT7473 and ADT7475, with additional features. In particular, it has 6 voltage inputs instead of 2. Signed-off-by: Jean Delvare <khali@linux-fr.org> Cc: Hans de Goede <hdegoede@redhat.com> Cc: Jordan Crouse <jordan@cosmicpenguin.net> Cc: "Darrick J. Wong" <djwong@us.ibm.com>
-rw-r--r--Documentation/hwmon/adt747534
-rw-r--r--drivers/hwmon/Kconfig4
-rw-r--r--drivers/hwmon/adt7475.c115
3 files changed, 134 insertions, 19 deletions
diff --git a/Documentation/hwmon/adt7475 b/Documentation/hwmon/adt7475
index ebfee5524020..f08f28715b84 100644
--- a/Documentation/hwmon/adt7475
+++ b/Documentation/hwmon/adt7475
@@ -10,24 +10,31 @@ Supported chips:
10 Prefix: 'adt7475' 10 Prefix: 'adt7475'
11 Addresses scanned: I2C 0x2E 11 Addresses scanned: I2C 0x2E
12 Datasheet: Publicly available at the On Semiconductors website 12 Datasheet: Publicly available at the On Semiconductors website
13 * Analog Devices ADT7490
14 Prefix: 'adt7490'
15 Addresses scanned: I2C 0x2C, 0x2D, 0x2E
16 Datasheet: Publicly available at the On Semiconductors website
13 17
14Authors: 18Authors:
15 Jordan Crouse 19 Jordan Crouse
16 Hans de Goede 20 Hans de Goede
17 Darrick J. Wong (documentation) 21 Darrick J. Wong (documentation)
22 Jean Delvare
18 23
19 24
20Description 25Description
21----------- 26-----------
22 27
23This driver implements support for the Analog Devices ADT7473 and ADT7475 28This driver implements support for the Analog Devices ADT7473, ADT7475 and
24chip family. Both chips differ only in minor details. They will be 29ADT7490 chip family. The ADT7473 and ADT7475 differ only in minor details.
25collectively designed by the name "ADT747x" in the rest of this document. 30The ADT7490 has additional features, including extra voltage measurement
31inputs and PECI support. All the supported chips will be collectively
32designed by the name "ADT747x" in the rest of this document.
26 33
27The ADT747x uses the 2-wire interface compatible with the SMBus 2.0 34The ADT747x uses the 2-wire interface compatible with the SMBus 2.0
28specification. Using an analog to digital converter it measures three (3) 35specification. Using an analog to digital converter it measures three (3)
29temperatures and two (2) voltages. It has four (4) 16-bit counters for 36temperatures and two (2) or more voltages. It has four (4) 16-bit counters
30measuring fan speed. There are three (3) PWM outputs that can be used 37for measuring fan speed. There are three (3) PWM outputs that can be used
31to control fan speed. 38to control fan speed.
32 39
33A sophisticated control system for the PWM outputs is designed into the 40A sophisticated control system for the PWM outputs is designed into the
@@ -45,6 +52,23 @@ The ADT747x samples all inputs continuously. The driver will not read
45the registers more often than once every other second. Further, 52the registers more often than once every other second. Further,
46configuration data is only read once per minute. 53configuration data is only read once per minute.
47 54
55Chip Differences Summary
56------------------------
57
58ADT7473:
59 * 2 voltage inputs
60 * system acoustics optimizations (not implemented)
61
62ADT7475:
63 * 2 voltage inputs
64
65ADT7490:
66 * 6 voltage inputs
67 * 1 Imon input (not implemented)
68 * PECI support (not implemented)
69 * 2 GPIO pins (not implemented)
70 * system acoustics optimizations (not implemented)
71
48Special Features 72Special Features
49---------------- 73----------------
50 74
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 5b2eaff47900..f9f4365349b2 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -205,11 +205,11 @@ config SENSORS_ADT7473
205 will be called adt7473. 205 will be called adt7473.
206 206
207config SENSORS_ADT7475 207config SENSORS_ADT7475
208 tristate "Analog Devices ADT7473 and ADT7475" 208 tristate "Analog Devices ADT7473, ADT7475 and ADT7490"
209 depends on I2C && EXPERIMENTAL 209 depends on I2C && EXPERIMENTAL
210 help 210 help
211 If you say yes here you get support for the Analog Devices 211 If you say yes here you get support for the Analog Devices
212 ADT7473 and ADT7475 hardware monitoring chips. 212 ADT7473, ADT7475 and ADT7490 hardware monitoring chips.
213 213
214 This driver can also be build as a module. If so, the module 214 This driver can also be build as a module. If so, the module
215 will be called adt7475. 215 will be called adt7475.
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index 520773b16544..e495665569e5 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -3,7 +3,8 @@
3 * Copyright (C) 2007-2008, Advanced Micro Devices, Inc. 3 * Copyright (C) 2007-2008, Advanced Micro Devices, Inc.
4 * Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net> 4 * Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net>
5 * Copyright (C) 2008 Hans de Goede <hdegoede@redhat.com> 5 * Copyright (C) 2008 Hans de Goede <hdegoede@redhat.com>
6 6 * Copyright (C) 2009 Jean Delvare <khali@linux-fr.org>
7 *
7 * Derived from the lm83 driver by Jean Delvare 8 * Derived from the lm83 driver by Jean Delvare
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
@@ -39,6 +40,9 @@
39 40
40/* 7475 Common Registers */ 41/* 7475 Common Registers */
41 42
43#define REG_VTT 0x1E /* ADT7490 only */
44#define REG_EXTEND3 0x1F /* ADT7490 only */
45
42#define REG_VOLTAGE_BASE 0x20 46#define REG_VOLTAGE_BASE 0x20
43#define REG_TEMP_BASE 0x25 47#define REG_TEMP_BASE 0x25
44#define REG_TACH_BASE 0x28 48#define REG_TACH_BASE 0x28
@@ -79,6 +83,11 @@
79#define REG_CONFIG5 0x7C 83#define REG_CONFIG5 0x7C
80#define REG_CONFIG4 0x7D 84#define REG_CONFIG4 0x7D
81 85
86#define REG_STATUS4 0x81 /* ADT7490 only */
87
88#define REG_VTT_MIN 0x84 /* ADT7490 only */
89#define REG_VTT_MAX 0x86 /* ADT7490 only */
90
82#define CONFIG4_MAXDUTY 0x08 91#define CONFIG4_MAXDUTY 0x08
83 92
84#define CONFIG5_TWOSCOMP 0x01 93#define CONFIG5_TWOSCOMP 0x01
@@ -119,11 +128,12 @@
119 128
120static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; 129static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
121 130
122I2C_CLIENT_INSMOD_2(adt7473, adt7475); 131I2C_CLIENT_INSMOD_3(adt7473, adt7475, adt7490);
123 132
124static const struct i2c_device_id adt7475_id[] = { 133static const struct i2c_device_id adt7475_id[] = {
125 { "adt7473", adt7473 }, 134 { "adt7473", adt7473 },
126 { "adt7475", adt7475 }, 135 { "adt7475", adt7475 },
136 { "adt7490", adt7490 },
127 { } 137 { }
128}; 138};
129MODULE_DEVICE_TABLE(i2c, adt7475_id); 139MODULE_DEVICE_TABLE(i2c, adt7475_id);
@@ -139,7 +149,7 @@ struct adt7475_data {
139 u8 config4; 149 u8 config4;
140 u8 config5; 150 u8 config5;
141 u8 has_voltage; 151 u8 has_voltage;
142 u16 alarms; 152 u32 alarms;
143 u16 voltage[3][6]; 153 u16 voltage[3][6];
144 u16 temp[7][3]; 154 u16 temp[7][3];
145 u16 tach[2][4]; 155 u16 tach[2][4];
@@ -306,10 +316,17 @@ static ssize_t set_voltage(struct device *dev, struct device_attribute *attr,
306 316
307 data->voltage[sattr->nr][sattr->index] = volt2reg(sattr->index, val); 317 data->voltage[sattr->nr][sattr->index] = volt2reg(sattr->index, val);
308 318
309 if (sattr->nr == MIN) 319 if (sattr->index < ADT7475_VOLTAGE_COUNT) {
310 reg = VOLTAGE_MIN_REG(sattr->index); 320 if (sattr->nr == MIN)
311 else 321 reg = VOLTAGE_MIN_REG(sattr->index);
312 reg = VOLTAGE_MAX_REG(sattr->index); 322 else
323 reg = VOLTAGE_MAX_REG(sattr->index);
324 } else {
325 if (sattr->nr == MIN)
326 reg = REG_VTT_MIN;
327 else
328 reg = REG_VTT_MAX;
329 }
313 330
314 i2c_smbus_write_byte_data(client, reg, 331 i2c_smbus_write_byte_data(client, reg,
315 data->voltage[sattr->nr][sattr->index] >> 2); 332 data->voltage[sattr->nr][sattr->index] >> 2);
@@ -818,6 +835,12 @@ static ssize_t set_pwm_at_crit(struct device *dev,
818 return count; 835 return count;
819} 836}
820 837
838static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_voltage, NULL, INPUT, 0);
839static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_voltage,
840 set_voltage, MAX, 0);
841static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_voltage,
842 set_voltage, MIN, 0);
843static SENSOR_DEVICE_ATTR_2(in0_alarm, S_IRUGO, show_voltage, NULL, ALARM, 0);
821static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_voltage, NULL, INPUT, 1); 844static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_voltage, NULL, INPUT, 1);
822static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_voltage, 845static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_voltage,
823 set_voltage, MAX, 1); 846 set_voltage, MAX, 1);
@@ -830,6 +853,24 @@ static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_voltage,
830static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_voltage, 853static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_voltage,
831 set_voltage, MIN, 2); 854 set_voltage, MIN, 2);
832static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_voltage, NULL, ALARM, 2); 855static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_voltage, NULL, ALARM, 2);
856static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_voltage, NULL, INPUT, 3);
857static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_voltage,
858 set_voltage, MAX, 3);
859static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_voltage,
860 set_voltage, MIN, 3);
861static SENSOR_DEVICE_ATTR_2(in3_alarm, S_IRUGO, show_voltage, NULL, ALARM, 3);
862static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_voltage, NULL, INPUT, 4);
863static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_voltage,
864 set_voltage, MAX, 4);
865static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_voltage,
866 set_voltage, MIN, 4);
867static SENSOR_DEVICE_ATTR_2(in4_alarm, S_IRUGO, show_voltage, NULL, ALARM, 8);
868static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_voltage, NULL, INPUT, 5);
869static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_voltage,
870 set_voltage, MAX, 5);
871static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_voltage,
872 set_voltage, MIN, 5);
873static SENSOR_DEVICE_ATTR_2(in5_alarm, S_IRUGO, show_voltage, NULL, ALARM, 31);
833static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, INPUT, 0); 874static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, INPUT, 0);
834static SENSOR_DEVICE_ATTR_2(temp1_alarm, S_IRUGO, show_temp, NULL, ALARM, 0); 875static SENSOR_DEVICE_ATTR_2(temp1_alarm, S_IRUGO, show_temp, NULL, ALARM, 0);
835static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_temp, NULL, FAULT, 0); 876static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_temp, NULL, FAULT, 0);
@@ -1009,7 +1050,29 @@ static struct attribute *adt7475_attrs[] = {
1009 NULL, 1050 NULL,
1010}; 1051};
1011 1052
1053/* Attributes specific to the ADT7490 */
1054static struct attribute *adt7490_attrs[] = {
1055 &sensor_dev_attr_in0_input.dev_attr.attr,
1056 &sensor_dev_attr_in0_max.dev_attr.attr,
1057 &sensor_dev_attr_in0_min.dev_attr.attr,
1058 &sensor_dev_attr_in0_alarm.dev_attr.attr,
1059 &sensor_dev_attr_in3_input.dev_attr.attr,
1060 &sensor_dev_attr_in3_max.dev_attr.attr,
1061 &sensor_dev_attr_in3_min.dev_attr.attr,
1062 &sensor_dev_attr_in3_alarm.dev_attr.attr,
1063 &sensor_dev_attr_in4_input.dev_attr.attr,
1064 &sensor_dev_attr_in4_max.dev_attr.attr,
1065 &sensor_dev_attr_in4_min.dev_attr.attr,
1066 &sensor_dev_attr_in4_alarm.dev_attr.attr,
1067 &sensor_dev_attr_in5_input.dev_attr.attr,
1068 &sensor_dev_attr_in5_max.dev_attr.attr,
1069 &sensor_dev_attr_in5_min.dev_attr.attr,
1070 &sensor_dev_attr_in5_alarm.dev_attr.attr,
1071 NULL
1072};
1073
1012static struct attribute_group adt7475_attr_group = { .attrs = adt7475_attrs }; 1074static struct attribute_group adt7475_attr_group = { .attrs = adt7475_attrs };
1075static struct attribute_group adt7490_attr_group = { .attrs = adt7490_attrs };
1013 1076
1014static int adt7475_detect(struct i2c_client *client, int kind, 1077static int adt7475_detect(struct i2c_client *client, int kind,
1015 struct i2c_board_info *info) 1078 struct i2c_board_info *info)
@@ -1032,9 +1095,11 @@ static int adt7475_detect(struct i2c_client *client, int kind,
1032 name = "adt7473"; 1095 name = "adt7473";
1033 else if (devid == 0x75 && client->addr == 0x2e) 1096 else if (devid == 0x75 && client->addr == 0x2e)
1034 name = "adt7475"; 1097 name = "adt7475";
1098 else if ((devid2 & 0xfc) == 0x6c)
1099 name = "adt7490";
1035 else { 1100 else {
1036 dev_dbg(&adapter->dev, 1101 dev_dbg(&adapter->dev,
1037 "Couldn't detect an ADT7473 or ADT7475 part at " 1102 "Couldn't detect an ADT7473/75/90 part at "
1038 "0x%02x\n", (unsigned int)client->addr); 1103 "0x%02x\n", (unsigned int)client->addr);
1039 return -ENODEV; 1104 return -ENODEV;
1040 } 1105 }
@@ -1059,6 +1124,9 @@ static int adt7475_probe(struct i2c_client *client,
1059 1124
1060 /* Initialize device-specific values */ 1125 /* Initialize device-specific values */
1061 switch (id->driver_data) { 1126 switch (id->driver_data) {
1127 case adt7490:
1128 data->has_voltage = 0x3f; /* in0 to in5 */
1129 break;
1062 default: 1130 default:
1063 data->has_voltage = 0x06; /* in1, in2 */ 1131 data->has_voltage = 0x06; /* in1, in2 */
1064 } 1132 }
@@ -1072,6 +1140,13 @@ static int adt7475_probe(struct i2c_client *client,
1072 if (ret) 1140 if (ret)
1073 goto efree; 1141 goto efree;
1074 1142
1143 if (id->driver_data == adt7490) {
1144 ret = sysfs_create_group(&client->dev.kobj,
1145 &adt7490_attr_group);
1146 if (ret)
1147 goto eremove;
1148 }
1149
1075 data->hwmon_dev = hwmon_device_register(&client->dev); 1150 data->hwmon_dev = hwmon_device_register(&client->dev);
1076 if (IS_ERR(data->hwmon_dev)) { 1151 if (IS_ERR(data->hwmon_dev)) {
1077 ret = PTR_ERR(data->hwmon_dev); 1152 ret = PTR_ERR(data->hwmon_dev);
@@ -1082,6 +1157,8 @@ static int adt7475_probe(struct i2c_client *client,
1082 1157
1083eremove: 1158eremove:
1084 sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group); 1159 sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group);
1160 if (data->has_voltage & 0x39)
1161 sysfs_remove_group(&client->dev.kobj, &adt7490_attr_group);
1085efree: 1162efree:
1086 kfree(data); 1163 kfree(data);
1087 return ret; 1164 return ret;
@@ -1093,6 +1170,8 @@ static int adt7475_remove(struct i2c_client *client)
1093 1170
1094 hwmon_device_unregister(data->hwmon_dev); 1171 hwmon_device_unregister(data->hwmon_dev);
1095 sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group); 1172 sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group);
1173 if (data->has_voltage & 0x39)
1174 sysfs_remove_group(&client->dev.kobj, &adt7490_attr_group);
1096 kfree(data); 1175 kfree(data);
1097 1176
1098 return 0; 1177 return 0;
@@ -1177,7 +1256,7 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
1177{ 1256{
1178 struct i2c_client *client = to_i2c_client(dev); 1257 struct i2c_client *client = to_i2c_client(dev);
1179 struct adt7475_data *data = i2c_get_clientdata(client); 1258 struct adt7475_data *data = i2c_get_clientdata(client);
1180 u8 ext; 1259 u16 ext;
1181 int i; 1260 int i;
1182 1261
1183 mutex_lock(&data->lock); 1262 mutex_lock(&data->lock);
@@ -1188,7 +1267,8 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
1188 data->alarms = adt7475_read(REG_STATUS2) << 8; 1267 data->alarms = adt7475_read(REG_STATUS2) << 8;
1189 data->alarms |= adt7475_read(REG_STATUS1); 1268 data->alarms |= adt7475_read(REG_STATUS1);
1190 1269
1191 ext = adt7475_read(REG_EXTEND1); 1270 ext = (adt7475_read(REG_EXTEND2) << 8) |
1271 adt7475_read(REG_EXTEND1);
1192 for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) { 1272 for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) {
1193 if (!(data->has_voltage & (1 << i))) 1273 if (!(data->has_voltage & (1 << i)))
1194 continue; 1274 continue;
@@ -1197,11 +1277,17 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
1197 ((ext >> (i * 2)) & 3); 1277 ((ext >> (i * 2)) & 3);
1198 } 1278 }
1199 1279
1200 ext = adt7475_read(REG_EXTEND2);
1201 for (i = 0; i < ADT7475_TEMP_COUNT; i++) 1280 for (i = 0; i < ADT7475_TEMP_COUNT; i++)
1202 data->temp[INPUT][i] = 1281 data->temp[INPUT][i] =
1203 (adt7475_read(TEMP_REG(i)) << 2) | 1282 (adt7475_read(TEMP_REG(i)) << 2) |
1204 ((ext >> ((i + 1) * 2)) & 3); 1283 ((ext >> ((i + 5) * 2)) & 3);
1284
1285 if (data->has_voltage & (1 << 5)) {
1286 data->alarms |= adt7475_read(REG_STATUS4) << 24;
1287 ext = adt7475_read(REG_EXTEND3);
1288 data->voltage[INPUT][5] = adt7475_read(REG_VTT) << 2 |
1289 ((ext >> 4) & 3);
1290 }
1205 1291
1206 for (i = 0; i < ADT7475_TACH_COUNT; i++) 1292 for (i = 0; i < ADT7475_TACH_COUNT; i++)
1207 data->tach[INPUT][i] = 1293 data->tach[INPUT][i] =
@@ -1230,6 +1316,11 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
1230 adt7475_read(VOLTAGE_MAX_REG(i)) << 2; 1316 adt7475_read(VOLTAGE_MAX_REG(i)) << 2;
1231 } 1317 }
1232 1318
1319 if (data->has_voltage & (1 << 5)) {
1320 data->voltage[MIN][5] = adt7475_read(REG_VTT_MIN) << 2;
1321 data->voltage[MAX][5] = adt7475_read(REG_VTT_MAX) << 2;
1322 }
1323
1233 for (i = 0; i < ADT7475_TEMP_COUNT; i++) { 1324 for (i = 0; i < ADT7475_TEMP_COUNT; i++) {
1234 /* Adjust values so they match the input precision */ 1325 /* Adjust values so they match the input precision */
1235 data->temp[MIN][i] = 1326 data->temp[MIN][i] =