aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/nct6775.c
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-12-04 11:30:54 -0500
committerGuenter Roeck <linux@roeck-us.net>2013-04-08 00:16:39 -0400
commit77eb5b3703d995e6c72ef4a1e5411821f81df7e4 (patch)
treef91488312051b427872d45c7b7b62b0bee7b2098 /drivers/hwmon/nct6775.c
parent84d19d92f78e10f8bdc1b3e1b5ddcaf5895edaf7 (diff)
hwmon: (nct6775) Add support for pwm, pwm_mode, and pwm_enable
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/nct6775.c')
-rw-r--r--drivers/hwmon/nct6775.c329
1 files changed, 329 insertions, 0 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index 56d7652d303b..ad4ecc04e239 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -96,6 +96,8 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
96#define SIO_NCT6779_ID 0xc560 96#define SIO_NCT6779_ID 0xc560
97#define SIO_ID_MASK 0xFFF0 97#define SIO_ID_MASK 0xFFF0
98 98
99enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
100
99static inline void 101static inline void
100superio_outb(int ioreg, int reg, int val) 102superio_outb(int ioreg, int reg, int val)
101{ 103{
@@ -209,6 +211,15 @@ static const s8 NCT6775_ALARM_BITS[] = {
209static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee }; 211static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
210static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 }; 212static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
211 213
214/* DC or PWM output fan configuration */
215static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 };
216static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 };
217
218static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302, 0x802, 0x902 };
219
220static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309, 0x809, 0x909 };
221static const u16 NCT6775_REG_PWM_READ[] = { 0x01, 0x03, 0x11, 0x13, 0x15 };
222
212static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; 223static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
213static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d }; 224static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
214static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 }; 225static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 };
@@ -270,6 +281,9 @@ static const s8 NCT6776_ALARM_BITS[] = {
270 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ 281 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
271 12, 9 }; /* intrusion0, intrusion1 */ 282 12, 9 }; /* intrusion0, intrusion1 */
272 283
284static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0 };
285static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 };
286
273static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 }; 287static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 };
274static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 }; 288static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 };
275 289
@@ -380,6 +394,20 @@ static const u16 NCT6779_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6779_temp_label) - 1]
380static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1] 394static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1]
381 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a }; 395 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
382 396
397static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
398{
399 if (mode == 0 && pwm == 255)
400 return off;
401 return mode + 1;
402}
403
404static int pwm_enable_to_reg(enum pwm_enable mode)
405{
406 if (mode == off)
407 return 0;
408 return mode - 1;
409}
410
383/* 411/*
384 * Conversions 412 * Conversions
385 */ 413 */
@@ -471,9 +499,16 @@ struct nct6775_data {
471 const u16 *REG_IN_MINMAX[2]; 499 const u16 *REG_IN_MINMAX[2];
472 500
473 const u16 *REG_FAN; 501 const u16 *REG_FAN;
502 const u16 *REG_FAN_MODE;
474 const u16 *REG_FAN_MIN; 503 const u16 *REG_FAN_MIN;
475 const u16 *REG_FAN_PULSES; 504 const u16 *REG_FAN_PULSES;
476 505
506 const u8 *REG_PWM_MODE;
507 const u8 *PWM_MODE_MASK;
508
509 const u16 *REG_PWM[1]; /* [0]=pwm */
510 const u16 *REG_PWM_READ;
511
477 const u16 *REG_TEMP_SOURCE; /* temp register sources */ 512 const u16 *REG_TEMP_SOURCE; /* temp register sources */
478 const u16 *REG_TEMP_OFFSET; 513 const u16 *REG_TEMP_OFFSET;
479 514
@@ -494,6 +529,7 @@ struct nct6775_data {
494 u16 fan_min[5]; 529 u16 fan_min[5];
495 u8 fan_pulses[5]; 530 u8 fan_pulses[5];
496 u8 fan_div[5]; 531 u8 fan_div[5];
532 u8 has_pwm;
497 u8 has_fan; /* some fan inputs can be disabled */ 533 u8 has_fan; /* some fan inputs can be disabled */
498 u8 has_fan_min; /* some fans don't have min register */ 534 u8 has_fan_min; /* some fans don't have min register */
499 bool has_fan_div; 535 bool has_fan_div;
@@ -505,6 +541,18 @@ struct nct6775_data {
505 * 3=temp_crit */ 541 * 3=temp_crit */
506 u64 alarms; 542 u64 alarms;
507 543
544 u8 pwm_num; /* number of pwm */
545 u8 pwm_mode[5]; /* 1->DC variable voltage, 0->PWM variable duty cycle */
546 enum pwm_enable pwm_enable[5];
547 /* 0->off
548 * 1->manual
549 * 2->thermal cruise mode (also called SmartFan I)
550 * 3->fan speed cruise mode
551 * 4->SmartFan III
552 * 5->enhanced variable thermal cruise (SmartFan IV)
553 */
554 u8 pwm[1][5]; /* [0]=pwm */
555
508 u8 vid; 556 u8 vid;
509 u8 vrm; 557 u8 vrm;
510 558
@@ -781,6 +829,36 @@ static void nct6775_select_fan_div(struct device *dev,
781 } 829 }
782} 830}
783 831
832static void nct6775_update_pwm(struct device *dev)
833{
834 struct nct6775_data *data = dev_get_drvdata(dev);
835 int i, j;
836 int fanmodecfg;
837 bool duty_is_dc;
838
839 for (i = 0; i < data->pwm_num; i++) {
840 if (!(data->has_pwm & (1 << i)))
841 continue;
842
843 duty_is_dc = data->REG_PWM_MODE[i] &&
844 (nct6775_read_value(data, data->REG_PWM_MODE[i])
845 & data->PWM_MODE_MASK[i]);
846 data->pwm_mode[i] = duty_is_dc;
847
848 fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
849 for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
850 if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
851 data->pwm[j][i]
852 = nct6775_read_value(data,
853 data->REG_PWM[j][i]);
854 }
855 }
856
857 data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
858 (fanmodecfg >> 4) & 7);
859 }
860}
861
784static struct nct6775_data *nct6775_update_device(struct device *dev) 862static struct nct6775_data *nct6775_update_device(struct device *dev)
785{ 863{
786 struct nct6775_data *data = dev_get_drvdata(dev); 864 struct nct6775_data *data = dev_get_drvdata(dev);
@@ -826,6 +904,8 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
826 nct6775_select_fan_div(dev, data, i, reg); 904 nct6775_select_fan_div(dev, data, i, reg);
827 } 905 }
828 906
907 nct6775_update_pwm(dev);
908
829 /* Measured temperatures and limits */ 909 /* Measured temperatures and limits */
830 for (i = 0; i < NUM_TEMP; i++) { 910 for (i = 0; i < NUM_TEMP; i++) {
831 if (!(data->have_temp & (1 << i))) 911 if (!(data->have_temp & (1 << i)))
@@ -1600,6 +1680,170 @@ static struct sensor_device_attribute sda_temp_alarm[] = {
1600#define NUM_TEMP_ALARM ARRAY_SIZE(sda_temp_alarm) 1680#define NUM_TEMP_ALARM ARRAY_SIZE(sda_temp_alarm)
1601 1681
1602static ssize_t 1682static ssize_t
1683show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
1684{
1685 struct nct6775_data *data = nct6775_update_device(dev);
1686 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1687
1688 return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]);
1689}
1690
1691static ssize_t
1692store_pwm_mode(struct device *dev, struct device_attribute *attr,
1693 const char *buf, size_t count)
1694{
1695 struct nct6775_data *data = dev_get_drvdata(dev);
1696 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1697 int nr = sattr->index;
1698 unsigned long val;
1699 int err;
1700 u8 reg;
1701
1702 err = kstrtoul(buf, 10, &val);
1703 if (err < 0)
1704 return err;
1705
1706 if (val > 1)
1707 return -EINVAL;
1708
1709 /* Setting DC mode is not supported for all chips/channels */
1710 if (data->REG_PWM_MODE[nr] == 0) {
1711 if (val)
1712 return -EINVAL;
1713 return count;
1714 }
1715
1716 mutex_lock(&data->update_lock);
1717 data->pwm_mode[nr] = val;
1718 reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
1719 reg &= ~data->PWM_MODE_MASK[nr];
1720 if (val)
1721 reg |= data->PWM_MODE_MASK[nr];
1722 nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
1723 mutex_unlock(&data->update_lock);
1724 return count;
1725}
1726
1727static ssize_t
1728show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
1729{
1730 struct nct6775_data *data = nct6775_update_device(dev);
1731 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1732 int nr = sattr->nr;
1733 int index = sattr->index;
1734 int pwm;
1735
1736 /*
1737 * For automatic fan control modes, show current pwm readings.
1738 * Otherwise, show the configured value.
1739 */
1740 if (index == 0 && data->pwm_enable[nr] > manual)
1741 pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]);
1742 else
1743 pwm = data->pwm[index][nr];
1744
1745 return sprintf(buf, "%d\n", pwm);
1746}
1747
1748static ssize_t
1749store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
1750 size_t count)
1751{
1752 struct nct6775_data *data = dev_get_drvdata(dev);
1753 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1754 int nr = sattr->nr;
1755 int index = sattr->index;
1756 unsigned long val;
1757 int err;
1758
1759 err = kstrtoul(buf, 10, &val);
1760 if (err < 0)
1761 return err;
1762 val = clamp_val(val, 0, 255);
1763
1764 mutex_lock(&data->update_lock);
1765 data->pwm[index][nr] = val;
1766 nct6775_write_value(data, data->REG_PWM[index][nr], val);
1767 mutex_unlock(&data->update_lock);
1768 return count;
1769}
1770
1771static ssize_t
1772show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
1773{
1774 struct nct6775_data *data = nct6775_update_device(dev);
1775 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1776
1777 return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]);
1778}
1779
1780static ssize_t
1781store_pwm_enable(struct device *dev, struct device_attribute *attr,
1782 const char *buf, size_t count)
1783{
1784 struct nct6775_data *data = dev_get_drvdata(dev);
1785 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1786 int nr = sattr->index;
1787 unsigned long val;
1788 int err;
1789 u16 reg;
1790
1791 err = kstrtoul(buf, 10, &val);
1792 if (err < 0)
1793 return err;
1794
1795 if (val > sf4)
1796 return -EINVAL;
1797
1798 if (val == sf3 && data->kind != nct6775)
1799 return -EINVAL;
1800
1801 mutex_lock(&data->update_lock);
1802 data->pwm_enable[nr] = val;
1803 if (val == off) {
1804 /*
1805 * turn off pwm control: select manual mode, set pwm to maximum
1806 */
1807 data->pwm[0][nr] = 255;
1808 nct6775_write_value(data, data->REG_PWM[0][nr], 255);
1809 }
1810 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
1811 reg &= 0x0f;
1812 reg |= pwm_enable_to_reg(val) << 4;
1813 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
1814 mutex_unlock(&data->update_lock);
1815 return count;
1816}
1817
1818static SENSOR_DEVICE_ATTR_2(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0);
1819static SENSOR_DEVICE_ATTR_2(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 0);
1820static SENSOR_DEVICE_ATTR_2(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 0);
1821static SENSOR_DEVICE_ATTR_2(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 0);
1822static SENSOR_DEVICE_ATTR_2(pwm5, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 0);
1823
1824static SENSOR_DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
1825 store_pwm_mode, 0);
1826static SENSOR_DEVICE_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
1827 store_pwm_mode, 1);
1828static SENSOR_DEVICE_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
1829 store_pwm_mode, 2);
1830static SENSOR_DEVICE_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
1831 store_pwm_mode, 3);
1832static SENSOR_DEVICE_ATTR(pwm5_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
1833 store_pwm_mode, 4);
1834
1835static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
1836 store_pwm_enable, 0);
1837static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
1838 store_pwm_enable, 1);
1839static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
1840 store_pwm_enable, 2);
1841static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
1842 store_pwm_enable, 3);
1843static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
1844 store_pwm_enable, 4);
1845
1846static ssize_t
1603show_name(struct device *dev, struct device_attribute *attr, char *buf) 1847show_name(struct device *dev, struct device_attribute *attr, char *buf)
1604{ 1848{
1605 struct nct6775_data *data = dev_get_drvdata(dev); 1849 struct nct6775_data *data = dev_get_drvdata(dev);
@@ -1609,6 +1853,47 @@ show_name(struct device *dev, struct device_attribute *attr, char *buf)
1609 1853
1610static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 1854static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
1611 1855
1856static struct attribute *nct6775_attributes_pwm[5][4] = {
1857 {
1858 &sensor_dev_attr_pwm1.dev_attr.attr,
1859 &sensor_dev_attr_pwm1_mode.dev_attr.attr,
1860 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1861 NULL
1862 },
1863 {
1864 &sensor_dev_attr_pwm2.dev_attr.attr,
1865 &sensor_dev_attr_pwm2_mode.dev_attr.attr,
1866 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
1867 NULL
1868 },
1869 {
1870 &sensor_dev_attr_pwm3.dev_attr.attr,
1871 &sensor_dev_attr_pwm3_mode.dev_attr.attr,
1872 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
1873 NULL
1874 },
1875 {
1876 &sensor_dev_attr_pwm4.dev_attr.attr,
1877 &sensor_dev_attr_pwm4_mode.dev_attr.attr,
1878 &sensor_dev_attr_pwm4_enable.dev_attr.attr,
1879 NULL
1880 },
1881 {
1882 &sensor_dev_attr_pwm5.dev_attr.attr,
1883 &sensor_dev_attr_pwm5_mode.dev_attr.attr,
1884 &sensor_dev_attr_pwm5_enable.dev_attr.attr,
1885 NULL
1886 },
1887};
1888
1889static const struct attribute_group nct6775_group_pwm[5] = {
1890 { .attrs = nct6775_attributes_pwm[0] },
1891 { .attrs = nct6775_attributes_pwm[1] },
1892 { .attrs = nct6775_attributes_pwm[2] },
1893 { .attrs = nct6775_attributes_pwm[3] },
1894 { .attrs = nct6775_attributes_pwm[4] },
1895};
1896
1612static ssize_t 1897static ssize_t
1613show_vid(struct device *dev, struct device_attribute *attr, char *buf) 1898show_vid(struct device *dev, struct device_attribute *attr, char *buf)
1614{ 1899{
@@ -1681,6 +1966,9 @@ static void nct6775_device_remove_files(struct device *dev)
1681 int i; 1966 int i;
1682 struct nct6775_data *data = dev_get_drvdata(dev); 1967 struct nct6775_data *data = dev_get_drvdata(dev);
1683 1968
1969 for (i = 0; i < data->pwm_num; i++)
1970 sysfs_remove_group(&dev->kobj, &nct6775_group_pwm[i]);
1971
1684 for (i = 0; i < data->in_num; i++) 1972 for (i = 0; i < data->in_num; i++)
1685 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]); 1973 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]);
1686 1974
@@ -1763,6 +2051,7 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
1763{ 2051{
1764 int regval; 2052 int regval;
1765 bool fan3pin, fan3min, fan4pin, fan4min, fan5pin; 2053 bool fan3pin, fan3min, fan4pin, fan4min, fan5pin;
2054 bool pwm3pin, pwm4pin, pwm5pin;
1766 int ret; 2055 int ret;
1767 2056
1768 ret = superio_enter(sio_data->sioreg); 2057 ret = superio_enter(sio_data->sioreg);
@@ -1775,11 +2064,14 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
1775 2064
1776 fan3pin = regval & (1 << 6); 2065 fan3pin = regval & (1 << 6);
1777 fan3min = fan3pin; 2066 fan3min = fan3pin;
2067 pwm3pin = regval & (1 << 7);
1778 2068
1779 /* On NCT6775, fan4 shares pins with the fdc interface */ 2069 /* On NCT6775, fan4 shares pins with the fdc interface */
1780 fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80); 2070 fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80);
1781 fan4min = 0; 2071 fan4min = 0;
1782 fan5pin = 0; 2072 fan5pin = 0;
2073 pwm4pin = 0;
2074 pwm5pin = 0;
1783 } else if (data->kind == nct6776) { 2075 } else if (data->kind == nct6776) {
1784 bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80; 2076 bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
1785 2077
@@ -1803,6 +2095,9 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
1803 2095
1804 fan4min = fan4pin; 2096 fan4min = fan4pin;
1805 fan3min = fan3pin; 2097 fan3min = fan3pin;
2098 pwm3pin = fan3pin;
2099 pwm4pin = 0;
2100 pwm5pin = 0;
1806 } else { /* NCT6779D */ 2101 } else { /* NCT6779D */
1807 regval = superio_inb(sio_data->sioreg, 0x1c); 2102 regval = superio_inb(sio_data->sioreg, 0x1c);
1808 2103
@@ -1810,6 +2105,10 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
1810 fan4pin = !(regval & (1 << 6)); 2105 fan4pin = !(regval & (1 << 6));
1811 fan5pin = !(regval & (1 << 7)); 2106 fan5pin = !(regval & (1 << 7));
1812 2107
2108 pwm3pin = !(regval & (1 << 0));
2109 pwm4pin = !(regval & (1 << 1));
2110 pwm5pin = !(regval & (1 << 2));
2111
1813 fan3min = fan3pin; 2112 fan3min = fan3pin;
1814 fan4min = fan4pin; 2113 fan4min = fan4pin;
1815 } 2114 }
@@ -1823,6 +2122,8 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
1823 data->has_fan |= (fan4pin << 3) | (fan5pin << 4); 2122 data->has_fan |= (fan4pin << 3) | (fan5pin << 4);
1824 data->has_fan_min |= (fan4min << 3) | (fan5pin << 4); 2123 data->has_fan_min |= (fan4min << 3) | (fan5pin << 4);
1825 2124
2125 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) | (pwm5pin << 4);
2126
1826 return 0; 2127 return 0;
1827} 2128}
1828 2129
@@ -1859,6 +2160,7 @@ static int nct6775_probe(struct platform_device *pdev)
1859 switch (data->kind) { 2160 switch (data->kind) {
1860 case nct6775: 2161 case nct6775:
1861 data->in_num = 9; 2162 data->in_num = 9;
2163 data->pwm_num = 3;
1862 data->has_fan_div = true; 2164 data->has_fan_div = true;
1863 data->temp_fixed_num = 3; 2165 data->temp_fixed_num = 3;
1864 2166
@@ -1877,8 +2179,13 @@ static int nct6775_probe(struct platform_device *pdev)
1877 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 2179 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
1878 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 2180 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
1879 data->REG_FAN = NCT6775_REG_FAN; 2181 data->REG_FAN = NCT6775_REG_FAN;
2182 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
1880 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN; 2183 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
1881 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES; 2184 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
2185 data->REG_PWM[0] = NCT6775_REG_PWM;
2186 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
2187 data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
2188 data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
1882 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; 2189 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
1883 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; 2190 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
1884 data->REG_ALARM = NCT6775_REG_ALARM; 2191 data->REG_ALARM = NCT6775_REG_ALARM;
@@ -1894,6 +2201,7 @@ static int nct6775_probe(struct platform_device *pdev)
1894 break; 2201 break;
1895 case nct6776: 2202 case nct6776:
1896 data->in_num = 9; 2203 data->in_num = 9;
2204 data->pwm_num = 3;
1897 data->has_fan_div = false; 2205 data->has_fan_div = false;
1898 data->temp_fixed_num = 3; 2206 data->temp_fixed_num = 3;
1899 2207
@@ -1912,8 +2220,13 @@ static int nct6775_probe(struct platform_device *pdev)
1912 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 2220 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
1913 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 2221 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
1914 data->REG_FAN = NCT6775_REG_FAN; 2222 data->REG_FAN = NCT6775_REG_FAN;
2223 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
1915 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; 2224 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
1916 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES; 2225 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
2226 data->REG_PWM[0] = NCT6775_REG_PWM;
2227 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
2228 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
2229 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
1917 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; 2230 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
1918 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; 2231 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
1919 data->REG_ALARM = NCT6775_REG_ALARM; 2232 data->REG_ALARM = NCT6775_REG_ALARM;
@@ -1929,6 +2242,7 @@ static int nct6775_probe(struct platform_device *pdev)
1929 break; 2242 break;
1930 case nct6779: 2243 case nct6779:
1931 data->in_num = 15; 2244 data->in_num = 15;
2245 data->pwm_num = 5;
1932 data->has_fan_div = false; 2246 data->has_fan_div = false;
1933 data->temp_fixed_num = 6; 2247 data->temp_fixed_num = 6;
1934 2248
@@ -1947,8 +2261,13 @@ static int nct6775_probe(struct platform_device *pdev)
1947 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 2261 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
1948 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 2262 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
1949 data->REG_FAN = NCT6779_REG_FAN; 2263 data->REG_FAN = NCT6779_REG_FAN;
2264 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
1950 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; 2265 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
1951 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES; 2266 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
2267 data->REG_PWM[0] = NCT6775_REG_PWM;
2268 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
2269 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
2270 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
1952 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; 2271 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
1953 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; 2272 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
1954 data->REG_ALARM = NCT6779_REG_ALARM; 2273 data->REG_ALARM = NCT6779_REG_ALARM;
@@ -2157,6 +2476,16 @@ static int nct6775_probe(struct platform_device *pdev)
2157 /* Read fan clock dividers immediately */ 2476 /* Read fan clock dividers immediately */
2158 nct6775_init_fan_common(dev, data); 2477 nct6775_init_fan_common(dev, data);
2159 2478
2479 /* Register sysfs hooks */
2480 for (i = 0; i < data->pwm_num; i++) {
2481 if (!(data->has_pwm & (1 << i)))
2482 continue;
2483
2484 err = sysfs_create_group(&dev->kobj, &nct6775_group_pwm[i]);
2485 if (err)
2486 goto exit_remove;
2487 }
2488
2160 for (i = 0; i < data->in_num; i++) { 2489 for (i = 0; i < data->in_num; i++) {
2161 if (!(data->have_in & (1 << i))) 2490 if (!(data->have_in & (1 << i)))
2162 continue; 2491 continue;