aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2015-03-26 21:18:19 -0400
committerGuenter Roeck <linux@roeck-us.net>2016-04-19 09:32:35 -0400
commit36c4d98a7883d4c51252d0f4ebf2c667fa7f879f (patch)
treed2e1421db3d9c2cbf4b219140189be1cf09c2f2e /drivers/hwmon
parent730554059bf26ab7a4f2cab8ed96e840a03d9b40 (diff)
hwmon: (it87) Add support for all pwm channels on IT8620E
IT8620E supports up to 6 pwm channels. Add support for it. Also check if fan tachometers 4..6 are enabled before instantiating the respective sysfs attributes. Tested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/it87.c114
1 files changed, 94 insertions, 20 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 146f93584cde..916d73630224 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -168,6 +168,7 @@ static inline void superio_exit(void)
168#define IT87_SIO_GPIO1_REG 0x25 168#define IT87_SIO_GPIO1_REG 0x25
169#define IT87_SIO_GPIO2_REG 0x26 169#define IT87_SIO_GPIO2_REG 0x26
170#define IT87_SIO_GPIO3_REG 0x27 170#define IT87_SIO_GPIO3_REG 0x27
171#define IT87_SIO_GPIO4_REG 0x28
171#define IT87_SIO_GPIO5_REG 0x29 172#define IT87_SIO_GPIO5_REG 0x29
172#define IT87_SIO_PINX1_REG 0x2a /* Pin selection */ 173#define IT87_SIO_PINX1_REG 0x2a /* Pin selection */
173#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */ 174#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */
@@ -227,8 +228,8 @@ static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 };
227 228
228#define IT87_REG_FAN_MAIN_CTRL 0x13 229#define IT87_REG_FAN_MAIN_CTRL 0x13
229#define IT87_REG_FAN_CTL 0x14 230#define IT87_REG_FAN_CTL 0x14
230#define IT87_REG_PWM(nr) (0x15 + (nr)) 231static const u8 IT87_REG_PWM[] = { 0x15, 0x16, 0x17, 0x7f, 0xa7, 0xaf };
231#define IT87_REG_PWM_DUTY(nr) (0x63 + (nr) * 8) 232static const u8 IT87_REG_PWM_DUTY[] = { 0x63, 0x6b, 0x73, 0x7b, 0xa3, 0xab };
232 233
233#define IT87_REG_VIN(nr) (0x20 + (nr)) 234#define IT87_REG_VIN(nr) (0x20 + (nr))
234#define IT87_REG_TEMP(nr) (0x29 + (nr)) 235#define IT87_REG_TEMP(nr) (0x29 + (nr))
@@ -272,6 +273,7 @@ struct it87_devices {
272#define FEAT_SIX_FANS (1 << 11) /* Supports six fans */ 273#define FEAT_SIX_FANS (1 << 11) /* Supports six fans */
273#define FEAT_10_9MV_ADC (1 << 12) 274#define FEAT_10_9MV_ADC (1 << 12)
274#define FEAT_AVCC3 (1 << 13) /* Chip supports in9/AVCC3 */ 275#define FEAT_AVCC3 (1 << 13) /* Chip supports in9/AVCC3 */
276#define FEAT_SIX_PWM (1 << 14) /* Chip supports 6 pwm chn */
275 277
276static const struct it87_devices it87_devices[] = { 278static const struct it87_devices it87_devices[] = {
277 [it87] = { 279 [it87] = {
@@ -401,7 +403,7 @@ static const struct it87_devices it87_devices[] = {
401 .suffix = "E", 403 .suffix = "E",
402 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 404 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
403 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS 405 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
404 | FEAT_IN7_INTERNAL, 406 | FEAT_IN7_INTERNAL | FEAT_SIX_PWM,
405 .peci_mask = 0x07, 407 .peci_mask = 0x07,
406 }, 408 },
407}; 409};
@@ -424,6 +426,7 @@ static const struct it87_devices it87_devices[] = {
424#define has_in7_internal(data) ((data)->features & FEAT_IN7_INTERNAL) 426#define has_in7_internal(data) ((data)->features & FEAT_IN7_INTERNAL)
425#define has_six_fans(data) ((data)->features & FEAT_SIX_FANS) 427#define has_six_fans(data) ((data)->features & FEAT_SIX_FANS)
426#define has_avcc3(data) ((data)->features & FEAT_AVCC3) 428#define has_avcc3(data) ((data)->features & FEAT_AVCC3)
429#define has_six_pwm(data) ((data)->features & FEAT_SIX_PWM)
427 430
428struct it87_sio_data { 431struct it87_sio_data {
429 enum chips type; 432 enum chips type;
@@ -483,9 +486,9 @@ struct it87_data {
483 * is no longer needed, but it is still done to keep the driver 486 * is no longer needed, but it is still done to keep the driver
484 * simple. 487 * simple.
485 */ 488 */
486 u8 pwm_ctrl[3]; /* Register value */ 489 u8 pwm_ctrl[6]; /* Register value */
487 u8 pwm_duty[3]; /* Manual PWM value set by user */ 490 u8 pwm_duty[6]; /* Manual PWM value set by user */
488 u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ 491 u8 pwm_temp_map[6]; /* PWM to temp. chan. mapping (bits 1-0) */
489 492
490 /* Automatic fan speed control registers */ 493 /* Automatic fan speed control registers */
491 u8 auto_pwm[3][4]; /* [nr][3] is hard-coded */ 494 u8 auto_pwm[3][4]; /* [nr][3] is hard-coded */
@@ -1068,7 +1071,7 @@ static ssize_t set_pwm_enable(struct device *dev,
1068 data->pwm_duty[nr]; 1071 data->pwm_duty[nr];
1069 else /* Automatic mode */ 1072 else /* Automatic mode */
1070 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; 1073 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
1071 it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); 1074 it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]);
1072 1075
1073 if (data->type != it8603) { 1076 if (data->type != it8603) {
1074 /* set SmartGuardian mode */ 1077 /* set SmartGuardian mode */
@@ -1104,7 +1107,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
1104 return -EBUSY; 1107 return -EBUSY;
1105 } 1108 }
1106 data->pwm_duty[nr] = pwm_to_reg(data, val); 1109 data->pwm_duty[nr] = pwm_to_reg(data, val);
1107 it87_write_value(data, IT87_REG_PWM_DUTY(nr), 1110 it87_write_value(data, IT87_REG_PWM_DUTY[nr],
1108 data->pwm_duty[nr]); 1111 data->pwm_duty[nr]);
1109 } else { 1112 } else {
1110 data->pwm_duty[nr] = pwm_to_reg(data, val); 1113 data->pwm_duty[nr] = pwm_to_reg(data, val);
@@ -1114,7 +1117,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
1114 */ 1117 */
1115 if (!(data->pwm_ctrl[nr] & 0x80)) { 1118 if (!(data->pwm_ctrl[nr] & 0x80)) {
1116 data->pwm_ctrl[nr] = data->pwm_duty[nr]; 1119 data->pwm_ctrl[nr] = data->pwm_duty[nr];
1117 it87_write_value(data, IT87_REG_PWM(nr), 1120 it87_write_value(data, IT87_REG_PWM[nr],
1118 data->pwm_ctrl[nr]); 1121 data->pwm_ctrl[nr]);
1119 } 1122 }
1120 } 1123 }
@@ -1207,7 +1210,7 @@ static ssize_t set_pwm_temp_map(struct device *dev,
1207 */ 1210 */
1208 if (data->pwm_ctrl[nr] & 0x80) { 1211 if (data->pwm_ctrl[nr] & 0x80) {
1209 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; 1212 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
1210 it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); 1213 it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]);
1211 } 1214 }
1212 mutex_unlock(&data->update_lock); 1215 mutex_unlock(&data->update_lock);
1213 return count; 1216 return count;
@@ -1385,6 +1388,27 @@ static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR,
1385static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR, 1388static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR,
1386 show_auto_temp, set_auto_temp, 2, 4); 1389 show_auto_temp, set_auto_temp, 2, 4);
1387 1390
1391static SENSOR_DEVICE_ATTR(pwm4_enable, S_IRUGO | S_IWUSR,
1392 show_pwm_enable, set_pwm_enable, 3);
1393static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 3);
1394static DEVICE_ATTR(pwm4_freq, S_IRUGO | S_IWUSR, show_pwm_freq, set_pwm_freq);
1395static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IRUGO | S_IWUSR,
1396 show_pwm_temp_map, set_pwm_temp_map, 3);
1397
1398static SENSOR_DEVICE_ATTR(pwm5_enable, S_IRUGO | S_IWUSR,
1399 show_pwm_enable, set_pwm_enable, 4);
1400static SENSOR_DEVICE_ATTR(pwm5, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 4);
1401static DEVICE_ATTR(pwm5_freq, S_IRUGO | S_IWUSR, show_pwm_freq, set_pwm_freq);
1402static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, S_IRUGO | S_IWUSR,
1403 show_pwm_temp_map, set_pwm_temp_map, 4);
1404
1405static SENSOR_DEVICE_ATTR(pwm6_enable, S_IRUGO | S_IWUSR,
1406 show_pwm_enable, set_pwm_enable, 5);
1407static SENSOR_DEVICE_ATTR(pwm6, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 5);
1408static DEVICE_ATTR(pwm6_freq, S_IRUGO | S_IWUSR, show_pwm_freq, set_pwm_freq);
1409static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, S_IRUGO | S_IWUSR,
1410 show_pwm_temp_map, set_pwm_temp_map, 5);
1411
1388/* Alarms */ 1412/* Alarms */
1389static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, 1413static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
1390 char *buf) 1414 char *buf)
@@ -1747,7 +1771,7 @@ static const struct attribute *it87_attributes_fan_div[] = {
1747 &sensor_dev_attr_fan3_div.dev_attr.attr, 1771 &sensor_dev_attr_fan3_div.dev_attr.attr,
1748}; 1772};
1749 1773
1750static struct attribute *it87_attributes_pwm[3][4+1] = { { 1774static struct attribute *it87_attributes_pwm[6][4+1] = { {
1751 &sensor_dev_attr_pwm1_enable.dev_attr.attr, 1775 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1752 &sensor_dev_attr_pwm1.dev_attr.attr, 1776 &sensor_dev_attr_pwm1.dev_attr.attr,
1753 &dev_attr_pwm1_freq.attr, 1777 &dev_attr_pwm1_freq.attr,
@@ -1765,12 +1789,33 @@ static struct attribute *it87_attributes_pwm[3][4+1] = { {
1765 &dev_attr_pwm3_freq.attr, 1789 &dev_attr_pwm3_freq.attr,
1766 &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, 1790 &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
1767 NULL 1791 NULL
1792}, {
1793 &sensor_dev_attr_pwm4_enable.dev_attr.attr,
1794 &sensor_dev_attr_pwm4.dev_attr.attr,
1795 &dev_attr_pwm4_freq.attr,
1796 &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr,
1797 NULL
1798}, {
1799 &sensor_dev_attr_pwm5_enable.dev_attr.attr,
1800 &sensor_dev_attr_pwm5.dev_attr.attr,
1801 &dev_attr_pwm5_freq.attr,
1802 &sensor_dev_attr_pwm5_auto_channels_temp.dev_attr.attr,
1803 NULL
1804}, {
1805 &sensor_dev_attr_pwm6_enable.dev_attr.attr,
1806 &sensor_dev_attr_pwm6.dev_attr.attr,
1807 &dev_attr_pwm6_freq.attr,
1808 &sensor_dev_attr_pwm6_auto_channels_temp.dev_attr.attr,
1809 NULL
1768} }; 1810} };
1769 1811
1770static const struct attribute_group it87_group_pwm[3] = { 1812static const struct attribute_group it87_group_pwm[6] = {
1771 { .attrs = it87_attributes_pwm[0] }, 1813 { .attrs = it87_attributes_pwm[0] },
1772 { .attrs = it87_attributes_pwm[1] }, 1814 { .attrs = it87_attributes_pwm[1] },
1773 { .attrs = it87_attributes_pwm[2] }, 1815 { .attrs = it87_attributes_pwm[2] },
1816 { .attrs = it87_attributes_pwm[3] },
1817 { .attrs = it87_attributes_pwm[4] },
1818 { .attrs = it87_attributes_pwm[5] },
1774}; 1819};
1775 1820
1776static struct attribute *it87_attributes_autopwm[3][9+1] = { { 1821static struct attribute *it87_attributes_autopwm[3][9+1] = { {
@@ -1955,6 +2000,9 @@ static int __init it87_find(unsigned short *address,
1955 else 2000 else
1956 sio_data->skip_in |= (1 << 9); 2001 sio_data->skip_in |= (1 << 9);
1957 2002
2003 if (!has_six_pwm(config))
2004 sio_data->skip_pwm |= (1 << 3) | (1 << 4) | (1 << 5);
2005
1958 if (!has_vid(config)) 2006 if (!has_vid(config))
1959 sio_data->skip_vid = 1; 2007 sio_data->skip_vid = 1;
1960 2008
@@ -2057,6 +2105,11 @@ static int __init it87_find(unsigned short *address,
2057 2105
2058 superio_select(GPIO); 2106 superio_select(GPIO);
2059 2107
2108 /* Check for pwm5 */
2109 reg = superio_inb(IT87_SIO_GPIO1_REG);
2110 if (reg & (1 << 6))
2111 sio_data->skip_pwm |= (1 << 4);
2112
2060 /* Check for fan4, fan5 */ 2113 /* Check for fan4, fan5 */
2061 reg = superio_inb(IT87_SIO_GPIO2_REG); 2114 reg = superio_inb(IT87_SIO_GPIO2_REG);
2062 if (!(reg & (1 << 5))) 2115 if (!(reg & (1 << 5)))
@@ -2071,12 +2124,22 @@ static int __init it87_find(unsigned short *address,
2071 if (reg & (1 << 7)) 2124 if (reg & (1 << 7))
2072 sio_data->skip_fan |= (1 << 2); 2125 sio_data->skip_fan |= (1 << 2);
2073 2126
2127 /* Check for pwm4 */
2128 reg = superio_inb(IT87_SIO_GPIO4_REG);
2129 if (!(reg & (1 << 2)))
2130 sio_data->skip_pwm |= (1 << 3);
2131
2074 /* Check for pwm2, fan2 */ 2132 /* Check for pwm2, fan2 */
2075 reg = superio_inb(IT87_SIO_GPIO5_REG); 2133 reg = superio_inb(IT87_SIO_GPIO5_REG);
2076 if (reg & (1 << 1)) 2134 if (reg & (1 << 1))
2077 sio_data->skip_pwm |= (1 << 1); 2135 sio_data->skip_pwm |= (1 << 1);
2078 if (reg & (1 << 2)) 2136 if (reg & (1 << 2))
2079 sio_data->skip_fan |= (1 << 1); 2137 sio_data->skip_fan |= (1 << 1);
2138 /* Check for pwm6, fan6 */
2139 if (!(reg & (1 << 7))) {
2140 sio_data->skip_pwm |= (1 << 5);
2141 sio_data->skip_fan |= (1 << 5);
2142 }
2080 2143
2081 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; 2144 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
2082 } else { 2145 } else {
@@ -2219,7 +2282,7 @@ static void it87_remove_files(struct device *dev)
2219 sysfs_remove_file(&dev->kobj, 2282 sysfs_remove_file(&dev->kobj,
2220 it87_attributes_fan_div[i]); 2283 it87_attributes_fan_div[i]);
2221 } 2284 }
2222 for (i = 0; i < 3; i++) { 2285 for (i = 0; i < 6; i++) {
2223 if (sio_data->skip_pwm & (1 << i)) 2286 if (sio_data->skip_pwm & (1 << i))
2224 continue; 2287 continue;
2225 sysfs_remove_group(&dev->kobj, &it87_group_pwm[i]); 2288 sysfs_remove_group(&dev->kobj, &it87_group_pwm[i]);
@@ -2402,7 +2465,7 @@ static int it87_probe(struct platform_device *pdev)
2402 } 2465 }
2403 2466
2404 if (enable_pwm_interface) { 2467 if (enable_pwm_interface) {
2405 for (i = 0; i < 3; i++) { 2468 for (i = 0; i < 6; i++) {
2406 if (sio_data->skip_pwm & (1 << i)) 2469 if (sio_data->skip_pwm & (1 << i))
2407 continue; 2470 continue;
2408 err = sysfs_create_group(&dev->kobj, 2471 err = sysfs_create_group(&dev->kobj,
@@ -2505,7 +2568,7 @@ static int it87_check_pwm(struct device *dev)
2505 2568
2506 for (i = 0; i < 3; i++) 2569 for (i = 0; i < 3; i++)
2507 pwm[i] = it87_read_value(data, 2570 pwm[i] = it87_read_value(data,
2508 IT87_REG_PWM(i)); 2571 IT87_REG_PWM[i]);
2509 2572
2510 /* 2573 /*
2511 * If any fan is in automatic pwm mode, the polarity 2574 * If any fan is in automatic pwm mode, the polarity
@@ -2520,7 +2583,7 @@ static int it87_check_pwm(struct device *dev)
2520 tmp | 0x87); 2583 tmp | 0x87);
2521 for (i = 0; i < 3; i++) 2584 for (i = 0; i < 3; i++)
2522 it87_write_value(data, 2585 it87_write_value(data,
2523 IT87_REG_PWM(i), 2586 IT87_REG_PWM[i],
2524 0x7f & ~pwm[i]); 2587 0x7f & ~pwm[i]);
2525 return 1; 2588 return 1;
2526 } 2589 }
@@ -2635,6 +2698,16 @@ static void it87_init_device(struct platform_device *pdev)
2635 /* Fan input pins may be used for alternative functions */ 2698 /* Fan input pins may be used for alternative functions */
2636 data->has_fan &= ~sio_data->skip_fan; 2699 data->has_fan &= ~sio_data->skip_fan;
2637 2700
2701 /* Check if pwm5, pwm6 are enabled */
2702 if (has_six_pwm(data)) {
2703 /* The following code may be IT8620E specific */
2704 tmp = it87_read_value(data, IT87_REG_FAN_DIV);
2705 if ((tmp & 0xc0) == 0xc0)
2706 sio_data->skip_pwm |= (1 << 4);
2707 if (!(tmp & (1 << 3)))
2708 sio_data->skip_pwm |= (1 << 5);
2709 }
2710
2638 /* Start monitoring */ 2711 /* Start monitoring */
2639 it87_write_value(data, IT87_REG_CONFIG, 2712 it87_write_value(data, IT87_REG_CONFIG,
2640 (it87_read_value(data, IT87_REG_CONFIG) & 0x3e) 2713 (it87_read_value(data, IT87_REG_CONFIG) & 0x3e)
@@ -2643,11 +2716,12 @@ static void it87_init_device(struct platform_device *pdev)
2643 2716
2644static void it87_update_pwm_ctrl(struct it87_data *data, int nr) 2717static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
2645{ 2718{
2646 data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); 2719 data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM[nr]);
2647 if (has_newer_autopwm(data)) { 2720 if (has_newer_autopwm(data)) {
2648 data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; 2721 data->pwm_temp_map[nr] = (data->pwm_ctrl[nr] & 0x03) +
2722 nr < 3 ? 0 : 3;
2649 data->pwm_duty[nr] = it87_read_value(data, 2723 data->pwm_duty[nr] = it87_read_value(data,
2650 IT87_REG_PWM_DUTY(nr)); 2724 IT87_REG_PWM_DUTY[nr]);
2651 } else { 2725 } else {
2652 if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ 2726 if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
2653 data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; 2727 data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
@@ -2746,7 +2820,7 @@ static struct it87_data *it87_update_device(struct device *dev)
2746 data->fan_main_ctrl = it87_read_value(data, 2820 data->fan_main_ctrl = it87_read_value(data,
2747 IT87_REG_FAN_MAIN_CTRL); 2821 IT87_REG_FAN_MAIN_CTRL);
2748 data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); 2822 data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL);
2749 for (i = 0; i < 3; i++) 2823 for (i = 0; i < 6; i++)
2750 it87_update_pwm_ctrl(data, i); 2824 it87_update_pwm_ctrl(data, i);
2751 2825
2752 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); 2826 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);