Commit 34e7dc6c authored by Jean Delvare's avatar Jean Delvare Committed by Jean Delvare

hwmon: (lm85) Implement the standard PWM frequency interface

Implement the standard PWM frequency interface: pwm[1-*]_freq in
units of 1 Hz, instead of the non-standard pwm[1-*]_auto_pwm_freq
in units of 0.1 Hz. The old naming was not only non-standard, it was
also confusing, because it suggested that the frequency value only
applied in automatic fan speed mode, which isn't true.
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
Acked-by: default avatarHerbert Poetzl <herbert@13thfloor.at>
parent 69fc1feb
...@@ -163,16 +163,6 @@ configured individually according to the following options. ...@@ -163,16 +163,6 @@ configured individually according to the following options.
* pwm#_auto_pwm_min - this specifies the PWM value for temp#_auto_temp_off * pwm#_auto_pwm_min - this specifies the PWM value for temp#_auto_temp_off
temperature. (PWM value from 0 to 255) temperature. (PWM value from 0 to 255)
* pwm#_auto_pwm_freq - select base frequency of PWM output. You can select
in range of 10.0 to 94.0 Hz in .1 Hz units.
(Values 100 to 940).
The pwm#_auto_pwm_freq can be set to one of the following 8 values. Setting the
frequency to a value not on this list, will result in the next higher frequency
being selected. The actual device frequency may vary slightly from this
specification as designed by the manufacturer. Consult the datasheet for more
details. (PWM Frequency values: 100, 150, 230, 300, 380, 470, 620, 940)
* pwm#_auto_pwm_minctl - this flags selects for temp#_auto_temp_off temperature * pwm#_auto_pwm_minctl - this flags selects for temp#_auto_temp_off temperature
the bahaviour of fans. Write 1 to let fans spinning at the bahaviour of fans. Write 1 to let fans spinning at
pwm#_auto_pwm_min or write 0 to let them off. pwm#_auto_pwm_min or write 0 to let them off.
......
...@@ -191,8 +191,8 @@ static int RANGE_TO_REG(int range) ...@@ -191,8 +191,8 @@ static int RANGE_TO_REG(int range)
#define RANGE_FROM_REG(val) lm85_range_map[(val) & 0x0f] #define RANGE_FROM_REG(val) lm85_range_map[(val) & 0x0f]
/* These are the PWM frequency encodings */ /* These are the PWM frequency encodings */
static const int lm85_freq_map[] = { /* .1 Hz */ static const int lm85_freq_map[8] = { /* 1 Hz */
100, 150, 230, 300, 380, 470, 620, 940 10, 15, 23, 30, 38, 47, 62, 94
}; };
static int FREQ_TO_REG(int freq) static int FREQ_TO_REG(int freq)
...@@ -275,7 +275,6 @@ struct lm85_zone { ...@@ -275,7 +275,6 @@ struct lm85_zone {
struct lm85_autofan { struct lm85_autofan {
u8 config; /* Register value */ u8 config; /* Register value */
u8 freq; /* PWM frequency, encoded */
u8 min_pwm; /* Minimum PWM value, encoded */ u8 min_pwm; /* Minimum PWM value, encoded */
u8 min_off; /* Min PWM or OFF below "limit", flag */ u8 min_off; /* Min PWM or OFF below "limit", flag */
}; };
...@@ -301,6 +300,7 @@ struct lm85_data { ...@@ -301,6 +300,7 @@ struct lm85_data {
u16 fan[4]; /* Register value */ u16 fan[4]; /* Register value */
u16 fan_min[4]; /* Register value */ u16 fan_min[4]; /* Register value */
u8 pwm[3]; /* Register value */ u8 pwm[3]; /* Register value */
u8 pwm_freq[3]; /* Register encoding */
u8 temp_ext[3]; /* Decoded values */ u8 temp_ext[3]; /* Decoded values */
u8 in_ext[8]; /* Decoded values */ u8 in_ext[8]; /* Decoded values */
u8 vid; /* Register value */ u8 vid; /* Register value */
...@@ -528,11 +528,38 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute ...@@ -528,11 +528,38 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
return count; return count;
} }
static ssize_t show_pwm_freq(struct device *dev,
struct device_attribute *attr, char *buf)
{
int nr = to_sensor_dev_attr(attr)->index;
struct lm85_data *data = lm85_update_device(dev);
return sprintf(buf, "%d\n", FREQ_FROM_REG(data->pwm_freq[nr]));
}
static ssize_t set_pwm_freq(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
mutex_lock(&data->update_lock);
data->pwm_freq[nr] = FREQ_TO_REG(val);
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
(data->zone[nr].range << 4)
| data->pwm_freq[nr]);
mutex_unlock(&data->update_lock);
return count;
}
#define show_pwm_reg(offset) \ #define show_pwm_reg(offset) \
static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_pwm, set_pwm, offset - 1); \ show_pwm, set_pwm, offset - 1); \
static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
show_pwm_enable, set_pwm_enable, offset - 1) show_pwm_enable, set_pwm_enable, offset - 1); \
static SENSOR_DEVICE_ATTR(pwm##offset##_freq, S_IRUGO | S_IWUSR, \
show_pwm_freq, set_pwm_freq, offset - 1)
show_pwm_reg(1); show_pwm_reg(1);
show_pwm_reg(2); show_pwm_reg(2);
...@@ -761,31 +788,6 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, ...@@ -761,31 +788,6 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev,
return count; return count;
} }
static ssize_t show_pwm_auto_pwm_freq(struct device *dev,
struct device_attribute *attr, char *buf)
{
int nr = to_sensor_dev_attr(attr)->index;
struct lm85_data *data = lm85_update_device(dev);
return sprintf(buf, "%d\n", FREQ_FROM_REG(data->autofan[nr].freq));
}
static ssize_t set_pwm_auto_pwm_freq(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
mutex_lock(&data->update_lock);
data->autofan[nr].freq = FREQ_TO_REG(val);
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
(data->zone[nr].range << 4)
| data->autofan[nr].freq);
mutex_unlock(&data->update_lock);
return count;
}
#define pwm_auto(offset) \ #define pwm_auto(offset) \
static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels, \ static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels, \
S_IRUGO | S_IWUSR, show_pwm_auto_channels, \ S_IRUGO | S_IWUSR, show_pwm_auto_channels, \
...@@ -795,10 +797,7 @@ static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_min, \ ...@@ -795,10 +797,7 @@ static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_min, \
set_pwm_auto_pwm_min, offset - 1); \ set_pwm_auto_pwm_min, offset - 1); \
static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, \ static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, \
S_IRUGO | S_IWUSR, show_pwm_auto_pwm_minctl, \ S_IRUGO | S_IWUSR, show_pwm_auto_pwm_minctl, \
set_pwm_auto_pwm_minctl, offset - 1); \ set_pwm_auto_pwm_minctl, offset - 1)
static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_freq, \
S_IRUGO | S_IWUSR, show_pwm_auto_pwm_freq, \
set_pwm_auto_pwm_freq, offset - 1);
pwm_auto(1); pwm_auto(1);
pwm_auto(2); pwm_auto(2);
...@@ -867,7 +866,7 @@ static ssize_t set_temp_auto_temp_min(struct device *dev, ...@@ -867,7 +866,7 @@ static ssize_t set_temp_auto_temp_min(struct device *dev,
TEMP_FROM_REG(data->zone[nr].limit)); TEMP_FROM_REG(data->zone[nr].limit));
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
((data->zone[nr].range & 0x0f) << 4) ((data->zone[nr].range & 0x0f) << 4)
| (data->autofan[nr].freq & 0x07)); | (data->pwm_freq[nr] & 0x07));
/* Update temp_auto_hyst and temp_auto_off */ /* Update temp_auto_hyst and temp_auto_off */
data->zone[nr].hyst = HYST_TO_REG(TEMP_FROM_REG( data->zone[nr].hyst = HYST_TO_REG(TEMP_FROM_REG(
...@@ -910,7 +909,7 @@ static ssize_t set_temp_auto_temp_max(struct device *dev, ...@@ -910,7 +909,7 @@ static ssize_t set_temp_auto_temp_max(struct device *dev,
val - min); val - min);
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
((data->zone[nr].range & 0x0f) << 4) ((data->zone[nr].range & 0x0f) << 4)
| (data->autofan[nr].freq & 0x07)); | (data->pwm_freq[nr] & 0x07));
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return count; return count;
} }
...@@ -984,6 +983,9 @@ static struct attribute *lm85_attributes[] = { ...@@ -984,6 +983,9 @@ static struct attribute *lm85_attributes[] = {
&sensor_dev_attr_pwm1_enable.dev_attr.attr, &sensor_dev_attr_pwm1_enable.dev_attr.attr,
&sensor_dev_attr_pwm2_enable.dev_attr.attr, &sensor_dev_attr_pwm2_enable.dev_attr.attr,
&sensor_dev_attr_pwm3_enable.dev_attr.attr, &sensor_dev_attr_pwm3_enable.dev_attr.attr,
&sensor_dev_attr_pwm1_freq.dev_attr.attr,
&sensor_dev_attr_pwm2_freq.dev_attr.attr,
&sensor_dev_attr_pwm3_freq.dev_attr.attr,
&sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr, &sensor_dev_attr_in1_input.dev_attr.attr,
...@@ -1026,9 +1028,6 @@ static struct attribute *lm85_attributes[] = { ...@@ -1026,9 +1028,6 @@ static struct attribute *lm85_attributes[] = {
&sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_pwm_freq.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_pwm_freq.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_pwm_freq.dev_attr.attr,
&sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr,
&sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr,
...@@ -1458,7 +1457,7 @@ static struct lm85_data *lm85_update_device(struct device *dev) ...@@ -1458,7 +1457,7 @@ static struct lm85_data *lm85_update_device(struct device *dev)
data->autofan[i].config = data->autofan[i].config =
lm85_read_value(client, LM85_REG_AFAN_CONFIG(i)); lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i)); val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
data->autofan[i].freq = val & 0x07; data->pwm_freq[i] = val & 0x07;
data->zone[i].range = val >> 4; data->zone[i].range = val >> 4;
data->autofan[i].min_pwm = data->autofan[i].min_pwm =
lm85_read_value(client, LM85_REG_AFAN_MINPWM(i)); lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment