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