提交 b5938f8c 编写于 作者: M Marc Hulsman 提交者: Jean Delvare

hwmon: (w83791d) add pwm_enable support

Add support for pwm_enable.
Signed-off-by: NMarc Hulsman <m.hulsman@tudelft.nl>
Acked-by: NHans de Goede <j.w.r.degoede@hhs.nl>
Signed-off-by: NJean Delvare <khali@linux-fr.org>
上级 6495ce18
...@@ -108,6 +108,17 @@ going forward. ...@@ -108,6 +108,17 @@ going forward.
The driver reads the hardware chip values at most once every three seconds. The driver reads the hardware chip values at most once every three seconds.
User mode code requesting values more often will receive cached values. User mode code requesting values more often will receive cached values.
/sys files
----------
The sysfs-interface is documented in the 'sysfs-interface' file. Only
chip-specific options are documented here.
pwm[1-3]_enable - this file controls mode of fan/temperature control for
fan 1-3. Fan/PWM 4-5 only support manual mode.
* 1 Manual mode
* 2 Thermal Cruise mode (no further support)
* 3 Fan Speed Cruise mode (no further support)
Alarms bitmap vs. beep_mask bitmask Alarms bitmap vs. beep_mask bitmask
------------------------------------ ------------------------------------
For legacy code using the alarms and beep_mask files: For legacy code using the alarms and beep_mask files:
...@@ -138,4 +149,4 @@ global_enable: alarms: -------- beep_mask: 0x800000 (modified via beep_enable) ...@@ -138,4 +149,4 @@ global_enable: alarms: -------- beep_mask: 0x800000 (modified via beep_enable)
W83791D TODO: W83791D TODO:
--------------- ---------------
Provide a patch for smart-fan control (still need appropriate motherboard/fans) Provide a patch for Thermal Cruise registers.
...@@ -287,6 +287,8 @@ struct w83791d_data { ...@@ -287,6 +287,8 @@ struct w83791d_data {
/* PWMs */ /* PWMs */
u8 pwm[5]; /* pwm duty cycle */ u8 pwm[5]; /* pwm duty cycle */
u8 pwm_enable[3]; /* pwm enable status for fan 1-3
(fan 4-5 only support manual mode) */
/* Misc */ /* Misc */
u32 alarms; /* realtime status register encoding,combined */ u32 alarms; /* realtime status register encoding,combined */
...@@ -707,6 +709,71 @@ static struct sensor_device_attribute sda_pwm[] = { ...@@ -707,6 +709,71 @@ static struct sensor_device_attribute sda_pwm[] = {
show_pwm, store_pwm, 4), show_pwm, store_pwm, 4),
}; };
static ssize_t show_pwmenable(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
struct w83791d_data *data = w83791d_update_device(dev);
return sprintf(buf, "%u\n", data->pwm_enable[nr] + 1);
}
static ssize_t store_pwmenable(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
struct i2c_client *client = to_i2c_client(dev);
struct w83791d_data *data = i2c_get_clientdata(client);
int nr = sensor_attr->index;
unsigned long val;
u8 reg_cfg_tmp;
u8 reg_idx = 0;
u8 val_shift = 0;
u8 keep_mask = 0;
int ret = strict_strtoul(buf, 10, &val);
if (ret || val < 1 || val > 3)
return -EINVAL;
mutex_lock(&data->update_lock);
data->pwm_enable[nr] = val - 1;
switch (nr) {
case 0:
reg_idx = 0;
val_shift = 2;
keep_mask = 0xf3;
break;
case 1:
reg_idx = 0;
val_shift = 4;
keep_mask = 0xcf;
break;
case 2:
reg_idx = 1;
val_shift = 2;
keep_mask = 0xf3;
break;
}
reg_cfg_tmp = w83791d_read(client, W83791D_REG_FAN_CFG[reg_idx]);
reg_cfg_tmp = (reg_cfg_tmp & keep_mask) |
data->pwm_enable[nr] << val_shift;
w83791d_write(client, W83791D_REG_FAN_CFG[reg_idx], reg_cfg_tmp);
mutex_unlock(&data->update_lock);
return count;
}
static struct sensor_device_attribute sda_pwmenable[] = {
SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
show_pwmenable, store_pwmenable, 0),
SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
show_pwmenable, store_pwmenable, 1),
SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO,
show_pwmenable, store_pwmenable, 2),
};
/* read/write the temperature1, includes measured value and limits */ /* read/write the temperature1, includes measured value and limits */
static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr,
char *buf) char *buf)
...@@ -974,6 +1041,9 @@ static struct attribute *w83791d_attributes[] = { ...@@ -974,6 +1041,9 @@ static struct attribute *w83791d_attributes[] = {
&sda_pwm[0].dev_attr.attr, &sda_pwm[0].dev_attr.attr,
&sda_pwm[1].dev_attr.attr, &sda_pwm[1].dev_attr.attr,
&sda_pwm[2].dev_attr.attr, &sda_pwm[2].dev_attr.attr,
&sda_pwmenable[0].dev_attr.attr,
&sda_pwmenable[1].dev_attr.attr,
&sda_pwmenable[2].dev_attr.attr,
NULL NULL
}; };
...@@ -1325,6 +1395,15 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) ...@@ -1325,6 +1395,15 @@ static struct w83791d_data *w83791d_update_device(struct device *dev)
W83791D_REG_PWM[i]); W83791D_REG_PWM[i]);
} }
/* Update PWM enable status */
for (i = 0; i < 2; i++) {
reg_array_tmp[i] = w83791d_read(client,
W83791D_REG_FAN_CFG[i]);
}
data->pwm_enable[0] = (reg_array_tmp[0] >> 2) & 0x03;
data->pwm_enable[1] = (reg_array_tmp[0] >> 4) & 0x03;
data->pwm_enable[2] = (reg_array_tmp[1] >> 2) & 0x03;
/* Update the first temperature sensor */ /* Update the first temperature sensor */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
data->temp1[i] = w83791d_read(client, data->temp1[i] = w83791d_read(client,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册