diff options
-rw-r--r-- | Documentation/hwmon/w83791d | 15 | ||||
-rw-r--r-- | drivers/hwmon/w83791d.c | 67 |
2 files changed, 75 insertions, 7 deletions
diff --git a/Documentation/hwmon/w83791d b/Documentation/hwmon/w83791d index a67d3b7a7098..49c0e94a118c 100644 --- a/Documentation/hwmon/w83791d +++ b/Documentation/hwmon/w83791d | |||
@@ -58,29 +58,32 @@ internal state that allows no clean access (Bank with ID register is not | |||
58 | currently selected). If you know the address of the chip, use a 'force' | 58 | currently selected). If you know the address of the chip, use a 'force' |
59 | parameter; this will put it into a more well-behaved state first. | 59 | parameter; this will put it into a more well-behaved state first. |
60 | 60 | ||
61 | The driver implements three temperature sensors, five fan rotation speed | 61 | The driver implements three temperature sensors, ten voltage sensors, |
62 | sensors, and ten voltage sensors. | 62 | five fan rotation speed sensors and manual PWM control of each fan. |
63 | 63 | ||
64 | Temperatures are measured in degrees Celsius and measurement resolution is 1 | 64 | Temperatures are measured in degrees Celsius and measurement resolution is 1 |
65 | degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when | 65 | degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when |
66 | the temperature gets higher than the Overtemperature Shutdown value; it stays | 66 | the temperature gets higher than the Overtemperature Shutdown value; it stays |
67 | on until the temperature falls below the Hysteresis value. | 67 | on until the temperature falls below the Hysteresis value. |
68 | 68 | ||
69 | Voltage sensors (also known as IN sensors) report their values in millivolts. | ||
70 | An alarm is triggered if the voltage has crossed a programmable minimum | ||
71 | or maximum limit. | ||
72 | |||
69 | Fan rotation speeds are reported in RPM (rotations per minute). An alarm is | 73 | Fan rotation speeds are reported in RPM (rotations per minute). An alarm is |
70 | triggered if the rotation speed has dropped below a programmable limit. Fan | 74 | triggered if the rotation speed has dropped below a programmable limit. Fan |
71 | readings can be divided by a programmable divider (1, 2, 4, 8, 16, | 75 | readings can be divided by a programmable divider (1, 2, 4, 8, 16, |
72 | 32, 64 or 128 for all fans) to give the readings more range or accuracy. | 76 | 32, 64 or 128 for all fans) to give the readings more range or accuracy. |
73 | 77 | ||
74 | Voltage sensors (also known as IN sensors) report their values in millivolts. | 78 | Each fan controlled is controlled by PWM. The PWM duty cycle can be read and |
75 | An alarm is triggered if the voltage has crossed a programmable minimum | 79 | set for each fan separately. Valid values range from 0 (stop) to 255 (full). |
76 | or maximum limit. | ||
77 | 80 | ||
78 | The w83791d has a global bit used to enable beeping from the speaker when an | 81 | The w83791d has a global bit used to enable beeping from the speaker when an |
79 | alarm is triggered as well as a bitmask to enable or disable the beep for | 82 | alarm is triggered as well as a bitmask to enable or disable the beep for |
80 | specific alarms. You need both the global beep enable bit and the | 83 | specific alarms. You need both the global beep enable bit and the |
81 | corresponding beep bit to be on for a triggered alarm to sound a beep. | 84 | corresponding beep bit to be on for a triggered alarm to sound a beep. |
82 | 85 | ||
83 | The sysfs interface to the gloabal enable is via the sysfs beep_enable file. | 86 | The sysfs interface to the global enable is via the sysfs beep_enable file. |
84 | This file is used for both legacy and new code. | 87 | This file is used for both legacy and new code. |
85 | 88 | ||
86 | The sysfs interface to the beep bitmask has migrated from the original legacy | 89 | The sysfs interface to the beep bitmask has migrated from the original legacy |
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 6b1cec9950ff..a8ff4e126713 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
@@ -23,7 +23,7 @@ | |||
23 | Supports following chips: | 23 | Supports following chips: |
24 | 24 | ||
25 | Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | 25 | Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA |
26 | w83791d 10 5 3 3 0x71 0x5ca3 yes no | 26 | w83791d 10 5 5 3 0x71 0x5ca3 yes no |
27 | 27 | ||
28 | The w83791d chip appears to be part way between the 83781d and the | 28 | The w83791d chip appears to be part way between the 83781d and the |
29 | 83792d. Thus, this file is derived from both the w83792d.c and | 29 | 83792d. Thus, this file is derived from both the w83792d.c and |
@@ -45,6 +45,7 @@ | |||
45 | #define NUMBER_OF_VIN 10 | 45 | #define NUMBER_OF_VIN 10 |
46 | #define NUMBER_OF_FANIN 5 | 46 | #define NUMBER_OF_FANIN 5 |
47 | #define NUMBER_OF_TEMPIN 3 | 47 | #define NUMBER_OF_TEMPIN 3 |
48 | #define NUMBER_OF_PWM 5 | ||
48 | 49 | ||
49 | /* Addresses to scan */ | 50 | /* Addresses to scan */ |
50 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, | 51 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, |
@@ -116,6 +117,14 @@ static const u8 W83791D_REG_FAN_MIN[NUMBER_OF_FANIN] = { | |||
116 | 0xBD, /* FAN 5 Count Low Limit in DataSheet */ | 117 | 0xBD, /* FAN 5 Count Low Limit in DataSheet */ |
117 | }; | 118 | }; |
118 | 119 | ||
120 | static const u8 W83791D_REG_PWM[NUMBER_OF_PWM] = { | ||
121 | 0x81, /* PWM 1 duty cycle register in DataSheet */ | ||
122 | 0x83, /* PWM 2 duty cycle register in DataSheet */ | ||
123 | 0x94, /* PWM 3 duty cycle register in DataSheet */ | ||
124 | 0xA0, /* PWM 4 duty cycle register in DataSheet */ | ||
125 | 0xA1, /* PWM 5 duty cycle register in DataSheet */ | ||
126 | }; | ||
127 | |||
119 | static const u8 W83791D_REG_FAN_CFG[2] = { | 128 | static const u8 W83791D_REG_FAN_CFG[2] = { |
120 | 0x84, /* FAN 1/2 configuration */ | 129 | 0x84, /* FAN 1/2 configuration */ |
121 | 0x95, /* FAN 3 configuration */ | 130 | 0x95, /* FAN 3 configuration */ |
@@ -276,6 +285,9 @@ struct w83791d_data { | |||
276 | two sensors with three values | 285 | two sensors with three values |
277 | (cur, over, hyst) */ | 286 | (cur, over, hyst) */ |
278 | 287 | ||
288 | /* PWMs */ | ||
289 | u8 pwm[5]; /* pwm duty cycle */ | ||
290 | |||
279 | /* Misc */ | 291 | /* Misc */ |
280 | u32 alarms; /* realtime status register encoding,combined */ | 292 | u32 alarms; /* realtime status register encoding,combined */ |
281 | u8 beep_enable; /* Global beep enable */ | 293 | u8 beep_enable; /* Global beep enable */ |
@@ -653,6 +665,48 @@ static struct sensor_device_attribute sda_fan_alarm[] = { | |||
653 | SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22), | 665 | SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22), |
654 | }; | 666 | }; |
655 | 667 | ||
668 | /* read/write PWMs */ | ||
669 | static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | ||
670 | char *buf) | ||
671 | { | ||
672 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
673 | int nr = sensor_attr->index; | ||
674 | struct w83791d_data *data = w83791d_update_device(dev); | ||
675 | return sprintf(buf, "%u\n", data->pwm[nr]); | ||
676 | } | ||
677 | |||
678 | static ssize_t store_pwm(struct device *dev, struct device_attribute *attr, | ||
679 | const char *buf, size_t count) | ||
680 | { | ||
681 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
682 | struct i2c_client *client = to_i2c_client(dev); | ||
683 | struct w83791d_data *data = i2c_get_clientdata(client); | ||
684 | int nr = sensor_attr->index; | ||
685 | unsigned long val; | ||
686 | |||
687 | if (strict_strtoul(buf, 10, &val)) | ||
688 | return -EINVAL; | ||
689 | |||
690 | mutex_lock(&data->update_lock); | ||
691 | data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); | ||
692 | w83791d_write(client, W83791D_REG_PWM[nr], data->pwm[nr]); | ||
693 | mutex_unlock(&data->update_lock); | ||
694 | return count; | ||
695 | } | ||
696 | |||
697 | static struct sensor_device_attribute sda_pwm[] = { | ||
698 | SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, | ||
699 | show_pwm, store_pwm, 0), | ||
700 | SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, | ||
701 | show_pwm, store_pwm, 1), | ||
702 | SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, | ||
703 | show_pwm, store_pwm, 2), | ||
704 | SENSOR_ATTR(pwm4, S_IWUSR | S_IRUGO, | ||
705 | show_pwm, store_pwm, 3), | ||
706 | SENSOR_ATTR(pwm5, S_IWUSR | S_IRUGO, | ||
707 | show_pwm, store_pwm, 4), | ||
708 | }; | ||
709 | |||
656 | /* read/write the temperature1, includes measured value and limits */ | 710 | /* read/write the temperature1, includes measured value and limits */ |
657 | static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, | 711 | static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, |
658 | char *buf) | 712 | char *buf) |
@@ -917,6 +971,9 @@ static struct attribute *w83791d_attributes[] = { | |||
917 | &sda_beep_ctrl[1].dev_attr.attr, | 971 | &sda_beep_ctrl[1].dev_attr.attr, |
918 | &dev_attr_cpu0_vid.attr, | 972 | &dev_attr_cpu0_vid.attr, |
919 | &dev_attr_vrm.attr, | 973 | &dev_attr_vrm.attr, |
974 | &sda_pwm[0].dev_attr.attr, | ||
975 | &sda_pwm[1].dev_attr.attr, | ||
976 | &sda_pwm[2].dev_attr.attr, | ||
920 | NULL | 977 | NULL |
921 | }; | 978 | }; |
922 | 979 | ||
@@ -930,6 +987,8 @@ static const struct attribute_group w83791d_group = { | |||
930 | static struct attribute *w83791d_attributes_fanpwm45[] = { | 987 | static struct attribute *w83791d_attributes_fanpwm45[] = { |
931 | FAN_UNIT_ATTRS(3), | 988 | FAN_UNIT_ATTRS(3), |
932 | FAN_UNIT_ATTRS(4), | 989 | FAN_UNIT_ATTRS(4), |
990 | &sda_pwm[3].dev_attr.attr, | ||
991 | &sda_pwm[4].dev_attr.attr, | ||
933 | NULL | 992 | NULL |
934 | }; | 993 | }; |
935 | 994 | ||
@@ -1260,6 +1319,12 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) | |||
1260 | for (i = 0; i < 3; i++) | 1319 | for (i = 0; i < 3; i++) |
1261 | data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04; | 1320 | data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04; |
1262 | 1321 | ||
1322 | /* Update PWM duty cycle */ | ||
1323 | for (i = 0; i < NUMBER_OF_PWM; i++) { | ||
1324 | data->pwm[i] = w83791d_read(client, | ||
1325 | W83791D_REG_PWM[i]); | ||
1326 | } | ||
1327 | |||
1263 | /* Update the first temperature sensor */ | 1328 | /* Update the first temperature sensor */ |
1264 | for (i = 0; i < 3; i++) { | 1329 | for (i = 0; i < 3; i++) { |
1265 | data->temp1[i] = w83791d_read(client, | 1330 | data->temp1[i] = w83791d_read(client, |