xref: /openbmc/linux/drivers/hwmon/f71805f.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2e53004e2SJean Delvare /*
351c997d8SJean Delvare  * f71805f.c - driver for the Fintek F71805F/FG and F71872F/FG Super-I/O
451c997d8SJean Delvare  *             chips integrated hardware monitoring features
57c81c60fSJean Delvare  * Copyright (C) 2005-2006  Jean Delvare <jdelvare@suse.de>
6e53004e2SJean Delvare  *
7e53004e2SJean Delvare  * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates
8e53004e2SJean Delvare  * complete hardware monitoring features: voltage, fan and temperature
9e53004e2SJean Delvare  * sensors, and manual and automatic fan speed control.
10e53004e2SJean Delvare  *
1151c997d8SJean Delvare  * The F71872F/FG is almost the same, with two more voltages monitored,
1251c997d8SJean Delvare  * and 6 VID inputs.
1351c997d8SJean Delvare  *
149cab0217SJean Delvare  * The F71806F/FG is essentially the same as the F71872F/FG. It even has
159cab0217SJean Delvare  * the same chip ID, so the driver can't differentiate between.
16e53004e2SJean Delvare  */
17e53004e2SJean Delvare 
18e54c5ad6SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19e54c5ad6SJoe Perches 
20e53004e2SJean Delvare #include <linux/module.h>
21e53004e2SJean Delvare #include <linux/init.h>
22e53004e2SJean Delvare #include <linux/slab.h>
23e53004e2SJean Delvare #include <linux/jiffies.h>
24e53004e2SJean Delvare #include <linux/platform_device.h>
25e53004e2SJean Delvare #include <linux/hwmon.h>
26e53004e2SJean Delvare #include <linux/hwmon-sysfs.h>
27e53004e2SJean Delvare #include <linux/err.h>
28f0819184SJean Delvare #include <linux/mutex.h>
290e39e01cSJean Delvare #include <linux/sysfs.h>
30ce7ee4e8SJean Delvare #include <linux/ioport.h>
31b9acb64aSJean Delvare #include <linux/acpi.h>
326055fae8SH Hartley Sweeten #include <linux/io.h>
33e53004e2SJean Delvare 
3467b671bcSJean Delvare static unsigned short force_id;
3567b671bcSJean Delvare module_param(force_id, ushort, 0);
3667b671bcSJean Delvare MODULE_PARM_DESC(force_id, "Override the detected device ID");
3767b671bcSJean Delvare 
38e53004e2SJean Delvare static struct platform_device *pdev;
39e53004e2SJean Delvare 
40e53004e2SJean Delvare #define DRVNAME "f71805f"
4151c997d8SJean Delvare enum kinds { f71805f, f71872f };
42e53004e2SJean Delvare 
43e53004e2SJean Delvare /*
44e53004e2SJean Delvare  * Super-I/O constants and functions
45e53004e2SJean Delvare  */
46e53004e2SJean Delvare 
47e53004e2SJean Delvare #define F71805F_LD_HWM		0x04
48e53004e2SJean Delvare 
49e53004e2SJean Delvare #define SIO_REG_LDSEL		0x07	/* Logical device select */
50e53004e2SJean Delvare #define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
51e53004e2SJean Delvare #define SIO_REG_DEVREV		0x22	/* Device revision */
52e53004e2SJean Delvare #define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */
5351c997d8SJean Delvare #define SIO_REG_FNSEL1		0x29	/* Multi Function Select 1 (F71872F) */
54e53004e2SJean Delvare #define SIO_REG_ENABLE		0x30	/* Logical device enable */
55e53004e2SJean Delvare #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
56e53004e2SJean Delvare 
57e53004e2SJean Delvare #define SIO_FINTEK_ID		0x1934
58e53004e2SJean Delvare #define SIO_F71805F_ID		0x0406
5951c997d8SJean Delvare #define SIO_F71872F_ID		0x0341
60e53004e2SJean Delvare 
61e53004e2SJean Delvare static inline int
superio_inb(int base,int reg)62e53004e2SJean Delvare superio_inb(int base, int reg)
63e53004e2SJean Delvare {
64e53004e2SJean Delvare 	outb(reg, base);
65e53004e2SJean Delvare 	return inb(base + 1);
66e53004e2SJean Delvare }
67e53004e2SJean Delvare 
68e53004e2SJean Delvare static int
superio_inw(int base,int reg)69e53004e2SJean Delvare superio_inw(int base, int reg)
70e53004e2SJean Delvare {
71e53004e2SJean Delvare 	int val;
72e53004e2SJean Delvare 	outb(reg++, base);
73e53004e2SJean Delvare 	val = inb(base + 1) << 8;
74e53004e2SJean Delvare 	outb(reg, base);
75e53004e2SJean Delvare 	val |= inb(base + 1);
76e53004e2SJean Delvare 	return val;
77e53004e2SJean Delvare }
78e53004e2SJean Delvare 
79e53004e2SJean Delvare static inline void
superio_select(int base,int ld)80e53004e2SJean Delvare superio_select(int base, int ld)
81e53004e2SJean Delvare {
82e53004e2SJean Delvare 	outb(SIO_REG_LDSEL, base);
83e53004e2SJean Delvare 	outb(ld, base + 1);
84e53004e2SJean Delvare }
85e53004e2SJean Delvare 
8673e6ff71SGuenter Roeck static inline int
superio_enter(int base)87e53004e2SJean Delvare superio_enter(int base)
88e53004e2SJean Delvare {
8973e6ff71SGuenter Roeck 	if (!request_muxed_region(base, 2, DRVNAME))
9073e6ff71SGuenter Roeck 		return -EBUSY;
9173e6ff71SGuenter Roeck 
92e53004e2SJean Delvare 	outb(0x87, base);
93e53004e2SJean Delvare 	outb(0x87, base);
9473e6ff71SGuenter Roeck 
9573e6ff71SGuenter Roeck 	return 0;
96e53004e2SJean Delvare }
97e53004e2SJean Delvare 
98e53004e2SJean Delvare static inline void
superio_exit(int base)99e53004e2SJean Delvare superio_exit(int base)
100e53004e2SJean Delvare {
101e53004e2SJean Delvare 	outb(0xaa, base);
10273e6ff71SGuenter Roeck 	release_region(base, 2);
103e53004e2SJean Delvare }
104e53004e2SJean Delvare 
105e53004e2SJean Delvare /*
106e53004e2SJean Delvare  * ISA constants
107e53004e2SJean Delvare  */
108e53004e2SJean Delvare 
10975c99029SJean Delvare #define REGION_LENGTH		8
11075c99029SJean Delvare #define ADDR_REG_OFFSET		5
11175c99029SJean Delvare #define DATA_REG_OFFSET		6
112e53004e2SJean Delvare 
113e53004e2SJean Delvare /*
114e53004e2SJean Delvare  * Registers
115e53004e2SJean Delvare  */
116e53004e2SJean Delvare 
11751c997d8SJean Delvare /* in nr from 0 to 10 (8-bit values) */
118e53004e2SJean Delvare #define F71805F_REG_IN(nr)		(0x10 + (nr))
11951c997d8SJean Delvare #define F71805F_REG_IN_HIGH(nr)		((nr) < 10 ? 0x40 + 2 * (nr) : 0x2E)
12051c997d8SJean Delvare #define F71805F_REG_IN_LOW(nr)		((nr) < 10 ? 0x41 + 2 * (nr) : 0x2F)
121e53004e2SJean Delvare /* fan nr from 0 to 2 (12-bit values, two registers) */
122e53004e2SJean Delvare #define F71805F_REG_FAN(nr)		(0x20 + 2 * (nr))
123e53004e2SJean Delvare #define F71805F_REG_FAN_LOW(nr)		(0x28 + 2 * (nr))
124315c7113SJean Delvare #define F71805F_REG_FAN_TARGET(nr)	(0x69 + 16 * (nr))
125e53004e2SJean Delvare #define F71805F_REG_FAN_CTRL(nr)	(0x60 + 16 * (nr))
1266e2bc17bSJean Delvare #define F71805F_REG_PWM_FREQ(nr)	(0x63 + 16 * (nr))
12795e35312SJean Delvare #define F71805F_REG_PWM_DUTY(nr)	(0x6B + 16 * (nr))
128e53004e2SJean Delvare /* temp nr from 0 to 2 (8-bit values) */
129e53004e2SJean Delvare #define F71805F_REG_TEMP(nr)		(0x1B + (nr))
130e53004e2SJean Delvare #define F71805F_REG_TEMP_HIGH(nr)	(0x54 + 2 * (nr))
131e53004e2SJean Delvare #define F71805F_REG_TEMP_HYST(nr)	(0x55 + 2 * (nr))
132e53004e2SJean Delvare #define F71805F_REG_TEMP_MODE		0x01
133aba5073dSPhil Endecott /* pwm/fan pwmnr from 0 to 2, auto point apnr from 0 to 2 */
134aba5073dSPhil Endecott /* map Fintek numbers to our numbers as follows: 9->0, 5->1, 1->2 */
135aba5073dSPhil Endecott #define F71805F_REG_PWM_AUTO_POINT_TEMP(pwmnr, apnr) \
136aba5073dSPhil Endecott 					(0xA0 + 0x10 * (pwmnr) + (2 - (apnr)))
137aba5073dSPhil Endecott #define F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr) \
138aba5073dSPhil Endecott 					(0xA4 + 0x10 * (pwmnr) + \
139aba5073dSPhil Endecott 						2 * (2 - (apnr)))
140e53004e2SJean Delvare 
141e53004e2SJean Delvare #define F71805F_REG_START		0x00
142e53004e2SJean Delvare /* status nr from 0 to 2 */
143e53004e2SJean Delvare #define F71805F_REG_STATUS(nr)		(0x36 + (nr))
144e53004e2SJean Delvare 
1456b14a546SJean Delvare /* individual register bits */
146e196783dSJean Delvare #define FAN_CTRL_DC_MODE		0x10
147315c7113SJean Delvare #define FAN_CTRL_LATCH_FULL		0x08
14895e35312SJean Delvare #define FAN_CTRL_MODE_MASK		0x03
14995e35312SJean Delvare #define FAN_CTRL_MODE_SPEED		0x00
15095e35312SJean Delvare #define FAN_CTRL_MODE_TEMPERATURE	0x01
15195e35312SJean Delvare #define FAN_CTRL_MODE_MANUAL		0x02
1526b14a546SJean Delvare 
153e53004e2SJean Delvare /*
154e53004e2SJean Delvare  * Data structures and manipulation thereof
155e53004e2SJean Delvare  */
156e53004e2SJean Delvare 
157aba5073dSPhil Endecott struct f71805f_auto_point {
158aba5073dSPhil Endecott 	u8 temp[3];
159aba5073dSPhil Endecott 	u16 fan[3];
160aba5073dSPhil Endecott };
161aba5073dSPhil Endecott 
162e53004e2SJean Delvare struct f71805f_data {
163e53004e2SJean Delvare 	unsigned short addr;
164e53004e2SJean Delvare 	const char *name;
1651beeffe4STony Jones 	struct device *hwmon_dev;
166e53004e2SJean Delvare 
167f0819184SJean Delvare 	struct mutex update_lock;
168*952a11caSPaul Fertser 	bool valid;		/* true if following fields are valid */
169e53004e2SJean Delvare 	unsigned long last_updated;	/* In jiffies */
170e53004e2SJean Delvare 	unsigned long last_limits;	/* In jiffies */
171e53004e2SJean Delvare 
172e53004e2SJean Delvare 	/* Register values */
17351c997d8SJean Delvare 	u8 in[11];
17451c997d8SJean Delvare 	u8 in_high[11];
17551c997d8SJean Delvare 	u8 in_low[11];
17651c997d8SJean Delvare 	u16 has_in;
177e53004e2SJean Delvare 	u16 fan[3];
178e53004e2SJean Delvare 	u16 fan_low[3];
179315c7113SJean Delvare 	u16 fan_target[3];
1806b14a546SJean Delvare 	u8 fan_ctrl[3];
18195e35312SJean Delvare 	u8 pwm[3];
1826e2bc17bSJean Delvare 	u8 pwm_freq[3];
183e53004e2SJean Delvare 	u8 temp[3];
184e53004e2SJean Delvare 	u8 temp_high[3];
185e53004e2SJean Delvare 	u8 temp_hyst[3];
186e53004e2SJean Delvare 	u8 temp_mode;
1872d45771eSJean Delvare 	unsigned long alarms;
188aba5073dSPhil Endecott 	struct f71805f_auto_point auto_points[3];
189e53004e2SJean Delvare };
190e53004e2SJean Delvare 
19151c997d8SJean Delvare struct f71805f_sio_data {
19251c997d8SJean Delvare 	enum kinds kind;
19351c997d8SJean Delvare 	u8 fnsel1;
19451c997d8SJean Delvare };
19551c997d8SJean Delvare 
in_from_reg(u8 reg)196e53004e2SJean Delvare static inline long in_from_reg(u8 reg)
197e53004e2SJean Delvare {
1987fe83ad8SFrans Meulenbroeks 	return reg * 8;
199e53004e2SJean Delvare }
200e53004e2SJean Delvare 
201e53004e2SJean Delvare /* The 2 least significant bits are not used */
in_to_reg(long val)202e53004e2SJean Delvare static inline u8 in_to_reg(long val)
203e53004e2SJean Delvare {
204e53004e2SJean Delvare 	if (val <= 0)
205e53004e2SJean Delvare 		return 0;
206e53004e2SJean Delvare 	if (val >= 2016)
207e53004e2SJean Delvare 		return 0xfc;
2087fe83ad8SFrans Meulenbroeks 	return ((val + 16) / 32) << 2;
209e53004e2SJean Delvare }
210e53004e2SJean Delvare 
211e53004e2SJean Delvare /* in0 is downscaled by a factor 2 internally */
in0_from_reg(u8 reg)212e53004e2SJean Delvare static inline long in0_from_reg(u8 reg)
213e53004e2SJean Delvare {
2147fe83ad8SFrans Meulenbroeks 	return reg * 16;
215e53004e2SJean Delvare }
216e53004e2SJean Delvare 
in0_to_reg(long val)217e53004e2SJean Delvare static inline u8 in0_to_reg(long val)
218e53004e2SJean Delvare {
219e53004e2SJean Delvare 	if (val <= 0)
220e53004e2SJean Delvare 		return 0;
221e53004e2SJean Delvare 	if (val >= 4032)
222e53004e2SJean Delvare 		return 0xfc;
2237fe83ad8SFrans Meulenbroeks 	return ((val + 32) / 64) << 2;
224e53004e2SJean Delvare }
225e53004e2SJean Delvare 
226e53004e2SJean Delvare /* The 4 most significant bits are not used */
fan_from_reg(u16 reg)227e53004e2SJean Delvare static inline long fan_from_reg(u16 reg)
228e53004e2SJean Delvare {
229e53004e2SJean Delvare 	reg &= 0xfff;
230e53004e2SJean Delvare 	if (!reg || reg == 0xfff)
231e53004e2SJean Delvare 		return 0;
2327fe83ad8SFrans Meulenbroeks 	return 1500000 / reg;
233e53004e2SJean Delvare }
234e53004e2SJean Delvare 
fan_to_reg(long rpm)235e53004e2SJean Delvare static inline u16 fan_to_reg(long rpm)
236e53004e2SJean Delvare {
2372fff0840SGuenter Roeck 	/*
2382fff0840SGuenter Roeck 	 * If the low limit is set below what the chip can measure,
2392fff0840SGuenter Roeck 	 * store the largest possible 12-bit value in the registers,
2402fff0840SGuenter Roeck 	 * so that no alarm will ever trigger.
2412fff0840SGuenter Roeck 	 */
242e53004e2SJean Delvare 	if (rpm < 367)
243e53004e2SJean Delvare 		return 0xfff;
2447fe83ad8SFrans Meulenbroeks 	return 1500000 / rpm;
245e53004e2SJean Delvare }
246e53004e2SJean Delvare 
pwm_freq_from_reg(u8 reg)2476e2bc17bSJean Delvare static inline unsigned long pwm_freq_from_reg(u8 reg)
2486e2bc17bSJean Delvare {
2496e2bc17bSJean Delvare 	unsigned long clock = (reg & 0x80) ? 48000000UL : 1000000UL;
2506e2bc17bSJean Delvare 
2516e2bc17bSJean Delvare 	reg &= 0x7f;
2526e2bc17bSJean Delvare 	if (reg == 0)
2536e2bc17bSJean Delvare 		reg++;
2546e2bc17bSJean Delvare 	return clock / (reg << 8);
2556e2bc17bSJean Delvare }
2566e2bc17bSJean Delvare 
pwm_freq_to_reg(unsigned long val)2576e2bc17bSJean Delvare static inline u8 pwm_freq_to_reg(unsigned long val)
2586e2bc17bSJean Delvare {
2596e2bc17bSJean Delvare 	if (val >= 187500)	/* The highest we can do */
2606e2bc17bSJean Delvare 		return 0x80;
2616e2bc17bSJean Delvare 	if (val >= 1475)	/* Use 48 MHz clock */
2626e2bc17bSJean Delvare 		return 0x80 | (48000000UL / (val << 8));
2636e2bc17bSJean Delvare 	if (val < 31)		/* The lowest we can do */
2646e2bc17bSJean Delvare 		return 0x7f;
2656e2bc17bSJean Delvare 	else			/* Use 1 MHz clock */
2666e2bc17bSJean Delvare 		return 1000000UL / (val << 8);
2676e2bc17bSJean Delvare }
2686e2bc17bSJean Delvare 
pwm_mode_from_reg(u8 reg)269e196783dSJean Delvare static inline int pwm_mode_from_reg(u8 reg)
270e196783dSJean Delvare {
271e196783dSJean Delvare 	return !(reg & FAN_CTRL_DC_MODE);
272e196783dSJean Delvare }
273e196783dSJean Delvare 
temp_from_reg(u8 reg)274e53004e2SJean Delvare static inline long temp_from_reg(u8 reg)
275e53004e2SJean Delvare {
2767fe83ad8SFrans Meulenbroeks 	return reg * 1000;
277e53004e2SJean Delvare }
278e53004e2SJean Delvare 
temp_to_reg(long val)279e53004e2SJean Delvare static inline u8 temp_to_reg(long val)
280e53004e2SJean Delvare {
28186b2bbfdSJean Delvare 	if (val <= 0)
28286b2bbfdSJean Delvare 		return 0;
28386b2bbfdSJean Delvare 	if (val >= 1000 * 0xff)
28486b2bbfdSJean Delvare 		return 0xff;
28586b2bbfdSJean Delvare 	return (val + 500) / 1000;
286e53004e2SJean Delvare }
287e53004e2SJean Delvare 
288e53004e2SJean Delvare /*
289e53004e2SJean Delvare  * Device I/O access
290e53004e2SJean Delvare  */
291e53004e2SJean Delvare 
2927f999aa7SJean Delvare /* Must be called with data->update_lock held, except during initialization */
f71805f_read8(struct f71805f_data * data,u8 reg)293e53004e2SJean Delvare static u8 f71805f_read8(struct f71805f_data *data, u8 reg)
294e53004e2SJean Delvare {
295e53004e2SJean Delvare 	outb(reg, data->addr + ADDR_REG_OFFSET);
2967f999aa7SJean Delvare 	return inb(data->addr + DATA_REG_OFFSET);
297e53004e2SJean Delvare }
298e53004e2SJean Delvare 
2997f999aa7SJean Delvare /* Must be called with data->update_lock held, except during initialization */
f71805f_write8(struct f71805f_data * data,u8 reg,u8 val)300e53004e2SJean Delvare static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val)
301e53004e2SJean Delvare {
302e53004e2SJean Delvare 	outb(reg, data->addr + ADDR_REG_OFFSET);
303e53004e2SJean Delvare 	outb(val, data->addr + DATA_REG_OFFSET);
304e53004e2SJean Delvare }
305e53004e2SJean Delvare 
3062fff0840SGuenter Roeck /*
3072fff0840SGuenter Roeck  * It is important to read the MSB first, because doing so latches the
3082fff0840SGuenter Roeck  * value of the LSB, so we are sure both bytes belong to the same value.
3092fff0840SGuenter Roeck  * Must be called with data->update_lock held, except during initialization
3102fff0840SGuenter Roeck  */
f71805f_read16(struct f71805f_data * data,u8 reg)311e53004e2SJean Delvare static u16 f71805f_read16(struct f71805f_data *data, u8 reg)
312e53004e2SJean Delvare {
313e53004e2SJean Delvare 	u16 val;
314e53004e2SJean Delvare 
315e53004e2SJean Delvare 	outb(reg, data->addr + ADDR_REG_OFFSET);
316e53004e2SJean Delvare 	val = inb(data->addr + DATA_REG_OFFSET) << 8;
317e53004e2SJean Delvare 	outb(++reg, data->addr + ADDR_REG_OFFSET);
318e53004e2SJean Delvare 	val |= inb(data->addr + DATA_REG_OFFSET);
319e53004e2SJean Delvare 
320e53004e2SJean Delvare 	return val;
321e53004e2SJean Delvare }
322e53004e2SJean Delvare 
3237f999aa7SJean Delvare /* Must be called with data->update_lock held, except during initialization */
f71805f_write16(struct f71805f_data * data,u8 reg,u16 val)324e53004e2SJean Delvare static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val)
325e53004e2SJean Delvare {
326e53004e2SJean Delvare 	outb(reg, data->addr + ADDR_REG_OFFSET);
327e53004e2SJean Delvare 	outb(val >> 8, data->addr + DATA_REG_OFFSET);
328e53004e2SJean Delvare 	outb(++reg, data->addr + ADDR_REG_OFFSET);
329e53004e2SJean Delvare 	outb(val & 0xff, data->addr + DATA_REG_OFFSET);
330e53004e2SJean Delvare }
331e53004e2SJean Delvare 
f71805f_update_device(struct device * dev)332e53004e2SJean Delvare static struct f71805f_data *f71805f_update_device(struct device *dev)
333e53004e2SJean Delvare {
334e53004e2SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
335aba5073dSPhil Endecott 	int nr, apnr;
336e53004e2SJean Delvare 
337f0819184SJean Delvare 	mutex_lock(&data->update_lock);
338e53004e2SJean Delvare 
339e53004e2SJean Delvare 	/* Limit registers cache is refreshed after 60 seconds */
340e53004e2SJean Delvare 	if (time_after(jiffies, data->last_updated + 60 * HZ)
341e53004e2SJean Delvare 	 || !data->valid) {
34251c997d8SJean Delvare 		for (nr = 0; nr < 11; nr++) {
34351c997d8SJean Delvare 			if (!(data->has_in & (1 << nr)))
34451c997d8SJean Delvare 				continue;
345e53004e2SJean Delvare 			data->in_high[nr] = f71805f_read8(data,
346e53004e2SJean Delvare 					    F71805F_REG_IN_HIGH(nr));
347e53004e2SJean Delvare 			data->in_low[nr] = f71805f_read8(data,
348e53004e2SJean Delvare 					   F71805F_REG_IN_LOW(nr));
349e53004e2SJean Delvare 		}
350e53004e2SJean Delvare 		for (nr = 0; nr < 3; nr++) {
351e53004e2SJean Delvare 			data->fan_low[nr] = f71805f_read16(data,
352e53004e2SJean Delvare 					    F71805F_REG_FAN_LOW(nr));
353315c7113SJean Delvare 			data->fan_target[nr] = f71805f_read16(data,
354315c7113SJean Delvare 					       F71805F_REG_FAN_TARGET(nr));
3556e2bc17bSJean Delvare 			data->pwm_freq[nr] = f71805f_read8(data,
3566e2bc17bSJean Delvare 					     F71805F_REG_PWM_FREQ(nr));
357e53004e2SJean Delvare 		}
358e53004e2SJean Delvare 		for (nr = 0; nr < 3; nr++) {
359e53004e2SJean Delvare 			data->temp_high[nr] = f71805f_read8(data,
360e53004e2SJean Delvare 					      F71805F_REG_TEMP_HIGH(nr));
361e53004e2SJean Delvare 			data->temp_hyst[nr] = f71805f_read8(data,
362e53004e2SJean Delvare 					      F71805F_REG_TEMP_HYST(nr));
363e53004e2SJean Delvare 		}
364e53004e2SJean Delvare 		data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE);
365aba5073dSPhil Endecott 		for (nr = 0; nr < 3; nr++) {
366aba5073dSPhil Endecott 			for (apnr = 0; apnr < 3; apnr++) {
367aba5073dSPhil Endecott 				data->auto_points[nr].temp[apnr] =
368aba5073dSPhil Endecott 					f71805f_read8(data,
369aba5073dSPhil Endecott 					F71805F_REG_PWM_AUTO_POINT_TEMP(nr,
370aba5073dSPhil Endecott 									apnr));
371aba5073dSPhil Endecott 				data->auto_points[nr].fan[apnr] =
372aba5073dSPhil Endecott 					f71805f_read16(data,
373aba5073dSPhil Endecott 					F71805F_REG_PWM_AUTO_POINT_FAN(nr,
374aba5073dSPhil Endecott 								       apnr));
375aba5073dSPhil Endecott 			}
376aba5073dSPhil Endecott 		}
377e53004e2SJean Delvare 
378e53004e2SJean Delvare 		data->last_limits = jiffies;
379e53004e2SJean Delvare 	}
380e53004e2SJean Delvare 
381e53004e2SJean Delvare 	/* Measurement registers cache is refreshed after 1 second */
382e53004e2SJean Delvare 	if (time_after(jiffies, data->last_updated + HZ)
383e53004e2SJean Delvare 	 || !data->valid) {
38451c997d8SJean Delvare 		for (nr = 0; nr < 11; nr++) {
38551c997d8SJean Delvare 			if (!(data->has_in & (1 << nr)))
38651c997d8SJean Delvare 				continue;
387e53004e2SJean Delvare 			data->in[nr] = f71805f_read8(data,
388e53004e2SJean Delvare 				       F71805F_REG_IN(nr));
389e53004e2SJean Delvare 		}
390e53004e2SJean Delvare 		for (nr = 0; nr < 3; nr++) {
391e53004e2SJean Delvare 			data->fan[nr] = f71805f_read16(data,
392e53004e2SJean Delvare 					F71805F_REG_FAN(nr));
39395e35312SJean Delvare 			data->fan_ctrl[nr] = f71805f_read8(data,
39495e35312SJean Delvare 					     F71805F_REG_FAN_CTRL(nr));
39595e35312SJean Delvare 			data->pwm[nr] = f71805f_read8(data,
39695e35312SJean Delvare 					F71805F_REG_PWM_DUTY(nr));
397e53004e2SJean Delvare 		}
398e53004e2SJean Delvare 		for (nr = 0; nr < 3; nr++) {
399e53004e2SJean Delvare 			data->temp[nr] = f71805f_read8(data,
400e53004e2SJean Delvare 					 F71805F_REG_TEMP(nr));
401e53004e2SJean Delvare 		}
4022d45771eSJean Delvare 		data->alarms = f71805f_read8(data, F71805F_REG_STATUS(0))
4032d45771eSJean Delvare 			+ (f71805f_read8(data, F71805F_REG_STATUS(1)) << 8)
4042d45771eSJean Delvare 			+ (f71805f_read8(data, F71805F_REG_STATUS(2)) << 16);
405e53004e2SJean Delvare 
406e53004e2SJean Delvare 		data->last_updated = jiffies;
407*952a11caSPaul Fertser 		data->valid = true;
408e53004e2SJean Delvare 	}
409e53004e2SJean Delvare 
410f0819184SJean Delvare 	mutex_unlock(&data->update_lock);
411e53004e2SJean Delvare 
412e53004e2SJean Delvare 	return data;
413e53004e2SJean Delvare }
414e53004e2SJean Delvare 
415e53004e2SJean Delvare /*
416e53004e2SJean Delvare  * Sysfs interface
417e53004e2SJean Delvare  */
418e53004e2SJean Delvare 
show_in0(struct device * dev,struct device_attribute * devattr,char * buf)419e53004e2SJean Delvare static ssize_t show_in0(struct device *dev, struct device_attribute *devattr,
420e53004e2SJean Delvare 			char *buf)
421e53004e2SJean Delvare {
422e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
42351c997d8SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
42451c997d8SJean Delvare 	int nr = attr->index;
425e53004e2SJean Delvare 
42651c997d8SJean Delvare 	return sprintf(buf, "%ld\n", in0_from_reg(data->in[nr]));
427e53004e2SJean Delvare }
428e53004e2SJean Delvare 
show_in0_max(struct device * dev,struct device_attribute * devattr,char * buf)429e53004e2SJean Delvare static ssize_t show_in0_max(struct device *dev, struct device_attribute
430e53004e2SJean Delvare 			    *devattr, char *buf)
431e53004e2SJean Delvare {
432e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
43351c997d8SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
43451c997d8SJean Delvare 	int nr = attr->index;
435e53004e2SJean Delvare 
43651c997d8SJean Delvare 	return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[nr]));
437e53004e2SJean Delvare }
438e53004e2SJean Delvare 
show_in0_min(struct device * dev,struct device_attribute * devattr,char * buf)439e53004e2SJean Delvare static ssize_t show_in0_min(struct device *dev, struct device_attribute
440e53004e2SJean Delvare 			    *devattr, char *buf)
441e53004e2SJean Delvare {
442e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
44351c997d8SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
44451c997d8SJean Delvare 	int nr = attr->index;
445e53004e2SJean Delvare 
44651c997d8SJean Delvare 	return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[nr]));
447e53004e2SJean Delvare }
448e53004e2SJean Delvare 
set_in0_max(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)449e53004e2SJean Delvare static ssize_t set_in0_max(struct device *dev, struct device_attribute
450e53004e2SJean Delvare 			   *devattr, const char *buf, size_t count)
451e53004e2SJean Delvare {
452e53004e2SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
45351c997d8SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
45451c997d8SJean Delvare 	int nr = attr->index;
4552fff0840SGuenter Roeck 	long val;
4562fff0840SGuenter Roeck 	int err;
4572fff0840SGuenter Roeck 
4582fff0840SGuenter Roeck 	err = kstrtol(buf, 10, &val);
4592fff0840SGuenter Roeck 	if (err)
4602fff0840SGuenter Roeck 		return err;
461e53004e2SJean Delvare 
462f0819184SJean Delvare 	mutex_lock(&data->update_lock);
46351c997d8SJean Delvare 	data->in_high[nr] = in0_to_reg(val);
46451c997d8SJean Delvare 	f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]);
465f0819184SJean Delvare 	mutex_unlock(&data->update_lock);
466e53004e2SJean Delvare 
467e53004e2SJean Delvare 	return count;
468e53004e2SJean Delvare }
469e53004e2SJean Delvare 
set_in0_min(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)470e53004e2SJean Delvare static ssize_t set_in0_min(struct device *dev, struct device_attribute
471e53004e2SJean Delvare 			   *devattr, const char *buf, size_t count)
472e53004e2SJean Delvare {
473e53004e2SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
47451c997d8SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
47551c997d8SJean Delvare 	int nr = attr->index;
4762fff0840SGuenter Roeck 	long val;
4772fff0840SGuenter Roeck 	int err;
4782fff0840SGuenter Roeck 
4792fff0840SGuenter Roeck 	err = kstrtol(buf, 10, &val);
4802fff0840SGuenter Roeck 	if (err)
4812fff0840SGuenter Roeck 		return err;
482e53004e2SJean Delvare 
483f0819184SJean Delvare 	mutex_lock(&data->update_lock);
48451c997d8SJean Delvare 	data->in_low[nr] = in0_to_reg(val);
48551c997d8SJean Delvare 	f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]);
486f0819184SJean Delvare 	mutex_unlock(&data->update_lock);
487e53004e2SJean Delvare 
488e53004e2SJean Delvare 	return count;
489e53004e2SJean Delvare }
490e53004e2SJean Delvare 
show_in(struct device * dev,struct device_attribute * devattr,char * buf)491e53004e2SJean Delvare static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
492e53004e2SJean Delvare 		       char *buf)
493e53004e2SJean Delvare {
494e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
495e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
496e53004e2SJean Delvare 	int nr = attr->index;
497e53004e2SJean Delvare 
498e53004e2SJean Delvare 	return sprintf(buf, "%ld\n", in_from_reg(data->in[nr]));
499e53004e2SJean Delvare }
500e53004e2SJean Delvare 
show_in_max(struct device * dev,struct device_attribute * devattr,char * buf)501e53004e2SJean Delvare static ssize_t show_in_max(struct device *dev, struct device_attribute
502e53004e2SJean Delvare 			   *devattr, char *buf)
503e53004e2SJean Delvare {
504e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
505e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
506e53004e2SJean Delvare 	int nr = attr->index;
507e53004e2SJean Delvare 
508e53004e2SJean Delvare 	return sprintf(buf, "%ld\n", in_from_reg(data->in_high[nr]));
509e53004e2SJean Delvare }
510e53004e2SJean Delvare 
show_in_min(struct device * dev,struct device_attribute * devattr,char * buf)511e53004e2SJean Delvare static ssize_t show_in_min(struct device *dev, struct device_attribute
512e53004e2SJean Delvare 			   *devattr, char *buf)
513e53004e2SJean Delvare {
514e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
515e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
516e53004e2SJean Delvare 	int nr = attr->index;
517e53004e2SJean Delvare 
518e53004e2SJean Delvare 	return sprintf(buf, "%ld\n", in_from_reg(data->in_low[nr]));
519e53004e2SJean Delvare }
520e53004e2SJean Delvare 
set_in_max(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)521e53004e2SJean Delvare static ssize_t set_in_max(struct device *dev, struct device_attribute
522e53004e2SJean Delvare 			  *devattr, const char *buf, size_t count)
523e53004e2SJean Delvare {
524e53004e2SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
525e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
526e53004e2SJean Delvare 	int nr = attr->index;
5272fff0840SGuenter Roeck 	long val;
5282fff0840SGuenter Roeck 	int err;
5292fff0840SGuenter Roeck 
5302fff0840SGuenter Roeck 	err = kstrtol(buf, 10, &val);
5312fff0840SGuenter Roeck 	if (err)
5322fff0840SGuenter Roeck 		return err;
533e53004e2SJean Delvare 
534f0819184SJean Delvare 	mutex_lock(&data->update_lock);
535e53004e2SJean Delvare 	data->in_high[nr] = in_to_reg(val);
536e53004e2SJean Delvare 	f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]);
537f0819184SJean Delvare 	mutex_unlock(&data->update_lock);
538e53004e2SJean Delvare 
539e53004e2SJean Delvare 	return count;
540e53004e2SJean Delvare }
541e53004e2SJean Delvare 
set_in_min(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)542e53004e2SJean Delvare static ssize_t set_in_min(struct device *dev, struct device_attribute
543e53004e2SJean Delvare 			  *devattr, const char *buf, size_t count)
544e53004e2SJean Delvare {
545e53004e2SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
546e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
547e53004e2SJean Delvare 	int nr = attr->index;
5482fff0840SGuenter Roeck 	long val;
5492fff0840SGuenter Roeck 	int err;
5502fff0840SGuenter Roeck 
5512fff0840SGuenter Roeck 	err = kstrtol(buf, 10, &val);
5522fff0840SGuenter Roeck 	if (err)
5532fff0840SGuenter Roeck 		return err;
554e53004e2SJean Delvare 
555f0819184SJean Delvare 	mutex_lock(&data->update_lock);
556e53004e2SJean Delvare 	data->in_low[nr] = in_to_reg(val);
557e53004e2SJean Delvare 	f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]);
558f0819184SJean Delvare 	mutex_unlock(&data->update_lock);
559e53004e2SJean Delvare 
560e53004e2SJean Delvare 	return count;
561e53004e2SJean Delvare }
562e53004e2SJean Delvare 
show_fan(struct device * dev,struct device_attribute * devattr,char * buf)563e53004e2SJean Delvare static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
564e53004e2SJean Delvare 			char *buf)
565e53004e2SJean Delvare {
566e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
567e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
568e53004e2SJean Delvare 	int nr = attr->index;
569e53004e2SJean Delvare 
570e53004e2SJean Delvare 	return sprintf(buf, "%ld\n", fan_from_reg(data->fan[nr]));
571e53004e2SJean Delvare }
572e53004e2SJean Delvare 
show_fan_min(struct device * dev,struct device_attribute * devattr,char * buf)573e53004e2SJean Delvare static ssize_t show_fan_min(struct device *dev, struct device_attribute
574e53004e2SJean Delvare 			    *devattr, char *buf)
575e53004e2SJean Delvare {
576e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
577e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
578e53004e2SJean Delvare 	int nr = attr->index;
579e53004e2SJean Delvare 
580e53004e2SJean Delvare 	return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr]));
581e53004e2SJean Delvare }
582e53004e2SJean Delvare 
show_fan_target(struct device * dev,struct device_attribute * devattr,char * buf)583315c7113SJean Delvare static ssize_t show_fan_target(struct device *dev, struct device_attribute
584315c7113SJean Delvare 			       *devattr, char *buf)
585315c7113SJean Delvare {
586315c7113SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
587315c7113SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
588315c7113SJean Delvare 	int nr = attr->index;
589315c7113SJean Delvare 
590315c7113SJean Delvare 	return sprintf(buf, "%ld\n", fan_from_reg(data->fan_target[nr]));
591315c7113SJean Delvare }
592315c7113SJean Delvare 
set_fan_min(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)593e53004e2SJean Delvare static ssize_t set_fan_min(struct device *dev, struct device_attribute
594e53004e2SJean Delvare 			   *devattr, const char *buf, size_t count)
595e53004e2SJean Delvare {
596e53004e2SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
597e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
598e53004e2SJean Delvare 	int nr = attr->index;
5992fff0840SGuenter Roeck 	long val;
6002fff0840SGuenter Roeck 	int err;
6012fff0840SGuenter Roeck 
6022fff0840SGuenter Roeck 	err = kstrtol(buf, 10, &val);
6032fff0840SGuenter Roeck 	if (err)
6042fff0840SGuenter Roeck 		return err;
605e53004e2SJean Delvare 
606f0819184SJean Delvare 	mutex_lock(&data->update_lock);
607e53004e2SJean Delvare 	data->fan_low[nr] = fan_to_reg(val);
608e53004e2SJean Delvare 	f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]);
609f0819184SJean Delvare 	mutex_unlock(&data->update_lock);
610e53004e2SJean Delvare 
611e53004e2SJean Delvare 	return count;
612e53004e2SJean Delvare }
613e53004e2SJean Delvare 
set_fan_target(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)614315c7113SJean Delvare static ssize_t set_fan_target(struct device *dev, struct device_attribute
615315c7113SJean Delvare 			      *devattr, const char *buf, size_t count)
616315c7113SJean Delvare {
617315c7113SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
618315c7113SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
619315c7113SJean Delvare 	int nr = attr->index;
6202fff0840SGuenter Roeck 	long val;
6212fff0840SGuenter Roeck 	int err;
6222fff0840SGuenter Roeck 
6232fff0840SGuenter Roeck 	err = kstrtol(buf, 10, &val);
6242fff0840SGuenter Roeck 	if (err)
6252fff0840SGuenter Roeck 		return err;
626315c7113SJean Delvare 
627315c7113SJean Delvare 	mutex_lock(&data->update_lock);
628315c7113SJean Delvare 	data->fan_target[nr] = fan_to_reg(val);
629315c7113SJean Delvare 	f71805f_write16(data, F71805F_REG_FAN_TARGET(nr),
630315c7113SJean Delvare 			data->fan_target[nr]);
631315c7113SJean Delvare 	mutex_unlock(&data->update_lock);
632315c7113SJean Delvare 
633315c7113SJean Delvare 	return count;
634315c7113SJean Delvare }
635315c7113SJean Delvare 
show_pwm(struct device * dev,struct device_attribute * devattr,char * buf)63695e35312SJean Delvare static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
63795e35312SJean Delvare 			char *buf)
63895e35312SJean Delvare {
63995e35312SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
64095e35312SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
64195e35312SJean Delvare 	int nr = attr->index;
64295e35312SJean Delvare 
64395e35312SJean Delvare 	return sprintf(buf, "%d\n", (int)data->pwm[nr]);
64495e35312SJean Delvare }
64595e35312SJean Delvare 
show_pwm_enable(struct device * dev,struct device_attribute * devattr,char * buf)64695e35312SJean Delvare static ssize_t show_pwm_enable(struct device *dev, struct device_attribute
64795e35312SJean Delvare 			       *devattr, char *buf)
64895e35312SJean Delvare {
64995e35312SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
65095e35312SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
65195e35312SJean Delvare 	int nr = attr->index;
65295e35312SJean Delvare 	int mode;
65395e35312SJean Delvare 
65495e35312SJean Delvare 	switch (data->fan_ctrl[nr] & FAN_CTRL_MODE_MASK) {
65595e35312SJean Delvare 	case FAN_CTRL_MODE_SPEED:
65695e35312SJean Delvare 		mode = 3;
65795e35312SJean Delvare 		break;
65895e35312SJean Delvare 	case FAN_CTRL_MODE_TEMPERATURE:
65995e35312SJean Delvare 		mode = 2;
66095e35312SJean Delvare 		break;
66195e35312SJean Delvare 	default: /* MANUAL */
66295e35312SJean Delvare 		mode = 1;
66395e35312SJean Delvare 	}
66495e35312SJean Delvare 
66595e35312SJean Delvare 	return sprintf(buf, "%d\n", mode);
66695e35312SJean Delvare }
66795e35312SJean Delvare 
show_pwm_freq(struct device * dev,struct device_attribute * devattr,char * buf)6686e2bc17bSJean Delvare static ssize_t show_pwm_freq(struct device *dev, struct device_attribute
6696e2bc17bSJean Delvare 			     *devattr, char *buf)
6706e2bc17bSJean Delvare {
6716e2bc17bSJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
6726e2bc17bSJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
6736e2bc17bSJean Delvare 	int nr = attr->index;
6746e2bc17bSJean Delvare 
6756e2bc17bSJean Delvare 	return sprintf(buf, "%lu\n", pwm_freq_from_reg(data->pwm_freq[nr]));
6766e2bc17bSJean Delvare }
6776e2bc17bSJean Delvare 
show_pwm_mode(struct device * dev,struct device_attribute * devattr,char * buf)678e196783dSJean Delvare static ssize_t show_pwm_mode(struct device *dev, struct device_attribute
679e196783dSJean Delvare 			     *devattr, char *buf)
680e196783dSJean Delvare {
681e196783dSJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
682e196783dSJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
683e196783dSJean Delvare 	int nr = attr->index;
684e196783dSJean Delvare 
685e196783dSJean Delvare 	return sprintf(buf, "%d\n", pwm_mode_from_reg(data->fan_ctrl[nr]));
686e196783dSJean Delvare }
687e196783dSJean Delvare 
set_pwm(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)68895e35312SJean Delvare static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
68995e35312SJean Delvare 		       const char *buf, size_t count)
69095e35312SJean Delvare {
69195e35312SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
69295e35312SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
69395e35312SJean Delvare 	int nr = attr->index;
6942fff0840SGuenter Roeck 	unsigned long val;
6952fff0840SGuenter Roeck 	int err;
6962fff0840SGuenter Roeck 
6972fff0840SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
6982fff0840SGuenter Roeck 	if (err)
6992fff0840SGuenter Roeck 		return err;
70095e35312SJean Delvare 
70195e35312SJean Delvare 	if (val > 255)
70295e35312SJean Delvare 		return -EINVAL;
70395e35312SJean Delvare 
70495e35312SJean Delvare 	mutex_lock(&data->update_lock);
70595e35312SJean Delvare 	data->pwm[nr] = val;
70695e35312SJean Delvare 	f71805f_write8(data, F71805F_REG_PWM_DUTY(nr), data->pwm[nr]);
70795e35312SJean Delvare 	mutex_unlock(&data->update_lock);
70895e35312SJean Delvare 
70995e35312SJean Delvare 	return count;
71095e35312SJean Delvare }
71195e35312SJean Delvare 
71295e35312SJean Delvare static struct attribute *f71805f_attr_pwm[];
71395e35312SJean Delvare 
set_pwm_enable(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)71495e35312SJean Delvare static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
71595e35312SJean Delvare 			      *devattr, const char *buf, size_t count)
71695e35312SJean Delvare {
71795e35312SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
71895e35312SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
71995e35312SJean Delvare 	int nr = attr->index;
72095e35312SJean Delvare 	u8 reg;
7212fff0840SGuenter Roeck 	unsigned long val;
7222fff0840SGuenter Roeck 	int err;
7232fff0840SGuenter Roeck 
7242fff0840SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
7252fff0840SGuenter Roeck 	if (err)
7262fff0840SGuenter Roeck 		return err;
72795e35312SJean Delvare 
72895e35312SJean Delvare 	if (val < 1 || val > 3)
72995e35312SJean Delvare 		return -EINVAL;
73095e35312SJean Delvare 
73195e35312SJean Delvare 	if (val > 1) { /* Automatic mode, user can't set PWM value */
73295e35312SJean Delvare 		if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr],
73395e35312SJean Delvare 				     S_IRUGO))
73495e35312SJean Delvare 			dev_dbg(dev, "chmod -w pwm%d failed\n", nr + 1);
73595e35312SJean Delvare 	}
73695e35312SJean Delvare 
73795e35312SJean Delvare 	mutex_lock(&data->update_lock);
73895e35312SJean Delvare 	reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(nr))
73995e35312SJean Delvare 	    & ~FAN_CTRL_MODE_MASK;
74095e35312SJean Delvare 	switch (val) {
74195e35312SJean Delvare 	case 1:
74295e35312SJean Delvare 		reg |= FAN_CTRL_MODE_MANUAL;
74395e35312SJean Delvare 		break;
74495e35312SJean Delvare 	case 2:
74595e35312SJean Delvare 		reg |= FAN_CTRL_MODE_TEMPERATURE;
74695e35312SJean Delvare 		break;
74795e35312SJean Delvare 	case 3:
74895e35312SJean Delvare 		reg |= FAN_CTRL_MODE_SPEED;
74995e35312SJean Delvare 		break;
75095e35312SJean Delvare 	}
75195e35312SJean Delvare 	data->fan_ctrl[nr] = reg;
75295e35312SJean Delvare 	f71805f_write8(data, F71805F_REG_FAN_CTRL(nr), reg);
75395e35312SJean Delvare 	mutex_unlock(&data->update_lock);
75495e35312SJean Delvare 
75595e35312SJean Delvare 	if (val == 1) { /* Manual mode, user can set PWM value */
75695e35312SJean Delvare 		if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr],
75795e35312SJean Delvare 				     S_IRUGO | S_IWUSR))
75895e35312SJean Delvare 			dev_dbg(dev, "chmod +w pwm%d failed\n", nr + 1);
75995e35312SJean Delvare 	}
76095e35312SJean Delvare 
76195e35312SJean Delvare 	return count;
76295e35312SJean Delvare }
76395e35312SJean Delvare 
set_pwm_freq(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)7646e2bc17bSJean Delvare static ssize_t set_pwm_freq(struct device *dev, struct device_attribute
7656e2bc17bSJean Delvare 			    *devattr, const char *buf, size_t count)
7666e2bc17bSJean Delvare {
7676e2bc17bSJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
7686e2bc17bSJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
7696e2bc17bSJean Delvare 	int nr = attr->index;
7702fff0840SGuenter Roeck 	unsigned long val;
7712fff0840SGuenter Roeck 	int err;
7722fff0840SGuenter Roeck 
7732fff0840SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
7742fff0840SGuenter Roeck 	if (err)
7752fff0840SGuenter Roeck 		return err;
7766e2bc17bSJean Delvare 
7776e2bc17bSJean Delvare 	mutex_lock(&data->update_lock);
7786e2bc17bSJean Delvare 	data->pwm_freq[nr] = pwm_freq_to_reg(val);
7796e2bc17bSJean Delvare 	f71805f_write8(data, F71805F_REG_PWM_FREQ(nr), data->pwm_freq[nr]);
7806e2bc17bSJean Delvare 	mutex_unlock(&data->update_lock);
7816e2bc17bSJean Delvare 
7826e2bc17bSJean Delvare 	return count;
7836e2bc17bSJean Delvare }
7846e2bc17bSJean Delvare 
show_pwm_auto_point_temp(struct device * dev,struct device_attribute * devattr,char * buf)785aba5073dSPhil Endecott static ssize_t show_pwm_auto_point_temp(struct device *dev,
786aba5073dSPhil Endecott 					struct device_attribute *devattr,
787aba5073dSPhil Endecott 					char *buf)
788aba5073dSPhil Endecott {
789aba5073dSPhil Endecott 	struct f71805f_data *data = dev_get_drvdata(dev);
790aba5073dSPhil Endecott 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
791aba5073dSPhil Endecott 	int pwmnr = attr->nr;
792aba5073dSPhil Endecott 	int apnr = attr->index;
793aba5073dSPhil Endecott 
794aba5073dSPhil Endecott 	return sprintf(buf, "%ld\n",
795aba5073dSPhil Endecott 		       temp_from_reg(data->auto_points[pwmnr].temp[apnr]));
796aba5073dSPhil Endecott }
797aba5073dSPhil Endecott 
set_pwm_auto_point_temp(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)798aba5073dSPhil Endecott static ssize_t set_pwm_auto_point_temp(struct device *dev,
799aba5073dSPhil Endecott 				       struct device_attribute *devattr,
800aba5073dSPhil Endecott 				       const char *buf, size_t count)
801aba5073dSPhil Endecott {
802aba5073dSPhil Endecott 	struct f71805f_data *data = dev_get_drvdata(dev);
803aba5073dSPhil Endecott 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
804aba5073dSPhil Endecott 	int pwmnr = attr->nr;
805aba5073dSPhil Endecott 	int apnr = attr->index;
8062fff0840SGuenter Roeck 	unsigned long val;
8072fff0840SGuenter Roeck 	int err;
8082fff0840SGuenter Roeck 
8092fff0840SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
8102fff0840SGuenter Roeck 	if (err)
8112fff0840SGuenter Roeck 		return err;
812aba5073dSPhil Endecott 
813aba5073dSPhil Endecott 	mutex_lock(&data->update_lock);
814aba5073dSPhil Endecott 	data->auto_points[pwmnr].temp[apnr] = temp_to_reg(val);
815aba5073dSPhil Endecott 	f71805f_write8(data, F71805F_REG_PWM_AUTO_POINT_TEMP(pwmnr, apnr),
816aba5073dSPhil Endecott 		       data->auto_points[pwmnr].temp[apnr]);
817aba5073dSPhil Endecott 	mutex_unlock(&data->update_lock);
818aba5073dSPhil Endecott 
819aba5073dSPhil Endecott 	return count;
820aba5073dSPhil Endecott }
821aba5073dSPhil Endecott 
show_pwm_auto_point_fan(struct device * dev,struct device_attribute * devattr,char * buf)822aba5073dSPhil Endecott static ssize_t show_pwm_auto_point_fan(struct device *dev,
823aba5073dSPhil Endecott 				       struct device_attribute *devattr,
824aba5073dSPhil Endecott 				       char *buf)
825aba5073dSPhil Endecott {
826aba5073dSPhil Endecott 	struct f71805f_data *data = dev_get_drvdata(dev);
827aba5073dSPhil Endecott 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
828aba5073dSPhil Endecott 	int pwmnr = attr->nr;
829aba5073dSPhil Endecott 	int apnr = attr->index;
830aba5073dSPhil Endecott 
831aba5073dSPhil Endecott 	return sprintf(buf, "%ld\n",
832aba5073dSPhil Endecott 		       fan_from_reg(data->auto_points[pwmnr].fan[apnr]));
833aba5073dSPhil Endecott }
834aba5073dSPhil Endecott 
set_pwm_auto_point_fan(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)835aba5073dSPhil Endecott static ssize_t set_pwm_auto_point_fan(struct device *dev,
836aba5073dSPhil Endecott 				      struct device_attribute *devattr,
837aba5073dSPhil Endecott 				      const char *buf, size_t count)
838aba5073dSPhil Endecott {
839aba5073dSPhil Endecott 	struct f71805f_data *data = dev_get_drvdata(dev);
840aba5073dSPhil Endecott 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
841aba5073dSPhil Endecott 	int pwmnr = attr->nr;
842aba5073dSPhil Endecott 	int apnr = attr->index;
8432fff0840SGuenter Roeck 	unsigned long val;
8442fff0840SGuenter Roeck 	int err;
8452fff0840SGuenter Roeck 
8462fff0840SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
8472fff0840SGuenter Roeck 	if (err)
8482fff0840SGuenter Roeck 		return err;
849aba5073dSPhil Endecott 
850aba5073dSPhil Endecott 	mutex_lock(&data->update_lock);
851aba5073dSPhil Endecott 	data->auto_points[pwmnr].fan[apnr] = fan_to_reg(val);
852aba5073dSPhil Endecott 	f71805f_write16(data, F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr),
853aba5073dSPhil Endecott 			data->auto_points[pwmnr].fan[apnr]);
854aba5073dSPhil Endecott 	mutex_unlock(&data->update_lock);
855aba5073dSPhil Endecott 
856aba5073dSPhil Endecott 	return count;
857aba5073dSPhil Endecott }
858aba5073dSPhil Endecott 
show_temp(struct device * dev,struct device_attribute * devattr,char * buf)859e53004e2SJean Delvare static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
860e53004e2SJean Delvare 			 char *buf)
861e53004e2SJean Delvare {
862e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
863e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
864e53004e2SJean Delvare 	int nr = attr->index;
865e53004e2SJean Delvare 
866e53004e2SJean Delvare 	return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr]));
867e53004e2SJean Delvare }
868e53004e2SJean Delvare 
show_temp_max(struct device * dev,struct device_attribute * devattr,char * buf)869e53004e2SJean Delvare static ssize_t show_temp_max(struct device *dev, struct device_attribute
870e53004e2SJean Delvare 			     *devattr, char *buf)
871e53004e2SJean Delvare {
872e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
873e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
874e53004e2SJean Delvare 	int nr = attr->index;
875e53004e2SJean Delvare 
876e53004e2SJean Delvare 	return sprintf(buf, "%ld\n", temp_from_reg(data->temp_high[nr]));
877e53004e2SJean Delvare }
878e53004e2SJean Delvare 
show_temp_hyst(struct device * dev,struct device_attribute * devattr,char * buf)879e53004e2SJean Delvare static ssize_t show_temp_hyst(struct device *dev, struct device_attribute
880e53004e2SJean Delvare 			      *devattr, char *buf)
881e53004e2SJean Delvare {
882e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
883e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
884e53004e2SJean Delvare 	int nr = attr->index;
885e53004e2SJean Delvare 
886e53004e2SJean Delvare 	return sprintf(buf, "%ld\n", temp_from_reg(data->temp_hyst[nr]));
887e53004e2SJean Delvare }
888e53004e2SJean Delvare 
show_temp_type(struct device * dev,struct device_attribute * devattr,char * buf)889e53004e2SJean Delvare static ssize_t show_temp_type(struct device *dev, struct device_attribute
890e53004e2SJean Delvare 			      *devattr, char *buf)
891e53004e2SJean Delvare {
892e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
893e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
894e53004e2SJean Delvare 	int nr = attr->index;
895e53004e2SJean Delvare 
896e53004e2SJean Delvare 	/* 3 is diode, 4 is thermistor */
897e53004e2SJean Delvare 	return sprintf(buf, "%u\n", (data->temp_mode & (1 << nr)) ? 3 : 4);
898e53004e2SJean Delvare }
899e53004e2SJean Delvare 
set_temp_max(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)900e53004e2SJean Delvare static ssize_t set_temp_max(struct device *dev, struct device_attribute
901e53004e2SJean Delvare 			    *devattr, const char *buf, size_t count)
902e53004e2SJean Delvare {
903e53004e2SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
904e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
905e53004e2SJean Delvare 	int nr = attr->index;
9062fff0840SGuenter Roeck 	long val;
9072fff0840SGuenter Roeck 	int err;
9082fff0840SGuenter Roeck 
9092fff0840SGuenter Roeck 	err = kstrtol(buf, 10, &val);
9102fff0840SGuenter Roeck 	if (err)
9112fff0840SGuenter Roeck 		return err;
912e53004e2SJean Delvare 
913f0819184SJean Delvare 	mutex_lock(&data->update_lock);
914e53004e2SJean Delvare 	data->temp_high[nr] = temp_to_reg(val);
915e53004e2SJean Delvare 	f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]);
916f0819184SJean Delvare 	mutex_unlock(&data->update_lock);
917e53004e2SJean Delvare 
918e53004e2SJean Delvare 	return count;
919e53004e2SJean Delvare }
920e53004e2SJean Delvare 
set_temp_hyst(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)921e53004e2SJean Delvare static ssize_t set_temp_hyst(struct device *dev, struct device_attribute
922e53004e2SJean Delvare 			     *devattr, const char *buf, size_t count)
923e53004e2SJean Delvare {
924e53004e2SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
925e53004e2SJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
926e53004e2SJean Delvare 	int nr = attr->index;
9272fff0840SGuenter Roeck 	long val;
9282fff0840SGuenter Roeck 	int err;
9292fff0840SGuenter Roeck 
9302fff0840SGuenter Roeck 	err = kstrtol(buf, 10, &val);
9312fff0840SGuenter Roeck 	if (err)
9322fff0840SGuenter Roeck 		return err;
933e53004e2SJean Delvare 
934f0819184SJean Delvare 	mutex_lock(&data->update_lock);
935e53004e2SJean Delvare 	data->temp_hyst[nr] = temp_to_reg(val);
936e53004e2SJean Delvare 	f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]);
937f0819184SJean Delvare 	mutex_unlock(&data->update_lock);
938e53004e2SJean Delvare 
939e53004e2SJean Delvare 	return count;
940e53004e2SJean Delvare }
941e53004e2SJean Delvare 
alarms_in_show(struct device * dev,struct device_attribute * devattr,char * buf)9428258e490SJulia Lawall static ssize_t alarms_in_show(struct device *dev, struct device_attribute
943e53004e2SJean Delvare 			      *devattr, char *buf)
944e53004e2SJean Delvare {
945e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
946e53004e2SJean Delvare 
94751c997d8SJean Delvare 	return sprintf(buf, "%lu\n", data->alarms & 0x7ff);
948e53004e2SJean Delvare }
949e53004e2SJean Delvare 
alarms_fan_show(struct device * dev,struct device_attribute * devattr,char * buf)9508258e490SJulia Lawall static ssize_t alarms_fan_show(struct device *dev, struct device_attribute
951e53004e2SJean Delvare 			       *devattr, char *buf)
952e53004e2SJean Delvare {
953e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
954e53004e2SJean Delvare 
9552d45771eSJean Delvare 	return sprintf(buf, "%lu\n", (data->alarms >> 16) & 0x07);
956e53004e2SJean Delvare }
957e53004e2SJean Delvare 
alarms_temp_show(struct device * dev,struct device_attribute * devattr,char * buf)9588258e490SJulia Lawall static ssize_t alarms_temp_show(struct device *dev, struct device_attribute
959e53004e2SJean Delvare 				*devattr, char *buf)
960e53004e2SJean Delvare {
961e53004e2SJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
962e53004e2SJean Delvare 
9632d45771eSJean Delvare 	return sprintf(buf, "%lu\n", (data->alarms >> 11) & 0x07);
9642d45771eSJean Delvare }
9652d45771eSJean Delvare 
show_alarm(struct device * dev,struct device_attribute * devattr,char * buf)9662d45771eSJean Delvare static ssize_t show_alarm(struct device *dev, struct device_attribute
9672d45771eSJean Delvare 			  *devattr, char *buf)
9682d45771eSJean Delvare {
9692d45771eSJean Delvare 	struct f71805f_data *data = f71805f_update_device(dev);
9702d45771eSJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
9712d45771eSJean Delvare 	int bitnr = attr->index;
9722d45771eSJean Delvare 
9732d45771eSJean Delvare 	return sprintf(buf, "%lu\n", (data->alarms >> bitnr) & 1);
974e53004e2SJean Delvare }
975e53004e2SJean Delvare 
name_show(struct device * dev,struct device_attribute * devattr,char * buf)9768258e490SJulia Lawall static ssize_t name_show(struct device *dev, struct device_attribute
977e53004e2SJean Delvare 			 *devattr, char *buf)
978e53004e2SJean Delvare {
979e53004e2SJean Delvare 	struct f71805f_data *data = dev_get_drvdata(dev);
980e53004e2SJean Delvare 
981e53004e2SJean Delvare 	return sprintf(buf, "%s\n", data->name);
982e53004e2SJean Delvare }
983e53004e2SJean Delvare 
98451c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL, 0);
98551c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR,
98651c997d8SJean Delvare 			  show_in0_max, set_in0_max, 0);
98751c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR,
98851c997d8SJean Delvare 			  show_in0_min, set_in0_min, 0);
9890e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1);
9900e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR,
9910e39e01cSJean Delvare 			  show_in_max, set_in_max, 1);
9920e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO | S_IWUSR,
9930e39e01cSJean Delvare 			  show_in_min, set_in_min, 1);
9940e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2);
9950e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO | S_IWUSR,
9960e39e01cSJean Delvare 			  show_in_max, set_in_max, 2);
9970e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO | S_IWUSR,
9980e39e01cSJean Delvare 			  show_in_min, set_in_min, 2);
9990e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3);
10000e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO | S_IWUSR,
10010e39e01cSJean Delvare 			  show_in_max, set_in_max, 3);
10020e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO | S_IWUSR,
10030e39e01cSJean Delvare 			  show_in_min, set_in_min, 3);
10040e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 4);
10050e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR,
10060e39e01cSJean Delvare 			  show_in_max, set_in_max, 4);
10070e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in4_min, S_IRUGO | S_IWUSR,
10080e39e01cSJean Delvare 			  show_in_min, set_in_min, 4);
10090e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in, NULL, 5);
10100e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in5_max, S_IRUGO | S_IWUSR,
10110e39e01cSJean Delvare 			  show_in_max, set_in_max, 5);
10120e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in5_min, S_IRUGO | S_IWUSR,
10130e39e01cSJean Delvare 			  show_in_min, set_in_min, 5);
10140e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in, NULL, 6);
10150e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in6_max, S_IRUGO | S_IWUSR,
10160e39e01cSJean Delvare 			  show_in_max, set_in_max, 6);
10170e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in6_min, S_IRUGO | S_IWUSR,
10180e39e01cSJean Delvare 			  show_in_min, set_in_min, 6);
10190e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in, NULL, 7);
10200e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in7_max, S_IRUGO | S_IWUSR,
10210e39e01cSJean Delvare 			  show_in_max, set_in_max, 7);
10220e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in7_min, S_IRUGO | S_IWUSR,
10230e39e01cSJean Delvare 			  show_in_min, set_in_min, 7);
10240e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_in, NULL, 8);
10250e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in8_max, S_IRUGO | S_IWUSR,
10260e39e01cSJean Delvare 			  show_in_max, set_in_max, 8);
10270e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in8_min, S_IRUGO | S_IWUSR,
10280e39e01cSJean Delvare 			  show_in_min, set_in_min, 8);
102951c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_in0, NULL, 9);
103051c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in9_max, S_IRUGO | S_IWUSR,
103151c997d8SJean Delvare 			  show_in0_max, set_in0_max, 9);
103251c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in9_min, S_IRUGO | S_IWUSR,
103351c997d8SJean Delvare 			  show_in0_min, set_in0_min, 9);
103451c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_in0, NULL, 10);
103551c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in10_max, S_IRUGO | S_IWUSR,
103651c997d8SJean Delvare 			  show_in0_max, set_in0_max, 10);
103751c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in10_min, S_IRUGO | S_IWUSR,
103851c997d8SJean Delvare 			  show_in0_min, set_in0_min, 10);
10390e39e01cSJean Delvare 
10400e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
10410e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR,
10420e39e01cSJean Delvare 			  show_fan_min, set_fan_min, 0);
1043315c7113SJean Delvare static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR,
1044315c7113SJean Delvare 			  show_fan_target, set_fan_target, 0);
10450e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
10460e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR,
10470e39e01cSJean Delvare 			  show_fan_min, set_fan_min, 1);
1048315c7113SJean Delvare static SENSOR_DEVICE_ATTR(fan2_target, S_IRUGO | S_IWUSR,
1049315c7113SJean Delvare 			  show_fan_target, set_fan_target, 1);
10500e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
10510e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR,
10520e39e01cSJean Delvare 			  show_fan_min, set_fan_min, 2);
1053315c7113SJean Delvare static SENSOR_DEVICE_ATTR(fan3_target, S_IRUGO | S_IWUSR,
1054315c7113SJean Delvare 			  show_fan_target, set_fan_target, 2);
10550e39e01cSJean Delvare 
10560e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
10570e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
10580e39e01cSJean Delvare 		    show_temp_max, set_temp_max, 0);
10590e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
10600e39e01cSJean Delvare 		    show_temp_hyst, set_temp_hyst, 0);
10610e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0);
10620e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
10630e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR,
10640e39e01cSJean Delvare 		    show_temp_max, set_temp_max, 1);
10650e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR,
10660e39e01cSJean Delvare 		    show_temp_hyst, set_temp_hyst, 1);
10670e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1);
10680e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
10690e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO | S_IWUSR,
10700e39e01cSJean Delvare 		    show_temp_max, set_temp_max, 2);
10710e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR,
10720e39e01cSJean Delvare 		    show_temp_hyst, set_temp_hyst, 2);
10730e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2);
10740e39e01cSJean Delvare 
10752fff0840SGuenter Roeck /*
10762fff0840SGuenter Roeck  * pwm (value) files are created read-only, write permission is
10772fff0840SGuenter Roeck  * then added or removed dynamically as needed
10782fff0840SGuenter Roeck  */
107995e35312SJean Delvare static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, show_pwm, set_pwm, 0);
108095e35312SJean Delvare static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
108195e35312SJean Delvare 			  show_pwm_enable, set_pwm_enable, 0);
10826e2bc17bSJean Delvare static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR,
10836e2bc17bSJean Delvare 			  show_pwm_freq, set_pwm_freq, 0);
1084e196783dSJean Delvare static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0);
108595e35312SJean Delvare static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO, show_pwm, set_pwm, 1);
108695e35312SJean Delvare static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
108795e35312SJean Delvare 			  show_pwm_enable, set_pwm_enable, 1);
10886e2bc17bSJean Delvare static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO | S_IWUSR,
10896e2bc17bSJean Delvare 			  show_pwm_freq, set_pwm_freq, 1);
1090e196783dSJean Delvare static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO, show_pwm_mode, NULL, 1);
109195e35312SJean Delvare static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO, show_pwm, set_pwm, 2);
109295e35312SJean Delvare static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR,
109395e35312SJean Delvare 			  show_pwm_enable, set_pwm_enable, 2);
10946e2bc17bSJean Delvare static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO | S_IWUSR,
10956e2bc17bSJean Delvare 			  show_pwm_freq, set_pwm_freq, 2);
1096e196783dSJean Delvare static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2);
109795e35312SJean Delvare 
1098aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR,
1099aba5073dSPhil Endecott 			    show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1100aba5073dSPhil Endecott 			    0, 0);
1101aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_fan, S_IRUGO | S_IWUSR,
1102aba5073dSPhil Endecott 			    show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1103aba5073dSPhil Endecott 			    0, 0);
1104aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR,
1105aba5073dSPhil Endecott 			    show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1106aba5073dSPhil Endecott 			    0, 1);
1107aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_fan, S_IRUGO | S_IWUSR,
1108aba5073dSPhil Endecott 			    show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1109aba5073dSPhil Endecott 			    0, 1);
1110aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR,
1111aba5073dSPhil Endecott 			    show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1112aba5073dSPhil Endecott 			    0, 2);
1113aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_fan, S_IRUGO | S_IWUSR,
1114aba5073dSPhil Endecott 			    show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1115aba5073dSPhil Endecott 			    0, 2);
1116aba5073dSPhil Endecott 
1117aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR,
1118aba5073dSPhil Endecott 			    show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1119aba5073dSPhil Endecott 			    1, 0);
1120aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_fan, S_IRUGO | S_IWUSR,
1121aba5073dSPhil Endecott 			    show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1122aba5073dSPhil Endecott 			    1, 0);
1123aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR,
1124aba5073dSPhil Endecott 			    show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1125aba5073dSPhil Endecott 			    1, 1);
1126aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_fan, S_IRUGO | S_IWUSR,
1127aba5073dSPhil Endecott 			    show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1128aba5073dSPhil Endecott 			    1, 1);
1129aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR,
1130aba5073dSPhil Endecott 			    show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1131aba5073dSPhil Endecott 			    1, 2);
1132aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_fan, S_IRUGO | S_IWUSR,
1133aba5073dSPhil Endecott 			    show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1134aba5073dSPhil Endecott 			    1, 2);
1135aba5073dSPhil Endecott 
1136aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR,
1137aba5073dSPhil Endecott 			    show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1138aba5073dSPhil Endecott 			    2, 0);
1139aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_fan, S_IRUGO | S_IWUSR,
1140aba5073dSPhil Endecott 			    show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1141aba5073dSPhil Endecott 			    2, 0);
1142aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR,
1143aba5073dSPhil Endecott 			    show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1144aba5073dSPhil Endecott 			    2, 1);
1145aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_fan, S_IRUGO | S_IWUSR,
1146aba5073dSPhil Endecott 			    show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1147aba5073dSPhil Endecott 			    2, 1);
1148aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR,
1149aba5073dSPhil Endecott 			    show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1150aba5073dSPhil Endecott 			    2, 2);
1151aba5073dSPhil Endecott static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_fan, S_IRUGO | S_IWUSR,
1152aba5073dSPhil Endecott 			    show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1153aba5073dSPhil Endecott 			    2, 2);
1154aba5073dSPhil Endecott 
11550e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
11560e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
11570e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
11580e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
11590e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4);
11600e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5);
11610e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6);
11620e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7);
11630e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8);
116451c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9);
116551c997d8SJean Delvare static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10);
11660e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 11);
11670e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 12);
11680e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13);
11690e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 16);
11700e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 17);
11710e39e01cSJean Delvare static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 18);
11728258e490SJulia Lawall static DEVICE_ATTR_RO(alarms_in);
11738258e490SJulia Lawall static DEVICE_ATTR_RO(alarms_fan);
11748258e490SJulia Lawall static DEVICE_ATTR_RO(alarms_temp);
11750e39e01cSJean Delvare 
11768258e490SJulia Lawall static DEVICE_ATTR_RO(name);
11770e39e01cSJean Delvare 
11780e39e01cSJean Delvare static struct attribute *f71805f_attributes[] = {
117951c997d8SJean Delvare 	&sensor_dev_attr_in0_input.dev_attr.attr,
118051c997d8SJean Delvare 	&sensor_dev_attr_in0_max.dev_attr.attr,
118151c997d8SJean Delvare 	&sensor_dev_attr_in0_min.dev_attr.attr,
11820e39e01cSJean Delvare 	&sensor_dev_attr_in1_input.dev_attr.attr,
11830e39e01cSJean Delvare 	&sensor_dev_attr_in1_max.dev_attr.attr,
11840e39e01cSJean Delvare 	&sensor_dev_attr_in1_min.dev_attr.attr,
11850e39e01cSJean Delvare 	&sensor_dev_attr_in2_input.dev_attr.attr,
11860e39e01cSJean Delvare 	&sensor_dev_attr_in2_max.dev_attr.attr,
11870e39e01cSJean Delvare 	&sensor_dev_attr_in2_min.dev_attr.attr,
11880e39e01cSJean Delvare 	&sensor_dev_attr_in3_input.dev_attr.attr,
11890e39e01cSJean Delvare 	&sensor_dev_attr_in3_max.dev_attr.attr,
11900e39e01cSJean Delvare 	&sensor_dev_attr_in3_min.dev_attr.attr,
11910e39e01cSJean Delvare 	&sensor_dev_attr_in5_input.dev_attr.attr,
11920e39e01cSJean Delvare 	&sensor_dev_attr_in5_max.dev_attr.attr,
11930e39e01cSJean Delvare 	&sensor_dev_attr_in5_min.dev_attr.attr,
11940e39e01cSJean Delvare 	&sensor_dev_attr_in6_input.dev_attr.attr,
11950e39e01cSJean Delvare 	&sensor_dev_attr_in6_max.dev_attr.attr,
11960e39e01cSJean Delvare 	&sensor_dev_attr_in6_min.dev_attr.attr,
11970e39e01cSJean Delvare 	&sensor_dev_attr_in7_input.dev_attr.attr,
11980e39e01cSJean Delvare 	&sensor_dev_attr_in7_max.dev_attr.attr,
11990e39e01cSJean Delvare 	&sensor_dev_attr_in7_min.dev_attr.attr,
12000e39e01cSJean Delvare 
1201c7176cb5SJean Delvare 	&sensor_dev_attr_fan1_input.dev_attr.attr,
1202c7176cb5SJean Delvare 	&sensor_dev_attr_fan1_min.dev_attr.attr,
1203c7176cb5SJean Delvare 	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
1204c7176cb5SJean Delvare 	&sensor_dev_attr_fan1_target.dev_attr.attr,
1205c7176cb5SJean Delvare 	&sensor_dev_attr_fan2_input.dev_attr.attr,
1206c7176cb5SJean Delvare 	&sensor_dev_attr_fan2_min.dev_attr.attr,
1207c7176cb5SJean Delvare 	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
1208c7176cb5SJean Delvare 	&sensor_dev_attr_fan2_target.dev_attr.attr,
1209c7176cb5SJean Delvare 	&sensor_dev_attr_fan3_input.dev_attr.attr,
1210c7176cb5SJean Delvare 	&sensor_dev_attr_fan3_min.dev_attr.attr,
1211c7176cb5SJean Delvare 	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
1212c7176cb5SJean Delvare 	&sensor_dev_attr_fan3_target.dev_attr.attr,
1213c7176cb5SJean Delvare 
1214c7176cb5SJean Delvare 	&sensor_dev_attr_pwm1.dev_attr.attr,
1215c7176cb5SJean Delvare 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
1216c7176cb5SJean Delvare 	&sensor_dev_attr_pwm1_mode.dev_attr.attr,
1217c7176cb5SJean Delvare 	&sensor_dev_attr_pwm2.dev_attr.attr,
1218c7176cb5SJean Delvare 	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
1219c7176cb5SJean Delvare 	&sensor_dev_attr_pwm2_mode.dev_attr.attr,
1220c7176cb5SJean Delvare 	&sensor_dev_attr_pwm3.dev_attr.attr,
1221c7176cb5SJean Delvare 	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
1222c7176cb5SJean Delvare 	&sensor_dev_attr_pwm3_mode.dev_attr.attr,
1223c7176cb5SJean Delvare 
12240e39e01cSJean Delvare 	&sensor_dev_attr_temp1_input.dev_attr.attr,
12250e39e01cSJean Delvare 	&sensor_dev_attr_temp1_max.dev_attr.attr,
12260e39e01cSJean Delvare 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
12270e39e01cSJean Delvare 	&sensor_dev_attr_temp1_type.dev_attr.attr,
12280e39e01cSJean Delvare 	&sensor_dev_attr_temp2_input.dev_attr.attr,
12290e39e01cSJean Delvare 	&sensor_dev_attr_temp2_max.dev_attr.attr,
12300e39e01cSJean Delvare 	&sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
12310e39e01cSJean Delvare 	&sensor_dev_attr_temp2_type.dev_attr.attr,
12320e39e01cSJean Delvare 	&sensor_dev_attr_temp3_input.dev_attr.attr,
12330e39e01cSJean Delvare 	&sensor_dev_attr_temp3_max.dev_attr.attr,
12340e39e01cSJean Delvare 	&sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
12350e39e01cSJean Delvare 	&sensor_dev_attr_temp3_type.dev_attr.attr,
12360e39e01cSJean Delvare 
1237aba5073dSPhil Endecott 	&sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
1238aba5073dSPhil Endecott 	&sensor_dev_attr_pwm1_auto_point1_fan.dev_attr.attr,
1239aba5073dSPhil Endecott 	&sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
1240aba5073dSPhil Endecott 	&sensor_dev_attr_pwm1_auto_point2_fan.dev_attr.attr,
1241aba5073dSPhil Endecott 	&sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
1242aba5073dSPhil Endecott 	&sensor_dev_attr_pwm1_auto_point3_fan.dev_attr.attr,
1243aba5073dSPhil Endecott 	&sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr,
1244aba5073dSPhil Endecott 	&sensor_dev_attr_pwm2_auto_point1_fan.dev_attr.attr,
1245aba5073dSPhil Endecott 	&sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
1246aba5073dSPhil Endecott 	&sensor_dev_attr_pwm2_auto_point2_fan.dev_attr.attr,
1247aba5073dSPhil Endecott 	&sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
1248aba5073dSPhil Endecott 	&sensor_dev_attr_pwm2_auto_point3_fan.dev_attr.attr,
1249aba5073dSPhil Endecott 	&sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr,
1250aba5073dSPhil Endecott 	&sensor_dev_attr_pwm3_auto_point1_fan.dev_attr.attr,
1251aba5073dSPhil Endecott 	&sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr,
1252aba5073dSPhil Endecott 	&sensor_dev_attr_pwm3_auto_point2_fan.dev_attr.attr,
1253aba5073dSPhil Endecott 	&sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr,
1254aba5073dSPhil Endecott 	&sensor_dev_attr_pwm3_auto_point3_fan.dev_attr.attr,
1255aba5073dSPhil Endecott 
12560e39e01cSJean Delvare 	&sensor_dev_attr_in0_alarm.dev_attr.attr,
12570e39e01cSJean Delvare 	&sensor_dev_attr_in1_alarm.dev_attr.attr,
12580e39e01cSJean Delvare 	&sensor_dev_attr_in2_alarm.dev_attr.attr,
12590e39e01cSJean Delvare 	&sensor_dev_attr_in3_alarm.dev_attr.attr,
12600e39e01cSJean Delvare 	&sensor_dev_attr_in5_alarm.dev_attr.attr,
12610e39e01cSJean Delvare 	&sensor_dev_attr_in6_alarm.dev_attr.attr,
12620e39e01cSJean Delvare 	&sensor_dev_attr_in7_alarm.dev_attr.attr,
12630e39e01cSJean Delvare 	&dev_attr_alarms_in.attr,
12640e39e01cSJean Delvare 	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
12650e39e01cSJean Delvare 	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
12660e39e01cSJean Delvare 	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
12670e39e01cSJean Delvare 	&dev_attr_alarms_temp.attr,
12680e39e01cSJean Delvare 	&dev_attr_alarms_fan.attr,
12690e39e01cSJean Delvare 
12700e39e01cSJean Delvare 	&dev_attr_name.attr,
12710e39e01cSJean Delvare 	NULL
12722488a39dSJean Delvare };
12732488a39dSJean Delvare 
12740e39e01cSJean Delvare static const struct attribute_group f71805f_group = {
12750e39e01cSJean Delvare 	.attrs = f71805f_attributes,
12762488a39dSJean Delvare };
12772488a39dSJean Delvare 
127851c997d8SJean Delvare static struct attribute *f71805f_attributes_optin[4][5] = {
127951c997d8SJean Delvare 	{
128051c997d8SJean Delvare 		&sensor_dev_attr_in4_input.dev_attr.attr,
128151c997d8SJean Delvare 		&sensor_dev_attr_in4_max.dev_attr.attr,
128251c997d8SJean Delvare 		&sensor_dev_attr_in4_min.dev_attr.attr,
128351c997d8SJean Delvare 		&sensor_dev_attr_in4_alarm.dev_attr.attr,
128451c997d8SJean Delvare 		NULL
128551c997d8SJean Delvare 	}, {
128651c997d8SJean Delvare 		&sensor_dev_attr_in8_input.dev_attr.attr,
128751c997d8SJean Delvare 		&sensor_dev_attr_in8_max.dev_attr.attr,
128851c997d8SJean Delvare 		&sensor_dev_attr_in8_min.dev_attr.attr,
128951c997d8SJean Delvare 		&sensor_dev_attr_in8_alarm.dev_attr.attr,
129051c997d8SJean Delvare 		NULL
129151c997d8SJean Delvare 	}, {
129251c997d8SJean Delvare 		&sensor_dev_attr_in9_input.dev_attr.attr,
129351c997d8SJean Delvare 		&sensor_dev_attr_in9_max.dev_attr.attr,
129451c997d8SJean Delvare 		&sensor_dev_attr_in9_min.dev_attr.attr,
129551c997d8SJean Delvare 		&sensor_dev_attr_in9_alarm.dev_attr.attr,
129651c997d8SJean Delvare 		NULL
129751c997d8SJean Delvare 	}, {
129851c997d8SJean Delvare 		&sensor_dev_attr_in10_input.dev_attr.attr,
129951c997d8SJean Delvare 		&sensor_dev_attr_in10_max.dev_attr.attr,
130051c997d8SJean Delvare 		&sensor_dev_attr_in10_min.dev_attr.attr,
130151c997d8SJean Delvare 		&sensor_dev_attr_in10_alarm.dev_attr.attr,
130251c997d8SJean Delvare 		NULL
130351c997d8SJean Delvare 	}
130451c997d8SJean Delvare };
130551c997d8SJean Delvare 
130651c997d8SJean Delvare static const struct attribute_group f71805f_group_optin[4] = {
130751c997d8SJean Delvare 	{ .attrs = f71805f_attributes_optin[0] },
130851c997d8SJean Delvare 	{ .attrs = f71805f_attributes_optin[1] },
130951c997d8SJean Delvare 	{ .attrs = f71805f_attributes_optin[2] },
131051c997d8SJean Delvare 	{ .attrs = f71805f_attributes_optin[3] },
131151c997d8SJean Delvare };
131251c997d8SJean Delvare 
13132fff0840SGuenter Roeck /*
13142fff0840SGuenter Roeck  * We don't include pwm_freq files in the arrays above, because they must be
13152fff0840SGuenter Roeck  * created conditionally (only if pwm_mode is 1 == PWM)
13162fff0840SGuenter Roeck  */
1317e196783dSJean Delvare static struct attribute *f71805f_attributes_pwm_freq[] = {
1318e196783dSJean Delvare 	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
1319e196783dSJean Delvare 	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
1320e196783dSJean Delvare 	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
1321e196783dSJean Delvare 	NULL
1322e196783dSJean Delvare };
1323e196783dSJean Delvare 
1324e196783dSJean Delvare static const struct attribute_group f71805f_group_pwm_freq = {
1325e196783dSJean Delvare 	.attrs = f71805f_attributes_pwm_freq,
1326e196783dSJean Delvare };
1327e196783dSJean Delvare 
132895e35312SJean Delvare /* We also need an indexed access to pwmN files to toggle writability */
132995e35312SJean Delvare static struct attribute *f71805f_attr_pwm[] = {
133095e35312SJean Delvare 	&sensor_dev_attr_pwm1.dev_attr.attr,
133195e35312SJean Delvare 	&sensor_dev_attr_pwm2.dev_attr.attr,
133295e35312SJean Delvare 	&sensor_dev_attr_pwm3.dev_attr.attr,
133395e35312SJean Delvare };
133495e35312SJean Delvare 
1335e53004e2SJean Delvare /*
1336e53004e2SJean Delvare  * Device registration and initialization
1337e53004e2SJean Delvare  */
1338e53004e2SJean Delvare 
f71805f_init_device(struct f71805f_data * data)13396c931ae1SBill Pemberton static void f71805f_init_device(struct f71805f_data *data)
1340e53004e2SJean Delvare {
1341e53004e2SJean Delvare 	u8 reg;
1342e53004e2SJean Delvare 	int i;
1343e53004e2SJean Delvare 
1344e53004e2SJean Delvare 	reg = f71805f_read8(data, F71805F_REG_START);
1345e53004e2SJean Delvare 	if ((reg & 0x41) != 0x01) {
1346692fe501SGuenter Roeck 		pr_debug("Starting monitoring operations\n");
1347e53004e2SJean Delvare 		f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40);
1348e53004e2SJean Delvare 	}
1349e53004e2SJean Delvare 
13502fff0840SGuenter Roeck 	/*
13512fff0840SGuenter Roeck 	 * Fan monitoring can be disabled. If it is, we won't be polling
13522fff0840SGuenter Roeck 	 * the register values, and won't create the related sysfs files.
13532fff0840SGuenter Roeck 	 */
1354e53004e2SJean Delvare 	for (i = 0; i < 3; i++) {
13556b14a546SJean Delvare 		data->fan_ctrl[i] = f71805f_read8(data,
13566b14a546SJean Delvare 						  F71805F_REG_FAN_CTRL(i));
13572fff0840SGuenter Roeck 		/*
13582fff0840SGuenter Roeck 		 * Clear latch full bit, else "speed mode" fan speed control
13592fff0840SGuenter Roeck 		 * doesn't work
13602fff0840SGuenter Roeck 		 */
1361315c7113SJean Delvare 		if (data->fan_ctrl[i] & FAN_CTRL_LATCH_FULL) {
1362315c7113SJean Delvare 			data->fan_ctrl[i] &= ~FAN_CTRL_LATCH_FULL;
1363315c7113SJean Delvare 			f71805f_write8(data, F71805F_REG_FAN_CTRL(i),
1364315c7113SJean Delvare 				       data->fan_ctrl[i]);
1365315c7113SJean Delvare 		}
1366e53004e2SJean Delvare 	}
1367e53004e2SJean Delvare }
1368e53004e2SJean Delvare 
f71805f_probe(struct platform_device * pdev)13696c931ae1SBill Pemberton static int f71805f_probe(struct platform_device *pdev)
1370e53004e2SJean Delvare {
1371a8b3a3a5SJingoo Han 	struct f71805f_sio_data *sio_data = dev_get_platdata(&pdev->dev);
1372e53004e2SJean Delvare 	struct f71805f_data *data;
1373e53004e2SJean Delvare 	struct resource *res;
13742488a39dSJean Delvare 	int i, err;
1375e53004e2SJean Delvare 
13762fff0840SGuenter Roeck 	static const char * const names[] = {
137751c997d8SJean Delvare 		"f71805f",
137851c997d8SJean Delvare 		"f71872f",
137951c997d8SJean Delvare 	};
138051c997d8SJean Delvare 
1381adc14132SGuenter Roeck 	data = devm_kzalloc(&pdev->dev, sizeof(struct f71805f_data),
1382adc14132SGuenter Roeck 			    GFP_KERNEL);
1383b83207fdSJingoo Han 	if (!data)
1384adc14132SGuenter Roeck 		return -ENOMEM;
1385e53004e2SJean Delvare 
1386e53004e2SJean Delvare 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
1387adc14132SGuenter Roeck 	if (!devm_request_region(&pdev->dev, res->start + ADDR_REG_OFFSET, 2,
1388adc14132SGuenter Roeck 				 DRVNAME)) {
1389ce7ee4e8SJean Delvare 		dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
1390ce7ee4e8SJean Delvare 			(unsigned long)(res->start + ADDR_REG_OFFSET),
1391ce7ee4e8SJean Delvare 			(unsigned long)(res->start + ADDR_REG_OFFSET + 1));
1392adc14132SGuenter Roeck 		return -EBUSY;
1393ce7ee4e8SJean Delvare 	}
1394e53004e2SJean Delvare 	data->addr = res->start;
139551c997d8SJean Delvare 	data->name = names[sio_data->kind];
1396f0819184SJean Delvare 	mutex_init(&data->update_lock);
1397e53004e2SJean Delvare 
1398e53004e2SJean Delvare 	platform_set_drvdata(pdev, data);
1399e53004e2SJean Delvare 
140051c997d8SJean Delvare 	/* Some voltage inputs depend on chip model and configuration */
140151c997d8SJean Delvare 	switch (sio_data->kind) {
140251c997d8SJean Delvare 	case f71805f:
140351c997d8SJean Delvare 		data->has_in = 0x1ff;
140451c997d8SJean Delvare 		break;
140551c997d8SJean Delvare 	case f71872f:
140651c997d8SJean Delvare 		data->has_in = 0x6ef;
140751c997d8SJean Delvare 		if (sio_data->fnsel1 & 0x01)
140851c997d8SJean Delvare 			data->has_in |= (1 << 4); /* in4 */
140951c997d8SJean Delvare 		if (sio_data->fnsel1 & 0x02)
141051c997d8SJean Delvare 			data->has_in |= (1 << 8); /* in8 */
141151c997d8SJean Delvare 		break;
141251c997d8SJean Delvare 	}
141351c997d8SJean Delvare 
1414e53004e2SJean Delvare 	/* Initialize the F71805F chip */
1415e53004e2SJean Delvare 	f71805f_init_device(data);
1416e53004e2SJean Delvare 
1417e53004e2SJean Delvare 	/* Register sysfs interface files */
14182fff0840SGuenter Roeck 	err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group);
14192fff0840SGuenter Roeck 	if (err)
1420adc14132SGuenter Roeck 		return err;
142151c997d8SJean Delvare 	if (data->has_in & (1 << 4)) { /* in4 */
14222fff0840SGuenter Roeck 		err = sysfs_create_group(&pdev->dev.kobj,
14232fff0840SGuenter Roeck 					 &f71805f_group_optin[0]);
14242fff0840SGuenter Roeck 		if (err)
142551c997d8SJean Delvare 			goto exit_remove_files;
142651c997d8SJean Delvare 	}
142751c997d8SJean Delvare 	if (data->has_in & (1 << 8)) { /* in8 */
14282fff0840SGuenter Roeck 		err = sysfs_create_group(&pdev->dev.kobj,
14292fff0840SGuenter Roeck 					 &f71805f_group_optin[1]);
14302fff0840SGuenter Roeck 		if (err)
143151c997d8SJean Delvare 			goto exit_remove_files;
143251c997d8SJean Delvare 	}
143351c997d8SJean Delvare 	if (data->has_in & (1 << 9)) { /* in9 (F71872F/FG only) */
14342fff0840SGuenter Roeck 		err = sysfs_create_group(&pdev->dev.kobj,
14352fff0840SGuenter Roeck 					 &f71805f_group_optin[2]);
14362fff0840SGuenter Roeck 		if (err)
143751c997d8SJean Delvare 			goto exit_remove_files;
143851c997d8SJean Delvare 	}
143951c997d8SJean Delvare 	if (data->has_in & (1 << 10)) { /* in9 (F71872F/FG only) */
14402fff0840SGuenter Roeck 		err = sysfs_create_group(&pdev->dev.kobj,
14412fff0840SGuenter Roeck 					 &f71805f_group_optin[3]);
14422fff0840SGuenter Roeck 		if (err)
144351c997d8SJean Delvare 			goto exit_remove_files;
144451c997d8SJean Delvare 	}
14450e39e01cSJean Delvare 	for (i = 0; i < 3; i++) {
1446e196783dSJean Delvare 		/* If control mode is PWM, create pwm_freq file */
1447e196783dSJean Delvare 		if (!(data->fan_ctrl[i] & FAN_CTRL_DC_MODE)) {
14482fff0840SGuenter Roeck 			err = sysfs_create_file(&pdev->dev.kobj,
14492fff0840SGuenter Roeck 						f71805f_attributes_pwm_freq[i]);
14502fff0840SGuenter Roeck 			if (err)
1451e196783dSJean Delvare 				goto exit_remove_files;
1452e196783dSJean Delvare 		}
145395e35312SJean Delvare 		/* If PWM is in manual mode, add write permission */
145495e35312SJean Delvare 		if (data->fan_ctrl[i] & FAN_CTRL_MODE_MANUAL) {
14552fff0840SGuenter Roeck 			err = sysfs_chmod_file(&pdev->dev.kobj,
145695e35312SJean Delvare 					       f71805f_attr_pwm[i],
14572fff0840SGuenter Roeck 					       S_IRUGO | S_IWUSR);
14582fff0840SGuenter Roeck 			if (err) {
145995e35312SJean Delvare 				dev_err(&pdev->dev, "chmod +w pwm%d failed\n",
146095e35312SJean Delvare 					i + 1);
146195e35312SJean Delvare 				goto exit_remove_files;
146295e35312SJean Delvare 			}
146395e35312SJean Delvare 		}
14640e39e01cSJean Delvare 	}
14650e39e01cSJean Delvare 
14661beeffe4STony Jones 	data->hwmon_dev = hwmon_device_register(&pdev->dev);
14671beeffe4STony Jones 	if (IS_ERR(data->hwmon_dev)) {
14681beeffe4STony Jones 		err = PTR_ERR(data->hwmon_dev);
14690e39e01cSJean Delvare 		dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
14700e39e01cSJean Delvare 		goto exit_remove_files;
1471e53004e2SJean Delvare 	}
1472e53004e2SJean Delvare 
1473e53004e2SJean Delvare 	return 0;
1474e53004e2SJean Delvare 
14750e39e01cSJean Delvare exit_remove_files:
14760e39e01cSJean Delvare 	sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
147751c997d8SJean Delvare 	for (i = 0; i < 4; i++)
147851c997d8SJean Delvare 		sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
1479e196783dSJean Delvare 	sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
1480e53004e2SJean Delvare 	return err;
1481e53004e2SJean Delvare }
1482e53004e2SJean Delvare 
f71805f_remove(struct platform_device * pdev)1483281dfd0bSBill Pemberton static int f71805f_remove(struct platform_device *pdev)
1484e53004e2SJean Delvare {
1485e53004e2SJean Delvare 	struct f71805f_data *data = platform_get_drvdata(pdev);
14860e39e01cSJean Delvare 	int i;
1487e53004e2SJean Delvare 
14881beeffe4STony Jones 	hwmon_device_unregister(data->hwmon_dev);
14890e39e01cSJean Delvare 	sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
149051c997d8SJean Delvare 	for (i = 0; i < 4; i++)
149151c997d8SJean Delvare 		sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
1492e196783dSJean Delvare 	sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
1493ce7ee4e8SJean Delvare 
1494e53004e2SJean Delvare 	return 0;
1495e53004e2SJean Delvare }
1496e53004e2SJean Delvare 
1497e53004e2SJean Delvare static struct platform_driver f71805f_driver = {
1498e53004e2SJean Delvare 	.driver = {
1499e53004e2SJean Delvare 		.name	= DRVNAME,
1500e53004e2SJean Delvare 	},
1501e53004e2SJean Delvare 	.probe		= f71805f_probe,
15029e5e9b7aSBill Pemberton 	.remove		= f71805f_remove,
1503e53004e2SJean Delvare };
1504e53004e2SJean Delvare 
f71805f_device_add(unsigned short address,const struct f71805f_sio_data * sio_data)150551c997d8SJean Delvare static int __init f71805f_device_add(unsigned short address,
150651c997d8SJean Delvare 				     const struct f71805f_sio_data *sio_data)
1507e53004e2SJean Delvare {
1508568825c8SJean Delvare 	struct resource res = {
1509568825c8SJean Delvare 		.start	= address,
1510568825c8SJean Delvare 		.end	= address + REGION_LENGTH - 1,
1511568825c8SJean Delvare 		.flags	= IORESOURCE_IO,
1512568825c8SJean Delvare 	};
1513e53004e2SJean Delvare 	int err;
1514e53004e2SJean Delvare 
1515e53004e2SJean Delvare 	pdev = platform_device_alloc(DRVNAME, address);
1516e53004e2SJean Delvare 	if (!pdev) {
1517e53004e2SJean Delvare 		err = -ENOMEM;
1518e54c5ad6SJoe Perches 		pr_err("Device allocation failed\n");
1519e53004e2SJean Delvare 		goto exit;
1520e53004e2SJean Delvare 	}
1521e53004e2SJean Delvare 
1522568825c8SJean Delvare 	res.name = pdev->name;
1523b9acb64aSJean Delvare 	err = acpi_check_resource_conflict(&res);
1524b9acb64aSJean Delvare 	if (err)
1525b9acb64aSJean Delvare 		goto exit_device_put;
1526b9acb64aSJean Delvare 
1527568825c8SJean Delvare 	err = platform_device_add_resources(pdev, &res, 1);
1528e53004e2SJean Delvare 	if (err) {
1529e54c5ad6SJoe Perches 		pr_err("Device resource addition failed (%d)\n", err);
1530e53004e2SJean Delvare 		goto exit_device_put;
1531e53004e2SJean Delvare 	}
1532e53004e2SJean Delvare 
15332df6d811SJean Delvare 	err = platform_device_add_data(pdev, sio_data,
15342df6d811SJean Delvare 				       sizeof(struct f71805f_sio_data));
15352df6d811SJean Delvare 	if (err) {
1536e54c5ad6SJoe Perches 		pr_err("Platform data allocation failed\n");
153751c997d8SJean Delvare 		goto exit_device_put;
153851c997d8SJean Delvare 	}
153951c997d8SJean Delvare 
1540e53004e2SJean Delvare 	err = platform_device_add(pdev);
1541e53004e2SJean Delvare 	if (err) {
1542e54c5ad6SJoe Perches 		pr_err("Device addition failed (%d)\n", err);
1543a117dddfSJean Delvare 		goto exit_device_put;
1544e53004e2SJean Delvare 	}
1545e53004e2SJean Delvare 
1546e53004e2SJean Delvare 	return 0;
1547e53004e2SJean Delvare 
1548e53004e2SJean Delvare exit_device_put:
1549e53004e2SJean Delvare 	platform_device_put(pdev);
1550e53004e2SJean Delvare exit:
1551e53004e2SJean Delvare 	return err;
1552e53004e2SJean Delvare }
1553e53004e2SJean Delvare 
f71805f_find(int sioaddr,unsigned short * address,struct f71805f_sio_data * sio_data)155451c997d8SJean Delvare static int __init f71805f_find(int sioaddr, unsigned short *address,
155551c997d8SJean Delvare 			       struct f71805f_sio_data *sio_data)
1556e53004e2SJean Delvare {
155773e6ff71SGuenter Roeck 	int err;
1558e53004e2SJean Delvare 	u16 devid;
1559e53004e2SJean Delvare 
15602fff0840SGuenter Roeck 	static const char * const names[] = {
156151c997d8SJean Delvare 		"F71805F/FG",
15629cab0217SJean Delvare 		"F71872F/FG or F71806F/FG",
156351c997d8SJean Delvare 	};
156451c997d8SJean Delvare 
156573e6ff71SGuenter Roeck 	err = superio_enter(sioaddr);
156673e6ff71SGuenter Roeck 	if (err)
156773e6ff71SGuenter Roeck 		return err;
1568e53004e2SJean Delvare 
156973e6ff71SGuenter Roeck 	err = -ENODEV;
1570e53004e2SJean Delvare 	devid = superio_inw(sioaddr, SIO_REG_MANID);
1571e53004e2SJean Delvare 	if (devid != SIO_FINTEK_ID)
1572e53004e2SJean Delvare 		goto exit;
1573e53004e2SJean Delvare 
157467b671bcSJean Delvare 	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
157551c997d8SJean Delvare 	switch (devid) {
157651c997d8SJean Delvare 	case SIO_F71805F_ID:
157751c997d8SJean Delvare 		sio_data->kind = f71805f;
157851c997d8SJean Delvare 		break;
157951c997d8SJean Delvare 	case SIO_F71872F_ID:
158051c997d8SJean Delvare 		sio_data->kind = f71872f;
158151c997d8SJean Delvare 		sio_data->fnsel1 = superio_inb(sioaddr, SIO_REG_FNSEL1);
158251c997d8SJean Delvare 		break;
158351c997d8SJean Delvare 	default:
1584e54c5ad6SJoe Perches 		pr_info("Unsupported Fintek device, skipping\n");
1585e53004e2SJean Delvare 		goto exit;
1586e53004e2SJean Delvare 	}
1587e53004e2SJean Delvare 
1588e53004e2SJean Delvare 	superio_select(sioaddr, F71805F_LD_HWM);
1589e53004e2SJean Delvare 	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
1590e54c5ad6SJoe Perches 		pr_warn("Device not activated, skipping\n");
1591e53004e2SJean Delvare 		goto exit;
1592e53004e2SJean Delvare 	}
1593e53004e2SJean Delvare 
1594e53004e2SJean Delvare 	*address = superio_inw(sioaddr, SIO_REG_ADDR);
1595e53004e2SJean Delvare 	if (*address == 0) {
1596e54c5ad6SJoe Perches 		pr_warn("Base address not set, skipping\n");
1597e53004e2SJean Delvare 		goto exit;
1598e53004e2SJean Delvare 	}
159975c99029SJean Delvare 	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
1600e53004e2SJean Delvare 
1601e53004e2SJean Delvare 	err = 0;
1602e54c5ad6SJoe Perches 	pr_info("Found %s chip at %#x, revision %u\n",
160351c997d8SJean Delvare 		names[sio_data->kind], *address,
160451c997d8SJean Delvare 		superio_inb(sioaddr, SIO_REG_DEVREV));
1605e53004e2SJean Delvare 
1606e53004e2SJean Delvare exit:
1607e53004e2SJean Delvare 	superio_exit(sioaddr);
1608e53004e2SJean Delvare 	return err;
1609e53004e2SJean Delvare }
1610e53004e2SJean Delvare 
f71805f_init(void)1611e53004e2SJean Delvare static int __init f71805f_init(void)
1612e53004e2SJean Delvare {
1613e53004e2SJean Delvare 	int err;
1614e53004e2SJean Delvare 	unsigned short address;
161551c997d8SJean Delvare 	struct f71805f_sio_data sio_data;
1616e53004e2SJean Delvare 
161751c997d8SJean Delvare 	if (f71805f_find(0x2e, &address, &sio_data)
161851c997d8SJean Delvare 	 && f71805f_find(0x4e, &address, &sio_data))
1619e53004e2SJean Delvare 		return -ENODEV;
1620e53004e2SJean Delvare 
1621e53004e2SJean Delvare 	err = platform_driver_register(&f71805f_driver);
1622e53004e2SJean Delvare 	if (err)
1623e53004e2SJean Delvare 		goto exit;
1624e53004e2SJean Delvare 
1625e53004e2SJean Delvare 	/* Sets global pdev as a side effect */
162651c997d8SJean Delvare 	err = f71805f_device_add(address, &sio_data);
1627e53004e2SJean Delvare 	if (err)
1628e53004e2SJean Delvare 		goto exit_driver;
1629e53004e2SJean Delvare 
1630e53004e2SJean Delvare 	return 0;
1631e53004e2SJean Delvare 
1632e53004e2SJean Delvare exit_driver:
1633e53004e2SJean Delvare 	platform_driver_unregister(&f71805f_driver);
1634e53004e2SJean Delvare exit:
1635e53004e2SJean Delvare 	return err;
1636e53004e2SJean Delvare }
1637e53004e2SJean Delvare 
f71805f_exit(void)1638e53004e2SJean Delvare static void __exit f71805f_exit(void)
1639e53004e2SJean Delvare {
1640e53004e2SJean Delvare 	platform_device_unregister(pdev);
1641e53004e2SJean Delvare 	platform_driver_unregister(&f71805f_driver);
1642e53004e2SJean Delvare }
1643e53004e2SJean Delvare 
1644964f945bSJean Delvare MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
1645e53004e2SJean Delvare MODULE_LICENSE("GPL");
164651c997d8SJean Delvare MODULE_DESCRIPTION("F71805F/F71872F hardware monitoring driver");
1647e53004e2SJean Delvare 
1648e53004e2SJean Delvare module_init(f71805f_init);
1649e53004e2SJean Delvare module_exit(f71805f_exit);
1650