aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/lm80.c134
1 files changed, 59 insertions, 75 deletions
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c
index fe980d64dc05..df6e07992baf 100644
--- a/drivers/hwmon/lm80.c
+++ b/drivers/hwmon/lm80.c
@@ -92,6 +92,23 @@ static inline unsigned char FAN_TO_REG(unsigned rpm, unsigned div)
92 92
93#define DIV_FROM_REG(val) (1 << (val)) 93#define DIV_FROM_REG(val) (1 << (val))
94 94
95enum temp_index {
96 t_input = 0,
97 t_hot_max,
98 t_hot_hyst,
99 t_os_max,
100 t_os_hyst,
101 t_num_temp
102};
103
104static const u8 temp_regs[t_num_temp] = {
105 [t_input] = LM80_REG_TEMP,
106 [t_hot_max] = LM80_REG_TEMP_HOT_MAX,
107 [t_hot_hyst] = LM80_REG_TEMP_HOT_HYST,
108 [t_os_max] = LM80_REG_TEMP_OS_MAX,
109 [t_os_hyst] = LM80_REG_TEMP_OS_HYST,
110};
111
95/* 112/*
96 * Client data (each client gets its own) 113 * Client data (each client gets its own)
97 */ 114 */
@@ -109,11 +126,7 @@ struct lm80_data {
109 u8 fan[2]; /* Register value */ 126 u8 fan[2]; /* Register value */
110 u8 fan_min[2]; /* Register value */ 127 u8 fan_min[2]; /* Register value */
111 u8 fan_div[2]; /* Register encoding, shifted right */ 128 u8 fan_div[2]; /* Register encoding, shifted right */
112 s16 temp; /* Register values */ 129 s16 temp[t_num_temp]; /* Register values, normalized to 16 bit */
113 s16 temp_hot_max; /* Register value, left shifted */
114 s16 temp_hot_hyst; /* Register value, left shifted */
115 s16 temp_os_max; /* Register value, left shifted */
116 s16 temp_os_hyst; /* Register value, left shifted */
117 u16 alarms; /* Register encoding, combined */ 130 u16 alarms; /* Register encoding, combined */
118}; 131};
119 132
@@ -288,50 +301,34 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
288 return count; 301 return count;
289} 302}
290 303
291static ssize_t show_temp_input1(struct device *dev, 304static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
292 struct device_attribute *attr, char *buf) 305 char *buf)
293{ 306{
307 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
294 struct lm80_data *data = lm80_update_device(dev); 308 struct lm80_data *data = lm80_update_device(dev);
295 if (IS_ERR(data)) 309 if (IS_ERR(data))
296 return PTR_ERR(data); 310 return PTR_ERR(data);
297 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp)); 311 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
298} 312}
299 313
300#define show_temp(suffix, value) \ 314static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
301static ssize_t show_temp_##suffix(struct device *dev, \ 315 const char *buf, size_t count)
302 struct device_attribute *attr, char *buf) \ 316{
303{ \ 317 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
304 struct lm80_data *data = lm80_update_device(dev); \ 318 struct lm80_data *data = dev_get_drvdata(dev);
305 if (IS_ERR(data)) \ 319 struct i2c_client *client = data->client;
306 return PTR_ERR(data); \ 320 int nr = attr->index;
307 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \ 321 long val;
308} 322 int err = kstrtol(buf, 10, &val);
309show_temp(hot_max, temp_hot_max); 323 if (err < 0)
310show_temp(hot_hyst, temp_hot_hyst); 324 return err;
311show_temp(os_max, temp_os_max);
312show_temp(os_hyst, temp_os_hyst);
313 325
314#define set_temp(suffix, value, reg) \ 326 mutex_lock(&data->update_lock);
315static ssize_t set_temp_##suffix(struct device *dev, \ 327 data->temp[nr] = TEMP_TO_REG(val);
316 struct device_attribute *attr, const char *buf, size_t count) \ 328 lm80_write_value(client, temp_regs[nr], data->temp[nr] >> 8);
317{ \ 329 mutex_unlock(&data->update_lock);
318 struct lm80_data *data = dev_get_drvdata(dev); \ 330 return count;
319 struct i2c_client *client = data->client; \
320 long val; \
321 int err = kstrtol(buf, 10, &val); \
322 if (err < 0) \
323 return err; \
324\
325 mutex_lock(&data->update_lock); \
326 data->value = TEMP_TO_REG(val); \
327 lm80_write_value(client, reg, data->value >> 8); \
328 mutex_unlock(&data->update_lock); \
329 return count; \
330} 331}
331set_temp(hot_max, temp_hot_max, LM80_REG_TEMP_HOT_MAX);
332set_temp(hot_hyst, temp_hot_hyst, LM80_REG_TEMP_HOT_HYST);
333set_temp(os_max, temp_os_max, LM80_REG_TEMP_OS_MAX);
334set_temp(os_hyst, temp_os_hyst, LM80_REG_TEMP_OS_HYST);
335 332
336static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, 333static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
337 char *buf) 334 char *buf)
@@ -397,15 +394,15 @@ static SENSOR_DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO,
397 show_fan_div, set_fan_div, 0); 394 show_fan_div, set_fan_div, 0);
398static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO, 395static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO,
399 show_fan_div, set_fan_div, 1); 396 show_fan_div, set_fan_div, 1);
400static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); 397static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, t_input);
401static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_hot_max, 398static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp,
402 set_temp_hot_max); 399 set_temp, t_hot_max);
403static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hot_hyst, 400static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp,
404 set_temp_hot_hyst); 401 set_temp, t_hot_hyst);
405static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_os_max, 402static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp,
406 set_temp_os_max); 403 set_temp, t_os_max);
407static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_os_hyst, 404static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp,
408 set_temp_os_hyst); 405 set_temp, t_os_hyst);
409static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); 406static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
410static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); 407static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
411static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); 408static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
@@ -451,11 +448,11 @@ static struct attribute *lm80_attrs[] = {
451 &sensor_dev_attr_fan2_input.dev_attr.attr, 448 &sensor_dev_attr_fan2_input.dev_attr.attr,
452 &sensor_dev_attr_fan1_div.dev_attr.attr, 449 &sensor_dev_attr_fan1_div.dev_attr.attr,
453 &sensor_dev_attr_fan2_div.dev_attr.attr, 450 &sensor_dev_attr_fan2_div.dev_attr.attr,
454 &dev_attr_temp1_input.attr, 451 &sensor_dev_attr_temp1_input.dev_attr.attr,
455 &dev_attr_temp1_max.attr, 452 &sensor_dev_attr_temp1_max.dev_attr.attr,
456 &dev_attr_temp1_max_hyst.attr, 453 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
457 &dev_attr_temp1_crit.attr, 454 &sensor_dev_attr_temp1_crit.dev_attr.attr,
458 &dev_attr_temp1_crit_hyst.attr, 455 &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
459 &dev_attr_alarms.attr, 456 &dev_attr_alarms.attr,
460 &sensor_dev_attr_in0_alarm.dev_attr.attr, 457 &sensor_dev_attr_in0_alarm.dev_attr.attr,
461 &sensor_dev_attr_in1_alarm.dev_attr.attr, 458 &sensor_dev_attr_in1_alarm.dev_attr.attr,
@@ -630,27 +627,14 @@ static struct lm80_data *lm80_update_device(struct device *dev)
630 rv = lm80_read_value(client, LM80_REG_RES); 627 rv = lm80_read_value(client, LM80_REG_RES);
631 if (rv < 0) 628 if (rv < 0)
632 goto abort; 629 goto abort;
633 data->temp = (prev_rv << 8) | (rv & 0xf0); 630 data->temp[t_input] = (prev_rv << 8) | (rv & 0xf0);
634 631
635 rv = lm80_read_value(client, LM80_REG_TEMP_OS_MAX); 632 for (i = t_input + 1; i < t_num_temp; i++) {
636 if (rv < 0) 633 rv = lm80_read_value(client, temp_regs[i]);
637 goto abort; 634 if (rv < 0)
638 data->temp_os_max = rv << 8; 635 goto abort;
639 636 data->temp[i] = rv << 8;
640 rv = lm80_read_value(client, LM80_REG_TEMP_OS_HYST); 637 }
641 if (rv < 0)
642 goto abort;
643 data->temp_os_hyst = rv << 8;
644
645 rv = lm80_read_value(client, LM80_REG_TEMP_HOT_MAX);
646 if (rv < 0)
647 goto abort;
648 data->temp_hot_max = rv << 8;
649
650 rv = lm80_read_value(client, LM80_REG_TEMP_HOT_HYST);
651 if (rv < 0)
652 goto abort;
653 data->temp_hot_hyst = rv << 8;
654 638
655 rv = lm80_read_value(client, LM80_REG_FANDIV); 639 rv = lm80_read_value(client, LM80_REG_FANDIV);
656 if (rv < 0) 640 if (rv < 0)