aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/w83791d15
-rw-r--r--drivers/hwmon/w83791d.c67
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
58currently selected). If you know the address of the chip, use a 'force' 58currently selected). If you know the address of the chip, use a 'force'
59parameter; this will put it into a more well-behaved state first. 59parameter; this will put it into a more well-behaved state first.
60 60
61The driver implements three temperature sensors, five fan rotation speed 61The driver implements three temperature sensors, ten voltage sensors,
62sensors, and ten voltage sensors. 62five fan rotation speed sensors and manual PWM control of each fan.
63 63
64Temperatures are measured in degrees Celsius and measurement resolution is 1 64Temperatures are measured in degrees Celsius and measurement resolution is 1
65degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when 65degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
66the temperature gets higher than the Overtemperature Shutdown value; it stays 66the temperature gets higher than the Overtemperature Shutdown value; it stays
67on until the temperature falls below the Hysteresis value. 67on until the temperature falls below the Hysteresis value.
68 68
69Voltage sensors (also known as IN sensors) report their values in millivolts.
70An alarm is triggered if the voltage has crossed a programmable minimum
71or maximum limit.
72
69Fan rotation speeds are reported in RPM (rotations per minute). An alarm is 73Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
70triggered if the rotation speed has dropped below a programmable limit. Fan 74triggered if the rotation speed has dropped below a programmable limit. Fan
71readings can be divided by a programmable divider (1, 2, 4, 8, 16, 75readings can be divided by a programmable divider (1, 2, 4, 8, 16,
7232, 64 or 128 for all fans) to give the readings more range or accuracy. 7632, 64 or 128 for all fans) to give the readings more range or accuracy.
73 77
74Voltage sensors (also known as IN sensors) report their values in millivolts. 78Each fan controlled is controlled by PWM. The PWM duty cycle can be read and
75An alarm is triggered if the voltage has crossed a programmable minimum 79set for each fan separately. Valid values range from 0 (stop) to 255 (full).
76or maximum limit.
77 80
78The w83791d has a global bit used to enable beeping from the speaker when an 81The w83791d has a global bit used to enable beeping from the speaker when an
79alarm is triggered as well as a bitmask to enable or disable the beep for 82alarm is triggered as well as a bitmask to enable or disable the beep for
80specific alarms. You need both the global beep enable bit and the 83specific alarms. You need both the global beep enable bit and the
81corresponding beep bit to be on for a triggered alarm to sound a beep. 84corresponding beep bit to be on for a triggered alarm to sound a beep.
82 85
83The sysfs interface to the gloabal enable is via the sysfs beep_enable file. 86The sysfs interface to the global enable is via the sysfs beep_enable file.
84This file is used for both legacy and new code. 87This file is used for both legacy and new code.
85 88
86The sysfs interface to the beep bitmask has migrated from the original legacy 89The 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 */
50static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, 51static 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
120static 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
119static const u8 W83791D_REG_FAN_CFG[2] = { 128static 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 */
669static 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
678static 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
697static 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 */
657static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, 711static 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 = {
930static struct attribute *w83791d_attributes_fanpwm45[] = { 987static 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,