aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Mu <ymu@winbond.com.tw>2006-06-04 14:18:05 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-22 14:10:34 -0400
commit53e2761bb2e4ed58913c266ad13e8c10692aec1e (patch)
tree163840e48c2a50f4a86f2a584cd9a697c065075a
parent3dc26c600cbae8e8e7566136148aef5667e8342b (diff)
[PATCH] w83792d: Fix setting the PWM value
W83792D use pwm register low 4 bits to store PWM/DC value, bit 7 is used to store fan PWM/DC mode. The store_pwm function did not convert the pwm input correctly, so it may change the fan mode when new value is set. This fix the problem. Change the "index" value of pwm*_mode and pwm* SENSOR_ATTR to simplify code. Signed-off-by: Yuan Mu <ymu@winbond.com.tw> Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/hwmon/w83792d.c56
1 files changed, 29 insertions, 27 deletions
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 958602e28412..6cdef18b1b27 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -250,8 +250,6 @@ FAN_TO_REG(long rpm, int div)
250 : (val)) / 1000, 0, 0xff)) 250 : (val)) / 1000, 0, 0xff))
251#define TEMP_ADD_TO_REG_LOW(val) ((val%1000) ? 0x80 : 0x00) 251#define TEMP_ADD_TO_REG_LOW(val) ((val%1000) ? 0x80 : 0x00)
252 252
253#define PWM_FROM_REG(val) (val)
254#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255))
255#define DIV_FROM_REG(val) (1 << (val)) 253#define DIV_FROM_REG(val) (1 << (val))
256 254
257static inline u8 255static inline u8
@@ -291,7 +289,6 @@ struct w83792d_data {
291 u8 pwm[7]; /* We only consider the first 3 set of pwm, 289 u8 pwm[7]; /* We only consider the first 3 set of pwm,
292 although 792 chip has 7 set of pwm. */ 290 although 792 chip has 7 set of pwm. */
293 u8 pwmenable[3]; 291 u8 pwmenable[3];
294 u8 pwm_mode[7]; /* indicates PWM or DC mode: 1->PWM; 0->DC */
295 u32 alarms; /* realtime status register encoding,combined */ 292 u32 alarms; /* realtime status register encoding,combined */
296 u8 chassis; /* Chassis status */ 293 u8 chassis; /* Chassis status */
297 u8 chassis_clear; /* CLR_CHS, clear chassis intrusion detection */ 294 u8 chassis_clear; /* CLR_CHS, clear chassis intrusion detection */
@@ -627,7 +624,7 @@ show_pwm(struct device *dev, struct device_attribute *attr,
627 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); 624 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
628 int nr = sensor_attr->index; 625 int nr = sensor_attr->index;
629 struct w83792d_data *data = w83792d_update_device(dev); 626 struct w83792d_data *data = w83792d_update_device(dev);
630 return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr-1])); 627 return sprintf(buf, "%d\n", (data->pwm[nr] & 0x0f) << 4);
631} 628}
632 629
633static ssize_t 630static ssize_t
@@ -659,14 +656,16 @@ store_pwm(struct device *dev, struct device_attribute *attr,
659 const char *buf, size_t count) 656 const char *buf, size_t count)
660{ 657{
661 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); 658 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
662 int nr = sensor_attr->index - 1; 659 int nr = sensor_attr->index;
663 struct i2c_client *client = to_i2c_client(dev); 660 struct i2c_client *client = to_i2c_client(dev);
664 struct w83792d_data *data = i2c_get_clientdata(client); 661 struct w83792d_data *data = i2c_get_clientdata(client);
665 u32 val; 662 u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255) >> 4;
666 663
667 val = simple_strtoul(buf, NULL, 10); 664 mutex_lock(&data->update_lock);
668 data->pwm[nr] = PWM_TO_REG(val); 665 val |= w83792d_read_value(client, W83792D_REG_PWM[nr]) & 0xf0;
666 data->pwm[nr] = val;
669 w83792d_write_value(client, W83792D_REG_PWM[nr], data->pwm[nr]); 667 w83792d_write_value(client, W83792D_REG_PWM[nr], data->pwm[nr]);
668 mutex_unlock(&data->update_lock);
670 669
671 return count; 670 return count;
672} 671}
@@ -707,9 +706,9 @@ store_pwmenable(struct device *dev, struct device_attribute *attr,
707} 706}
708 707
709static struct sensor_device_attribute sda_pwm[] = { 708static struct sensor_device_attribute sda_pwm[] = {
710 SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1), 709 SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0),
711 SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2), 710 SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1),
712 SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3), 711 SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2),
713}; 712};
714static struct sensor_device_attribute sda_pwm_enable[] = { 713static struct sensor_device_attribute sda_pwm_enable[] = {
715 SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, 714 SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
@@ -728,7 +727,7 @@ show_pwm_mode(struct device *dev, struct device_attribute *attr,
728 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); 727 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
729 int nr = sensor_attr->index; 728 int nr = sensor_attr->index;
730 struct w83792d_data *data = w83792d_update_device(dev); 729 struct w83792d_data *data = w83792d_update_device(dev);
731 return sprintf(buf, "%d\n", data->pwm_mode[nr-1]); 730 return sprintf(buf, "%d\n", data->pwm[nr] >> 7);
732} 731}
733 732
734static ssize_t 733static ssize_t
@@ -736,29 +735,35 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
736 const char *buf, size_t count) 735 const char *buf, size_t count)
737{ 736{
738 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); 737 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
739 int nr = sensor_attr->index - 1; 738 int nr = sensor_attr->index;
740 struct i2c_client *client = to_i2c_client(dev); 739 struct i2c_client *client = to_i2c_client(dev);
741 struct w83792d_data *data = i2c_get_clientdata(client); 740 struct w83792d_data *data = i2c_get_clientdata(client);
742 u32 val; 741 u32 val;
743 u8 pwm_mode_mask = 0;
744 742
745 val = simple_strtoul(buf, NULL, 10); 743 val = simple_strtoul(buf, NULL, 10);
746 data->pwm_mode[nr] = SENSORS_LIMIT(val, 0, 1); 744 if (val != 0 && val != 1)
747 pwm_mode_mask = w83792d_read_value(client, 745 return -EINVAL;
748 W83792D_REG_PWM[nr]) & 0x7f; 746
749 w83792d_write_value(client, W83792D_REG_PWM[nr], 747 mutex_lock(&data->update_lock);
750 ((data->pwm_mode[nr]) << 7) | pwm_mode_mask); 748 data->pwm[nr] = w83792d_read_value(client, W83792D_REG_PWM[nr]);
749 if (val) { /* PWM mode */
750 data->pwm[nr] |= 0x80;
751 } else { /* DC mode */
752 data->pwm[nr] &= 0x7f;
753 }
754 w83792d_write_value(client, W83792D_REG_PWM[nr], data->pwm[nr]);
755 mutex_unlock(&data->update_lock);
751 756
752 return count; 757 return count;
753} 758}
754 759
755static struct sensor_device_attribute sda_pwm_mode[] = { 760static struct sensor_device_attribute sda_pwm_mode[] = {
756 SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, 761 SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO,
757 show_pwm_mode, store_pwm_mode, 1), 762 show_pwm_mode, store_pwm_mode, 0),
758 SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, 763 SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO,
759 show_pwm_mode, store_pwm_mode, 2), 764 show_pwm_mode, store_pwm_mode, 1),
760 SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, 765 SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO,
761 show_pwm_mode, store_pwm_mode, 3), 766 show_pwm_mode, store_pwm_mode, 2),
762}; 767};
763 768
764 769
@@ -1373,7 +1378,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
1373 struct i2c_client *client = to_i2c_client(dev); 1378 struct i2c_client *client = to_i2c_client(dev);
1374 struct w83792d_data *data = i2c_get_clientdata(client); 1379 struct w83792d_data *data = i2c_get_clientdata(client);
1375 int i, j; 1380 int i, j;
1376 u8 reg_array_tmp[4], pwm_array_tmp[7], reg_tmp; 1381 u8 reg_array_tmp[4], reg_tmp;
1377 1382
1378 mutex_lock(&data->update_lock); 1383 mutex_lock(&data->update_lock);
1379 1384
@@ -1402,10 +1407,8 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
1402 data->fan_min[i] = w83792d_read_value(client, 1407 data->fan_min[i] = w83792d_read_value(client,
1403 W83792D_REG_FAN_MIN[i]); 1408 W83792D_REG_FAN_MIN[i]);
1404 /* Update the PWM/DC Value and PWM/DC flag */ 1409 /* Update the PWM/DC Value and PWM/DC flag */
1405 pwm_array_tmp[i] = w83792d_read_value(client, 1410 data->pwm[i] = w83792d_read_value(client,
1406 W83792D_REG_PWM[i]); 1411 W83792D_REG_PWM[i]);
1407 data->pwm[i] = pwm_array_tmp[i] & 0x0f;
1408 data->pwm_mode[i] = pwm_array_tmp[i] >> 7;
1409 } 1412 }
1410 1413
1411 reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG); 1414 reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG);
@@ -1513,7 +1516,6 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev)
1513 dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]); 1516 dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]);
1514 dev_dbg(dev, "fan[%d] min is: 0x%x\n", i, data->fan_min[i]); 1517 dev_dbg(dev, "fan[%d] min is: 0x%x\n", i, data->fan_min[i]);
1515 dev_dbg(dev, "pwm[%d] is: 0x%x\n", i, data->pwm[i]); 1518 dev_dbg(dev, "pwm[%d] is: 0x%x\n", i, data->pwm[i]);
1516 dev_dbg(dev, "pwm_mode[%d] is: 0x%x\n", i, data->pwm_mode[i]);
1517 } 1519 }
1518 dev_dbg(dev, "3 set of Temperatures: =====>\n"); 1520 dev_dbg(dev, "3 set of Temperatures: =====>\n");
1519 for (i=0; i<3; i++) { 1521 for (i=0; i<3; i++) {