aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2015-03-26 02:15:32 -0400
committerGuenter Roeck <linux@roeck-us.net>2015-04-05 09:01:00 -0400
commitfa3f70d62844bd91880ea634c06b46585fefd74b (patch)
tree0067547cd62a0b34739eb2189d47e449e4d0b4e2
parent3ba9d977a9b8a90c586f46444448d977bdbdcc3b (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.c48
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
219static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82 }; 219static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x4c };
220static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86 }; 220static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86, 0x4e };
221static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83 }; 221static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x4d };
222static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; 222static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0x4f };
223static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 }; 223static 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
268static const struct it87_devices it87_devices[] = { 269static 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
406struct it87_sio_data { 409struct 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);
1277static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan, 1280static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
1278 4, 1); 1281 4, 1);
1279 1282
1283static SENSOR_DEVICE_ATTR_2(fan6_input, S_IRUGO, show_fan, NULL, 5, 0);
1284static SENSOR_DEVICE_ATTR_2(fan6_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
1285 5, 1);
1286
1280static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, 1287static 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);
1282static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0); 1289static 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);
1407static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 2); 1414static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 2);
1408static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 3); 1415static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 3);
1409static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 6); 1416static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 6);
1417static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 7);
1410static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16); 1418static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16);
1411static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17); 1419static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17);
1412static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18); 1420static 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);
1457static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0); 1465static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0);
1458static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0); 1466static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0);
1459static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0); 1467static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0);
1468static SENSOR_DEVICE_ATTR(fan6_beep, S_IRUGO, show_beep, set_beep, 0);
1460static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR, 1469static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR,
1461 show_beep, set_beep, 2); 1470 show_beep, set_beep, 2);
1462static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2); 1471static 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
1663static struct attribute *it87_attributes_fan[5][3+1] = { { 1672static 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
1690static const struct attribute_group it87_group_fan[5] = { 1704static 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
1698static const struct attribute *it87_attributes_fan_div[] = { 1713static 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
1779static struct attribute *it87_attributes_vid[] = { 1795static 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;