aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-12-04 12:08:29 -0500
committerGuenter Roeck <linux@roeck-us.net>2013-04-08 00:16:39 -0400
commitbbd8decd4123648ddeba2be485bc7e1a3117bfe4 (patch)
treea39d3b3d8a787862b632d8c9ec0545c49a84747c /drivers/hwmon
parentcdcaeceb74ff3686eb25de6812870fbc765c3c39 (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.c280
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)] = {
255static const u16 NCT6775_REG_TEMP_SEL[] = { 255static const u16 NCT6775_REG_TEMP_SEL[] = {
256 0x100, 0x200, 0x300, 0x800, 0x900 }; 256 0x100, 0x200, 0x300, 0x800, 0x900 };
257 257
258static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = {
259 0x139, 0x239, 0x339, 0x839, 0x939 };
260static const u16 NCT6775_REG_WEIGHT_TEMP_STEP[] = {
261 0x13a, 0x23a, 0x33a, 0x83a, 0x93a };
262static const u16 NCT6775_REG_WEIGHT_TEMP_STEP_TOL[] = {
263 0x13b, 0x23b, 0x33b, 0x83b, 0x93b };
264static const u16 NCT6775_REG_WEIGHT_DUTY_STEP[] = {
265 0x13c, 0x23c, 0x33c, 0x83c, 0x93c };
266static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = {
267 0x13d, 0x23d, 0x33d, 0x83d, 0x93d };
268
258static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; 269static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 };
259 270
260static const u16 NCT6775_REG_AUTO_TEMP[] = { 271static const u16 NCT6775_REG_AUTO_TEMP[] = {
@@ -323,6 +334,9 @@ static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 };
323static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 }; 334static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 };
324static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 }; 335static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 };
325 336
337static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = {
338 0x13e, 0x23e, 0x33e, 0x83e, 0x93e };
339
326static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { 340static 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
2080static ssize_t 2116static ssize_t
2081show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf) 2117show_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
2101static ssize_t 2133static ssize_t
2134show_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
2143static ssize_t
2102store_pwm_temp_sel(struct device *dev, struct device_attribute *attr, 2144store_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
2131static ssize_t 2173static ssize_t
2174show_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
2185static ssize_t
2186store_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
2223static ssize_t
2132show_target_temp(struct device *dev, struct device_attribute *attr, char *buf) 2224show_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
2383static ssize_t 2475static ssize_t
2476show_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
2486static ssize_t
2487store_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
2510static SENSOR_DEVICE_ATTR(pwm1_weight_temp_sel, S_IWUSR | S_IRUGO,
2511 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2512 0);
2513static SENSOR_DEVICE_ATTR(pwm2_weight_temp_sel, S_IWUSR | S_IRUGO,
2514 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2515 1);
2516static SENSOR_DEVICE_ATTR(pwm3_weight_temp_sel, S_IWUSR | S_IRUGO,
2517 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2518 2);
2519static SENSOR_DEVICE_ATTR(pwm4_weight_temp_sel, S_IWUSR | S_IRUGO,
2520 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2521 3);
2522static 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
2526static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step, S_IWUSR | S_IRUGO,
2527 show_weight_temp, store_weight_temp, 0, 0);
2528static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step, S_IWUSR | S_IRUGO,
2529 show_weight_temp, store_weight_temp, 1, 0);
2530static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step, S_IWUSR | S_IRUGO,
2531 show_weight_temp, store_weight_temp, 2, 0);
2532static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step, S_IWUSR | S_IRUGO,
2533 show_weight_temp, store_weight_temp, 3, 0);
2534static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step, S_IWUSR | S_IRUGO,
2535 show_weight_temp, store_weight_temp, 4, 0);
2536
2537static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2538 show_weight_temp, store_weight_temp, 0, 1);
2539static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2540 show_weight_temp, store_weight_temp, 1, 1);
2541static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2542 show_weight_temp, store_weight_temp, 2, 1);
2543static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2544 show_weight_temp, store_weight_temp, 3, 1);
2545static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2546 show_weight_temp, store_weight_temp, 4, 1);
2547
2548static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_base, S_IWUSR | S_IRUGO,
2549 show_weight_temp, store_weight_temp, 0, 2);
2550static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_base, S_IWUSR | S_IRUGO,
2551 show_weight_temp, store_weight_temp, 1, 2);
2552static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_base, S_IWUSR | S_IRUGO,
2553 show_weight_temp, store_weight_temp, 2, 2);
2554static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_base, S_IWUSR | S_IRUGO,
2555 show_weight_temp, store_weight_temp, 3, 2);
2556static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_base, S_IWUSR | S_IRUGO,
2557 show_weight_temp, store_weight_temp, 4, 2);
2558
2559static SENSOR_DEVICE_ATTR_2(pwm1_weight_duty_step, S_IWUSR | S_IRUGO,
2560 show_pwm, store_pwm, 0, 5);
2561static SENSOR_DEVICE_ATTR_2(pwm2_weight_duty_step, S_IWUSR | S_IRUGO,
2562 show_pwm, store_pwm, 1, 5);
2563static SENSOR_DEVICE_ATTR_2(pwm3_weight_duty_step, S_IWUSR | S_IRUGO,
2564 show_pwm, store_pwm, 2, 5);
2565static SENSOR_DEVICE_ATTR_2(pwm4_weight_duty_step, S_IWUSR | S_IRUGO,
2566 show_pwm, store_pwm, 3, 5);
2567static 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 */
2571static 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
2584static ssize_t
2384show_fan_time(struct device *dev, struct device_attribute *attr, char *buf) 2585show_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
2529static struct attribute *nct6775_attributes_pwm[5][15] = { 2730static 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 =