diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/w83792d.c | 56 |
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 | ||
257 | static inline u8 | 255 | static 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 | ||
633 | static ssize_t | 630 | static 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 | ||
709 | static struct sensor_device_attribute sda_pwm[] = { | 708 | static 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 | }; |
714 | static struct sensor_device_attribute sda_pwm_enable[] = { | 713 | static 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 | ||
734 | static ssize_t | 733 | static 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 | ||
755 | static struct sensor_device_attribute sda_pwm_mode[] = { | 760 | static 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++) { |