diff options
author | Juerg Haefliger <juergh@gmail.com> | 2010-05-27 13:59:01 -0400 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2010-05-27 13:59:01 -0400 |
commit | ea694431f9c862bd409c90ba1cb3bdc6fdde8635 (patch) | |
tree | 702ee926abff58b9896220ce02e4592b13978005 /drivers/hwmon/dme1737.c | |
parent | 38806bda6b7c8473c47a967a514260c1a1c32c2e (diff) |
hwmon: (dme1737) Add SCH5127 support
Add support for the hardware monitoring capabilities of the SCH5127
chip to the dme1737 driver.
Signed-off-by: Juerg Haefliger <juergh@gmail.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Tested-by: Jeff Rickman <jrickman@myamigos.us>
Diffstat (limited to 'drivers/hwmon/dme1737.c')
-rw-r--r-- | drivers/hwmon/dme1737.c | 328 |
1 files changed, 225 insertions, 103 deletions
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 823dd28a902c..980c17d5eeae 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
@@ -1,12 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x and | 2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x, SCH5027, |
3 | * SCH5027 Super-I/O chips integrated hardware monitoring features. | 3 | * and SCH5127 Super-I/O chips integrated hardware monitoring |
4 | * Copyright (c) 2007, 2008 Juerg Haefliger <juergh@gmail.com> | 4 | * features. |
5 | * Copyright (c) 2007, 2008, 2009, 2010 Juerg Haefliger <juergh@gmail.com> | ||
5 | * | 6 | * |
6 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access | 7 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access |
7 | * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus | 8 | * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus |
8 | * if a SCH311x chip is found. Both types of chips have very similar hardware | 9 | * if a SCH311x or SCH5127 chip is found. Both types of chips have very |
9 | * monitoring capabilities but differ in the way they can be accessed. | 10 | * similar hardware monitoring capabilities but differ in the way they can be |
11 | * accessed. | ||
10 | * | 12 | * |
11 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 14 | * it under the terms of the GNU General Public License as published by |
@@ -57,7 +59,7 @@ MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC " | |||
57 | /* Addresses to scan */ | 59 | /* Addresses to scan */ |
58 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; | 60 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; |
59 | 61 | ||
60 | enum chips { dme1737, sch5027, sch311x }; | 62 | enum chips { dme1737, sch5027, sch311x, sch5127 }; |
61 | 63 | ||
62 | /* --------------------------------------------------------------------- | 64 | /* --------------------------------------------------------------------- |
63 | * Registers | 65 | * Registers |
@@ -164,10 +166,29 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | |||
164 | #define DME1737_VERSTEP_MASK 0xf8 | 166 | #define DME1737_VERSTEP_MASK 0xf8 |
165 | #define SCH311X_DEVICE 0x8c | 167 | #define SCH311X_DEVICE 0x8c |
166 | #define SCH5027_VERSTEP 0x69 | 168 | #define SCH5027_VERSTEP 0x69 |
169 | #define SCH5127_DEVICE 0x8e | ||
170 | |||
171 | /* Device ID values (global configuration register index 0x20) */ | ||
172 | #define DME1737_ID_1 0x77 | ||
173 | #define DME1737_ID_2 0x78 | ||
174 | #define SCH3112_ID 0x7c | ||
175 | #define SCH3114_ID 0x7d | ||
176 | #define SCH3116_ID 0x7f | ||
177 | #define SCH5027_ID 0x89 | ||
178 | #define SCH5127_ID 0x86 | ||
167 | 179 | ||
168 | /* Length of ISA address segment */ | 180 | /* Length of ISA address segment */ |
169 | #define DME1737_EXTENT 2 | 181 | #define DME1737_EXTENT 2 |
170 | 182 | ||
183 | /* chip-dependent features */ | ||
184 | #define HAS_TEMP_OFFSET (1 << 0) /* bit 0 */ | ||
185 | #define HAS_VID (1 << 1) /* bit 1 */ | ||
186 | #define HAS_ZONE3 (1 << 2) /* bit 2 */ | ||
187 | #define HAS_ZONE_HYST (1 << 3) /* bit 3 */ | ||
188 | #define HAS_PWM_MIN (1 << 4) /* bit 4 */ | ||
189 | #define HAS_FAN(ix) (1 << ((ix) + 5)) /* bits 5-10 */ | ||
190 | #define HAS_PWM(ix) (1 << ((ix) + 11)) /* bits 11-16 */ | ||
191 | |||
171 | /* --------------------------------------------------------------------- | 192 | /* --------------------------------------------------------------------- |
172 | * Data structures and manipulation thereof | 193 | * Data structures and manipulation thereof |
173 | * --------------------------------------------------------------------- */ | 194 | * --------------------------------------------------------------------- */ |
@@ -187,8 +208,7 @@ struct dme1737_data { | |||
187 | 208 | ||
188 | u8 vid; | 209 | u8 vid; |
189 | u8 pwm_rr_en; | 210 | u8 pwm_rr_en; |
190 | u8 has_pwm; | 211 | u32 has_features; |
191 | u8 has_fan; | ||
192 | 212 | ||
193 | /* Register values */ | 213 | /* Register values */ |
194 | u16 in[7]; | 214 | u16 in[7]; |
@@ -224,8 +244,11 @@ static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300, | |||
224 | 3300}; | 244 | 3300}; |
225 | static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, | 245 | static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, |
226 | 3300}; | 246 | 3300}; |
247 | static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300, | ||
248 | 3300}; | ||
227 | #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ | 249 | #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ |
228 | (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ | 250 | (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ |
251 | (type) == sch5127 ? IN_NOMINAL_SCH5127 : \ | ||
229 | IN_NOMINAL_DME1737) | 252 | IN_NOMINAL_DME1737) |
230 | 253 | ||
231 | /* Voltage input | 254 | /* Voltage input |
@@ -568,7 +591,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
568 | 591 | ||
569 | /* Sample register contents every 1 sec */ | 592 | /* Sample register contents every 1 sec */ |
570 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { | 593 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { |
571 | if (data->type == dme1737) { | 594 | if (data->has_features & HAS_VID) { |
572 | data->vid = dme1737_read(data, DME1737_REG_VID) & | 595 | data->vid = dme1737_read(data, DME1737_REG_VID) & |
573 | 0x3f; | 596 | 0x3f; |
574 | } | 597 | } |
@@ -599,7 +622,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
599 | DME1737_REG_TEMP_MIN(ix)); | 622 | DME1737_REG_TEMP_MIN(ix)); |
600 | data->temp_max[ix] = dme1737_read(data, | 623 | data->temp_max[ix] = dme1737_read(data, |
601 | DME1737_REG_TEMP_MAX(ix)); | 624 | DME1737_REG_TEMP_MAX(ix)); |
602 | if (data->type != sch5027) { | 625 | if (data->has_features & HAS_TEMP_OFFSET) { |
603 | data->temp_offset[ix] = dme1737_read(data, | 626 | data->temp_offset[ix] = dme1737_read(data, |
604 | DME1737_REG_TEMP_OFFSET(ix)); | 627 | DME1737_REG_TEMP_OFFSET(ix)); |
605 | } | 628 | } |
@@ -626,7 +649,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
626 | for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { | 649 | for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { |
627 | /* Skip reading registers if optional fans are not | 650 | /* Skip reading registers if optional fans are not |
628 | * present */ | 651 | * present */ |
629 | if (!(data->has_fan & (1 << ix))) { | 652 | if (!(data->has_features & HAS_FAN(ix))) { |
630 | continue; | 653 | continue; |
631 | } | 654 | } |
632 | data->fan[ix] = dme1737_read(data, | 655 | data->fan[ix] = dme1737_read(data, |
@@ -650,7 +673,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
650 | for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) { | 673 | for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) { |
651 | /* Skip reading registers if optional PWMs are not | 674 | /* Skip reading registers if optional PWMs are not |
652 | * present */ | 675 | * present */ |
653 | if (!(data->has_pwm & (1 << ix))) { | 676 | if (!(data->has_features & HAS_PWM(ix))) { |
654 | continue; | 677 | continue; |
655 | } | 678 | } |
656 | data->pwm[ix] = dme1737_read(data, | 679 | data->pwm[ix] = dme1737_read(data, |
@@ -672,12 +695,24 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
672 | 695 | ||
673 | /* Thermal zone registers */ | 696 | /* Thermal zone registers */ |
674 | for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { | 697 | for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { |
675 | data->zone_low[ix] = dme1737_read(data, | 698 | /* Skip reading registers if zone3 is not present */ |
676 | DME1737_REG_ZONE_LOW(ix)); | 699 | if ((ix == 2) && !(data->has_features & HAS_ZONE3)) { |
677 | data->zone_abs[ix] = dme1737_read(data, | 700 | continue; |
678 | DME1737_REG_ZONE_ABS(ix)); | 701 | } |
702 | /* sch5127 zone2 registers are special */ | ||
703 | if ((ix == 1) && (data->type == sch5127)) { | ||
704 | data->zone_low[1] = dme1737_read(data, | ||
705 | DME1737_REG_ZONE_LOW(2)); | ||
706 | data->zone_abs[1] = dme1737_read(data, | ||
707 | DME1737_REG_ZONE_ABS(2)); | ||
708 | } else { | ||
709 | data->zone_low[ix] = dme1737_read(data, | ||
710 | DME1737_REG_ZONE_LOW(ix)); | ||
711 | data->zone_abs[ix] = dme1737_read(data, | ||
712 | DME1737_REG_ZONE_ABS(ix)); | ||
713 | } | ||
679 | } | 714 | } |
680 | if (data->type != sch5027) { | 715 | if (data->has_features & HAS_ZONE_HYST) { |
681 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { | 716 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { |
682 | data->zone_hyst[ix] = dme1737_read(data, | 717 | data->zone_hyst[ix] = dme1737_read(data, |
683 | DME1737_REG_ZONE_HYST(ix)); | 718 | DME1737_REG_ZONE_HYST(ix)); |
@@ -1594,10 +1629,6 @@ static struct attribute *dme1737_attr[] ={ | |||
1594 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, | 1629 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, |
1595 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, | 1630 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, |
1596 | &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, | 1631 | &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, |
1597 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | ||
1598 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | ||
1599 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | ||
1600 | &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, | ||
1601 | NULL | 1632 | NULL |
1602 | }; | 1633 | }; |
1603 | 1634 | ||
@@ -1605,27 +1636,23 @@ static const struct attribute_group dme1737_group = { | |||
1605 | .attrs = dme1737_attr, | 1636 | .attrs = dme1737_attr, |
1606 | }; | 1637 | }; |
1607 | 1638 | ||
1608 | /* The following struct holds misc attributes, which are not available in all | 1639 | /* The following struct holds temp offset attributes, which are not available |
1609 | * chips. Their creation depends on the chip type which is determined during | 1640 | * in all chips. The following chips support them: |
1610 | * module load. */ | 1641 | * DME1737, SCH311x */ |
1611 | static struct attribute *dme1737_misc_attr[] = { | 1642 | static struct attribute *dme1737_temp_offset_attr[] = { |
1612 | /* Temperatures */ | ||
1613 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | 1643 | &sensor_dev_attr_temp1_offset.dev_attr.attr, |
1614 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | 1644 | &sensor_dev_attr_temp2_offset.dev_attr.attr, |
1615 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | 1645 | &sensor_dev_attr_temp3_offset.dev_attr.attr, |
1616 | /* Zones */ | ||
1617 | &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, | ||
1618 | &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, | ||
1619 | &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, | ||
1620 | NULL | 1646 | NULL |
1621 | }; | 1647 | }; |
1622 | 1648 | ||
1623 | static const struct attribute_group dme1737_misc_group = { | 1649 | static const struct attribute_group dme1737_temp_offset_group = { |
1624 | .attrs = dme1737_misc_attr, | 1650 | .attrs = dme1737_temp_offset_attr, |
1625 | }; | 1651 | }; |
1626 | 1652 | ||
1627 | /* The following struct holds VID-related attributes. Their creation | 1653 | /* The following struct holds VID related attributes, which are not available |
1628 | depends on the chip type which is determined during module load. */ | 1654 | * in all chips. The following chips support them: |
1655 | * DME1737 */ | ||
1629 | static struct attribute *dme1737_vid_attr[] = { | 1656 | static struct attribute *dme1737_vid_attr[] = { |
1630 | &dev_attr_vrm.attr, | 1657 | &dev_attr_vrm.attr, |
1631 | &dev_attr_cpu0_vid.attr, | 1658 | &dev_attr_cpu0_vid.attr, |
@@ -1636,6 +1663,36 @@ static const struct attribute_group dme1737_vid_group = { | |||
1636 | .attrs = dme1737_vid_attr, | 1663 | .attrs = dme1737_vid_attr, |
1637 | }; | 1664 | }; |
1638 | 1665 | ||
1666 | /* The following struct holds temp zone 3 related attributes, which are not | ||
1667 | * available in all chips. The following chips support them: | ||
1668 | * DME1737, SCH311x, SCH5027 */ | ||
1669 | static struct attribute *dme1737_zone3_attr[] = { | ||
1670 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | ||
1671 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | ||
1672 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | ||
1673 | &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, | ||
1674 | NULL | ||
1675 | }; | ||
1676 | |||
1677 | static const struct attribute_group dme1737_zone3_group = { | ||
1678 | .attrs = dme1737_zone3_attr, | ||
1679 | }; | ||
1680 | |||
1681 | |||
1682 | /* The following struct holds temp zone hysteresis related attributes, which | ||
1683 | * are not available in all chips. The following chips support them: | ||
1684 | * DME1737, SCH311x */ | ||
1685 | static struct attribute *dme1737_zone_hyst_attr[] = { | ||
1686 | &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, | ||
1687 | &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, | ||
1688 | &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, | ||
1689 | NULL | ||
1690 | }; | ||
1691 | |||
1692 | static const struct attribute_group dme1737_zone_hyst_group = { | ||
1693 | .attrs = dme1737_zone_hyst_attr, | ||
1694 | }; | ||
1695 | |||
1639 | /* The following structs hold the PWM attributes, some of which are optional. | 1696 | /* The following structs hold the PWM attributes, some of which are optional. |
1640 | * Their creation depends on the chip configuration which is determined during | 1697 | * Their creation depends on the chip configuration which is determined during |
1641 | * module load. */ | 1698 | * module load. */ |
@@ -1691,10 +1748,10 @@ static const struct attribute_group dme1737_pwm_group[] = { | |||
1691 | { .attrs = dme1737_pwm6_attr }, | 1748 | { .attrs = dme1737_pwm6_attr }, |
1692 | }; | 1749 | }; |
1693 | 1750 | ||
1694 | /* The following struct holds misc PWM attributes, which are not available in | 1751 | /* The following struct holds auto PWM min attributes, which are not available |
1695 | * all chips. Their creation depends on the chip type which is determined | 1752 | * in all chips. Their creation depends on the chip type which is determined |
1696 | * during module load. */ | 1753 | * during module load. */ |
1697 | static struct attribute *dme1737_pwm_misc_attr[] = { | 1754 | static struct attribute *dme1737_auto_pwm_min_attr[] = { |
1698 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, | 1755 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, |
1699 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, | 1756 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, |
1700 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, | 1757 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, |
@@ -1764,14 +1821,25 @@ static struct attribute *dme1737_zone_chmod_attr[] = { | |||
1764 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, | 1821 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, |
1765 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, | 1822 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, |
1766 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, | 1823 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, |
1824 | NULL | ||
1825 | }; | ||
1826 | |||
1827 | static const struct attribute_group dme1737_zone_chmod_group = { | ||
1828 | .attrs = dme1737_zone_chmod_attr, | ||
1829 | }; | ||
1830 | |||
1831 | |||
1832 | /* The permissions of the following zone 3 attributes are changed to read- | ||
1833 | * writeable if the chip is *not* locked. Otherwise they stay read-only. */ | ||
1834 | static struct attribute *dme1737_zone3_chmod_attr[] = { | ||
1767 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | 1835 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, |
1768 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | 1836 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, |
1769 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | 1837 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, |
1770 | NULL | 1838 | NULL |
1771 | }; | 1839 | }; |
1772 | 1840 | ||
1773 | static const struct attribute_group dme1737_zone_chmod_group = { | 1841 | static const struct attribute_group dme1737_zone3_chmod_group = { |
1774 | .attrs = dme1737_zone_chmod_attr, | 1842 | .attrs = dme1737_zone3_chmod_attr, |
1775 | }; | 1843 | }; |
1776 | 1844 | ||
1777 | /* The permissions of the following PWM attributes are changed to read- | 1845 | /* The permissions of the following PWM attributes are changed to read- |
@@ -1887,30 +1955,35 @@ static void dme1737_remove_files(struct device *dev) | |||
1887 | int ix; | 1955 | int ix; |
1888 | 1956 | ||
1889 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 1957 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
1890 | if (data->has_fan & (1 << ix)) { | 1958 | if (data->has_features & HAS_FAN(ix)) { |
1891 | sysfs_remove_group(&dev->kobj, | 1959 | sysfs_remove_group(&dev->kobj, |
1892 | &dme1737_fan_group[ix]); | 1960 | &dme1737_fan_group[ix]); |
1893 | } | 1961 | } |
1894 | } | 1962 | } |
1895 | 1963 | ||
1896 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | 1964 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { |
1897 | if (data->has_pwm & (1 << ix)) { | 1965 | if (data->has_features & HAS_PWM(ix)) { |
1898 | sysfs_remove_group(&dev->kobj, | 1966 | sysfs_remove_group(&dev->kobj, |
1899 | &dme1737_pwm_group[ix]); | 1967 | &dme1737_pwm_group[ix]); |
1900 | if (data->type != sch5027 && ix < 3) { | 1968 | if ((data->has_features & HAS_PWM_MIN) && ix < 3) { |
1901 | sysfs_remove_file(&dev->kobj, | 1969 | sysfs_remove_file(&dev->kobj, |
1902 | dme1737_pwm_misc_attr[ix]); | 1970 | dme1737_auto_pwm_min_attr[ix]); |
1903 | } | 1971 | } |
1904 | } | 1972 | } |
1905 | } | 1973 | } |
1906 | 1974 | ||
1907 | if (data->type != sch5027) { | 1975 | if (data->has_features & HAS_TEMP_OFFSET) { |
1908 | sysfs_remove_group(&dev->kobj, &dme1737_misc_group); | 1976 | sysfs_remove_group(&dev->kobj, &dme1737_temp_offset_group); |
1909 | } | 1977 | } |
1910 | if (data->type == dme1737) { | 1978 | if (data->has_features & HAS_VID) { |
1911 | sysfs_remove_group(&dev->kobj, &dme1737_vid_group); | 1979 | sysfs_remove_group(&dev->kobj, &dme1737_vid_group); |
1912 | } | 1980 | } |
1913 | 1981 | if (data->has_features & HAS_ZONE3) { | |
1982 | sysfs_remove_group(&dev->kobj, &dme1737_zone3_group); | ||
1983 | } | ||
1984 | if (data->has_features & HAS_ZONE_HYST) { | ||
1985 | sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group); | ||
1986 | } | ||
1914 | sysfs_remove_group(&dev->kobj, &dme1737_group); | 1987 | sysfs_remove_group(&dev->kobj, &dme1737_group); |
1915 | 1988 | ||
1916 | if (!data->client) { | 1989 | if (!data->client) { |
@@ -1934,23 +2007,31 @@ static int dme1737_create_files(struct device *dev) | |||
1934 | goto exit_remove; | 2007 | goto exit_remove; |
1935 | } | 2008 | } |
1936 | 2009 | ||
1937 | /* Create misc sysfs attributes */ | 2010 | /* Create chip-dependent sysfs attributes */ |
1938 | if ((data->type != sch5027) && | 2011 | if ((data->has_features & HAS_TEMP_OFFSET) && |
1939 | (err = sysfs_create_group(&dev->kobj, | 2012 | (err = sysfs_create_group(&dev->kobj, |
1940 | &dme1737_misc_group))) { | 2013 | &dme1737_temp_offset_group))) { |
1941 | goto exit_remove; | 2014 | goto exit_remove; |
1942 | } | 2015 | } |
1943 | 2016 | if ((data->has_features & HAS_VID) && | |
1944 | /* Create VID-related sysfs attributes */ | ||
1945 | if ((data->type == dme1737) && | ||
1946 | (err = sysfs_create_group(&dev->kobj, | 2017 | (err = sysfs_create_group(&dev->kobj, |
1947 | &dme1737_vid_group))) { | 2018 | &dme1737_vid_group))) { |
1948 | goto exit_remove; | 2019 | goto exit_remove; |
1949 | } | 2020 | } |
2021 | if ((data->has_features & HAS_ZONE3) && | ||
2022 | (err = sysfs_create_group(&dev->kobj, | ||
2023 | &dme1737_zone3_group))) { | ||
2024 | goto exit_remove; | ||
2025 | } | ||
2026 | if ((data->has_features & HAS_ZONE_HYST) && | ||
2027 | (err = sysfs_create_group(&dev->kobj, | ||
2028 | &dme1737_zone_hyst_group))) { | ||
2029 | goto exit_remove; | ||
2030 | } | ||
1950 | 2031 | ||
1951 | /* Create fan sysfs attributes */ | 2032 | /* Create fan sysfs attributes */ |
1952 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 2033 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
1953 | if (data->has_fan & (1 << ix)) { | 2034 | if (data->has_features & HAS_FAN(ix)) { |
1954 | if ((err = sysfs_create_group(&dev->kobj, | 2035 | if ((err = sysfs_create_group(&dev->kobj, |
1955 | &dme1737_fan_group[ix]))) { | 2036 | &dme1737_fan_group[ix]))) { |
1956 | goto exit_remove; | 2037 | goto exit_remove; |
@@ -1960,14 +2041,14 @@ static int dme1737_create_files(struct device *dev) | |||
1960 | 2041 | ||
1961 | /* Create PWM sysfs attributes */ | 2042 | /* Create PWM sysfs attributes */ |
1962 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | 2043 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { |
1963 | if (data->has_pwm & (1 << ix)) { | 2044 | if (data->has_features & HAS_PWM(ix)) { |
1964 | if ((err = sysfs_create_group(&dev->kobj, | 2045 | if ((err = sysfs_create_group(&dev->kobj, |
1965 | &dme1737_pwm_group[ix]))) { | 2046 | &dme1737_pwm_group[ix]))) { |
1966 | goto exit_remove; | 2047 | goto exit_remove; |
1967 | } | 2048 | } |
1968 | if (data->type != sch5027 && ix < 3 && | 2049 | if ((data->has_features & HAS_PWM_MIN) && ix < 3 && |
1969 | (err = sysfs_create_file(&dev->kobj, | 2050 | (err = sysfs_create_file(&dev->kobj, |
1970 | dme1737_pwm_misc_attr[ix]))) { | 2051 | dme1737_auto_pwm_min_attr[ix]))) { |
1971 | goto exit_remove; | 2052 | goto exit_remove; |
1972 | } | 2053 | } |
1973 | } | 2054 | } |
@@ -1983,21 +2064,30 @@ static int dme1737_create_files(struct device *dev) | |||
1983 | dme1737_chmod_group(dev, &dme1737_zone_chmod_group, | 2064 | dme1737_chmod_group(dev, &dme1737_zone_chmod_group, |
1984 | S_IRUGO | S_IWUSR); | 2065 | S_IRUGO | S_IWUSR); |
1985 | 2066 | ||
1986 | /* Change permissions of misc sysfs attributes */ | 2067 | /* Change permissions of chip-dependent sysfs attributes */ |
1987 | if (data->type != sch5027) { | 2068 | if (data->has_features & HAS_TEMP_OFFSET) { |
1988 | dme1737_chmod_group(dev, &dme1737_misc_group, | 2069 | dme1737_chmod_group(dev, &dme1737_temp_offset_group, |
2070 | S_IRUGO | S_IWUSR); | ||
2071 | } | ||
2072 | if (data->has_features & HAS_ZONE3) { | ||
2073 | dme1737_chmod_group(dev, &dme1737_zone3_chmod_group, | ||
2074 | S_IRUGO | S_IWUSR); | ||
2075 | } | ||
2076 | if (data->has_features & HAS_ZONE_HYST) { | ||
2077 | dme1737_chmod_group(dev, &dme1737_zone_hyst_group, | ||
1989 | S_IRUGO | S_IWUSR); | 2078 | S_IRUGO | S_IWUSR); |
1990 | } | 2079 | } |
1991 | 2080 | ||
1992 | /* Change permissions of PWM sysfs attributes */ | 2081 | /* Change permissions of PWM sysfs attributes */ |
1993 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) { | 2082 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) { |
1994 | if (data->has_pwm & (1 << ix)) { | 2083 | if (data->has_features & HAS_PWM(ix)) { |
1995 | dme1737_chmod_group(dev, | 2084 | dme1737_chmod_group(dev, |
1996 | &dme1737_pwm_chmod_group[ix], | 2085 | &dme1737_pwm_chmod_group[ix], |
1997 | S_IRUGO | S_IWUSR); | 2086 | S_IRUGO | S_IWUSR); |
1998 | if (data->type != sch5027 && ix < 3) { | 2087 | if ((data->has_features & HAS_PWM_MIN) && |
2088 | ix < 3) { | ||
1999 | dme1737_chmod_file(dev, | 2089 | dme1737_chmod_file(dev, |
2000 | dme1737_pwm_misc_attr[ix], | 2090 | dme1737_auto_pwm_min_attr[ix], |
2001 | S_IRUGO | S_IWUSR); | 2091 | S_IRUGO | S_IWUSR); |
2002 | } | 2092 | } |
2003 | } | 2093 | } |
@@ -2005,7 +2095,7 @@ static int dme1737_create_files(struct device *dev) | |||
2005 | 2095 | ||
2006 | /* Change permissions of pwm[1-3] if in manual mode */ | 2096 | /* Change permissions of pwm[1-3] if in manual mode */ |
2007 | for (ix = 0; ix < 3; ix++) { | 2097 | for (ix = 0; ix < 3; ix++) { |
2008 | if ((data->has_pwm & (1 << ix)) && | 2098 | if ((data->has_features & HAS_PWM(ix)) && |
2009 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { | 2099 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { |
2010 | dme1737_chmod_file(dev, | 2100 | dme1737_chmod_file(dev, |
2011 | dme1737_pwm_chmod_attr[ix], | 2101 | dme1737_pwm_chmod_attr[ix], |
@@ -2052,20 +2142,20 @@ static int dme1737_init_device(struct device *dev) | |||
2052 | return -EFAULT; | 2142 | return -EFAULT; |
2053 | } | 2143 | } |
2054 | 2144 | ||
2055 | /* Determine which optional fan and pwm features are enabled/present */ | 2145 | /* Determine which optional fan and pwm features are enabled (only |
2146 | * valid for I2C devices) */ | ||
2056 | if (client) { /* I2C chip */ | 2147 | if (client) { /* I2C chip */ |
2057 | data->config2 = dme1737_read(data, DME1737_REG_CONFIG2); | 2148 | data->config2 = dme1737_read(data, DME1737_REG_CONFIG2); |
2058 | /* Check if optional fan3 input is enabled */ | 2149 | /* Check if optional fan3 input is enabled */ |
2059 | if (data->config2 & 0x04) { | 2150 | if (data->config2 & 0x04) { |
2060 | data->has_fan |= (1 << 2); | 2151 | data->has_features |= HAS_FAN(2); |
2061 | } | 2152 | } |
2062 | 2153 | ||
2063 | /* Fan4 and pwm3 are only available if the client's I2C address | 2154 | /* Fan4 and pwm3 are only available if the client's I2C address |
2064 | * is the default 0x2e. Otherwise the I/Os associated with | 2155 | * is the default 0x2e. Otherwise the I/Os associated with |
2065 | * these functions are used for addr enable/select. */ | 2156 | * these functions are used for addr enable/select. */ |
2066 | if (client->addr == 0x2e) { | 2157 | if (client->addr == 0x2e) { |
2067 | data->has_fan |= (1 << 3); | 2158 | data->has_features |= HAS_FAN(3) | HAS_PWM(2); |
2068 | data->has_pwm |= (1 << 2); | ||
2069 | } | 2159 | } |
2070 | 2160 | ||
2071 | /* Determine which of the optional fan[5-6] and pwm[5-6] | 2161 | /* Determine which of the optional fan[5-6] and pwm[5-6] |
@@ -2077,26 +2167,40 @@ static int dme1737_init_device(struct device *dev) | |||
2077 | dev_warn(dev, "Failed to query Super-IO for optional " | 2167 | dev_warn(dev, "Failed to query Super-IO for optional " |
2078 | "features.\n"); | 2168 | "features.\n"); |
2079 | } | 2169 | } |
2080 | } else { /* ISA chip */ | ||
2081 | /* Fan3 and pwm3 are always available. Fan[4-5] and pwm[5-6] | ||
2082 | * don't exist in the ISA chip. */ | ||
2083 | data->has_fan |= (1 << 2); | ||
2084 | data->has_pwm |= (1 << 2); | ||
2085 | } | 2170 | } |
2086 | 2171 | ||
2087 | /* Fan1, fan2, pwm1, and pwm2 are always present */ | 2172 | /* Fan[1-2] and pwm[1-2] are present in all chips */ |
2088 | data->has_fan |= 0x03; | 2173 | data->has_features |= HAS_FAN(0) | HAS_FAN(1) | HAS_PWM(0) | HAS_PWM(1); |
2089 | data->has_pwm |= 0x03; | 2174 | |
2175 | /* Chip-dependent features */ | ||
2176 | switch (data->type) { | ||
2177 | case dme1737: | ||
2178 | data->has_features |= HAS_TEMP_OFFSET | HAS_VID | HAS_ZONE3 | | ||
2179 | HAS_ZONE_HYST | HAS_PWM_MIN; | ||
2180 | break; | ||
2181 | case sch311x: | ||
2182 | data->has_features |= HAS_TEMP_OFFSET | HAS_ZONE3 | | ||
2183 | HAS_ZONE_HYST | HAS_PWM_MIN | HAS_FAN(2) | HAS_PWM(2); | ||
2184 | break; | ||
2185 | case sch5027: | ||
2186 | data->has_features |= HAS_ZONE3; | ||
2187 | break; | ||
2188 | case sch5127: | ||
2189 | data->has_features |= HAS_FAN(2) | HAS_PWM(2); | ||
2190 | break; | ||
2191 | default: | ||
2192 | break; | ||
2193 | } | ||
2090 | 2194 | ||
2091 | dev_info(dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " | 2195 | dev_info(dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " |
2092 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", | 2196 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", |
2093 | (data->has_pwm & (1 << 2)) ? "yes" : "no", | 2197 | (data->has_features & HAS_PWM(2)) ? "yes" : "no", |
2094 | (data->has_pwm & (1 << 4)) ? "yes" : "no", | 2198 | (data->has_features & HAS_PWM(4)) ? "yes" : "no", |
2095 | (data->has_pwm & (1 << 5)) ? "yes" : "no", | 2199 | (data->has_features & HAS_PWM(5)) ? "yes" : "no", |
2096 | (data->has_fan & (1 << 2)) ? "yes" : "no", | 2200 | (data->has_features & HAS_FAN(2)) ? "yes" : "no", |
2097 | (data->has_fan & (1 << 3)) ? "yes" : "no", | 2201 | (data->has_features & HAS_FAN(3)) ? "yes" : "no", |
2098 | (data->has_fan & (1 << 4)) ? "yes" : "no", | 2202 | (data->has_features & HAS_FAN(4)) ? "yes" : "no", |
2099 | (data->has_fan & (1 << 5)) ? "yes" : "no"); | 2203 | (data->has_features & HAS_FAN(5)) ? "yes" : "no"); |
2100 | 2204 | ||
2101 | reg = dme1737_read(data, DME1737_REG_TACH_PWM); | 2205 | reg = dme1737_read(data, DME1737_REG_TACH_PWM); |
2102 | /* Inform if fan-to-pwm mapping differs from the default */ | 2206 | /* Inform if fan-to-pwm mapping differs from the default */ |
@@ -2122,7 +2226,7 @@ static int dme1737_init_device(struct device *dev) | |||
2122 | for (ix = 0; ix < 3; ix++) { | 2226 | for (ix = 0; ix < 3; ix++) { |
2123 | data->pwm_config[ix] = dme1737_read(data, | 2227 | data->pwm_config[ix] = dme1737_read(data, |
2124 | DME1737_REG_PWM_CONFIG(ix)); | 2228 | DME1737_REG_PWM_CONFIG(ix)); |
2125 | if ((data->has_pwm & (1 << ix)) && | 2229 | if ((data->has_features & HAS_PWM(ix)) && |
2126 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { | 2230 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { |
2127 | dev_info(dev, "Switching pwm%d to " | 2231 | dev_info(dev, "Switching pwm%d to " |
2128 | "manual mode.\n", ix + 1); | 2232 | "manual mode.\n", ix + 1); |
@@ -2142,7 +2246,7 @@ static int dme1737_init_device(struct device *dev) | |||
2142 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ | 2246 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ |
2143 | 2247 | ||
2144 | /* Set VRM */ | 2248 | /* Set VRM */ |
2145 | if (data->type == dme1737) { | 2249 | if (data->has_features & HAS_VID) { |
2146 | data->vrm = vid_which_vrm(); | 2250 | data->vrm = vid_which_vrm(); |
2147 | } | 2251 | } |
2148 | 2252 | ||
@@ -2163,10 +2267,10 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) | |||
2163 | dme1737_sio_enter(sio_cip); | 2267 | dme1737_sio_enter(sio_cip); |
2164 | 2268 | ||
2165 | /* Check device ID | 2269 | /* Check device ID |
2166 | * The DME1737 can return either 0x78 or 0x77 as its device ID. | 2270 | * We currently know about two kinds of DME1737 and SCH5027. */ |
2167 | * The SCH5027 returns 0x89 as its device ID. */ | ||
2168 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); | 2271 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); |
2169 | if (!(reg == 0x77 || reg == 0x78 || reg == 0x89)) { | 2272 | if (!(reg == DME1737_ID_1 || reg == DME1737_ID_2 || |
2273 | reg == SCH5027_ID)) { | ||
2170 | err = -ENODEV; | 2274 | err = -ENODEV; |
2171 | goto exit; | 2275 | goto exit; |
2172 | } | 2276 | } |
@@ -2185,16 +2289,16 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) | |||
2185 | * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set | 2289 | * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set |
2186 | * to '10' if the respective feature is enabled. */ | 2290 | * to '10' if the respective feature is enabled. */ |
2187 | if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ | 2291 | if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ |
2188 | data->has_fan |= (1 << 5); | 2292 | data->has_features |= HAS_FAN(5); |
2189 | } | 2293 | } |
2190 | if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ | 2294 | if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ |
2191 | data->has_pwm |= (1 << 5); | 2295 | data->has_features |= HAS_PWM(5); |
2192 | } | 2296 | } |
2193 | if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ | 2297 | if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ |
2194 | data->has_fan |= (1 << 4); | 2298 | data->has_features |= HAS_FAN(4); |
2195 | } | 2299 | } |
2196 | if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ | 2300 | if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ |
2197 | data->has_pwm |= (1 << 4); | 2301 | data->has_features |= HAS_PWM(4); |
2198 | } | 2302 | } |
2199 | 2303 | ||
2200 | exit: | 2304 | exit: |
@@ -2222,7 +2326,6 @@ static int dme1737_i2c_detect(struct i2c_client *client, | |||
2222 | if (company == DME1737_COMPANY_SMSC && | 2326 | if (company == DME1737_COMPANY_SMSC && |
2223 | verstep == SCH5027_VERSTEP) { | 2327 | verstep == SCH5027_VERSTEP) { |
2224 | name = "sch5027"; | 2328 | name = "sch5027"; |
2225 | |||
2226 | } else if (company == DME1737_COMPANY_SMSC && | 2329 | } else if (company == DME1737_COMPANY_SMSC && |
2227 | (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { | 2330 | (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { |
2228 | name = "dme1737"; | 2331 | name = "dme1737"; |
@@ -2329,10 +2432,10 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr) | |||
2329 | dme1737_sio_enter(sio_cip); | 2432 | dme1737_sio_enter(sio_cip); |
2330 | 2433 | ||
2331 | /* Check device ID | 2434 | /* Check device ID |
2332 | * We currently know about SCH3112 (0x7c), SCH3114 (0x7d), and | 2435 | * We currently know about SCH3112, SCH3114, SCH3116, and SCH5127 */ |
2333 | * SCH3116 (0x7f). */ | ||
2334 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); | 2436 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); |
2335 | if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) { | 2437 | if (!(reg == SCH3112_ID || reg == SCH3114_ID || reg == SCH3116_ID || |
2438 | reg == SCH5127_ID)) { | ||
2336 | err = -ENODEV; | 2439 | err = -ENODEV; |
2337 | goto exit; | 2440 | goto exit; |
2338 | } | 2441 | } |
@@ -2424,23 +2527,42 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) | |||
2424 | platform_set_drvdata(pdev, data); | 2527 | platform_set_drvdata(pdev, data); |
2425 | 2528 | ||
2426 | /* Skip chip detection if module is loaded with force_id parameter */ | 2529 | /* Skip chip detection if module is loaded with force_id parameter */ |
2427 | if (!force_id) { | 2530 | switch (force_id) { |
2531 | case SCH3112_ID: | ||
2532 | case SCH3114_ID: | ||
2533 | case SCH3116_ID: | ||
2534 | data->type = sch311x; | ||
2535 | break; | ||
2536 | case SCH5127_ID: | ||
2537 | data->type = sch5127; | ||
2538 | break; | ||
2539 | default: | ||
2428 | company = dme1737_read(data, DME1737_REG_COMPANY); | 2540 | company = dme1737_read(data, DME1737_REG_COMPANY); |
2429 | device = dme1737_read(data, DME1737_REG_DEVICE); | 2541 | device = dme1737_read(data, DME1737_REG_DEVICE); |
2430 | 2542 | ||
2431 | if (!((company == DME1737_COMPANY_SMSC) && | 2543 | if ((company == DME1737_COMPANY_SMSC) && |
2432 | (device == SCH311X_DEVICE))) { | 2544 | (device == SCH311X_DEVICE)) { |
2545 | data->type = sch311x; | ||
2546 | } else if ((company == DME1737_COMPANY_SMSC) && | ||
2547 | (device == SCH5127_DEVICE)) { | ||
2548 | data->type = sch5127; | ||
2549 | } else { | ||
2433 | err = -ENODEV; | 2550 | err = -ENODEV; |
2434 | goto exit_kfree; | 2551 | goto exit_kfree; |
2435 | } | 2552 | } |
2436 | } | 2553 | } |
2437 | data->type = sch311x; | ||
2438 | 2554 | ||
2439 | /* Fill in the remaining client fields and initialize the mutex */ | 2555 | if (data->type == sch5127) { |
2440 | data->name = "sch311x"; | 2556 | data->name = "sch5127"; |
2557 | } else { | ||
2558 | data->name = "sch311x"; | ||
2559 | } | ||
2560 | |||
2561 | /* Initialize the mutex */ | ||
2441 | mutex_init(&data->update_lock); | 2562 | mutex_init(&data->update_lock); |
2442 | 2563 | ||
2443 | dev_info(dev, "Found a SCH311x chip at 0x%04x\n", data->addr); | 2564 | dev_info(dev, "Found a %s chip at 0x%04x\n", |
2565 | data->type == sch5127 ? "SCH5127" : "SCH311x", data->addr); | ||
2444 | 2566 | ||
2445 | /* Initialize the chip */ | 2567 | /* Initialize the chip */ |
2446 | if ((err = dme1737_init_device(dev))) { | 2568 | if ((err = dme1737_init_device(dev))) { |