aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-12-04 12:04:52 -0500
committerGuenter Roeck <linux@roeck-us.net>2013-04-08 00:16:39 -0400
commitcdcaeceb74ff3686eb25de6812870fbc765c3c39 (patch)
treec00ea91cde0d84fb1eead4be15e82089c84f7cfe
parent77eb5b3703d995e6c72ef4a1e5411821f81df7e4 (diff)
hwmon: (nct6775) Add support for automatic fan control
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--Documentation/hwmon/nct677569
-rw-r--r--drivers/hwmon/nct6775.c1099
2 files changed, 1161 insertions, 7 deletions
diff --git a/Documentation/hwmon/nct6775 b/Documentation/hwmon/nct6775
index 7c9f1d303913..b4fe6bc4d371 100644
--- a/Documentation/hwmon/nct6775
+++ b/Documentation/hwmon/nct6775
@@ -87,6 +87,75 @@ pwm[1-5]_mode - controls if output is PWM or DC level
87 * 0 DC output 87 * 0 DC output
88 * 1 PWM output 88 * 1 PWM output
89 89
90Common fan control attributes
91-----------------------------
92
93pwm[1-5]_temp_sel Temperature source. Value is temperature sensor index.
94 For example, select '1' for temp1_input.
95
96Thermal Cruise mode (2)
97-----------------------
98
99If the temperature is in the range defined by:
100
101pwm[1-5]_target_temp Target temperature, unit millidegree Celsius
102 (range 0 - 127000)
103pwm[1-5]_temp_tolerance
104 Target temperature tolerance, unit millidegree Celsius
105
106there are no changes to fan speed. Once the temperature leaves the interval, fan
107speed increases (if temperature is higher that desired) or decreases (if
108temperature is lower than desired), using the following limits and time
109intervals.
110
111pwm[1-5]_start fan pwm start value (range 1 - 255), to start fan
112 when the temperature is above defined range.
113pwm[1-5]_floor lowest fan pwm (range 0 - 255) if temperature is below
114 the defined range. If set to 0, the fan is expected to
115 stop if the temperature is below the defined range.
116pwm[1-5]_step_up_time milliseconds before fan speed is increased
117pwm[1-5]_step_down_time milliseconds before fan speed is decreased
118pwm[1-5]_stop_time how many milliseconds must elapse to switch
119 corresponding fan off (when the temperature was below
120 defined range).
121
122Speed Cruise mode (3)
123---------------------
124
125This modes tries to keep the fan speed constant.
126
127fan[1-5]_target Target fan speed
128fan[1-5]_tolerance
129 Target speed tolerance
130
131
132Untested; use at your own risk.
133
134Smart Fan IV mode (5)
135---------------------
136
137This mode offers multiple slopes to control the fan speed. The slopes can be
138controlled by setting the pwm and temperature attributes. When the temperature
139rises, the chip will calculate the DC/PWM output based on the current slope.
140There are up to seven data points depending on the chip type. Subsequent data
141points should be set to higher temperatures and higher pwm values to achieve
142higher fan speeds with increasing temperature. The last data point reflects
143critical temperature mode, in which the fans should run at full speed.
144
145pwm[1-5]_auto_point[1-7]_pwm
146 pwm value to be set if temperature reaches matching
147 temperature range.
148pwm[1-5]_auto_point[1-7]_temp
149 Temperature over which the matching pwm is enabled.
150pwm[1-5]_temp_tolerance
151 Temperature tolerance, unit millidegree Celsius
152pwm[1-5]_crit_temp_tolerance
153 Temperature tolerance for critical temperature,
154 unit millidegree Celsius
155
156pwm[1-5]_step_up_time milliseconds before fan speed is increased
157pwm[1-5]_step_down_time milliseconds before fan speed is decreased
158
90Usage Notes 159Usage Notes
91----------- 160-----------
92 161
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index ad4ecc04e239..47b1d8947e4d 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -215,8 +215,23 @@ static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
215static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 }; 215static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 };
216static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 }; 216static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 };
217 217
218static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302, 0x802, 0x902 }; 218/* Advanced Fan control, some values are common for all fans */
219 219
220static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301, 0x801, 0x901 };
221static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302, 0x802, 0x902 };
222static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = {
223 0x103, 0x203, 0x303, 0x803, 0x903 };
224static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = {
225 0x104, 0x204, 0x304, 0x804, 0x904 };
226static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = {
227 0x105, 0x205, 0x305, 0x805, 0x905 };
228static const u16 NCT6775_REG_FAN_START_OUTPUT[]
229 = { 0x106, 0x206, 0x306, 0x806, 0x906 };
230static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
231static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
232
233static const u16 NCT6775_REG_FAN_STOP_TIME[] = {
234 0x107, 0x207, 0x307, 0x807, 0x907 };
220static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309, 0x809, 0x909 }; 235static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309, 0x809, 0x909 };
221static const u16 NCT6775_REG_PWM_READ[] = { 0x01, 0x03, 0x11, 0x13, 0x15 }; 236static const u16 NCT6775_REG_PWM_READ[] = { 0x01, 0x03, 0x11, 0x13, 0x15 };
222 237
@@ -237,8 +252,26 @@ static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
237static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = { 252static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
238 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 }; 253 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 };
239 254
255static const u16 NCT6775_REG_TEMP_SEL[] = {
256 0x100, 0x200, 0x300, 0x800, 0x900 };
257
240static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; 258static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 };
241 259
260static const u16 NCT6775_REG_AUTO_TEMP[] = {
261 0x121, 0x221, 0x321, 0x821, 0x921 };
262static const u16 NCT6775_REG_AUTO_PWM[] = {
263 0x127, 0x227, 0x327, 0x827, 0x927 };
264
265#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p))
266#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p))
267
268static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 };
269
270static const u16 NCT6775_REG_CRITICAL_TEMP[] = {
271 0x135, 0x235, 0x335, 0x835, 0x935 };
272static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = {
273 0x138, 0x238, 0x338, 0x838, 0x938 };
274
242static const char *const nct6775_temp_label[] = { 275static const char *const nct6775_temp_label[] = {
243 "", 276 "",
244 "SYSTIN", 277 "SYSTIN",
@@ -281,6 +314,9 @@ static const s8 NCT6776_ALARM_BITS[] = {
281 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ 314 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
282 12, 9 }; /* intrusion0, intrusion1 */ 315 12, 9 }; /* intrusion0, intrusion1 */
283 316
317static const u16 NCT6776_REG_TOLERANCE_H[] = {
318 0x10c, 0x20c, 0x30c, 0x80c, 0x90c };
319
284static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0 }; 320static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0 };
285static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 }; 321static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 };
286 322
@@ -344,6 +380,11 @@ static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 };
344static const u16 NCT6779_REG_FAN_PULSES[] = { 380static const u16 NCT6779_REG_FAN_PULSES[] = {
345 0x644, 0x645, 0x646, 0x647, 0x648 }; 381 0x644, 0x645, 0x646, 0x647, 0x648 };
346 382
383static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
384 0x136, 0x236, 0x336, 0x836, 0x936 };
385static const u16 NCT6779_REG_CRITICAL_PWM[] = {
386 0x137, 0x237, 0x337, 0x837, 0x937 };
387
347static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; 388static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
348static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = { 389static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
349 0x18, 0x152 }; 390 0x18, 0x152 };
@@ -412,6 +453,18 @@ static int pwm_enable_to_reg(enum pwm_enable mode)
412 * Conversions 453 * Conversions
413 */ 454 */
414 455
456/* 1 is DC mode, output in ms */
457static unsigned int step_time_from_reg(u8 reg, u8 mode)
458{
459 return mode ? 400 * reg : 100 * reg;
460}
461
462static u8 step_time_to_reg(unsigned int msec, u8 mode)
463{
464 return clamp_val((mode ? (msec + 200) / 400 :
465 (msec + 50) / 100), 1, 255);
466}
467
415static unsigned int fan_from_reg8(u16 reg, unsigned int divreg) 468static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
416{ 469{
417 if (reg == 0 || reg == 255) 470 if (reg == 0 || reg == 255)
@@ -444,6 +497,14 @@ static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
444 return 1350000U / (reg << divreg); 497 return 1350000U / (reg << divreg);
445} 498}
446 499
500static u16 fan_to_reg(u32 fan, unsigned int divreg)
501{
502 if (!fan)
503 return 0;
504
505 return (1350000U / fan) >> divreg;
506}
507
447static inline unsigned int 508static inline unsigned int
448div_from_reg(u8 reg) 509div_from_reg(u8 reg)
449{ 510{
@@ -498,18 +559,31 @@ struct nct6775_data {
498 const u16 *REG_VIN; 559 const u16 *REG_VIN;
499 const u16 *REG_IN_MINMAX[2]; 560 const u16 *REG_IN_MINMAX[2];
500 561
562 const u16 *REG_TARGET;
501 const u16 *REG_FAN; 563 const u16 *REG_FAN;
502 const u16 *REG_FAN_MODE; 564 const u16 *REG_FAN_MODE;
503 const u16 *REG_FAN_MIN; 565 const u16 *REG_FAN_MIN;
504 const u16 *REG_FAN_PULSES; 566 const u16 *REG_FAN_PULSES;
567 const u16 *REG_FAN_TIME[3];
568
569 const u16 *REG_TOLERANCE_H;
505 570
506 const u8 *REG_PWM_MODE; 571 const u8 *REG_PWM_MODE;
507 const u8 *PWM_MODE_MASK; 572 const u8 *PWM_MODE_MASK;
508 573
509 const u16 *REG_PWM[1]; /* [0]=pwm */ 574 const u16 *REG_PWM[5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
575 * [3]=pwm_max, [4]=pwm_step
576 */
510 const u16 *REG_PWM_READ; 577 const u16 *REG_PWM_READ;
511 578
579 const u16 *REG_AUTO_TEMP;
580 const u16 *REG_AUTO_PWM;
581
582 const u16 *REG_CRITICAL_TEMP;
583 const u16 *REG_CRITICAL_TEMP_TOLERANCE;
584
512 const u16 *REG_TEMP_SOURCE; /* temp register sources */ 585 const u16 *REG_TEMP_SOURCE; /* temp register sources */
586 const u16 *REG_TEMP_SEL;
513 const u16 *REG_TEMP_OFFSET; 587 const u16 *REG_TEMP_OFFSET;
514 588
515 const u16 *REG_ALARM; 589 const u16 *REG_ALARM;
@@ -551,7 +625,26 @@ struct nct6775_data {
551 * 4->SmartFan III 625 * 4->SmartFan III
552 * 5->enhanced variable thermal cruise (SmartFan IV) 626 * 5->enhanced variable thermal cruise (SmartFan IV)
553 */ 627 */
554 u8 pwm[1][5]; /* [0]=pwm */ 628 u8 pwm[5][5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
629 * [3]=pwm_max, [4]=pwm_step
630 */
631
632 u8 target_temp[5];
633 u8 target_temp_mask;
634 u32 target_speed[5];
635 u32 target_speed_tolerance[5];
636 u8 speed_tolerance_limit;
637
638 u8 temp_tolerance[2][5];
639 u8 tolerance_mask;
640
641 u8 fan_time[3][5]; /* 0 = stop_time, 1 = step_up, 2 = step_down */
642
643 /* Automatic fan speed control registers */
644 int auto_pwm_num;
645 u8 auto_pwm[5][7];
646 u8 auto_temp[5][7];
647 u8 pwm_temp_sel[5];
555 648
556 u8 vid; 649 u8 vid;
557 u8 vrm; 650 u8 vrm;
@@ -833,7 +926,7 @@ static void nct6775_update_pwm(struct device *dev)
833{ 926{
834 struct nct6775_data *data = dev_get_drvdata(dev); 927 struct nct6775_data *data = dev_get_drvdata(dev);
835 int i, j; 928 int i, j;
836 int fanmodecfg; 929 int fanmodecfg, reg;
837 bool duty_is_dc; 930 bool duty_is_dc;
838 931
839 for (i = 0; i < data->pwm_num; i++) { 932 for (i = 0; i < data->pwm_num; i++) {
@@ -856,6 +949,96 @@ static void nct6775_update_pwm(struct device *dev)
856 949
857 data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i], 950 data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
858 (fanmodecfg >> 4) & 7); 951 (fanmodecfg >> 4) & 7);
952
953 if (!data->temp_tolerance[0][i] ||
954 data->pwm_enable[i] != speed_cruise)
955 data->temp_tolerance[0][i] = fanmodecfg & 0x0f;
956 if (!data->target_speed_tolerance[i] ||
957 data->pwm_enable[i] == speed_cruise) {
958 u8 t = fanmodecfg & 0x0f;
959 if (data->REG_TOLERANCE_H) {
960 t |= (nct6775_read_value(data,
961 data->REG_TOLERANCE_H[i]) & 0x70) >> 1;
962 }
963 data->target_speed_tolerance[i] = t;
964 }
965
966 data->temp_tolerance[1][i] =
967 nct6775_read_value(data,
968 data->REG_CRITICAL_TEMP_TOLERANCE[i]);
969
970 reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]);
971 data->pwm_temp_sel[i] = reg & 0x1f;
972 /* If fan can stop, report floor as 0 */
973 if (reg & 0x80)
974 data->pwm[2][i] = 0;
975 }
976}
977
978static void nct6775_update_pwm_limits(struct device *dev)
979{
980 struct nct6775_data *data = dev_get_drvdata(dev);
981 int i, j;
982 u8 reg;
983 u16 reg_t;
984
985 for (i = 0; i < data->pwm_num; i++) {
986 if (!(data->has_pwm & (1 << i)))
987 continue;
988
989 for (j = 0; j < 3; j++) {
990 data->fan_time[j][i] =
991 nct6775_read_value(data, data->REG_FAN_TIME[j][i]);
992 }
993
994 reg_t = nct6775_read_value(data, data->REG_TARGET[i]);
995 /* Update only in matching mode or if never updated */
996 if (!data->target_temp[i] ||
997 data->pwm_enable[i] == thermal_cruise)
998 data->target_temp[i] = reg_t & data->target_temp_mask;
999 if (!data->target_speed[i] ||
1000 data->pwm_enable[i] == speed_cruise) {
1001 if (data->REG_TOLERANCE_H) {
1002 reg_t |= (nct6775_read_value(data,
1003 data->REG_TOLERANCE_H[i]) & 0x0f) << 8;
1004 }
1005 data->target_speed[i] = reg_t;
1006 }
1007
1008 for (j = 0; j < data->auto_pwm_num; j++) {
1009 data->auto_pwm[i][j] =
1010 nct6775_read_value(data,
1011 NCT6775_AUTO_PWM(data, i, j));
1012 data->auto_temp[i][j] =
1013 nct6775_read_value(data,
1014 NCT6775_AUTO_TEMP(data, i, j));
1015 }
1016
1017 /* critical auto_pwm temperature data */
1018 data->auto_temp[i][data->auto_pwm_num] =
1019 nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]);
1020
1021 switch (data->kind) {
1022 case nct6775:
1023 reg = nct6775_read_value(data,
1024 NCT6775_REG_CRITICAL_ENAB[i]);
1025 data->auto_pwm[i][data->auto_pwm_num] =
1026 (reg & 0x02) ? 0xff : 0x00;
1027 break;
1028 case nct6776:
1029 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1030 break;
1031 case nct6779:
1032 reg = nct6775_read_value(data,
1033 NCT6779_REG_CRITICAL_PWM_ENABLE[i]);
1034 if (reg & 1)
1035 data->auto_pwm[i][data->auto_pwm_num] =
1036 nct6775_read_value(data,
1037 NCT6779_REG_CRITICAL_PWM[i]);
1038 else
1039 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1040 break;
1041 }
859 } 1042 }
860} 1043}
861 1044
@@ -905,6 +1088,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
905 } 1088 }
906 1089
907 nct6775_update_pwm(dev); 1090 nct6775_update_pwm(dev);
1091 nct6775_update_pwm_limits(dev);
908 1092
909 /* Measured temperatures and limits */ 1093 /* Measured temperatures and limits */
910 for (i = 0; i < NUM_TEMP; i++) { 1094 for (i = 0; i < NUM_TEMP; i++) {
@@ -1754,20 +1938,91 @@ store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
1754 int nr = sattr->nr; 1938 int nr = sattr->nr;
1755 int index = sattr->index; 1939 int index = sattr->index;
1756 unsigned long val; 1940 unsigned long val;
1941 int minval[5] = { 0, 1, 1, data->pwm[2][nr], 0 };
1942 int maxval[5]
1943 = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255 };
1757 int err; 1944 int err;
1945 u8 reg;
1758 1946
1759 err = kstrtoul(buf, 10, &val); 1947 err = kstrtoul(buf, 10, &val);
1760 if (err < 0) 1948 if (err < 0)
1761 return err; 1949 return err;
1762 val = clamp_val(val, 0, 255); 1950 val = clamp_val(val, minval[index], maxval[index]);
1763 1951
1764 mutex_lock(&data->update_lock); 1952 mutex_lock(&data->update_lock);
1765 data->pwm[index][nr] = val; 1953 data->pwm[index][nr] = val;
1766 nct6775_write_value(data, data->REG_PWM[index][nr], val); 1954 nct6775_write_value(data, data->REG_PWM[index][nr], val);
1955 if (index == 2) { /* floor: disable if val == 0 */
1956 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
1957 reg &= 0x7f;
1958 if (val)
1959 reg |= 0x80;
1960 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
1961 }
1767 mutex_unlock(&data->update_lock); 1962 mutex_unlock(&data->update_lock);
1768 return count; 1963 return count;
1769} 1964}
1770 1965
1966/* Returns 0 if OK, -EINVAL otherwise */
1967static int check_trip_points(struct nct6775_data *data, int nr)
1968{
1969 int i;
1970
1971 for (i = 0; i < data->auto_pwm_num - 1; i++) {
1972 if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
1973 return -EINVAL;
1974 }
1975 for (i = 0; i < data->auto_pwm_num - 1; i++) {
1976 if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
1977 return -EINVAL;
1978 }
1979 /* validate critical temperature and pwm if enabled (pwm > 0) */
1980 if (data->auto_pwm[nr][data->auto_pwm_num]) {
1981 if (data->auto_temp[nr][data->auto_pwm_num - 1] >
1982 data->auto_temp[nr][data->auto_pwm_num] ||
1983 data->auto_pwm[nr][data->auto_pwm_num - 1] >
1984 data->auto_pwm[nr][data->auto_pwm_num])
1985 return -EINVAL;
1986 }
1987 return 0;
1988}
1989
1990static void pwm_update_registers(struct nct6775_data *data, int nr)
1991{
1992 u8 reg;
1993
1994 switch (data->pwm_enable[nr]) {
1995 case off:
1996 case manual:
1997 break;
1998 case speed_cruise:
1999 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2000 reg = (reg & ~data->tolerance_mask) |
2001 (data->target_speed_tolerance[nr] & data->tolerance_mask);
2002 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2003 nct6775_write_value(data, data->REG_TARGET[nr],
2004 data->target_speed[nr] & 0xff);
2005 if (data->REG_TOLERANCE_H) {
2006 reg = (data->target_speed[nr] >> 8) & 0x0f;
2007 reg |= (data->target_speed_tolerance[nr] & 0x38) << 1;
2008 nct6775_write_value(data,
2009 data->REG_TOLERANCE_H[nr],
2010 reg);
2011 }
2012 break;
2013 case thermal_cruise:
2014 nct6775_write_value(data, data->REG_TARGET[nr],
2015 data->target_temp[nr]);
2016 /* intentional */
2017 default:
2018 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2019 reg = (reg & ~data->tolerance_mask) |
2020 data->temp_tolerance[0][nr];
2021 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2022 break;
2023 }
2024}
2025
1771static ssize_t 2026static ssize_t
1772show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) 2027show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
1773{ 2028{
@@ -1798,6 +2053,12 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
1798 if (val == sf3 && data->kind != nct6775) 2053 if (val == sf3 && data->kind != nct6775)
1799 return -EINVAL; 2054 return -EINVAL;
1800 2055
2056 if (val == sf4 && check_trip_points(data, nr)) {
2057 dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n");
2058 dev_err(dev, "Adjust trip points and try again\n");
2059 return -EINVAL;
2060 }
2061
1801 mutex_lock(&data->update_lock); 2062 mutex_lock(&data->update_lock);
1802 data->pwm_enable[nr] = val; 2063 data->pwm_enable[nr] = val;
1803 if (val == off) { 2064 if (val == off) {
@@ -1807,6 +2068,7 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
1807 data->pwm[0][nr] = 255; 2068 data->pwm[0][nr] = 255;
1808 nct6775_write_value(data, data->REG_PWM[0][nr], 255); 2069 nct6775_write_value(data, data->REG_PWM[0][nr], 255);
1809 } 2070 }
2071 pwm_update_registers(data, nr);
1810 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]); 2072 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
1811 reg &= 0x0f; 2073 reg &= 0x0f;
1812 reg |= pwm_enable_to_reg(val) << 4; 2074 reg |= pwm_enable_to_reg(val) << 4;
@@ -1815,6 +2077,235 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
1815 return count; 2077 return count;
1816} 2078}
1817 2079
2080static ssize_t
2081show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf)
2082{
2083 struct nct6775_data *data = nct6775_update_device(dev);
2084 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2085 int i, src, sel = 0;
2086
2087 src = data->pwm_temp_sel[sattr->index];
2088
2089 for (i = 0; i < NUM_TEMP; i++) {
2090 if (!(data->have_temp & (1 << i)))
2091 continue;
2092 if (src == data->temp_src[i]) {
2093 sel = i + 1;
2094 break;
2095 }
2096 }
2097
2098 return sprintf(buf, "%d\n", sel);
2099}
2100
2101static ssize_t
2102store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
2103 const char *buf, size_t count)
2104{
2105 struct nct6775_data *data = nct6775_update_device(dev);
2106 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2107 int nr = sattr->index;
2108 unsigned long val;
2109 int err, reg, src;
2110
2111 err = kstrtoul(buf, 10, &val);
2112 if (err < 0)
2113 return err;
2114 if (val == 0 || val > NUM_TEMP)
2115 return -EINVAL;
2116 if (!(data->have_temp & (1 << (val - 1))) || !data->temp_src[val - 1])
2117 return -EINVAL;
2118
2119 mutex_lock(&data->update_lock);
2120 src = data->temp_src[val - 1];
2121 data->pwm_temp_sel[nr] = src;
2122 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
2123 reg &= 0xe0;
2124 reg |= src;
2125 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
2126 mutex_unlock(&data->update_lock);
2127
2128 return count;
2129}
2130
2131static ssize_t
2132show_target_temp(struct device *dev, struct device_attribute *attr, char *buf)
2133{
2134 struct nct6775_data *data = nct6775_update_device(dev);
2135 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2136
2137 return sprintf(buf, "%d\n", data->target_temp[sattr->index] * 1000);
2138}
2139
2140static ssize_t
2141store_target_temp(struct device *dev, struct device_attribute *attr,
2142 const char *buf, size_t count)
2143{
2144 struct nct6775_data *data = dev_get_drvdata(dev);
2145 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2146 int nr = sattr->index;
2147 unsigned long val;
2148 int err;
2149
2150 err = kstrtoul(buf, 10, &val);
2151 if (err < 0)
2152 return err;
2153
2154 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0,
2155 data->target_temp_mask);
2156
2157 mutex_lock(&data->update_lock);
2158 data->target_temp[nr] = val;
2159 pwm_update_registers(data, nr);
2160 mutex_unlock(&data->update_lock);
2161 return count;
2162}
2163
2164static ssize_t
2165show_target_speed(struct device *dev, struct device_attribute *attr, char *buf)
2166{
2167 struct nct6775_data *data = nct6775_update_device(dev);
2168 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2169 int nr = sattr->index;
2170
2171 return sprintf(buf, "%d\n",
2172 fan_from_reg16(data->target_speed[nr],
2173 data->fan_div[nr]));
2174}
2175
2176static ssize_t
2177store_target_speed(struct device *dev, struct device_attribute *attr,
2178 const char *buf, size_t count)
2179{
2180 struct nct6775_data *data = dev_get_drvdata(dev);
2181 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2182 int nr = sattr->index;
2183 unsigned long val;
2184 int err;
2185 u16 speed;
2186
2187 err = kstrtoul(buf, 10, &val);
2188 if (err < 0)
2189 return err;
2190
2191 val = clamp_val(val, 0, 1350000U);
2192 speed = fan_to_reg(val, data->fan_div[nr]);
2193
2194 mutex_lock(&data->update_lock);
2195 data->target_speed[nr] = speed;
2196 pwm_update_registers(data, nr);
2197 mutex_unlock(&data->update_lock);
2198 return count;
2199}
2200
2201static ssize_t
2202show_temp_tolerance(struct device *dev, struct device_attribute *attr,
2203 char *buf)
2204{
2205 struct nct6775_data *data = nct6775_update_device(dev);
2206 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2207 int nr = sattr->nr;
2208 int index = sattr->index;
2209
2210 return sprintf(buf, "%d\n", data->temp_tolerance[index][nr] * 1000);
2211}
2212
2213static ssize_t
2214store_temp_tolerance(struct device *dev, struct device_attribute *attr,
2215 const char *buf, size_t count)
2216{
2217 struct nct6775_data *data = dev_get_drvdata(dev);
2218 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2219 int nr = sattr->nr;
2220 int index = sattr->index;
2221 unsigned long val;
2222 int err;
2223
2224 err = kstrtoul(buf, 10, &val);
2225 if (err < 0)
2226 return err;
2227
2228 /* Limit tolerance as needed */
2229 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask);
2230
2231 mutex_lock(&data->update_lock);
2232 data->temp_tolerance[index][nr] = val;
2233 if (index)
2234 pwm_update_registers(data, nr);
2235 else
2236 nct6775_write_value(data,
2237 data->REG_CRITICAL_TEMP_TOLERANCE[nr],
2238 val);
2239 mutex_unlock(&data->update_lock);
2240 return count;
2241}
2242
2243/*
2244 * Fan speed tolerance is a tricky beast, since the associated register is
2245 * a tick counter, but the value is reported and configured as rpm.
2246 * Compute resulting low and high rpm values and report the difference.
2247 */
2248static ssize_t
2249show_speed_tolerance(struct device *dev, struct device_attribute *attr,
2250 char *buf)
2251{
2252 struct nct6775_data *data = nct6775_update_device(dev);
2253 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2254 int nr = sattr->index;
2255 int low = data->target_speed[nr] - data->target_speed_tolerance[nr];
2256 int high = data->target_speed[nr] + data->target_speed_tolerance[nr];
2257 int tolerance;
2258
2259 if (low <= 0)
2260 low = 1;
2261 if (high > 0xffff)
2262 high = 0xffff;
2263 if (high < low)
2264 high = low;
2265
2266 tolerance = (fan_from_reg16(low, data->fan_div[nr])
2267 - fan_from_reg16(high, data->fan_div[nr])) / 2;
2268
2269 return sprintf(buf, "%d\n", tolerance);
2270}
2271
2272static ssize_t
2273store_speed_tolerance(struct device *dev, struct device_attribute *attr,
2274 const char *buf, size_t count)
2275{
2276 struct nct6775_data *data = dev_get_drvdata(dev);
2277 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2278 int nr = sattr->index;
2279 unsigned long val;
2280 int err;
2281 int low, high;
2282
2283 err = kstrtoul(buf, 10, &val);
2284 if (err < 0)
2285 return err;
2286
2287 high = fan_from_reg16(data->target_speed[nr],
2288 data->fan_div[nr]) + val;
2289 low = fan_from_reg16(data->target_speed[nr],
2290 data->fan_div[nr]) - val;
2291 if (low <= 0)
2292 low = 1;
2293 if (high < low)
2294 high = low;
2295
2296 val = (fan_to_reg(low, data->fan_div[nr]) -
2297 fan_to_reg(high, data->fan_div[nr])) / 2;
2298
2299 /* Limit tolerance as needed */
2300 val = clamp_val(val, 0, data->speed_tolerance_limit);
2301
2302 mutex_lock(&data->update_lock);
2303 data->target_speed_tolerance[nr] = val;
2304 pwm_update_registers(data, nr);
2305 mutex_unlock(&data->update_lock);
2306 return count;
2307}
2308
1818static SENSOR_DEVICE_ATTR_2(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0); 2309static 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); 2310static 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); 2311static SENSOR_DEVICE_ATTR_2(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 0);
@@ -1843,6 +2334,88 @@ static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
1843static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_enable, 2334static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
1844 store_pwm_enable, 4); 2335 store_pwm_enable, 4);
1845 2336
2337static SENSOR_DEVICE_ATTR(pwm1_temp_sel, S_IWUSR | S_IRUGO,
2338 show_pwm_temp_sel, store_pwm_temp_sel, 0);
2339static SENSOR_DEVICE_ATTR(pwm2_temp_sel, S_IWUSR | S_IRUGO,
2340 show_pwm_temp_sel, store_pwm_temp_sel, 1);
2341static SENSOR_DEVICE_ATTR(pwm3_temp_sel, S_IWUSR | S_IRUGO,
2342 show_pwm_temp_sel, store_pwm_temp_sel, 2);
2343static SENSOR_DEVICE_ATTR(pwm4_temp_sel, S_IWUSR | S_IRUGO,
2344 show_pwm_temp_sel, store_pwm_temp_sel, 3);
2345static SENSOR_DEVICE_ATTR(pwm5_temp_sel, S_IWUSR | S_IRUGO,
2346 show_pwm_temp_sel, store_pwm_temp_sel, 4);
2347
2348static SENSOR_DEVICE_ATTR(pwm1_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2349 store_target_temp, 0);
2350static SENSOR_DEVICE_ATTR(pwm2_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2351 store_target_temp, 1);
2352static SENSOR_DEVICE_ATTR(pwm3_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2353 store_target_temp, 2);
2354static SENSOR_DEVICE_ATTR(pwm4_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2355 store_target_temp, 3);
2356static SENSOR_DEVICE_ATTR(pwm5_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2357 store_target_temp, 4);
2358
2359static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, show_target_speed,
2360 store_target_speed, 0);
2361static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, show_target_speed,
2362 store_target_speed, 1);
2363static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, show_target_speed,
2364 store_target_speed, 2);
2365static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, show_target_speed,
2366 store_target_speed, 3);
2367static SENSOR_DEVICE_ATTR(fan5_target, S_IWUSR | S_IRUGO, show_target_speed,
2368 store_target_speed, 4);
2369
2370static SENSOR_DEVICE_ATTR(fan1_tolerance, S_IWUSR | S_IRUGO,
2371 show_speed_tolerance, store_speed_tolerance, 0);
2372static SENSOR_DEVICE_ATTR(fan2_tolerance, S_IWUSR | S_IRUGO,
2373 show_speed_tolerance, store_speed_tolerance, 1);
2374static SENSOR_DEVICE_ATTR(fan3_tolerance, S_IWUSR | S_IRUGO,
2375 show_speed_tolerance, store_speed_tolerance, 2);
2376static SENSOR_DEVICE_ATTR(fan4_tolerance, S_IWUSR | S_IRUGO,
2377 show_speed_tolerance, store_speed_tolerance, 3);
2378static SENSOR_DEVICE_ATTR(fan5_tolerance, S_IWUSR | S_IRUGO,
2379 show_speed_tolerance, store_speed_tolerance, 4);
2380
2381/* Smart Fan registers */
2382
2383static ssize_t
2384show_fan_time(struct device *dev, struct device_attribute *attr, char *buf)
2385{
2386 struct nct6775_data *data = nct6775_update_device(dev);
2387 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2388 int nr = sattr->nr;
2389 int index = sattr->index;
2390
2391 return sprintf(buf, "%d\n",
2392 step_time_from_reg(data->fan_time[index][nr],
2393 data->pwm_mode[nr]));
2394}
2395
2396static ssize_t
2397store_fan_time(struct device *dev, struct device_attribute *attr,
2398 const char *buf, size_t count)
2399{
2400 struct nct6775_data *data = dev_get_drvdata(dev);
2401 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2402 int nr = sattr->nr;
2403 int index = sattr->index;
2404 unsigned long val;
2405 int err;
2406
2407 err = kstrtoul(buf, 10, &val);
2408 if (err < 0)
2409 return err;
2410
2411 val = step_time_to_reg(val, data->pwm_mode[nr]);
2412 mutex_lock(&data->update_lock);
2413 data->fan_time[index][nr] = val;
2414 nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
2415 mutex_unlock(&data->update_lock);
2416 return count;
2417}
2418
1846static ssize_t 2419static ssize_t
1847show_name(struct device *dev, struct device_attribute *attr, char *buf) 2420show_name(struct device *dev, struct device_attribute *attr, char *buf)
1848{ 2421{
@@ -1853,35 +2426,190 @@ show_name(struct device *dev, struct device_attribute *attr, char *buf)
1853 2426
1854static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 2427static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
1855 2428
1856static struct attribute *nct6775_attributes_pwm[5][4] = { 2429static SENSOR_DEVICE_ATTR_2(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2430 store_fan_time, 0, 0);
2431static SENSOR_DEVICE_ATTR_2(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2432 store_fan_time, 1, 0);
2433static SENSOR_DEVICE_ATTR_2(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2434 store_fan_time, 2, 0);
2435static SENSOR_DEVICE_ATTR_2(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2436 store_fan_time, 3, 0);
2437static SENSOR_DEVICE_ATTR_2(pwm5_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2438 store_fan_time, 4, 0);
2439
2440static SENSOR_DEVICE_ATTR_2(pwm1_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2441 store_fan_time, 0, 1);
2442static SENSOR_DEVICE_ATTR_2(pwm2_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2443 store_fan_time, 1, 1);
2444static SENSOR_DEVICE_ATTR_2(pwm3_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2445 store_fan_time, 2, 1);
2446static SENSOR_DEVICE_ATTR_2(pwm4_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2447 store_fan_time, 3, 1);
2448static SENSOR_DEVICE_ATTR_2(pwm5_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2449 store_fan_time, 4, 1);
2450
2451static SENSOR_DEVICE_ATTR_2(pwm1_step_down_time, S_IWUSR | S_IRUGO,
2452 show_fan_time, store_fan_time, 0, 2);
2453static SENSOR_DEVICE_ATTR_2(pwm2_step_down_time, S_IWUSR | S_IRUGO,
2454 show_fan_time, store_fan_time, 1, 2);
2455static SENSOR_DEVICE_ATTR_2(pwm3_step_down_time, S_IWUSR | S_IRUGO,
2456 show_fan_time, store_fan_time, 2, 2);
2457static SENSOR_DEVICE_ATTR_2(pwm4_step_down_time, S_IWUSR | S_IRUGO,
2458 show_fan_time, store_fan_time, 3, 2);
2459static SENSOR_DEVICE_ATTR_2(pwm5_step_down_time, S_IWUSR | S_IRUGO,
2460 show_fan_time, store_fan_time, 4, 2);
2461
2462static SENSOR_DEVICE_ATTR_2(pwm1_start, S_IWUSR | S_IRUGO, show_pwm,
2463 store_pwm, 0, 1);
2464static SENSOR_DEVICE_ATTR_2(pwm2_start, S_IWUSR | S_IRUGO, show_pwm,
2465 store_pwm, 1, 1);
2466static SENSOR_DEVICE_ATTR_2(pwm3_start, S_IWUSR | S_IRUGO, show_pwm,
2467 store_pwm, 2, 1);
2468static SENSOR_DEVICE_ATTR_2(pwm4_start, S_IWUSR | S_IRUGO, show_pwm,
2469 store_pwm, 3, 1);
2470static SENSOR_DEVICE_ATTR_2(pwm5_start, S_IWUSR | S_IRUGO, show_pwm,
2471 store_pwm, 4, 1);
2472
2473static SENSOR_DEVICE_ATTR_2(pwm1_floor, S_IWUSR | S_IRUGO, show_pwm,
2474 store_pwm, 0, 2);
2475static SENSOR_DEVICE_ATTR_2(pwm2_floor, S_IWUSR | S_IRUGO, show_pwm,
2476 store_pwm, 1, 2);
2477static SENSOR_DEVICE_ATTR_2(pwm3_floor, S_IWUSR | S_IRUGO, show_pwm,
2478 store_pwm, 2, 2);
2479static SENSOR_DEVICE_ATTR_2(pwm4_floor, S_IWUSR | S_IRUGO, show_pwm,
2480 store_pwm, 3, 2);
2481static SENSOR_DEVICE_ATTR_2(pwm5_floor, S_IWUSR | S_IRUGO, show_pwm,
2482 store_pwm, 4, 2);
2483
2484static SENSOR_DEVICE_ATTR_2(pwm1_temp_tolerance, S_IWUSR | S_IRUGO,
2485 show_temp_tolerance, store_temp_tolerance, 0, 0);
2486static SENSOR_DEVICE_ATTR_2(pwm2_temp_tolerance, S_IWUSR | S_IRUGO,
2487 show_temp_tolerance, store_temp_tolerance, 1, 0);
2488static SENSOR_DEVICE_ATTR_2(pwm3_temp_tolerance, S_IWUSR | S_IRUGO,
2489 show_temp_tolerance, store_temp_tolerance, 2, 0);
2490static SENSOR_DEVICE_ATTR_2(pwm4_temp_tolerance, S_IWUSR | S_IRUGO,
2491 show_temp_tolerance, store_temp_tolerance, 3, 0);
2492static SENSOR_DEVICE_ATTR_2(pwm5_temp_tolerance, S_IWUSR | S_IRUGO,
2493 show_temp_tolerance, store_temp_tolerance, 4, 0);
2494
2495static SENSOR_DEVICE_ATTR_2(pwm1_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2496 show_temp_tolerance, store_temp_tolerance, 0, 1);
2497static SENSOR_DEVICE_ATTR_2(pwm2_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2498 show_temp_tolerance, store_temp_tolerance, 1, 1);
2499static SENSOR_DEVICE_ATTR_2(pwm3_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2500 show_temp_tolerance, store_temp_tolerance, 2, 1);
2501static SENSOR_DEVICE_ATTR_2(pwm4_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2502 show_temp_tolerance, store_temp_tolerance, 3, 1);
2503static SENSOR_DEVICE_ATTR_2(pwm5_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2504 show_temp_tolerance, store_temp_tolerance, 4, 1);
2505
2506/* pwm_max is not supported on all chips */
2507static struct sensor_device_attribute_2 sda_pwm_max[] = {
2508 SENSOR_ATTR_2(pwm1_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2509 0, 3),
2510 SENSOR_ATTR_2(pwm2_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2511 1, 3),
2512 SENSOR_ATTR_2(pwm3_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2513 2, 3),
2514 SENSOR_ATTR_2(pwm4_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2515 3, 3),
2516 SENSOR_ATTR_2(pwm5_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2517 4, 3),
2518};
2519
2520/* pwm_step is not supported on all chips */
2521static struct sensor_device_attribute_2 sda_pwm_step[] = {
2522 SENSOR_ATTR_2(pwm1_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 4),
2523 SENSOR_ATTR_2(pwm2_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 4),
2524 SENSOR_ATTR_2(pwm3_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 4),
2525 SENSOR_ATTR_2(pwm4_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 4),
2526 SENSOR_ATTR_2(pwm5_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 4),
2527};
2528
2529static struct attribute *nct6775_attributes_pwm[5][15] = {
1857 { 2530 {
1858 &sensor_dev_attr_pwm1.dev_attr.attr, 2531 &sensor_dev_attr_pwm1.dev_attr.attr,
1859 &sensor_dev_attr_pwm1_mode.dev_attr.attr, 2532 &sensor_dev_attr_pwm1_mode.dev_attr.attr,
1860 &sensor_dev_attr_pwm1_enable.dev_attr.attr, 2533 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
2534 &sensor_dev_attr_pwm1_temp_sel.dev_attr.attr,
2535 &sensor_dev_attr_pwm1_temp_tolerance.dev_attr.attr,
2536 &sensor_dev_attr_pwm1_crit_temp_tolerance.dev_attr.attr,
2537 &sensor_dev_attr_pwm1_target_temp.dev_attr.attr,
2538 &sensor_dev_attr_fan1_target.dev_attr.attr,
2539 &sensor_dev_attr_fan1_tolerance.dev_attr.attr,
2540 &sensor_dev_attr_pwm1_stop_time.dev_attr.attr,
2541 &sensor_dev_attr_pwm1_step_up_time.dev_attr.attr,
2542 &sensor_dev_attr_pwm1_step_down_time.dev_attr.attr,
2543 &sensor_dev_attr_pwm1_start.dev_attr.attr,
2544 &sensor_dev_attr_pwm1_floor.dev_attr.attr,
1861 NULL 2545 NULL
1862 }, 2546 },
1863 { 2547 {
1864 &sensor_dev_attr_pwm2.dev_attr.attr, 2548 &sensor_dev_attr_pwm2.dev_attr.attr,
1865 &sensor_dev_attr_pwm2_mode.dev_attr.attr, 2549 &sensor_dev_attr_pwm2_mode.dev_attr.attr,
1866 &sensor_dev_attr_pwm2_enable.dev_attr.attr, 2550 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
2551 &sensor_dev_attr_pwm2_temp_sel.dev_attr.attr,
2552 &sensor_dev_attr_pwm2_temp_tolerance.dev_attr.attr,
2553 &sensor_dev_attr_pwm2_crit_temp_tolerance.dev_attr.attr,
2554 &sensor_dev_attr_pwm2_target_temp.dev_attr.attr,
2555 &sensor_dev_attr_fan2_target.dev_attr.attr,
2556 &sensor_dev_attr_fan2_tolerance.dev_attr.attr,
2557 &sensor_dev_attr_pwm2_stop_time.dev_attr.attr,
2558 &sensor_dev_attr_pwm2_step_up_time.dev_attr.attr,
2559 &sensor_dev_attr_pwm2_step_down_time.dev_attr.attr,
2560 &sensor_dev_attr_pwm2_start.dev_attr.attr,
2561 &sensor_dev_attr_pwm2_floor.dev_attr.attr,
1867 NULL 2562 NULL
1868 }, 2563 },
1869 { 2564 {
1870 &sensor_dev_attr_pwm3.dev_attr.attr, 2565 &sensor_dev_attr_pwm3.dev_attr.attr,
1871 &sensor_dev_attr_pwm3_mode.dev_attr.attr, 2566 &sensor_dev_attr_pwm3_mode.dev_attr.attr,
1872 &sensor_dev_attr_pwm3_enable.dev_attr.attr, 2567 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
2568 &sensor_dev_attr_pwm3_temp_sel.dev_attr.attr,
2569 &sensor_dev_attr_pwm3_temp_tolerance.dev_attr.attr,
2570 &sensor_dev_attr_pwm3_crit_temp_tolerance.dev_attr.attr,
2571 &sensor_dev_attr_pwm3_target_temp.dev_attr.attr,
2572 &sensor_dev_attr_fan3_target.dev_attr.attr,
2573 &sensor_dev_attr_fan3_tolerance.dev_attr.attr,
2574 &sensor_dev_attr_pwm3_stop_time.dev_attr.attr,
2575 &sensor_dev_attr_pwm3_step_up_time.dev_attr.attr,
2576 &sensor_dev_attr_pwm3_step_down_time.dev_attr.attr,
2577 &sensor_dev_attr_pwm3_start.dev_attr.attr,
2578 &sensor_dev_attr_pwm3_floor.dev_attr.attr,
1873 NULL 2579 NULL
1874 }, 2580 },
1875 { 2581 {
1876 &sensor_dev_attr_pwm4.dev_attr.attr, 2582 &sensor_dev_attr_pwm4.dev_attr.attr,
1877 &sensor_dev_attr_pwm4_mode.dev_attr.attr, 2583 &sensor_dev_attr_pwm4_mode.dev_attr.attr,
1878 &sensor_dev_attr_pwm4_enable.dev_attr.attr, 2584 &sensor_dev_attr_pwm4_enable.dev_attr.attr,
2585 &sensor_dev_attr_pwm4_temp_sel.dev_attr.attr,
2586 &sensor_dev_attr_pwm4_temp_tolerance.dev_attr.attr,
2587 &sensor_dev_attr_pwm4_crit_temp_tolerance.dev_attr.attr,
2588 &sensor_dev_attr_pwm4_target_temp.dev_attr.attr,
2589 &sensor_dev_attr_fan4_target.dev_attr.attr,
2590 &sensor_dev_attr_fan4_tolerance.dev_attr.attr,
2591 &sensor_dev_attr_pwm4_stop_time.dev_attr.attr,
2592 &sensor_dev_attr_pwm4_step_up_time.dev_attr.attr,
2593 &sensor_dev_attr_pwm4_step_down_time.dev_attr.attr,
2594 &sensor_dev_attr_pwm4_start.dev_attr.attr,
2595 &sensor_dev_attr_pwm4_floor.dev_attr.attr,
1879 NULL 2596 NULL
1880 }, 2597 },
1881 { 2598 {
1882 &sensor_dev_attr_pwm5.dev_attr.attr, 2599 &sensor_dev_attr_pwm5.dev_attr.attr,
1883 &sensor_dev_attr_pwm5_mode.dev_attr.attr, 2600 &sensor_dev_attr_pwm5_mode.dev_attr.attr,
1884 &sensor_dev_attr_pwm5_enable.dev_attr.attr, 2601 &sensor_dev_attr_pwm5_enable.dev_attr.attr,
2602 &sensor_dev_attr_pwm5_temp_sel.dev_attr.attr,
2603 &sensor_dev_attr_pwm5_temp_tolerance.dev_attr.attr,
2604 &sensor_dev_attr_pwm5_crit_temp_tolerance.dev_attr.attr,
2605 &sensor_dev_attr_pwm5_target_temp.dev_attr.attr,
2606 &sensor_dev_attr_fan5_target.dev_attr.attr,
2607 &sensor_dev_attr_fan5_tolerance.dev_attr.attr,
2608 &sensor_dev_attr_pwm5_stop_time.dev_attr.attr,
2609 &sensor_dev_attr_pwm5_step_up_time.dev_attr.attr,
2610 &sensor_dev_attr_pwm5_step_down_time.dev_attr.attr,
2611 &sensor_dev_attr_pwm5_start.dev_attr.attr,
2612 &sensor_dev_attr_pwm5_floor.dev_attr.attr,
1885 NULL 2613 NULL
1886 }, 2614 },
1887}; 2615};
@@ -1895,6 +2623,277 @@ static const struct attribute_group nct6775_group_pwm[5] = {
1895}; 2623};
1896 2624
1897static ssize_t 2625static ssize_t
2626show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
2627{
2628 struct nct6775_data *data = nct6775_update_device(dev);
2629 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2630
2631 return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]);
2632}
2633
2634static ssize_t
2635store_auto_pwm(struct device *dev, struct device_attribute *attr,
2636 const char *buf, size_t count)
2637{
2638 struct nct6775_data *data = dev_get_drvdata(dev);
2639 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2640 int nr = sattr->nr;
2641 int point = sattr->index;
2642 unsigned long val;
2643 int err;
2644 u8 reg;
2645
2646 err = kstrtoul(buf, 10, &val);
2647 if (err < 0)
2648 return err;
2649 if (val > 255)
2650 return -EINVAL;
2651
2652 if (point == data->auto_pwm_num) {
2653 if (data->kind != nct6775 && !val)
2654 return -EINVAL;
2655 if (data->kind != nct6779 && val)
2656 val = 0xff;
2657 }
2658
2659 mutex_lock(&data->update_lock);
2660 data->auto_pwm[nr][point] = val;
2661 if (point < data->auto_pwm_num) {
2662 nct6775_write_value(data,
2663 NCT6775_AUTO_PWM(data, nr, point),
2664 data->auto_pwm[nr][point]);
2665 } else {
2666 switch (data->kind) {
2667 case nct6775:
2668 /* disable if needed (pwm == 0) */
2669 reg = nct6775_read_value(data,
2670 NCT6775_REG_CRITICAL_ENAB[nr]);
2671 if (val)
2672 reg |= 0x02;
2673 else
2674 reg &= ~0x02;
2675 nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr],
2676 reg);
2677 break;
2678 case nct6776:
2679 break; /* always enabled, nothing to do */
2680 case nct6779:
2681 nct6775_write_value(data, NCT6779_REG_CRITICAL_PWM[nr],
2682 val);
2683 reg = nct6775_read_value(data,
2684 NCT6779_REG_CRITICAL_PWM_ENABLE[nr]);
2685 if (val == 255)
2686 reg &= ~0x01;
2687 else
2688 reg |= 0x01;
2689 nct6775_write_value(data,
2690 NCT6779_REG_CRITICAL_PWM_ENABLE[nr],
2691 reg);
2692 break;
2693 }
2694 }
2695 mutex_unlock(&data->update_lock);
2696 return count;
2697}
2698
2699static ssize_t
2700show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf)
2701{
2702 struct nct6775_data *data = nct6775_update_device(dev);
2703 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2704 int nr = sattr->nr;
2705 int point = sattr->index;
2706
2707 /*
2708 * We don't know for sure if the temperature is signed or unsigned.
2709 * Assume it is unsigned.
2710 */
2711 return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000);
2712}
2713
2714static ssize_t
2715store_auto_temp(struct device *dev, struct device_attribute *attr,
2716 const char *buf, size_t count)
2717{
2718 struct nct6775_data *data = dev_get_drvdata(dev);
2719 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2720 int nr = sattr->nr;
2721 int point = sattr->index;
2722 unsigned long val;
2723 int err;
2724
2725 err = kstrtoul(buf, 10, &val);
2726 if (err)
2727 return err;
2728 if (val > 255000)
2729 return -EINVAL;
2730
2731 mutex_lock(&data->update_lock);
2732 data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000);
2733 if (point < data->auto_pwm_num) {
2734 nct6775_write_value(data,
2735 NCT6775_AUTO_TEMP(data, nr, point),
2736 data->auto_temp[nr][point]);
2737 } else {
2738 nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr],
2739 data->auto_temp[nr][point]);
2740 }
2741 mutex_unlock(&data->update_lock);
2742 return count;
2743}
2744
2745/*
2746 * The number of auto-point trip points is chip dependent.
2747 * Need to check support while generating/removing attribute files.
2748 */
2749static struct sensor_device_attribute_2 sda_auto_pwm_arrays[] = {
2750 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
2751 show_auto_pwm, store_auto_pwm, 0, 0),
2752 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO,
2753 show_auto_temp, store_auto_temp, 0, 0),
2754 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
2755 show_auto_pwm, store_auto_pwm, 0, 1),
2756 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO,
2757 show_auto_temp, store_auto_temp, 0, 1),
2758 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO,
2759 show_auto_pwm, store_auto_pwm, 0, 2),
2760 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO,
2761 show_auto_temp, store_auto_temp, 0, 2),
2762 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO,
2763 show_auto_pwm, store_auto_pwm, 0, 3),
2764 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO,
2765 show_auto_temp, store_auto_temp, 0, 3),
2766 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO,
2767 show_auto_pwm, store_auto_pwm, 0, 4),
2768 SENSOR_ATTR_2(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO,
2769 show_auto_temp, store_auto_temp, 0, 4),
2770 SENSOR_ATTR_2(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO,
2771 show_auto_pwm, store_auto_pwm, 0, 5),
2772 SENSOR_ATTR_2(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO,
2773 show_auto_temp, store_auto_temp, 0, 5),
2774 SENSOR_ATTR_2(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO,
2775 show_auto_pwm, store_auto_pwm, 0, 6),
2776 SENSOR_ATTR_2(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO,
2777 show_auto_temp, store_auto_temp, 0, 6),
2778
2779 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO,
2780 show_auto_pwm, store_auto_pwm, 1, 0),
2781 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IWUSR | S_IRUGO,
2782 show_auto_temp, store_auto_temp, 1, 0),
2783 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO,
2784 show_auto_pwm, store_auto_pwm, 1, 1),
2785 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IWUSR | S_IRUGO,
2786 show_auto_temp, store_auto_temp, 1, 1),
2787 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IWUSR | S_IRUGO,
2788 show_auto_pwm, store_auto_pwm, 1, 2),
2789 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IWUSR | S_IRUGO,
2790 show_auto_temp, store_auto_temp, 1, 2),
2791 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IWUSR | S_IRUGO,
2792 show_auto_pwm, store_auto_pwm, 1, 3),
2793 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IWUSR | S_IRUGO,
2794 show_auto_temp, store_auto_temp, 1, 3),
2795 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IWUSR | S_IRUGO,
2796 show_auto_pwm, store_auto_pwm, 1, 4),
2797 SENSOR_ATTR_2(pwm2_auto_point5_temp, S_IWUSR | S_IRUGO,
2798 show_auto_temp, store_auto_temp, 1, 4),
2799 SENSOR_ATTR_2(pwm2_auto_point6_pwm, S_IWUSR | S_IRUGO,
2800 show_auto_pwm, store_auto_pwm, 1, 5),
2801 SENSOR_ATTR_2(pwm2_auto_point6_temp, S_IWUSR | S_IRUGO,
2802 show_auto_temp, store_auto_temp, 1, 5),
2803 SENSOR_ATTR_2(pwm2_auto_point7_pwm, S_IWUSR | S_IRUGO,
2804 show_auto_pwm, store_auto_pwm, 1, 6),
2805 SENSOR_ATTR_2(pwm2_auto_point7_temp, S_IWUSR | S_IRUGO,
2806 show_auto_temp, store_auto_temp, 1, 6),
2807
2808 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO,
2809 show_auto_pwm, store_auto_pwm, 2, 0),
2810 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IWUSR | S_IRUGO,
2811 show_auto_temp, store_auto_temp, 2, 0),
2812 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO,
2813 show_auto_pwm, store_auto_pwm, 2, 1),
2814 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IWUSR | S_IRUGO,
2815 show_auto_temp, store_auto_temp, 2, 1),
2816 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IWUSR | S_IRUGO,
2817 show_auto_pwm, store_auto_pwm, 2, 2),
2818 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IWUSR | S_IRUGO,
2819 show_auto_temp, store_auto_temp, 2, 2),
2820 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IWUSR | S_IRUGO,
2821 show_auto_pwm, store_auto_pwm, 2, 3),
2822 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IWUSR | S_IRUGO,
2823 show_auto_temp, store_auto_temp, 2, 3),
2824 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IWUSR | S_IRUGO,
2825 show_auto_pwm, store_auto_pwm, 2, 4),
2826 SENSOR_ATTR_2(pwm3_auto_point5_temp, S_IWUSR | S_IRUGO,
2827 show_auto_temp, store_auto_temp, 2, 4),
2828 SENSOR_ATTR_2(pwm3_auto_point6_pwm, S_IWUSR | S_IRUGO,
2829 show_auto_pwm, store_auto_pwm, 2, 5),
2830 SENSOR_ATTR_2(pwm3_auto_point6_temp, S_IWUSR | S_IRUGO,
2831 show_auto_temp, store_auto_temp, 2, 5),
2832 SENSOR_ATTR_2(pwm3_auto_point7_pwm, S_IWUSR | S_IRUGO,
2833 show_auto_pwm, store_auto_pwm, 2, 6),
2834 SENSOR_ATTR_2(pwm3_auto_point7_temp, S_IWUSR | S_IRUGO,
2835 show_auto_temp, store_auto_temp, 2, 6),
2836
2837 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO,
2838 show_auto_pwm, store_auto_pwm, 3, 0),
2839 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IWUSR | S_IRUGO,
2840 show_auto_temp, store_auto_temp, 3, 0),
2841 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO,
2842 show_auto_pwm, store_auto_pwm, 3, 1),
2843 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IWUSR | S_IRUGO,
2844 show_auto_temp, store_auto_temp, 3, 1),
2845 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IWUSR | S_IRUGO,
2846 show_auto_pwm, store_auto_pwm, 3, 2),
2847 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IWUSR | S_IRUGO,
2848 show_auto_temp, store_auto_temp, 3, 2),
2849 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IWUSR | S_IRUGO,
2850 show_auto_pwm, store_auto_pwm, 3, 3),
2851 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IWUSR | S_IRUGO,
2852 show_auto_temp, store_auto_temp, 3, 3),
2853 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IWUSR | S_IRUGO,
2854 show_auto_pwm, store_auto_pwm, 3, 4),
2855 SENSOR_ATTR_2(pwm4_auto_point5_temp, S_IWUSR | S_IRUGO,
2856 show_auto_temp, store_auto_temp, 3, 4),
2857 SENSOR_ATTR_2(pwm4_auto_point6_pwm, S_IWUSR | S_IRUGO,
2858 show_auto_pwm, store_auto_pwm, 3, 5),
2859 SENSOR_ATTR_2(pwm4_auto_point6_temp, S_IWUSR | S_IRUGO,
2860 show_auto_temp, store_auto_temp, 3, 5),
2861 SENSOR_ATTR_2(pwm4_auto_point7_pwm, S_IWUSR | S_IRUGO,
2862 show_auto_pwm, store_auto_pwm, 3, 6),
2863 SENSOR_ATTR_2(pwm4_auto_point7_temp, S_IWUSR | S_IRUGO,
2864 show_auto_temp, store_auto_temp, 3, 6),
2865
2866 SENSOR_ATTR_2(pwm5_auto_point1_pwm, S_IWUSR | S_IRUGO,
2867 show_auto_pwm, store_auto_pwm, 4, 0),
2868 SENSOR_ATTR_2(pwm5_auto_point1_temp, S_IWUSR | S_IRUGO,
2869 show_auto_temp, store_auto_temp, 4, 0),
2870 SENSOR_ATTR_2(pwm5_auto_point2_pwm, S_IWUSR | S_IRUGO,
2871 show_auto_pwm, store_auto_pwm, 4, 1),
2872 SENSOR_ATTR_2(pwm5_auto_point2_temp, S_IWUSR | S_IRUGO,
2873 show_auto_temp, store_auto_temp, 4, 1),
2874 SENSOR_ATTR_2(pwm5_auto_point3_pwm, S_IWUSR | S_IRUGO,
2875 show_auto_pwm, store_auto_pwm, 4, 2),
2876 SENSOR_ATTR_2(pwm5_auto_point3_temp, S_IWUSR | S_IRUGO,
2877 show_auto_temp, store_auto_temp, 4, 2),
2878 SENSOR_ATTR_2(pwm5_auto_point4_pwm, S_IWUSR | S_IRUGO,
2879 show_auto_pwm, store_auto_pwm, 4, 3),
2880 SENSOR_ATTR_2(pwm5_auto_point4_temp, S_IWUSR | S_IRUGO,
2881 show_auto_temp, store_auto_temp, 4, 3),
2882 SENSOR_ATTR_2(pwm5_auto_point5_pwm, S_IWUSR | S_IRUGO,
2883 show_auto_pwm, store_auto_pwm, 4, 4),
2884 SENSOR_ATTR_2(pwm5_auto_point5_temp, S_IWUSR | S_IRUGO,
2885 show_auto_temp, store_auto_temp, 4, 4),
2886 SENSOR_ATTR_2(pwm5_auto_point6_pwm, S_IWUSR | S_IRUGO,
2887 show_auto_pwm, store_auto_pwm, 4, 5),
2888 SENSOR_ATTR_2(pwm5_auto_point6_temp, S_IWUSR | S_IRUGO,
2889 show_auto_temp, store_auto_temp, 4, 5),
2890 SENSOR_ATTR_2(pwm5_auto_point7_pwm, S_IWUSR | S_IRUGO,
2891 show_auto_pwm, store_auto_pwm, 4, 6),
2892 SENSOR_ATTR_2(pwm5_auto_point7_temp, S_IWUSR | S_IRUGO,
2893 show_auto_temp, store_auto_temp, 4, 6),
2894};
2895
2896static ssize_t
1898show_vid(struct device *dev, struct device_attribute *attr, char *buf) 2897show_vid(struct device *dev, struct device_attribute *attr, char *buf)
1899{ 2898{
1900 struct nct6775_data *data = dev_get_drvdata(dev); 2899 struct nct6775_data *data = dev_get_drvdata(dev);
@@ -1969,6 +2968,15 @@ static void nct6775_device_remove_files(struct device *dev)
1969 for (i = 0; i < data->pwm_num; i++) 2968 for (i = 0; i < data->pwm_num; i++)
1970 sysfs_remove_group(&dev->kobj, &nct6775_group_pwm[i]); 2969 sysfs_remove_group(&dev->kobj, &nct6775_group_pwm[i]);
1971 2970
2971 for (i = 0; i < ARRAY_SIZE(sda_pwm_max); i++)
2972 device_remove_file(dev, &sda_pwm_max[i].dev_attr);
2973
2974 for (i = 0; i < ARRAY_SIZE(sda_pwm_step); i++)
2975 device_remove_file(dev, &sda_pwm_step[i].dev_attr);
2976
2977 for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++)
2978 device_remove_file(dev, &sda_auto_pwm_arrays[i].dev_attr);
2979
1972 for (i = 0; i < data->in_num; i++) 2980 for (i = 0; i < data->in_num; i++)
1973 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]); 2981 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]);
1974 2982
@@ -2161,6 +3169,7 @@ static int nct6775_probe(struct platform_device *pdev)
2161 case nct6775: 3169 case nct6775:
2162 data->in_num = 9; 3170 data->in_num = 9;
2163 data->pwm_num = 3; 3171 data->pwm_num = 3;
3172 data->auto_pwm_num = 6;
2164 data->has_fan_div = true; 3173 data->has_fan_div = true;
2165 data->temp_fixed_num = 3; 3174 data->temp_fixed_num = 3;
2166 3175
@@ -2168,6 +3177,9 @@ static int nct6775_probe(struct platform_device *pdev)
2168 3177
2169 data->fan_from_reg = fan_from_reg16; 3178 data->fan_from_reg = fan_from_reg16;
2170 data->fan_from_reg_min = fan_from_reg8; 3179 data->fan_from_reg_min = fan_from_reg8;
3180 data->target_temp_mask = 0x7f;
3181 data->tolerance_mask = 0x0f;
3182 data->speed_tolerance_limit = 15;
2171 3183
2172 data->temp_label = nct6775_temp_label; 3184 data->temp_label = nct6775_temp_label;
2173 data->temp_label_num = ARRAY_SIZE(nct6775_temp_label); 3185 data->temp_label_num = ARRAY_SIZE(nct6775_temp_label);
@@ -2178,16 +3190,30 @@ static int nct6775_probe(struct platform_device *pdev)
2178 data->REG_VIN = NCT6775_REG_IN; 3190 data->REG_VIN = NCT6775_REG_IN;
2179 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 3191 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
2180 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 3192 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
3193 data->REG_TARGET = NCT6775_REG_TARGET;
2181 data->REG_FAN = NCT6775_REG_FAN; 3194 data->REG_FAN = NCT6775_REG_FAN;
2182 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; 3195 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
2183 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN; 3196 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
2184 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES; 3197 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
3198 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3199 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3200 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
2185 data->REG_PWM[0] = NCT6775_REG_PWM; 3201 data->REG_PWM[0] = NCT6775_REG_PWM;
3202 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3203 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
3204 data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT;
3205 data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT;
2186 data->REG_PWM_READ = NCT6775_REG_PWM_READ; 3206 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
2187 data->REG_PWM_MODE = NCT6775_REG_PWM_MODE; 3207 data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
2188 data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK; 3208 data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
3209 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3210 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3211 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3212 data->REG_CRITICAL_TEMP_TOLERANCE
3213 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
2189 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; 3214 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
2190 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; 3215 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
3216 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
2191 data->REG_ALARM = NCT6775_REG_ALARM; 3217 data->REG_ALARM = NCT6775_REG_ALARM;
2192 3218
2193 reg_temp = NCT6775_REG_TEMP; 3219 reg_temp = NCT6775_REG_TEMP;
@@ -2202,6 +3228,7 @@ static int nct6775_probe(struct platform_device *pdev)
2202 case nct6776: 3228 case nct6776:
2203 data->in_num = 9; 3229 data->in_num = 9;
2204 data->pwm_num = 3; 3230 data->pwm_num = 3;
3231 data->auto_pwm_num = 4;
2205 data->has_fan_div = false; 3232 data->has_fan_div = false;
2206 data->temp_fixed_num = 3; 3233 data->temp_fixed_num = 3;
2207 3234
@@ -2209,6 +3236,9 @@ static int nct6775_probe(struct platform_device *pdev)
2209 3236
2210 data->fan_from_reg = fan_from_reg13; 3237 data->fan_from_reg = fan_from_reg13;
2211 data->fan_from_reg_min = fan_from_reg13; 3238 data->fan_from_reg_min = fan_from_reg13;
3239 data->target_temp_mask = 0xff;
3240 data->tolerance_mask = 0x07;
3241 data->speed_tolerance_limit = 63;
2212 3242
2213 data->temp_label = nct6776_temp_label; 3243 data->temp_label = nct6776_temp_label;
2214 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label); 3244 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
@@ -2219,16 +3249,29 @@ static int nct6775_probe(struct platform_device *pdev)
2219 data->REG_VIN = NCT6775_REG_IN; 3249 data->REG_VIN = NCT6775_REG_IN;
2220 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 3250 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
2221 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 3251 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
3252 data->REG_TARGET = NCT6775_REG_TARGET;
2222 data->REG_FAN = NCT6775_REG_FAN; 3253 data->REG_FAN = NCT6775_REG_FAN;
2223 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; 3254 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
2224 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; 3255 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
2225 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES; 3256 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
3257 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3258 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3259 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3260 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
2226 data->REG_PWM[0] = NCT6775_REG_PWM; 3261 data->REG_PWM[0] = NCT6775_REG_PWM;
3262 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3263 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
2227 data->REG_PWM_READ = NCT6775_REG_PWM_READ; 3264 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
2228 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE; 3265 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
2229 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK; 3266 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
3267 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3268 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3269 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3270 data->REG_CRITICAL_TEMP_TOLERANCE
3271 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
2230 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; 3272 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
2231 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; 3273 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
3274 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
2232 data->REG_ALARM = NCT6775_REG_ALARM; 3275 data->REG_ALARM = NCT6775_REG_ALARM;
2233 3276
2234 reg_temp = NCT6775_REG_TEMP; 3277 reg_temp = NCT6775_REG_TEMP;
@@ -2243,6 +3286,7 @@ static int nct6775_probe(struct platform_device *pdev)
2243 case nct6779: 3286 case nct6779:
2244 data->in_num = 15; 3287 data->in_num = 15;
2245 data->pwm_num = 5; 3288 data->pwm_num = 5;
3289 data->auto_pwm_num = 4;
2246 data->has_fan_div = false; 3290 data->has_fan_div = false;
2247 data->temp_fixed_num = 6; 3291 data->temp_fixed_num = 6;
2248 3292
@@ -2250,6 +3294,9 @@ static int nct6775_probe(struct platform_device *pdev)
2250 3294
2251 data->fan_from_reg = fan_from_reg13; 3295 data->fan_from_reg = fan_from_reg13;
2252 data->fan_from_reg_min = fan_from_reg13; 3296 data->fan_from_reg_min = fan_from_reg13;
3297 data->target_temp_mask = 0xff;
3298 data->tolerance_mask = 0x07;
3299 data->speed_tolerance_limit = 63;
2253 3300
2254 data->temp_label = nct6779_temp_label; 3301 data->temp_label = nct6779_temp_label;
2255 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label); 3302 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label);
@@ -2260,16 +3307,29 @@ static int nct6775_probe(struct platform_device *pdev)
2260 data->REG_VIN = NCT6779_REG_IN; 3307 data->REG_VIN = NCT6779_REG_IN;
2261 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 3308 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
2262 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 3309 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
3310 data->REG_TARGET = NCT6775_REG_TARGET;
2263 data->REG_FAN = NCT6779_REG_FAN; 3311 data->REG_FAN = NCT6779_REG_FAN;
2264 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; 3312 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
2265 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; 3313 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
2266 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES; 3314 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
3315 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3316 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3317 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3318 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
2267 data->REG_PWM[0] = NCT6775_REG_PWM; 3319 data->REG_PWM[0] = NCT6775_REG_PWM;
3320 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3321 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
2268 data->REG_PWM_READ = NCT6775_REG_PWM_READ; 3322 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
2269 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE; 3323 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
2270 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK; 3324 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
3325 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3326 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3327 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3328 data->REG_CRITICAL_TEMP_TOLERANCE
3329 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
2271 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; 3330 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
2272 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; 3331 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
3332 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
2273 data->REG_ALARM = NCT6779_REG_ALARM; 3333 data->REG_ALARM = NCT6779_REG_ALARM;
2274 3334
2275 reg_temp = NCT6779_REG_TEMP; 3335 reg_temp = NCT6779_REG_TEMP;
@@ -2484,6 +3544,31 @@ static int nct6775_probe(struct platform_device *pdev)
2484 err = sysfs_create_group(&dev->kobj, &nct6775_group_pwm[i]); 3544 err = sysfs_create_group(&dev->kobj, &nct6775_group_pwm[i]);
2485 if (err) 3545 if (err)
2486 goto exit_remove; 3546 goto exit_remove;
3547
3548 if (data->REG_PWM[3]) {
3549 err = device_create_file(dev,
3550 &sda_pwm_max[i].dev_attr);
3551 if (err)
3552 goto exit_remove;
3553 }
3554 if (data->REG_PWM[4]) {
3555 err = device_create_file(dev,
3556 &sda_pwm_step[i].dev_attr);
3557 if (err)
3558 goto exit_remove;
3559 }
3560 }
3561 for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) {
3562 struct sensor_device_attribute_2 *attr =
3563 &sda_auto_pwm_arrays[i];
3564
3565 if (!(data->has_pwm & (1 << attr->nr)))
3566 continue;
3567 if (attr->index > data->auto_pwm_num)
3568 continue;
3569 err = device_create_file(dev, &attr->dev_attr);
3570 if (err)
3571 goto exit_remove;
2487 } 3572 }
2488 3573
2489 for (i = 0; i < data->in_num; i++) { 3574 for (i = 0; i < data->in_num; i++) {
@@ -2518,7 +3603,7 @@ static int nct6775_probe(struct platform_device *pdev)
2518 goto exit_remove; 3603 goto exit_remove;
2519 } 3604 }
2520 err = device_create_file(dev, 3605 err = device_create_file(dev,
2521 &sda_fan_pulses[i].dev_attr); 3606 &sda_fan_pulses[i].dev_attr);
2522 if (err) 3607 if (err)
2523 goto exit_remove; 3608 goto exit_remove;
2524 } 3609 }