diff options
-rw-r--r-- | drivers/hwmon/it87.c | 81 |
1 files changed, 61 insertions, 20 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 071dd60f1c82..e7701d99f8e8 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -218,6 +218,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; #define IT87_REG_VIN_ENABLE 0x50 #define IT87_REG_TEMP_ENABLE 0x51 +#define IT87_REG_TEMP_EXTRA 0x55 #define IT87_REG_BEEP_ENABLE 0x5c #define IT87_REG_CHIPID 0x58 @@ -238,6 +239,7 @@ struct it87_sio_data { u8 skip_vid; u8 skip_fan; u8 skip_pwm; + u8 skip_temp; }; /* @@ -262,6 +264,7 @@ struct it87_data { u8 has_fan; /* Bitfield, fans enabled */ u16 fan[5]; /* Register values, possibly combined */ u16 fan_min[5]; /* Register values, possibly combined */ + u8 has_temp; /* Bitfield, temp sensors enabled */ s8 temp[3]; /* Register value */ s8 temp_high[3]; /* Register value */ s8 temp_low[3]; /* Register value */ @@ -1438,23 +1441,37 @@ static const struct attribute_group it87_group_in[9] = { { .attrs = it87_attributes_in[8] }, }; -static struct attribute *it87_attributes[] = { +static struct attribute *it87_attributes_temp[3][6] = { +{ &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp3_input.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp2_max.dev_attr.attr, - &sensor_dev_attr_temp3_max.dev_attr.attr, &sensor_dev_attr_temp1_min.dev_attr.attr, - &sensor_dev_attr_temp2_min.dev_attr.attr, - &sensor_dev_attr_temp3_min.dev_attr.attr, &sensor_dev_attr_temp1_type.dev_attr.attr, - &sensor_dev_attr_temp2_type.dev_attr.attr, - &sensor_dev_attr_temp3_type.dev_attr.attr, &sensor_dev_attr_temp1_alarm.dev_attr.attr, + NULL +} , { + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_type.dev_attr.attr, &sensor_dev_attr_temp2_alarm.dev_attr.attr, + NULL +} , { + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_type.dev_attr.attr, &sensor_dev_attr_temp3_alarm.dev_attr.attr, + NULL +} }; + +static const struct attribute_group it87_group_temp[3] = { + { .attrs = it87_attributes_temp[0] }, + { .attrs = it87_attributes_temp[1] }, + { .attrs = it87_attributes_temp[2] }, +}; +static struct attribute *it87_attributes[] = { &dev_attr_alarms.attr, &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, &dev_attr_name.attr, @@ -1477,15 +1494,10 @@ static struct attribute *it87_attributes_in_beep[] = { NULL }; -static struct attribute *it87_attributes_beep[] = { +static struct attribute *it87_attributes_temp_beep[] = { &sensor_dev_attr_temp1_beep.dev_attr.attr, &sensor_dev_attr_temp2_beep.dev_attr.attr, &sensor_dev_attr_temp3_beep.dev_attr.attr, - NULL -}; - -static const struct attribute_group it87_group_beep = { - .attrs = it87_attributes_beep, }; static struct attribute *it87_attributes_fan16[5][3+1] = { { @@ -1870,9 +1882,15 @@ static int __init it87_find(unsigned short *address, * On IT8782F, UART6 pins overlap with VIN5, VIN6, and VIN7. * While VIN7 can be routed to the internal voltage divider, * VIN5 and VIN6 are not available if UART6 is enabled. + * + * Also, temp3 is not available if UART6 is enabled and TEMPIN3 + * is the temperature source. Since we can not read the + * temperature source here, skip_temp is preliminary. */ - if (uart6) + if (uart6) { sio_data->skip_in |= (1 << 5) | (1 << 6); + sio_data->skip_temp |= (1 << 2); + } sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; } @@ -1919,8 +1937,14 @@ static void it87_remove_files(struct device *dev) sysfs_remove_file(&dev->kobj, it87_attributes_in_beep[i]); } - if (sio_data->beep_pin) - sysfs_remove_group(&dev->kobj, &it87_group_beep); + for (i = 0; i < 3; i++) { + if (!(data->has_temp & (1 << i))) + continue; + sysfs_remove_group(&dev->kobj, &it87_group_temp[i]); + if (sio_data->beep_pin) + sysfs_remove_file(&dev->kobj, + it87_attributes_temp_beep[i]); + } for (i = 0; i < 5; i++) { if (!(data->has_fan & (1 << i))) continue; @@ -2009,6 +2033,13 @@ static int __devinit it87_probe(struct platform_device *pdev) data->in_scaled |= (1 << 7); /* in7 is VCCH5V */ } + data->has_temp = 0x07; + if (sio_data->skip_temp & (1 << 2)) { + if (sio_data->type == it8782 + && !(it87_read_value(data, IT87_REG_TEMP_EXTRA) & 0x80)) + data->has_temp &= ~(1 << 2); + } + /* Initialize the IT87 chip */ it87_init_device(pdev); @@ -2031,10 +2062,18 @@ static int __devinit it87_probe(struct platform_device *pdev) } } - if (sio_data->beep_pin) { - err = sysfs_create_group(&dev->kobj, &it87_group_beep); + for (i = 0; i < 3; i++) { + if (!(data->has_temp & (1 << i))) + continue; + err = sysfs_create_group(&dev->kobj, &it87_group_temp[i]); if (err) goto error; + if (sio_data->beep_pin) { + err = sysfs_create_file(&dev->kobj, + it87_attributes_temp_beep[i]); + if (err) + goto error; + } } /* Do not create fan files for disabled fans */ @@ -2378,6 +2417,8 @@ static struct it87_data *it87_update_device(struct device *dev) } } for (i = 0; i < 3; i++) { + if (!(data->has_temp & (1 << i))) + continue; data->temp[i] = it87_read_value(data, IT87_REG_TEMP(i)); data->temp_high[i] = |