aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2009-12-09 14:36:03 -0500
committerJean Delvare <khali@linux-fr.org>2009-12-09 14:36:03 -0500
commitcffb9dd07fea8865093f6ccfb51d686487b89415 (patch)
tree3390cdab4076372dc7ca60207d97e37420923b1f /drivers/hwmon
parentf99318b2540da75e663603e1a0faef30a3bb0c92 (diff)
hwmon: (adt7475) Rework voltage inputs handling
Rework the handling of voltage inputs to make it possible and easy to support more inputs. This will be needed for the upcoming ADT7490 support. 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>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/adt7475.c83
1 files changed, 48 insertions, 35 deletions
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index 188ae428ccdd..e9f69ee197d7 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -39,7 +39,7 @@
39 39
40/* 7475 Common Registers */ 40/* 7475 Common Registers */
41 41
42#define REG_VOLTAGE_BASE 0x21 42#define REG_VOLTAGE_BASE 0x20
43#define REG_TEMP_BASE 0x25 43#define REG_TEMP_BASE 0x25
44#define REG_TACH_BASE 0x28 44#define REG_TACH_BASE 0x28
45#define REG_PWM_BASE 0x30 45#define REG_PWM_BASE 0x30
@@ -51,8 +51,8 @@
51#define REG_STATUS1 0x41 51#define REG_STATUS1 0x41
52#define REG_STATUS2 0x42 52#define REG_STATUS2 0x42
53 53
54#define REG_VOLTAGE_MIN_BASE 0x46 54#define REG_VOLTAGE_MIN_BASE 0x44
55#define REG_VOLTAGE_MAX_BASE 0x47 55#define REG_VOLTAGE_MAX_BASE 0x45
56 56
57#define REG_TEMP_MIN_BASE 0x4E 57#define REG_TEMP_MIN_BASE 0x4E
58#define REG_TEMP_MAX_BASE 0x4F 58#define REG_TEMP_MAX_BASE 0x4F
@@ -85,7 +85,7 @@
85 85
86/* ADT7475 Settings */ 86/* ADT7475 Settings */
87 87
88#define ADT7475_VOLTAGE_COUNT 2 88#define ADT7475_VOLTAGE_COUNT 5 /* Not counting Vtt */
89#define ADT7475_TEMP_COUNT 3 89#define ADT7475_TEMP_COUNT 3
90#define ADT7475_TACH_COUNT 4 90#define ADT7475_TACH_COUNT 4
91#define ADT7475_PWM_COUNT 3 91#define ADT7475_PWM_COUNT 3
@@ -137,8 +137,9 @@ struct adt7475_data {
137 137
138 u8 config4; 138 u8 config4;
139 u8 config5; 139 u8 config5;
140 u8 has_voltage;
140 u16 alarms; 141 u16 alarms;
141 u16 voltage[3][3]; 142 u16 voltage[3][6];
142 u16 temp[7][3]; 143 u16 temp[7][3];
143 u16 tach[2][4]; 144 u16 tach[2][4];
144 u8 pwm[4][3]; 145 u8 pwm[4][3];
@@ -201,26 +202,30 @@ static inline u16 rpm2tach(unsigned long rpm)
201 return SENSORS_LIMIT((90000 * 60) / rpm, 1, 0xFFFF); 202 return SENSORS_LIMIT((90000 * 60) / rpm, 1, 0xFFFF);
202} 203}
203 204
204static inline int reg2vcc(u16 reg) 205/* Scaling factors for voltage inputs, taken from the ADT7490 datasheet */
205{ 206static const int adt7473_in_scaling[ADT7475_VOLTAGE_COUNT + 1][2] = {
206 return (4296 * reg) / 1000; 207 { 45, 94 }, /* +2.5V */
207} 208 { 175, 525 }, /* Vccp */
209 { 68, 71 }, /* Vcc */
210 { 93, 47 }, /* +5V */
211 { 120, 20 }, /* +12V */
212 { 45, 45 }, /* Vtt */
213};
208 214
209static inline int reg2vccp(u16 reg) 215static inline int reg2volt(int channel, u16 reg)
210{ 216{
211 return (2929 * reg) / 1000; 217 const int *r = adt7473_in_scaling[channel];
212}
213 218
214static inline u16 vcc2reg(long vcc) 219 return DIV_ROUND_CLOSEST(reg * (r[0] + r[1]) * 2250, r[1] * 1024);
215{
216 vcc = SENSORS_LIMIT(vcc, 0, 4396);
217 return (vcc * 1000) / 4296;
218} 220}
219 221
220static inline u16 vccp2reg(long vcc) 222static inline u16 volt2reg(int channel, long volt)
221{ 223{
222 vcc = SENSORS_LIMIT(vcc, 0, 2998); 224 const int *r = adt7473_in_scaling[channel];
223 return (vcc * 1000) / 2929; 225 long reg;
226
227 reg = (volt * r[1] * 1024) / ((r[0] + r[1]) * 2250);
228 return SENSORS_LIMIT(reg, 0, 1023) & (0xff << 2);
224} 229}
225 230
226static u16 adt7475_read_word(struct i2c_client *client, int reg) 231static u16 adt7475_read_word(struct i2c_client *client, int reg)
@@ -276,12 +281,10 @@ static ssize_t show_voltage(struct device *dev, struct device_attribute *attr,
276 switch (sattr->nr) { 281 switch (sattr->nr) {
277 case ALARM: 282 case ALARM:
278 return sprintf(buf, "%d\n", 283 return sprintf(buf, "%d\n",
279 (data->alarms >> (sattr->index + 1)) & 1); 284 (data->alarms >> sattr->index) & 1);
280 default: 285 default:
281 val = data->voltage[sattr->nr][sattr->index]; 286 val = data->voltage[sattr->nr][sattr->index];
282 return sprintf(buf, "%d\n", 287 return sprintf(buf, "%d\n", reg2volt(sattr->index, val));
283 sattr->index ==
284 0 ? reg2vccp(val) : reg2vcc(val));
285 } 288 }
286} 289}
287 290
@@ -300,8 +303,7 @@ static ssize_t set_voltage(struct device *dev, struct device_attribute *attr,
300 303
301 mutex_lock(&data->lock); 304 mutex_lock(&data->lock);
302 305
303 data->voltage[sattr->nr][sattr->index] = 306 data->voltage[sattr->nr][sattr->index] = volt2reg(sattr->index, val);
304 sattr->index ? vcc2reg(val) : vccp2reg(val);
305 307
306 if (sattr->nr == MIN) 308 if (sattr->nr == MIN)
307 reg = VOLTAGE_MIN_REG(sattr->index); 309 reg = VOLTAGE_MIN_REG(sattr->index);
@@ -815,18 +817,18 @@ static ssize_t set_pwm_at_crit(struct device *dev,
815 return count; 817 return count;
816} 818}
817 819
818static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_voltage, NULL, INPUT, 0); 820static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_voltage, NULL, INPUT, 1);
819static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_voltage, 821static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_voltage,
820 set_voltage, MAX, 0); 822 set_voltage, MAX, 1);
821static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_voltage, 823static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_voltage,
822 set_voltage, MIN, 0); 824 set_voltage, MIN, 1);
823static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, show_voltage, NULL, ALARM, 0); 825static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, show_voltage, NULL, ALARM, 1);
824static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_voltage, NULL, INPUT, 1); 826static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_voltage, NULL, INPUT, 2);
825static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_voltage, 827static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_voltage,
826 set_voltage, MAX, 1); 828 set_voltage, MAX, 2);
827static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_voltage, 829static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_voltage,
828 set_voltage, MIN, 1); 830 set_voltage, MIN, 2);
829static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_voltage, NULL, ALARM, 1); 831static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_voltage, NULL, ALARM, 2);
830static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, INPUT, 0); 832static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, INPUT, 0);
831static SENSOR_DEVICE_ATTR_2(temp1_alarm, S_IRUGO, show_temp, NULL, ALARM, 0); 833static SENSOR_DEVICE_ATTR_2(temp1_alarm, S_IRUGO, show_temp, NULL, ALARM, 0);
832static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_temp, NULL, FAULT, 0); 834static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_temp, NULL, FAULT, 0);
@@ -1050,6 +1052,12 @@ static int adt7475_probe(struct i2c_client *client,
1050 mutex_init(&data->lock); 1052 mutex_init(&data->lock);
1051 i2c_set_clientdata(client, data); 1053 i2c_set_clientdata(client, data);
1052 1054
1055 /* Initialize device-specific values */
1056 switch (id->driver_data) {
1057 default:
1058 data->has_voltage = 0x06; /* in1, in2 */
1059 }
1060
1053 /* Call adt7475_read_pwm for all pwm's as this will reprogram any 1061 /* Call adt7475_read_pwm for all pwm's as this will reprogram any
1054 pwm's which are disabled to manual mode with 0% duty cycle */ 1062 pwm's which are disabled to manual mode with 0% duty cycle */
1055 for (i = 0; i < ADT7475_PWM_COUNT; i++) 1063 for (i = 0; i < ADT7475_PWM_COUNT; i++)
@@ -1176,10 +1184,13 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
1176 data->alarms |= adt7475_read(REG_STATUS1); 1184 data->alarms |= adt7475_read(REG_STATUS1);
1177 1185
1178 ext = adt7475_read(REG_EXTEND1); 1186 ext = adt7475_read(REG_EXTEND1);
1179 for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) 1187 for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) {
1188 if (!(data->has_voltage & (1 << i)))
1189 continue;
1180 data->voltage[INPUT][i] = 1190 data->voltage[INPUT][i] =
1181 (adt7475_read(VOLTAGE_REG(i)) << 2) | 1191 (adt7475_read(VOLTAGE_REG(i)) << 2) |
1182 ((ext >> ((i + 1) * 2)) & 3); 1192 ((ext >> (i * 2)) & 3);
1193 }
1183 1194
1184 ext = adt7475_read(REG_EXTEND2); 1195 ext = adt7475_read(REG_EXTEND2);
1185 for (i = 0; i < ADT7475_TEMP_COUNT; i++) 1196 for (i = 0; i < ADT7475_TEMP_COUNT; i++)
@@ -1205,6 +1216,8 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
1205 data->config5 = adt7475_read(REG_CONFIG5); 1216 data->config5 = adt7475_read(REG_CONFIG5);
1206 1217
1207 for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) { 1218 for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) {
1219 if (!(data->has_voltage & (1 << i)))
1220 continue;
1208 /* Adjust values so they match the input precision */ 1221 /* Adjust values so they match the input precision */
1209 data->voltage[MIN][i] = 1222 data->voltage[MIN][i] =
1210 adt7475_read(VOLTAGE_MIN_REG(i)) << 2; 1223 adt7475_read(VOLTAGE_MIN_REG(i)) << 2;