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