xref: /openbmc/linux/drivers/hwmon/f71882fg.c (revision 384740dc)
1 /***************************************************************************
2  *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *
3  *   Copyright (C) 2007 by Hans de Goede  <j.w.r.degoede@hhs.nl>           *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/slab.h>
24 #include <linux/jiffies.h>
25 #include <linux/platform_device.h>
26 #include <linux/hwmon.h>
27 #include <linux/hwmon-sysfs.h>
28 #include <linux/err.h>
29 #include <linux/mutex.h>
30 #include <asm/io.h>
31 
32 #define DRVNAME "f71882fg"
33 
34 #define SIO_F71882FG_LD_HWM	0x04	/* Hardware monitor logical device*/
35 #define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
36 #define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
37 
38 #define SIO_REG_LDSEL		0x07	/* Logical device select */
39 #define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
40 #define SIO_REG_DEVREV		0x22	/* Device revision */
41 #define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */
42 #define SIO_REG_ENABLE		0x30	/* Logical device enable */
43 #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
44 
45 #define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
46 #define SIO_F71882_ID		0x0541	/* Chipset ID */
47 
48 #define REGION_LENGTH		8
49 #define ADDR_REG_OFFSET		5
50 #define DATA_REG_OFFSET		6
51 
52 #define F71882FG_REG_PECI		0x0A
53 
54 #define F71882FG_REG_IN_STATUS		0x12
55 #define F71882FG_REG_IN_BEEP		0x13
56 #define F71882FG_REG_IN(nr)		(0x20  + (nr))
57 #define F71882FG_REG_IN1_HIGH		0x32
58 
59 #define F71882FG_REG_FAN(nr)		(0xA0 + (16 * (nr)))
60 #define F71882FG_REG_FAN_STATUS		0x92
61 #define F71882FG_REG_FAN_BEEP		0x93
62 
63 #define F71882FG_REG_TEMP(nr)		(0x72 + 2 * (nr))
64 #define F71882FG_REG_TEMP_OVT(nr)	(0x82 + 2 * (nr))
65 #define F71882FG_REG_TEMP_HIGH(nr)	(0x83 + 2 * (nr))
66 #define F71882FG_REG_TEMP_STATUS	0x62
67 #define F71882FG_REG_TEMP_BEEP		0x63
68 #define F71882FG_REG_TEMP_HYST1		0x6C
69 #define F71882FG_REG_TEMP_HYST23	0x6D
70 #define F71882FG_REG_TEMP_TYPE		0x6B
71 #define F71882FG_REG_TEMP_DIODE_OPEN	0x6F
72 
73 #define	F71882FG_REG_START		0x01
74 
75 #define FAN_MIN_DETECT			366 /* Lowest detectable fanspeed */
76 
77 static unsigned short force_id;
78 module_param(force_id, ushort, 0);
79 MODULE_PARM_DESC(force_id, "Override the detected device ID");
80 
81 static struct platform_device *f71882fg_pdev = NULL;
82 
83 /* Super-I/O Function prototypes */
84 static inline int superio_inb(int base, int reg);
85 static inline int superio_inw(int base, int reg);
86 static inline void superio_enter(int base);
87 static inline void superio_select(int base, int ld);
88 static inline void superio_exit(int base);
89 
90 struct f71882fg_data {
91 	unsigned short addr;
92 	struct device *hwmon_dev;
93 
94 	struct mutex update_lock;
95 	char valid;			/* !=0 if following fields are valid */
96 	unsigned long last_updated;	/* In jiffies */
97 	unsigned long last_limits;	/* In jiffies */
98 
99 	/* Register Values */
100 	u8	in[9];
101 	u8	in1_max;
102 	u8	in_status;
103 	u8	in_beep;
104 	u16	fan[4];
105 	u8	fan_status;
106 	u8	fan_beep;
107 	u8	temp[3];
108 	u8	temp_ovt[3];
109 	u8	temp_high[3];
110 	u8	temp_hyst[3];
111 	u8	temp_type[3];
112 	u8	temp_status;
113 	u8	temp_beep;
114 	u8	temp_diode_open;
115 };
116 
117 /* Sysfs in*/
118 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
119 	char *buf);
120 static ssize_t show_in_max(struct device *dev, struct device_attribute
121 	*devattr, char *buf);
122 static ssize_t store_in_max(struct device *dev, struct device_attribute
123 	*devattr, const char *buf, size_t count);
124 static ssize_t show_in_beep(struct device *dev, struct device_attribute
125 	*devattr, char *buf);
126 static ssize_t store_in_beep(struct device *dev, struct device_attribute
127 	*devattr, const char *buf, size_t count);
128 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
129 	*devattr, char *buf);
130 /* Sysfs Fan */
131 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
132 	char *buf);
133 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
134 	*devattr, char *buf);
135 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
136 	*devattr, const char *buf, size_t count);
137 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
138 	*devattr, char *buf);
139 /* Sysfs Temp */
140 static ssize_t show_temp(struct device *dev, struct device_attribute
141 	*devattr, char *buf);
142 static ssize_t show_temp_max(struct device *dev, struct device_attribute
143 	*devattr, char *buf);
144 static ssize_t store_temp_max(struct device *dev, struct device_attribute
145 	*devattr, const char *buf, size_t count);
146 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
147 	*devattr, char *buf);
148 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
149 	*devattr, const char *buf, size_t count);
150 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
151 	*devattr, char *buf);
152 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
153 	*devattr, const char *buf, size_t count);
154 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
155 	*devattr, char *buf);
156 static ssize_t show_temp_type(struct device *dev, struct device_attribute
157 	*devattr, char *buf);
158 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
159 	*devattr, char *buf);
160 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
161 	*devattr, const char *buf, size_t count);
162 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
163 	*devattr, char *buf);
164 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
165 	*devattr, char *buf);
166 /* Sysfs misc */
167 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
168 	char *buf);
169 
170 static int __devinit f71882fg_probe(struct platform_device * pdev);
171 static int __devexit f71882fg_remove(struct platform_device *pdev);
172 static int __init f71882fg_init(void);
173 static int __init f71882fg_find(int sioaddr, unsigned short *address);
174 static int __init f71882fg_device_add(unsigned short address);
175 static void __exit f71882fg_exit(void);
176 
177 static struct platform_driver f71882fg_driver = {
178 	.driver = {
179 		.owner	= THIS_MODULE,
180 		.name	= DRVNAME,
181 	},
182 	.probe		= f71882fg_probe,
183 	.remove		= __devexit_p(f71882fg_remove),
184 };
185 
186 static struct device_attribute f71882fg_dev_attr[] =
187 {
188 	__ATTR( name, S_IRUGO, show_name, NULL ),
189 };
190 
191 static struct sensor_device_attribute f71882fg_in_temp_attr[] =
192 {
193 	SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
194 	SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
195 	SENSOR_ATTR(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 1),
196 	SENSOR_ATTR(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, 1),
197 	SENSOR_ATTR(in1_alarm, S_IRUGO, show_in_alarm, NULL, 1),
198 	SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
199 	SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
200 	SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
201 	SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
202 	SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
203 	SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
204 	SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
205 	SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0),
206 	SENSOR_ATTR(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
207 		store_temp_max, 0),
208 	SENSOR_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
209 		store_temp_max_hyst, 0),
210 	SENSOR_ATTR(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
211 		store_temp_crit, 0),
212 	SENSOR_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 0),
213 	SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0),
214 	SENSOR_ATTR(temp1_beep, S_IRUGO|S_IWUSR, show_temp_beep,
215 		store_temp_beep, 0),
216 	SENSOR_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0),
217 	SENSOR_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0),
218 	SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1),
219 	SENSOR_ATTR(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
220 		store_temp_max, 1),
221 	SENSOR_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
222 		store_temp_max_hyst, 1),
223 	SENSOR_ATTR(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
224 		store_temp_crit, 1),
225 	SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1),
226 	SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1),
227 	SENSOR_ATTR(temp2_beep, S_IRUGO|S_IWUSR, show_temp_beep,
228 		store_temp_beep, 1),
229 	SENSOR_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1),
230 	SENSOR_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1),
231 	SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2),
232 	SENSOR_ATTR(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
233 		store_temp_max, 2),
234 	SENSOR_ATTR(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
235 		store_temp_max_hyst, 2),
236 	SENSOR_ATTR(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
237 		store_temp_crit, 2),
238 	SENSOR_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 2),
239 	SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2),
240 	SENSOR_ATTR(temp3_beep, S_IRUGO|S_IWUSR, show_temp_beep,
241 		store_temp_beep, 2),
242 	SENSOR_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2),
243 	SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2)
244 };
245 
246 static struct sensor_device_attribute f71882fg_fan_attr[] =
247 {
248 	SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
249 	SENSOR_ATTR(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
250 		store_fan_beep, 0),
251 	SENSOR_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0),
252 	SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
253 	SENSOR_ATTR(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
254 		store_fan_beep, 1),
255 	SENSOR_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1),
256 	SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
257 	SENSOR_ATTR(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
258 		store_fan_beep, 2),
259 	SENSOR_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2),
260 	SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
261 	SENSOR_ATTR(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
262 		store_fan_beep, 3),
263 	SENSOR_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3)
264 };
265 
266 
267 /* Super I/O functions */
268 static inline int superio_inb(int base, int reg)
269 {
270 	outb(reg, base);
271 	return inb(base + 1);
272 }
273 
274 static int superio_inw(int base, int reg)
275 {
276 	int val;
277 	outb(reg++, base);
278 	val = inb(base + 1) << 8;
279 	outb(reg, base);
280 	val |= inb(base + 1);
281 	return val;
282 }
283 
284 static inline void superio_enter(int base)
285 {
286 	/* according to the datasheet the key must be send twice! */
287 	outb( SIO_UNLOCK_KEY, base);
288 	outb( SIO_UNLOCK_KEY, base);
289 }
290 
291 static inline void superio_select( int base, int ld)
292 {
293 	outb(SIO_REG_LDSEL, base);
294 	outb(ld, base + 1);
295 }
296 
297 static inline void superio_exit(int base)
298 {
299 	outb(SIO_LOCK_KEY, base);
300 }
301 
302 static inline u16 fan_from_reg(u16 reg)
303 {
304 	return reg ? (1500000 / reg) : 0;
305 }
306 
307 static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
308 {
309 	u8 val;
310 
311 	outb(reg, data->addr + ADDR_REG_OFFSET);
312 	val = inb(data->addr + DATA_REG_OFFSET);
313 
314 	return val;
315 }
316 
317 static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
318 {
319 	u16 val;
320 
321 	outb(reg++, data->addr + ADDR_REG_OFFSET);
322 	val = inb(data->addr + DATA_REG_OFFSET) << 8;
323 	outb(reg, data->addr + ADDR_REG_OFFSET);
324 	val |= inb(data->addr + DATA_REG_OFFSET);
325 
326 	return val;
327 }
328 
329 static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
330 {
331 	outb(reg, data->addr + ADDR_REG_OFFSET);
332 	outb(val, data->addr + DATA_REG_OFFSET);
333 }
334 
335 static struct f71882fg_data *f71882fg_update_device(struct device * dev)
336 {
337 	struct f71882fg_data *data = dev_get_drvdata(dev);
338 	int nr, reg, reg2;
339 
340 	mutex_lock(&data->update_lock);
341 
342 	/* Update once every 60 seconds */
343 	if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
344 			!data->valid) {
345 		data->in1_max = f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
346 		data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
347 
348 		/* Get High & boundary temps*/
349 		for (nr = 0; nr < 3; nr++) {
350 			data->temp_ovt[nr] = f71882fg_read8(data,
351 						F71882FG_REG_TEMP_OVT(nr));
352 			data->temp_high[nr] = f71882fg_read8(data,
353 						F71882FG_REG_TEMP_HIGH(nr));
354 		}
355 
356 		/* Have to hardcode hyst*/
357 		data->temp_hyst[0] = f71882fg_read8(data,
358 						F71882FG_REG_TEMP_HYST1) >> 4;
359 		/* Hyst temps 2 & 3 stored in same register */
360 		reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST23);
361 		data->temp_hyst[1] = reg & 0x0F;
362 		data->temp_hyst[2] = reg >> 4;
363 
364 		/* Have to hardcode type, because temp1 is special */
365 		reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
366 		reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
367 		if ((reg2 & 0x03) == 0x01)
368 			data->temp_type[0] = 6 /* PECI */;
369 		else if ((reg2 & 0x03) == 0x02)
370 			data->temp_type[0] = 5 /* AMDSI */;
371 		else
372 			data->temp_type[0] = (reg & 0x02) ? 2 : 4;
373 
374 		data->temp_type[1] = (reg & 0x04) ? 2 : 4;
375 		data->temp_type[2] = (reg & 0x08) ? 2 : 4;
376 
377 		data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
378 
379 		data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
380 
381 		data->last_limits = jiffies;
382 	}
383 
384 	/* Update every second */
385 	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
386 		data->temp_status = f71882fg_read8(data,
387 						F71882FG_REG_TEMP_STATUS);
388 		data->temp_diode_open = f71882fg_read8(data,
389 						F71882FG_REG_TEMP_DIODE_OPEN);
390 		for (nr = 0; nr < 3; nr++)
391 			data->temp[nr] = f71882fg_read8(data,
392 						F71882FG_REG_TEMP(nr));
393 
394 		data->fan_status = f71882fg_read8(data,
395 						F71882FG_REG_FAN_STATUS);
396 		for (nr = 0; nr < 4; nr++)
397 			data->fan[nr] = f71882fg_read16(data,
398 						F71882FG_REG_FAN(nr));
399 
400 		data->in_status = f71882fg_read8(data,
401 						F71882FG_REG_IN_STATUS);
402 		for (nr = 0; nr < 9; nr++)
403 			data->in[nr] = f71882fg_read8(data,
404 						F71882FG_REG_IN(nr));
405 
406 		data->last_updated = jiffies;
407 		data->valid = 1;
408 	}
409 
410 	mutex_unlock(&data->update_lock);
411 
412 	return data;
413 }
414 
415 /* Sysfs Interface */
416 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
417 	char *buf)
418 {
419 	struct f71882fg_data *data = f71882fg_update_device(dev);
420 	int nr = to_sensor_dev_attr(devattr)->index;
421 	int speed = fan_from_reg(data->fan[nr]);
422 
423 	if (speed == FAN_MIN_DETECT)
424 		speed = 0;
425 
426 	return sprintf(buf, "%d\n", speed);
427 }
428 
429 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
430 	*devattr, char *buf)
431 {
432 	struct f71882fg_data *data = f71882fg_update_device(dev);
433 	int nr = to_sensor_dev_attr(devattr)->index;
434 
435 	if (data->fan_beep & (1 << nr))
436 		return sprintf(buf, "1\n");
437 	else
438 		return sprintf(buf, "0\n");
439 }
440 
441 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
442 	*devattr, const char *buf, size_t count)
443 {
444 	struct f71882fg_data *data = dev_get_drvdata(dev);
445 	int nr = to_sensor_dev_attr(devattr)->index;
446 	int val = simple_strtoul(buf, NULL, 10);
447 
448 	mutex_lock(&data->update_lock);
449 	if (val)
450 		data->fan_beep |= 1 << nr;
451 	else
452 		data->fan_beep &= ~(1 << nr);
453 
454 	f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
455 	mutex_unlock(&data->update_lock);
456 
457 	return count;
458 }
459 
460 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
461 	*devattr, char *buf)
462 {
463 	struct f71882fg_data *data = f71882fg_update_device(dev);
464 	int nr = to_sensor_dev_attr(devattr)->index;
465 
466 	if (data->fan_status & (1 << nr))
467 		return sprintf(buf, "1\n");
468 	else
469 		return sprintf(buf, "0\n");
470 }
471 
472 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
473 	char *buf)
474 {
475 	struct f71882fg_data *data = f71882fg_update_device(dev);
476 	int nr = to_sensor_dev_attr(devattr)->index;
477 
478 	return sprintf(buf, "%d\n", data->in[nr] * 8);
479 }
480 
481 static ssize_t show_in_max(struct device *dev, struct device_attribute
482 	*devattr, char *buf)
483 {
484 	struct f71882fg_data *data = f71882fg_update_device(dev);
485 
486 	return sprintf(buf, "%d\n", data->in1_max * 8);
487 }
488 
489 static ssize_t store_in_max(struct device *dev, struct device_attribute
490 	*devattr, const char *buf, size_t count)
491 {
492 	struct f71882fg_data *data = dev_get_drvdata(dev);
493 	int val = simple_strtoul(buf, NULL, 10) / 8;
494 
495 	if (val > 255)
496 		val = 255;
497 
498 	mutex_lock(&data->update_lock);
499 	f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
500 	data->in1_max = val;
501 	mutex_unlock(&data->update_lock);
502 
503 	return count;
504 }
505 
506 static ssize_t show_in_beep(struct device *dev, struct device_attribute
507 	*devattr, char *buf)
508 {
509 	struct f71882fg_data *data = f71882fg_update_device(dev);
510 	int nr = to_sensor_dev_attr(devattr)->index;
511 
512 	if (data->in_beep & (1 << nr))
513 		return sprintf(buf, "1\n");
514 	else
515 		return sprintf(buf, "0\n");
516 }
517 
518 static ssize_t store_in_beep(struct device *dev, struct device_attribute
519 	*devattr, const char *buf, size_t count)
520 {
521 	struct f71882fg_data *data = dev_get_drvdata(dev);
522 	int nr = to_sensor_dev_attr(devattr)->index;
523 	int val = simple_strtoul(buf, NULL, 10);
524 
525 	mutex_lock(&data->update_lock);
526 	if (val)
527 		data->in_beep |= 1 << nr;
528 	else
529 		data->in_beep &= ~(1 << nr);
530 
531 	f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
532 	mutex_unlock(&data->update_lock);
533 
534 	return count;
535 }
536 
537 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
538 	*devattr, char *buf)
539 {
540 	struct f71882fg_data *data = f71882fg_update_device(dev);
541 	int nr = to_sensor_dev_attr(devattr)->index;
542 
543 	if (data->in_status & (1 << nr))
544 		return sprintf(buf, "1\n");
545 	else
546 		return sprintf(buf, "0\n");
547 }
548 
549 static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
550 	char *buf)
551 {
552 	struct f71882fg_data *data = f71882fg_update_device(dev);
553 	int nr = to_sensor_dev_attr(devattr)->index;
554 
555 	return sprintf(buf, "%d\n", data->temp[nr] * 1000);
556 }
557 
558 static ssize_t show_temp_max(struct device *dev, struct device_attribute
559 	*devattr, char *buf)
560 {
561 	struct f71882fg_data *data = f71882fg_update_device(dev);
562 	int nr = to_sensor_dev_attr(devattr)->index;
563 
564 	return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
565 }
566 
567 static ssize_t store_temp_max(struct device *dev, struct device_attribute
568 	*devattr, const char *buf, size_t count)
569 {
570 	struct f71882fg_data *data = dev_get_drvdata(dev);
571 	int nr = to_sensor_dev_attr(devattr)->index;
572 	int val = simple_strtoul(buf, NULL, 10) / 1000;
573 
574 	if (val > 255)
575 		val = 255;
576 
577 	mutex_lock(&data->update_lock);
578 	f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
579 	data->temp_high[nr] = val;
580 	mutex_unlock(&data->update_lock);
581 
582 	return count;
583 }
584 
585 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
586 	*devattr, char *buf)
587 {
588 	struct f71882fg_data *data = f71882fg_update_device(dev);
589 	int nr = to_sensor_dev_attr(devattr)->index;
590 
591 	return sprintf(buf, "%d\n",
592 		(data->temp_high[nr] - data->temp_hyst[nr]) * 1000);
593 }
594 
595 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
596 	*devattr, const char *buf, size_t count)
597 {
598 	struct f71882fg_data *data = dev_get_drvdata(dev);
599 	int nr = to_sensor_dev_attr(devattr)->index;
600 	int val = simple_strtoul(buf, NULL, 10) / 1000;
601 	ssize_t ret = count;
602 
603 	mutex_lock(&data->update_lock);
604 
605 	/* convert abs to relative and check */
606 	val = data->temp_high[nr] - val;
607 	if (val < 0 || val > 15) {
608 		ret = -EINVAL;
609 		goto store_temp_max_hyst_exit;
610 	}
611 
612 	data->temp_hyst[nr] = val;
613 
614 	/* convert value to register contents */
615 	switch (nr) {
616 		case 0:
617 			val = val << 4;
618 			break;
619 		case 1:
620 			val = val | (data->temp_hyst[2] << 4);
621 			break;
622 		case 2:
623 			val = data->temp_hyst[1] | (val << 4);
624 			break;
625 	}
626 
627 	f71882fg_write8(data, nr ? F71882FG_REG_TEMP_HYST23 :
628 		F71882FG_REG_TEMP_HYST1, val);
629 
630 store_temp_max_hyst_exit:
631 	mutex_unlock(&data->update_lock);
632 	return ret;
633 }
634 
635 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
636 	*devattr, char *buf)
637 {
638 	struct f71882fg_data *data = f71882fg_update_device(dev);
639 	int nr = to_sensor_dev_attr(devattr)->index;
640 
641 	return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
642 }
643 
644 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
645 	*devattr, const char *buf, size_t count)
646 {
647 	struct f71882fg_data *data = dev_get_drvdata(dev);
648 	int nr = to_sensor_dev_attr(devattr)->index;
649 	int val = simple_strtoul(buf, NULL, 10) / 1000;
650 
651 	if (val > 255)
652 		val = 255;
653 
654 	mutex_lock(&data->update_lock);
655 	f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
656 	data->temp_ovt[nr] = val;
657 	mutex_unlock(&data->update_lock);
658 
659 	return count;
660 }
661 
662 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
663 	*devattr, char *buf)
664 {
665 	struct f71882fg_data *data = f71882fg_update_device(dev);
666 	int nr = to_sensor_dev_attr(devattr)->index;
667 
668 	return sprintf(buf, "%d\n",
669 		(data->temp_ovt[nr] - data->temp_hyst[nr]) * 1000);
670 }
671 
672 static ssize_t show_temp_type(struct device *dev, struct device_attribute
673 	*devattr, char *buf)
674 {
675 	struct f71882fg_data *data = f71882fg_update_device(dev);
676 	int nr = to_sensor_dev_attr(devattr)->index;
677 
678 	return sprintf(buf, "%d\n", data->temp_type[nr]);
679 }
680 
681 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
682 	*devattr, char *buf)
683 {
684 	struct f71882fg_data *data = f71882fg_update_device(dev);
685 	int nr = to_sensor_dev_attr(devattr)->index;
686 
687 	if (data->temp_beep & (1 << (nr + 1)))
688 		return sprintf(buf, "1\n");
689 	else
690 		return sprintf(buf, "0\n");
691 }
692 
693 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
694 	*devattr, const char *buf, size_t count)
695 {
696 	struct f71882fg_data *data = dev_get_drvdata(dev);
697 	int nr = to_sensor_dev_attr(devattr)->index;
698 	int val = simple_strtoul(buf, NULL, 10);
699 
700 	mutex_lock(&data->update_lock);
701 	if (val)
702 		data->temp_beep |= 1 << (nr + 1);
703 	else
704 		data->temp_beep &= ~(1 << (nr + 1));
705 
706 	f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
707 	mutex_unlock(&data->update_lock);
708 
709 	return count;
710 }
711 
712 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
713 	*devattr, char *buf)
714 {
715 	struct f71882fg_data *data = f71882fg_update_device(dev);
716 	int nr = to_sensor_dev_attr(devattr)->index;
717 
718 	if (data->temp_status & (1 << (nr + 1)))
719 		return sprintf(buf, "1\n");
720 	else
721 		return sprintf(buf, "0\n");
722 }
723 
724 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
725 	*devattr, char *buf)
726 {
727 	struct f71882fg_data *data = f71882fg_update_device(dev);
728 	int nr = to_sensor_dev_attr(devattr)->index;
729 
730 	if (data->temp_diode_open & (1 << (nr + 1)))
731 		return sprintf(buf, "1\n");
732 	else
733 		return sprintf(buf, "0\n");
734 }
735 
736 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
737 	char *buf)
738 {
739 	return sprintf(buf, DRVNAME "\n");
740 }
741 
742 
743 static int __devinit f71882fg_probe(struct platform_device * pdev)
744 {
745 	struct f71882fg_data *data;
746 	int err, i;
747 	u8 start_reg;
748 
749 	if (!(data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL)))
750 		return -ENOMEM;
751 
752 	data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
753 	mutex_init(&data->update_lock);
754 	platform_set_drvdata(pdev, data);
755 
756 	/* Register sysfs interface files */
757 	for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) {
758 		err = device_create_file(&pdev->dev, &f71882fg_dev_attr[i]);
759 		if (err)
760 			goto exit_unregister_sysfs;
761 	}
762 
763 	start_reg = f71882fg_read8(data, F71882FG_REG_START);
764 	if (start_reg & 0x01) {
765 		for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) {
766 			err = device_create_file(&pdev->dev,
767 					&f71882fg_in_temp_attr[i].dev_attr);
768 			if (err)
769 				goto exit_unregister_sysfs;
770 		}
771 	}
772 
773 	if (start_reg & 0x02) {
774 		for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) {
775 			err = device_create_file(&pdev->dev,
776 					&f71882fg_fan_attr[i].dev_attr);
777 			if (err)
778 				goto exit_unregister_sysfs;
779 		}
780 	}
781 
782 	data->hwmon_dev = hwmon_device_register(&pdev->dev);
783 	if (IS_ERR(data->hwmon_dev)) {
784 		err = PTR_ERR(data->hwmon_dev);
785 		goto exit_unregister_sysfs;
786 	}
787 
788 	return 0;
789 
790 exit_unregister_sysfs:
791 	for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++)
792 		device_remove_file(&pdev->dev, &f71882fg_dev_attr[i]);
793 
794 	for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
795 		device_remove_file(&pdev->dev,
796 					&f71882fg_in_temp_attr[i].dev_attr);
797 
798 	for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
799 		device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
800 
801 	kfree(data);
802 
803 	return err;
804 }
805 
806 static int __devexit f71882fg_remove(struct platform_device *pdev)
807 {
808 	int i;
809 	struct f71882fg_data *data = platform_get_drvdata(pdev);
810 
811 	platform_set_drvdata(pdev, NULL);
812 	hwmon_device_unregister(data->hwmon_dev);
813 
814 	for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++)
815 		device_remove_file(&pdev->dev, &f71882fg_dev_attr[i]);
816 
817 	for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
818 		device_remove_file(&pdev->dev,
819 					&f71882fg_in_temp_attr[i].dev_attr);
820 
821 	for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
822 		device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
823 
824 	kfree(data);
825 
826 	return 0;
827 }
828 
829 static int __init f71882fg_find(int sioaddr, unsigned short *address)
830 {
831 	int err = -ENODEV;
832 	u16 devid;
833 	u8 start_reg;
834 	struct f71882fg_data data;
835 
836 	superio_enter(sioaddr);
837 
838 	devid = superio_inw(sioaddr, SIO_REG_MANID);
839 	if (devid != SIO_FINTEK_ID) {
840 		printk(KERN_INFO DRVNAME ": Not a Fintek device\n");
841 		goto exit;
842 	}
843 
844 	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
845 	if (devid != SIO_F71882_ID) {
846 		printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
847 		goto exit;
848 	}
849 
850 	superio_select(sioaddr, SIO_F71882FG_LD_HWM);
851 	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
852 		printk(KERN_WARNING DRVNAME ": Device not activated\n");
853 		goto exit;
854 	}
855 
856 	*address = superio_inw(sioaddr, SIO_REG_ADDR);
857 	if (*address == 0)
858 	{
859 		printk(KERN_WARNING DRVNAME ": Base address not set\n");
860 		goto exit;
861 	}
862 	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
863 
864 	data.addr = *address;
865 	start_reg = f71882fg_read8(&data, F71882FG_REG_START);
866 	if (!(start_reg & 0x03)) {
867 		printk(KERN_WARNING DRVNAME
868 			": Hardware monitoring not activated\n");
869 		goto exit;
870 	}
871 
872 	err = 0;
873 	printk(KERN_INFO DRVNAME ": Found F71882FG chip at %#x, revision %d\n",
874 		(unsigned int)*address,
875 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
876 exit:
877 	superio_exit(sioaddr);
878 	return err;
879 }
880 
881 static int __init f71882fg_device_add(unsigned short address)
882 {
883 	struct resource res = {
884 		.start	= address,
885 		.end	= address + REGION_LENGTH - 1,
886 		.flags	= IORESOURCE_IO,
887 	};
888 	int err;
889 
890 	f71882fg_pdev = platform_device_alloc(DRVNAME, address);
891 	if (!f71882fg_pdev)
892 		return -ENOMEM;
893 
894 	res.name = f71882fg_pdev->name;
895 	err = platform_device_add_resources(f71882fg_pdev, &res, 1);
896 	if (err) {
897 		printk(KERN_ERR DRVNAME ": Device resource addition failed\n");
898 		goto exit_device_put;
899 	}
900 
901 	err = platform_device_add(f71882fg_pdev);
902 	if (err) {
903 		printk(KERN_ERR DRVNAME ": Device addition failed\n");
904 		goto exit_device_put;
905 	}
906 
907 	return 0;
908 
909 exit_device_put:
910 	platform_device_put(f71882fg_pdev);
911 
912 	return err;
913 }
914 
915 static int __init f71882fg_init(void)
916 {
917 	int err = -ENODEV;
918 	unsigned short address;
919 
920 	if (f71882fg_find(0x2e, &address) && f71882fg_find(0x4e, &address))
921 		goto exit;
922 
923 	if ((err = platform_driver_register(&f71882fg_driver)))
924 		goto exit;
925 
926 	if ((err = f71882fg_device_add(address)))
927 		goto exit_driver;
928 
929 	return 0;
930 
931 exit_driver:
932 	platform_driver_unregister(&f71882fg_driver);
933 exit:
934 	return err;
935 }
936 
937 static void __exit f71882fg_exit(void)
938 {
939 	platform_device_unregister(f71882fg_pdev);
940 	platform_driver_unregister(&f71882fg_driver);
941 }
942 
943 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
944 MODULE_AUTHOR("Hans Edgington (hans@edgington.nl)");
945 MODULE_LICENSE("GPL");
946 
947 module_init(f71882fg_init);
948 module_exit(f71882fg_exit);
949