diff options
author | Guenter Roeck <linux@roeck-us.net> | 2012-12-04 12:08:29 -0500 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2013-04-08 00:16:39 -0400 |
commit | bbd8decd4123648ddeba2be485bc7e1a3117bfe4 (patch) | |
tree | a39d3b3d8a787862b632d8c9ec0545c49a84747c /drivers/hwmon | |
parent | cdcaeceb74ff3686eb25de6812870fbc765c3c39 (diff) |
hwmon: (nct6775) Add support for weighted fan control
The NCT677X series support weighted fan control. In this mode, a secondary
temperature source is used in addition to the primary temperature source to
control fan speed. Add support for this feature.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/nct6775.c | 280 |
1 files changed, 266 insertions, 14 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 47b1d8947e4d..f80ff823c28e 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c | |||
@@ -255,6 +255,17 @@ static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = { | |||
255 | static const u16 NCT6775_REG_TEMP_SEL[] = { | 255 | static const u16 NCT6775_REG_TEMP_SEL[] = { |
256 | 0x100, 0x200, 0x300, 0x800, 0x900 }; | 256 | 0x100, 0x200, 0x300, 0x800, 0x900 }; |
257 | 257 | ||
258 | static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = { | ||
259 | 0x139, 0x239, 0x339, 0x839, 0x939 }; | ||
260 | static const u16 NCT6775_REG_WEIGHT_TEMP_STEP[] = { | ||
261 | 0x13a, 0x23a, 0x33a, 0x83a, 0x93a }; | ||
262 | static const u16 NCT6775_REG_WEIGHT_TEMP_STEP_TOL[] = { | ||
263 | 0x13b, 0x23b, 0x33b, 0x83b, 0x93b }; | ||
264 | static const u16 NCT6775_REG_WEIGHT_DUTY_STEP[] = { | ||
265 | 0x13c, 0x23c, 0x33c, 0x83c, 0x93c }; | ||
266 | static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = { | ||
267 | 0x13d, 0x23d, 0x33d, 0x83d, 0x93d }; | ||
268 | |||
258 | static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; | 269 | static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; |
259 | 270 | ||
260 | static const u16 NCT6775_REG_AUTO_TEMP[] = { | 271 | static const u16 NCT6775_REG_AUTO_TEMP[] = { |
@@ -323,6 +334,9 @@ static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 }; | |||
323 | static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 }; | 334 | static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 }; |
324 | static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 }; | 335 | static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 }; |
325 | 336 | ||
337 | static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = { | ||
338 | 0x13e, 0x23e, 0x33e, 0x83e, 0x93e }; | ||
339 | |||
326 | static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { | 340 | static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { |
327 | 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A }; | 341 | 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A }; |
328 | 342 | ||
@@ -571,8 +585,9 @@ struct nct6775_data { | |||
571 | const u8 *REG_PWM_MODE; | 585 | const u8 *REG_PWM_MODE; |
572 | const u8 *PWM_MODE_MASK; | 586 | const u8 *PWM_MODE_MASK; |
573 | 587 | ||
574 | const u16 *REG_PWM[5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor, | 588 | const u16 *REG_PWM[7]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor, |
575 | * [3]=pwm_max, [4]=pwm_step | 589 | * [3]=pwm_max, [4]=pwm_step, |
590 | * [5]=weight_duty_step, [6]=weight_duty_base | ||
576 | */ | 591 | */ |
577 | const u16 *REG_PWM_READ; | 592 | const u16 *REG_PWM_READ; |
578 | 593 | ||
@@ -584,6 +599,9 @@ struct nct6775_data { | |||
584 | 599 | ||
585 | const u16 *REG_TEMP_SOURCE; /* temp register sources */ | 600 | const u16 *REG_TEMP_SOURCE; /* temp register sources */ |
586 | const u16 *REG_TEMP_SEL; | 601 | const u16 *REG_TEMP_SEL; |
602 | const u16 *REG_WEIGHT_TEMP_SEL; | ||
603 | const u16 *REG_WEIGHT_TEMP[3]; /* 0=base, 1=tolerance, 2=step */ | ||
604 | |||
587 | const u16 *REG_TEMP_OFFSET; | 605 | const u16 *REG_TEMP_OFFSET; |
588 | 606 | ||
589 | const u16 *REG_ALARM; | 607 | const u16 *REG_ALARM; |
@@ -625,8 +643,9 @@ struct nct6775_data { | |||
625 | * 4->SmartFan III | 643 | * 4->SmartFan III |
626 | * 5->enhanced variable thermal cruise (SmartFan IV) | 644 | * 5->enhanced variable thermal cruise (SmartFan IV) |
627 | */ | 645 | */ |
628 | u8 pwm[5][5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor, | 646 | u8 pwm[7][5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor, |
629 | * [3]=pwm_max, [4]=pwm_step | 647 | * [3]=pwm_max, [4]=pwm_step, |
648 | * [5]=weight_duty_step, [6]=weight_duty_base | ||
630 | */ | 649 | */ |
631 | 650 | ||
632 | u8 target_temp[5]; | 651 | u8 target_temp[5]; |
@@ -645,6 +664,10 @@ struct nct6775_data { | |||
645 | u8 auto_pwm[5][7]; | 664 | u8 auto_pwm[5][7]; |
646 | u8 auto_temp[5][7]; | 665 | u8 auto_temp[5][7]; |
647 | u8 pwm_temp_sel[5]; | 666 | u8 pwm_temp_sel[5]; |
667 | u8 pwm_weight_temp_sel[5]; | ||
668 | u8 weight_temp[3][5]; /* 0->temp_step, 1->temp_step_tol, | ||
669 | * 2->temp_base | ||
670 | */ | ||
648 | 671 | ||
649 | u8 vid; | 672 | u8 vid; |
650 | u8 vrm; | 673 | u8 vrm; |
@@ -972,6 +995,19 @@ static void nct6775_update_pwm(struct device *dev) | |||
972 | /* If fan can stop, report floor as 0 */ | 995 | /* If fan can stop, report floor as 0 */ |
973 | if (reg & 0x80) | 996 | if (reg & 0x80) |
974 | data->pwm[2][i] = 0; | 997 | data->pwm[2][i] = 0; |
998 | |||
999 | reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]); | ||
1000 | data->pwm_weight_temp_sel[i] = reg & 0x1f; | ||
1001 | /* If weight is disabled, report weight source as 0 */ | ||
1002 | if (j == 1 && !(reg & 0x80)) | ||
1003 | data->pwm_weight_temp_sel[i] = 0; | ||
1004 | |||
1005 | /* Weight temp data */ | ||
1006 | for (j = 0; j < 3; j++) { | ||
1007 | data->weight_temp[j][i] | ||
1008 | = nct6775_read_value(data, | ||
1009 | data->REG_WEIGHT_TEMP[j][i]); | ||
1010 | } | ||
975 | } | 1011 | } |
976 | } | 1012 | } |
977 | 1013 | ||
@@ -1938,9 +1974,9 @@ store_pwm(struct device *dev, struct device_attribute *attr, const char *buf, | |||
1938 | int nr = sattr->nr; | 1974 | int nr = sattr->nr; |
1939 | int index = sattr->index; | 1975 | int index = sattr->index; |
1940 | unsigned long val; | 1976 | unsigned long val; |
1941 | int minval[5] = { 0, 1, 1, data->pwm[2][nr], 0 }; | 1977 | int minval[7] = { 0, 1, 1, data->pwm[2][nr], 0, 0, 0 }; |
1942 | int maxval[5] | 1978 | int maxval[7] |
1943 | = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255 }; | 1979 | = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255, 255, 255 }; |
1944 | int err; | 1980 | int err; |
1945 | u8 reg; | 1981 | u8 reg; |
1946 | 1982 | ||
@@ -2078,13 +2114,9 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
2078 | } | 2114 | } |
2079 | 2115 | ||
2080 | static ssize_t | 2116 | static ssize_t |
2081 | show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf) | 2117 | show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src) |
2082 | { | 2118 | { |
2083 | struct nct6775_data *data = nct6775_update_device(dev); | 2119 | int i, sel = 0; |
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 | 2120 | ||
2089 | for (i = 0; i < NUM_TEMP; i++) { | 2121 | for (i = 0; i < NUM_TEMP; i++) { |
2090 | if (!(data->have_temp & (1 << i))) | 2122 | if (!(data->have_temp & (1 << i))) |
@@ -2099,6 +2131,16 @@ show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf) | |||
2099 | } | 2131 | } |
2100 | 2132 | ||
2101 | static ssize_t | 2133 | static ssize_t |
2134 | show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf) | ||
2135 | { | ||
2136 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2137 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2138 | int index = sattr->index; | ||
2139 | |||
2140 | return show_pwm_temp_sel_common(data, buf, data->pwm_temp_sel[index]); | ||
2141 | } | ||
2142 | |||
2143 | static ssize_t | ||
2102 | store_pwm_temp_sel(struct device *dev, struct device_attribute *attr, | 2144 | store_pwm_temp_sel(struct device *dev, struct device_attribute *attr, |
2103 | const char *buf, size_t count) | 2145 | const char *buf, size_t count) |
2104 | { | 2146 | { |
@@ -2129,6 +2171,56 @@ store_pwm_temp_sel(struct device *dev, struct device_attribute *attr, | |||
2129 | } | 2171 | } |
2130 | 2172 | ||
2131 | static ssize_t | 2173 | static ssize_t |
2174 | show_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr, | ||
2175 | char *buf) | ||
2176 | { | ||
2177 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2178 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2179 | int index = sattr->index; | ||
2180 | |||
2181 | return show_pwm_temp_sel_common(data, buf, | ||
2182 | data->pwm_weight_temp_sel[index]); | ||
2183 | } | ||
2184 | |||
2185 | static ssize_t | ||
2186 | store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr, | ||
2187 | const char *buf, size_t count) | ||
2188 | { | ||
2189 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2190 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
2191 | int nr = sattr->index; | ||
2192 | unsigned long val; | ||
2193 | int err, reg, src; | ||
2194 | |||
2195 | err = kstrtoul(buf, 10, &val); | ||
2196 | if (err < 0) | ||
2197 | return err; | ||
2198 | if (val > NUM_TEMP) | ||
2199 | return -EINVAL; | ||
2200 | if (val && (!(data->have_temp & (1 << (val - 1))) || | ||
2201 | !data->temp_src[val - 1])) | ||
2202 | return -EINVAL; | ||
2203 | |||
2204 | mutex_lock(&data->update_lock); | ||
2205 | if (val) { | ||
2206 | src = data->temp_src[val - 1]; | ||
2207 | data->pwm_weight_temp_sel[nr] = src; | ||
2208 | reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]); | ||
2209 | reg &= 0xe0; | ||
2210 | reg |= (src | 0x80); | ||
2211 | nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg); | ||
2212 | } else { | ||
2213 | data->pwm_weight_temp_sel[nr] = 0; | ||
2214 | reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]); | ||
2215 | reg &= 0x7f; | ||
2216 | nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg); | ||
2217 | } | ||
2218 | mutex_unlock(&data->update_lock); | ||
2219 | |||
2220 | return count; | ||
2221 | } | ||
2222 | |||
2223 | static ssize_t | ||
2132 | show_target_temp(struct device *dev, struct device_attribute *attr, char *buf) | 2224 | show_target_temp(struct device *dev, struct device_attribute *attr, char *buf) |
2133 | { | 2225 | { |
2134 | struct nct6775_data *data = nct6775_update_device(dev); | 2226 | struct nct6775_data *data = nct6775_update_device(dev); |
@@ -2381,6 +2473,115 @@ static SENSOR_DEVICE_ATTR(fan5_tolerance, S_IWUSR | S_IRUGO, | |||
2381 | /* Smart Fan registers */ | 2473 | /* Smart Fan registers */ |
2382 | 2474 | ||
2383 | static ssize_t | 2475 | static ssize_t |
2476 | show_weight_temp(struct device *dev, struct device_attribute *attr, char *buf) | ||
2477 | { | ||
2478 | struct nct6775_data *data = nct6775_update_device(dev); | ||
2479 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2480 | int nr = sattr->nr; | ||
2481 | int index = sattr->index; | ||
2482 | |||
2483 | return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000); | ||
2484 | } | ||
2485 | |||
2486 | static ssize_t | ||
2487 | store_weight_temp(struct device *dev, struct device_attribute *attr, | ||
2488 | const char *buf, size_t count) | ||
2489 | { | ||
2490 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
2491 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
2492 | int nr = sattr->nr; | ||
2493 | int index = sattr->index; | ||
2494 | unsigned long val; | ||
2495 | int err; | ||
2496 | |||
2497 | err = kstrtoul(buf, 10, &val); | ||
2498 | if (err < 0) | ||
2499 | return err; | ||
2500 | |||
2501 | val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255); | ||
2502 | |||
2503 | mutex_lock(&data->update_lock); | ||
2504 | data->weight_temp[index][nr] = val; | ||
2505 | nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val); | ||
2506 | mutex_unlock(&data->update_lock); | ||
2507 | return count; | ||
2508 | } | ||
2509 | |||
2510 | static SENSOR_DEVICE_ATTR(pwm1_weight_temp_sel, S_IWUSR | S_IRUGO, | ||
2511 | show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, | ||
2512 | 0); | ||
2513 | static SENSOR_DEVICE_ATTR(pwm2_weight_temp_sel, S_IWUSR | S_IRUGO, | ||
2514 | show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, | ||
2515 | 1); | ||
2516 | static SENSOR_DEVICE_ATTR(pwm3_weight_temp_sel, S_IWUSR | S_IRUGO, | ||
2517 | show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, | ||
2518 | 2); | ||
2519 | static SENSOR_DEVICE_ATTR(pwm4_weight_temp_sel, S_IWUSR | S_IRUGO, | ||
2520 | show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, | ||
2521 | 3); | ||
2522 | static SENSOR_DEVICE_ATTR(pwm5_weight_temp_sel, S_IWUSR | S_IRUGO, | ||
2523 | show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, | ||
2524 | 4); | ||
2525 | |||
2526 | static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step, S_IWUSR | S_IRUGO, | ||
2527 | show_weight_temp, store_weight_temp, 0, 0); | ||
2528 | static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step, S_IWUSR | S_IRUGO, | ||
2529 | show_weight_temp, store_weight_temp, 1, 0); | ||
2530 | static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step, S_IWUSR | S_IRUGO, | ||
2531 | show_weight_temp, store_weight_temp, 2, 0); | ||
2532 | static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step, S_IWUSR | S_IRUGO, | ||
2533 | show_weight_temp, store_weight_temp, 3, 0); | ||
2534 | static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step, S_IWUSR | S_IRUGO, | ||
2535 | show_weight_temp, store_weight_temp, 4, 0); | ||
2536 | |||
2537 | static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_tol, S_IWUSR | S_IRUGO, | ||
2538 | show_weight_temp, store_weight_temp, 0, 1); | ||
2539 | static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_tol, S_IWUSR | S_IRUGO, | ||
2540 | show_weight_temp, store_weight_temp, 1, 1); | ||
2541 | static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_tol, S_IWUSR | S_IRUGO, | ||
2542 | show_weight_temp, store_weight_temp, 2, 1); | ||
2543 | static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_tol, S_IWUSR | S_IRUGO, | ||
2544 | show_weight_temp, store_weight_temp, 3, 1); | ||
2545 | static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_tol, S_IWUSR | S_IRUGO, | ||
2546 | show_weight_temp, store_weight_temp, 4, 1); | ||
2547 | |||
2548 | static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_base, S_IWUSR | S_IRUGO, | ||
2549 | show_weight_temp, store_weight_temp, 0, 2); | ||
2550 | static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_base, S_IWUSR | S_IRUGO, | ||
2551 | show_weight_temp, store_weight_temp, 1, 2); | ||
2552 | static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_base, S_IWUSR | S_IRUGO, | ||
2553 | show_weight_temp, store_weight_temp, 2, 2); | ||
2554 | static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_base, S_IWUSR | S_IRUGO, | ||
2555 | show_weight_temp, store_weight_temp, 3, 2); | ||
2556 | static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_base, S_IWUSR | S_IRUGO, | ||
2557 | show_weight_temp, store_weight_temp, 4, 2); | ||
2558 | |||
2559 | static SENSOR_DEVICE_ATTR_2(pwm1_weight_duty_step, S_IWUSR | S_IRUGO, | ||
2560 | show_pwm, store_pwm, 0, 5); | ||
2561 | static SENSOR_DEVICE_ATTR_2(pwm2_weight_duty_step, S_IWUSR | S_IRUGO, | ||
2562 | show_pwm, store_pwm, 1, 5); | ||
2563 | static SENSOR_DEVICE_ATTR_2(pwm3_weight_duty_step, S_IWUSR | S_IRUGO, | ||
2564 | show_pwm, store_pwm, 2, 5); | ||
2565 | static SENSOR_DEVICE_ATTR_2(pwm4_weight_duty_step, S_IWUSR | S_IRUGO, | ||
2566 | show_pwm, store_pwm, 3, 5); | ||
2567 | static SENSOR_DEVICE_ATTR_2(pwm5_weight_duty_step, S_IWUSR | S_IRUGO, | ||
2568 | show_pwm, store_pwm, 4, 5); | ||
2569 | |||
2570 | /* duty_base is not supported on all chips */ | ||
2571 | static struct sensor_device_attribute_2 sda_weight_duty_base[] = { | ||
2572 | SENSOR_ATTR_2(pwm1_weight_duty_base, S_IWUSR | S_IRUGO, | ||
2573 | show_pwm, store_pwm, 0, 6), | ||
2574 | SENSOR_ATTR_2(pwm2_weight_duty_base, S_IWUSR | S_IRUGO, | ||
2575 | show_pwm, store_pwm, 1, 6), | ||
2576 | SENSOR_ATTR_2(pwm3_weight_duty_base, S_IWUSR | S_IRUGO, | ||
2577 | show_pwm, store_pwm, 2, 6), | ||
2578 | SENSOR_ATTR_2(pwm4_weight_duty_base, S_IWUSR | S_IRUGO, | ||
2579 | show_pwm, store_pwm, 3, 6), | ||
2580 | SENSOR_ATTR_2(pwm5_weight_duty_base, S_IWUSR | S_IRUGO, | ||
2581 | show_pwm, store_pwm, 4, 6), | ||
2582 | }; | ||
2583 | |||
2584 | static ssize_t | ||
2384 | show_fan_time(struct device *dev, struct device_attribute *attr, char *buf) | 2585 | show_fan_time(struct device *dev, struct device_attribute *attr, char *buf) |
2385 | { | 2586 | { |
2386 | struct nct6775_data *data = nct6775_update_device(dev); | 2587 | struct nct6775_data *data = nct6775_update_device(dev); |
@@ -2526,7 +2727,7 @@ static struct sensor_device_attribute_2 sda_pwm_step[] = { | |||
2526 | SENSOR_ATTR_2(pwm5_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 4), | 2727 | SENSOR_ATTR_2(pwm5_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 4), |
2527 | }; | 2728 | }; |
2528 | 2729 | ||
2529 | static struct attribute *nct6775_attributes_pwm[5][15] = { | 2730 | static struct attribute *nct6775_attributes_pwm[5][20] = { |
2530 | { | 2731 | { |
2531 | &sensor_dev_attr_pwm1.dev_attr.attr, | 2732 | &sensor_dev_attr_pwm1.dev_attr.attr, |
2532 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, | 2733 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, |
@@ -2542,6 +2743,11 @@ static struct attribute *nct6775_attributes_pwm[5][15] = { | |||
2542 | &sensor_dev_attr_pwm1_step_down_time.dev_attr.attr, | 2743 | &sensor_dev_attr_pwm1_step_down_time.dev_attr.attr, |
2543 | &sensor_dev_attr_pwm1_start.dev_attr.attr, | 2744 | &sensor_dev_attr_pwm1_start.dev_attr.attr, |
2544 | &sensor_dev_attr_pwm1_floor.dev_attr.attr, | 2745 | &sensor_dev_attr_pwm1_floor.dev_attr.attr, |
2746 | &sensor_dev_attr_pwm1_weight_temp_sel.dev_attr.attr, | ||
2747 | &sensor_dev_attr_pwm1_weight_temp_step.dev_attr.attr, | ||
2748 | &sensor_dev_attr_pwm1_weight_temp_step_tol.dev_attr.attr, | ||
2749 | &sensor_dev_attr_pwm1_weight_temp_step_base.dev_attr.attr, | ||
2750 | &sensor_dev_attr_pwm1_weight_duty_step.dev_attr.attr, | ||
2545 | NULL | 2751 | NULL |
2546 | }, | 2752 | }, |
2547 | { | 2753 | { |
@@ -2559,6 +2765,11 @@ static struct attribute *nct6775_attributes_pwm[5][15] = { | |||
2559 | &sensor_dev_attr_pwm2_step_down_time.dev_attr.attr, | 2765 | &sensor_dev_attr_pwm2_step_down_time.dev_attr.attr, |
2560 | &sensor_dev_attr_pwm2_start.dev_attr.attr, | 2766 | &sensor_dev_attr_pwm2_start.dev_attr.attr, |
2561 | &sensor_dev_attr_pwm2_floor.dev_attr.attr, | 2767 | &sensor_dev_attr_pwm2_floor.dev_attr.attr, |
2768 | &sensor_dev_attr_pwm2_weight_temp_sel.dev_attr.attr, | ||
2769 | &sensor_dev_attr_pwm2_weight_temp_step.dev_attr.attr, | ||
2770 | &sensor_dev_attr_pwm2_weight_temp_step_tol.dev_attr.attr, | ||
2771 | &sensor_dev_attr_pwm2_weight_temp_step_base.dev_attr.attr, | ||
2772 | &sensor_dev_attr_pwm2_weight_duty_step.dev_attr.attr, | ||
2562 | NULL | 2773 | NULL |
2563 | }, | 2774 | }, |
2564 | { | 2775 | { |
@@ -2576,6 +2787,11 @@ static struct attribute *nct6775_attributes_pwm[5][15] = { | |||
2576 | &sensor_dev_attr_pwm3_step_down_time.dev_attr.attr, | 2787 | &sensor_dev_attr_pwm3_step_down_time.dev_attr.attr, |
2577 | &sensor_dev_attr_pwm3_start.dev_attr.attr, | 2788 | &sensor_dev_attr_pwm3_start.dev_attr.attr, |
2578 | &sensor_dev_attr_pwm3_floor.dev_attr.attr, | 2789 | &sensor_dev_attr_pwm3_floor.dev_attr.attr, |
2790 | &sensor_dev_attr_pwm3_weight_temp_sel.dev_attr.attr, | ||
2791 | &sensor_dev_attr_pwm3_weight_temp_step.dev_attr.attr, | ||
2792 | &sensor_dev_attr_pwm3_weight_temp_step_tol.dev_attr.attr, | ||
2793 | &sensor_dev_attr_pwm3_weight_temp_step_base.dev_attr.attr, | ||
2794 | &sensor_dev_attr_pwm3_weight_duty_step.dev_attr.attr, | ||
2579 | NULL | 2795 | NULL |
2580 | }, | 2796 | }, |
2581 | { | 2797 | { |
@@ -2593,6 +2809,11 @@ static struct attribute *nct6775_attributes_pwm[5][15] = { | |||
2593 | &sensor_dev_attr_pwm4_step_down_time.dev_attr.attr, | 2809 | &sensor_dev_attr_pwm4_step_down_time.dev_attr.attr, |
2594 | &sensor_dev_attr_pwm4_start.dev_attr.attr, | 2810 | &sensor_dev_attr_pwm4_start.dev_attr.attr, |
2595 | &sensor_dev_attr_pwm4_floor.dev_attr.attr, | 2811 | &sensor_dev_attr_pwm4_floor.dev_attr.attr, |
2812 | &sensor_dev_attr_pwm4_weight_temp_sel.dev_attr.attr, | ||
2813 | &sensor_dev_attr_pwm4_weight_temp_step.dev_attr.attr, | ||
2814 | &sensor_dev_attr_pwm4_weight_temp_step_tol.dev_attr.attr, | ||
2815 | &sensor_dev_attr_pwm4_weight_temp_step_base.dev_attr.attr, | ||
2816 | &sensor_dev_attr_pwm4_weight_duty_step.dev_attr.attr, | ||
2596 | NULL | 2817 | NULL |
2597 | }, | 2818 | }, |
2598 | { | 2819 | { |
@@ -2610,6 +2831,11 @@ static struct attribute *nct6775_attributes_pwm[5][15] = { | |||
2610 | &sensor_dev_attr_pwm5_step_down_time.dev_attr.attr, | 2831 | &sensor_dev_attr_pwm5_step_down_time.dev_attr.attr, |
2611 | &sensor_dev_attr_pwm5_start.dev_attr.attr, | 2832 | &sensor_dev_attr_pwm5_start.dev_attr.attr, |
2612 | &sensor_dev_attr_pwm5_floor.dev_attr.attr, | 2833 | &sensor_dev_attr_pwm5_floor.dev_attr.attr, |
2834 | &sensor_dev_attr_pwm5_weight_temp_sel.dev_attr.attr, | ||
2835 | &sensor_dev_attr_pwm5_weight_temp_step.dev_attr.attr, | ||
2836 | &sensor_dev_attr_pwm5_weight_temp_step_tol.dev_attr.attr, | ||
2837 | &sensor_dev_attr_pwm5_weight_temp_step_base.dev_attr.attr, | ||
2838 | &sensor_dev_attr_pwm5_weight_duty_step.dev_attr.attr, | ||
2613 | NULL | 2839 | NULL |
2614 | }, | 2840 | }, |
2615 | }; | 2841 | }; |
@@ -2974,6 +3200,9 @@ static void nct6775_device_remove_files(struct device *dev) | |||
2974 | for (i = 0; i < ARRAY_SIZE(sda_pwm_step); i++) | 3200 | for (i = 0; i < ARRAY_SIZE(sda_pwm_step); i++) |
2975 | device_remove_file(dev, &sda_pwm_step[i].dev_attr); | 3201 | device_remove_file(dev, &sda_pwm_step[i].dev_attr); |
2976 | 3202 | ||
3203 | for (i = 0; i < ARRAY_SIZE(sda_weight_duty_base); i++) | ||
3204 | device_remove_file(dev, &sda_weight_duty_base[i].dev_attr); | ||
3205 | |||
2977 | for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) | 3206 | for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) |
2978 | device_remove_file(dev, &sda_auto_pwm_arrays[i].dev_attr); | 3207 | device_remove_file(dev, &sda_auto_pwm_arrays[i].dev_attr); |
2979 | 3208 | ||
@@ -3203,6 +3432,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3203 | data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; | 3432 | data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; |
3204 | data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT; | 3433 | data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT; |
3205 | data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT; | 3434 | data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT; |
3435 | data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP; | ||
3206 | data->REG_PWM_READ = NCT6775_REG_PWM_READ; | 3436 | data->REG_PWM_READ = NCT6775_REG_PWM_READ; |
3207 | data->REG_PWM_MODE = NCT6775_REG_PWM_MODE; | 3437 | data->REG_PWM_MODE = NCT6775_REG_PWM_MODE; |
3208 | data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK; | 3438 | data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK; |
@@ -3214,6 +3444,10 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3214 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; | 3444 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; |
3215 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; | 3445 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; |
3216 | data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; | 3446 | data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; |
3447 | data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL; | ||
3448 | data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP; | ||
3449 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; | ||
3450 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; | ||
3217 | data->REG_ALARM = NCT6775_REG_ALARM; | 3451 | data->REG_ALARM = NCT6775_REG_ALARM; |
3218 | 3452 | ||
3219 | reg_temp = NCT6775_REG_TEMP; | 3453 | reg_temp = NCT6775_REG_TEMP; |
@@ -3261,6 +3495,8 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3261 | data->REG_PWM[0] = NCT6775_REG_PWM; | 3495 | data->REG_PWM[0] = NCT6775_REG_PWM; |
3262 | data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; | 3496 | data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; |
3263 | data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; | 3497 | data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; |
3498 | data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP; | ||
3499 | data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE; | ||
3264 | data->REG_PWM_READ = NCT6775_REG_PWM_READ; | 3500 | data->REG_PWM_READ = NCT6775_REG_PWM_READ; |
3265 | data->REG_PWM_MODE = NCT6776_REG_PWM_MODE; | 3501 | data->REG_PWM_MODE = NCT6776_REG_PWM_MODE; |
3266 | data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK; | 3502 | data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK; |
@@ -3272,6 +3508,10 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3272 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; | 3508 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; |
3273 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; | 3509 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; |
3274 | data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; | 3510 | data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; |
3511 | data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL; | ||
3512 | data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP; | ||
3513 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; | ||
3514 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; | ||
3275 | data->REG_ALARM = NCT6775_REG_ALARM; | 3515 | data->REG_ALARM = NCT6775_REG_ALARM; |
3276 | 3516 | ||
3277 | reg_temp = NCT6775_REG_TEMP; | 3517 | reg_temp = NCT6775_REG_TEMP; |
@@ -3319,6 +3559,8 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3319 | data->REG_PWM[0] = NCT6775_REG_PWM; | 3559 | data->REG_PWM[0] = NCT6775_REG_PWM; |
3320 | data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; | 3560 | data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; |
3321 | data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; | 3561 | data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; |
3562 | data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP; | ||
3563 | data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE; | ||
3322 | data->REG_PWM_READ = NCT6775_REG_PWM_READ; | 3564 | data->REG_PWM_READ = NCT6775_REG_PWM_READ; |
3323 | data->REG_PWM_MODE = NCT6776_REG_PWM_MODE; | 3565 | data->REG_PWM_MODE = NCT6776_REG_PWM_MODE; |
3324 | data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK; | 3566 | data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK; |
@@ -3330,6 +3572,10 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3330 | data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; | 3572 | data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; |
3331 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; | 3573 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; |
3332 | data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; | 3574 | data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; |
3575 | data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL; | ||
3576 | data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP; | ||
3577 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; | ||
3578 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; | ||
3333 | data->REG_ALARM = NCT6779_REG_ALARM; | 3579 | data->REG_ALARM = NCT6779_REG_ALARM; |
3334 | 3580 | ||
3335 | reg_temp = NCT6779_REG_TEMP; | 3581 | reg_temp = NCT6779_REG_TEMP; |
@@ -3557,6 +3803,12 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3557 | if (err) | 3803 | if (err) |
3558 | goto exit_remove; | 3804 | goto exit_remove; |
3559 | } | 3805 | } |
3806 | if (data->REG_PWM[6]) { | ||
3807 | err = device_create_file(dev, | ||
3808 | &sda_weight_duty_base[i].dev_attr); | ||
3809 | if (err) | ||
3810 | goto exit_remove; | ||
3811 | } | ||
3560 | } | 3812 | } |
3561 | for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) { | 3813 | for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) { |
3562 | struct sensor_device_attribute_2 *attr = | 3814 | struct sensor_device_attribute_2 *attr = |