diff options
author | Marc Hulsman <m.hulsman@tudelft.nl> | 2008-10-17 11:51:17 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-10-17 11:51:17 -0400 |
commit | b5938f8c4a530b2fad18f2293ffaf79ac9f5a148 (patch) | |
tree | 0d8d9ca9640e34e494f1dd5337c5b2593f22133c /drivers/hwmon/w83791d.c | |
parent | 6495ce184033d5e70dfdf5bb8d149e9e02feaaa9 (diff) |
hwmon: (w83791d) add pwm_enable support
Add support for pwm_enable.
Signed-off-by: Marc Hulsman <m.hulsman@tudelft.nl>
Acked-by: Hans de Goede <j.w.r.degoede@hhs.nl>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/w83791d.c')
-rw-r--r-- | drivers/hwmon/w83791d.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index a8ff4e126713..a4d2b02d9e04 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
@@ -287,6 +287,8 @@ struct w83791d_data { | |||
287 | 287 | ||
288 | /* PWMs */ | 288 | /* PWMs */ |
289 | u8 pwm[5]; /* pwm duty cycle */ | 289 | u8 pwm[5]; /* pwm duty cycle */ |
290 | u8 pwm_enable[3]; /* pwm enable status for fan 1-3 | ||
291 | (fan 4-5 only support manual mode) */ | ||
290 | 292 | ||
291 | /* Misc */ | 293 | /* Misc */ |
292 | u32 alarms; /* realtime status register encoding,combined */ | 294 | u32 alarms; /* realtime status register encoding,combined */ |
@@ -707,6 +709,71 @@ static struct sensor_device_attribute sda_pwm[] = { | |||
707 | show_pwm, store_pwm, 4), | 709 | show_pwm, store_pwm, 4), |
708 | }; | 710 | }; |
709 | 711 | ||
712 | static ssize_t show_pwmenable(struct device *dev, struct device_attribute *attr, | ||
713 | char *buf) | ||
714 | { | ||
715 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
716 | int nr = sensor_attr->index; | ||
717 | struct w83791d_data *data = w83791d_update_device(dev); | ||
718 | return sprintf(buf, "%u\n", data->pwm_enable[nr] + 1); | ||
719 | } | ||
720 | |||
721 | static ssize_t store_pwmenable(struct device *dev, | ||
722 | struct device_attribute *attr, const char *buf, size_t count) | ||
723 | { | ||
724 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
725 | struct i2c_client *client = to_i2c_client(dev); | ||
726 | struct w83791d_data *data = i2c_get_clientdata(client); | ||
727 | int nr = sensor_attr->index; | ||
728 | unsigned long val; | ||
729 | u8 reg_cfg_tmp; | ||
730 | u8 reg_idx = 0; | ||
731 | u8 val_shift = 0; | ||
732 | u8 keep_mask = 0; | ||
733 | |||
734 | int ret = strict_strtoul(buf, 10, &val); | ||
735 | |||
736 | if (ret || val < 1 || val > 3) | ||
737 | return -EINVAL; | ||
738 | |||
739 | mutex_lock(&data->update_lock); | ||
740 | data->pwm_enable[nr] = val - 1; | ||
741 | switch (nr) { | ||
742 | case 0: | ||
743 | reg_idx = 0; | ||
744 | val_shift = 2; | ||
745 | keep_mask = 0xf3; | ||
746 | break; | ||
747 | case 1: | ||
748 | reg_idx = 0; | ||
749 | val_shift = 4; | ||
750 | keep_mask = 0xcf; | ||
751 | break; | ||
752 | case 2: | ||
753 | reg_idx = 1; | ||
754 | val_shift = 2; | ||
755 | keep_mask = 0xf3; | ||
756 | break; | ||
757 | } | ||
758 | |||
759 | reg_cfg_tmp = w83791d_read(client, W83791D_REG_FAN_CFG[reg_idx]); | ||
760 | reg_cfg_tmp = (reg_cfg_tmp & keep_mask) | | ||
761 | data->pwm_enable[nr] << val_shift; | ||
762 | |||
763 | w83791d_write(client, W83791D_REG_FAN_CFG[reg_idx], reg_cfg_tmp); | ||
764 | mutex_unlock(&data->update_lock); | ||
765 | |||
766 | return count; | ||
767 | } | ||
768 | static struct sensor_device_attribute sda_pwmenable[] = { | ||
769 | SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, | ||
770 | show_pwmenable, store_pwmenable, 0), | ||
771 | SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, | ||
772 | show_pwmenable, store_pwmenable, 1), | ||
773 | SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, | ||
774 | show_pwmenable, store_pwmenable, 2), | ||
775 | }; | ||
776 | |||
710 | /* read/write the temperature1, includes measured value and limits */ | 777 | /* read/write the temperature1, includes measured value and limits */ |
711 | static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, | 778 | static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, |
712 | char *buf) | 779 | char *buf) |
@@ -974,6 +1041,9 @@ static struct attribute *w83791d_attributes[] = { | |||
974 | &sda_pwm[0].dev_attr.attr, | 1041 | &sda_pwm[0].dev_attr.attr, |
975 | &sda_pwm[1].dev_attr.attr, | 1042 | &sda_pwm[1].dev_attr.attr, |
976 | &sda_pwm[2].dev_attr.attr, | 1043 | &sda_pwm[2].dev_attr.attr, |
1044 | &sda_pwmenable[0].dev_attr.attr, | ||
1045 | &sda_pwmenable[1].dev_attr.attr, | ||
1046 | &sda_pwmenable[2].dev_attr.attr, | ||
977 | NULL | 1047 | NULL |
978 | }; | 1048 | }; |
979 | 1049 | ||
@@ -1325,6 +1395,15 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) | |||
1325 | W83791D_REG_PWM[i]); | 1395 | W83791D_REG_PWM[i]); |
1326 | } | 1396 | } |
1327 | 1397 | ||
1398 | /* Update PWM enable status */ | ||
1399 | for (i = 0; i < 2; i++) { | ||
1400 | reg_array_tmp[i] = w83791d_read(client, | ||
1401 | W83791D_REG_FAN_CFG[i]); | ||
1402 | } | ||
1403 | data->pwm_enable[0] = (reg_array_tmp[0] >> 2) & 0x03; | ||
1404 | data->pwm_enable[1] = (reg_array_tmp[0] >> 4) & 0x03; | ||
1405 | data->pwm_enable[2] = (reg_array_tmp[1] >> 2) & 0x03; | ||
1406 | |||
1328 | /* Update the first temperature sensor */ | 1407 | /* Update the first temperature sensor */ |
1329 | for (i = 0; i < 3; i++) { | 1408 | for (i = 0; i < 3; i++) { |
1330 | data->temp1[i] = w83791d_read(client, | 1409 | data->temp1[i] = w83791d_read(client, |