aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2012-03-23 05:02:19 -0400
committerJean Delvare <khali@endymion.delvare>2012-03-23 05:02:19 -0400
commitaf2ef4fc043f8fef078ba58c6cd8483d1348d70b (patch)
treefb29644aa69298791ee454e02dd137a007e8316b /drivers/hwmon
parent817c6cc546a4ebea8016766f0f26e7d53118c6b6 (diff)
hwmon: (lm63) Let the user adjust the lookup table
Make the automatic fan speed control lookup table writable. This lets the user tweak the fan speed / temperature response curve. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Guenter Roeck <guenter.roeck@ericsson.com> Tested-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/lm63.c118
1 files changed, 76 insertions, 42 deletions
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 910599ac31ca..602a0f0b0de8 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -205,6 +205,15 @@ static inline int lut_temp_from_reg(struct lm63_data *data, int nr)
205 return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000); 205 return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000);
206} 206}
207 207
208static inline int lut_temp_to_reg(struct lm63_data *data, long val)
209{
210 val -= data->temp2_offset;
211 if (data->lut_temp_highres)
212 return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127500), 500);
213 else
214 return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127000), 1000);
215}
216
208/* 217/*
209 * Update the lookup table register cache. 218 * Update the lookup table register cache.
210 * client->update_lock must be held when calling this function. 219 * client->update_lock must be held when calling this function.
@@ -387,13 +396,16 @@ static ssize_t show_pwm1(struct device *dev, struct device_attribute *devattr,
387 return sprintf(buf, "%d\n", pwm); 396 return sprintf(buf, "%d\n", pwm);
388} 397}
389 398
390static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy, 399static ssize_t set_pwm1(struct device *dev, struct device_attribute *devattr,
391 const char *buf, size_t count) 400 const char *buf, size_t count)
392{ 401{
402 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
393 struct i2c_client *client = to_i2c_client(dev); 403 struct i2c_client *client = to_i2c_client(dev);
394 struct lm63_data *data = i2c_get_clientdata(client); 404 struct lm63_data *data = i2c_get_clientdata(client);
405 int nr = attr->index;
395 unsigned long val; 406 unsigned long val;
396 int err; 407 int err;
408 u8 reg;
397 409
398 if (!(data->config_fan & 0x20)) /* register is read-only */ 410 if (!(data->config_fan & 0x20)) /* register is read-only */
399 return -EPERM; 411 return -EPERM;
@@ -402,11 +414,13 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy,
402 if (err) 414 if (err)
403 return err; 415 return err;
404 416
417 reg = nr ? LM63_REG_LUT_PWM(nr - 1) : LM63_REG_PWM_VALUE;
405 val = SENSORS_LIMIT(val, 0, 255); 418 val = SENSORS_LIMIT(val, 0, 255);
419
406 mutex_lock(&data->update_lock); 420 mutex_lock(&data->update_lock);
407 data->pwm1[0] = data->pwm_highres ? val : 421 data->pwm1[nr] = data->pwm_highres ? val :
408 (val * data->pwm1_freq * 2 + 127) / 255; 422 (val * data->pwm1_freq * 2 + 127) / 255;
409 i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1[0]); 423 i2c_smbus_write_byte_data(client, reg, data->pwm1[nr]);
410 mutex_unlock(&data->update_lock); 424 mutex_unlock(&data->update_lock);
411 return count; 425 return count;
412} 426}
@@ -495,23 +509,31 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
495 struct i2c_client *client = to_i2c_client(dev); 509 struct i2c_client *client = to_i2c_client(dev);
496 struct lm63_data *data = i2c_get_clientdata(client); 510 struct lm63_data *data = i2c_get_clientdata(client);
497 int nr = attr->index; 511 int nr = attr->index;
498 int reg = nr == 2 ? LM63_REG_REMOTE_TCRIT : LM63_REG_LOCAL_HIGH;
499 long val; 512 long val;
500 int err; 513 int err;
501 int temp; 514 int temp;
515 u8 reg;
502 516
503 err = kstrtol(buf, 10, &val); 517 err = kstrtol(buf, 10, &val);
504 if (err) 518 if (err)
505 return err; 519 return err;
506 520
507 mutex_lock(&data->update_lock); 521 mutex_lock(&data->update_lock);
508 if (nr == 2) { 522 switch (nr) {
523 case 2:
524 reg = LM63_REG_REMOTE_TCRIT;
509 if (data->remote_unsigned) 525 if (data->remote_unsigned)
510 temp = TEMP8U_TO_REG(val - data->temp2_offset); 526 temp = TEMP8U_TO_REG(val - data->temp2_offset);
511 else 527 else
512 temp = TEMP8_TO_REG(val - data->temp2_offset); 528 temp = TEMP8_TO_REG(val - data->temp2_offset);
513 } else { 529 break;
530 case 1:
531 reg = LM63_REG_LOCAL_HIGH;
514 temp = TEMP8_TO_REG(val); 532 temp = TEMP8_TO_REG(val);
533 break;
534 default: /* lookup table */
535 reg = LM63_REG_LUT_TEMP(nr - 3);
536 temp = lut_temp_to_reg(data, val);
515 } 537 }
516 data->temp8[nr] = temp; 538 data->temp8[nr] = temp;
517 i2c_smbus_write_byte_data(client, reg, temp); 539 i2c_smbus_write_byte_data(client, reg, temp);
@@ -743,64 +765,76 @@ static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
743static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1, 0); 765static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1, 0);
744static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, 766static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
745 show_pwm1_enable, set_pwm1_enable); 767 show_pwm1_enable, set_pwm1_enable);
746static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO, show_pwm1, NULL, 1); 768static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
747static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IRUGO, 769 show_pwm1, set_pwm1, 1);
748 show_lut_temp, NULL, 3); 770static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO,
771 show_lut_temp, set_temp8, 3);
749static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp_hyst, S_IRUGO, 772static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp_hyst, S_IRUGO,
750 show_lut_temp_hyst, NULL, 3); 773 show_lut_temp_hyst, NULL, 3);
751static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO, show_pwm1, NULL, 2); 774static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
752static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IRUGO, 775 show_pwm1, set_pwm1, 2);
753 show_lut_temp, NULL, 4); 776static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO,
777 show_lut_temp, set_temp8, 4);
754static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp_hyst, S_IRUGO, 778static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp_hyst, S_IRUGO,
755 show_lut_temp_hyst, NULL, 4); 779 show_lut_temp_hyst, NULL, 4);
756static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO, show_pwm1, NULL, 3); 780static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO,
757static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IRUGO, 781 show_pwm1, set_pwm1, 3);
758 show_lut_temp, NULL, 5); 782static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO,
783 show_lut_temp, set_temp8, 5);
759static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp_hyst, S_IRUGO, 784static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp_hyst, S_IRUGO,
760 show_lut_temp_hyst, NULL, 5); 785 show_lut_temp_hyst, NULL, 5);
761static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO, show_pwm1, NULL, 4); 786static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO,
762static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IRUGO, 787 show_pwm1, set_pwm1, 4);
763 show_lut_temp, NULL, 6); 788static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO,
789 show_lut_temp, set_temp8, 6);
764static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp_hyst, S_IRUGO, 790static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp_hyst, S_IRUGO,
765 show_lut_temp_hyst, NULL, 6); 791 show_lut_temp_hyst, NULL, 6);
766static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm1, NULL, 5); 792static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO,
767static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IRUGO, 793 show_pwm1, set_pwm1, 5);
768 show_lut_temp, NULL, 7); 794static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO,
795 show_lut_temp, set_temp8, 7);
769static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp_hyst, S_IRUGO, 796static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp_hyst, S_IRUGO,
770 show_lut_temp_hyst, NULL, 7); 797 show_lut_temp_hyst, NULL, 7);
771static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IRUGO, show_pwm1, NULL, 6); 798static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO,
772static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IRUGO, 799 show_pwm1, set_pwm1, 6);
773 show_lut_temp, NULL, 8); 800static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO,
801 show_lut_temp, set_temp8, 8);
774static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp_hyst, S_IRUGO, 802static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp_hyst, S_IRUGO,
775 show_lut_temp_hyst, NULL, 8); 803 show_lut_temp_hyst, NULL, 8);
776static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IRUGO, show_pwm1, NULL, 7); 804static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO,
777static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IRUGO, 805 show_pwm1, set_pwm1, 7);
778 show_lut_temp, NULL, 9); 806static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO,
807 show_lut_temp, set_temp8, 9);
779static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp_hyst, S_IRUGO, 808static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp_hyst, S_IRUGO,
780 show_lut_temp_hyst, NULL, 9); 809 show_lut_temp_hyst, NULL, 9);
781static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IRUGO, show_pwm1, NULL, 8); 810static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IWUSR | S_IRUGO,
782static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO, 811 show_pwm1, set_pwm1, 8);
783 show_lut_temp, NULL, 10); 812static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IWUSR | S_IRUGO,
813 show_lut_temp, set_temp8, 10);
784static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, 814static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO,
785 show_lut_temp_hyst, NULL, 10); 815 show_lut_temp_hyst, NULL, 10);
786static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IRUGO, show_pwm1, NULL, 9); 816static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IWUSR | S_IRUGO,
787static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IRUGO, 817 show_pwm1, set_pwm1, 9);
788 show_lut_temp, NULL, 11); 818static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IWUSR | S_IRUGO,
819 show_lut_temp, set_temp8, 11);
789static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO, 820static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO,
790 show_lut_temp_hyst, NULL, 11); 821 show_lut_temp_hyst, NULL, 11);
791static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IRUGO, show_pwm1, NULL, 10); 822static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IWUSR | S_IRUGO,
792static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IRUGO, 823 show_pwm1, set_pwm1, 10);
793 show_lut_temp, NULL, 12); 824static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IWUSR | S_IRUGO,
825 show_lut_temp, set_temp8, 12);
794static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO, 826static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO,
795 show_lut_temp_hyst, NULL, 12); 827 show_lut_temp_hyst, NULL, 12);
796static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IRUGO, show_pwm1, NULL, 11); 828static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IWUSR | S_IRUGO,
797static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IRUGO, 829 show_pwm1, set_pwm1, 11);
798 show_lut_temp, NULL, 13); 830static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IWUSR | S_IRUGO,
831 show_lut_temp, set_temp8, 13);
799static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO, 832static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO,
800 show_lut_temp_hyst, NULL, 13); 833 show_lut_temp_hyst, NULL, 13);
801static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IRUGO, show_pwm1, NULL, 12); 834static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IWUSR | S_IRUGO,
802static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IRUGO, 835 show_pwm1, set_pwm1, 12);
803 show_lut_temp, NULL, 14); 836static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IWUSR | S_IRUGO,
837 show_lut_temp, set_temp8, 14);
804static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO, 838static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO,
805 show_lut_temp_hyst, NULL, 14); 839 show_lut_temp_hyst, NULL, 14);
806 840