hwmon: (it87) Add support for second pwm frequency register

Recent chips have a separate register to select the pwm2 frequency.

Tested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Guenter Roeck 2015-03-26 19:57:42 -07:00
parent 36c4d98a78
commit 60878bcfd3
1 changed files with 69 additions and 31 deletions

View File

@ -274,6 +274,7 @@ struct it87_devices {
#define FEAT_10_9MV_ADC (1 << 12) #define FEAT_10_9MV_ADC (1 << 12)
#define FEAT_AVCC3 (1 << 13) /* Chip supports in9/AVCC3 */ #define FEAT_AVCC3 (1 << 13) /* Chip supports in9/AVCC3 */
#define FEAT_SIX_PWM (1 << 14) /* Chip supports 6 pwm chn */ #define FEAT_SIX_PWM (1 << 14) /* Chip supports 6 pwm chn */
#define FEAT_PWM_FREQ2 (1 << 15) /* Separate pwm freq 2 */
static const struct it87_devices it87_devices[] = { static const struct it87_devices it87_devices[] = {
[it87] = { [it87] = {
@ -291,20 +292,22 @@ static const struct it87_devices it87_devices[] = {
.name = "it8716", .name = "it8716",
.suffix = "F", .suffix = "F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2,
}, },
[it8718] = { [it8718] = {
.name = "it8718", .name = "it8718",
.suffix = "F", .suffix = "F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2,
.old_peci_mask = 0x4, .old_peci_mask = 0x4,
}, },
[it8720] = { [it8720] = {
.name = "it8720", .name = "it8720",
.suffix = "F", .suffix = "F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2,
.old_peci_mask = 0x4, .old_peci_mask = 0x4,
}, },
[it8721] = { [it8721] = {
@ -312,7 +315,8 @@ static const struct it87_devices it87_devices[] = {
.suffix = "F", .suffix = "F",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL, | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2,
.peci_mask = 0x05, .peci_mask = 0x05,
.old_peci_mask = 0x02, /* Actually reports PCH */ .old_peci_mask = 0x02, /* Actually reports PCH */
}, },
@ -321,7 +325,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "F", .suffix = "F",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_IN7_INTERNAL, | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2,
.peci_mask = 0x07, .peci_mask = 0x07,
}, },
[it8732] = { [it8732] = {
@ -337,7 +341,8 @@ static const struct it87_devices it87_devices[] = {
.name = "it8771", .name = "it8771",
.suffix = "E", .suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL, | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2,
/* PECI: guesswork */ /* PECI: guesswork */
/* 12mV ADC (OHM) */ /* 12mV ADC (OHM) */
/* 16 bit fans (OHM) */ /* 16 bit fans (OHM) */
@ -348,7 +353,8 @@ static const struct it87_devices it87_devices[] = {
.name = "it8772", .name = "it8772",
.suffix = "E", .suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL, | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2,
/* PECI (coreboot) */ /* PECI (coreboot) */
/* 12mV ADC (HWSensors4, OHM) */ /* 12mV ADC (HWSensors4, OHM) */
/* 16 bit fans (HWSensors4, OHM) */ /* 16 bit fans (HWSensors4, OHM) */
@ -359,35 +365,37 @@ static const struct it87_devices it87_devices[] = {
.name = "it8781", .name = "it8781",
.suffix = "F", .suffix = "F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG, | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2,
.old_peci_mask = 0x4, .old_peci_mask = 0x4,
}, },
[it8782] = { [it8782] = {
.name = "it8782", .name = "it8782",
.suffix = "F", .suffix = "F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG, | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2,
.old_peci_mask = 0x4, .old_peci_mask = 0x4,
}, },
[it8783] = { [it8783] = {
.name = "it8783", .name = "it8783",
.suffix = "E/F", .suffix = "E/F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG, | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2,
.old_peci_mask = 0x4, .old_peci_mask = 0x4,
}, },
[it8786] = { [it8786] = {
.name = "it8786", .name = "it8786",
.suffix = "E", .suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL, | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2,
.peci_mask = 0x07, .peci_mask = 0x07,
}, },
[it8790] = { [it8790] = {
.name = "it8790", .name = "it8790",
.suffix = "E", .suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL, | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2,
.peci_mask = 0x07, .peci_mask = 0x07,
}, },
[it8603] = { [it8603] = {
@ -395,7 +403,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E", .suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_AVCC3, | FEAT_AVCC3 | FEAT_PWM_FREQ2,
.peci_mask = 0x07, .peci_mask = 0x07,
}, },
[it8620] = { [it8620] = {
@ -403,7 +411,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E", .suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM, | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2,
.peci_mask = 0x07, .peci_mask = 0x07,
}, },
}; };
@ -427,6 +435,7 @@ static const struct it87_devices it87_devices[] = {
#define has_six_fans(data) ((data)->features & FEAT_SIX_FANS) #define has_six_fans(data) ((data)->features & FEAT_SIX_FANS)
#define has_avcc3(data) ((data)->features & FEAT_AVCC3) #define has_avcc3(data) ((data)->features & FEAT_AVCC3)
#define has_six_pwm(data) ((data)->features & FEAT_SIX_PWM) #define has_six_pwm(data) ((data)->features & FEAT_SIX_PWM)
#define has_pwm_freq2(data) ((data)->features & FEAT_PWM_FREQ2)
struct it87_sio_data { struct it87_sio_data {
enum chips type; enum chips type;
@ -906,9 +915,16 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
struct it87_data *data = it87_update_device(dev); struct it87_data *data = it87_update_device(dev);
int index = (data->fan_ctl >> 4) & 0x07; int nr = sensor_attr->index;
unsigned int freq; unsigned int freq;
int index;
if (has_pwm_freq2(data) && nr == 1)
index = (data->extra >> 4) & 0x07;
else
index = (data->fan_ctl >> 4) & 0x07;
freq = pwm_freq[index] / (has_newer_autopwm(data) ? 256 : 128); freq = pwm_freq[index] / (has_newer_autopwm(data) ? 256 : 128);
@ -1127,7 +1143,9 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
static ssize_t set_pwm_freq(struct device *dev, static ssize_t set_pwm_freq(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count) struct device_attribute *attr, const char *buf, size_t count)
{ {
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
struct it87_data *data = dev_get_drvdata(dev); struct it87_data *data = dev_get_drvdata(dev);
int nr = sensor_attr->index;
unsigned long val; unsigned long val;
int i; int i;
@ -1144,9 +1162,15 @@ static ssize_t set_pwm_freq(struct device *dev,
} }
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL) & 0x8f; if (nr == 0) {
data->fan_ctl |= i << 4; data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL) & 0x8f;
it87_write_value(data, IT87_REG_FAN_CTL, data->fan_ctl); data->fan_ctl |= i << 4;
it87_write_value(data, IT87_REG_FAN_CTL, data->fan_ctl);
} else {
data->extra = it87_read_value(data, IT87_REG_TEMP_EXTRA) & 0x8f;
data->extra |= i << 4;
it87_write_value(data, IT87_REG_TEMP_EXTRA, data->extra);
}
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return count; return count;
@ -1316,7 +1340,8 @@ static SENSOR_DEVICE_ATTR_2(fan6_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
show_pwm_enable, set_pwm_enable, 0); show_pwm_enable, set_pwm_enable, 0);
static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0); static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0);
static DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, show_pwm_freq, set_pwm_freq); static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, show_pwm_freq,
set_pwm_freq, 0);
static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO | S_IWUSR,
show_pwm_temp_map, set_pwm_temp_map, 0); show_pwm_temp_map, set_pwm_temp_map, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR,
@ -1341,7 +1366,7 @@ static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR,
static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
show_pwm_enable, set_pwm_enable, 1); show_pwm_enable, set_pwm_enable, 1);
static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1); static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1);
static DEVICE_ATTR(pwm2_freq, S_IRUGO, show_pwm_freq, NULL); static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO, show_pwm_freq, set_pwm_freq, 1);
static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO | S_IWUSR,
show_pwm_temp_map, set_pwm_temp_map, 1); show_pwm_temp_map, set_pwm_temp_map, 1);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR,
@ -1366,7 +1391,7 @@ static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, S_IRUGO | S_IWUSR,
static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR,
show_pwm_enable, set_pwm_enable, 2); show_pwm_enable, set_pwm_enable, 2);
static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 2); static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 2);
static DEVICE_ATTR(pwm3_freq, S_IRUGO, show_pwm_freq, NULL); static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO, show_pwm_freq, NULL, 2);
static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO | S_IWUSR,
show_pwm_temp_map, set_pwm_temp_map, 2); show_pwm_temp_map, set_pwm_temp_map, 2);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR,
@ -1391,21 +1416,21 @@ static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR,
static SENSOR_DEVICE_ATTR(pwm4_enable, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm4_enable, S_IRUGO | S_IWUSR,
show_pwm_enable, set_pwm_enable, 3); show_pwm_enable, set_pwm_enable, 3);
static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 3); static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 3);
static DEVICE_ATTR(pwm4_freq, S_IRUGO | S_IWUSR, show_pwm_freq, set_pwm_freq); static SENSOR_DEVICE_ATTR(pwm4_freq, S_IRUGO, show_pwm_freq, NULL, 3);
static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IRUGO | S_IWUSR,
show_pwm_temp_map, set_pwm_temp_map, 3); show_pwm_temp_map, set_pwm_temp_map, 3);
static SENSOR_DEVICE_ATTR(pwm5_enable, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm5_enable, S_IRUGO | S_IWUSR,
show_pwm_enable, set_pwm_enable, 4); show_pwm_enable, set_pwm_enable, 4);
static SENSOR_DEVICE_ATTR(pwm5, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 4); static SENSOR_DEVICE_ATTR(pwm5, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 4);
static DEVICE_ATTR(pwm5_freq, S_IRUGO | S_IWUSR, show_pwm_freq, set_pwm_freq); static SENSOR_DEVICE_ATTR(pwm5_freq, S_IRUGO, show_pwm_freq, NULL, 4);
static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, S_IRUGO | S_IWUSR,
show_pwm_temp_map, set_pwm_temp_map, 4); show_pwm_temp_map, set_pwm_temp_map, 4);
static SENSOR_DEVICE_ATTR(pwm6_enable, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm6_enable, S_IRUGO | S_IWUSR,
show_pwm_enable, set_pwm_enable, 5); show_pwm_enable, set_pwm_enable, 5);
static SENSOR_DEVICE_ATTR(pwm6, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 5); static SENSOR_DEVICE_ATTR(pwm6, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 5);
static DEVICE_ATTR(pwm6_freq, S_IRUGO | S_IWUSR, show_pwm_freq, set_pwm_freq); static SENSOR_DEVICE_ATTR(pwm6_freq, S_IRUGO, show_pwm_freq, NULL, 5);
static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, S_IRUGO | S_IWUSR,
show_pwm_temp_map, set_pwm_temp_map, 5); show_pwm_temp_map, set_pwm_temp_map, 5);
@ -1774,44 +1799,57 @@ static const struct attribute *it87_attributes_fan_div[] = {
static struct attribute *it87_attributes_pwm[6][4+1] = { { static struct attribute *it87_attributes_pwm[6][4+1] = { {
&sensor_dev_attr_pwm1_enable.dev_attr.attr, &sensor_dev_attr_pwm1_enable.dev_attr.attr,
&sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm1.dev_attr.attr,
&dev_attr_pwm1_freq.attr, &sensor_dev_attr_pwm1_freq.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
NULL NULL
}, { }, {
&sensor_dev_attr_pwm2_enable.dev_attr.attr, &sensor_dev_attr_pwm2_enable.dev_attr.attr,
&sensor_dev_attr_pwm2.dev_attr.attr, &sensor_dev_attr_pwm2.dev_attr.attr,
&dev_attr_pwm2_freq.attr, &sensor_dev_attr_pwm2_freq.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
NULL NULL
}, { }, {
&sensor_dev_attr_pwm3_enable.dev_attr.attr, &sensor_dev_attr_pwm3_enable.dev_attr.attr,
&sensor_dev_attr_pwm3.dev_attr.attr, &sensor_dev_attr_pwm3.dev_attr.attr,
&dev_attr_pwm3_freq.attr, &sensor_dev_attr_pwm3_freq.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
NULL NULL
}, { }, {
&sensor_dev_attr_pwm4_enable.dev_attr.attr, &sensor_dev_attr_pwm4_enable.dev_attr.attr,
&sensor_dev_attr_pwm4.dev_attr.attr, &sensor_dev_attr_pwm4.dev_attr.attr,
&dev_attr_pwm4_freq.attr, &sensor_dev_attr_pwm4_freq.dev_attr.attr,
&sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr, &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr,
NULL NULL
}, { }, {
&sensor_dev_attr_pwm5_enable.dev_attr.attr, &sensor_dev_attr_pwm5_enable.dev_attr.attr,
&sensor_dev_attr_pwm5.dev_attr.attr, &sensor_dev_attr_pwm5.dev_attr.attr,
&dev_attr_pwm5_freq.attr, &sensor_dev_attr_pwm5_freq.dev_attr.attr,
&sensor_dev_attr_pwm5_auto_channels_temp.dev_attr.attr, &sensor_dev_attr_pwm5_auto_channels_temp.dev_attr.attr,
NULL NULL
}, { }, {
&sensor_dev_attr_pwm6_enable.dev_attr.attr, &sensor_dev_attr_pwm6_enable.dev_attr.attr,
&sensor_dev_attr_pwm6.dev_attr.attr, &sensor_dev_attr_pwm6.dev_attr.attr,
&dev_attr_pwm6_freq.attr, &sensor_dev_attr_pwm6_freq.dev_attr.attr,
&sensor_dev_attr_pwm6_auto_channels_temp.dev_attr.attr, &sensor_dev_attr_pwm6_auto_channels_temp.dev_attr.attr,
NULL NULL
} }; } };
static umode_t pwm_attribute_mode(struct kobject *kobj, struct attribute *attr,
int index)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct it87_data *data = dev_get_drvdata(dev);
if (has_pwm_freq2(data) && index == 2)
return attr->mode | S_IWUSR;
return attr->mode;
}
static const struct attribute_group it87_group_pwm[6] = { static const struct attribute_group it87_group_pwm[6] = {
{ .attrs = it87_attributes_pwm[0] }, { .attrs = it87_attributes_pwm[0] },
{ .attrs = it87_attributes_pwm[1] }, { .attrs = it87_attributes_pwm[1],
.is_visible = pwm_attribute_mode, },
{ .attrs = it87_attributes_pwm[2] }, { .attrs = it87_attributes_pwm[2] },
{ .attrs = it87_attributes_pwm[3] }, { .attrs = it87_attributes_pwm[3] },
{ .attrs = it87_attributes_pwm[4] }, { .attrs = it87_attributes_pwm[4] },