1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
/*
* fan_policy.c -- fan policy support
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* Written by Soós Péter <sp@osb.hu>, 2002-2004
* Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
*/
#include "omnibook.h"
#include <linux/ctype.h>
#include "hardware.h"
/*
* Default temperature limits.
* Danger! You may overheat your CPU!
* Do not change these values unless you exactly know what you do.
*/
#define OMNIBOOK_FAN_LEVELS 8
#define OMNIBOOK_FAN_MIN 25 /* Minimal value of fan off temperature */
#define OMNIBOOK_FOT_MAX 75 /* Maximal value of fan off temperature */
#define OMNIBOOK_FAN_MAX 95 /* Maximal value of fan on temperature */
#define OMNIBOOK_FOT_DEFAULT 60 /* Default value of fan off temperature */
#define OMNIBOOK_FAN1_DEFAULT 75 /* Default value of fan on temperature */
#define OMNIBOOK_FAN2_DEFAULT 85 /* Default value of fan level 2 temperature */
#define OMNIBOOK_FAN3_DEFAULT 90 /* Default value of fan level 3 temperature */
#define OMNIBOOK_FAN4_DEFAULT 95 /* Default value of fan level 4 temperature */
#define OMNIBOOK_FAN5_DEFAULT 95 /* Default value of fan level 5 temperature */
#define OMNIBOOK_FAN6_DEFAULT 95 /* Default value of fan level 6 temperature */
#define OMNIBOOK_FAN7_DEFAULT 95 /* Default value of fan level 7 temperature */
static const u8 fan_defaults[] = {
OMNIBOOK_FOT_DEFAULT,
OMNIBOOK_FAN1_DEFAULT,
OMNIBOOK_FAN2_DEFAULT,
OMNIBOOK_FAN3_DEFAULT,
OMNIBOOK_FAN4_DEFAULT,
OMNIBOOK_FAN5_DEFAULT,
OMNIBOOK_FAN6_DEFAULT,
OMNIBOOK_FAN7_DEFAULT,
};
static int omnibook_get_fan_policy(struct omnibook_operation *io_op, u8 *fan_policy)
{
int retval ;
int i;
for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
io_op->read_addr = XE3GF_FOT + i;
if ((retval = __backend_byte_read(io_op, &fan_policy[i])))
return retval;
}
return 0;
}
static int omnibook_set_fan_policy(struct omnibook_operation *io_op, const u8 *fan_policy)
{
int retval;
int i;
if (fan_policy[0] > OMNIBOOK_FOT_MAX)
return -EINVAL;
for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
if ((fan_policy[i] > fan_policy[i + 1])
|| (fan_policy[i] < OMNIBOOK_FAN_MIN)
|| (fan_policy[i] > OMNIBOOK_FAN_MAX))
return -EINVAL;
}
for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
io_op->write_addr = XE3GF_FOT + i;
if ((retval = __backend_byte_write(io_op, fan_policy[i])))
return retval;
}
return 0;
}
static int omnibook_fan_policy_read(char *buffer, struct omnibook_operation *io_op)
{
int retval;
int len = 0;
u8 i;
u8 fan_policy[OMNIBOOK_FAN_LEVELS];
if(mutex_lock_interruptible(&io_op->backend->mutex))
return -ERESTARTSYS;
retval = omnibook_get_fan_policy(io_op, &fan_policy[0]);
mutex_unlock(&io_op->backend->mutex);
if(retval)
return retval;
len += sprintf(buffer + len, "Fan off temperature: %2d C\n", fan_policy[0]);
len += sprintf(buffer + len, "Fan on temperature: %2d C\n", fan_policy[1]);
for (i = 2; i < OMNIBOOK_FAN_LEVELS; i++) {
len +=
sprintf(buffer + len, "Fan level %1d temperature: %2d C\n", i,
fan_policy[i]);
}
len += sprintf(buffer + len, "Minimal temperature to set: %2d C\n", OMNIBOOK_FAN_MIN);
len += sprintf(buffer + len, "Maximal temperature to set: %2d C\n", OMNIBOOK_FAN_MAX);
return len;
}
static int omnibook_fan_policy_write(char *buffer, struct omnibook_operation *io_op)
{
int n = 0;
char *b;
char *endp;
int retval;
int temp;
u8 fan_policy[OMNIBOOK_FAN_LEVELS];
if(mutex_lock_interruptible(&io_op->backend->mutex))
return -ERESTARTSYS;
if ((retval = omnibook_get_fan_policy(io_op, &fan_policy[0])))
goto out;
/*
* Could also be done much simpler using sscanf(,"%u %u ...
* but this would hardcode OMNIBOOK_FAN_LEVELS.
* The parsed format is "%u " repeated OMNIBOOK_FAN_LEVELS+1 times
*/
b = buffer;
do {
dprintk("n=[%i] b=[%s]\n", n, b);
if (n > OMNIBOOK_FAN_LEVELS) {
retval = -EINVAL;
goto out;
}
if (!isspace(*b)) {
temp = simple_strtoul(b, &endp, 10);
if (endp != b) { /* there was a match */
fan_policy[n++] = temp;
b = endp;
} else {
retval = -EINVAL;
goto out;
}
} else
b++;
} while ((*b != '\0') && (*b != '\n'));
/* A zero value set the defaults */
if ((fan_policy[0] == 0) && (n == 1))
retval = omnibook_set_fan_policy(io_op, &fan_defaults[0]);
else
retval = omnibook_set_fan_policy(io_op, &fan_policy[0]);
out:
mutex_unlock(&io_op->backend->mutex);
return retval;
}
static struct omnibook_tbl fan_policy_table[] __initdata = {
{XE3GF, {EC,}},
{0,}
};
static struct omnibook_feature __declared_feature fan_policy_driver = {
.name = "fan_policy",
.enabled = 1,
.read = omnibook_fan_policy_read,
.write = omnibook_fan_policy_write,
.ectypes = XE3GF,
.tbl = fan_policy_table,
};
module_param_named(fan_policy, fan_policy_driver.enabled, int, S_IRUGO);
MODULE_PARM_DESC(fan_policy, "Use 0 to disable, 1 to enable fan control policy support");
/* End of file */
|