diff options
author | Guenter Roeck <linux@roeck-us.net> | 2015-03-26 02:15:32 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2015-04-05 09:01:00 -0400 |
commit | fa3f70d62844bd91880ea634c06b46585fefd74b (patch) | |
tree | 0067547cd62a0b34739eb2189d47e449e4d0b4e2 | |
parent | 3ba9d977a9b8a90c586f46444448d977bdbdcc3b (diff) |
hwmon: (it87) Add support for 6th fan of IT8620E
IT8620E supports up to 6 fan tachometers.
Reviewed-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | drivers/hwmon/it87.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 4e4db72d38e8..8acbe8f852d1 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -216,11 +216,11 @@ static bool fix_pwm_polarity; | |||
216 | 216 | ||
217 | /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ | 217 | /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ |
218 | 218 | ||
219 | static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82 }; | 219 | static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x4c }; |
220 | static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86 }; | 220 | static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86, 0x4e }; |
221 | static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83 }; | 221 | static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x4d }; |
222 | static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; | 222 | static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0x4f }; |
223 | static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 }; | 223 | static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 }; |
224 | 224 | ||
225 | #define IT87_REG_FAN_MAIN_CTRL 0x13 | 225 | #define IT87_REG_FAN_MAIN_CTRL 0x13 |
226 | #define IT87_REG_FAN_CTL 0x14 | 226 | #define IT87_REG_FAN_CTL 0x14 |
@@ -264,6 +264,7 @@ struct it87_devices { | |||
264 | #define FEAT_FIVE_FANS (1 << 8) /* Supports five fans */ | 264 | #define FEAT_FIVE_FANS (1 << 8) /* Supports five fans */ |
265 | #define FEAT_VID (1 << 9) /* Set if chip supports VID */ | 265 | #define FEAT_VID (1 << 9) /* Set if chip supports VID */ |
266 | #define FEAT_IN7_INTERNAL (1 << 10) /* Set if in7 is internal */ | 266 | #define FEAT_IN7_INTERNAL (1 << 10) /* Set if in7 is internal */ |
267 | #define FEAT_SIX_FANS (1 << 11) /* Supports six fans */ | ||
267 | 268 | ||
268 | static const struct it87_devices it87_devices[] = { | 269 | static const struct it87_devices it87_devices[] = { |
269 | [it87] = { | 270 | [it87] = { |
@@ -382,7 +383,7 @@ static const struct it87_devices it87_devices[] = { | |||
382 | .name = "it8620", | 383 | .name = "it8620", |
383 | .suffix = "E", | 384 | .suffix = "E", |
384 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | 385 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS |
385 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS | 386 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS |
386 | | FEAT_IN7_INTERNAL, | 387 | | FEAT_IN7_INTERNAL, |
387 | .peci_mask = 0x07, | 388 | .peci_mask = 0x07, |
388 | }, | 389 | }, |
@@ -399,9 +400,11 @@ static const struct it87_devices it87_devices[] = { | |||
399 | (((data)->features & FEAT_TEMP_OLD_PECI) && \ | 400 | (((data)->features & FEAT_TEMP_OLD_PECI) && \ |
400 | ((data)->old_peci_mask & (1 << nr))) | 401 | ((data)->old_peci_mask & (1 << nr))) |
401 | #define has_fan16_config(data) ((data)->features & FEAT_FAN16_CONFIG) | 402 | #define has_fan16_config(data) ((data)->features & FEAT_FAN16_CONFIG) |
402 | #define has_five_fans(data) ((data)->features & FEAT_FIVE_FANS) | 403 | #define has_five_fans(data) ((data)->features & (FEAT_FIVE_FANS | \ |
404 | FEAT_SIX_FANS)) | ||
403 | #define has_vid(data) ((data)->features & FEAT_VID) | 405 | #define has_vid(data) ((data)->features & FEAT_VID) |
404 | #define has_in7_internal(data) ((data)->features & FEAT_IN7_INTERNAL) | 406 | #define has_in7_internal(data) ((data)->features & FEAT_IN7_INTERNAL) |
407 | #define has_six_fans(data) ((data)->features & FEAT_SIX_FANS) | ||
405 | 408 | ||
406 | struct it87_sio_data { | 409 | struct it87_sio_data { |
407 | enum chips type; | 410 | enum chips type; |
@@ -438,7 +441,7 @@ struct it87_data { | |||
438 | u16 in_scaled; /* Internal voltage sensors are scaled */ | 441 | u16 in_scaled; /* Internal voltage sensors are scaled */ |
439 | u8 in[10][3]; /* [nr][0]=in, [1]=min, [2]=max */ | 442 | u8 in[10][3]; /* [nr][0]=in, [1]=min, [2]=max */ |
440 | u8 has_fan; /* Bitfield, fans enabled */ | 443 | u8 has_fan; /* Bitfield, fans enabled */ |
441 | u16 fan[5][2]; /* Register values, [nr][0]=fan, [1]=min */ | 444 | u16 fan[6][2]; /* Register values, [nr][0]=fan, [1]=min */ |
442 | u8 has_temp; /* Bitfield, temp sensors enabled */ | 445 | u8 has_temp; /* Bitfield, temp sensors enabled */ |
443 | s8 temp[3][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */ | 446 | s8 temp[3][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */ |
444 | u8 sensor; /* Register value (IT87_REG_TEMP_ENABLE) */ | 447 | u8 sensor; /* Register value (IT87_REG_TEMP_ENABLE) */ |
@@ -1277,6 +1280,10 @@ static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, 0); | |||
1277 | static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan, | 1280 | static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan, |
1278 | 4, 1); | 1281 | 4, 1); |
1279 | 1282 | ||
1283 | static SENSOR_DEVICE_ATTR_2(fan6_input, S_IRUGO, show_fan, NULL, 5, 0); | ||
1284 | static SENSOR_DEVICE_ATTR_2(fan6_min, S_IRUGO | S_IWUSR, show_fan, set_fan, | ||
1285 | 5, 1); | ||
1286 | |||
1280 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, | 1287 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, |
1281 | show_pwm_enable, set_pwm_enable, 0); | 1288 | show_pwm_enable, set_pwm_enable, 0); |
1282 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0); | 1289 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0); |
@@ -1407,6 +1414,7 @@ static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 1); | |||
1407 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 2); | 1414 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 2); |
1408 | static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 3); | 1415 | static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 3); |
1409 | static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 6); | 1416 | static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 6); |
1417 | static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
1410 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16); | 1418 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16); |
1411 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17); | 1419 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17); |
1412 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18); | 1420 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18); |
@@ -1457,6 +1465,7 @@ static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO, show_beep, set_beep, 0); | |||
1457 | static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0); | 1465 | static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0); |
1458 | static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0); | 1466 | static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0); |
1459 | static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0); | 1467 | static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0); |
1468 | static SENSOR_DEVICE_ATTR(fan6_beep, S_IRUGO, show_beep, set_beep, 0); | ||
1460 | static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR, | 1469 | static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR, |
1461 | show_beep, set_beep, 2); | 1470 | show_beep, set_beep, 2); |
1462 | static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2); | 1471 | static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2); |
@@ -1660,7 +1669,7 @@ static struct attribute *it87_attributes_temp_beep[] = { | |||
1660 | &sensor_dev_attr_temp3_beep.dev_attr.attr, | 1669 | &sensor_dev_attr_temp3_beep.dev_attr.attr, |
1661 | }; | 1670 | }; |
1662 | 1671 | ||
1663 | static struct attribute *it87_attributes_fan[5][3+1] = { { | 1672 | static struct attribute *it87_attributes_fan[6][3+1] = { { |
1664 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 1673 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
1665 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 1674 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
1666 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | 1675 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, |
@@ -1685,14 +1694,20 @@ static struct attribute *it87_attributes_fan[5][3+1] = { { | |||
1685 | &sensor_dev_attr_fan5_min.dev_attr.attr, | 1694 | &sensor_dev_attr_fan5_min.dev_attr.attr, |
1686 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, | 1695 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, |
1687 | NULL | 1696 | NULL |
1697 | }, { | ||
1698 | &sensor_dev_attr_fan6_input.dev_attr.attr, | ||
1699 | &sensor_dev_attr_fan6_min.dev_attr.attr, | ||
1700 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, | ||
1701 | NULL | ||
1688 | } }; | 1702 | } }; |
1689 | 1703 | ||
1690 | static const struct attribute_group it87_group_fan[5] = { | 1704 | static const struct attribute_group it87_group_fan[6] = { |
1691 | { .attrs = it87_attributes_fan[0] }, | 1705 | { .attrs = it87_attributes_fan[0] }, |
1692 | { .attrs = it87_attributes_fan[1] }, | 1706 | { .attrs = it87_attributes_fan[1] }, |
1693 | { .attrs = it87_attributes_fan[2] }, | 1707 | { .attrs = it87_attributes_fan[2] }, |
1694 | { .attrs = it87_attributes_fan[3] }, | 1708 | { .attrs = it87_attributes_fan[3] }, |
1695 | { .attrs = it87_attributes_fan[4] }, | 1709 | { .attrs = it87_attributes_fan[4] }, |
1710 | { .attrs = it87_attributes_fan[5] }, | ||
1696 | }; | 1711 | }; |
1697 | 1712 | ||
1698 | static const struct attribute *it87_attributes_fan_div[] = { | 1713 | static const struct attribute *it87_attributes_fan_div[] = { |
@@ -1774,6 +1789,7 @@ static struct attribute *it87_attributes_fan_beep[] = { | |||
1774 | &sensor_dev_attr_fan3_beep.dev_attr.attr, | 1789 | &sensor_dev_attr_fan3_beep.dev_attr.attr, |
1775 | &sensor_dev_attr_fan4_beep.dev_attr.attr, | 1790 | &sensor_dev_attr_fan4_beep.dev_attr.attr, |
1776 | &sensor_dev_attr_fan5_beep.dev_attr.attr, | 1791 | &sensor_dev_attr_fan5_beep.dev_attr.attr, |
1792 | &sensor_dev_attr_fan6_beep.dev_attr.attr, | ||
1777 | }; | 1793 | }; |
1778 | 1794 | ||
1779 | static struct attribute *it87_attributes_vid[] = { | 1795 | static struct attribute *it87_attributes_vid[] = { |
@@ -2155,7 +2171,7 @@ static void it87_remove_files(struct device *dev) | |||
2155 | sysfs_remove_file(&dev->kobj, | 2171 | sysfs_remove_file(&dev->kobj, |
2156 | it87_attributes_temp_beep[i]); | 2172 | it87_attributes_temp_beep[i]); |
2157 | } | 2173 | } |
2158 | for (i = 0; i < 5; i++) { | 2174 | for (i = 0; i < 6; i++) { |
2159 | if (!(data->has_fan & (1 << i))) | 2175 | if (!(data->has_fan & (1 << i))) |
2160 | continue; | 2176 | continue; |
2161 | sysfs_remove_group(&dev->kobj, &it87_group_fan[i]); | 2177 | sysfs_remove_group(&dev->kobj, &it87_group_fan[i]); |
@@ -2312,7 +2328,7 @@ static int it87_probe(struct platform_device *pdev) | |||
2312 | 2328 | ||
2313 | /* Do not create fan files for disabled fans */ | 2329 | /* Do not create fan files for disabled fans */ |
2314 | fan_beep_need_rw = 1; | 2330 | fan_beep_need_rw = 1; |
2315 | for (i = 0; i < 5; i++) { | 2331 | for (i = 0; i < 6; i++) { |
2316 | if (!(data->has_fan & (1 << i))) | 2332 | if (!(data->has_fan & (1 << i))) |
2317 | continue; | 2333 | continue; |
2318 | err = sysfs_create_group(&dev->kobj, &it87_group_fan[i]); | 2334 | err = sysfs_create_group(&dev->kobj, &it87_group_fan[i]); |
@@ -2557,9 +2573,10 @@ static void it87_init_device(struct platform_device *pdev) | |||
2557 | } | 2573 | } |
2558 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; | 2574 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; |
2559 | 2575 | ||
2576 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); | ||
2577 | |||
2560 | /* Set tachometers to 16-bit mode if needed */ | 2578 | /* Set tachometers to 16-bit mode if needed */ |
2561 | if (has_fan16_config(data)) { | 2579 | if (has_fan16_config(data)) { |
2562 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); | ||
2563 | if (~tmp & 0x07 & data->has_fan) { | 2580 | if (~tmp & 0x07 & data->has_fan) { |
2564 | dev_dbg(&pdev->dev, | 2581 | dev_dbg(&pdev->dev, |
2565 | "Setting fan1-3 to 16-bit mode\n"); | 2582 | "Setting fan1-3 to 16-bit mode\n"); |
@@ -2570,11 +2587,12 @@ static void it87_init_device(struct platform_device *pdev) | |||
2570 | 2587 | ||
2571 | /* Check for additional fans */ | 2588 | /* Check for additional fans */ |
2572 | if (has_five_fans(data)) { | 2589 | if (has_five_fans(data)) { |
2573 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); | ||
2574 | if (tmp & (1 << 4)) | 2590 | if (tmp & (1 << 4)) |
2575 | data->has_fan |= (1 << 3); /* fan4 enabled */ | 2591 | data->has_fan |= (1 << 3); /* fan4 enabled */ |
2576 | if (tmp & (1 << 5)) | 2592 | if (tmp & (1 << 5)) |
2577 | data->has_fan |= (1 << 4); /* fan5 enabled */ | 2593 | data->has_fan |= (1 << 4); /* fan5 enabled */ |
2594 | if (has_six_fans(data) && (tmp & (1 << 2))) | ||
2595 | data->has_fan |= (1 << 5); /* fan6 enabled */ | ||
2578 | } | 2596 | } |
2579 | 2597 | ||
2580 | /* Fan input pins may be used for alternative functions */ | 2598 | /* Fan input pins may be used for alternative functions */ |
@@ -2642,7 +2660,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
2642 | if (data->type == it8603) | 2660 | if (data->type == it8603) |
2643 | data->in[9][0] = it87_read_value(data, 0x2f); | 2661 | data->in[9][0] = it87_read_value(data, 0x2f); |
2644 | 2662 | ||
2645 | for (i = 0; i < 5; i++) { | 2663 | for (i = 0; i < 6; i++) { |
2646 | /* Skip disabled fans */ | 2664 | /* Skip disabled fans */ |
2647 | if (!(data->has_fan & (1 << i))) | 2665 | if (!(data->has_fan & (1 << i))) |
2648 | continue; | 2666 | continue; |