aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/lm63.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 24a96f89d206..a9e6212ed54a 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -117,6 +117,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
117 (val) >= 127000 ? 127 : \ 117 (val) >= 127000 ? 127 : \
118 (val) < 0 ? ((val) - 500) / 1000 : \ 118 (val) < 0 ? ((val) - 500) / 1000 : \
119 ((val) + 500) / 1000) 119 ((val) + 500) / 1000)
120#define TEMP8U_TO_REG(val) ((val) <= 0 ? 0 : \
121 (val) >= 255000 ? 255 : \
122 ((val) + 500) / 1000)
120#define TEMP11_FROM_REG(reg) ((reg) / 32 * 125) 123#define TEMP11_FROM_REG(reg) ((reg) / 32 * 125)
121#define TEMP11_TO_REG(val) ((val) <= -128000 ? 0x8000 : \ 124#define TEMP11_TO_REG(val) ((val) <= -128000 ? 0x8000 : \
122 (val) >= 127875 ? 0x7FE0 : \ 125 (val) >= 127875 ? 0x7FE0 : \
@@ -313,22 +316,33 @@ static ssize_t show_remote_temp8(struct device *dev,
313 + data->temp2_offset); 316 + data->temp2_offset);
314} 317}
315 318
316static ssize_t set_local_temp8(struct device *dev, 319static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
317 struct device_attribute *dummy, 320 const char *buf, size_t count)
318 const char *buf, size_t count)
319{ 321{
322 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
320 struct i2c_client *client = to_i2c_client(dev); 323 struct i2c_client *client = to_i2c_client(dev);
321 struct lm63_data *data = i2c_get_clientdata(client); 324 struct lm63_data *data = i2c_get_clientdata(client);
325 int nr = attr->index;
326 int reg = nr == 2 ? LM63_REG_REMOTE_TCRIT : LM63_REG_LOCAL_HIGH;
322 long val; 327 long val;
323 int err; 328 int err;
329 int temp;
324 330
325 err = kstrtol(buf, 10, &val); 331 err = kstrtol(buf, 10, &val);
326 if (err) 332 if (err)
327 return err; 333 return err;
328 334
329 mutex_lock(&data->update_lock); 335 mutex_lock(&data->update_lock);
330 data->temp8[1] = TEMP8_TO_REG(val); 336 if (nr == 2) {
331 i2c_smbus_write_byte_data(client, LM63_REG_LOCAL_HIGH, data->temp8[1]); 337 if (data->remote_unsigned)
338 temp = TEMP8U_TO_REG(val - data->temp2_offset);
339 else
340 temp = TEMP8_TO_REG(val - data->temp2_offset);
341 } else {
342 temp = TEMP8_TO_REG(val);
343 }
344 data->temp8[nr] = temp;
345 i2c_smbus_write_byte_data(client, reg, temp);
332 mutex_unlock(&data->update_lock); 346 mutex_unlock(&data->update_lock);
333 return count; 347 return count;
334} 348}
@@ -461,7 +475,7 @@ static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL);
461 475
462static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0); 476static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0);
463static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8, 477static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8,
464 set_local_temp8, 1); 478 set_temp8, 1);
465 479
466static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); 480static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
467static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, 481static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
@@ -470,12 +484,8 @@ static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
470 set_temp11, 2); 484 set_temp11, 2);
471static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, 485static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11,
472 set_temp11, 3); 486 set_temp11, 3);
473/*
474 * On LM63, temp2_crit can be set only once, which should be job
475 * of the bootloader.
476 */
477static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_remote_temp8, 487static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_remote_temp8,
478 NULL, 2); 488 set_temp8, 2);
479static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, 489static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
480 set_temp2_crit_hyst); 490 set_temp2_crit_hyst);
481 491
@@ -510,7 +520,30 @@ static struct attribute *lm63_attributes[] = {
510 NULL 520 NULL
511}; 521};
512 522
523/*
524 * On LM63, temp2_crit can be set only once, which should be job
525 * of the bootloader.
526 * On LM64, temp2_crit can always be set.
527 * On LM96163, temp2_crit can be set if bit 1 of the configuration
528 * register is true.
529 */
530static umode_t lm63_attribute_mode(struct kobject *kobj,
531 struct attribute *attr, int index)
532{
533 struct device *dev = container_of(kobj, struct device, kobj);
534 struct i2c_client *client = to_i2c_client(dev);
535 struct lm63_data *data = i2c_get_clientdata(client);
536
537 if (attr == &sensor_dev_attr_temp2_crit.dev_attr.attr
538 && (data->kind == lm64 ||
539 (data->kind == lm96163 && (data->config & 0x02))))
540 return attr->mode | S_IWUSR;
541
542 return attr->mode;
543}
544
513static const struct attribute_group lm63_group = { 545static const struct attribute_group lm63_group = {
546 .is_visible = lm63_attribute_mode,
514 .attrs = lm63_attributes, 547 .attrs = lm63_attributes,
515}; 548};
516 549