Marc Hulsman wrote: > These patches add support for pwm_enable. I did allow for setting fan speed > cruise mode although I will only implement further support for thermal cruise > mode (next patch), as the bios could initialize the chip with this mode. > > Marc > > --- > Add support for pwm_enable. > > Signed-off-by: Marc Hulsman <m.hulsman at tudelft.nl> > > --- > Documentation/hwmon/w83791d | 13 ++++++- > drivers/hwmon/w83791d.c | 79 > ++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 91 insertions(+), 1 deletion(-) > > --- > Index: linux-2.6.27-rc1/Documentation/hwmon/w83791d > =================================================================== > --- linux-2.6.27-rc1.orig/Documentation/hwmon/w83791d > +++ linux-2.6.27-rc1/Documentation/hwmon/w83791d > @@ -108,6 +108,17 @@ going forward. > The driver reads the hardware chip values at most once every three seconds. > 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 > ------------------------------------ > For legacy code using the alarms and beep_mask files: > @@ -138,4 +149,4 @@ global_enable: alarms: -------- beep_ma > > W83791D TODO: > --------------- > -Provide a patch for smart-fan control (still need appropriate > motherboard/fans) > +Provide a patch for Thermal Cruise registers. > Index: linux-2.6.27-rc1/drivers/hwmon/w83791d.c > =================================================================== > --- linux-2.6.27-rc1.orig/drivers/hwmon/w83791d.c > +++ linux-2.6.27-rc1/drivers/hwmon/w83791d.c > @@ -287,6 +287,8 @@ struct w83791d_data { > > /* PWMs */ > 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 */ > u32 alarms; /* realtime status register encoding,combined */ > @@ -707,6 +709,71 @@ static struct sensor_device_attribute sd > 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]); > +} You show data->pwm_enable "as is", but ... > + > +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; Here you store "val - 1", continued ... > + switch (nr) { > + case 0: > + reg_idx = 0; > + val_shift = 2; > + keep_mask = 0xf3; > + break; <snip> > @@ -1324,6 +1394,15 @@ static struct w83791d_data *w83791d_upda > 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) + 1; > + data->pwm_enable[1] = ((reg_array_tmp[0] >> 4) & 0x03) + 1; > + data->pwm_enable[2] = ((reg_array_tmp[1] >> 2) & 0x03) + 1; > + > /* Update the first temperature sensor */ > for (i = 0; i < 3; i++) { > data->temp1[i] = w83791d_read(client, And here you store the register val + 1 again, making show_pwmenable actually show the less value, unless pwm#_enable is read very quickly after a write, in which case w83791d_update won't do anything and the shown pwm_enable value will be one to small. I think it would be best to consistently store the val as seen by userspace - 1 (iow the actual reg val) in pwm_enable (as you do in store_pwmenable) and then add the + 1 when showing it. Regards, Hans