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