x86: make 32bit use irq_cfg_alloc, etc
[deliverable/linux.git] / drivers / hwmon / f71805f.c
CommitLineData
e53004e2 1/*
51c997d8
JD
2 * f71805f.c - driver for the Fintek F71805F/FG and F71872F/FG Super-I/O
3 * chips integrated hardware monitoring features
2d45771e 4 * Copyright (C) 2005-2006 Jean Delvare <khali@linux-fr.org>
e53004e2
JD
5 *
6 * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates
7 * complete hardware monitoring features: voltage, fan and temperature
8 * sensors, and manual and automatic fan speed control.
9 *
51c997d8
JD
10 * The F71872F/FG is almost the same, with two more voltages monitored,
11 * and 6 VID inputs.
12 *
9cab0217
JD
13 * The F71806F/FG is essentially the same as the F71872F/FG. It even has
14 * the same chip ID, so the driver can't differentiate between.
15 *
e53004e2
JD
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/slab.h>
34#include <linux/jiffies.h>
35#include <linux/platform_device.h>
36#include <linux/hwmon.h>
37#include <linux/hwmon-sysfs.h>
38#include <linux/err.h>
f0819184 39#include <linux/mutex.h>
0e39e01c 40#include <linux/sysfs.h>
ce7ee4e8 41#include <linux/ioport.h>
e53004e2
JD
42#include <asm/io.h>
43
67b671bc
JD
44static unsigned short force_id;
45module_param(force_id, ushort, 0);
46MODULE_PARM_DESC(force_id, "Override the detected device ID");
47
e53004e2
JD
48static struct platform_device *pdev;
49
50#define DRVNAME "f71805f"
51c997d8 51enum kinds { f71805f, f71872f };
e53004e2
JD
52
53/*
54 * Super-I/O constants and functions
55 */
56
57#define F71805F_LD_HWM 0x04
58
59#define SIO_REG_LDSEL 0x07 /* Logical device select */
60#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
61#define SIO_REG_DEVREV 0x22 /* Device revision */
62#define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */
51c997d8 63#define SIO_REG_FNSEL1 0x29 /* Multi Function Select 1 (F71872F) */
e53004e2
JD
64#define SIO_REG_ENABLE 0x30 /* Logical device enable */
65#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
66
67#define SIO_FINTEK_ID 0x1934
68#define SIO_F71805F_ID 0x0406
51c997d8 69#define SIO_F71872F_ID 0x0341
e53004e2
JD
70
71static inline int
72superio_inb(int base, int reg)
73{
74 outb(reg, base);
75 return inb(base + 1);
76}
77
78static int
79superio_inw(int base, int reg)
80{
81 int val;
82 outb(reg++, base);
83 val = inb(base + 1) << 8;
84 outb(reg, base);
85 val |= inb(base + 1);
86 return val;
87}
88
89static inline void
90superio_select(int base, int ld)
91{
92 outb(SIO_REG_LDSEL, base);
93 outb(ld, base + 1);
94}
95
96static inline void
97superio_enter(int base)
98{
99 outb(0x87, base);
100 outb(0x87, base);
101}
102
103static inline void
104superio_exit(int base)
105{
106 outb(0xaa, base);
107}
108
109/*
110 * ISA constants
111 */
112
75c99029
JD
113#define REGION_LENGTH 8
114#define ADDR_REG_OFFSET 5
115#define DATA_REG_OFFSET 6
e53004e2 116
e53004e2
JD
117/*
118 * Registers
119 */
120
51c997d8 121/* in nr from 0 to 10 (8-bit values) */
e53004e2 122#define F71805F_REG_IN(nr) (0x10 + (nr))
51c997d8
JD
123#define F71805F_REG_IN_HIGH(nr) ((nr) < 10 ? 0x40 + 2 * (nr) : 0x2E)
124#define F71805F_REG_IN_LOW(nr) ((nr) < 10 ? 0x41 + 2 * (nr) : 0x2F)
e53004e2
JD
125/* fan nr from 0 to 2 (12-bit values, two registers) */
126#define F71805F_REG_FAN(nr) (0x20 + 2 * (nr))
127#define F71805F_REG_FAN_LOW(nr) (0x28 + 2 * (nr))
315c7113 128#define F71805F_REG_FAN_TARGET(nr) (0x69 + 16 * (nr))
e53004e2 129#define F71805F_REG_FAN_CTRL(nr) (0x60 + 16 * (nr))
6e2bc17b 130#define F71805F_REG_PWM_FREQ(nr) (0x63 + 16 * (nr))
95e35312 131#define F71805F_REG_PWM_DUTY(nr) (0x6B + 16 * (nr))
e53004e2
JD
132/* temp nr from 0 to 2 (8-bit values) */
133#define F71805F_REG_TEMP(nr) (0x1B + (nr))
134#define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr))
135#define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr))
136#define F71805F_REG_TEMP_MODE 0x01
aba5073d
PE
137/* pwm/fan pwmnr from 0 to 2, auto point apnr from 0 to 2 */
138/* map Fintek numbers to our numbers as follows: 9->0, 5->1, 1->2 */
139#define F71805F_REG_PWM_AUTO_POINT_TEMP(pwmnr, apnr) \
140 (0xA0 + 0x10 * (pwmnr) + (2 - (apnr)))
141#define F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr) \
142 (0xA4 + 0x10 * (pwmnr) + \
143 2 * (2 - (apnr)))
e53004e2
JD
144
145#define F71805F_REG_START 0x00
146/* status nr from 0 to 2 */
147#define F71805F_REG_STATUS(nr) (0x36 + (nr))
148
6b14a546 149/* individual register bits */
e196783d 150#define FAN_CTRL_DC_MODE 0x10
315c7113 151#define FAN_CTRL_LATCH_FULL 0x08
95e35312
JD
152#define FAN_CTRL_MODE_MASK 0x03
153#define FAN_CTRL_MODE_SPEED 0x00
154#define FAN_CTRL_MODE_TEMPERATURE 0x01
155#define FAN_CTRL_MODE_MANUAL 0x02
6b14a546 156
e53004e2
JD
157/*
158 * Data structures and manipulation thereof
159 */
160
aba5073d
PE
161struct f71805f_auto_point {
162 u8 temp[3];
163 u16 fan[3];
164};
165
e53004e2
JD
166struct f71805f_data {
167 unsigned short addr;
168 const char *name;
1beeffe4 169 struct device *hwmon_dev;
e53004e2 170
f0819184 171 struct mutex update_lock;
e53004e2
JD
172 char valid; /* !=0 if following fields are valid */
173 unsigned long last_updated; /* In jiffies */
174 unsigned long last_limits; /* In jiffies */
175
176 /* Register values */
51c997d8
JD
177 u8 in[11];
178 u8 in_high[11];
179 u8 in_low[11];
180 u16 has_in;
e53004e2
JD
181 u16 fan[3];
182 u16 fan_low[3];
315c7113 183 u16 fan_target[3];
6b14a546 184 u8 fan_ctrl[3];
95e35312 185 u8 pwm[3];
6e2bc17b 186 u8 pwm_freq[3];
e53004e2
JD
187 u8 temp[3];
188 u8 temp_high[3];
189 u8 temp_hyst[3];
190 u8 temp_mode;
2d45771e 191 unsigned long alarms;
aba5073d 192 struct f71805f_auto_point auto_points[3];
e53004e2
JD
193};
194
51c997d8
JD
195struct f71805f_sio_data {
196 enum kinds kind;
197 u8 fnsel1;
198};
199
e53004e2
JD
200static inline long in_from_reg(u8 reg)
201{
202 return (reg * 8);
203}
204
205/* The 2 least significant bits are not used */
206static inline u8 in_to_reg(long val)
207{
208 if (val <= 0)
209 return 0;
210 if (val >= 2016)
211 return 0xfc;
212 return (((val + 16) / 32) << 2);
213}
214
215/* in0 is downscaled by a factor 2 internally */
216static inline long in0_from_reg(u8 reg)
217{
218 return (reg * 16);
219}
220
221static inline u8 in0_to_reg(long val)
222{
223 if (val <= 0)
224 return 0;
225 if (val >= 4032)
226 return 0xfc;
227 return (((val + 32) / 64) << 2);
228}
229
230/* The 4 most significant bits are not used */
231static inline long fan_from_reg(u16 reg)
232{
233 reg &= 0xfff;
234 if (!reg || reg == 0xfff)
235 return 0;
236 return (1500000 / reg);
237}
238
239static inline u16 fan_to_reg(long rpm)
240{
241 /* If the low limit is set below what the chip can measure,
242 store the largest possible 12-bit value in the registers,
243 so that no alarm will ever trigger. */
244 if (rpm < 367)
245 return 0xfff;
246 return (1500000 / rpm);
247}
248
6e2bc17b
JD
249static inline unsigned long pwm_freq_from_reg(u8 reg)
250{
251 unsigned long clock = (reg & 0x80) ? 48000000UL : 1000000UL;
252
253 reg &= 0x7f;
254 if (reg == 0)
255 reg++;
256 return clock / (reg << 8);
257}
258
259static inline u8 pwm_freq_to_reg(unsigned long val)
260{
261 if (val >= 187500) /* The highest we can do */
262 return 0x80;
263 if (val >= 1475) /* Use 48 MHz clock */
264 return 0x80 | (48000000UL / (val << 8));
265 if (val < 31) /* The lowest we can do */
266 return 0x7f;
267 else /* Use 1 MHz clock */
268 return 1000000UL / (val << 8);
269}
270
e196783d
JD
271static inline int pwm_mode_from_reg(u8 reg)
272{
273 return !(reg & FAN_CTRL_DC_MODE);
274}
275
e53004e2
JD
276static inline long temp_from_reg(u8 reg)
277{
278 return (reg * 1000);
279}
280
281static inline u8 temp_to_reg(long val)
282{
283 if (val < 0)
284 val = 0;
285 else if (val > 1000 * 0xff)
286 val = 0xff;
287 return ((val + 500) / 1000);
288}
289
290/*
291 * Device I/O access
292 */
293
7f999aa7 294/* Must be called with data->update_lock held, except during initialization */
e53004e2
JD
295static u8 f71805f_read8(struct f71805f_data *data, u8 reg)
296{
e53004e2 297 outb(reg, data->addr + ADDR_REG_OFFSET);
7f999aa7 298 return inb(data->addr + DATA_REG_OFFSET);
e53004e2
JD
299}
300
7f999aa7 301/* Must be called with data->update_lock held, except during initialization */
e53004e2
JD
302static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val)
303{
e53004e2
JD
304 outb(reg, data->addr + ADDR_REG_OFFSET);
305 outb(val, data->addr + DATA_REG_OFFSET);
e53004e2
JD
306}
307
308/* It is important to read the MSB first, because doing so latches the
7f999aa7
JD
309 value of the LSB, so we are sure both bytes belong to the same value.
310 Must be called with data->update_lock held, except during initialization */
e53004e2
JD
311static u16 f71805f_read16(struct f71805f_data *data, u8 reg)
312{
313 u16 val;
314
e53004e2
JD
315 outb(reg, data->addr + ADDR_REG_OFFSET);
316 val = inb(data->addr + DATA_REG_OFFSET) << 8;
317 outb(++reg, data->addr + ADDR_REG_OFFSET);
318 val |= inb(data->addr + DATA_REG_OFFSET);
e53004e2
JD
319
320 return val;
321}
322
7f999aa7 323/* Must be called with data->update_lock held, except during initialization */
e53004e2
JD
324static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val)
325{
e53004e2
JD
326 outb(reg, data->addr + ADDR_REG_OFFSET);
327 outb(val >> 8, data->addr + DATA_REG_OFFSET);
328 outb(++reg, data->addr + ADDR_REG_OFFSET);
329 outb(val & 0xff, data->addr + DATA_REG_OFFSET);
e53004e2
JD
330}
331
332static struct f71805f_data *f71805f_update_device(struct device *dev)
333{
334 struct f71805f_data *data = dev_get_drvdata(dev);
aba5073d 335 int nr, apnr;
e53004e2 336
f0819184 337 mutex_lock(&data->update_lock);
e53004e2
JD
338
339 /* Limit registers cache is refreshed after 60 seconds */
340 if (time_after(jiffies, data->last_updated + 60 * HZ)
341 || !data->valid) {
51c997d8
JD
342 for (nr = 0; nr < 11; nr++) {
343 if (!(data->has_in & (1 << nr)))
344 continue;
e53004e2
JD
345 data->in_high[nr] = f71805f_read8(data,
346 F71805F_REG_IN_HIGH(nr));
347 data->in_low[nr] = f71805f_read8(data,
348 F71805F_REG_IN_LOW(nr));
349 }
350 for (nr = 0; nr < 3; nr++) {
6b14a546
JD
351 data->fan_low[nr] = f71805f_read16(data,
352 F71805F_REG_FAN_LOW(nr));
315c7113
JD
353 data->fan_target[nr] = f71805f_read16(data,
354 F71805F_REG_FAN_TARGET(nr));
6e2bc17b
JD
355 data->pwm_freq[nr] = f71805f_read8(data,
356 F71805F_REG_PWM_FREQ(nr));
e53004e2
JD
357 }
358 for (nr = 0; nr < 3; nr++) {
359 data->temp_high[nr] = f71805f_read8(data,
360 F71805F_REG_TEMP_HIGH(nr));
361 data->temp_hyst[nr] = f71805f_read8(data,
362 F71805F_REG_TEMP_HYST(nr));
363 }
364 data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE);
aba5073d
PE
365 for (nr = 0; nr < 3; nr++) {
366 for (apnr = 0; apnr < 3; apnr++) {
367 data->auto_points[nr].temp[apnr] =
368 f71805f_read8(data,
369 F71805F_REG_PWM_AUTO_POINT_TEMP(nr,
370 apnr));
371 data->auto_points[nr].fan[apnr] =
372 f71805f_read16(data,
373 F71805F_REG_PWM_AUTO_POINT_FAN(nr,
374 apnr));
375 }
376 }
e53004e2
JD
377
378 data->last_limits = jiffies;
379 }
380
381 /* Measurement registers cache is refreshed after 1 second */
382 if (time_after(jiffies, data->last_updated + HZ)
383 || !data->valid) {
51c997d8
JD
384 for (nr = 0; nr < 11; nr++) {
385 if (!(data->has_in & (1 << nr)))
386 continue;
e53004e2
JD
387 data->in[nr] = f71805f_read8(data,
388 F71805F_REG_IN(nr));
389 }
390 for (nr = 0; nr < 3; nr++) {
6b14a546
JD
391 data->fan[nr] = f71805f_read16(data,
392 F71805F_REG_FAN(nr));
95e35312
JD
393 data->fan_ctrl[nr] = f71805f_read8(data,
394 F71805F_REG_FAN_CTRL(nr));
395 data->pwm[nr] = f71805f_read8(data,
396 F71805F_REG_PWM_DUTY(nr));
e53004e2
JD
397 }
398 for (nr = 0; nr < 3; nr++) {
399 data->temp[nr] = f71805f_read8(data,
400 F71805F_REG_TEMP(nr));
401 }
2d45771e
JD
402 data->alarms = f71805f_read8(data, F71805F_REG_STATUS(0))
403 + (f71805f_read8(data, F71805F_REG_STATUS(1)) << 8)
404 + (f71805f_read8(data, F71805F_REG_STATUS(2)) << 16);
e53004e2
JD
405
406 data->last_updated = jiffies;
407 data->valid = 1;
408 }
409
f0819184 410 mutex_unlock(&data->update_lock);
e53004e2
JD
411
412 return data;
413}
414
415/*
416 * Sysfs interface
417 */
418
419static ssize_t show_in0(struct device *dev, struct device_attribute *devattr,
420 char *buf)
421{
422 struct f71805f_data *data = f71805f_update_device(dev);
51c997d8
JD
423 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
424 int nr = attr->index;
e53004e2 425
51c997d8 426 return sprintf(buf, "%ld\n", in0_from_reg(data->in[nr]));
e53004e2
JD
427}
428
429static ssize_t show_in0_max(struct device *dev, struct device_attribute
430 *devattr, char *buf)
431{
432 struct f71805f_data *data = f71805f_update_device(dev);
51c997d8
JD
433 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
434 int nr = attr->index;
e53004e2 435
51c997d8 436 return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[nr]));
e53004e2
JD
437}
438
439static ssize_t show_in0_min(struct device *dev, struct device_attribute
440 *devattr, char *buf)
441{
442 struct f71805f_data *data = f71805f_update_device(dev);
51c997d8
JD
443 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
444 int nr = attr->index;
e53004e2 445
51c997d8 446 return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[nr]));
e53004e2
JD
447}
448
449static ssize_t set_in0_max(struct device *dev, struct device_attribute
450 *devattr, const char *buf, size_t count)
451{
452 struct f71805f_data *data = dev_get_drvdata(dev);
51c997d8
JD
453 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
454 int nr = attr->index;
e53004e2
JD
455 long val = simple_strtol(buf, NULL, 10);
456
f0819184 457 mutex_lock(&data->update_lock);
51c997d8
JD
458 data->in_high[nr] = in0_to_reg(val);
459 f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]);
f0819184 460 mutex_unlock(&data->update_lock);
e53004e2
JD
461
462 return count;
463}
464
465static ssize_t set_in0_min(struct device *dev, struct device_attribute
466 *devattr, const char *buf, size_t count)
467{
468 struct f71805f_data *data = dev_get_drvdata(dev);
51c997d8
JD
469 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
470 int nr = attr->index;
e53004e2
JD
471 long val = simple_strtol(buf, NULL, 10);
472
f0819184 473 mutex_lock(&data->update_lock);
51c997d8
JD
474 data->in_low[nr] = in0_to_reg(val);
475 f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]);
f0819184 476 mutex_unlock(&data->update_lock);
e53004e2
JD
477
478 return count;
479}
480
e53004e2
JD
481static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
482 char *buf)
483{
484 struct f71805f_data *data = f71805f_update_device(dev);
485 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
486 int nr = attr->index;
487
488 return sprintf(buf, "%ld\n", in_from_reg(data->in[nr]));
489}
490
491static ssize_t show_in_max(struct device *dev, struct device_attribute
492 *devattr, char *buf)
493{
494 struct f71805f_data *data = f71805f_update_device(dev);
495 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
496 int nr = attr->index;
497
498 return sprintf(buf, "%ld\n", in_from_reg(data->in_high[nr]));
499}
500
501static ssize_t show_in_min(struct device *dev, struct device_attribute
502 *devattr, char *buf)
503{
504 struct f71805f_data *data = f71805f_update_device(dev);
505 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
506 int nr = attr->index;
507
508 return sprintf(buf, "%ld\n", in_from_reg(data->in_low[nr]));
509}
510
511static ssize_t set_in_max(struct device *dev, struct device_attribute
512 *devattr, const char *buf, size_t count)
513{
514 struct f71805f_data *data = dev_get_drvdata(dev);
515 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
516 int nr = attr->index;
517 long val = simple_strtol(buf, NULL, 10);
518
f0819184 519 mutex_lock(&data->update_lock);
e53004e2
JD
520 data->in_high[nr] = in_to_reg(val);
521 f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]);
f0819184 522 mutex_unlock(&data->update_lock);
e53004e2
JD
523
524 return count;
525}
526
527static ssize_t set_in_min(struct device *dev, struct device_attribute
528 *devattr, const char *buf, size_t count)
529{
530 struct f71805f_data *data = dev_get_drvdata(dev);
531 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
532 int nr = attr->index;
533 long val = simple_strtol(buf, NULL, 10);
534
f0819184 535 mutex_lock(&data->update_lock);
e53004e2
JD
536 data->in_low[nr] = in_to_reg(val);
537 f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]);
f0819184 538 mutex_unlock(&data->update_lock);
e53004e2
JD
539
540 return count;
541}
542
e53004e2
JD
543static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
544 char *buf)
545{
546 struct f71805f_data *data = f71805f_update_device(dev);
547 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
548 int nr = attr->index;
549
550 return sprintf(buf, "%ld\n", fan_from_reg(data->fan[nr]));
551}
552
553static ssize_t show_fan_min(struct device *dev, struct device_attribute
554 *devattr, char *buf)
555{
556 struct f71805f_data *data = f71805f_update_device(dev);
557 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
558 int nr = attr->index;
559
560 return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr]));
561}
562
315c7113
JD
563static ssize_t show_fan_target(struct device *dev, struct device_attribute
564 *devattr, char *buf)
565{
566 struct f71805f_data *data = f71805f_update_device(dev);
567 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
568 int nr = attr->index;
569
570 return sprintf(buf, "%ld\n", fan_from_reg(data->fan_target[nr]));
571}
572
e53004e2
JD
573static ssize_t set_fan_min(struct device *dev, struct device_attribute
574 *devattr, const char *buf, size_t count)
575{
576 struct f71805f_data *data = dev_get_drvdata(dev);
577 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
578 int nr = attr->index;
579 long val = simple_strtol(buf, NULL, 10);
580
f0819184 581 mutex_lock(&data->update_lock);
e53004e2
JD
582 data->fan_low[nr] = fan_to_reg(val);
583 f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]);
f0819184 584 mutex_unlock(&data->update_lock);
e53004e2
JD
585
586 return count;
587}
588
315c7113
JD
589static ssize_t set_fan_target(struct device *dev, struct device_attribute
590 *devattr, const char *buf, size_t count)
591{
592 struct f71805f_data *data = dev_get_drvdata(dev);
593 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
594 int nr = attr->index;
595 long val = simple_strtol(buf, NULL, 10);
596
597 mutex_lock(&data->update_lock);
598 data->fan_target[nr] = fan_to_reg(val);
599 f71805f_write16(data, F71805F_REG_FAN_TARGET(nr),
600 data->fan_target[nr]);
601 mutex_unlock(&data->update_lock);
602
603 return count;
604}
605
95e35312
JD
606static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
607 char *buf)
608{
609 struct f71805f_data *data = f71805f_update_device(dev);
610 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
611 int nr = attr->index;
612
613 return sprintf(buf, "%d\n", (int)data->pwm[nr]);
614}
615
616static ssize_t show_pwm_enable(struct device *dev, struct device_attribute
617 *devattr, char *buf)
618{
619 struct f71805f_data *data = f71805f_update_device(dev);
620 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
621 int nr = attr->index;
622 int mode;
623
624 switch (data->fan_ctrl[nr] & FAN_CTRL_MODE_MASK) {
625 case FAN_CTRL_MODE_SPEED:
626 mode = 3;
627 break;
628 case FAN_CTRL_MODE_TEMPERATURE:
629 mode = 2;
630 break;
631 default: /* MANUAL */
632 mode = 1;
633 }
634
635 return sprintf(buf, "%d\n", mode);
636}
637
6e2bc17b
JD
638static ssize_t show_pwm_freq(struct device *dev, struct device_attribute
639 *devattr, char *buf)
640{
641 struct f71805f_data *data = f71805f_update_device(dev);
642 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
643 int nr = attr->index;
644
645 return sprintf(buf, "%lu\n", pwm_freq_from_reg(data->pwm_freq[nr]));
646}
647
e196783d
JD
648static ssize_t show_pwm_mode(struct device *dev, struct device_attribute
649 *devattr, char *buf)
650{
651 struct f71805f_data *data = f71805f_update_device(dev);
652 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
653 int nr = attr->index;
654
655 return sprintf(buf, "%d\n", pwm_mode_from_reg(data->fan_ctrl[nr]));
656}
657
95e35312
JD
658static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
659 const char *buf, size_t count)
660{
661 struct f71805f_data *data = dev_get_drvdata(dev);
662 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
663 int nr = attr->index;
664 unsigned long val = simple_strtoul(buf, NULL, 10);
665
666 if (val > 255)
667 return -EINVAL;
668
669 mutex_lock(&data->update_lock);
670 data->pwm[nr] = val;
671 f71805f_write8(data, F71805F_REG_PWM_DUTY(nr), data->pwm[nr]);
672 mutex_unlock(&data->update_lock);
673
674 return count;
675}
676
677static struct attribute *f71805f_attr_pwm[];
678
679static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
680 *devattr, const char *buf, size_t count)
681{
682 struct f71805f_data *data = dev_get_drvdata(dev);
683 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
684 int nr = attr->index;
685 unsigned long val = simple_strtoul(buf, NULL, 10);
686 u8 reg;
687
688 if (val < 1 || val > 3)
689 return -EINVAL;
690
691 if (val > 1) { /* Automatic mode, user can't set PWM value */
692 if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr],
693 S_IRUGO))
694 dev_dbg(dev, "chmod -w pwm%d failed\n", nr + 1);
695 }
696
697 mutex_lock(&data->update_lock);
698 reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(nr))
699 & ~FAN_CTRL_MODE_MASK;
700 switch (val) {
701 case 1:
702 reg |= FAN_CTRL_MODE_MANUAL;
703 break;
704 case 2:
705 reg |= FAN_CTRL_MODE_TEMPERATURE;
706 break;
707 case 3:
708 reg |= FAN_CTRL_MODE_SPEED;
709 break;
710 }
711 data->fan_ctrl[nr] = reg;
712 f71805f_write8(data, F71805F_REG_FAN_CTRL(nr), reg);
713 mutex_unlock(&data->update_lock);
714
715 if (val == 1) { /* Manual mode, user can set PWM value */
716 if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr],
717 S_IRUGO | S_IWUSR))
718 dev_dbg(dev, "chmod +w pwm%d failed\n", nr + 1);
719 }
720
721 return count;
722}
723
6e2bc17b
JD
724static ssize_t set_pwm_freq(struct device *dev, struct device_attribute
725 *devattr, const char *buf, size_t count)
726{
727 struct f71805f_data *data = dev_get_drvdata(dev);
728 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
729 int nr = attr->index;
730 unsigned long val = simple_strtoul(buf, NULL, 10);
731
732 mutex_lock(&data->update_lock);
733 data->pwm_freq[nr] = pwm_freq_to_reg(val);
734 f71805f_write8(data, F71805F_REG_PWM_FREQ(nr), data->pwm_freq[nr]);
735 mutex_unlock(&data->update_lock);
736
737 return count;
738}
739
aba5073d
PE
740static ssize_t show_pwm_auto_point_temp(struct device *dev,
741 struct device_attribute *devattr,
742 char* buf)
743{
744 struct f71805f_data *data = dev_get_drvdata(dev);
745 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
746 int pwmnr = attr->nr;
747 int apnr = attr->index;
748
749 return sprintf(buf, "%ld\n",
750 temp_from_reg(data->auto_points[pwmnr].temp[apnr]));
751}
752
753static ssize_t set_pwm_auto_point_temp(struct device *dev,
754 struct device_attribute *devattr,
755 const char* buf, size_t count)
756{
757 struct f71805f_data *data = dev_get_drvdata(dev);
758 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
759 int pwmnr = attr->nr;
760 int apnr = attr->index;
761 unsigned long val = simple_strtol(buf, NULL, 10);
762
763 mutex_lock(&data->update_lock);
764 data->auto_points[pwmnr].temp[apnr] = temp_to_reg(val);
765 f71805f_write8(data, F71805F_REG_PWM_AUTO_POINT_TEMP(pwmnr, apnr),
766 data->auto_points[pwmnr].temp[apnr]);
767 mutex_unlock(&data->update_lock);
768
769 return count;
770}
771
772static ssize_t show_pwm_auto_point_fan(struct device *dev,
773 struct device_attribute *devattr,
774 char* buf)
775{
776 struct f71805f_data *data = dev_get_drvdata(dev);
777 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
778 int pwmnr = attr->nr;
779 int apnr = attr->index;
780
781 return sprintf(buf, "%ld\n",
782 fan_from_reg(data->auto_points[pwmnr].fan[apnr]));
783}
784
785static ssize_t set_pwm_auto_point_fan(struct device *dev,
786 struct device_attribute *devattr,
787 const char* buf, size_t count)
788{
789 struct f71805f_data *data = dev_get_drvdata(dev);
790 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
791 int pwmnr = attr->nr;
792 int apnr = attr->index;
793 unsigned long val = simple_strtoul(buf, NULL, 10);
794
795 mutex_lock(&data->update_lock);
796 data->auto_points[pwmnr].fan[apnr] = fan_to_reg(val);
797 f71805f_write16(data, F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr),
798 data->auto_points[pwmnr].fan[apnr]);
799 mutex_unlock(&data->update_lock);
800
801 return count;
802}
803
e53004e2
JD
804static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
805 char *buf)
806{
807 struct f71805f_data *data = f71805f_update_device(dev);
808 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
809 int nr = attr->index;
810
811 return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr]));
812}
813
814static ssize_t show_temp_max(struct device *dev, struct device_attribute
815 *devattr, char *buf)
816{
817 struct f71805f_data *data = f71805f_update_device(dev);
818 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
819 int nr = attr->index;
820
821 return sprintf(buf, "%ld\n", temp_from_reg(data->temp_high[nr]));
822}
823
824static ssize_t show_temp_hyst(struct device *dev, struct device_attribute
825 *devattr, char *buf)
826{
827 struct f71805f_data *data = f71805f_update_device(dev);
828 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
829 int nr = attr->index;
830
831 return sprintf(buf, "%ld\n", temp_from_reg(data->temp_hyst[nr]));
832}
833
834static ssize_t show_temp_type(struct device *dev, struct device_attribute
835 *devattr, char *buf)
836{
837 struct f71805f_data *data = f71805f_update_device(dev);
838 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
839 int nr = attr->index;
840
841 /* 3 is diode, 4 is thermistor */
842 return sprintf(buf, "%u\n", (data->temp_mode & (1 << nr)) ? 3 : 4);
843}
844
845static ssize_t set_temp_max(struct device *dev, struct device_attribute
846 *devattr, const char *buf, size_t count)
847{
848 struct f71805f_data *data = dev_get_drvdata(dev);
849 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
850 int nr = attr->index;
851 long val = simple_strtol(buf, NULL, 10);
852
f0819184 853 mutex_lock(&data->update_lock);
e53004e2
JD
854 data->temp_high[nr] = temp_to_reg(val);
855 f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]);
f0819184 856 mutex_unlock(&data->update_lock);
e53004e2
JD
857
858 return count;
859}
860
861static ssize_t set_temp_hyst(struct device *dev, struct device_attribute
862 *devattr, const char *buf, size_t count)
863{
864 struct f71805f_data *data = dev_get_drvdata(dev);
865 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
866 int nr = attr->index;
867 long val = simple_strtol(buf, NULL, 10);
868
f0819184 869 mutex_lock(&data->update_lock);
e53004e2
JD
870 data->temp_hyst[nr] = temp_to_reg(val);
871 f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]);
f0819184 872 mutex_unlock(&data->update_lock);
e53004e2
JD
873
874 return count;
875}
876
e53004e2
JD
877static ssize_t show_alarms_in(struct device *dev, struct device_attribute
878 *devattr, char *buf)
879{
880 struct f71805f_data *data = f71805f_update_device(dev);
881
51c997d8 882 return sprintf(buf, "%lu\n", data->alarms & 0x7ff);
e53004e2
JD
883}
884
885static ssize_t show_alarms_fan(struct device *dev, struct device_attribute
886 *devattr, char *buf)
887{
888 struct f71805f_data *data = f71805f_update_device(dev);
889
2d45771e 890 return sprintf(buf, "%lu\n", (data->alarms >> 16) & 0x07);
e53004e2
JD
891}
892
893static ssize_t show_alarms_temp(struct device *dev, struct device_attribute
894 *devattr, char *buf)
895{
896 struct f71805f_data *data = f71805f_update_device(dev);
897
2d45771e
JD
898 return sprintf(buf, "%lu\n", (data->alarms >> 11) & 0x07);
899}
900
901static ssize_t show_alarm(struct device *dev, struct device_attribute
902 *devattr, char *buf)
903{
904 struct f71805f_data *data = f71805f_update_device(dev);
905 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
906 int bitnr = attr->index;
907
908 return sprintf(buf, "%lu\n", (data->alarms >> bitnr) & 1);
e53004e2
JD
909}
910
e53004e2
JD
911static ssize_t show_name(struct device *dev, struct device_attribute
912 *devattr, char *buf)
913{
914 struct f71805f_data *data = dev_get_drvdata(dev);
915
916 return sprintf(buf, "%s\n", data->name);
917}
918
51c997d8
JD
919static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL, 0);
920static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR,
921 show_in0_max, set_in0_max, 0);
922static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR,
923 show_in0_min, set_in0_min, 0);
0e39e01c
JD
924static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1);
925static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR,
926 show_in_max, set_in_max, 1);
927static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO | S_IWUSR,
928 show_in_min, set_in_min, 1);
929static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2);
930static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO | S_IWUSR,
931 show_in_max, set_in_max, 2);
932static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO | S_IWUSR,
933 show_in_min, set_in_min, 2);
934static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3);
935static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO | S_IWUSR,
936 show_in_max, set_in_max, 3);
937static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO | S_IWUSR,
938 show_in_min, set_in_min, 3);
939static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 4);
940static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR,
941 show_in_max, set_in_max, 4);
942static SENSOR_DEVICE_ATTR(in4_min, S_IRUGO | S_IWUSR,
943 show_in_min, set_in_min, 4);
944static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in, NULL, 5);
945static SENSOR_DEVICE_ATTR(in5_max, S_IRUGO | S_IWUSR,
946 show_in_max, set_in_max, 5);
947static SENSOR_DEVICE_ATTR(in5_min, S_IRUGO | S_IWUSR,
948 show_in_min, set_in_min, 5);
949static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in, NULL, 6);
950static SENSOR_DEVICE_ATTR(in6_max, S_IRUGO | S_IWUSR,
951 show_in_max, set_in_max, 6);
952static SENSOR_DEVICE_ATTR(in6_min, S_IRUGO | S_IWUSR,
953 show_in_min, set_in_min, 6);
954static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in, NULL, 7);
955static SENSOR_DEVICE_ATTR(in7_max, S_IRUGO | S_IWUSR,
956 show_in_max, set_in_max, 7);
957static SENSOR_DEVICE_ATTR(in7_min, S_IRUGO | S_IWUSR,
958 show_in_min, set_in_min, 7);
959static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_in, NULL, 8);
960static SENSOR_DEVICE_ATTR(in8_max, S_IRUGO | S_IWUSR,
961 show_in_max, set_in_max, 8);
962static SENSOR_DEVICE_ATTR(in8_min, S_IRUGO | S_IWUSR,
963 show_in_min, set_in_min, 8);
51c997d8
JD
964static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_in0, NULL, 9);
965static SENSOR_DEVICE_ATTR(in9_max, S_IRUGO | S_IWUSR,
966 show_in0_max, set_in0_max, 9);
967static SENSOR_DEVICE_ATTR(in9_min, S_IRUGO | S_IWUSR,
968 show_in0_min, set_in0_min, 9);
969static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_in0, NULL, 10);
970static SENSOR_DEVICE_ATTR(in10_max, S_IRUGO | S_IWUSR,
971 show_in0_max, set_in0_max, 10);
972static SENSOR_DEVICE_ATTR(in10_min, S_IRUGO | S_IWUSR,
973 show_in0_min, set_in0_min, 10);
0e39e01c
JD
974
975static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
976static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR,
977 show_fan_min, set_fan_min, 0);
315c7113
JD
978static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR,
979 show_fan_target, set_fan_target, 0);
0e39e01c
JD
980static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
981static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR,
982 show_fan_min, set_fan_min, 1);
315c7113
JD
983static SENSOR_DEVICE_ATTR(fan2_target, S_IRUGO | S_IWUSR,
984 show_fan_target, set_fan_target, 1);
0e39e01c
JD
985static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
986static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR,
987 show_fan_min, set_fan_min, 2);
315c7113
JD
988static SENSOR_DEVICE_ATTR(fan3_target, S_IRUGO | S_IWUSR,
989 show_fan_target, set_fan_target, 2);
0e39e01c
JD
990
991static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
992static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
993 show_temp_max, set_temp_max, 0);
994static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
995 show_temp_hyst, set_temp_hyst, 0);
996static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0);
997static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
998static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR,
999 show_temp_max, set_temp_max, 1);
1000static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR,
1001 show_temp_hyst, set_temp_hyst, 1);
1002static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1);
1003static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
1004static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO | S_IWUSR,
1005 show_temp_max, set_temp_max, 2);
1006static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR,
1007 show_temp_hyst, set_temp_hyst, 2);
1008static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2);
1009
95e35312
JD
1010/* pwm (value) files are created read-only, write permission is
1011 then added or removed dynamically as needed */
1012static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, show_pwm, set_pwm, 0);
1013static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
1014 show_pwm_enable, set_pwm_enable, 0);
6e2bc17b
JD
1015static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR,
1016 show_pwm_freq, set_pwm_freq, 0);
e196783d 1017static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0);
95e35312
JD
1018static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO, show_pwm, set_pwm, 1);
1019static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
1020 show_pwm_enable, set_pwm_enable, 1);
6e2bc17b
JD
1021static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO | S_IWUSR,
1022 show_pwm_freq, set_pwm_freq, 1);
e196783d 1023static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO, show_pwm_mode, NULL, 1);
95e35312
JD
1024static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO, show_pwm, set_pwm, 2);
1025static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR,
1026 show_pwm_enable, set_pwm_enable, 2);
6e2bc17b
JD
1027static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO | S_IWUSR,
1028 show_pwm_freq, set_pwm_freq, 2);
e196783d 1029static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2);
95e35312 1030
aba5073d
PE
1031static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR,
1032 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1033 0, 0);
1034static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_fan, S_IRUGO | S_IWUSR,
1035 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1036 0, 0);
1037static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR,
1038 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1039 0, 1);
1040static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_fan, S_IRUGO | S_IWUSR,
1041 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1042 0, 1);
1043static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR,
1044 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1045 0, 2);
1046static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_fan, S_IRUGO | S_IWUSR,
1047 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1048 0, 2);
1049
1050static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR,
1051 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1052 1, 0);
1053static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_fan, S_IRUGO | S_IWUSR,
1054 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1055 1, 0);
1056static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR,
1057 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1058 1, 1);
1059static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_fan, S_IRUGO | S_IWUSR,
1060 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1061 1, 1);
1062static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR,
1063 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1064 1, 2);
1065static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_fan, S_IRUGO | S_IWUSR,
1066 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1067 1, 2);
1068
1069static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR,
1070 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1071 2, 0);
1072static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_fan, S_IRUGO | S_IWUSR,
1073 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1074 2, 0);
1075static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR,
1076 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1077 2, 1);
1078static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_fan, S_IRUGO | S_IWUSR,
1079 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1080 2, 1);
1081static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR,
1082 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1083 2, 2);
1084static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_fan, S_IRUGO | S_IWUSR,
1085 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1086 2, 2);
1087
0e39e01c
JD
1088static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
1089static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
1090static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
1091static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
1092static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4);
1093static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5);
1094static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6);
1095static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7);
1096static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8);
51c997d8
JD
1097static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9);
1098static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10);
0e39e01c
JD
1099static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 11);
1100static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 12);
1101static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13);
1102static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 16);
1103static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 17);
1104static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 18);
1105static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL);
1106static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL);
1107static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL);
1108
1109static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
1110
1111static struct attribute *f71805f_attributes[] = {
51c997d8
JD
1112 &sensor_dev_attr_in0_input.dev_attr.attr,
1113 &sensor_dev_attr_in0_max.dev_attr.attr,
1114 &sensor_dev_attr_in0_min.dev_attr.attr,
0e39e01c
JD
1115 &sensor_dev_attr_in1_input.dev_attr.attr,
1116 &sensor_dev_attr_in1_max.dev_attr.attr,
1117 &sensor_dev_attr_in1_min.dev_attr.attr,
1118 &sensor_dev_attr_in2_input.dev_attr.attr,
1119 &sensor_dev_attr_in2_max.dev_attr.attr,
1120 &sensor_dev_attr_in2_min.dev_attr.attr,
1121 &sensor_dev_attr_in3_input.dev_attr.attr,
1122 &sensor_dev_attr_in3_max.dev_attr.attr,
1123 &sensor_dev_attr_in3_min.dev_attr.attr,
0e39e01c
JD
1124 &sensor_dev_attr_in5_input.dev_attr.attr,
1125 &sensor_dev_attr_in5_max.dev_attr.attr,
1126 &sensor_dev_attr_in5_min.dev_attr.attr,
1127 &sensor_dev_attr_in6_input.dev_attr.attr,
1128 &sensor_dev_attr_in6_max.dev_attr.attr,
1129 &sensor_dev_attr_in6_min.dev_attr.attr,
1130 &sensor_dev_attr_in7_input.dev_attr.attr,
1131 &sensor_dev_attr_in7_max.dev_attr.attr,
1132 &sensor_dev_attr_in7_min.dev_attr.attr,
0e39e01c 1133
c7176cb5
JD
1134 &sensor_dev_attr_fan1_input.dev_attr.attr,
1135 &sensor_dev_attr_fan1_min.dev_attr.attr,
1136 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
1137 &sensor_dev_attr_fan1_target.dev_attr.attr,
1138 &sensor_dev_attr_fan2_input.dev_attr.attr,
1139 &sensor_dev_attr_fan2_min.dev_attr.attr,
1140 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
1141 &sensor_dev_attr_fan2_target.dev_attr.attr,
1142 &sensor_dev_attr_fan3_input.dev_attr.attr,
1143 &sensor_dev_attr_fan3_min.dev_attr.attr,
1144 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
1145 &sensor_dev_attr_fan3_target.dev_attr.attr,
1146
1147 &sensor_dev_attr_pwm1.dev_attr.attr,
1148 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1149 &sensor_dev_attr_pwm1_mode.dev_attr.attr,
1150 &sensor_dev_attr_pwm2.dev_attr.attr,
1151 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
1152 &sensor_dev_attr_pwm2_mode.dev_attr.attr,
1153 &sensor_dev_attr_pwm3.dev_attr.attr,
1154 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
1155 &sensor_dev_attr_pwm3_mode.dev_attr.attr,
1156
0e39e01c
JD
1157 &sensor_dev_attr_temp1_input.dev_attr.attr,
1158 &sensor_dev_attr_temp1_max.dev_attr.attr,
1159 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
1160 &sensor_dev_attr_temp1_type.dev_attr.attr,
1161 &sensor_dev_attr_temp2_input.dev_attr.attr,
1162 &sensor_dev_attr_temp2_max.dev_attr.attr,
1163 &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
1164 &sensor_dev_attr_temp2_type.dev_attr.attr,
1165 &sensor_dev_attr_temp3_input.dev_attr.attr,
1166 &sensor_dev_attr_temp3_max.dev_attr.attr,
1167 &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
1168 &sensor_dev_attr_temp3_type.dev_attr.attr,
1169
aba5073d
PE
1170 &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
1171 &sensor_dev_attr_pwm1_auto_point1_fan.dev_attr.attr,
1172 &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
1173 &sensor_dev_attr_pwm1_auto_point2_fan.dev_attr.attr,
1174 &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
1175 &sensor_dev_attr_pwm1_auto_point3_fan.dev_attr.attr,
1176 &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr,
1177 &sensor_dev_attr_pwm2_auto_point1_fan.dev_attr.attr,
1178 &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
1179 &sensor_dev_attr_pwm2_auto_point2_fan.dev_attr.attr,
1180 &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
1181 &sensor_dev_attr_pwm2_auto_point3_fan.dev_attr.attr,
1182 &sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr,
1183 &sensor_dev_attr_pwm3_auto_point1_fan.dev_attr.attr,
1184 &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr,
1185 &sensor_dev_attr_pwm3_auto_point2_fan.dev_attr.attr,
1186 &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr,
1187 &sensor_dev_attr_pwm3_auto_point3_fan.dev_attr.attr,
1188
0e39e01c
JD
1189 &sensor_dev_attr_in0_alarm.dev_attr.attr,
1190 &sensor_dev_attr_in1_alarm.dev_attr.attr,
1191 &sensor_dev_attr_in2_alarm.dev_attr.attr,
1192 &sensor_dev_attr_in3_alarm.dev_attr.attr,
0e39e01c
JD
1193 &sensor_dev_attr_in5_alarm.dev_attr.attr,
1194 &sensor_dev_attr_in6_alarm.dev_attr.attr,
1195 &sensor_dev_attr_in7_alarm.dev_attr.attr,
0e39e01c
JD
1196 &dev_attr_alarms_in.attr,
1197 &sensor_dev_attr_temp1_alarm.dev_attr.attr,
1198 &sensor_dev_attr_temp2_alarm.dev_attr.attr,
1199 &sensor_dev_attr_temp3_alarm.dev_attr.attr,
1200 &dev_attr_alarms_temp.attr,
1201 &dev_attr_alarms_fan.attr,
1202
1203 &dev_attr_name.attr,
1204 NULL
2488a39d
JD
1205};
1206
0e39e01c
JD
1207static const struct attribute_group f71805f_group = {
1208 .attrs = f71805f_attributes,
2488a39d
JD
1209};
1210
51c997d8
JD
1211static struct attribute *f71805f_attributes_optin[4][5] = {
1212 {
1213 &sensor_dev_attr_in4_input.dev_attr.attr,
1214 &sensor_dev_attr_in4_max.dev_attr.attr,
1215 &sensor_dev_attr_in4_min.dev_attr.attr,
1216 &sensor_dev_attr_in4_alarm.dev_attr.attr,
1217 NULL
1218 }, {
1219 &sensor_dev_attr_in8_input.dev_attr.attr,
1220 &sensor_dev_attr_in8_max.dev_attr.attr,
1221 &sensor_dev_attr_in8_min.dev_attr.attr,
1222 &sensor_dev_attr_in8_alarm.dev_attr.attr,
1223 NULL
1224 }, {
1225 &sensor_dev_attr_in9_input.dev_attr.attr,
1226 &sensor_dev_attr_in9_max.dev_attr.attr,
1227 &sensor_dev_attr_in9_min.dev_attr.attr,
1228 &sensor_dev_attr_in9_alarm.dev_attr.attr,
1229 NULL
1230 }, {
1231 &sensor_dev_attr_in10_input.dev_attr.attr,
1232 &sensor_dev_attr_in10_max.dev_attr.attr,
1233 &sensor_dev_attr_in10_min.dev_attr.attr,
1234 &sensor_dev_attr_in10_alarm.dev_attr.attr,
1235 NULL
1236 }
1237};
1238
1239static const struct attribute_group f71805f_group_optin[4] = {
1240 { .attrs = f71805f_attributes_optin[0] },
1241 { .attrs = f71805f_attributes_optin[1] },
1242 { .attrs = f71805f_attributes_optin[2] },
1243 { .attrs = f71805f_attributes_optin[3] },
1244};
1245
e196783d
JD
1246/* We don't include pwm_freq files in the arrays above, because they must be
1247 created conditionally (only if pwm_mode is 1 == PWM) */
1248static struct attribute *f71805f_attributes_pwm_freq[] = {
1249 &sensor_dev_attr_pwm1_freq.dev_attr.attr,
1250 &sensor_dev_attr_pwm2_freq.dev_attr.attr,
1251 &sensor_dev_attr_pwm3_freq.dev_attr.attr,
1252 NULL
1253};
1254
1255static const struct attribute_group f71805f_group_pwm_freq = {
1256 .attrs = f71805f_attributes_pwm_freq,
1257};
1258
95e35312
JD
1259/* We also need an indexed access to pwmN files to toggle writability */
1260static struct attribute *f71805f_attr_pwm[] = {
1261 &sensor_dev_attr_pwm1.dev_attr.attr,
1262 &sensor_dev_attr_pwm2.dev_attr.attr,
1263 &sensor_dev_attr_pwm3.dev_attr.attr,
1264};
1265
e53004e2
JD
1266/*
1267 * Device registration and initialization
1268 */
1269
1270static void __devinit f71805f_init_device(struct f71805f_data *data)
1271{
1272 u8 reg;
1273 int i;
1274
1275 reg = f71805f_read8(data, F71805F_REG_START);
1276 if ((reg & 0x41) != 0x01) {
1277 printk(KERN_DEBUG DRVNAME ": Starting monitoring "
1278 "operations\n");
1279 f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40);
1280 }
1281
1282 /* Fan monitoring can be disabled. If it is, we won't be polling
1283 the register values, and won't create the related sysfs files. */
1284 for (i = 0; i < 3; i++) {
6b14a546
JD
1285 data->fan_ctrl[i] = f71805f_read8(data,
1286 F71805F_REG_FAN_CTRL(i));
315c7113
JD
1287 /* Clear latch full bit, else "speed mode" fan speed control
1288 doesn't work */
1289 if (data->fan_ctrl[i] & FAN_CTRL_LATCH_FULL) {
1290 data->fan_ctrl[i] &= ~FAN_CTRL_LATCH_FULL;
1291 f71805f_write8(data, F71805F_REG_FAN_CTRL(i),
1292 data->fan_ctrl[i]);
1293 }
e53004e2
JD
1294 }
1295}
1296
1297static int __devinit f71805f_probe(struct platform_device *pdev)
1298{
51c997d8 1299 struct f71805f_sio_data *sio_data = pdev->dev.platform_data;
e53004e2
JD
1300 struct f71805f_data *data;
1301 struct resource *res;
2488a39d 1302 int i, err;
e53004e2 1303
51c997d8
JD
1304 static const char *names[] = {
1305 "f71805f",
1306 "f71872f",
1307 };
1308
e53004e2
JD
1309 if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) {
1310 err = -ENOMEM;
1311 printk(KERN_ERR DRVNAME ": Out of memory\n");
1312 goto exit;
1313 }
1314
1315 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
ce7ee4e8
JD
1316 if (!request_region(res->start + ADDR_REG_OFFSET, 2, DRVNAME)) {
1317 err = -EBUSY;
1318 dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
1319 (unsigned long)(res->start + ADDR_REG_OFFSET),
1320 (unsigned long)(res->start + ADDR_REG_OFFSET + 1));
1321 goto exit_free;
1322 }
e53004e2 1323 data->addr = res->start;
51c997d8 1324 data->name = names[sio_data->kind];
f0819184 1325 mutex_init(&data->update_lock);
e53004e2
JD
1326
1327 platform_set_drvdata(pdev, data);
1328
51c997d8
JD
1329 /* Some voltage inputs depend on chip model and configuration */
1330 switch (sio_data->kind) {
1331 case f71805f:
1332 data->has_in = 0x1ff;
1333 break;
1334 case f71872f:
1335 data->has_in = 0x6ef;
1336 if (sio_data->fnsel1 & 0x01)
1337 data->has_in |= (1 << 4); /* in4 */
1338 if (sio_data->fnsel1 & 0x02)
1339 data->has_in |= (1 << 8); /* in8 */
1340 break;
1341 }
1342
e53004e2
JD
1343 /* Initialize the F71805F chip */
1344 f71805f_init_device(data);
1345
1346 /* Register sysfs interface files */
0e39e01c 1347 if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group)))
ce7ee4e8 1348 goto exit_release_region;
51c997d8
JD
1349 if (data->has_in & (1 << 4)) { /* in4 */
1350 if ((err = sysfs_create_group(&pdev->dev.kobj,
1351 &f71805f_group_optin[0])))
1352 goto exit_remove_files;
1353 }
1354 if (data->has_in & (1 << 8)) { /* in8 */
1355 if ((err = sysfs_create_group(&pdev->dev.kobj,
1356 &f71805f_group_optin[1])))
1357 goto exit_remove_files;
1358 }
1359 if (data->has_in & (1 << 9)) { /* in9 (F71872F/FG only) */
1360 if ((err = sysfs_create_group(&pdev->dev.kobj,
1361 &f71805f_group_optin[2])))
1362 goto exit_remove_files;
1363 }
1364 if (data->has_in & (1 << 10)) { /* in9 (F71872F/FG only) */
1365 if ((err = sysfs_create_group(&pdev->dev.kobj,
1366 &f71805f_group_optin[3])))
1367 goto exit_remove_files;
1368 }
0e39e01c 1369 for (i = 0; i < 3; i++) {
e196783d
JD
1370 /* If control mode is PWM, create pwm_freq file */
1371 if (!(data->fan_ctrl[i] & FAN_CTRL_DC_MODE)) {
1372 if ((err = sysfs_create_file(&pdev->dev.kobj,
1373 f71805f_attributes_pwm_freq[i])))
1374 goto exit_remove_files;
1375 }
95e35312
JD
1376 /* If PWM is in manual mode, add write permission */
1377 if (data->fan_ctrl[i] & FAN_CTRL_MODE_MANUAL) {
1378 if ((err = sysfs_chmod_file(&pdev->dev.kobj,
1379 f71805f_attr_pwm[i],
1380 S_IRUGO | S_IWUSR))) {
1381 dev_err(&pdev->dev, "chmod +w pwm%d failed\n",
1382 i + 1);
1383 goto exit_remove_files;
1384 }
1385 }
0e39e01c
JD
1386 }
1387
1beeffe4
TJ
1388 data->hwmon_dev = hwmon_device_register(&pdev->dev);
1389 if (IS_ERR(data->hwmon_dev)) {
1390 err = PTR_ERR(data->hwmon_dev);
0e39e01c
JD
1391 dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
1392 goto exit_remove_files;
e53004e2 1393 }
e53004e2
JD
1394
1395 return 0;
1396
0e39e01c
JD
1397exit_remove_files:
1398 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
51c997d8
JD
1399 for (i = 0; i < 4; i++)
1400 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
e196783d 1401 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
ce7ee4e8
JD
1402exit_release_region:
1403 release_region(res->start + ADDR_REG_OFFSET, 2);
e53004e2 1404exit_free:
0e39e01c 1405 platform_set_drvdata(pdev, NULL);
e53004e2
JD
1406 kfree(data);
1407exit:
1408 return err;
1409}
1410
1411static int __devexit f71805f_remove(struct platform_device *pdev)
1412{
1413 struct f71805f_data *data = platform_get_drvdata(pdev);
ce7ee4e8 1414 struct resource *res;
0e39e01c 1415 int i;
e53004e2 1416
1beeffe4 1417 hwmon_device_unregister(data->hwmon_dev);
0e39e01c 1418 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
51c997d8
JD
1419 for (i = 0; i < 4; i++)
1420 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
e196783d 1421 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
04a6217d 1422 platform_set_drvdata(pdev, NULL);
e53004e2
JD
1423 kfree(data);
1424
ce7ee4e8
JD
1425 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
1426 release_region(res->start + ADDR_REG_OFFSET, 2);
1427
e53004e2
JD
1428 return 0;
1429}
1430
1431static struct platform_driver f71805f_driver = {
1432 .driver = {
1433 .owner = THIS_MODULE,
1434 .name = DRVNAME,
1435 },
1436 .probe = f71805f_probe,
1437 .remove = __devexit_p(f71805f_remove),
1438};
1439
51c997d8
JD
1440static int __init f71805f_device_add(unsigned short address,
1441 const struct f71805f_sio_data *sio_data)
e53004e2 1442{
568825c8
JD
1443 struct resource res = {
1444 .start = address,
1445 .end = address + REGION_LENGTH - 1,
1446 .flags = IORESOURCE_IO,
1447 };
e53004e2
JD
1448 int err;
1449
1450 pdev = platform_device_alloc(DRVNAME, address);
1451 if (!pdev) {
1452 err = -ENOMEM;
1453 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
1454 goto exit;
1455 }
1456
568825c8
JD
1457 res.name = pdev->name;
1458 err = platform_device_add_resources(pdev, &res, 1);
e53004e2
JD
1459 if (err) {
1460 printk(KERN_ERR DRVNAME ": Device resource addition failed "
1461 "(%d)\n", err);
1462 goto exit_device_put;
1463 }
1464
2df6d811
JD
1465 err = platform_device_add_data(pdev, sio_data,
1466 sizeof(struct f71805f_sio_data));
1467 if (err) {
51c997d8
JD
1468 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
1469 goto exit_device_put;
1470 }
51c997d8 1471
e53004e2
JD
1472 err = platform_device_add(pdev);
1473 if (err) {
1474 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
1475 err);
a117dddf 1476 goto exit_device_put;
e53004e2
JD
1477 }
1478
1479 return 0;
1480
1481exit_device_put:
1482 platform_device_put(pdev);
1483exit:
1484 return err;
1485}
1486
51c997d8
JD
1487static int __init f71805f_find(int sioaddr, unsigned short *address,
1488 struct f71805f_sio_data *sio_data)
e53004e2
JD
1489{
1490 int err = -ENODEV;
1491 u16 devid;
1492
51c997d8
JD
1493 static const char *names[] = {
1494 "F71805F/FG",
9cab0217 1495 "F71872F/FG or F71806F/FG",
51c997d8
JD
1496 };
1497
e53004e2
JD
1498 superio_enter(sioaddr);
1499
1500 devid = superio_inw(sioaddr, SIO_REG_MANID);
1501 if (devid != SIO_FINTEK_ID)
1502 goto exit;
1503
67b671bc 1504 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
51c997d8
JD
1505 switch (devid) {
1506 case SIO_F71805F_ID:
1507 sio_data->kind = f71805f;
1508 break;
1509 case SIO_F71872F_ID:
1510 sio_data->kind = f71872f;
1511 sio_data->fnsel1 = superio_inb(sioaddr, SIO_REG_FNSEL1);
1512 break;
1513 default:
e53004e2
JD
1514 printk(KERN_INFO DRVNAME ": Unsupported Fintek device, "
1515 "skipping\n");
1516 goto exit;
1517 }
1518
1519 superio_select(sioaddr, F71805F_LD_HWM);
1520 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
1521 printk(KERN_WARNING DRVNAME ": Device not activated, "
1522 "skipping\n");
1523 goto exit;
1524 }
1525
1526 *address = superio_inw(sioaddr, SIO_REG_ADDR);
1527 if (*address == 0) {
1528 printk(KERN_WARNING DRVNAME ": Base address not set, "
1529 "skipping\n");
1530 goto exit;
1531 }
75c99029 1532 *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
e53004e2
JD
1533
1534 err = 0;
51c997d8
JD
1535 printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %u\n",
1536 names[sio_data->kind], *address,
1537 superio_inb(sioaddr, SIO_REG_DEVREV));
e53004e2
JD
1538
1539exit:
1540 superio_exit(sioaddr);
1541 return err;
1542}
1543
1544static int __init f71805f_init(void)
1545{
1546 int err;
1547 unsigned short address;
51c997d8 1548 struct f71805f_sio_data sio_data;
e53004e2 1549
51c997d8
JD
1550 if (f71805f_find(0x2e, &address, &sio_data)
1551 && f71805f_find(0x4e, &address, &sio_data))
e53004e2
JD
1552 return -ENODEV;
1553
1554 err = platform_driver_register(&f71805f_driver);
1555 if (err)
1556 goto exit;
1557
1558 /* Sets global pdev as a side effect */
51c997d8 1559 err = f71805f_device_add(address, &sio_data);
e53004e2
JD
1560 if (err)
1561 goto exit_driver;
1562
1563 return 0;
1564
1565exit_driver:
1566 platform_driver_unregister(&f71805f_driver);
1567exit:
1568 return err;
1569}
1570
1571static void __exit f71805f_exit(void)
1572{
1573 platform_device_unregister(pdev);
1574 platform_driver_unregister(&f71805f_driver);
1575}
1576
1577MODULE_AUTHOR("Jean Delvare <khali@linux-fr>");
1578MODULE_LICENSE("GPL");
51c997d8 1579MODULE_DESCRIPTION("F71805F/F71872F hardware monitoring driver");
e53004e2
JD
1580
1581module_init(f71805f_init);
1582module_exit(f71805f_exit);
This page took 0.331984 seconds and 5 git commands to generate.