Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
cdcaeceb
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
cdcaeceb
编写于
12月 04, 2012
作者:
G
Guenter Roeck
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
hwmon: (nct6775) Add support for automatic fan control
Signed-off-by:
N
Guenter Roeck
<
linux@roeck-us.net
>
上级
77eb5b37
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
1161 addition
and
7 deletion
+1161
-7
Documentation/hwmon/nct6775
Documentation/hwmon/nct6775
+69
-0
drivers/hwmon/nct6775.c
drivers/hwmon/nct6775.c
+1092
-7
未找到文件。
Documentation/hwmon/nct6775
浏览文件 @
cdcaeceb
...
@@ -87,6 +87,75 @@ pwm[1-5]_mode - controls if output is PWM or DC level
...
@@ -87,6 +87,75 @@ pwm[1-5]_mode - controls if output is PWM or DC level
* 0 DC output
* 0 DC output
* 1 PWM output
* 1 PWM output
Common fan control attributes
-----------------------------
pwm[1-5]_temp_sel Temperature source. Value is temperature sensor index.
For example, select '1' for temp1_input.
Thermal Cruise mode (2)
-----------------------
If the temperature is in the range defined by:
pwm[1-5]_target_temp Target temperature, unit millidegree Celsius
(range 0 - 127000)
pwm[1-5]_temp_tolerance
Target temperature tolerance, unit millidegree Celsius
there are no changes to fan speed. Once the temperature leaves the interval, fan
speed increases (if temperature is higher that desired) or decreases (if
temperature is lower than desired), using the following limits and time
intervals.
pwm[1-5]_start fan pwm start value (range 1 - 255), to start fan
when the temperature is above defined range.
pwm[1-5]_floor lowest fan pwm (range 0 - 255) if temperature is below
the defined range. If set to 0, the fan is expected to
stop if the temperature is below the defined range.
pwm[1-5]_step_up_time milliseconds before fan speed is increased
pwm[1-5]_step_down_time milliseconds before fan speed is decreased
pwm[1-5]_stop_time how many milliseconds must elapse to switch
corresponding fan off (when the temperature was below
defined range).
Speed Cruise mode (3)
---------------------
This modes tries to keep the fan speed constant.
fan[1-5]_target Target fan speed
fan[1-5]_tolerance
Target speed tolerance
Untested; use at your own risk.
Smart Fan IV mode (5)
---------------------
This mode offers multiple slopes to control the fan speed. The slopes can be
controlled by setting the pwm and temperature attributes. When the temperature
rises, the chip will calculate the DC/PWM output based on the current slope.
There are up to seven data points depending on the chip type. Subsequent data
points should be set to higher temperatures and higher pwm values to achieve
higher fan speeds with increasing temperature. The last data point reflects
critical temperature mode, in which the fans should run at full speed.
pwm[1-5]_auto_point[1-7]_pwm
pwm value to be set if temperature reaches matching
temperature range.
pwm[1-5]_auto_point[1-7]_temp
Temperature over which the matching pwm is enabled.
pwm[1-5]_temp_tolerance
Temperature tolerance, unit millidegree Celsius
pwm[1-5]_crit_temp_tolerance
Temperature tolerance for critical temperature,
unit millidegree Celsius
pwm[1-5]_step_up_time milliseconds before fan speed is increased
pwm[1-5]_step_down_time milliseconds before fan speed is decreased
Usage Notes
Usage Notes
-----------
-----------
...
...
drivers/hwmon/nct6775.c
浏览文件 @
cdcaeceb
...
@@ -215,8 +215,23 @@ static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
...
@@ -215,8 +215,23 @@ static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
static
const
u8
NCT6775_REG_PWM_MODE
[]
=
{
0x04
,
0x04
,
0x12
};
static
const
u8
NCT6775_REG_PWM_MODE
[]
=
{
0x04
,
0x04
,
0x12
};
static
const
u8
NCT6775_PWM_MODE_MASK
[]
=
{
0x01
,
0x02
,
0x01
};
static
const
u8
NCT6775_PWM_MODE_MASK
[]
=
{
0x01
,
0x02
,
0x01
};
static
const
u16
NCT6775_REG_FAN_MODE
[]
=
{
0x102
,
0x202
,
0x302
,
0x802
,
0x902
};
/* Advanced Fan control, some values are common for all fans */
static
const
u16
NCT6775_REG_TARGET
[]
=
{
0x101
,
0x201
,
0x301
,
0x801
,
0x901
};
static
const
u16
NCT6775_REG_FAN_MODE
[]
=
{
0x102
,
0x202
,
0x302
,
0x802
,
0x902
};
static
const
u16
NCT6775_REG_FAN_STEP_DOWN_TIME
[]
=
{
0x103
,
0x203
,
0x303
,
0x803
,
0x903
};
static
const
u16
NCT6775_REG_FAN_STEP_UP_TIME
[]
=
{
0x104
,
0x204
,
0x304
,
0x804
,
0x904
};
static
const
u16
NCT6775_REG_FAN_STOP_OUTPUT
[]
=
{
0x105
,
0x205
,
0x305
,
0x805
,
0x905
};
static
const
u16
NCT6775_REG_FAN_START_OUTPUT
[]
=
{
0x106
,
0x206
,
0x306
,
0x806
,
0x906
};
static
const
u16
NCT6775_REG_FAN_MAX_OUTPUT
[]
=
{
0x10a
,
0x20a
,
0x30a
};
static
const
u16
NCT6775_REG_FAN_STEP_OUTPUT
[]
=
{
0x10b
,
0x20b
,
0x30b
};
static
const
u16
NCT6775_REG_FAN_STOP_TIME
[]
=
{
0x107
,
0x207
,
0x307
,
0x807
,
0x907
};
static
const
u16
NCT6775_REG_PWM
[]
=
{
0x109
,
0x209
,
0x309
,
0x809
,
0x909
};
static
const
u16
NCT6775_REG_PWM
[]
=
{
0x109
,
0x209
,
0x309
,
0x809
,
0x909
};
static
const
u16
NCT6775_REG_PWM_READ
[]
=
{
0x01
,
0x03
,
0x11
,
0x13
,
0x15
};
static
const
u16
NCT6775_REG_PWM_READ
[]
=
{
0x01
,
0x03
,
0x11
,
0x13
,
0x15
};
...
@@ -237,8 +252,26 @@ static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
...
@@ -237,8 +252,26 @@ static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
static
const
u16
NCT6775_REG_TEMP_SOURCE
[
ARRAY_SIZE
(
NCT6775_REG_TEMP
)]
=
{
static
const
u16
NCT6775_REG_TEMP_SOURCE
[
ARRAY_SIZE
(
NCT6775_REG_TEMP
)]
=
{
0x621
,
0x622
,
0x623
,
0x624
,
0x625
,
0x626
};
0x621
,
0x622
,
0x623
,
0x624
,
0x625
,
0x626
};
static
const
u16
NCT6775_REG_TEMP_SEL
[]
=
{
0x100
,
0x200
,
0x300
,
0x800
,
0x900
};
static
const
u16
NCT6775_REG_TEMP_OFFSET
[]
=
{
0x454
,
0x455
,
0x456
};
static
const
u16
NCT6775_REG_TEMP_OFFSET
[]
=
{
0x454
,
0x455
,
0x456
};
static
const
u16
NCT6775_REG_AUTO_TEMP
[]
=
{
0x121
,
0x221
,
0x321
,
0x821
,
0x921
};
static
const
u16
NCT6775_REG_AUTO_PWM
[]
=
{
0x127
,
0x227
,
0x327
,
0x827
,
0x927
};
#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p))
#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p))
static
const
u16
NCT6775_REG_CRITICAL_ENAB
[]
=
{
0x134
,
0x234
,
0x334
};
static
const
u16
NCT6775_REG_CRITICAL_TEMP
[]
=
{
0x135
,
0x235
,
0x335
,
0x835
,
0x935
};
static
const
u16
NCT6775_REG_CRITICAL_TEMP_TOLERANCE
[]
=
{
0x138
,
0x238
,
0x338
,
0x838
,
0x938
};
static
const
char
*
const
nct6775_temp_label
[]
=
{
static
const
char
*
const
nct6775_temp_label
[]
=
{
""
,
""
,
"SYSTIN"
,
"SYSTIN"
,
...
@@ -281,6 +314,9 @@ static const s8 NCT6776_ALARM_BITS[] = {
...
@@ -281,6 +314,9 @@ static const s8 NCT6776_ALARM_BITS[] = {
4
,
5
,
13
,
-
1
,
-
1
,
-
1
,
/* temp1..temp6 */
4
,
5
,
13
,
-
1
,
-
1
,
-
1
,
/* temp1..temp6 */
12
,
9
};
/* intrusion0, intrusion1 */
12
,
9
};
/* intrusion0, intrusion1 */
static
const
u16
NCT6776_REG_TOLERANCE_H
[]
=
{
0x10c
,
0x20c
,
0x30c
,
0x80c
,
0x90c
};
static
const
u8
NCT6776_REG_PWM_MODE
[]
=
{
0x04
,
0
,
0
};
static
const
u8
NCT6776_REG_PWM_MODE
[]
=
{
0x04
,
0
,
0
};
static
const
u8
NCT6776_PWM_MODE_MASK
[]
=
{
0x01
,
0
,
0
};
static
const
u8
NCT6776_PWM_MODE_MASK
[]
=
{
0x01
,
0
,
0
};
...
@@ -344,6 +380,11 @@ static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 };
...
@@ -344,6 +380,11 @@ static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 };
static
const
u16
NCT6779_REG_FAN_PULSES
[]
=
{
static
const
u16
NCT6779_REG_FAN_PULSES
[]
=
{
0x644
,
0x645
,
0x646
,
0x647
,
0x648
};
0x644
,
0x645
,
0x646
,
0x647
,
0x648
};
static
const
u16
NCT6779_REG_CRITICAL_PWM_ENABLE
[]
=
{
0x136
,
0x236
,
0x336
,
0x836
,
0x936
};
static
const
u16
NCT6779_REG_CRITICAL_PWM
[]
=
{
0x137
,
0x237
,
0x337
,
0x837
,
0x937
};
static
const
u16
NCT6779_REG_TEMP
[]
=
{
0x27
,
0x150
};
static
const
u16
NCT6779_REG_TEMP
[]
=
{
0x27
,
0x150
};
static
const
u16
NCT6779_REG_TEMP_CONFIG
[
ARRAY_SIZE
(
NCT6779_REG_TEMP
)]
=
{
static
const
u16
NCT6779_REG_TEMP_CONFIG
[
ARRAY_SIZE
(
NCT6779_REG_TEMP
)]
=
{
0x18
,
0x152
};
0x18
,
0x152
};
...
@@ -412,6 +453,18 @@ static int pwm_enable_to_reg(enum pwm_enable mode)
...
@@ -412,6 +453,18 @@ static int pwm_enable_to_reg(enum pwm_enable mode)
* Conversions
* Conversions
*/
*/
/* 1 is DC mode, output in ms */
static
unsigned
int
step_time_from_reg
(
u8
reg
,
u8
mode
)
{
return
mode
?
400
*
reg
:
100
*
reg
;
}
static
u8
step_time_to_reg
(
unsigned
int
msec
,
u8
mode
)
{
return
clamp_val
((
mode
?
(
msec
+
200
)
/
400
:
(
msec
+
50
)
/
100
),
1
,
255
);
}
static
unsigned
int
fan_from_reg8
(
u16
reg
,
unsigned
int
divreg
)
static
unsigned
int
fan_from_reg8
(
u16
reg
,
unsigned
int
divreg
)
{
{
if
(
reg
==
0
||
reg
==
255
)
if
(
reg
==
0
||
reg
==
255
)
...
@@ -444,6 +497,14 @@ static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
...
@@ -444,6 +497,14 @@ static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
return
1350000U
/
(
reg
<<
divreg
);
return
1350000U
/
(
reg
<<
divreg
);
}
}
static
u16
fan_to_reg
(
u32
fan
,
unsigned
int
divreg
)
{
if
(
!
fan
)
return
0
;
return
(
1350000U
/
fan
)
>>
divreg
;
}
static
inline
unsigned
int
static
inline
unsigned
int
div_from_reg
(
u8
reg
)
div_from_reg
(
u8
reg
)
{
{
...
@@ -498,18 +559,31 @@ struct nct6775_data {
...
@@ -498,18 +559,31 @@ struct nct6775_data {
const
u16
*
REG_VIN
;
const
u16
*
REG_VIN
;
const
u16
*
REG_IN_MINMAX
[
2
];
const
u16
*
REG_IN_MINMAX
[
2
];
const
u16
*
REG_TARGET
;
const
u16
*
REG_FAN
;
const
u16
*
REG_FAN
;
const
u16
*
REG_FAN_MODE
;
const
u16
*
REG_FAN_MODE
;
const
u16
*
REG_FAN_MIN
;
const
u16
*
REG_FAN_MIN
;
const
u16
*
REG_FAN_PULSES
;
const
u16
*
REG_FAN_PULSES
;
const
u16
*
REG_FAN_TIME
[
3
];
const
u16
*
REG_TOLERANCE_H
;
const
u8
*
REG_PWM_MODE
;
const
u8
*
REG_PWM_MODE
;
const
u8
*
PWM_MODE_MASK
;
const
u8
*
PWM_MODE_MASK
;
const
u16
*
REG_PWM
[
1
];
/* [0]=pwm */
const
u16
*
REG_PWM
[
5
];
/* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
* [3]=pwm_max, [4]=pwm_step
*/
const
u16
*
REG_PWM_READ
;
const
u16
*
REG_PWM_READ
;
const
u16
*
REG_AUTO_TEMP
;
const
u16
*
REG_AUTO_PWM
;
const
u16
*
REG_CRITICAL_TEMP
;
const
u16
*
REG_CRITICAL_TEMP_TOLERANCE
;
const
u16
*
REG_TEMP_SOURCE
;
/* temp register sources */
const
u16
*
REG_TEMP_SOURCE
;
/* temp register sources */
const
u16
*
REG_TEMP_SEL
;
const
u16
*
REG_TEMP_OFFSET
;
const
u16
*
REG_TEMP_OFFSET
;
const
u16
*
REG_ALARM
;
const
u16
*
REG_ALARM
;
...
@@ -551,7 +625,26 @@ struct nct6775_data {
...
@@ -551,7 +625,26 @@ struct nct6775_data {
* 4->SmartFan III
* 4->SmartFan III
* 5->enhanced variable thermal cruise (SmartFan IV)
* 5->enhanced variable thermal cruise (SmartFan IV)
*/
*/
u8
pwm
[
1
][
5
];
/* [0]=pwm */
u8
pwm
[
5
][
5
];
/* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
* [3]=pwm_max, [4]=pwm_step
*/
u8
target_temp
[
5
];
u8
target_temp_mask
;
u32
target_speed
[
5
];
u32
target_speed_tolerance
[
5
];
u8
speed_tolerance_limit
;
u8
temp_tolerance
[
2
][
5
];
u8
tolerance_mask
;
u8
fan_time
[
3
][
5
];
/* 0 = stop_time, 1 = step_up, 2 = step_down */
/* Automatic fan speed control registers */
int
auto_pwm_num
;
u8
auto_pwm
[
5
][
7
];
u8
auto_temp
[
5
][
7
];
u8
pwm_temp_sel
[
5
];
u8
vid
;
u8
vid
;
u8
vrm
;
u8
vrm
;
...
@@ -833,7 +926,7 @@ static void nct6775_update_pwm(struct device *dev)
...
@@ -833,7 +926,7 @@ static void nct6775_update_pwm(struct device *dev)
{
{
struct
nct6775_data
*
data
=
dev_get_drvdata
(
dev
);
struct
nct6775_data
*
data
=
dev_get_drvdata
(
dev
);
int
i
,
j
;
int
i
,
j
;
int
fanmodecfg
;
int
fanmodecfg
,
reg
;
bool
duty_is_dc
;
bool
duty_is_dc
;
for
(
i
=
0
;
i
<
data
->
pwm_num
;
i
++
)
{
for
(
i
=
0
;
i
<
data
->
pwm_num
;
i
++
)
{
...
@@ -856,6 +949,96 @@ static void nct6775_update_pwm(struct device *dev)
...
@@ -856,6 +949,96 @@ static void nct6775_update_pwm(struct device *dev)
data
->
pwm_enable
[
i
]
=
reg_to_pwm_enable
(
data
->
pwm
[
0
][
i
],
data
->
pwm_enable
[
i
]
=
reg_to_pwm_enable
(
data
->
pwm
[
0
][
i
],
(
fanmodecfg
>>
4
)
&
7
);
(
fanmodecfg
>>
4
)
&
7
);
if
(
!
data
->
temp_tolerance
[
0
][
i
]
||
data
->
pwm_enable
[
i
]
!=
speed_cruise
)
data
->
temp_tolerance
[
0
][
i
]
=
fanmodecfg
&
0x0f
;
if
(
!
data
->
target_speed_tolerance
[
i
]
||
data
->
pwm_enable
[
i
]
==
speed_cruise
)
{
u8
t
=
fanmodecfg
&
0x0f
;
if
(
data
->
REG_TOLERANCE_H
)
{
t
|=
(
nct6775_read_value
(
data
,
data
->
REG_TOLERANCE_H
[
i
])
&
0x70
)
>>
1
;
}
data
->
target_speed_tolerance
[
i
]
=
t
;
}
data
->
temp_tolerance
[
1
][
i
]
=
nct6775_read_value
(
data
,
data
->
REG_CRITICAL_TEMP_TOLERANCE
[
i
]);
reg
=
nct6775_read_value
(
data
,
data
->
REG_TEMP_SEL
[
i
]);
data
->
pwm_temp_sel
[
i
]
=
reg
&
0x1f
;
/* If fan can stop, report floor as 0 */
if
(
reg
&
0x80
)
data
->
pwm
[
2
][
i
]
=
0
;
}
}
static
void
nct6775_update_pwm_limits
(
struct
device
*
dev
)
{
struct
nct6775_data
*
data
=
dev_get_drvdata
(
dev
);
int
i
,
j
;
u8
reg
;
u16
reg_t
;
for
(
i
=
0
;
i
<
data
->
pwm_num
;
i
++
)
{
if
(
!
(
data
->
has_pwm
&
(
1
<<
i
)))
continue
;
for
(
j
=
0
;
j
<
3
;
j
++
)
{
data
->
fan_time
[
j
][
i
]
=
nct6775_read_value
(
data
,
data
->
REG_FAN_TIME
[
j
][
i
]);
}
reg_t
=
nct6775_read_value
(
data
,
data
->
REG_TARGET
[
i
]);
/* Update only in matching mode or if never updated */
if
(
!
data
->
target_temp
[
i
]
||
data
->
pwm_enable
[
i
]
==
thermal_cruise
)
data
->
target_temp
[
i
]
=
reg_t
&
data
->
target_temp_mask
;
if
(
!
data
->
target_speed
[
i
]
||
data
->
pwm_enable
[
i
]
==
speed_cruise
)
{
if
(
data
->
REG_TOLERANCE_H
)
{
reg_t
|=
(
nct6775_read_value
(
data
,
data
->
REG_TOLERANCE_H
[
i
])
&
0x0f
)
<<
8
;
}
data
->
target_speed
[
i
]
=
reg_t
;
}
for
(
j
=
0
;
j
<
data
->
auto_pwm_num
;
j
++
)
{
data
->
auto_pwm
[
i
][
j
]
=
nct6775_read_value
(
data
,
NCT6775_AUTO_PWM
(
data
,
i
,
j
));
data
->
auto_temp
[
i
][
j
]
=
nct6775_read_value
(
data
,
NCT6775_AUTO_TEMP
(
data
,
i
,
j
));
}
/* critical auto_pwm temperature data */
data
->
auto_temp
[
i
][
data
->
auto_pwm_num
]
=
nct6775_read_value
(
data
,
data
->
REG_CRITICAL_TEMP
[
i
]);
switch
(
data
->
kind
)
{
case
nct6775
:
reg
=
nct6775_read_value
(
data
,
NCT6775_REG_CRITICAL_ENAB
[
i
]);
data
->
auto_pwm
[
i
][
data
->
auto_pwm_num
]
=
(
reg
&
0x02
)
?
0xff
:
0x00
;
break
;
case
nct6776
:
data
->
auto_pwm
[
i
][
data
->
auto_pwm_num
]
=
0xff
;
break
;
case
nct6779
:
reg
=
nct6775_read_value
(
data
,
NCT6779_REG_CRITICAL_PWM_ENABLE
[
i
]);
if
(
reg
&
1
)
data
->
auto_pwm
[
i
][
data
->
auto_pwm_num
]
=
nct6775_read_value
(
data
,
NCT6779_REG_CRITICAL_PWM
[
i
]);
else
data
->
auto_pwm
[
i
][
data
->
auto_pwm_num
]
=
0xff
;
break
;
}
}
}
}
}
...
@@ -905,6 +1088,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
...
@@ -905,6 +1088,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
}
}
nct6775_update_pwm
(
dev
);
nct6775_update_pwm
(
dev
);
nct6775_update_pwm_limits
(
dev
);
/* Measured temperatures and limits */
/* Measured temperatures and limits */
for
(
i
=
0
;
i
<
NUM_TEMP
;
i
++
)
{
for
(
i
=
0
;
i
<
NUM_TEMP
;
i
++
)
{
...
@@ -1754,20 +1938,91 @@ store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
...
@@ -1754,20 +1938,91 @@ store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
int
nr
=
sattr
->
nr
;
int
nr
=
sattr
->
nr
;
int
index
=
sattr
->
index
;
int
index
=
sattr
->
index
;
unsigned
long
val
;
unsigned
long
val
;
int
minval
[
5
]
=
{
0
,
1
,
1
,
data
->
pwm
[
2
][
nr
],
0
};
int
maxval
[
5
]
=
{
255
,
255
,
data
->
pwm
[
3
][
nr
]
?
:
255
,
255
,
255
};
int
err
;
int
err
;
u8
reg
;
err
=
kstrtoul
(
buf
,
10
,
&
val
);
err
=
kstrtoul
(
buf
,
10
,
&
val
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
val
=
clamp_val
(
val
,
0
,
255
);
val
=
clamp_val
(
val
,
minval
[
index
],
maxval
[
index
]
);
mutex_lock
(
&
data
->
update_lock
);
mutex_lock
(
&
data
->
update_lock
);
data
->
pwm
[
index
][
nr
]
=
val
;
data
->
pwm
[
index
][
nr
]
=
val
;
nct6775_write_value
(
data
,
data
->
REG_PWM
[
index
][
nr
],
val
);
nct6775_write_value
(
data
,
data
->
REG_PWM
[
index
][
nr
],
val
);
if
(
index
==
2
)
{
/* floor: disable if val == 0 */
reg
=
nct6775_read_value
(
data
,
data
->
REG_TEMP_SEL
[
nr
]);
reg
&=
0x7f
;
if
(
val
)
reg
|=
0x80
;
nct6775_write_value
(
data
,
data
->
REG_TEMP_SEL
[
nr
],
reg
);
}
mutex_unlock
(
&
data
->
update_lock
);
mutex_unlock
(
&
data
->
update_lock
);
return
count
;
return
count
;
}
}
/* Returns 0 if OK, -EINVAL otherwise */
static
int
check_trip_points
(
struct
nct6775_data
*
data
,
int
nr
)
{
int
i
;
for
(
i
=
0
;
i
<
data
->
auto_pwm_num
-
1
;
i
++
)
{
if
(
data
->
auto_temp
[
nr
][
i
]
>
data
->
auto_temp
[
nr
][
i
+
1
])
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
data
->
auto_pwm_num
-
1
;
i
++
)
{
if
(
data
->
auto_pwm
[
nr
][
i
]
>
data
->
auto_pwm
[
nr
][
i
+
1
])
return
-
EINVAL
;
}
/* validate critical temperature and pwm if enabled (pwm > 0) */
if
(
data
->
auto_pwm
[
nr
][
data
->
auto_pwm_num
])
{
if
(
data
->
auto_temp
[
nr
][
data
->
auto_pwm_num
-
1
]
>
data
->
auto_temp
[
nr
][
data
->
auto_pwm_num
]
||
data
->
auto_pwm
[
nr
][
data
->
auto_pwm_num
-
1
]
>
data
->
auto_pwm
[
nr
][
data
->
auto_pwm_num
])
return
-
EINVAL
;
}
return
0
;
}
static
void
pwm_update_registers
(
struct
nct6775_data
*
data
,
int
nr
)
{
u8
reg
;
switch
(
data
->
pwm_enable
[
nr
])
{
case
off
:
case
manual
:
break
;
case
speed_cruise
:
reg
=
nct6775_read_value
(
data
,
data
->
REG_FAN_MODE
[
nr
]);
reg
=
(
reg
&
~
data
->
tolerance_mask
)
|
(
data
->
target_speed_tolerance
[
nr
]
&
data
->
tolerance_mask
);
nct6775_write_value
(
data
,
data
->
REG_FAN_MODE
[
nr
],
reg
);
nct6775_write_value
(
data
,
data
->
REG_TARGET
[
nr
],
data
->
target_speed
[
nr
]
&
0xff
);
if
(
data
->
REG_TOLERANCE_H
)
{
reg
=
(
data
->
target_speed
[
nr
]
>>
8
)
&
0x0f
;
reg
|=
(
data
->
target_speed_tolerance
[
nr
]
&
0x38
)
<<
1
;
nct6775_write_value
(
data
,
data
->
REG_TOLERANCE_H
[
nr
],
reg
);
}
break
;
case
thermal_cruise
:
nct6775_write_value
(
data
,
data
->
REG_TARGET
[
nr
],
data
->
target_temp
[
nr
]);
/* intentional */
default:
reg
=
nct6775_read_value
(
data
,
data
->
REG_FAN_MODE
[
nr
]);
reg
=
(
reg
&
~
data
->
tolerance_mask
)
|
data
->
temp_tolerance
[
0
][
nr
];
nct6775_write_value
(
data
,
data
->
REG_FAN_MODE
[
nr
],
reg
);
break
;
}
}
static
ssize_t
static
ssize_t
show_pwm_enable
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
show_pwm_enable
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
{
...
@@ -1798,6 +2053,12 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
...
@@ -1798,6 +2053,12 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
if
(
val
==
sf3
&&
data
->
kind
!=
nct6775
)
if
(
val
==
sf3
&&
data
->
kind
!=
nct6775
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
val
==
sf4
&&
check_trip_points
(
data
,
nr
))
{
dev_err
(
dev
,
"Inconsistent trip points, not switching to SmartFan IV mode
\n
"
);
dev_err
(
dev
,
"Adjust trip points and try again
\n
"
);
return
-
EINVAL
;
}
mutex_lock
(
&
data
->
update_lock
);
mutex_lock
(
&
data
->
update_lock
);
data
->
pwm_enable
[
nr
]
=
val
;
data
->
pwm_enable
[
nr
]
=
val
;
if
(
val
==
off
)
{
if
(
val
==
off
)
{
...
@@ -1807,6 +2068,7 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
...
@@ -1807,6 +2068,7 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
data
->
pwm
[
0
][
nr
]
=
255
;
data
->
pwm
[
0
][
nr
]
=
255
;
nct6775_write_value
(
data
,
data
->
REG_PWM
[
0
][
nr
],
255
);
nct6775_write_value
(
data
,
data
->
REG_PWM
[
0
][
nr
],
255
);
}
}
pwm_update_registers
(
data
,
nr
);
reg
=
nct6775_read_value
(
data
,
data
->
REG_FAN_MODE
[
nr
]);
reg
=
nct6775_read_value
(
data
,
data
->
REG_FAN_MODE
[
nr
]);
reg
&=
0x0f
;
reg
&=
0x0f
;
reg
|=
pwm_enable_to_reg
(
val
)
<<
4
;
reg
|=
pwm_enable_to_reg
(
val
)
<<
4
;
...
@@ -1815,6 +2077,235 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
...
@@ -1815,6 +2077,235 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
return
count
;
return
count
;
}
}
static
ssize_t
show_pwm_temp_sel
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
nct6775_data
*
data
=
nct6775_update_device
(
dev
);
struct
sensor_device_attribute
*
sattr
=
to_sensor_dev_attr
(
attr
);
int
i
,
src
,
sel
=
0
;
src
=
data
->
pwm_temp_sel
[
sattr
->
index
];
for
(
i
=
0
;
i
<
NUM_TEMP
;
i
++
)
{
if
(
!
(
data
->
have_temp
&
(
1
<<
i
)))
continue
;
if
(
src
==
data
->
temp_src
[
i
])
{
sel
=
i
+
1
;
break
;
}
}
return
sprintf
(
buf
,
"%d
\n
"
,
sel
);
}
static
ssize_t
store_pwm_temp_sel
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
nct6775_data
*
data
=
nct6775_update_device
(
dev
);
struct
sensor_device_attribute
*
sattr
=
to_sensor_dev_attr
(
attr
);
int
nr
=
sattr
->
index
;
unsigned
long
val
;
int
err
,
reg
,
src
;
err
=
kstrtoul
(
buf
,
10
,
&
val
);
if
(
err
<
0
)
return
err
;
if
(
val
==
0
||
val
>
NUM_TEMP
)
return
-
EINVAL
;
if
(
!
(
data
->
have_temp
&
(
1
<<
(
val
-
1
)))
||
!
data
->
temp_src
[
val
-
1
])
return
-
EINVAL
;
mutex_lock
(
&
data
->
update_lock
);
src
=
data
->
temp_src
[
val
-
1
];
data
->
pwm_temp_sel
[
nr
]
=
src
;
reg
=
nct6775_read_value
(
data
,
data
->
REG_TEMP_SEL
[
nr
]);
reg
&=
0xe0
;
reg
|=
src
;
nct6775_write_value
(
data
,
data
->
REG_TEMP_SEL
[
nr
],
reg
);
mutex_unlock
(
&
data
->
update_lock
);
return
count
;
}
static
ssize_t
show_target_temp
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
nct6775_data
*
data
=
nct6775_update_device
(
dev
);
struct
sensor_device_attribute
*
sattr
=
to_sensor_dev_attr
(
attr
);
return
sprintf
(
buf
,
"%d
\n
"
,
data
->
target_temp
[
sattr
->
index
]
*
1000
);
}
static
ssize_t
store_target_temp
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
nct6775_data
*
data
=
dev_get_drvdata
(
dev
);
struct
sensor_device_attribute
*
sattr
=
to_sensor_dev_attr
(
attr
);
int
nr
=
sattr
->
index
;
unsigned
long
val
;
int
err
;
err
=
kstrtoul
(
buf
,
10
,
&
val
);
if
(
err
<
0
)
return
err
;
val
=
clamp_val
(
DIV_ROUND_CLOSEST
(
val
,
1000
),
0
,
data
->
target_temp_mask
);
mutex_lock
(
&
data
->
update_lock
);
data
->
target_temp
[
nr
]
=
val
;
pwm_update_registers
(
data
,
nr
);
mutex_unlock
(
&
data
->
update_lock
);
return
count
;
}
static
ssize_t
show_target_speed
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
nct6775_data
*
data
=
nct6775_update_device
(
dev
);
struct
sensor_device_attribute
*
sattr
=
to_sensor_dev_attr
(
attr
);
int
nr
=
sattr
->
index
;
return
sprintf
(
buf
,
"%d
\n
"
,
fan_from_reg16
(
data
->
target_speed
[
nr
],
data
->
fan_div
[
nr
]));
}
static
ssize_t
store_target_speed
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
nct6775_data
*
data
=
dev_get_drvdata
(
dev
);
struct
sensor_device_attribute
*
sattr
=
to_sensor_dev_attr
(
attr
);
int
nr
=
sattr
->
index
;
unsigned
long
val
;
int
err
;
u16
speed
;
err
=
kstrtoul
(
buf
,
10
,
&
val
);
if
(
err
<
0
)
return
err
;
val
=
clamp_val
(
val
,
0
,
1350000U
);
speed
=
fan_to_reg
(
val
,
data
->
fan_div
[
nr
]);
mutex_lock
(
&
data
->
update_lock
);
data
->
target_speed
[
nr
]
=
speed
;
pwm_update_registers
(
data
,
nr
);
mutex_unlock
(
&
data
->
update_lock
);
return
count
;
}
static
ssize_t
show_temp_tolerance
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
nct6775_data
*
data
=
nct6775_update_device
(
dev
);
struct
sensor_device_attribute_2
*
sattr
=
to_sensor_dev_attr_2
(
attr
);
int
nr
=
sattr
->
nr
;
int
index
=
sattr
->
index
;
return
sprintf
(
buf
,
"%d
\n
"
,
data
->
temp_tolerance
[
index
][
nr
]
*
1000
);
}
static
ssize_t
store_temp_tolerance
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
nct6775_data
*
data
=
dev_get_drvdata
(
dev
);
struct
sensor_device_attribute_2
*
sattr
=
to_sensor_dev_attr_2
(
attr
);
int
nr
=
sattr
->
nr
;
int
index
=
sattr
->
index
;
unsigned
long
val
;
int
err
;
err
=
kstrtoul
(
buf
,
10
,
&
val
);
if
(
err
<
0
)
return
err
;
/* Limit tolerance as needed */
val
=
clamp_val
(
DIV_ROUND_CLOSEST
(
val
,
1000
),
0
,
data
->
tolerance_mask
);
mutex_lock
(
&
data
->
update_lock
);
data
->
temp_tolerance
[
index
][
nr
]
=
val
;
if
(
index
)
pwm_update_registers
(
data
,
nr
);
else
nct6775_write_value
(
data
,
data
->
REG_CRITICAL_TEMP_TOLERANCE
[
nr
],
val
);
mutex_unlock
(
&
data
->
update_lock
);
return
count
;
}
/*
* Fan speed tolerance is a tricky beast, since the associated register is
* a tick counter, but the value is reported and configured as rpm.
* Compute resulting low and high rpm values and report the difference.
*/
static
ssize_t
show_speed_tolerance
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
nct6775_data
*
data
=
nct6775_update_device
(
dev
);
struct
sensor_device_attribute
*
sattr
=
to_sensor_dev_attr
(
attr
);
int
nr
=
sattr
->
index
;
int
low
=
data
->
target_speed
[
nr
]
-
data
->
target_speed_tolerance
[
nr
];
int
high
=
data
->
target_speed
[
nr
]
+
data
->
target_speed_tolerance
[
nr
];
int
tolerance
;
if
(
low
<=
0
)
low
=
1
;
if
(
high
>
0xffff
)
high
=
0xffff
;
if
(
high
<
low
)
high
=
low
;
tolerance
=
(
fan_from_reg16
(
low
,
data
->
fan_div
[
nr
])
-
fan_from_reg16
(
high
,
data
->
fan_div
[
nr
]))
/
2
;
return
sprintf
(
buf
,
"%d
\n
"
,
tolerance
);
}
static
ssize_t
store_speed_tolerance
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
nct6775_data
*
data
=
dev_get_drvdata
(
dev
);
struct
sensor_device_attribute
*
sattr
=
to_sensor_dev_attr
(
attr
);
int
nr
=
sattr
->
index
;
unsigned
long
val
;
int
err
;
int
low
,
high
;
err
=
kstrtoul
(
buf
,
10
,
&
val
);
if
(
err
<
0
)
return
err
;
high
=
fan_from_reg16
(
data
->
target_speed
[
nr
],
data
->
fan_div
[
nr
])
+
val
;
low
=
fan_from_reg16
(
data
->
target_speed
[
nr
],
data
->
fan_div
[
nr
])
-
val
;
if
(
low
<=
0
)
low
=
1
;
if
(
high
<
low
)
high
=
low
;
val
=
(
fan_to_reg
(
low
,
data
->
fan_div
[
nr
])
-
fan_to_reg
(
high
,
data
->
fan_div
[
nr
]))
/
2
;
/* Limit tolerance as needed */
val
=
clamp_val
(
val
,
0
,
data
->
speed_tolerance_limit
);
mutex_lock
(
&
data
->
update_lock
);
data
->
target_speed_tolerance
[
nr
]
=
val
;
pwm_update_registers
(
data
,
nr
);
mutex_unlock
(
&
data
->
update_lock
);
return
count
;
}
static
SENSOR_DEVICE_ATTR_2
(
pwm1
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
0
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm1
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
0
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm2
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
1
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm2
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
1
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm3
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
2
,
0
);
static
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,
...
@@ -1843,6 +2334,88 @@ static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
static
SENSOR_DEVICE_ATTR
(
pwm5_enable
,
S_IWUSR
|
S_IRUGO
,
show_pwm_enable
,
static
SENSOR_DEVICE_ATTR
(
pwm5_enable
,
S_IWUSR
|
S_IRUGO
,
show_pwm_enable
,
store_pwm_enable
,
4
);
store_pwm_enable
,
4
);
static
SENSOR_DEVICE_ATTR
(
pwm1_temp_sel
,
S_IWUSR
|
S_IRUGO
,
show_pwm_temp_sel
,
store_pwm_temp_sel
,
0
);
static
SENSOR_DEVICE_ATTR
(
pwm2_temp_sel
,
S_IWUSR
|
S_IRUGO
,
show_pwm_temp_sel
,
store_pwm_temp_sel
,
1
);
static
SENSOR_DEVICE_ATTR
(
pwm3_temp_sel
,
S_IWUSR
|
S_IRUGO
,
show_pwm_temp_sel
,
store_pwm_temp_sel
,
2
);
static
SENSOR_DEVICE_ATTR
(
pwm4_temp_sel
,
S_IWUSR
|
S_IRUGO
,
show_pwm_temp_sel
,
store_pwm_temp_sel
,
3
);
static
SENSOR_DEVICE_ATTR
(
pwm5_temp_sel
,
S_IWUSR
|
S_IRUGO
,
show_pwm_temp_sel
,
store_pwm_temp_sel
,
4
);
static
SENSOR_DEVICE_ATTR
(
pwm1_target_temp
,
S_IWUSR
|
S_IRUGO
,
show_target_temp
,
store_target_temp
,
0
);
static
SENSOR_DEVICE_ATTR
(
pwm2_target_temp
,
S_IWUSR
|
S_IRUGO
,
show_target_temp
,
store_target_temp
,
1
);
static
SENSOR_DEVICE_ATTR
(
pwm3_target_temp
,
S_IWUSR
|
S_IRUGO
,
show_target_temp
,
store_target_temp
,
2
);
static
SENSOR_DEVICE_ATTR
(
pwm4_target_temp
,
S_IWUSR
|
S_IRUGO
,
show_target_temp
,
store_target_temp
,
3
);
static
SENSOR_DEVICE_ATTR
(
pwm5_target_temp
,
S_IWUSR
|
S_IRUGO
,
show_target_temp
,
store_target_temp
,
4
);
static
SENSOR_DEVICE_ATTR
(
fan1_target
,
S_IWUSR
|
S_IRUGO
,
show_target_speed
,
store_target_speed
,
0
);
static
SENSOR_DEVICE_ATTR
(
fan2_target
,
S_IWUSR
|
S_IRUGO
,
show_target_speed
,
store_target_speed
,
1
);
static
SENSOR_DEVICE_ATTR
(
fan3_target
,
S_IWUSR
|
S_IRUGO
,
show_target_speed
,
store_target_speed
,
2
);
static
SENSOR_DEVICE_ATTR
(
fan4_target
,
S_IWUSR
|
S_IRUGO
,
show_target_speed
,
store_target_speed
,
3
);
static
SENSOR_DEVICE_ATTR
(
fan5_target
,
S_IWUSR
|
S_IRUGO
,
show_target_speed
,
store_target_speed
,
4
);
static
SENSOR_DEVICE_ATTR
(
fan1_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_speed_tolerance
,
store_speed_tolerance
,
0
);
static
SENSOR_DEVICE_ATTR
(
fan2_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_speed_tolerance
,
store_speed_tolerance
,
1
);
static
SENSOR_DEVICE_ATTR
(
fan3_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_speed_tolerance
,
store_speed_tolerance
,
2
);
static
SENSOR_DEVICE_ATTR
(
fan4_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_speed_tolerance
,
store_speed_tolerance
,
3
);
static
SENSOR_DEVICE_ATTR
(
fan5_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_speed_tolerance
,
store_speed_tolerance
,
4
);
/* Smart Fan registers */
static
ssize_t
show_fan_time
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
nct6775_data
*
data
=
nct6775_update_device
(
dev
);
struct
sensor_device_attribute_2
*
sattr
=
to_sensor_dev_attr_2
(
attr
);
int
nr
=
sattr
->
nr
;
int
index
=
sattr
->
index
;
return
sprintf
(
buf
,
"%d
\n
"
,
step_time_from_reg
(
data
->
fan_time
[
index
][
nr
],
data
->
pwm_mode
[
nr
]));
}
static
ssize_t
store_fan_time
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
nct6775_data
*
data
=
dev_get_drvdata
(
dev
);
struct
sensor_device_attribute_2
*
sattr
=
to_sensor_dev_attr_2
(
attr
);
int
nr
=
sattr
->
nr
;
int
index
=
sattr
->
index
;
unsigned
long
val
;
int
err
;
err
=
kstrtoul
(
buf
,
10
,
&
val
);
if
(
err
<
0
)
return
err
;
val
=
step_time_to_reg
(
val
,
data
->
pwm_mode
[
nr
]);
mutex_lock
(
&
data
->
update_lock
);
data
->
fan_time
[
index
][
nr
]
=
val
;
nct6775_write_value
(
data
,
data
->
REG_FAN_TIME
[
index
][
nr
],
val
);
mutex_unlock
(
&
data
->
update_lock
);
return
count
;
}
static
ssize_t
static
ssize_t
show_name
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
show_name
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
{
...
@@ -1853,35 +2426,190 @@ show_name(struct device *dev, struct device_attribute *attr, char *buf)
...
@@ -1853,35 +2426,190 @@ show_name(struct device *dev, struct device_attribute *attr, char *buf)
static
DEVICE_ATTR
(
name
,
S_IRUGO
,
show_name
,
NULL
);
static
DEVICE_ATTR
(
name
,
S_IRUGO
,
show_name
,
NULL
);
static
struct
attribute
*
nct6775_attributes_pwm
[
5
][
4
]
=
{
static
SENSOR_DEVICE_ATTR_2
(
pwm1_stop_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
0
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm2_stop_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
1
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm3_stop_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
2
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm4_stop_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
3
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm5_stop_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
4
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm1_step_up_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
0
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm2_step_up_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
1
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm3_step_up_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
2
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm4_step_up_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
3
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm5_step_up_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
4
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm1_step_down_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
0
,
2
);
static
SENSOR_DEVICE_ATTR_2
(
pwm2_step_down_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
1
,
2
);
static
SENSOR_DEVICE_ATTR_2
(
pwm3_step_down_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
2
,
2
);
static
SENSOR_DEVICE_ATTR_2
(
pwm4_step_down_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
3
,
2
);
static
SENSOR_DEVICE_ATTR_2
(
pwm5_step_down_time
,
S_IWUSR
|
S_IRUGO
,
show_fan_time
,
store_fan_time
,
4
,
2
);
static
SENSOR_DEVICE_ATTR_2
(
pwm1_start
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
0
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm2_start
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
1
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm3_start
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
2
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm4_start
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
3
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm5_start
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
4
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm1_floor
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
0
,
2
);
static
SENSOR_DEVICE_ATTR_2
(
pwm2_floor
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
1
,
2
);
static
SENSOR_DEVICE_ATTR_2
(
pwm3_floor
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
2
,
2
);
static
SENSOR_DEVICE_ATTR_2
(
pwm4_floor
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
3
,
2
);
static
SENSOR_DEVICE_ATTR_2
(
pwm5_floor
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
4
,
2
);
static
SENSOR_DEVICE_ATTR_2
(
pwm1_temp_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_temp_tolerance
,
store_temp_tolerance
,
0
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm2_temp_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_temp_tolerance
,
store_temp_tolerance
,
1
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm3_temp_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_temp_tolerance
,
store_temp_tolerance
,
2
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm4_temp_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_temp_tolerance
,
store_temp_tolerance
,
3
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm5_temp_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_temp_tolerance
,
store_temp_tolerance
,
4
,
0
);
static
SENSOR_DEVICE_ATTR_2
(
pwm1_crit_temp_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_temp_tolerance
,
store_temp_tolerance
,
0
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm2_crit_temp_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_temp_tolerance
,
store_temp_tolerance
,
1
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm3_crit_temp_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_temp_tolerance
,
store_temp_tolerance
,
2
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm4_crit_temp_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_temp_tolerance
,
store_temp_tolerance
,
3
,
1
);
static
SENSOR_DEVICE_ATTR_2
(
pwm5_crit_temp_tolerance
,
S_IWUSR
|
S_IRUGO
,
show_temp_tolerance
,
store_temp_tolerance
,
4
,
1
);
/* pwm_max is not supported on all chips */
static
struct
sensor_device_attribute_2
sda_pwm_max
[]
=
{
SENSOR_ATTR_2
(
pwm1_max
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
0
,
3
),
SENSOR_ATTR_2
(
pwm2_max
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
1
,
3
),
SENSOR_ATTR_2
(
pwm3_max
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
2
,
3
),
SENSOR_ATTR_2
(
pwm4_max
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
3
,
3
),
SENSOR_ATTR_2
(
pwm5_max
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
4
,
3
),
};
/* pwm_step is not supported on all chips */
static
struct
sensor_device_attribute_2
sda_pwm_step
[]
=
{
SENSOR_ATTR_2
(
pwm1_step
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
0
,
4
),
SENSOR_ATTR_2
(
pwm2_step
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
1
,
4
),
SENSOR_ATTR_2
(
pwm3_step
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
2
,
4
),
SENSOR_ATTR_2
(
pwm4_step
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
3
,
4
),
SENSOR_ATTR_2
(
pwm5_step
,
S_IWUSR
|
S_IRUGO
,
show_pwm
,
store_pwm
,
4
,
4
),
};
static
struct
attribute
*
nct6775_attributes_pwm
[
5
][
15
]
=
{
{
{
&
sensor_dev_attr_pwm1
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_mode
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_mode
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_enable
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_enable
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_temp_sel
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_temp_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_crit_temp_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_target_temp
.
dev_attr
.
attr
,
&
sensor_dev_attr_fan1_target
.
dev_attr
.
attr
,
&
sensor_dev_attr_fan1_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_stop_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_step_up_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_step_down_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_start
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm1_floor
.
dev_attr
.
attr
,
NULL
NULL
},
},
{
{
&
sensor_dev_attr_pwm2
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_mode
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_mode
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_enable
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_enable
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_temp_sel
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_temp_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_crit_temp_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_target_temp
.
dev_attr
.
attr
,
&
sensor_dev_attr_fan2_target
.
dev_attr
.
attr
,
&
sensor_dev_attr_fan2_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_stop_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_step_up_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_step_down_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_start
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm2_floor
.
dev_attr
.
attr
,
NULL
NULL
},
},
{
{
&
sensor_dev_attr_pwm3
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_mode
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_mode
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_enable
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_enable
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_temp_sel
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_temp_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_crit_temp_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_target_temp
.
dev_attr
.
attr
,
&
sensor_dev_attr_fan3_target
.
dev_attr
.
attr
,
&
sensor_dev_attr_fan3_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_stop_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_step_up_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_step_down_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_start
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm3_floor
.
dev_attr
.
attr
,
NULL
NULL
},
},
{
{
&
sensor_dev_attr_pwm4
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_mode
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_mode
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_enable
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_enable
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_temp_sel
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_temp_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_crit_temp_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_target_temp
.
dev_attr
.
attr
,
&
sensor_dev_attr_fan4_target
.
dev_attr
.
attr
,
&
sensor_dev_attr_fan4_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_stop_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_step_up_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_step_down_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_start
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm4_floor
.
dev_attr
.
attr
,
NULL
NULL
},
},
{
{
&
sensor_dev_attr_pwm5
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_mode
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_mode
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_enable
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_enable
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_temp_sel
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_temp_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_crit_temp_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_target_temp
.
dev_attr
.
attr
,
&
sensor_dev_attr_fan5_target
.
dev_attr
.
attr
,
&
sensor_dev_attr_fan5_tolerance
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_stop_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_step_up_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_step_down_time
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_start
.
dev_attr
.
attr
,
&
sensor_dev_attr_pwm5_floor
.
dev_attr
.
attr
,
NULL
NULL
},
},
};
};
...
@@ -1894,6 +2622,277 @@ static const struct attribute_group nct6775_group_pwm[5] = {
...
@@ -1894,6 +2622,277 @@ static const struct attribute_group nct6775_group_pwm[5] = {
{
.
attrs
=
nct6775_attributes_pwm
[
4
]
},
{
.
attrs
=
nct6775_attributes_pwm
[
4
]
},
};
};
static
ssize_t
show_auto_pwm
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
nct6775_data
*
data
=
nct6775_update_device
(
dev
);
struct
sensor_device_attribute_2
*
sattr
=
to_sensor_dev_attr_2
(
attr
);
return
sprintf
(
buf
,
"%d
\n
"
,
data
->
auto_pwm
[
sattr
->
nr
][
sattr
->
index
]);
}
static
ssize_t
store_auto_pwm
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
nct6775_data
*
data
=
dev_get_drvdata
(
dev
);
struct
sensor_device_attribute_2
*
sattr
=
to_sensor_dev_attr_2
(
attr
);
int
nr
=
sattr
->
nr
;
int
point
=
sattr
->
index
;
unsigned
long
val
;
int
err
;
u8
reg
;
err
=
kstrtoul
(
buf
,
10
,
&
val
);
if
(
err
<
0
)
return
err
;
if
(
val
>
255
)
return
-
EINVAL
;
if
(
point
==
data
->
auto_pwm_num
)
{
if
(
data
->
kind
!=
nct6775
&&
!
val
)
return
-
EINVAL
;
if
(
data
->
kind
!=
nct6779
&&
val
)
val
=
0xff
;
}
mutex_lock
(
&
data
->
update_lock
);
data
->
auto_pwm
[
nr
][
point
]
=
val
;
if
(
point
<
data
->
auto_pwm_num
)
{
nct6775_write_value
(
data
,
NCT6775_AUTO_PWM
(
data
,
nr
,
point
),
data
->
auto_pwm
[
nr
][
point
]);
}
else
{
switch
(
data
->
kind
)
{
case
nct6775
:
/* disable if needed (pwm == 0) */
reg
=
nct6775_read_value
(
data
,
NCT6775_REG_CRITICAL_ENAB
[
nr
]);
if
(
val
)
reg
|=
0x02
;
else
reg
&=
~
0x02
;
nct6775_write_value
(
data
,
NCT6775_REG_CRITICAL_ENAB
[
nr
],
reg
);
break
;
case
nct6776
:
break
;
/* always enabled, nothing to do */
case
nct6779
:
nct6775_write_value
(
data
,
NCT6779_REG_CRITICAL_PWM
[
nr
],
val
);
reg
=
nct6775_read_value
(
data
,
NCT6779_REG_CRITICAL_PWM_ENABLE
[
nr
]);
if
(
val
==
255
)
reg
&=
~
0x01
;
else
reg
|=
0x01
;
nct6775_write_value
(
data
,
NCT6779_REG_CRITICAL_PWM_ENABLE
[
nr
],
reg
);
break
;
}
}
mutex_unlock
(
&
data
->
update_lock
);
return
count
;
}
static
ssize_t
show_auto_temp
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
nct6775_data
*
data
=
nct6775_update_device
(
dev
);
struct
sensor_device_attribute_2
*
sattr
=
to_sensor_dev_attr_2
(
attr
);
int
nr
=
sattr
->
nr
;
int
point
=
sattr
->
index
;
/*
* We don't know for sure if the temperature is signed or unsigned.
* Assume it is unsigned.
*/
return
sprintf
(
buf
,
"%d
\n
"
,
data
->
auto_temp
[
nr
][
point
]
*
1000
);
}
static
ssize_t
store_auto_temp
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
nct6775_data
*
data
=
dev_get_drvdata
(
dev
);
struct
sensor_device_attribute_2
*
sattr
=
to_sensor_dev_attr_2
(
attr
);
int
nr
=
sattr
->
nr
;
int
point
=
sattr
->
index
;
unsigned
long
val
;
int
err
;
err
=
kstrtoul
(
buf
,
10
,
&
val
);
if
(
err
)
return
err
;
if
(
val
>
255000
)
return
-
EINVAL
;
mutex_lock
(
&
data
->
update_lock
);
data
->
auto_temp
[
nr
][
point
]
=
DIV_ROUND_CLOSEST
(
val
,
1000
);
if
(
point
<
data
->
auto_pwm_num
)
{
nct6775_write_value
(
data
,
NCT6775_AUTO_TEMP
(
data
,
nr
,
point
),
data
->
auto_temp
[
nr
][
point
]);
}
else
{
nct6775_write_value
(
data
,
data
->
REG_CRITICAL_TEMP
[
nr
],
data
->
auto_temp
[
nr
][
point
]);
}
mutex_unlock
(
&
data
->
update_lock
);
return
count
;
}
/*
* The number of auto-point trip points is chip dependent.
* Need to check support while generating/removing attribute files.
*/
static
struct
sensor_device_attribute_2
sda_auto_pwm_arrays
[]
=
{
SENSOR_ATTR_2
(
pwm1_auto_point1_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
0
,
0
),
SENSOR_ATTR_2
(
pwm1_auto_point1_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
0
,
0
),
SENSOR_ATTR_2
(
pwm1_auto_point2_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
0
,
1
),
SENSOR_ATTR_2
(
pwm1_auto_point2_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
0
,
1
),
SENSOR_ATTR_2
(
pwm1_auto_point3_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
0
,
2
),
SENSOR_ATTR_2
(
pwm1_auto_point3_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
0
,
2
),
SENSOR_ATTR_2
(
pwm1_auto_point4_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
0
,
3
),
SENSOR_ATTR_2
(
pwm1_auto_point4_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
0
,
3
),
SENSOR_ATTR_2
(
pwm1_auto_point5_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
0
,
4
),
SENSOR_ATTR_2
(
pwm1_auto_point5_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
0
,
4
),
SENSOR_ATTR_2
(
pwm1_auto_point6_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
0
,
5
),
SENSOR_ATTR_2
(
pwm1_auto_point6_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
0
,
5
),
SENSOR_ATTR_2
(
pwm1_auto_point7_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
0
,
6
),
SENSOR_ATTR_2
(
pwm1_auto_point7_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
0
,
6
),
SENSOR_ATTR_2
(
pwm2_auto_point1_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
1
,
0
),
SENSOR_ATTR_2
(
pwm2_auto_point1_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
1
,
0
),
SENSOR_ATTR_2
(
pwm2_auto_point2_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
1
,
1
),
SENSOR_ATTR_2
(
pwm2_auto_point2_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
1
,
1
),
SENSOR_ATTR_2
(
pwm2_auto_point3_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
1
,
2
),
SENSOR_ATTR_2
(
pwm2_auto_point3_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
1
,
2
),
SENSOR_ATTR_2
(
pwm2_auto_point4_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
1
,
3
),
SENSOR_ATTR_2
(
pwm2_auto_point4_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
1
,
3
),
SENSOR_ATTR_2
(
pwm2_auto_point5_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
1
,
4
),
SENSOR_ATTR_2
(
pwm2_auto_point5_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
1
,
4
),
SENSOR_ATTR_2
(
pwm2_auto_point6_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
1
,
5
),
SENSOR_ATTR_2
(
pwm2_auto_point6_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
1
,
5
),
SENSOR_ATTR_2
(
pwm2_auto_point7_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
1
,
6
),
SENSOR_ATTR_2
(
pwm2_auto_point7_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
1
,
6
),
SENSOR_ATTR_2
(
pwm3_auto_point1_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
2
,
0
),
SENSOR_ATTR_2
(
pwm3_auto_point1_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
2
,
0
),
SENSOR_ATTR_2
(
pwm3_auto_point2_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
2
,
1
),
SENSOR_ATTR_2
(
pwm3_auto_point2_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
2
,
1
),
SENSOR_ATTR_2
(
pwm3_auto_point3_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
2
,
2
),
SENSOR_ATTR_2
(
pwm3_auto_point3_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
2
,
2
),
SENSOR_ATTR_2
(
pwm3_auto_point4_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
2
,
3
),
SENSOR_ATTR_2
(
pwm3_auto_point4_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
2
,
3
),
SENSOR_ATTR_2
(
pwm3_auto_point5_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
2
,
4
),
SENSOR_ATTR_2
(
pwm3_auto_point5_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
2
,
4
),
SENSOR_ATTR_2
(
pwm3_auto_point6_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
2
,
5
),
SENSOR_ATTR_2
(
pwm3_auto_point6_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
2
,
5
),
SENSOR_ATTR_2
(
pwm3_auto_point7_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
2
,
6
),
SENSOR_ATTR_2
(
pwm3_auto_point7_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
2
,
6
),
SENSOR_ATTR_2
(
pwm4_auto_point1_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
3
,
0
),
SENSOR_ATTR_2
(
pwm4_auto_point1_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
3
,
0
),
SENSOR_ATTR_2
(
pwm4_auto_point2_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
3
,
1
),
SENSOR_ATTR_2
(
pwm4_auto_point2_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
3
,
1
),
SENSOR_ATTR_2
(
pwm4_auto_point3_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
3
,
2
),
SENSOR_ATTR_2
(
pwm4_auto_point3_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
3
,
2
),
SENSOR_ATTR_2
(
pwm4_auto_point4_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
3
,
3
),
SENSOR_ATTR_2
(
pwm4_auto_point4_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
3
,
3
),
SENSOR_ATTR_2
(
pwm4_auto_point5_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
3
,
4
),
SENSOR_ATTR_2
(
pwm4_auto_point5_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
3
,
4
),
SENSOR_ATTR_2
(
pwm4_auto_point6_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
3
,
5
),
SENSOR_ATTR_2
(
pwm4_auto_point6_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
3
,
5
),
SENSOR_ATTR_2
(
pwm4_auto_point7_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
3
,
6
),
SENSOR_ATTR_2
(
pwm4_auto_point7_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
3
,
6
),
SENSOR_ATTR_2
(
pwm5_auto_point1_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
4
,
0
),
SENSOR_ATTR_2
(
pwm5_auto_point1_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
4
,
0
),
SENSOR_ATTR_2
(
pwm5_auto_point2_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
4
,
1
),
SENSOR_ATTR_2
(
pwm5_auto_point2_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
4
,
1
),
SENSOR_ATTR_2
(
pwm5_auto_point3_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
4
,
2
),
SENSOR_ATTR_2
(
pwm5_auto_point3_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
4
,
2
),
SENSOR_ATTR_2
(
pwm5_auto_point4_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
4
,
3
),
SENSOR_ATTR_2
(
pwm5_auto_point4_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
4
,
3
),
SENSOR_ATTR_2
(
pwm5_auto_point5_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
4
,
4
),
SENSOR_ATTR_2
(
pwm5_auto_point5_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
4
,
4
),
SENSOR_ATTR_2
(
pwm5_auto_point6_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
4
,
5
),
SENSOR_ATTR_2
(
pwm5_auto_point6_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
4
,
5
),
SENSOR_ATTR_2
(
pwm5_auto_point7_pwm
,
S_IWUSR
|
S_IRUGO
,
show_auto_pwm
,
store_auto_pwm
,
4
,
6
),
SENSOR_ATTR_2
(
pwm5_auto_point7_temp
,
S_IWUSR
|
S_IRUGO
,
show_auto_temp
,
store_auto_temp
,
4
,
6
),
};
static
ssize_t
static
ssize_t
show_vid
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
show_vid
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
{
...
@@ -1969,6 +2968,15 @@ static void nct6775_device_remove_files(struct device *dev)
...
@@ -1969,6 +2968,15 @@ static void nct6775_device_remove_files(struct device *dev)
for
(
i
=
0
;
i
<
data
->
pwm_num
;
i
++
)
for
(
i
=
0
;
i
<
data
->
pwm_num
;
i
++
)
sysfs_remove_group
(
&
dev
->
kobj
,
&
nct6775_group_pwm
[
i
]);
sysfs_remove_group
(
&
dev
->
kobj
,
&
nct6775_group_pwm
[
i
]);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
sda_pwm_max
);
i
++
)
device_remove_file
(
dev
,
&
sda_pwm_max
[
i
].
dev_attr
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
sda_pwm_step
);
i
++
)
device_remove_file
(
dev
,
&
sda_pwm_step
[
i
].
dev_attr
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
sda_auto_pwm_arrays
);
i
++
)
device_remove_file
(
dev
,
&
sda_auto_pwm_arrays
[
i
].
dev_attr
);
for
(
i
=
0
;
i
<
data
->
in_num
;
i
++
)
for
(
i
=
0
;
i
<
data
->
in_num
;
i
++
)
sysfs_remove_group
(
&
dev
->
kobj
,
&
nct6775_group_in
[
i
]);
sysfs_remove_group
(
&
dev
->
kobj
,
&
nct6775_group_in
[
i
]);
...
@@ -2161,6 +3169,7 @@ static int nct6775_probe(struct platform_device *pdev)
...
@@ -2161,6 +3169,7 @@ static int nct6775_probe(struct platform_device *pdev)
case
nct6775
:
case
nct6775
:
data
->
in_num
=
9
;
data
->
in_num
=
9
;
data
->
pwm_num
=
3
;
data
->
pwm_num
=
3
;
data
->
auto_pwm_num
=
6
;
data
->
has_fan_div
=
true
;
data
->
has_fan_div
=
true
;
data
->
temp_fixed_num
=
3
;
data
->
temp_fixed_num
=
3
;
...
@@ -2168,6 +3177,9 @@ static int nct6775_probe(struct platform_device *pdev)
...
@@ -2168,6 +3177,9 @@ static int nct6775_probe(struct platform_device *pdev)
data
->
fan_from_reg
=
fan_from_reg16
;
data
->
fan_from_reg
=
fan_from_reg16
;
data
->
fan_from_reg_min
=
fan_from_reg8
;
data
->
fan_from_reg_min
=
fan_from_reg8
;
data
->
target_temp_mask
=
0x7f
;
data
->
tolerance_mask
=
0x0f
;
data
->
speed_tolerance_limit
=
15
;
data
->
temp_label
=
nct6775_temp_label
;
data
->
temp_label
=
nct6775_temp_label
;
data
->
temp_label_num
=
ARRAY_SIZE
(
nct6775_temp_label
);
data
->
temp_label_num
=
ARRAY_SIZE
(
nct6775_temp_label
);
...
@@ -2178,16 +3190,30 @@ static int nct6775_probe(struct platform_device *pdev)
...
@@ -2178,16 +3190,30 @@ static int nct6775_probe(struct platform_device *pdev)
data
->
REG_VIN
=
NCT6775_REG_IN
;
data
->
REG_VIN
=
NCT6775_REG_IN
;
data
->
REG_IN_MINMAX
[
0
]
=
NCT6775_REG_IN_MIN
;
data
->
REG_IN_MINMAX
[
0
]
=
NCT6775_REG_IN_MIN
;
data
->
REG_IN_MINMAX
[
1
]
=
NCT6775_REG_IN_MAX
;
data
->
REG_IN_MINMAX
[
1
]
=
NCT6775_REG_IN_MAX
;
data
->
REG_TARGET
=
NCT6775_REG_TARGET
;
data
->
REG_FAN
=
NCT6775_REG_FAN
;
data
->
REG_FAN
=
NCT6775_REG_FAN
;
data
->
REG_FAN_MODE
=
NCT6775_REG_FAN_MODE
;
data
->
REG_FAN_MODE
=
NCT6775_REG_FAN_MODE
;
data
->
REG_FAN_MIN
=
NCT6775_REG_FAN_MIN
;
data
->
REG_FAN_MIN
=
NCT6775_REG_FAN_MIN
;
data
->
REG_FAN_PULSES
=
NCT6775_REG_FAN_PULSES
;
data
->
REG_FAN_PULSES
=
NCT6775_REG_FAN_PULSES
;
data
->
REG_FAN_TIME
[
0
]
=
NCT6775_REG_FAN_STOP_TIME
;
data
->
REG_FAN_TIME
[
1
]
=
NCT6775_REG_FAN_STEP_UP_TIME
;
data
->
REG_FAN_TIME
[
2
]
=
NCT6775_REG_FAN_STEP_DOWN_TIME
;
data
->
REG_PWM
[
0
]
=
NCT6775_REG_PWM
;
data
->
REG_PWM
[
0
]
=
NCT6775_REG_PWM
;
data
->
REG_PWM
[
1
]
=
NCT6775_REG_FAN_START_OUTPUT
;
data
->
REG_PWM
[
2
]
=
NCT6775_REG_FAN_STOP_OUTPUT
;
data
->
REG_PWM
[
3
]
=
NCT6775_REG_FAN_MAX_OUTPUT
;
data
->
REG_PWM
[
4
]
=
NCT6775_REG_FAN_STEP_OUTPUT
;
data
->
REG_PWM_READ
=
NCT6775_REG_PWM_READ
;
data
->
REG_PWM_READ
=
NCT6775_REG_PWM_READ
;
data
->
REG_PWM_MODE
=
NCT6775_REG_PWM_MODE
;
data
->
REG_PWM_MODE
=
NCT6775_REG_PWM_MODE
;
data
->
PWM_MODE_MASK
=
NCT6775_PWM_MODE_MASK
;
data
->
PWM_MODE_MASK
=
NCT6775_PWM_MODE_MASK
;
data
->
REG_AUTO_TEMP
=
NCT6775_REG_AUTO_TEMP
;
data
->
REG_AUTO_PWM
=
NCT6775_REG_AUTO_PWM
;
data
->
REG_CRITICAL_TEMP
=
NCT6775_REG_CRITICAL_TEMP
;
data
->
REG_CRITICAL_TEMP_TOLERANCE
=
NCT6775_REG_CRITICAL_TEMP_TOLERANCE
;
data
->
REG_TEMP_OFFSET
=
NCT6775_REG_TEMP_OFFSET
;
data
->
REG_TEMP_OFFSET
=
NCT6775_REG_TEMP_OFFSET
;
data
->
REG_TEMP_SOURCE
=
NCT6775_REG_TEMP_SOURCE
;
data
->
REG_TEMP_SOURCE
=
NCT6775_REG_TEMP_SOURCE
;
data
->
REG_TEMP_SEL
=
NCT6775_REG_TEMP_SEL
;
data
->
REG_ALARM
=
NCT6775_REG_ALARM
;
data
->
REG_ALARM
=
NCT6775_REG_ALARM
;
reg_temp
=
NCT6775_REG_TEMP
;
reg_temp
=
NCT6775_REG_TEMP
;
...
@@ -2202,6 +3228,7 @@ static int nct6775_probe(struct platform_device *pdev)
...
@@ -2202,6 +3228,7 @@ static int nct6775_probe(struct platform_device *pdev)
case
nct6776
:
case
nct6776
:
data
->
in_num
=
9
;
data
->
in_num
=
9
;
data
->
pwm_num
=
3
;
data
->
pwm_num
=
3
;
data
->
auto_pwm_num
=
4
;
data
->
has_fan_div
=
false
;
data
->
has_fan_div
=
false
;
data
->
temp_fixed_num
=
3
;
data
->
temp_fixed_num
=
3
;
...
@@ -2209,6 +3236,9 @@ static int nct6775_probe(struct platform_device *pdev)
...
@@ -2209,6 +3236,9 @@ static int nct6775_probe(struct platform_device *pdev)
data
->
fan_from_reg
=
fan_from_reg13
;
data
->
fan_from_reg
=
fan_from_reg13
;
data
->
fan_from_reg_min
=
fan_from_reg13
;
data
->
fan_from_reg_min
=
fan_from_reg13
;
data
->
target_temp_mask
=
0xff
;
data
->
tolerance_mask
=
0x07
;
data
->
speed_tolerance_limit
=
63
;
data
->
temp_label
=
nct6776_temp_label
;
data
->
temp_label
=
nct6776_temp_label
;
data
->
temp_label_num
=
ARRAY_SIZE
(
nct6776_temp_label
);
data
->
temp_label_num
=
ARRAY_SIZE
(
nct6776_temp_label
);
...
@@ -2219,16 +3249,29 @@ static int nct6775_probe(struct platform_device *pdev)
...
@@ -2219,16 +3249,29 @@ static int nct6775_probe(struct platform_device *pdev)
data
->
REG_VIN
=
NCT6775_REG_IN
;
data
->
REG_VIN
=
NCT6775_REG_IN
;
data
->
REG_IN_MINMAX
[
0
]
=
NCT6775_REG_IN_MIN
;
data
->
REG_IN_MINMAX
[
0
]
=
NCT6775_REG_IN_MIN
;
data
->
REG_IN_MINMAX
[
1
]
=
NCT6775_REG_IN_MAX
;
data
->
REG_IN_MINMAX
[
1
]
=
NCT6775_REG_IN_MAX
;
data
->
REG_TARGET
=
NCT6775_REG_TARGET
;
data
->
REG_FAN
=
NCT6775_REG_FAN
;
data
->
REG_FAN
=
NCT6775_REG_FAN
;
data
->
REG_FAN_MODE
=
NCT6775_REG_FAN_MODE
;
data
->
REG_FAN_MODE
=
NCT6775_REG_FAN_MODE
;
data
->
REG_FAN_MIN
=
NCT6776_REG_FAN_MIN
;
data
->
REG_FAN_MIN
=
NCT6776_REG_FAN_MIN
;
data
->
REG_FAN_PULSES
=
NCT6776_REG_FAN_PULSES
;
data
->
REG_FAN_PULSES
=
NCT6776_REG_FAN_PULSES
;
data
->
REG_FAN_TIME
[
0
]
=
NCT6775_REG_FAN_STOP_TIME
;
data
->
REG_FAN_TIME
[
1
]
=
NCT6775_REG_FAN_STEP_UP_TIME
;
data
->
REG_FAN_TIME
[
2
]
=
NCT6775_REG_FAN_STEP_DOWN_TIME
;
data
->
REG_TOLERANCE_H
=
NCT6776_REG_TOLERANCE_H
;
data
->
REG_PWM
[
0
]
=
NCT6775_REG_PWM
;
data
->
REG_PWM
[
0
]
=
NCT6775_REG_PWM
;
data
->
REG_PWM
[
1
]
=
NCT6775_REG_FAN_START_OUTPUT
;
data
->
REG_PWM
[
2
]
=
NCT6775_REG_FAN_STOP_OUTPUT
;
data
->
REG_PWM_READ
=
NCT6775_REG_PWM_READ
;
data
->
REG_PWM_READ
=
NCT6775_REG_PWM_READ
;
data
->
REG_PWM_MODE
=
NCT6776_REG_PWM_MODE
;
data
->
REG_PWM_MODE
=
NCT6776_REG_PWM_MODE
;
data
->
PWM_MODE_MASK
=
NCT6776_PWM_MODE_MASK
;
data
->
PWM_MODE_MASK
=
NCT6776_PWM_MODE_MASK
;
data
->
REG_AUTO_TEMP
=
NCT6775_REG_AUTO_TEMP
;
data
->
REG_AUTO_PWM
=
NCT6775_REG_AUTO_PWM
;
data
->
REG_CRITICAL_TEMP
=
NCT6775_REG_CRITICAL_TEMP
;
data
->
REG_CRITICAL_TEMP_TOLERANCE
=
NCT6775_REG_CRITICAL_TEMP_TOLERANCE
;
data
->
REG_TEMP_OFFSET
=
NCT6775_REG_TEMP_OFFSET
;
data
->
REG_TEMP_OFFSET
=
NCT6775_REG_TEMP_OFFSET
;
data
->
REG_TEMP_SOURCE
=
NCT6775_REG_TEMP_SOURCE
;
data
->
REG_TEMP_SOURCE
=
NCT6775_REG_TEMP_SOURCE
;
data
->
REG_TEMP_SEL
=
NCT6775_REG_TEMP_SEL
;
data
->
REG_ALARM
=
NCT6775_REG_ALARM
;
data
->
REG_ALARM
=
NCT6775_REG_ALARM
;
reg_temp
=
NCT6775_REG_TEMP
;
reg_temp
=
NCT6775_REG_TEMP
;
...
@@ -2243,6 +3286,7 @@ static int nct6775_probe(struct platform_device *pdev)
...
@@ -2243,6 +3286,7 @@ static int nct6775_probe(struct platform_device *pdev)
case
nct6779
:
case
nct6779
:
data
->
in_num
=
15
;
data
->
in_num
=
15
;
data
->
pwm_num
=
5
;
data
->
pwm_num
=
5
;
data
->
auto_pwm_num
=
4
;
data
->
has_fan_div
=
false
;
data
->
has_fan_div
=
false
;
data
->
temp_fixed_num
=
6
;
data
->
temp_fixed_num
=
6
;
...
@@ -2250,6 +3294,9 @@ static int nct6775_probe(struct platform_device *pdev)
...
@@ -2250,6 +3294,9 @@ static int nct6775_probe(struct platform_device *pdev)
data
->
fan_from_reg
=
fan_from_reg13
;
data
->
fan_from_reg
=
fan_from_reg13
;
data
->
fan_from_reg_min
=
fan_from_reg13
;
data
->
fan_from_reg_min
=
fan_from_reg13
;
data
->
target_temp_mask
=
0xff
;
data
->
tolerance_mask
=
0x07
;
data
->
speed_tolerance_limit
=
63
;
data
->
temp_label
=
nct6779_temp_label
;
data
->
temp_label
=
nct6779_temp_label
;
data
->
temp_label_num
=
ARRAY_SIZE
(
nct6779_temp_label
);
data
->
temp_label_num
=
ARRAY_SIZE
(
nct6779_temp_label
);
...
@@ -2260,16 +3307,29 @@ static int nct6775_probe(struct platform_device *pdev)
...
@@ -2260,16 +3307,29 @@ static int nct6775_probe(struct platform_device *pdev)
data
->
REG_VIN
=
NCT6779_REG_IN
;
data
->
REG_VIN
=
NCT6779_REG_IN
;
data
->
REG_IN_MINMAX
[
0
]
=
NCT6775_REG_IN_MIN
;
data
->
REG_IN_MINMAX
[
0
]
=
NCT6775_REG_IN_MIN
;
data
->
REG_IN_MINMAX
[
1
]
=
NCT6775_REG_IN_MAX
;
data
->
REG_IN_MINMAX
[
1
]
=
NCT6775_REG_IN_MAX
;
data
->
REG_TARGET
=
NCT6775_REG_TARGET
;
data
->
REG_FAN
=
NCT6779_REG_FAN
;
data
->
REG_FAN
=
NCT6779_REG_FAN
;
data
->
REG_FAN_MODE
=
NCT6775_REG_FAN_MODE
;
data
->
REG_FAN_MODE
=
NCT6775_REG_FAN_MODE
;
data
->
REG_FAN_MIN
=
NCT6776_REG_FAN_MIN
;
data
->
REG_FAN_MIN
=
NCT6776_REG_FAN_MIN
;
data
->
REG_FAN_PULSES
=
NCT6779_REG_FAN_PULSES
;
data
->
REG_FAN_PULSES
=
NCT6779_REG_FAN_PULSES
;
data
->
REG_FAN_TIME
[
0
]
=
NCT6775_REG_FAN_STOP_TIME
;
data
->
REG_FAN_TIME
[
1
]
=
NCT6775_REG_FAN_STEP_UP_TIME
;
data
->
REG_FAN_TIME
[
2
]
=
NCT6775_REG_FAN_STEP_DOWN_TIME
;
data
->
REG_TOLERANCE_H
=
NCT6776_REG_TOLERANCE_H
;
data
->
REG_PWM
[
0
]
=
NCT6775_REG_PWM
;
data
->
REG_PWM
[
0
]
=
NCT6775_REG_PWM
;
data
->
REG_PWM
[
1
]
=
NCT6775_REG_FAN_START_OUTPUT
;
data
->
REG_PWM
[
2
]
=
NCT6775_REG_FAN_STOP_OUTPUT
;
data
->
REG_PWM_READ
=
NCT6775_REG_PWM_READ
;
data
->
REG_PWM_READ
=
NCT6775_REG_PWM_READ
;
data
->
REG_PWM_MODE
=
NCT6776_REG_PWM_MODE
;
data
->
REG_PWM_MODE
=
NCT6776_REG_PWM_MODE
;
data
->
PWM_MODE_MASK
=
NCT6776_PWM_MODE_MASK
;
data
->
PWM_MODE_MASK
=
NCT6776_PWM_MODE_MASK
;
data
->
REG_AUTO_TEMP
=
NCT6775_REG_AUTO_TEMP
;
data
->
REG_AUTO_PWM
=
NCT6775_REG_AUTO_PWM
;
data
->
REG_CRITICAL_TEMP
=
NCT6775_REG_CRITICAL_TEMP
;
data
->
REG_CRITICAL_TEMP_TOLERANCE
=
NCT6775_REG_CRITICAL_TEMP_TOLERANCE
;
data
->
REG_TEMP_OFFSET
=
NCT6779_REG_TEMP_OFFSET
;
data
->
REG_TEMP_OFFSET
=
NCT6779_REG_TEMP_OFFSET
;
data
->
REG_TEMP_SOURCE
=
NCT6775_REG_TEMP_SOURCE
;
data
->
REG_TEMP_SOURCE
=
NCT6775_REG_TEMP_SOURCE
;
data
->
REG_TEMP_SEL
=
NCT6775_REG_TEMP_SEL
;
data
->
REG_ALARM
=
NCT6779_REG_ALARM
;
data
->
REG_ALARM
=
NCT6779_REG_ALARM
;
reg_temp
=
NCT6779_REG_TEMP
;
reg_temp
=
NCT6779_REG_TEMP
;
...
@@ -2484,6 +3544,31 @@ static int nct6775_probe(struct platform_device *pdev)
...
@@ -2484,6 +3544,31 @@ static int nct6775_probe(struct platform_device *pdev)
err
=
sysfs_create_group
(
&
dev
->
kobj
,
&
nct6775_group_pwm
[
i
]);
err
=
sysfs_create_group
(
&
dev
->
kobj
,
&
nct6775_group_pwm
[
i
]);
if
(
err
)
if
(
err
)
goto
exit_remove
;
goto
exit_remove
;
if
(
data
->
REG_PWM
[
3
])
{
err
=
device_create_file
(
dev
,
&
sda_pwm_max
[
i
].
dev_attr
);
if
(
err
)
goto
exit_remove
;
}
if
(
data
->
REG_PWM
[
4
])
{
err
=
device_create_file
(
dev
,
&
sda_pwm_step
[
i
].
dev_attr
);
if
(
err
)
goto
exit_remove
;
}
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
sda_auto_pwm_arrays
);
i
++
)
{
struct
sensor_device_attribute_2
*
attr
=
&
sda_auto_pwm_arrays
[
i
];
if
(
!
(
data
->
has_pwm
&
(
1
<<
attr
->
nr
)))
continue
;
if
(
attr
->
index
>
data
->
auto_pwm_num
)
continue
;
err
=
device_create_file
(
dev
,
&
attr
->
dev_attr
);
if
(
err
)
goto
exit_remove
;
}
}
for
(
i
=
0
;
i
<
data
->
in_num
;
i
++
)
{
for
(
i
=
0
;
i
<
data
->
in_num
;
i
++
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录