diff options
Diffstat (limited to 'drivers/hwmon/gl520sm.c')
-rw-r--r-- | drivers/hwmon/gl520sm.c | 408 |
1 files changed, 239 insertions, 169 deletions
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 7c3b73a1623d..40bfdc702dc3 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/jiffies.h> | 27 | #include <linux/jiffies.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/hwmon.h> | 29 | #include <linux/hwmon.h> |
30 | #include <linux/hwmon-sysfs.h> | ||
30 | #include <linux/hwmon-vid.h> | 31 | #include <linux/hwmon-vid.h> |
31 | #include <linux/err.h> | 32 | #include <linux/err.h> |
32 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
@@ -126,93 +127,13 @@ struct gl520_data { | |||
126 | * Sysfs stuff | 127 | * Sysfs stuff |
127 | */ | 128 | */ |
128 | 129 | ||
129 | #define sysfs_r(type, n, item, reg) \ | 130 | static ssize_t get_cpu_vid(struct device *dev, struct device_attribute *attr, |
130 | static ssize_t get_##type##item (struct gl520_data *, char *, int); \ | 131 | char *buf) |
131 | static ssize_t get_##type##n##item (struct device *, struct device_attribute *attr, char *); \ | ||
132 | static ssize_t get_##type##n##item (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
133 | { \ | ||
134 | struct gl520_data *data = gl520_update_device(dev); \ | ||
135 | return get_##type##item(data, buf, (n)); \ | ||
136 | } | ||
137 | |||
138 | #define sysfs_w(type, n, item, reg) \ | ||
139 | static ssize_t set_##type##item (struct i2c_client *, struct gl520_data *, const char *, size_t, int, int); \ | ||
140 | static ssize_t set_##type##n##item (struct device *, struct device_attribute *attr, const char *, size_t); \ | ||
141 | static ssize_t set_##type##n##item (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | ||
142 | { \ | ||
143 | struct i2c_client *client = to_i2c_client(dev); \ | ||
144 | struct gl520_data *data = i2c_get_clientdata(client); \ | ||
145 | return set_##type##item(client, data, buf, count, (n), reg); \ | ||
146 | } | ||
147 | |||
148 | #define sysfs_rw_n(type, n, item, reg) \ | ||
149 | sysfs_r(type, n, item, reg) \ | ||
150 | sysfs_w(type, n, item, reg) \ | ||
151 | static DEVICE_ATTR(type##n##item, S_IRUGO | S_IWUSR, get_##type##n##item, set_##type##n##item); | ||
152 | |||
153 | #define sysfs_ro_n(type, n, item, reg) \ | ||
154 | sysfs_r(type, n, item, reg) \ | ||
155 | static DEVICE_ATTR(type##n##item, S_IRUGO, get_##type##n##item, NULL); | ||
156 | |||
157 | #define sysfs_rw(type, item, reg) \ | ||
158 | sysfs_r(type, 0, item, reg) \ | ||
159 | sysfs_w(type, 0, item, reg) \ | ||
160 | static DEVICE_ATTR(type##item, S_IRUGO | S_IWUSR, get_##type##0##item, set_##type##0##item); | ||
161 | |||
162 | #define sysfs_ro(type, item, reg) \ | ||
163 | sysfs_r(type, 0, item, reg) \ | ||
164 | static DEVICE_ATTR(type##item, S_IRUGO, get_##type##0##item, NULL); | ||
165 | |||
166 | |||
167 | #define sysfs_vid(n) \ | ||
168 | sysfs_ro_n(cpu, n, _vid, GL520_REG_VID_INPUT) | ||
169 | |||
170 | #define sysfs_in(n) \ | ||
171 | sysfs_ro_n(in, n, _input, GL520_REG_IN_INPUT[n]) \ | ||
172 | sysfs_rw_n(in, n, _min, GL520_REG_IN_MIN[n]) \ | ||
173 | sysfs_rw_n(in, n, _max, GL520_REG_IN_MAX[n]) | ||
174 | |||
175 | #define sysfs_fan(n) \ | ||
176 | sysfs_ro_n(fan, n, _input, GL520_REG_FAN_INPUT) \ | ||
177 | sysfs_rw_n(fan, n, _min, GL520_REG_FAN_MIN) \ | ||
178 | sysfs_rw_n(fan, n, _div, GL520_REG_FAN_DIV) | ||
179 | |||
180 | #define sysfs_fan_off(n) \ | ||
181 | sysfs_rw_n(fan, n, _off, GL520_REG_FAN_OFF) | ||
182 | |||
183 | #define sysfs_temp(n) \ | ||
184 | sysfs_ro_n(temp, n, _input, GL520_REG_TEMP_INPUT[(n) - 1]) \ | ||
185 | sysfs_rw_n(temp, n, _max, GL520_REG_TEMP_MAX[(n) - 1]) \ | ||
186 | sysfs_rw_n(temp, n, _max_hyst, GL520_REG_TEMP_MAX_HYST[(n) - 1]) | ||
187 | |||
188 | #define sysfs_alarms() \ | ||
189 | sysfs_ro(alarms, , GL520_REG_ALARMS) \ | ||
190 | sysfs_rw(beep_enable, , GL520_REG_BEEP_ENABLE) \ | ||
191 | sysfs_rw(beep_mask, , GL520_REG_BEEP_MASK) | ||
192 | |||
193 | |||
194 | sysfs_vid(0) | ||
195 | |||
196 | sysfs_in(0) | ||
197 | sysfs_in(1) | ||
198 | sysfs_in(2) | ||
199 | sysfs_in(3) | ||
200 | sysfs_in(4) | ||
201 | |||
202 | sysfs_fan(1) | ||
203 | sysfs_fan(2) | ||
204 | sysfs_fan_off(1) | ||
205 | |||
206 | sysfs_temp(1) | ||
207 | sysfs_temp(2) | ||
208 | |||
209 | sysfs_alarms() | ||
210 | |||
211 | |||
212 | static ssize_t get_cpu_vid(struct gl520_data *data, char *buf, int n) | ||
213 | { | 132 | { |
133 | struct gl520_data *data = gl520_update_device(dev); | ||
214 | return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm)); | 134 | return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm)); |
215 | } | 135 | } |
136 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, get_cpu_vid, NULL); | ||
216 | 137 | ||
217 | #define VDD_FROM_REG(val) (((val)*95+2)/4) | 138 | #define VDD_FROM_REG(val) (((val)*95+2)/4) |
218 | #define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255)) | 139 | #define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255)) |
@@ -220,8 +141,11 @@ static ssize_t get_cpu_vid(struct gl520_data *data, char *buf, int n) | |||
220 | #define IN_FROM_REG(val) ((val)*19) | 141 | #define IN_FROM_REG(val) ((val)*19) |
221 | #define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255)) | 142 | #define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255)) |
222 | 143 | ||
223 | static ssize_t get_in_input(struct gl520_data *data, char *buf, int n) | 144 | static ssize_t get_in_input(struct device *dev, struct device_attribute *attr, |
145 | char *buf) | ||
224 | { | 146 | { |
147 | int n = to_sensor_dev_attr(attr)->index; | ||
148 | struct gl520_data *data = gl520_update_device(dev); | ||
225 | u8 r = data->in_input[n]; | 149 | u8 r = data->in_input[n]; |
226 | 150 | ||
227 | if (n == 0) | 151 | if (n == 0) |
@@ -230,8 +154,11 @@ static ssize_t get_in_input(struct gl520_data *data, char *buf, int n) | |||
230 | return sprintf(buf, "%d\n", IN_FROM_REG(r)); | 154 | return sprintf(buf, "%d\n", IN_FROM_REG(r)); |
231 | } | 155 | } |
232 | 156 | ||
233 | static ssize_t get_in_min(struct gl520_data *data, char *buf, int n) | 157 | static ssize_t get_in_min(struct device *dev, struct device_attribute *attr, |
158 | char *buf) | ||
234 | { | 159 | { |
160 | int n = to_sensor_dev_attr(attr)->index; | ||
161 | struct gl520_data *data = gl520_update_device(dev); | ||
235 | u8 r = data->in_min[n]; | 162 | u8 r = data->in_min[n]; |
236 | 163 | ||
237 | if (n == 0) | 164 | if (n == 0) |
@@ -240,8 +167,11 @@ static ssize_t get_in_min(struct gl520_data *data, char *buf, int n) | |||
240 | return sprintf(buf, "%d\n", IN_FROM_REG(r)); | 167 | return sprintf(buf, "%d\n", IN_FROM_REG(r)); |
241 | } | 168 | } |
242 | 169 | ||
243 | static ssize_t get_in_max(struct gl520_data *data, char *buf, int n) | 170 | static ssize_t get_in_max(struct device *dev, struct device_attribute *attr, |
171 | char *buf) | ||
244 | { | 172 | { |
173 | int n = to_sensor_dev_attr(attr)->index; | ||
174 | struct gl520_data *data = gl520_update_device(dev); | ||
245 | u8 r = data->in_max[n]; | 175 | u8 r = data->in_max[n]; |
246 | 176 | ||
247 | if (n == 0) | 177 | if (n == 0) |
@@ -250,8 +180,12 @@ static ssize_t get_in_max(struct gl520_data *data, char *buf, int n) | |||
250 | return sprintf(buf, "%d\n", IN_FROM_REG(r)); | 180 | return sprintf(buf, "%d\n", IN_FROM_REG(r)); |
251 | } | 181 | } |
252 | 182 | ||
253 | static ssize_t set_in_min(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) | 183 | static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, |
184 | const char *buf, size_t count) | ||
254 | { | 185 | { |
186 | struct i2c_client *client = to_i2c_client(dev); | ||
187 | struct gl520_data *data = i2c_get_clientdata(client); | ||
188 | int n = to_sensor_dev_attr(attr)->index; | ||
255 | long v = simple_strtol(buf, NULL, 10); | 189 | long v = simple_strtol(buf, NULL, 10); |
256 | u8 r; | 190 | u8 r; |
257 | 191 | ||
@@ -265,16 +199,22 @@ static ssize_t set_in_min(struct i2c_client *client, struct gl520_data *data, co | |||
265 | data->in_min[n] = r; | 199 | data->in_min[n] = r; |
266 | 200 | ||
267 | if (n < 4) | 201 | if (n < 4) |
268 | gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff) | r); | 202 | gl520_write_value(client, GL520_REG_IN_MIN[n], |
203 | (gl520_read_value(client, GL520_REG_IN_MIN[n]) | ||
204 | & ~0xff) | r); | ||
269 | else | 205 | else |
270 | gl520_write_value(client, reg, r); | 206 | gl520_write_value(client, GL520_REG_IN_MIN[n], r); |
271 | 207 | ||
272 | mutex_unlock(&data->update_lock); | 208 | mutex_unlock(&data->update_lock); |
273 | return count; | 209 | return count; |
274 | } | 210 | } |
275 | 211 | ||
276 | static ssize_t set_in_max(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) | 212 | static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, |
213 | const char *buf, size_t count) | ||
277 | { | 214 | { |
215 | struct i2c_client *client = to_i2c_client(dev); | ||
216 | struct gl520_data *data = i2c_get_clientdata(client); | ||
217 | int n = to_sensor_dev_attr(attr)->index; | ||
278 | long v = simple_strtol(buf, NULL, 10); | 218 | long v = simple_strtol(buf, NULL, 10); |
279 | u8 r; | 219 | u8 r; |
280 | 220 | ||
@@ -288,57 +228,109 @@ static ssize_t set_in_max(struct i2c_client *client, struct gl520_data *data, co | |||
288 | data->in_max[n] = r; | 228 | data->in_max[n] = r; |
289 | 229 | ||
290 | if (n < 4) | 230 | if (n < 4) |
291 | gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff00) | (r << 8)); | 231 | gl520_write_value(client, GL520_REG_IN_MAX[n], |
232 | (gl520_read_value(client, GL520_REG_IN_MAX[n]) | ||
233 | & ~0xff00) | (r << 8)); | ||
292 | else | 234 | else |
293 | gl520_write_value(client, reg, r); | 235 | gl520_write_value(client, GL520_REG_IN_MAX[n], r); |
294 | 236 | ||
295 | mutex_unlock(&data->update_lock); | 237 | mutex_unlock(&data->update_lock); |
296 | return count; | 238 | return count; |
297 | } | 239 | } |
298 | 240 | ||
241 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, get_in_input, NULL, 0); | ||
242 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, get_in_input, NULL, 1); | ||
243 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, get_in_input, NULL, 2); | ||
244 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, get_in_input, NULL, 3); | ||
245 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, get_in_input, NULL, 4); | ||
246 | static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR, | ||
247 | get_in_min, set_in_min, 0); | ||
248 | static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO | S_IWUSR, | ||
249 | get_in_min, set_in_min, 1); | ||
250 | static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO | S_IWUSR, | ||
251 | get_in_min, set_in_min, 2); | ||
252 | static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO | S_IWUSR, | ||
253 | get_in_min, set_in_min, 3); | ||
254 | static SENSOR_DEVICE_ATTR(in4_min, S_IRUGO | S_IWUSR, | ||
255 | get_in_min, set_in_min, 4); | ||
256 | static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, | ||
257 | get_in_max, set_in_max, 0); | ||
258 | static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR, | ||
259 | get_in_max, set_in_max, 1); | ||
260 | static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO | S_IWUSR, | ||
261 | get_in_max, set_in_max, 2); | ||
262 | static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO | S_IWUSR, | ||
263 | get_in_max, set_in_max, 3); | ||
264 | static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR, | ||
265 | get_in_max, set_in_max, 4); | ||
266 | |||
299 | #define DIV_FROM_REG(val) (1 << (val)) | 267 | #define DIV_FROM_REG(val) (1 << (val)) |
300 | #define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val) << (div)))) | 268 | #define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val) << (div)))) |
301 | #define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255)); | 269 | #define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255)); |
302 | 270 | ||
303 | static ssize_t get_fan_input(struct gl520_data *data, char *buf, int n) | 271 | static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr, |
272 | char *buf) | ||
304 | { | 273 | { |
305 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_input[n - 1], data->fan_div[n - 1])); | 274 | int n = to_sensor_dev_attr(attr)->index; |
275 | struct gl520_data *data = gl520_update_device(dev); | ||
276 | |||
277 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_input[n], | ||
278 | data->fan_div[n])); | ||
306 | } | 279 | } |
307 | 280 | ||
308 | static ssize_t get_fan_min(struct gl520_data *data, char *buf, int n) | 281 | static ssize_t get_fan_min(struct device *dev, struct device_attribute *attr, |
282 | char *buf) | ||
309 | { | 283 | { |
310 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[n - 1], data->fan_div[n - 1])); | 284 | int n = to_sensor_dev_attr(attr)->index; |
285 | struct gl520_data *data = gl520_update_device(dev); | ||
286 | |||
287 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[n], | ||
288 | data->fan_div[n])); | ||
311 | } | 289 | } |
312 | 290 | ||
313 | static ssize_t get_fan_div(struct gl520_data *data, char *buf, int n) | 291 | static ssize_t get_fan_div(struct device *dev, struct device_attribute *attr, |
292 | char *buf) | ||
314 | { | 293 | { |
315 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[n - 1])); | 294 | int n = to_sensor_dev_attr(attr)->index; |
295 | struct gl520_data *data = gl520_update_device(dev); | ||
296 | |||
297 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[n])); | ||
316 | } | 298 | } |
317 | 299 | ||
318 | static ssize_t get_fan_off(struct gl520_data *data, char *buf, int n) | 300 | static ssize_t get_fan_off(struct device *dev, struct device_attribute *attr, |
301 | char *buf) | ||
319 | { | 302 | { |
303 | struct gl520_data *data = gl520_update_device(dev); | ||
320 | return sprintf(buf, "%d\n", data->fan_off); | 304 | return sprintf(buf, "%d\n", data->fan_off); |
321 | } | 305 | } |
322 | 306 | ||
323 | static ssize_t set_fan_min(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) | 307 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, |
308 | const char *buf, size_t count) | ||
324 | { | 309 | { |
310 | struct i2c_client *client = to_i2c_client(dev); | ||
311 | struct gl520_data *data = i2c_get_clientdata(client); | ||
312 | int n = to_sensor_dev_attr(attr)->index; | ||
325 | unsigned long v = simple_strtoul(buf, NULL, 10); | 313 | unsigned long v = simple_strtoul(buf, NULL, 10); |
326 | u8 r; | 314 | u8 r; |
327 | 315 | ||
328 | mutex_lock(&data->update_lock); | 316 | mutex_lock(&data->update_lock); |
329 | r = FAN_TO_REG(v, data->fan_div[n - 1]); | 317 | r = FAN_TO_REG(v, data->fan_div[n]); |
330 | data->fan_min[n - 1] = r; | 318 | data->fan_min[n] = r; |
331 | 319 | ||
332 | if (n == 1) | 320 | if (n == 0) |
333 | gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff00) | (r << 8)); | 321 | gl520_write_value(client, GL520_REG_FAN_MIN, |
322 | (gl520_read_value(client, GL520_REG_FAN_MIN) | ||
323 | & ~0xff00) | (r << 8)); | ||
334 | else | 324 | else |
335 | gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff) | r); | 325 | gl520_write_value(client, GL520_REG_FAN_MIN, |
326 | (gl520_read_value(client, GL520_REG_FAN_MIN) | ||
327 | & ~0xff) | r); | ||
336 | 328 | ||
337 | data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK); | 329 | data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK); |
338 | if (data->fan_min[n - 1] == 0) | 330 | if (data->fan_min[n] == 0) |
339 | data->alarm_mask &= (n == 1) ? ~0x20 : ~0x40; | 331 | data->alarm_mask &= (n == 0) ? ~0x20 : ~0x40; |
340 | else | 332 | else |
341 | data->alarm_mask |= (n == 1) ? 0x20 : 0x40; | 333 | data->alarm_mask |= (n == 0) ? 0x20 : 0x40; |
342 | data->beep_mask &= data->alarm_mask; | 334 | data->beep_mask &= data->alarm_mask; |
343 | gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask); | 335 | gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask); |
344 | 336 | ||
@@ -346,8 +338,12 @@ static ssize_t set_fan_min(struct i2c_client *client, struct gl520_data *data, c | |||
346 | return count; | 338 | return count; |
347 | } | 339 | } |
348 | 340 | ||
349 | static ssize_t set_fan_div(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) | 341 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, |
342 | const char *buf, size_t count) | ||
350 | { | 343 | { |
344 | struct i2c_client *client = to_i2c_client(dev); | ||
345 | struct gl520_data *data = i2c_get_clientdata(client); | ||
346 | int n = to_sensor_dev_attr(attr)->index; | ||
351 | unsigned long v = simple_strtoul(buf, NULL, 10); | 347 | unsigned long v = simple_strtoul(buf, NULL, 10); |
352 | u8 r; | 348 | u8 r; |
353 | 349 | ||
@@ -362,133 +358,207 @@ static ssize_t set_fan_div(struct i2c_client *client, struct gl520_data *data, c | |||
362 | } | 358 | } |
363 | 359 | ||
364 | mutex_lock(&data->update_lock); | 360 | mutex_lock(&data->update_lock); |
365 | data->fan_div[n - 1] = r; | 361 | data->fan_div[n] = r; |
366 | 362 | ||
367 | if (n == 1) | 363 | if (n == 0) |
368 | gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xc0) | (r << 6)); | 364 | gl520_write_value(client, GL520_REG_FAN_DIV, |
365 | (gl520_read_value(client, GL520_REG_FAN_DIV) | ||
366 | & ~0xc0) | (r << 6)); | ||
369 | else | 367 | else |
370 | gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x30) | (r << 4)); | 368 | gl520_write_value(client, GL520_REG_FAN_DIV, |
369 | (gl520_read_value(client, GL520_REG_FAN_DIV) | ||
370 | & ~0x30) | (r << 4)); | ||
371 | 371 | ||
372 | mutex_unlock(&data->update_lock); | 372 | mutex_unlock(&data->update_lock); |
373 | return count; | 373 | return count; |
374 | } | 374 | } |
375 | 375 | ||
376 | static ssize_t set_fan_off(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) | 376 | static ssize_t set_fan_off(struct device *dev, struct device_attribute *attr, |
377 | const char *buf, size_t count) | ||
377 | { | 378 | { |
379 | struct i2c_client *client = to_i2c_client(dev); | ||
380 | struct gl520_data *data = i2c_get_clientdata(client); | ||
378 | u8 r = simple_strtoul(buf, NULL, 10)?1:0; | 381 | u8 r = simple_strtoul(buf, NULL, 10)?1:0; |
379 | 382 | ||
380 | mutex_lock(&data->update_lock); | 383 | mutex_lock(&data->update_lock); |
381 | data->fan_off = r; | 384 | data->fan_off = r; |
382 | gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x0c) | (r << 2)); | 385 | gl520_write_value(client, GL520_REG_FAN_OFF, |
386 | (gl520_read_value(client, GL520_REG_FAN_OFF) | ||
387 | & ~0x0c) | (r << 2)); | ||
383 | mutex_unlock(&data->update_lock); | 388 | mutex_unlock(&data->update_lock); |
384 | return count; | 389 | return count; |
385 | } | 390 | } |
386 | 391 | ||
392 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan_input, NULL, 0); | ||
393 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan_input, NULL, 1); | ||
394 | static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR, | ||
395 | get_fan_min, set_fan_min, 0); | ||
396 | static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR, | ||
397 | get_fan_min, set_fan_min, 1); | ||
398 | static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, | ||
399 | get_fan_div, set_fan_div, 0); | ||
400 | static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, | ||
401 | get_fan_div, set_fan_div, 1); | ||
402 | static DEVICE_ATTR(fan1_off, S_IRUGO | S_IWUSR, | ||
403 | get_fan_off, set_fan_off); | ||
404 | |||
387 | #define TEMP_FROM_REG(val) (((val) - 130) * 1000) | 405 | #define TEMP_FROM_REG(val) (((val) - 130) * 1000) |
388 | #define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-500:(val)+500) / 1000)+130),0,255)) | 406 | #define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-500:(val)+500) / 1000)+130),0,255)) |
389 | 407 | ||
390 | static ssize_t get_temp_input(struct gl520_data *data, char *buf, int n) | 408 | static ssize_t get_temp_input(struct device *dev, struct device_attribute *attr, |
409 | char *buf) | ||
391 | { | 410 | { |
392 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_input[n - 1])); | 411 | int n = to_sensor_dev_attr(attr)->index; |
412 | struct gl520_data *data = gl520_update_device(dev); | ||
413 | |||
414 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_input[n])); | ||
393 | } | 415 | } |
394 | 416 | ||
395 | static ssize_t get_temp_max(struct gl520_data *data, char *buf, int n) | 417 | static ssize_t get_temp_max(struct device *dev, struct device_attribute *attr, |
418 | char *buf) | ||
396 | { | 419 | { |
397 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[n - 1])); | 420 | int n = to_sensor_dev_attr(attr)->index; |
421 | struct gl520_data *data = gl520_update_device(dev); | ||
422 | |||
423 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[n])); | ||
398 | } | 424 | } |
399 | 425 | ||
400 | static ssize_t get_temp_max_hyst(struct gl520_data *data, char *buf, int n) | 426 | static ssize_t get_temp_max_hyst(struct device *dev, struct device_attribute |
427 | *attr, char *buf) | ||
401 | { | 428 | { |
402 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max_hyst[n - 1])); | 429 | int n = to_sensor_dev_attr(attr)->index; |
430 | struct gl520_data *data = gl520_update_device(dev); | ||
431 | |||
432 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max_hyst[n])); | ||
403 | } | 433 | } |
404 | 434 | ||
405 | static ssize_t set_temp_max(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) | 435 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, |
436 | const char *buf, size_t count) | ||
406 | { | 437 | { |
438 | struct i2c_client *client = to_i2c_client(dev); | ||
439 | struct gl520_data *data = i2c_get_clientdata(client); | ||
440 | int n = to_sensor_dev_attr(attr)->index; | ||
407 | long v = simple_strtol(buf, NULL, 10); | 441 | long v = simple_strtol(buf, NULL, 10); |
408 | 442 | ||
409 | mutex_lock(&data->update_lock); | 443 | mutex_lock(&data->update_lock); |
410 | data->temp_max[n - 1] = TEMP_TO_REG(v); | 444 | data->temp_max[n] = TEMP_TO_REG(v); |
411 | gl520_write_value(client, reg, data->temp_max[n - 1]); | 445 | gl520_write_value(client, GL520_REG_TEMP_MAX[n], data->temp_max[n]); |
412 | mutex_unlock(&data->update_lock); | 446 | mutex_unlock(&data->update_lock); |
413 | return count; | 447 | return count; |
414 | } | 448 | } |
415 | 449 | ||
416 | static ssize_t set_temp_max_hyst(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) | 450 | static ssize_t set_temp_max_hyst(struct device *dev, struct device_attribute |
451 | *attr, const char *buf, size_t count) | ||
417 | { | 452 | { |
453 | struct i2c_client *client = to_i2c_client(dev); | ||
454 | struct gl520_data *data = i2c_get_clientdata(client); | ||
455 | int n = to_sensor_dev_attr(attr)->index; | ||
418 | long v = simple_strtol(buf, NULL, 10); | 456 | long v = simple_strtol(buf, NULL, 10); |
419 | 457 | ||
420 | mutex_lock(&data->update_lock); | 458 | mutex_lock(&data->update_lock); |
421 | data->temp_max_hyst[n - 1] = TEMP_TO_REG(v); | 459 | data->temp_max_hyst[n] = TEMP_TO_REG(v); |
422 | gl520_write_value(client, reg, data->temp_max_hyst[n - 1]); | 460 | gl520_write_value(client, GL520_REG_TEMP_MAX_HYST[n], |
461 | data->temp_max_hyst[n]); | ||
423 | mutex_unlock(&data->update_lock); | 462 | mutex_unlock(&data->update_lock); |
424 | return count; | 463 | return count; |
425 | } | 464 | } |
426 | 465 | ||
427 | static ssize_t get_alarms(struct gl520_data *data, char *buf, int n) | 466 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_temp_input, NULL, 0); |
467 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_temp_input, NULL, 1); | ||
468 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, | ||
469 | get_temp_max, set_temp_max, 0); | ||
470 | static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR, | ||
471 | get_temp_max, set_temp_max, 1); | ||
472 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, | ||
473 | get_temp_max_hyst, set_temp_max_hyst, 0); | ||
474 | static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, | ||
475 | get_temp_max_hyst, set_temp_max_hyst, 1); | ||
476 | |||
477 | static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, | ||
478 | char *buf) | ||
428 | { | 479 | { |
480 | struct gl520_data *data = gl520_update_device(dev); | ||
429 | return sprintf(buf, "%d\n", data->alarms); | 481 | return sprintf(buf, "%d\n", data->alarms); |
430 | } | 482 | } |
431 | 483 | ||
432 | static ssize_t get_beep_enable(struct gl520_data *data, char *buf, int n) | 484 | static ssize_t get_beep_enable(struct device *dev, struct device_attribute |
485 | *attr, char *buf) | ||
433 | { | 486 | { |
487 | struct gl520_data *data = gl520_update_device(dev); | ||
434 | return sprintf(buf, "%d\n", data->beep_enable); | 488 | return sprintf(buf, "%d\n", data->beep_enable); |
435 | } | 489 | } |
436 | 490 | ||
437 | static ssize_t get_beep_mask(struct gl520_data *data, char *buf, int n) | 491 | static ssize_t get_beep_mask(struct device *dev, struct device_attribute *attr, |
492 | char *buf) | ||
438 | { | 493 | { |
494 | struct gl520_data *data = gl520_update_device(dev); | ||
439 | return sprintf(buf, "%d\n", data->beep_mask); | 495 | return sprintf(buf, "%d\n", data->beep_mask); |
440 | } | 496 | } |
441 | 497 | ||
442 | static ssize_t set_beep_enable(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) | 498 | static ssize_t set_beep_enable(struct device *dev, struct device_attribute |
499 | *attr, const char *buf, size_t count) | ||
443 | { | 500 | { |
501 | struct i2c_client *client = to_i2c_client(dev); | ||
502 | struct gl520_data *data = i2c_get_clientdata(client); | ||
444 | u8 r = simple_strtoul(buf, NULL, 10)?0:1; | 503 | u8 r = simple_strtoul(buf, NULL, 10)?0:1; |
445 | 504 | ||
446 | mutex_lock(&data->update_lock); | 505 | mutex_lock(&data->update_lock); |
447 | data->beep_enable = !r; | 506 | data->beep_enable = !r; |
448 | gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x04) | (r << 2)); | 507 | gl520_write_value(client, GL520_REG_BEEP_ENABLE, |
508 | (gl520_read_value(client, GL520_REG_BEEP_ENABLE) | ||
509 | & ~0x04) | (r << 2)); | ||
449 | mutex_unlock(&data->update_lock); | 510 | mutex_unlock(&data->update_lock); |
450 | return count; | 511 | return count; |
451 | } | 512 | } |
452 | 513 | ||
453 | static ssize_t set_beep_mask(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) | 514 | static ssize_t set_beep_mask(struct device *dev, struct device_attribute *attr, |
515 | const char *buf, size_t count) | ||
454 | { | 516 | { |
517 | struct i2c_client *client = to_i2c_client(dev); | ||
518 | struct gl520_data *data = i2c_get_clientdata(client); | ||
455 | u8 r = simple_strtoul(buf, NULL, 10); | 519 | u8 r = simple_strtoul(buf, NULL, 10); |
456 | 520 | ||
457 | mutex_lock(&data->update_lock); | 521 | mutex_lock(&data->update_lock); |
458 | r &= data->alarm_mask; | 522 | r &= data->alarm_mask; |
459 | data->beep_mask = r; | 523 | data->beep_mask = r; |
460 | gl520_write_value(client, reg, r); | 524 | gl520_write_value(client, GL520_REG_BEEP_MASK, r); |
461 | mutex_unlock(&data->update_lock); | 525 | mutex_unlock(&data->update_lock); |
462 | return count; | 526 | return count; |
463 | } | 527 | } |
464 | 528 | ||
529 | static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); | ||
530 | static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, | ||
531 | get_beep_enable, set_beep_enable); | ||
532 | static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR, | ||
533 | get_beep_mask, set_beep_mask); | ||
534 | |||
465 | static struct attribute *gl520_attributes[] = { | 535 | static struct attribute *gl520_attributes[] = { |
466 | &dev_attr_cpu0_vid.attr, | 536 | &dev_attr_cpu0_vid.attr, |
467 | 537 | ||
468 | &dev_attr_in0_input.attr, | 538 | &sensor_dev_attr_in0_input.dev_attr.attr, |
469 | &dev_attr_in0_min.attr, | 539 | &sensor_dev_attr_in0_min.dev_attr.attr, |
470 | &dev_attr_in0_max.attr, | 540 | &sensor_dev_attr_in0_max.dev_attr.attr, |
471 | &dev_attr_in1_input.attr, | 541 | &sensor_dev_attr_in1_input.dev_attr.attr, |
472 | &dev_attr_in1_min.attr, | 542 | &sensor_dev_attr_in1_min.dev_attr.attr, |
473 | &dev_attr_in1_max.attr, | 543 | &sensor_dev_attr_in1_max.dev_attr.attr, |
474 | &dev_attr_in2_input.attr, | 544 | &sensor_dev_attr_in2_input.dev_attr.attr, |
475 | &dev_attr_in2_min.attr, | 545 | &sensor_dev_attr_in2_min.dev_attr.attr, |
476 | &dev_attr_in2_max.attr, | 546 | &sensor_dev_attr_in2_max.dev_attr.attr, |
477 | &dev_attr_in3_input.attr, | 547 | &sensor_dev_attr_in3_input.dev_attr.attr, |
478 | &dev_attr_in3_min.attr, | 548 | &sensor_dev_attr_in3_min.dev_attr.attr, |
479 | &dev_attr_in3_max.attr, | 549 | &sensor_dev_attr_in3_max.dev_attr.attr, |
480 | 550 | ||
481 | &dev_attr_fan1_input.attr, | 551 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
482 | &dev_attr_fan1_min.attr, | 552 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
483 | &dev_attr_fan1_div.attr, | 553 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
484 | &dev_attr_fan1_off.attr, | 554 | &dev_attr_fan1_off.attr, |
485 | &dev_attr_fan2_input.attr, | 555 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
486 | &dev_attr_fan2_min.attr, | 556 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
487 | &dev_attr_fan2_div.attr, | 557 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
488 | 558 | ||
489 | &dev_attr_temp1_input.attr, | 559 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
490 | &dev_attr_temp1_max.attr, | 560 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
491 | &dev_attr_temp1_max_hyst.attr, | 561 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
492 | 562 | ||
493 | &dev_attr_alarms.attr, | 563 | &dev_attr_alarms.attr, |
494 | &dev_attr_beep_enable.attr, | 564 | &dev_attr_beep_enable.attr, |
@@ -501,13 +571,13 @@ static const struct attribute_group gl520_group = { | |||
501 | }; | 571 | }; |
502 | 572 | ||
503 | static struct attribute *gl520_attributes_opt[] = { | 573 | static struct attribute *gl520_attributes_opt[] = { |
504 | &dev_attr_in4_input.attr, | 574 | &sensor_dev_attr_in4_input.dev_attr.attr, |
505 | &dev_attr_in4_min.attr, | 575 | &sensor_dev_attr_in4_min.dev_attr.attr, |
506 | &dev_attr_in4_max.attr, | 576 | &sensor_dev_attr_in4_max.dev_attr.attr, |
507 | 577 | ||
508 | &dev_attr_temp2_input.attr, | 578 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
509 | &dev_attr_temp2_max.attr, | 579 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
510 | &dev_attr_temp2_max_hyst.attr, | 580 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, |
511 | NULL | 581 | NULL |
512 | }; | 582 | }; |
513 | 583 | ||
@@ -579,19 +649,19 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) | |||
579 | 649 | ||
580 | if (data->two_temps) { | 650 | if (data->two_temps) { |
581 | if ((err = device_create_file(&client->dev, | 651 | if ((err = device_create_file(&client->dev, |
582 | &dev_attr_temp2_input)) | 652 | &sensor_dev_attr_temp2_input.dev_attr)) |
583 | || (err = device_create_file(&client->dev, | 653 | || (err = device_create_file(&client->dev, |
584 | &dev_attr_temp2_max)) | 654 | &sensor_dev_attr_temp2_max.dev_attr)) |
585 | || (err = device_create_file(&client->dev, | 655 | || (err = device_create_file(&client->dev, |
586 | &dev_attr_temp2_max_hyst))) | 656 | &sensor_dev_attr_temp2_max_hyst.dev_attr))) |
587 | goto exit_remove_files; | 657 | goto exit_remove_files; |
588 | } else { | 658 | } else { |
589 | if ((err = device_create_file(&client->dev, | 659 | if ((err = device_create_file(&client->dev, |
590 | &dev_attr_in4_input)) | 660 | &sensor_dev_attr_in4_input.dev_attr)) |
591 | || (err = device_create_file(&client->dev, | 661 | || (err = device_create_file(&client->dev, |
592 | &dev_attr_in4_min)) | 662 | &sensor_dev_attr_in4_min.dev_attr)) |
593 | || (err = device_create_file(&client->dev, | 663 | || (err = device_create_file(&client->dev, |
594 | &dev_attr_in4_max))) | 664 | &sensor_dev_attr_in4_max.dev_attr))) |
595 | goto exit_remove_files; | 665 | goto exit_remove_files; |
596 | } | 666 | } |
597 | 667 | ||