hwmon: (lm85) Add support for ADT7468 high-frequency PWM mode

The ADT7468 supports a high-frequency PWM output mode where all PWM
outputs are driven by a 22.5 kHz clock. Add support for this mode, and
document it, as it may surprise the user that setting one PWM output
frequency also affects the other PWM outputs.

Signed-off-by: Jean Delvare <[email protected]>
Cc: Darrick J. Wong <[email protected]>
Acked-by: Guenter Roeck <[email protected]>
This commit is contained in:
Jean Delvare 2010-10-28 20:31:50 +02:00 • committed by Jean Delvare
commit f6c61cff8b
2 changed files with 35 additions and 7 deletions

View file

@ -64,9 +64,12 @@ enum chips {
#define LM85_REG_VERSTEP 0x3f
#define ADT7468_REG_CFG5 0x7c
#define ADT7468_OFF64 0x01
#define ADT7468_OFF64 (1 << 0)
#define ADT7468_HFPWM (1 << 1)
#define IS_ADT7468_OFF64(data) \
((data)->type == adt7468 && !((data)->cfg5 & ADT7468_OFF64))
#define IS_ADT7468_HFPWM(data) \
((data)->type == adt7468 && !((data)->cfg5 & ADT7468_HFPWM))
/* These are the recognized values for the above regs */
#define LM85_COMPANY_NATIONAL 0x01
@ -567,8 +570,14 @@ static ssize_t show_pwm_freq(struct device *dev,
{
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->freq_map,
data->pwm_freq[nr]));
int freq;
if (IS_ADT7468_HFPWM(data))
freq = 22500;
else
freq = FREQ_FROM_REG(data->freq_map, data->pwm_freq[nr]);
return sprintf(buf, "%d\n", freq);
}
static ssize_t set_pwm_freq(struct device *dev,
@ -580,10 +589,22 @@ static ssize_t set_pwm_freq(struct device *dev,
long val = simple_strtol(buf, NULL, 10);
mutex_lock(&data->update_lock);
data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, val);
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
(data->zone[nr].range << 4)
| data->pwm_freq[nr]);
/* The ADT7468 has a special high-frequency PWM output mode,
* where all PWM outputs are driven by a 22.5 kHz clock.
* This might confuse the user, but there's not much we can do. */
if (data->type == adt7468 && val >= 11300) { /* High freq. mode */
data->cfg5 &= ~ADT7468_HFPWM;
lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5);
} else { /* Low freq. mode */
data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, val);
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
(data->zone[nr].range << 4)
| data->pwm_freq[nr]);
if (data->type == adt7468) {
data->cfg5 |= ADT7468_HFPWM;
lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5);
}
}
mutex_unlock(&data->update_lock);
return count;
}