• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/hwmon/
1/*
2 *  pc87360.c - Part of lm_sensors, Linux kernel modules
3 *              for hardware monitoring
4 *  Copyright (C) 2004, 2007 Jean Delvare <khali@linux-fr.org>
5 *
6 *  Copied from smsc47m1.c:
7 *  Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
8 *
9 *  This program is free software; you can redistribute it and/or modify
10 *  it under the terms of the GNU General Public License as published by
11 *  the Free Software Foundation; either version 2 of the License, or
12 *  (at your option) any later version.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *  Supports the following chips:
24 *
25 *  Chip        #vin    #fan    #pwm    #temp   devid
26 *  PC87360     -       2       2       -       0xE1
27 *  PC87363     -       2       2       -       0xE8
28 *  PC87364     -       3       3       -       0xE4
29 *  PC87365     11      3       3       2       0xE5
30 *  PC87366     11      3       3       3-4     0xE9
31 *
32 *  This driver assumes that no more than one chip is present, and one of
33 *  the standard Super-I/O addresses is used (0x2E/0x2F or 0x4E/0x4F).
34 */
35
36#include <linux/module.h>
37#include <linux/init.h>
38#include <linux/slab.h>
39#include <linux/jiffies.h>
40#include <linux/platform_device.h>
41#include <linux/hwmon.h>
42#include <linux/hwmon-sysfs.h>
43#include <linux/hwmon-vid.h>
44#include <linux/err.h>
45#include <linux/mutex.h>
46#include <linux/acpi.h>
47#include <linux/io.h>
48
49static u8 devid;
50static struct platform_device *pdev;
51static unsigned short extra_isa[3];
52static u8 confreg[4];
53
54static int init = 1;
55module_param(init, int, 0);
56MODULE_PARM_DESC(init,
57 "Chip initialization level:\n"
58 " 0: None\n"
59 "*1: Forcibly enable internal voltage and temperature channels, except in9\n"
60 " 2: Forcibly enable all voltage and temperature channels, except in9\n"
61 " 3: Forcibly enable all voltage and temperature channels, including in9");
62
63static unsigned short force_id;
64module_param(force_id, ushort, 0);
65MODULE_PARM_DESC(force_id, "Override the detected device ID");
66
67/*
68 * Super-I/O registers and operations
69 */
70
71#define DEV	0x07	/* Register: Logical device select */
72#define DEVID	0x20	/* Register: Device ID */
73#define ACT	0x30	/* Register: Device activation */
74#define BASE	0x60	/* Register: Base address */
75
76#define FSCM	0x09	/* Logical device: fans */
77#define VLM	0x0d	/* Logical device: voltages */
78#define TMS	0x0e	/* Logical device: temperatures */
79#define LDNI_MAX 3
80static const u8 logdev[LDNI_MAX] = { FSCM, VLM, TMS };
81
82#define LD_FAN		0
83#define LD_IN		1
84#define LD_TEMP		2
85
86static inline void superio_outb(int sioaddr, int reg, int val)
87{
88	outb(reg, sioaddr);
89	outb(val, sioaddr+1);
90}
91
92static inline int superio_inb(int sioaddr, int reg)
93{
94	outb(reg, sioaddr);
95	return inb(sioaddr+1);
96}
97
98static inline void superio_exit(int sioaddr)
99{
100	outb(0x02, sioaddr);
101	outb(0x02, sioaddr+1);
102}
103
104/*
105 * Logical devices
106 */
107
108#define PC87360_EXTENT		0x10
109#define PC87365_REG_BANK	0x09
110#define NO_BANK			0xff
111
112/*
113 * Fan registers and conversions
114 */
115
116/* nr has to be 0 or 1 (PC87360/87363) or 2 (PC87364/87365/87366) */
117#define PC87360_REG_PRESCALE(nr)	(0x00 + 2 * (nr))
118#define PC87360_REG_PWM(nr)		(0x01 + 2 * (nr))
119#define PC87360_REG_FAN_MIN(nr)		(0x06 + 3 * (nr))
120#define PC87360_REG_FAN(nr)		(0x07 + 3 * (nr))
121#define PC87360_REG_FAN_STATUS(nr)	(0x08 + 3 * (nr))
122
123#define FAN_FROM_REG(val,div)		((val) == 0 ? 0: \
124					 480000 / ((val)*(div)))
125#define FAN_TO_REG(val,div)		((val) <= 100 ? 0 : \
126					 480000 / ((val)*(div)))
127#define FAN_DIV_FROM_REG(val)		(1 << ((val >> 5) & 0x03))
128#define FAN_STATUS_FROM_REG(val)	((val) & 0x07)
129
130#define FAN_CONFIG_MONITOR(val,nr)	(((val) >> (2 + nr * 3)) & 1)
131#define FAN_CONFIG_CONTROL(val,nr)	(((val) >> (3 + nr * 3)) & 1)
132#define FAN_CONFIG_INVERT(val,nr)	(((val) >> (4 + nr * 3)) & 1)
133
134#define PWM_FROM_REG(val,inv)		((inv) ? 255 - (val) : (val))
135static inline u8 PWM_TO_REG(int val, int inv)
136{
137	if (inv)
138		val = 255 - val;
139	if (val < 0)
140		return 0;
141	if (val > 255)
142		return 255;
143	return val;
144}
145
146/*
147 * Voltage registers and conversions
148 */
149
150#define PC87365_REG_IN_CONVRATE		0x07
151#define PC87365_REG_IN_CONFIG		0x08
152#define PC87365_REG_IN			0x0B
153#define PC87365_REG_IN_MIN		0x0D
154#define PC87365_REG_IN_MAX		0x0C
155#define PC87365_REG_IN_STATUS		0x0A
156#define PC87365_REG_IN_ALARMS1		0x00
157#define PC87365_REG_IN_ALARMS2		0x01
158#define PC87365_REG_VID			0x06
159
160#define IN_FROM_REG(val,ref)		(((val) * (ref) + 128) / 256)
161#define IN_TO_REG(val,ref)		((val) < 0 ? 0 : \
162					 (val)*256 >= (ref)*255 ? 255: \
163					 ((val) * 256 + (ref)/2) / (ref))
164
165/*
166 * Temperature registers and conversions
167 */
168
169#define PC87365_REG_TEMP_CONFIG		0x08
170#define PC87365_REG_TEMP		0x0B
171#define PC87365_REG_TEMP_MIN		0x0D
172#define PC87365_REG_TEMP_MAX		0x0C
173#define PC87365_REG_TEMP_CRIT		0x0E
174#define PC87365_REG_TEMP_STATUS		0x0A
175#define PC87365_REG_TEMP_ALARMS		0x00
176
177#define TEMP_FROM_REG(val)		((val) * 1000)
178#define TEMP_TO_REG(val)		((val) < -55000 ? -55 : \
179					 (val) > 127000 ? 127 : \
180					 (val) < 0 ? ((val) - 500) / 1000 : \
181					 ((val) + 500) / 1000)
182
183/*
184 * Device data
185 */
186
187struct pc87360_data {
188	const char *name;
189	struct device *hwmon_dev;
190	struct mutex lock;
191	struct mutex update_lock;
192	char valid;		/* !=0 if following fields are valid */
193	unsigned long last_updated;	/* In jiffies */
194
195	int address[3];
196
197	u8 fannr, innr, tempnr;
198
199	u8 fan[3];		/* Register value */
200	u8 fan_min[3];		/* Register value */
201	u8 fan_status[3];	/* Register value */
202	u8 pwm[3];		/* Register value */
203	u16 fan_conf;		/* Configuration register values, combined */
204
205	u16 in_vref;		/* 1 mV/bit */
206	u8 in[14];		/* Register value */
207	u8 in_min[14];		/* Register value */
208	u8 in_max[14];		/* Register value */
209	u8 in_crit[3];		/* Register value */
210	u8 in_status[14];	/* Register value */
211	u16 in_alarms;		/* Register values, combined, masked */
212	u8 vid_conf;		/* Configuration register value */
213	u8 vrm;
214	u8 vid;			/* Register value */
215
216	s8 temp[3];		/* Register value */
217	s8 temp_min[3];		/* Register value */
218	s8 temp_max[3];		/* Register value */
219	s8 temp_crit[3];	/* Register value */
220	u8 temp_status[3];	/* Register value */
221	u8 temp_alarms;		/* Register value, masked */
222};
223
224/*
225 * Functions declaration
226 */
227
228static int pc87360_probe(struct platform_device *pdev);
229static int __devexit pc87360_remove(struct platform_device *pdev);
230
231static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
232			      u8 reg);
233static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
234				u8 reg, u8 value);
235static void pc87360_init_device(struct platform_device *pdev,
236				int use_thermistors);
237static struct pc87360_data *pc87360_update_device(struct device *dev);
238
239/*
240 * Driver data
241 */
242
243static struct platform_driver pc87360_driver = {
244	.driver = {
245		.owner	= THIS_MODULE,
246		.name	= "pc87360",
247	},
248	.probe		= pc87360_probe,
249	.remove		= __devexit_p(pc87360_remove),
250};
251
252/*
253 * Sysfs stuff
254 */
255
256static ssize_t show_fan_input(struct device *dev, struct device_attribute *devattr, char *buf)
257{
258	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
259	struct pc87360_data *data = pc87360_update_device(dev);
260	return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan[attr->index],
261		       FAN_DIV_FROM_REG(data->fan_status[attr->index])));
262}
263static ssize_t show_fan_min(struct device *dev, struct device_attribute *devattr, char *buf)
264{
265	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
266	struct pc87360_data *data = pc87360_update_device(dev);
267	return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan_min[attr->index],
268		       FAN_DIV_FROM_REG(data->fan_status[attr->index])));
269}
270static ssize_t show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf)
271{
272	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
273	struct pc87360_data *data = pc87360_update_device(dev);
274	return sprintf(buf, "%u\n",
275		       FAN_DIV_FROM_REG(data->fan_status[attr->index]));
276}
277static ssize_t show_fan_status(struct device *dev, struct device_attribute *devattr, char *buf)
278{
279	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
280	struct pc87360_data *data = pc87360_update_device(dev);
281	return sprintf(buf, "%u\n",
282		       FAN_STATUS_FROM_REG(data->fan_status[attr->index]));
283}
284static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr, const char *buf,
285	size_t count)
286{
287	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
288	struct pc87360_data *data = dev_get_drvdata(dev);
289	long fan_min = simple_strtol(buf, NULL, 10);
290
291	mutex_lock(&data->update_lock);
292	fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[attr->index]));
293
294	/* If it wouldn't fit, change clock divisor */
295	while (fan_min > 255
296	    && (data->fan_status[attr->index] & 0x60) != 0x60) {
297		fan_min >>= 1;
298		data->fan[attr->index] >>= 1;
299		data->fan_status[attr->index] += 0x20;
300	}
301	data->fan_min[attr->index] = fan_min > 255 ? 255 : fan_min;
302	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_MIN(attr->index),
303			    data->fan_min[attr->index]);
304
305	/* Write new divider, preserve alarm bits */
306	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(attr->index),
307			    data->fan_status[attr->index] & 0xF9);
308	mutex_unlock(&data->update_lock);
309
310	return count;
311}
312
313static struct sensor_device_attribute fan_input[] = {
314	SENSOR_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0),
315	SENSOR_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1),
316	SENSOR_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2),
317};
318static struct sensor_device_attribute fan_status[] = {
319	SENSOR_ATTR(fan1_status, S_IRUGO, show_fan_status, NULL, 0),
320	SENSOR_ATTR(fan2_status, S_IRUGO, show_fan_status, NULL, 1),
321	SENSOR_ATTR(fan3_status, S_IRUGO, show_fan_status, NULL, 2),
322};
323static struct sensor_device_attribute fan_div[] = {
324	SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
325	SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
326	SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
327};
328static struct sensor_device_attribute fan_min[] = {
329	SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 0),
330	SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 1),
331	SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 2),
332};
333
334#define FAN_UNIT_ATTRS(X)	\
335	&fan_input[X].dev_attr.attr,	\
336	&fan_status[X].dev_attr.attr,	\
337	&fan_div[X].dev_attr.attr,	\
338	&fan_min[X].dev_attr.attr
339
340static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, char *buf)
341{
342	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
343	struct pc87360_data *data = pc87360_update_device(dev);
344	return sprintf(buf, "%u\n",
345		       PWM_FROM_REG(data->pwm[attr->index],
346				    FAN_CONFIG_INVERT(data->fan_conf,
347						      attr->index)));
348}
349static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, const char *buf,
350	size_t count)
351{
352	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
353	struct pc87360_data *data = dev_get_drvdata(dev);
354	long val = simple_strtol(buf, NULL, 10);
355
356	mutex_lock(&data->update_lock);
357	data->pwm[attr->index] = PWM_TO_REG(val,
358			      FAN_CONFIG_INVERT(data->fan_conf, attr->index));
359	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(attr->index),
360			    data->pwm[attr->index]);
361	mutex_unlock(&data->update_lock);
362	return count;
363}
364
365static struct sensor_device_attribute pwm[] = {
366	SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0),
367	SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1),
368	SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2),
369};
370
371static struct attribute * pc8736x_fan_attr_array[] = {
372	FAN_UNIT_ATTRS(0),
373	FAN_UNIT_ATTRS(1),
374	FAN_UNIT_ATTRS(2),
375	&pwm[0].dev_attr.attr,
376	&pwm[1].dev_attr.attr,
377	&pwm[2].dev_attr.attr,
378	NULL
379};
380static const struct attribute_group pc8736x_fan_group = {
381	.attrs = pc8736x_fan_attr_array,
382};
383
384static ssize_t show_in_input(struct device *dev, struct device_attribute *devattr, char *buf)
385{
386	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
387	struct pc87360_data *data = pc87360_update_device(dev);
388	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[attr->index],
389		       data->in_vref));
390}
391static ssize_t show_in_min(struct device *dev, struct device_attribute *devattr, char *buf)
392{
393	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
394	struct pc87360_data *data = pc87360_update_device(dev);
395	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[attr->index],
396		       data->in_vref));
397}
398static ssize_t show_in_max(struct device *dev, struct device_attribute *devattr, char *buf)
399{
400	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
401	struct pc87360_data *data = pc87360_update_device(dev);
402	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[attr->index],
403		       data->in_vref));
404}
405static ssize_t show_in_status(struct device *dev, struct device_attribute *devattr, char *buf)
406{
407	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
408	struct pc87360_data *data = pc87360_update_device(dev);
409	return sprintf(buf, "%u\n", data->in_status[attr->index]);
410}
411static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, const char *buf,
412	size_t count)
413{
414	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
415	struct pc87360_data *data = dev_get_drvdata(dev);
416	long val = simple_strtol(buf, NULL, 10);
417
418	mutex_lock(&data->update_lock);
419	data->in_min[attr->index] = IN_TO_REG(val, data->in_vref);
420	pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MIN,
421			    data->in_min[attr->index]);
422	mutex_unlock(&data->update_lock);
423	return count;
424}
425static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, const char *buf,
426	size_t count)
427{
428	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
429	struct pc87360_data *data = dev_get_drvdata(dev);
430	long val = simple_strtol(buf, NULL, 10);
431
432	mutex_lock(&data->update_lock);
433	data->in_max[attr->index] = IN_TO_REG(val,
434			       data->in_vref);
435	pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MAX,
436			    data->in_max[attr->index]);
437	mutex_unlock(&data->update_lock);
438	return count;
439}
440
441static struct sensor_device_attribute in_input[] = {
442	SENSOR_ATTR(in0_input, S_IRUGO, show_in_input, NULL, 0),
443	SENSOR_ATTR(in1_input, S_IRUGO, show_in_input, NULL, 1),
444	SENSOR_ATTR(in2_input, S_IRUGO, show_in_input, NULL, 2),
445	SENSOR_ATTR(in3_input, S_IRUGO, show_in_input, NULL, 3),
446	SENSOR_ATTR(in4_input, S_IRUGO, show_in_input, NULL, 4),
447	SENSOR_ATTR(in5_input, S_IRUGO, show_in_input, NULL, 5),
448	SENSOR_ATTR(in6_input, S_IRUGO, show_in_input, NULL, 6),
449	SENSOR_ATTR(in7_input, S_IRUGO, show_in_input, NULL, 7),
450	SENSOR_ATTR(in8_input, S_IRUGO, show_in_input, NULL, 8),
451	SENSOR_ATTR(in9_input, S_IRUGO, show_in_input, NULL, 9),
452	SENSOR_ATTR(in10_input, S_IRUGO, show_in_input, NULL, 10),
453};
454static struct sensor_device_attribute in_status[] = {
455	SENSOR_ATTR(in0_status, S_IRUGO, show_in_status, NULL, 0),
456	SENSOR_ATTR(in1_status, S_IRUGO, show_in_status, NULL, 1),
457	SENSOR_ATTR(in2_status, S_IRUGO, show_in_status, NULL, 2),
458	SENSOR_ATTR(in3_status, S_IRUGO, show_in_status, NULL, 3),
459	SENSOR_ATTR(in4_status, S_IRUGO, show_in_status, NULL, 4),
460	SENSOR_ATTR(in5_status, S_IRUGO, show_in_status, NULL, 5),
461	SENSOR_ATTR(in6_status, S_IRUGO, show_in_status, NULL, 6),
462	SENSOR_ATTR(in7_status, S_IRUGO, show_in_status, NULL, 7),
463	SENSOR_ATTR(in8_status, S_IRUGO, show_in_status, NULL, 8),
464	SENSOR_ATTR(in9_status, S_IRUGO, show_in_status, NULL, 9),
465	SENSOR_ATTR(in10_status, S_IRUGO, show_in_status, NULL, 10),
466};
467static struct sensor_device_attribute in_min[] = {
468	SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 0),
469	SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 1),
470	SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 2),
471	SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 3),
472	SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 4),
473	SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 5),
474	SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 6),
475	SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 7),
476	SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 8),
477	SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 9),
478	SENSOR_ATTR(in10_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 10),
479};
480static struct sensor_device_attribute in_max[] = {
481	SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 0),
482	SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 1),
483	SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 2),
484	SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 3),
485	SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 4),
486	SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 5),
487	SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 6),
488	SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 7),
489	SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 8),
490	SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 9),
491	SENSOR_ATTR(in10_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 10),
492};
493
494/* (temp & vin) channel status register alarm bits (pdf sec.11.5.12) */
495#define CHAN_ALM_MIN	0x02	/* min limit crossed */
496#define CHAN_ALM_MAX	0x04	/* max limit exceeded */
497#define TEMP_ALM_CRIT	0x08	/* temp crit exceeded (temp only) */
498
499/* show_in_min/max_alarm() reads data from the per-channel status
500   register (sec 11.5.12), not the vin event status registers (sec
501   11.5.2) that (legacy) show_in_alarm() resds (via data->in_alarms) */
502
503static ssize_t show_in_min_alarm(struct device *dev,
504			struct device_attribute *devattr, char *buf)
505{
506	struct pc87360_data *data = pc87360_update_device(dev);
507	unsigned nr = to_sensor_dev_attr(devattr)->index;
508
509	return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MIN));
510}
511static ssize_t show_in_max_alarm(struct device *dev,
512			struct device_attribute *devattr, char *buf)
513{
514	struct pc87360_data *data = pc87360_update_device(dev);
515	unsigned nr = to_sensor_dev_attr(devattr)->index;
516
517	return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MAX));
518}
519
520static struct sensor_device_attribute in_min_alarm[] = {
521	SENSOR_ATTR(in0_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 0),
522	SENSOR_ATTR(in1_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 1),
523	SENSOR_ATTR(in2_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 2),
524	SENSOR_ATTR(in3_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 3),
525	SENSOR_ATTR(in4_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 4),
526	SENSOR_ATTR(in5_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 5),
527	SENSOR_ATTR(in6_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 6),
528	SENSOR_ATTR(in7_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 7),
529	SENSOR_ATTR(in8_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 8),
530	SENSOR_ATTR(in9_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 9),
531	SENSOR_ATTR(in10_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 10),
532};
533static struct sensor_device_attribute in_max_alarm[] = {
534	SENSOR_ATTR(in0_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 0),
535	SENSOR_ATTR(in1_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 1),
536	SENSOR_ATTR(in2_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 2),
537	SENSOR_ATTR(in3_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 3),
538	SENSOR_ATTR(in4_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 4),
539	SENSOR_ATTR(in5_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 5),
540	SENSOR_ATTR(in6_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 6),
541	SENSOR_ATTR(in7_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 7),
542	SENSOR_ATTR(in8_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 8),
543	SENSOR_ATTR(in9_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 9),
544	SENSOR_ATTR(in10_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 10),
545};
546
547#define VIN_UNIT_ATTRS(X) \
548	&in_input[X].dev_attr.attr,	\
549	&in_status[X].dev_attr.attr,	\
550	&in_min[X].dev_attr.attr,	\
551	&in_max[X].dev_attr.attr,	\
552	&in_min_alarm[X].dev_attr.attr,	\
553	&in_max_alarm[X].dev_attr.attr
554
555static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
556{
557	struct pc87360_data *data = pc87360_update_device(dev);
558	return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
559}
560static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
561
562static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
563{
564	struct pc87360_data *data = dev_get_drvdata(dev);
565	return sprintf(buf, "%u\n", data->vrm);
566}
567static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
568{
569	struct pc87360_data *data = dev_get_drvdata(dev);
570	data->vrm = simple_strtoul(buf, NULL, 10);
571	return count;
572}
573static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
574
575static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, char *buf)
576{
577	struct pc87360_data *data = pc87360_update_device(dev);
578	return sprintf(buf, "%u\n", data->in_alarms);
579}
580static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL);
581
582static struct attribute *pc8736x_vin_attr_array[] = {
583	VIN_UNIT_ATTRS(0),
584	VIN_UNIT_ATTRS(1),
585	VIN_UNIT_ATTRS(2),
586	VIN_UNIT_ATTRS(3),
587	VIN_UNIT_ATTRS(4),
588	VIN_UNIT_ATTRS(5),
589	VIN_UNIT_ATTRS(6),
590	VIN_UNIT_ATTRS(7),
591	VIN_UNIT_ATTRS(8),
592	VIN_UNIT_ATTRS(9),
593	VIN_UNIT_ATTRS(10),
594	&dev_attr_cpu0_vid.attr,
595	&dev_attr_vrm.attr,
596	&dev_attr_alarms_in.attr,
597	NULL
598};
599static const struct attribute_group pc8736x_vin_group = {
600	.attrs = pc8736x_vin_attr_array,
601};
602
603static ssize_t show_therm_input(struct device *dev, struct device_attribute *devattr, char *buf)
604{
605	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
606	struct pc87360_data *data = pc87360_update_device(dev);
607	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[attr->index],
608		       data->in_vref));
609}
610static ssize_t show_therm_min(struct device *dev, struct device_attribute *devattr, char *buf)
611{
612	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
613	struct pc87360_data *data = pc87360_update_device(dev);
614	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[attr->index],
615		       data->in_vref));
616}
617static ssize_t show_therm_max(struct device *dev, struct device_attribute *devattr, char *buf)
618{
619	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
620	struct pc87360_data *data = pc87360_update_device(dev);
621	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[attr->index],
622		       data->in_vref));
623}
624static ssize_t show_therm_crit(struct device *dev, struct device_attribute *devattr, char *buf)
625{
626	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
627	struct pc87360_data *data = pc87360_update_device(dev);
628	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_crit[attr->index-11],
629		       data->in_vref));
630}
631static ssize_t show_therm_status(struct device *dev, struct device_attribute *devattr, char *buf)
632{
633	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
634	struct pc87360_data *data = pc87360_update_device(dev);
635	return sprintf(buf, "%u\n", data->in_status[attr->index]);
636}
637static ssize_t set_therm_min(struct device *dev, struct device_attribute *devattr, const char *buf,
638	size_t count)
639{
640	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
641	struct pc87360_data *data = dev_get_drvdata(dev);
642	long val = simple_strtol(buf, NULL, 10);
643
644	mutex_lock(&data->update_lock);
645	data->in_min[attr->index] = IN_TO_REG(val, data->in_vref);
646	pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MIN,
647			    data->in_min[attr->index]);
648	mutex_unlock(&data->update_lock);
649	return count;
650}
651static ssize_t set_therm_max(struct device *dev, struct device_attribute *devattr, const char *buf,
652	size_t count)
653{
654	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
655	struct pc87360_data *data = dev_get_drvdata(dev);
656	long val = simple_strtol(buf, NULL, 10);
657
658	mutex_lock(&data->update_lock);
659	data->in_max[attr->index] = IN_TO_REG(val, data->in_vref);
660	pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MAX,
661			    data->in_max[attr->index]);
662	mutex_unlock(&data->update_lock);
663	return count;
664}
665static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devattr, const char *buf,
666	size_t count)
667{
668	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
669	struct pc87360_data *data = dev_get_drvdata(dev);
670	long val = simple_strtol(buf, NULL, 10);
671
672	mutex_lock(&data->update_lock);
673	data->in_crit[attr->index-11] = IN_TO_REG(val, data->in_vref);
674	pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_CRIT,
675			    data->in_crit[attr->index-11]);
676	mutex_unlock(&data->update_lock);
677	return count;
678}
679
680/* the +11 term below reflects the fact that VLM units 11,12,13 are
681   used in the chip to measure voltage across the thermistors
682*/
683static struct sensor_device_attribute therm_input[] = {
684	SENSOR_ATTR(temp4_input, S_IRUGO, show_therm_input, NULL, 0+11),
685	SENSOR_ATTR(temp5_input, S_IRUGO, show_therm_input, NULL, 1+11),
686	SENSOR_ATTR(temp6_input, S_IRUGO, show_therm_input, NULL, 2+11),
687};
688static struct sensor_device_attribute therm_status[] = {
689	SENSOR_ATTR(temp4_status, S_IRUGO, show_therm_status, NULL, 0+11),
690	SENSOR_ATTR(temp5_status, S_IRUGO, show_therm_status, NULL, 1+11),
691	SENSOR_ATTR(temp6_status, S_IRUGO, show_therm_status, NULL, 2+11),
692};
693static struct sensor_device_attribute therm_min[] = {
694	SENSOR_ATTR(temp4_min, S_IRUGO | S_IWUSR,
695		    show_therm_min, set_therm_min, 0+11),
696	SENSOR_ATTR(temp5_min, S_IRUGO | S_IWUSR,
697		    show_therm_min, set_therm_min, 1+11),
698	SENSOR_ATTR(temp6_min, S_IRUGO | S_IWUSR,
699		    show_therm_min, set_therm_min, 2+11),
700};
701static struct sensor_device_attribute therm_max[] = {
702	SENSOR_ATTR(temp4_max, S_IRUGO | S_IWUSR,
703		    show_therm_max, set_therm_max, 0+11),
704	SENSOR_ATTR(temp5_max, S_IRUGO | S_IWUSR,
705		    show_therm_max, set_therm_max, 1+11),
706	SENSOR_ATTR(temp6_max, S_IRUGO | S_IWUSR,
707		    show_therm_max, set_therm_max, 2+11),
708};
709static struct sensor_device_attribute therm_crit[] = {
710	SENSOR_ATTR(temp4_crit, S_IRUGO | S_IWUSR,
711		    show_therm_crit, set_therm_crit, 0+11),
712	SENSOR_ATTR(temp5_crit, S_IRUGO | S_IWUSR,
713		    show_therm_crit, set_therm_crit, 1+11),
714	SENSOR_ATTR(temp6_crit, S_IRUGO | S_IWUSR,
715		    show_therm_crit, set_therm_crit, 2+11),
716};
717
718/* show_therm_min/max_alarm() reads data from the per-channel voltage
719   status register (sec 11.5.12) */
720
721static ssize_t show_therm_min_alarm(struct device *dev,
722				struct device_attribute *devattr, char *buf)
723{
724	struct pc87360_data *data = pc87360_update_device(dev);
725	unsigned nr = to_sensor_dev_attr(devattr)->index;
726
727	return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MIN));
728}
729static ssize_t show_therm_max_alarm(struct device *dev,
730				struct device_attribute *devattr, char *buf)
731{
732	struct pc87360_data *data = pc87360_update_device(dev);
733	unsigned nr = to_sensor_dev_attr(devattr)->index;
734
735	return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MAX));
736}
737static ssize_t show_therm_crit_alarm(struct device *dev,
738				struct device_attribute *devattr, char *buf)
739{
740	struct pc87360_data *data = pc87360_update_device(dev);
741	unsigned nr = to_sensor_dev_attr(devattr)->index;
742
743	return sprintf(buf, "%u\n", !!(data->in_status[nr] & TEMP_ALM_CRIT));
744}
745
746static struct sensor_device_attribute therm_min_alarm[] = {
747	SENSOR_ATTR(temp4_min_alarm, S_IRUGO,
748		    show_therm_min_alarm, NULL, 0+11),
749	SENSOR_ATTR(temp5_min_alarm, S_IRUGO,
750		    show_therm_min_alarm, NULL, 1+11),
751	SENSOR_ATTR(temp6_min_alarm, S_IRUGO,
752		    show_therm_min_alarm, NULL, 2+11),
753};
754static struct sensor_device_attribute therm_max_alarm[] = {
755	SENSOR_ATTR(temp4_max_alarm, S_IRUGO,
756		    show_therm_max_alarm, NULL, 0+11),
757	SENSOR_ATTR(temp5_max_alarm, S_IRUGO,
758		    show_therm_max_alarm, NULL, 1+11),
759	SENSOR_ATTR(temp6_max_alarm, S_IRUGO,
760		    show_therm_max_alarm, NULL, 2+11),
761};
762static struct sensor_device_attribute therm_crit_alarm[] = {
763	SENSOR_ATTR(temp4_crit_alarm, S_IRUGO,
764		    show_therm_crit_alarm, NULL, 0+11),
765	SENSOR_ATTR(temp5_crit_alarm, S_IRUGO,
766		    show_therm_crit_alarm, NULL, 1+11),
767	SENSOR_ATTR(temp6_crit_alarm, S_IRUGO,
768		    show_therm_crit_alarm, NULL, 2+11),
769};
770
771#define THERM_UNIT_ATTRS(X) \
772	&therm_input[X].dev_attr.attr,	\
773	&therm_status[X].dev_attr.attr,	\
774	&therm_min[X].dev_attr.attr,	\
775	&therm_max[X].dev_attr.attr,	\
776	&therm_crit[X].dev_attr.attr,	\
777	&therm_min_alarm[X].dev_attr.attr, \
778	&therm_max_alarm[X].dev_attr.attr, \
779	&therm_crit_alarm[X].dev_attr.attr
780
781static struct attribute * pc8736x_therm_attr_array[] = {
782	THERM_UNIT_ATTRS(0),
783	THERM_UNIT_ATTRS(1),
784	THERM_UNIT_ATTRS(2),
785	NULL
786};
787static const struct attribute_group pc8736x_therm_group = {
788	.attrs = pc8736x_therm_attr_array,
789};
790
791static ssize_t show_temp_input(struct device *dev, struct device_attribute *devattr, char *buf)
792{
793	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
794	struct pc87360_data *data = pc87360_update_device(dev);
795	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
796}
797static ssize_t show_temp_min(struct device *dev, struct device_attribute *devattr, char *buf)
798{
799	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
800	struct pc87360_data *data = pc87360_update_device(dev);
801	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[attr->index]));
802}
803static ssize_t show_temp_max(struct device *dev, struct device_attribute *devattr, char *buf)
804{
805	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
806	struct pc87360_data *data = pc87360_update_device(dev);
807	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[attr->index]));
808}
809static ssize_t show_temp_crit(struct device *dev, struct device_attribute *devattr, char *buf)
810{
811	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
812	struct pc87360_data *data = pc87360_update_device(dev);
813	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[attr->index]));
814}
815static ssize_t show_temp_status(struct device *dev, struct device_attribute *devattr, char *buf)
816{
817	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
818	struct pc87360_data *data = pc87360_update_device(dev);
819	return sprintf(buf, "%d\n", data->temp_status[attr->index]);
820}
821static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr, const char *buf,
822	size_t count)
823{
824	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
825	struct pc87360_data *data = dev_get_drvdata(dev);
826	long val = simple_strtol(buf, NULL, 10);
827
828	mutex_lock(&data->update_lock);
829	data->temp_min[attr->index] = TEMP_TO_REG(val);
830	pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MIN,
831			    data->temp_min[attr->index]);
832	mutex_unlock(&data->update_lock);
833	return count;
834}
835static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf,
836	size_t count)
837{
838	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
839	struct pc87360_data *data = dev_get_drvdata(dev);
840	long val = simple_strtol(buf, NULL, 10);
841
842	mutex_lock(&data->update_lock);
843	data->temp_max[attr->index] = TEMP_TO_REG(val);
844	pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MAX,
845			    data->temp_max[attr->index]);
846	mutex_unlock(&data->update_lock);
847	return count;
848}
849static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devattr, const char *buf,
850	size_t count)
851{
852	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
853	struct pc87360_data *data = dev_get_drvdata(dev);
854	long val = simple_strtol(buf, NULL, 10);
855
856	mutex_lock(&data->update_lock);
857	data->temp_crit[attr->index] = TEMP_TO_REG(val);
858	pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_CRIT,
859			    data->temp_crit[attr->index]);
860	mutex_unlock(&data->update_lock);
861	return count;
862}
863
864static struct sensor_device_attribute temp_input[] = {
865	SENSOR_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0),
866	SENSOR_ATTR(temp2_input, S_IRUGO, show_temp_input, NULL, 1),
867	SENSOR_ATTR(temp3_input, S_IRUGO, show_temp_input, NULL, 2),
868};
869static struct sensor_device_attribute temp_status[] = {
870	SENSOR_ATTR(temp1_status, S_IRUGO, show_temp_status, NULL, 0),
871	SENSOR_ATTR(temp2_status, S_IRUGO, show_temp_status, NULL, 1),
872	SENSOR_ATTR(temp3_status, S_IRUGO, show_temp_status, NULL, 2),
873};
874static struct sensor_device_attribute temp_min[] = {
875	SENSOR_ATTR(temp1_min, S_IRUGO | S_IWUSR,
876		    show_temp_min, set_temp_min, 0),
877	SENSOR_ATTR(temp2_min, S_IRUGO | S_IWUSR,
878		    show_temp_min, set_temp_min, 1),
879	SENSOR_ATTR(temp3_min, S_IRUGO | S_IWUSR,
880		    show_temp_min, set_temp_min, 2),
881};
882static struct sensor_device_attribute temp_max[] = {
883	SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR,
884		    show_temp_max, set_temp_max, 0),
885	SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR,
886		    show_temp_max, set_temp_max, 1),
887	SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR,
888		    show_temp_max, set_temp_max, 2),
889};
890static struct sensor_device_attribute temp_crit[] = {
891	SENSOR_ATTR(temp1_crit, S_IRUGO | S_IWUSR,
892		    show_temp_crit, set_temp_crit, 0),
893	SENSOR_ATTR(temp2_crit, S_IRUGO | S_IWUSR,
894		    show_temp_crit, set_temp_crit, 1),
895	SENSOR_ATTR(temp3_crit, S_IRUGO | S_IWUSR,
896		    show_temp_crit, set_temp_crit, 2),
897};
898
899static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *attr, char *buf)
900{
901	struct pc87360_data *data = pc87360_update_device(dev);
902	return sprintf(buf, "%u\n", data->temp_alarms);
903}
904static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL);
905
906/* show_temp_min/max_alarm() reads data from the per-channel status
907   register (sec 12.3.7), not the temp event status registers (sec
908   12.3.2) that show_temp_alarm() reads (via data->temp_alarms) */
909
910static ssize_t show_temp_min_alarm(struct device *dev,
911			struct device_attribute *devattr, char *buf)
912{
913	struct pc87360_data *data = pc87360_update_device(dev);
914	unsigned nr = to_sensor_dev_attr(devattr)->index;
915
916	return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MIN));
917}
918static ssize_t show_temp_max_alarm(struct device *dev,
919			struct device_attribute *devattr, char *buf)
920{
921	struct pc87360_data *data = pc87360_update_device(dev);
922	unsigned nr = to_sensor_dev_attr(devattr)->index;
923
924	return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MAX));
925}
926static ssize_t show_temp_crit_alarm(struct device *dev,
927			struct device_attribute *devattr, char *buf)
928{
929	struct pc87360_data *data = pc87360_update_device(dev);
930	unsigned nr = to_sensor_dev_attr(devattr)->index;
931
932	return sprintf(buf, "%u\n", !!(data->temp_status[nr] & TEMP_ALM_CRIT));
933}
934
935static struct sensor_device_attribute temp_min_alarm[] = {
936	SENSOR_ATTR(temp1_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 0),
937	SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 1),
938	SENSOR_ATTR(temp3_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 2),
939};
940static struct sensor_device_attribute temp_max_alarm[] = {
941	SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 0),
942	SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 1),
943	SENSOR_ATTR(temp3_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 2),
944};
945static struct sensor_device_attribute temp_crit_alarm[] = {
946	SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 0),
947	SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 1),
948	SENSOR_ATTR(temp3_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 2),
949};
950
951#define TEMP_FAULT	0x40	/* open diode */
952static ssize_t show_temp_fault(struct device *dev,
953			struct device_attribute *devattr, char *buf)
954{
955	struct pc87360_data *data = pc87360_update_device(dev);
956	unsigned nr = to_sensor_dev_attr(devattr)->index;
957
958	return sprintf(buf, "%u\n", !!(data->temp_status[nr] & TEMP_FAULT));
959}
960static struct sensor_device_attribute temp_fault[] = {
961	SENSOR_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0),
962	SENSOR_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1),
963	SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2),
964};
965
966#define TEMP_UNIT_ATTRS(X) \
967	&temp_input[X].dev_attr.attr,	\
968	&temp_status[X].dev_attr.attr,	\
969	&temp_min[X].dev_attr.attr,	\
970	&temp_max[X].dev_attr.attr,	\
971	&temp_crit[X].dev_attr.attr,	\
972	&temp_min_alarm[X].dev_attr.attr, \
973	&temp_max_alarm[X].dev_attr.attr, \
974	&temp_crit_alarm[X].dev_attr.attr, \
975	&temp_fault[X].dev_attr.attr
976
977static struct attribute * pc8736x_temp_attr_array[] = {
978	TEMP_UNIT_ATTRS(0),
979	TEMP_UNIT_ATTRS(1),
980	TEMP_UNIT_ATTRS(2),
981	/* include the few miscellaneous atts here */
982	&dev_attr_alarms_temp.attr,
983	NULL
984};
985static const struct attribute_group pc8736x_temp_group = {
986	.attrs = pc8736x_temp_attr_array,
987};
988
989static ssize_t show_name(struct device *dev,
990			struct device_attribute *devattr, char *buf)
991{
992	struct pc87360_data *data = dev_get_drvdata(dev);
993	return sprintf(buf, "%s\n", data->name);
994}
995static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
996
997/*
998 * Device detection, registration and update
999 */
1000
1001static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses)
1002{
1003	u16 val;
1004	int i;
1005	int nrdev; /* logical device count */
1006
1007	/* No superio_enter */
1008
1009	/* Identify device */
1010	val = force_id ? force_id : superio_inb(sioaddr, DEVID);
1011	switch (val) {
1012	case 0xE1: /* PC87360 */
1013	case 0xE8: /* PC87363 */
1014	case 0xE4: /* PC87364 */
1015		nrdev = 1;
1016		break;
1017	case 0xE5: /* PC87365 */
1018	case 0xE9: /* PC87366 */
1019		nrdev = 3;
1020		break;
1021	default:
1022		superio_exit(sioaddr);
1023		return -ENODEV;
1024	}
1025	/* Remember the device id */
1026	*devid = val;
1027
1028	for (i = 0; i < nrdev; i++) {
1029		/* select logical device */
1030		superio_outb(sioaddr, DEV, logdev[i]);
1031
1032		val = superio_inb(sioaddr, ACT);
1033		if (!(val & 0x01)) {
1034			printk(KERN_INFO "pc87360: Device 0x%02x not "
1035			       "activated\n", logdev[i]);
1036			continue;
1037		}
1038
1039		val = (superio_inb(sioaddr, BASE) << 8)
1040		    | superio_inb(sioaddr, BASE + 1);
1041		if (!val) {
1042			printk(KERN_INFO "pc87360: Base address not set for "
1043			       "device 0x%02x\n", logdev[i]);
1044			continue;
1045		}
1046
1047		addresses[i] = val;
1048
1049		if (i==0) { /* Fans */
1050			confreg[0] = superio_inb(sioaddr, 0xF0);
1051			confreg[1] = superio_inb(sioaddr, 0xF1);
1052
1053#ifdef DEBUG
1054			printk(KERN_DEBUG "pc87360: Fan 1: mon=%d "
1055			       "ctrl=%d inv=%d\n", (confreg[0]>>2)&1,
1056			       (confreg[0]>>3)&1, (confreg[0]>>4)&1);
1057			printk(KERN_DEBUG "pc87360: Fan 2: mon=%d "
1058			       "ctrl=%d inv=%d\n", (confreg[0]>>5)&1,
1059			       (confreg[0]>>6)&1, (confreg[0]>>7)&1);
1060			printk(KERN_DEBUG "pc87360: Fan 3: mon=%d "
1061			       "ctrl=%d inv=%d\n", confreg[1]&1,
1062			       (confreg[1]>>1)&1, (confreg[1]>>2)&1);
1063#endif
1064		} else if (i==1) { /* Voltages */
1065			/* Are we using thermistors? */
1066			if (*devid == 0xE9) { /* PC87366 */
1067				/* These registers are not logical-device
1068				   specific, just that we won't need them if
1069				   we don't use the VLM device */
1070				confreg[2] = superio_inb(sioaddr, 0x2B);
1071				confreg[3] = superio_inb(sioaddr, 0x25);
1072
1073				if (confreg[2] & 0x40) {
1074					printk(KERN_INFO "pc87360: Using "
1075					       "thermistors for temperature "
1076					       "monitoring\n");
1077				}
1078				if (confreg[3] & 0xE0) {
1079					printk(KERN_INFO "pc87360: VID "
1080					       "inputs routed (mode %u)\n",
1081					       confreg[3] >> 5);
1082				}
1083			}
1084		}
1085	}
1086
1087	superio_exit(sioaddr);
1088	return 0;
1089}
1090
1091static int __devinit pc87360_probe(struct platform_device *pdev)
1092{
1093	int i;
1094	struct pc87360_data *data;
1095	int err = 0;
1096	const char *name = "pc87360";
1097	int use_thermistors = 0;
1098	struct device *dev = &pdev->dev;
1099
1100	if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
1101		return -ENOMEM;
1102
1103	data->fannr = 2;
1104	data->innr = 0;
1105	data->tempnr = 0;
1106
1107	switch (devid) {
1108	case 0xe8:
1109		name = "pc87363";
1110		break;
1111	case 0xe4:
1112		name = "pc87364";
1113		data->fannr = 3;
1114		break;
1115	case 0xe5:
1116		name = "pc87365";
1117		data->fannr = extra_isa[0] ? 3 : 0;
1118		data->innr = extra_isa[1] ? 11 : 0;
1119		data->tempnr = extra_isa[2] ? 2 : 0;
1120		break;
1121	case 0xe9:
1122		name = "pc87366";
1123		data->fannr = extra_isa[0] ? 3 : 0;
1124		data->innr = extra_isa[1] ? 14 : 0;
1125		data->tempnr = extra_isa[2] ? 3 : 0;
1126		break;
1127	}
1128
1129	data->name = name;
1130	data->valid = 0;
1131	mutex_init(&data->lock);
1132	mutex_init(&data->update_lock);
1133	platform_set_drvdata(pdev, data);
1134
1135	for (i = 0; i < LDNI_MAX; i++) {
1136		if (((data->address[i] = extra_isa[i]))
1137		 && !request_region(extra_isa[i], PC87360_EXTENT,
1138		 		    pc87360_driver.driver.name)) {
1139			dev_err(dev, "Region 0x%x-0x%x already "
1140				"in use!\n", extra_isa[i],
1141				extra_isa[i]+PC87360_EXTENT-1);
1142			for (i--; i >= 0; i--)
1143				release_region(extra_isa[i], PC87360_EXTENT);
1144			err = -EBUSY;
1145			goto ERROR1;
1146		}
1147	}
1148
1149	/* Retrieve the fans configuration from Super-I/O space */
1150	if (data->fannr)
1151		data->fan_conf = confreg[0] | (confreg[1] << 8);
1152
1153	/* Use the correct reference voltage
1154	   Unless both the VLM and the TMS logical devices agree to
1155	   use an external Vref, the internal one is used. */
1156	if (data->innr) {
1157		i = pc87360_read_value(data, LD_IN, NO_BANK,
1158				       PC87365_REG_IN_CONFIG);
1159		if (data->tempnr) {
1160			i &= pc87360_read_value(data, LD_TEMP, NO_BANK,
1161						PC87365_REG_TEMP_CONFIG);
1162		}
1163		data->in_vref = (i&0x02) ? 3025 : 2966;
1164		dev_dbg(dev, "Using %s reference voltage\n",
1165			(i&0x02) ? "external" : "internal");
1166
1167		data->vid_conf = confreg[3];
1168		data->vrm = vid_which_vrm();
1169	}
1170
1171	/* Fan clock dividers may be needed before any data is read */
1172	for (i = 0; i < data->fannr; i++) {
1173		if (FAN_CONFIG_MONITOR(data->fan_conf, i))
1174			data->fan_status[i] = pc87360_read_value(data,
1175					      LD_FAN, NO_BANK,
1176					      PC87360_REG_FAN_STATUS(i));
1177	}
1178
1179	if (init > 0) {
1180		if (devid == 0xe9 && data->address[1]) /* PC87366 */
1181			use_thermistors = confreg[2] & 0x40;
1182
1183		pc87360_init_device(pdev, use_thermistors);
1184	}
1185
1186	/* Register all-or-nothing sysfs groups */
1187
1188	if (data->innr &&
1189	    (err = sysfs_create_group(&dev->kobj,
1190				      &pc8736x_vin_group)))
1191		goto ERROR3;
1192
1193	if (data->innr == 14 &&
1194	    (err = sysfs_create_group(&dev->kobj,
1195				      &pc8736x_therm_group)))
1196		goto ERROR3;
1197
1198	/* create device attr-files for varying sysfs groups */
1199
1200	if (data->tempnr) {
1201		for (i = 0; i < data->tempnr; i++) {
1202			if ((err = device_create_file(dev,
1203					&temp_input[i].dev_attr))
1204			    || (err = device_create_file(dev,
1205					&temp_min[i].dev_attr))
1206			    || (err = device_create_file(dev,
1207					&temp_max[i].dev_attr))
1208			    || (err = device_create_file(dev,
1209					&temp_crit[i].dev_attr))
1210			    || (err = device_create_file(dev,
1211					&temp_status[i].dev_attr))
1212			    || (err = device_create_file(dev,
1213					&temp_min_alarm[i].dev_attr))
1214			    || (err = device_create_file(dev,
1215					&temp_max_alarm[i].dev_attr))
1216			    || (err = device_create_file(dev,
1217					&temp_crit_alarm[i].dev_attr))
1218			    || (err = device_create_file(dev,
1219					&temp_fault[i].dev_attr)))
1220				goto ERROR3;
1221		}
1222		if ((err = device_create_file(dev, &dev_attr_alarms_temp)))
1223			goto ERROR3;
1224	}
1225
1226	for (i = 0; i < data->fannr; i++) {
1227		if (FAN_CONFIG_MONITOR(data->fan_conf, i)
1228		    && ((err = device_create_file(dev,
1229					&fan_input[i].dev_attr))
1230			|| (err = device_create_file(dev,
1231					&fan_min[i].dev_attr))
1232			|| (err = device_create_file(dev,
1233					&fan_div[i].dev_attr))
1234			|| (err = device_create_file(dev,
1235					&fan_status[i].dev_attr))))
1236			goto ERROR3;
1237
1238		if (FAN_CONFIG_CONTROL(data->fan_conf, i)
1239		    && (err = device_create_file(dev, &pwm[i].dev_attr)))
1240			goto ERROR3;
1241	}
1242
1243	if ((err = device_create_file(dev, &dev_attr_name)))
1244		goto ERROR3;
1245
1246	data->hwmon_dev = hwmon_device_register(dev);
1247	if (IS_ERR(data->hwmon_dev)) {
1248		err = PTR_ERR(data->hwmon_dev);
1249		goto ERROR3;
1250	}
1251	return 0;
1252
1253ERROR3:
1254	device_remove_file(dev, &dev_attr_name);
1255	/* can still remove groups whose members were added individually */
1256	sysfs_remove_group(&dev->kobj, &pc8736x_temp_group);
1257	sysfs_remove_group(&dev->kobj, &pc8736x_fan_group);
1258	sysfs_remove_group(&dev->kobj, &pc8736x_therm_group);
1259	sysfs_remove_group(&dev->kobj, &pc8736x_vin_group);
1260	for (i = 0; i < 3; i++) {
1261		if (data->address[i]) {
1262			release_region(data->address[i], PC87360_EXTENT);
1263		}
1264	}
1265ERROR1:
1266	kfree(data);
1267	return err;
1268}
1269
1270static int __devexit pc87360_remove(struct platform_device *pdev)
1271{
1272	struct pc87360_data *data = platform_get_drvdata(pdev);
1273	int i;
1274
1275	hwmon_device_unregister(data->hwmon_dev);
1276
1277	device_remove_file(&pdev->dev, &dev_attr_name);
1278	sysfs_remove_group(&pdev->dev.kobj, &pc8736x_temp_group);
1279	sysfs_remove_group(&pdev->dev.kobj, &pc8736x_fan_group);
1280	sysfs_remove_group(&pdev->dev.kobj, &pc8736x_therm_group);
1281	sysfs_remove_group(&pdev->dev.kobj, &pc8736x_vin_group);
1282
1283	for (i = 0; i < 3; i++) {
1284		if (data->address[i]) {
1285			release_region(data->address[i], PC87360_EXTENT);
1286		}
1287	}
1288	kfree(data);
1289
1290	return 0;
1291}
1292
1293/* ldi is the logical device index
1294   bank is for voltages and temperatures only */
1295static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
1296			      u8 reg)
1297{
1298	int res;
1299
1300	mutex_lock(&(data->lock));
1301	if (bank != NO_BANK)
1302		outb_p(bank, data->address[ldi] + PC87365_REG_BANK);
1303	res = inb_p(data->address[ldi] + reg);
1304	mutex_unlock(&(data->lock));
1305
1306	return res;
1307}
1308
1309static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
1310				u8 reg, u8 value)
1311{
1312	mutex_lock(&(data->lock));
1313	if (bank != NO_BANK)
1314		outb_p(bank, data->address[ldi] + PC87365_REG_BANK);
1315	outb_p(value, data->address[ldi] + reg);
1316	mutex_unlock(&(data->lock));
1317}
1318
1319/* (temp & vin) channel conversion status register flags (pdf sec.11.5.12) */
1320#define CHAN_CNVRTD	0x80	/* new data ready */
1321#define CHAN_ENA	0x01	/* enabled channel (temp or vin) */
1322#define CHAN_ALM_ENA	0x10	/* propagate to alarms-reg ?? (chk val!) */
1323#define CHAN_READY	(CHAN_ENA|CHAN_CNVRTD) /* sample ready mask */
1324
1325#define TEMP_OTS_OE	0x20	/* OTS Output Enable */
1326#define VIN_RW1C_MASK	(CHAN_READY|CHAN_ALM_MAX|CHAN_ALM_MIN)   /* 0x87 */
1327#define TEMP_RW1C_MASK	(VIN_RW1C_MASK|TEMP_ALM_CRIT|TEMP_FAULT) /* 0xCF */
1328
1329static void pc87360_init_device(struct platform_device *pdev,
1330				int use_thermistors)
1331{
1332	struct pc87360_data *data = platform_get_drvdata(pdev);
1333	int i, nr;
1334	const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 };
1335	const u8 init_temp[3] = { 2, 2, 1 };
1336	u8 reg;
1337
1338	if (init >= 2 && data->innr) {
1339		reg = pc87360_read_value(data, LD_IN, NO_BANK,
1340					 PC87365_REG_IN_CONVRATE);
1341		dev_info(&pdev->dev, "VLM conversion set to "
1342			 "1s period, 160us delay\n");
1343		pc87360_write_value(data, LD_IN, NO_BANK,
1344				    PC87365_REG_IN_CONVRATE,
1345				    (reg & 0xC0) | 0x11);
1346	}
1347
1348	nr = data->innr < 11 ? data->innr : 11;
1349	for (i = 0; i < nr; i++) {
1350		reg = pc87360_read_value(data, LD_IN, i,
1351					 PC87365_REG_IN_STATUS);
1352		dev_dbg(&pdev->dev, "bios in%d status:0x%02x\n", i, reg);
1353		if (init >= init_in[i]) {
1354			/* Forcibly enable voltage channel */
1355			if (!(reg & CHAN_ENA)) {
1356				dev_dbg(&pdev->dev, "Forcibly "
1357					"enabling in%d\n", i);
1358				pc87360_write_value(data, LD_IN, i,
1359						    PC87365_REG_IN_STATUS,
1360						    (reg & 0x68) | 0x87);
1361			}
1362		}
1363	}
1364
1365	/* We can't blindly trust the Super-I/O space configuration bit,
1366	   most BIOS won't set it properly */
1367	dev_dbg(&pdev->dev, "bios thermistors:%d\n", use_thermistors);
1368	for (i = 11; i < data->innr; i++) {
1369		reg = pc87360_read_value(data, LD_IN, i,
1370					 PC87365_REG_TEMP_STATUS);
1371		use_thermistors = use_thermistors || (reg & CHAN_ENA);
1372		/* thermistors are temp[4-6], measured on vin[11-14] */
1373		dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i-7, reg);
1374	}
1375	dev_dbg(&pdev->dev, "using thermistors:%d\n", use_thermistors);
1376
1377	i = use_thermistors ? 2 : 0;
1378	for (; i < data->tempnr; i++) {
1379		reg = pc87360_read_value(data, LD_TEMP, i,
1380					 PC87365_REG_TEMP_STATUS);
1381		dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i+1, reg);
1382		if (init >= init_temp[i]) {
1383			/* Forcibly enable temperature channel */
1384			if (!(reg & CHAN_ENA)) {
1385				dev_dbg(&pdev->dev, "Forcibly "
1386					"enabling temp%d\n", i+1);
1387				pc87360_write_value(data, LD_TEMP, i,
1388						    PC87365_REG_TEMP_STATUS,
1389						    0xCF);
1390			}
1391		}
1392	}
1393
1394	if (use_thermistors) {
1395		for (i = 11; i < data->innr; i++) {
1396			if (init >= init_in[i]) {
1397				/* The pin may already be used by thermal
1398				   diodes */
1399				reg = pc87360_read_value(data, LD_TEMP,
1400				      (i-11)/2, PC87365_REG_TEMP_STATUS);
1401				if (reg & CHAN_ENA) {
1402					dev_dbg(&pdev->dev, "Skipping "
1403						"temp%d, pin already in use "
1404						"by temp%d\n", i-7, (i-11)/2);
1405					continue;
1406				}
1407
1408				/* Forcibly enable thermistor channel */
1409				reg = pc87360_read_value(data, LD_IN, i,
1410							 PC87365_REG_IN_STATUS);
1411				if (!(reg & CHAN_ENA)) {
1412					dev_dbg(&pdev->dev, "Forcibly "
1413						"enabling temp%d\n", i-7);
1414					pc87360_write_value(data, LD_IN, i,
1415						PC87365_REG_TEMP_STATUS,
1416						(reg & 0x60) | 0x8F);
1417				}
1418			}
1419		}
1420	}
1421
1422	if (data->innr) {
1423		reg = pc87360_read_value(data, LD_IN, NO_BANK,
1424					 PC87365_REG_IN_CONFIG);
1425		dev_dbg(&pdev->dev, "bios vin-cfg:0x%02x\n", reg);
1426		if (reg & CHAN_ENA) {
1427			dev_dbg(&pdev->dev, "Forcibly "
1428				"enabling monitoring (VLM)\n");
1429			pc87360_write_value(data, LD_IN, NO_BANK,
1430					    PC87365_REG_IN_CONFIG,
1431					    reg & 0xFE);
1432		}
1433	}
1434
1435	if (data->tempnr) {
1436		reg = pc87360_read_value(data, LD_TEMP, NO_BANK,
1437					 PC87365_REG_TEMP_CONFIG);
1438		dev_dbg(&pdev->dev, "bios temp-cfg:0x%02x\n", reg);
1439		if (reg & CHAN_ENA) {
1440			dev_dbg(&pdev->dev, "Forcibly enabling "
1441				"monitoring (TMS)\n");
1442			pc87360_write_value(data, LD_TEMP, NO_BANK,
1443					    PC87365_REG_TEMP_CONFIG,
1444					    reg & 0xFE);
1445		}
1446
1447		if (init >= 2) {
1448			/* Chip config as documented by National Semi. */
1449			pc87360_write_value(data, LD_TEMP, 0xF, 0xA, 0x08);
1450			/* We voluntarily omit the bank here, in case the
1451			   sequence itself matters. It shouldn't be a problem,
1452			   since nobody else is supposed to access the
1453			   device at that point. */
1454			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xB, 0x04);
1455			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xC, 0x35);
1456			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xD, 0x05);
1457			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xE, 0x05);
1458		}
1459	}
1460}
1461
1462static void pc87360_autodiv(struct device *dev, int nr)
1463{
1464	struct pc87360_data *data = dev_get_drvdata(dev);
1465	u8 old_min = data->fan_min[nr];
1466
1467	/* Increase clock divider if needed and possible */
1468	if ((data->fan_status[nr] & 0x04) /* overflow flag */
1469	 || (data->fan[nr] >= 224)) { /* next to overflow */
1470		if ((data->fan_status[nr] & 0x60) != 0x60) {
1471			data->fan_status[nr] += 0x20;
1472			data->fan_min[nr] >>= 1;
1473			data->fan[nr] >>= 1;
1474			dev_dbg(dev, "Increasing "
1475				"clock divider to %d for fan %d\n",
1476				FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1);
1477		}
1478	} else {
1479		/* Decrease clock divider if possible */
1480		while (!(data->fan_min[nr] & 0x80) /* min "nails" divider */
1481		 && data->fan[nr] < 85 /* bad accuracy */
1482		 && (data->fan_status[nr] & 0x60) != 0x00) {
1483			data->fan_status[nr] -= 0x20;
1484			data->fan_min[nr] <<= 1;
1485			data->fan[nr] <<= 1;
1486			dev_dbg(dev, "Decreasing "
1487				"clock divider to %d for fan %d\n",
1488				FAN_DIV_FROM_REG(data->fan_status[nr]),
1489				nr+1);
1490		}
1491	}
1492
1493	/* Write new fan min if it changed */
1494	if (old_min != data->fan_min[nr]) {
1495		pc87360_write_value(data, LD_FAN, NO_BANK,
1496				    PC87360_REG_FAN_MIN(nr),
1497				    data->fan_min[nr]);
1498	}
1499}
1500
1501static struct pc87360_data *pc87360_update_device(struct device *dev)
1502{
1503	struct pc87360_data *data = dev_get_drvdata(dev);
1504	u8 i;
1505
1506	mutex_lock(&data->update_lock);
1507
1508	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
1509		dev_dbg(dev, "Data update\n");
1510
1511		/* Fans */
1512		for (i = 0; i < data->fannr; i++) {
1513			if (FAN_CONFIG_MONITOR(data->fan_conf, i)) {
1514				data->fan_status[i] =
1515					pc87360_read_value(data, LD_FAN,
1516					NO_BANK, PC87360_REG_FAN_STATUS(i));
1517				data->fan[i] = pc87360_read_value(data, LD_FAN,
1518					       NO_BANK, PC87360_REG_FAN(i));
1519				data->fan_min[i] = pc87360_read_value(data,
1520						   LD_FAN, NO_BANK,
1521						   PC87360_REG_FAN_MIN(i));
1522				/* Change clock divider if needed */
1523				pc87360_autodiv(dev, i);
1524				/* Clear bits and write new divider */
1525				pc87360_write_value(data, LD_FAN, NO_BANK,
1526						    PC87360_REG_FAN_STATUS(i),
1527						    data->fan_status[i]);
1528			}
1529			if (FAN_CONFIG_CONTROL(data->fan_conf, i))
1530				data->pwm[i] = pc87360_read_value(data, LD_FAN,
1531					       NO_BANK, PC87360_REG_PWM(i));
1532		}
1533
1534		/* Voltages */
1535		for (i = 0; i < data->innr; i++) {
1536			data->in_status[i] = pc87360_read_value(data, LD_IN, i,
1537					     PC87365_REG_IN_STATUS);
1538			/* Clear bits */
1539			pc87360_write_value(data, LD_IN, i,
1540					    PC87365_REG_IN_STATUS,
1541					    data->in_status[i]);
1542			if ((data->in_status[i] & CHAN_READY) == CHAN_READY) {
1543				data->in[i] = pc87360_read_value(data, LD_IN,
1544					      i, PC87365_REG_IN);
1545			}
1546			if (data->in_status[i] & CHAN_ENA) {
1547				data->in_min[i] = pc87360_read_value(data,
1548						  LD_IN, i,
1549						  PC87365_REG_IN_MIN);
1550				data->in_max[i] = pc87360_read_value(data,
1551						  LD_IN, i,
1552						  PC87365_REG_IN_MAX);
1553				if (i >= 11)
1554					data->in_crit[i-11] =
1555						pc87360_read_value(data, LD_IN,
1556						i, PC87365_REG_TEMP_CRIT);
1557			}
1558		}
1559		if (data->innr) {
1560			data->in_alarms = pc87360_read_value(data, LD_IN,
1561					  NO_BANK, PC87365_REG_IN_ALARMS1)
1562					| ((pc87360_read_value(data, LD_IN,
1563					    NO_BANK, PC87365_REG_IN_ALARMS2)
1564					    & 0x07) << 8);
1565			data->vid = (data->vid_conf & 0xE0) ?
1566				    pc87360_read_value(data, LD_IN,
1567				    NO_BANK, PC87365_REG_VID) : 0x1F;
1568		}
1569
1570		/* Temperatures */
1571		for (i = 0; i < data->tempnr; i++) {
1572			data->temp_status[i] = pc87360_read_value(data,
1573					       LD_TEMP, i,
1574					       PC87365_REG_TEMP_STATUS);
1575			/* Clear bits */
1576			pc87360_write_value(data, LD_TEMP, i,
1577					    PC87365_REG_TEMP_STATUS,
1578					    data->temp_status[i]);
1579			if ((data->temp_status[i] & CHAN_READY) == CHAN_READY) {
1580				data->temp[i] = pc87360_read_value(data,
1581						LD_TEMP, i,
1582						PC87365_REG_TEMP);
1583			}
1584			if (data->temp_status[i] & CHAN_ENA) {
1585				data->temp_min[i] = pc87360_read_value(data,
1586						    LD_TEMP, i,
1587						    PC87365_REG_TEMP_MIN);
1588				data->temp_max[i] = pc87360_read_value(data,
1589						    LD_TEMP, i,
1590						    PC87365_REG_TEMP_MAX);
1591				data->temp_crit[i] = pc87360_read_value(data,
1592						     LD_TEMP, i,
1593						     PC87365_REG_TEMP_CRIT);
1594			}
1595		}
1596		if (data->tempnr) {
1597			data->temp_alarms = pc87360_read_value(data, LD_TEMP,
1598					    NO_BANK, PC87365_REG_TEMP_ALARMS)
1599					    & 0x3F;
1600		}
1601
1602		data->last_updated = jiffies;
1603		data->valid = 1;
1604	}
1605
1606	mutex_unlock(&data->update_lock);
1607
1608	return data;
1609}
1610
1611static int __init pc87360_device_add(unsigned short address)
1612{
1613	struct resource res[3];
1614	int err, i, res_count;
1615
1616	pdev = platform_device_alloc("pc87360", address);
1617	if (!pdev) {
1618		err = -ENOMEM;
1619		printk(KERN_ERR "pc87360: Device allocation failed\n");
1620		goto exit;
1621	}
1622
1623	memset(res, 0, 3 * sizeof(struct resource));
1624	res_count = 0;
1625	for (i = 0; i < 3; i++) {
1626		if (!extra_isa[i])
1627			continue;
1628		res[res_count].start = extra_isa[i];
1629		res[res_count].end = extra_isa[i] + PC87360_EXTENT - 1;
1630		res[res_count].name = "pc87360",
1631		res[res_count].flags = IORESOURCE_IO,
1632
1633		err = acpi_check_resource_conflict(&res[res_count]);
1634		if (err)
1635			goto exit_device_put;
1636
1637		res_count++;
1638	}
1639
1640	err = platform_device_add_resources(pdev, res, res_count);
1641	if (err) {
1642		printk(KERN_ERR "pc87360: Device resources addition failed "
1643		       "(%d)\n", err);
1644		goto exit_device_put;
1645	}
1646
1647	err = platform_device_add(pdev);
1648	if (err) {
1649		printk(KERN_ERR "pc87360: Device addition failed (%d)\n",
1650		       err);
1651		goto exit_device_put;
1652	}
1653
1654	return 0;
1655
1656exit_device_put:
1657	platform_device_put(pdev);
1658exit:
1659	return err;
1660}
1661
1662static int __init pc87360_init(void)
1663{
1664	int err, i;
1665	unsigned short address = 0;
1666
1667	if (pc87360_find(0x2e, &devid, extra_isa)
1668	 && pc87360_find(0x4e, &devid, extra_isa)) {
1669		printk(KERN_WARNING "pc87360: PC8736x not detected, "
1670		       "module not inserted.\n");
1671		return -ENODEV;
1672	}
1673
1674	/* Arbitrarily pick one of the addresses */
1675	for (i = 0; i < 3; i++) {
1676		if (extra_isa[i] != 0x0000) {
1677			address = extra_isa[i];
1678			break;
1679		}
1680	}
1681
1682	if (address == 0x0000) {
1683		printk(KERN_WARNING "pc87360: No active logical device, "
1684		       "module not inserted.\n");
1685		return -ENODEV;
1686	}
1687
1688	err = platform_driver_register(&pc87360_driver);
1689	if (err)
1690		goto exit;
1691
1692	/* Sets global pdev as a side effect */
1693	err = pc87360_device_add(address);
1694	if (err)
1695		goto exit_driver;
1696
1697	return 0;
1698
1699 exit_driver:
1700	platform_driver_unregister(&pc87360_driver);
1701 exit:
1702	return err;
1703}
1704
1705static void __exit pc87360_exit(void)
1706{
1707	platform_device_unregister(pdev);
1708	platform_driver_unregister(&pc87360_driver);
1709}
1710
1711
1712MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
1713MODULE_DESCRIPTION("PC8736x hardware monitor");
1714MODULE_LICENSE("GPL");
1715
1716module_init(pc87360_init);
1717module_exit(pc87360_exit);
1718