xref: /openbmc/linux/drivers/hwmon/via686a.c (revision 8fa5723aa7e053d498336b48448b292fc2e0458b)
1 /*
2     via686a.c - Part of lm_sensors, Linux kernel modules
3 		for hardware monitoring
4 
5     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
6 			Kyösti Mälkki <kmalkki@cc.hut.fi>,
7 			Mark Studebaker <mdsxyz123@yahoo.com>,
8 			and Bob Dougherty <bobd@stanford.edu>
9     (Some conversion-factor data were contributed by Jonathan Teh Soon Yew
10     <j.teh@iname.com> and Alex van Kaam <darkside@chello.nl>.)
11 
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; either version 2 of the License, or
15     (at your option) any later version.
16 
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20     GNU General Public License for more details.
21 
22     You should have received a copy of the GNU General Public License
23     along with this program; if not, write to the Free Software
24     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26 
27 /*
28     Supports the Via VT82C686A, VT82C686B south bridges.
29     Reports all as a 686A.
30     Warning - only supports a single device.
31 */
32 
33 #include <linux/module.h>
34 #include <linux/slab.h>
35 #include <linux/pci.h>
36 #include <linux/jiffies.h>
37 #include <linux/platform_device.h>
38 #include <linux/hwmon.h>
39 #include <linux/hwmon-sysfs.h>
40 #include <linux/err.h>
41 #include <linux/init.h>
42 #include <linux/mutex.h>
43 #include <linux/sysfs.h>
44 #include <asm/io.h>
45 
46 
47 /* If force_addr is set to anything different from 0, we forcibly enable
48    the device at the given address. */
49 static unsigned short force_addr;
50 module_param(force_addr, ushort, 0);
51 MODULE_PARM_DESC(force_addr,
52 		 "Initialize the base address of the sensors");
53 
54 static struct platform_device *pdev;
55 
56 /*
57    The Via 686a southbridge has a LM78-like chip integrated on the same IC.
58    This driver is a customized copy of lm78.c
59 */
60 
61 /* Many VIA686A constants specified below */
62 
63 /* Length of ISA address segment */
64 #define VIA686A_EXTENT		0x80
65 #define VIA686A_BASE_REG	0x70
66 #define VIA686A_ENABLE_REG	0x74
67 
68 /* The VIA686A registers */
69 /* ins numbered 0-4 */
70 #define VIA686A_REG_IN_MAX(nr)	(0x2b + ((nr) * 2))
71 #define VIA686A_REG_IN_MIN(nr)	(0x2c + ((nr) * 2))
72 #define VIA686A_REG_IN(nr)	(0x22 + (nr))
73 
74 /* fans numbered 1-2 */
75 #define VIA686A_REG_FAN_MIN(nr)	(0x3a + (nr))
76 #define VIA686A_REG_FAN(nr)	(0x28 + (nr))
77 
78 /* temps numbered 1-3 */
79 static const u8 VIA686A_REG_TEMP[]	= { 0x20, 0x21, 0x1f };
80 static const u8 VIA686A_REG_TEMP_OVER[]	= { 0x39, 0x3d, 0x1d };
81 static const u8 VIA686A_REG_TEMP_HYST[]	= { 0x3a, 0x3e, 0x1e };
82 /* bits 7-6 */
83 #define VIA686A_REG_TEMP_LOW1	0x4b
84 /* 2 = bits 5-4, 3 = bits 7-6 */
85 #define VIA686A_REG_TEMP_LOW23	0x49
86 
87 #define VIA686A_REG_ALARM1	0x41
88 #define VIA686A_REG_ALARM2	0x42
89 #define VIA686A_REG_FANDIV	0x47
90 #define VIA686A_REG_CONFIG	0x40
91 /* The following register sets temp interrupt mode (bits 1-0 for temp1,
92  3-2 for temp2, 5-4 for temp3).  Modes are:
93     00 interrupt stays as long as value is out-of-range
94     01 interrupt is cleared once register is read (default)
95     10 comparator mode- like 00, but ignores hysteresis
96     11 same as 00 */
97 #define VIA686A_REG_TEMP_MODE		0x4b
98 /* We'll just assume that you want to set all 3 simultaneously: */
99 #define VIA686A_TEMP_MODE_MASK		0x3F
100 #define VIA686A_TEMP_MODE_CONTINUOUS	0x00
101 
102 /* Conversions. Limit checking is only done on the TO_REG
103    variants.
104 
105 ********* VOLTAGE CONVERSIONS (Bob Dougherty) ********
106  From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew):
107  voltagefactor[0]=1.25/2628; (2628/1.25=2102.4)   // Vccp
108  voltagefactor[1]=1.25/2628; (2628/1.25=2102.4)   // +2.5V
109  voltagefactor[2]=1.67/2628; (2628/1.67=1573.7)   // +3.3V
110  voltagefactor[3]=2.6/2628;  (2628/2.60=1010.8)   // +5V
111  voltagefactor[4]=6.3/2628;  (2628/6.30=417.14)   // +12V
112  in[i]=(data[i+2]*25.0+133)*voltagefactor[i];
113  That is:
114  volts = (25*regVal+133)*factor
115  regVal = (volts/factor-133)/25
116  (These conversions were contributed by Jonathan Teh Soon Yew
117  <j.teh@iname.com>) */
118 static inline u8 IN_TO_REG(long val, int inNum)
119 {
120 	/* To avoid floating point, we multiply constants by 10 (100 for +12V).
121 	   Rounding is done (120500 is actually 133000 - 12500).
122 	   Remember that val is expressed in 0.001V/bit, which is why we divide
123 	   by an additional 10000 (100000 for +12V): 1000 for val and 10 (100)
124 	   for the constants. */
125 	if (inNum <= 1)
126 		return (u8)
127 		    SENSORS_LIMIT((val * 21024 - 1205000) / 250000, 0, 255);
128 	else if (inNum == 2)
129 		return (u8)
130 		    SENSORS_LIMIT((val * 15737 - 1205000) / 250000, 0, 255);
131 	else if (inNum == 3)
132 		return (u8)
133 		    SENSORS_LIMIT((val * 10108 - 1205000) / 250000, 0, 255);
134 	else
135 		return (u8)
136 		    SENSORS_LIMIT((val * 41714 - 12050000) / 2500000, 0, 255);
137 }
138 
139 static inline long IN_FROM_REG(u8 val, int inNum)
140 {
141 	/* To avoid floating point, we multiply constants by 10 (100 for +12V).
142 	   We also multiply them by 1000 because we want 0.001V/bit for the
143 	   output value. Rounding is done. */
144 	if (inNum <= 1)
145 		return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024);
146 	else if (inNum == 2)
147 		return (long) ((250000 * val + 1330000 + 15737 / 2) / 15737);
148 	else if (inNum == 3)
149 		return (long) ((250000 * val + 1330000 + 10108 / 2) / 10108);
150 	else
151 		return (long) ((2500000 * val + 13300000 + 41714 / 2) / 41714);
152 }
153 
154 /********* FAN RPM CONVERSIONS ********/
155 /* Higher register values = slower fans (the fan's strobe gates a counter).
156  But this chip saturates back at 0, not at 255 like all the other chips.
157  So, 0 means 0 RPM */
158 static inline u8 FAN_TO_REG(long rpm, int div)
159 {
160 	if (rpm == 0)
161 		return 0;
162 	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
163 	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 255);
164 }
165 
166 #define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1350000/((val)*(div)))
167 
168 /******** TEMP CONVERSIONS (Bob Dougherty) *********/
169 /* linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew)
170       if(temp<169)
171 	      return double(temp)*0.427-32.08;
172       else if(temp>=169 && temp<=202)
173 	      return double(temp)*0.582-58.16;
174       else
175 	      return double(temp)*0.924-127.33;
176 
177  A fifth-order polynomial fits the unofficial data (provided by Alex van
178  Kaam <darkside@chello.nl>) a bit better.  It also give more reasonable
179  numbers on my machine (ie. they agree with what my BIOS tells me).
180  Here's the fifth-order fit to the 8-bit data:
181  temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 -
182 	2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
183 
184  (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for
185  finding my typos in this formula!)
186 
187  Alas, none of the elegant function-fit solutions will work because we
188  aren't allowed to use floating point in the kernel and doing it with
189  integers doesn't provide enough precision.  So we'll do boring old
190  look-up table stuff.  The unofficial data (see below) have effectively
191  7-bit resolution (they are rounded to the nearest degree).  I'm assuming
192  that the transfer function of the device is monotonic and smooth, so a
193  smooth function fit to the data will allow us to get better precision.
194  I used the 5th-order poly fit described above and solved for
195  VIA register values 0-255.  I *10 before rounding, so we get tenth-degree
196  precision.  (I could have done all 1024 values for our 10-bit readings,
197  but the function is very linear in the useful range (0-80 deg C), so
198  we'll just use linear interpolation for 10-bit readings.)  So, tempLUT
199  is the temp at via register values 0-255: */
200 static const s16 tempLUT[] =
201 { -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
202 	-503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
203 	-362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
204 	-255, -246, -237, -229, -220, -212, -204, -196, -188, -180,
205 	-173, -166, -159, -152, -145, -139, -132, -126, -120, -114,
206 	-108, -102, -96, -91, -85, -80, -74, -69, -64, -59, -54, -49,
207 	-44, -39, -34, -29, -25, -20, -15, -11, -6, -2, 3, 7, 12, 16,
208 	20, 25, 29, 33, 37, 42, 46, 50, 54, 59, 63, 67, 71, 75, 79, 84,
209 	88, 92, 96, 100, 104, 109, 113, 117, 121, 125, 130, 134, 138,
210 	142, 146, 151, 155, 159, 163, 168, 172, 176, 181, 185, 189,
211 	193, 198, 202, 206, 211, 215, 219, 224, 228, 232, 237, 241,
212 	245, 250, 254, 259, 263, 267, 272, 276, 281, 285, 290, 294,
213 	299, 303, 307, 312, 316, 321, 325, 330, 334, 339, 344, 348,
214 	353, 357, 362, 366, 371, 376, 380, 385, 390, 395, 399, 404,
215 	409, 414, 419, 423, 428, 433, 438, 443, 449, 454, 459, 464,
216 	469, 475, 480, 486, 491, 497, 502, 508, 514, 520, 526, 532,
217 	538, 544, 551, 557, 564, 571, 578, 584, 592, 599, 606, 614,
218 	621, 629, 637, 645, 654, 662, 671, 680, 689, 698, 708, 718,
219 	728, 738, 749, 759, 770, 782, 793, 805, 818, 830, 843, 856,
220 	870, 883, 898, 912, 927, 943, 958, 975, 991, 1008, 1026, 1044,
221 	1062, 1081, 1101, 1121, 1141, 1162, 1184, 1206, 1229, 1252,
222 	1276, 1301, 1326, 1352, 1378, 1406, 1434, 1462
223 };
224 
225 /* the original LUT values from Alex van Kaam <darkside@chello.nl>
226    (for via register values 12-240):
227 {-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31,
228 -30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,
229 -15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,
230 -3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12,
231 12,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22,
232 22,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33,
233 33,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,
234 45,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60,
235 61,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84,
236 85,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110};
237 
238 
239  Here's the reverse LUT.  I got it by doing a 6-th order poly fit (needed
240  an extra term for a good fit to these inverse data!) and then
241  solving for each temp value from -50 to 110 (the useable range for
242  this chip).  Here's the fit:
243  viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4
244  - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01)
245  Note that n=161: */
246 static const u8 viaLUT[] =
247 { 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23,
248 	23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40,
249 	41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66,
250 	69, 71, 73, 75, 77, 79, 82, 84, 86, 88, 91, 93, 95, 98, 100,
251 	103, 105, 107, 110, 112, 115, 117, 119, 122, 124, 126, 129,
252 	131, 134, 136, 138, 140, 143, 145, 147, 150, 152, 154, 156,
253 	158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180,
254 	182, 183, 185, 187, 188, 190, 192, 193, 195, 196, 198, 199,
255 	200, 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, 213,
256 	214, 215, 216, 217, 218, 219, 220, 221, 222, 222, 223, 224,
257 	225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232,
258 	233, 233, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239,
259 	239, 240
260 };
261 
262 /* Converting temps to (8-bit) hyst and over registers
263    No interpolation here.
264    The +50 is because the temps start at -50 */
265 static inline u8 TEMP_TO_REG(long val)
266 {
267 	return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 :
268 		      (val < 0 ? val - 500 : val + 500) / 1000 + 50];
269 }
270 
271 /* for 8-bit temperature hyst and over registers */
272 #define TEMP_FROM_REG(val)	((long)tempLUT[val] * 100)
273 
274 /* for 10-bit temperature readings */
275 static inline long TEMP_FROM_REG10(u16 val)
276 {
277 	u16 eightBits = val >> 2;
278 	u16 twoBits = val & 3;
279 
280 	/* no interpolation for these */
281 	if (twoBits == 0 || eightBits == 255)
282 		return TEMP_FROM_REG(eightBits);
283 
284 	/* do some linear interpolation */
285 	return (tempLUT[eightBits] * (4 - twoBits) +
286 		tempLUT[eightBits + 1] * twoBits) * 25;
287 }
288 
289 #define DIV_FROM_REG(val) (1 << (val))
290 #define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
291 
292 /* For each registered chip, we need to keep some data in memory.
293    The structure is dynamically allocated. */
294 struct via686a_data {
295 	unsigned short addr;
296 	const char *name;
297 	struct device *hwmon_dev;
298 	struct mutex update_lock;
299 	char valid;		/* !=0 if following fields are valid */
300 	unsigned long last_updated;	/* In jiffies */
301 
302 	u8 in[5];		/* Register value */
303 	u8 in_max[5];		/* Register value */
304 	u8 in_min[5];		/* Register value */
305 	u8 fan[2];		/* Register value */
306 	u8 fan_min[2];		/* Register value */
307 	u16 temp[3];		/* Register value 10 bit */
308 	u8 temp_over[3];	/* Register value */
309 	u8 temp_hyst[3];	/* Register value */
310 	u8 fan_div[2];		/* Register encoding, shifted right */
311 	u16 alarms;		/* Register encoding, combined */
312 };
313 
314 static struct pci_dev *s_bridge;	/* pointer to the (only) via686a */
315 
316 static int via686a_probe(struct platform_device *pdev);
317 static int __devexit via686a_remove(struct platform_device *pdev);
318 
319 static inline int via686a_read_value(struct via686a_data *data, u8 reg)
320 {
321 	return inb_p(data->addr + reg);
322 }
323 
324 static inline void via686a_write_value(struct via686a_data *data, u8 reg,
325 				       u8 value)
326 {
327 	outb_p(value, data->addr + reg);
328 }
329 
330 static struct via686a_data *via686a_update_device(struct device *dev);
331 static void via686a_init_device(struct via686a_data *data);
332 
333 /* following are the sysfs callback functions */
334 
335 /* 7 voltage sensors */
336 static ssize_t show_in(struct device *dev, struct device_attribute *da,
337 		char *buf) {
338 	struct via686a_data *data = via686a_update_device(dev);
339 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
340 	int nr = attr->index;
341 	return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr));
342 }
343 
344 static ssize_t show_in_min(struct device *dev, struct device_attribute *da,
345 		char *buf) {
346 	struct via686a_data *data = via686a_update_device(dev);
347 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
348 	int nr = attr->index;
349 	return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr));
350 }
351 
352 static ssize_t show_in_max(struct device *dev, struct device_attribute *da,
353 		char *buf) {
354 	struct via686a_data *data = via686a_update_device(dev);
355 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
356 	int nr = attr->index;
357 	return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr));
358 }
359 
360 static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
361 		const char *buf, size_t count) {
362 	struct via686a_data *data = dev_get_drvdata(dev);
363 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
364 	int nr = attr->index;
365 	unsigned long val = simple_strtoul(buf, NULL, 10);
366 
367 	mutex_lock(&data->update_lock);
368 	data->in_min[nr] = IN_TO_REG(val, nr);
369 	via686a_write_value(data, VIA686A_REG_IN_MIN(nr),
370 			data->in_min[nr]);
371 	mutex_unlock(&data->update_lock);
372 	return count;
373 }
374 static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
375 		const char *buf, size_t count) {
376 	struct via686a_data *data = dev_get_drvdata(dev);
377 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
378 	int nr = attr->index;
379 	unsigned long val = simple_strtoul(buf, NULL, 10);
380 
381 	mutex_lock(&data->update_lock);
382 	data->in_max[nr] = IN_TO_REG(val, nr);
383 	via686a_write_value(data, VIA686A_REG_IN_MAX(nr),
384 			data->in_max[nr]);
385 	mutex_unlock(&data->update_lock);
386 	return count;
387 }
388 #define show_in_offset(offset)					\
389 static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,		\
390 		show_in, NULL, offset);				\
391 static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,	\
392 		show_in_min, set_in_min, offset);		\
393 static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,	\
394 		show_in_max, set_in_max, offset);
395 
396 show_in_offset(0);
397 show_in_offset(1);
398 show_in_offset(2);
399 show_in_offset(3);
400 show_in_offset(4);
401 
402 /* 3 temperatures */
403 static ssize_t show_temp(struct device *dev, struct device_attribute *da,
404 		char *buf) {
405 	struct via686a_data *data = via686a_update_device(dev);
406 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
407 	int nr = attr->index;
408 	return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr]));
409 }
410 static ssize_t show_temp_over(struct device *dev, struct device_attribute *da,
411 		char *buf) {
412 	struct via686a_data *data = via686a_update_device(dev);
413 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
414 	int nr = attr->index;
415 	return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr]));
416 }
417 static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da,
418 		char *buf) {
419 	struct via686a_data *data = via686a_update_device(dev);
420 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
421 	int nr = attr->index;
422 	return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr]));
423 }
424 static ssize_t set_temp_over(struct device *dev, struct device_attribute *da,
425 		const char *buf, size_t count) {
426 	struct via686a_data *data = dev_get_drvdata(dev);
427 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
428 	int nr = attr->index;
429 	int val = simple_strtol(buf, NULL, 10);
430 
431 	mutex_lock(&data->update_lock);
432 	data->temp_over[nr] = TEMP_TO_REG(val);
433 	via686a_write_value(data, VIA686A_REG_TEMP_OVER[nr],
434 			    data->temp_over[nr]);
435 	mutex_unlock(&data->update_lock);
436 	return count;
437 }
438 static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da,
439 		const char *buf, size_t count) {
440 	struct via686a_data *data = dev_get_drvdata(dev);
441 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
442 	int nr = attr->index;
443 	int val = simple_strtol(buf, NULL, 10);
444 
445 	mutex_lock(&data->update_lock);
446 	data->temp_hyst[nr] = TEMP_TO_REG(val);
447 	via686a_write_value(data, VIA686A_REG_TEMP_HYST[nr],
448 			    data->temp_hyst[nr]);
449 	mutex_unlock(&data->update_lock);
450 	return count;
451 }
452 #define show_temp_offset(offset)					\
453 static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,		\
454 		show_temp, NULL, offset - 1);				\
455 static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,	\
456 		show_temp_over, set_temp_over, offset - 1);		\
457 static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR,	\
458 		show_temp_hyst, set_temp_hyst, offset - 1);
459 
460 show_temp_offset(1);
461 show_temp_offset(2);
462 show_temp_offset(3);
463 
464 /* 2 Fans */
465 static ssize_t show_fan(struct device *dev, struct device_attribute *da,
466 		char *buf) {
467 	struct via686a_data *data = via686a_update_device(dev);
468 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
469 	int nr = attr->index;
470 	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
471 				DIV_FROM_REG(data->fan_div[nr])) );
472 }
473 static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
474 		char *buf) {
475 	struct via686a_data *data = via686a_update_device(dev);
476 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
477 	int nr = attr->index;
478 	return sprintf(buf, "%d\n",
479 		FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) );
480 }
481 static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
482 		char *buf) {
483 	struct via686a_data *data = via686a_update_device(dev);
484 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
485 	int nr = attr->index;
486 	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
487 }
488 static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
489 		const char *buf, size_t count) {
490 	struct via686a_data *data = dev_get_drvdata(dev);
491 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
492 	int nr = attr->index;
493 	int val = simple_strtol(buf, NULL, 10);
494 
495 	mutex_lock(&data->update_lock);
496 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
497 	via686a_write_value(data, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]);
498 	mutex_unlock(&data->update_lock);
499 	return count;
500 }
501 static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
502 		const char *buf, size_t count) {
503 	struct via686a_data *data = dev_get_drvdata(dev);
504 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
505 	int nr = attr->index;
506 	int val = simple_strtol(buf, NULL, 10);
507 	int old;
508 
509 	mutex_lock(&data->update_lock);
510 	old = via686a_read_value(data, VIA686A_REG_FANDIV);
511 	data->fan_div[nr] = DIV_TO_REG(val);
512 	old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
513 	via686a_write_value(data, VIA686A_REG_FANDIV, old);
514 	mutex_unlock(&data->update_lock);
515 	return count;
516 }
517 
518 #define show_fan_offset(offset)						\
519 static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,			\
520 		show_fan, NULL, offset - 1);				\
521 static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
522 		show_fan_min, set_fan_min, offset - 1);			\
523 static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,		\
524 		show_fan_div, set_fan_div, offset - 1);
525 
526 show_fan_offset(1);
527 show_fan_offset(2);
528 
529 /* Alarms */
530 static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) {
531 	struct via686a_data *data = via686a_update_device(dev);
532 	return sprintf(buf, "%u\n", data->alarms);
533 }
534 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
535 
536 static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
537 			  char *buf)
538 {
539 	int bitnr = to_sensor_dev_attr(attr)->index;
540 	struct via686a_data *data = via686a_update_device(dev);
541 	return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
542 }
543 static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
544 static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
545 static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
546 static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
547 static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
548 static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
549 static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11);
550 static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 15);
551 static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
552 static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
553 
554 static ssize_t show_name(struct device *dev, struct device_attribute
555 			 *devattr, char *buf)
556 {
557 	struct via686a_data *data = dev_get_drvdata(dev);
558 	return sprintf(buf, "%s\n", data->name);
559 }
560 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
561 
562 static struct attribute *via686a_attributes[] = {
563 	&sensor_dev_attr_in0_input.dev_attr.attr,
564 	&sensor_dev_attr_in1_input.dev_attr.attr,
565 	&sensor_dev_attr_in2_input.dev_attr.attr,
566 	&sensor_dev_attr_in3_input.dev_attr.attr,
567 	&sensor_dev_attr_in4_input.dev_attr.attr,
568 	&sensor_dev_attr_in0_min.dev_attr.attr,
569 	&sensor_dev_attr_in1_min.dev_attr.attr,
570 	&sensor_dev_attr_in2_min.dev_attr.attr,
571 	&sensor_dev_attr_in3_min.dev_attr.attr,
572 	&sensor_dev_attr_in4_min.dev_attr.attr,
573 	&sensor_dev_attr_in0_max.dev_attr.attr,
574 	&sensor_dev_attr_in1_max.dev_attr.attr,
575 	&sensor_dev_attr_in2_max.dev_attr.attr,
576 	&sensor_dev_attr_in3_max.dev_attr.attr,
577 	&sensor_dev_attr_in4_max.dev_attr.attr,
578 	&sensor_dev_attr_in0_alarm.dev_attr.attr,
579 	&sensor_dev_attr_in1_alarm.dev_attr.attr,
580 	&sensor_dev_attr_in2_alarm.dev_attr.attr,
581 	&sensor_dev_attr_in3_alarm.dev_attr.attr,
582 	&sensor_dev_attr_in4_alarm.dev_attr.attr,
583 
584 	&sensor_dev_attr_temp1_input.dev_attr.attr,
585 	&sensor_dev_attr_temp2_input.dev_attr.attr,
586 	&sensor_dev_attr_temp3_input.dev_attr.attr,
587 	&sensor_dev_attr_temp1_max.dev_attr.attr,
588 	&sensor_dev_attr_temp2_max.dev_attr.attr,
589 	&sensor_dev_attr_temp3_max.dev_attr.attr,
590 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
591 	&sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
592 	&sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
593 	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
594 	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
595 	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
596 
597 	&sensor_dev_attr_fan1_input.dev_attr.attr,
598 	&sensor_dev_attr_fan2_input.dev_attr.attr,
599 	&sensor_dev_attr_fan1_min.dev_attr.attr,
600 	&sensor_dev_attr_fan2_min.dev_attr.attr,
601 	&sensor_dev_attr_fan1_div.dev_attr.attr,
602 	&sensor_dev_attr_fan2_div.dev_attr.attr,
603 	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
604 	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
605 
606 	&dev_attr_alarms.attr,
607 	&dev_attr_name.attr,
608 	NULL
609 };
610 
611 static const struct attribute_group via686a_group = {
612 	.attrs = via686a_attributes,
613 };
614 
615 static struct platform_driver via686a_driver = {
616 	.driver = {
617 		.owner	= THIS_MODULE,
618 		.name	= "via686a",
619 	},
620 	.probe		= via686a_probe,
621 	.remove		= __devexit_p(via686a_remove),
622 };
623 
624 
625 /* This is called when the module is loaded */
626 static int __devinit via686a_probe(struct platform_device *pdev)
627 {
628 	struct via686a_data *data;
629 	struct resource *res;
630 	int err;
631 
632 	/* Reserve the ISA region */
633 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
634 	if (!request_region(res->start, VIA686A_EXTENT,
635 			    via686a_driver.driver.name)) {
636 		dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n",
637 			(unsigned long)res->start, (unsigned long)res->end);
638 		return -ENODEV;
639 	}
640 
641 	if (!(data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
642 		err = -ENOMEM;
643 		goto exit_release;
644 	}
645 
646 	platform_set_drvdata(pdev, data);
647 	data->addr = res->start;
648 	data->name = "via686a";
649 	mutex_init(&data->update_lock);
650 
651 	/* Initialize the VIA686A chip */
652 	via686a_init_device(data);
653 
654 	/* Register sysfs hooks */
655 	if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group)))
656 		goto exit_free;
657 
658 	data->hwmon_dev = hwmon_device_register(&pdev->dev);
659 	if (IS_ERR(data->hwmon_dev)) {
660 		err = PTR_ERR(data->hwmon_dev);
661 		goto exit_remove_files;
662 	}
663 
664 	return 0;
665 
666 exit_remove_files:
667 	sysfs_remove_group(&pdev->dev.kobj, &via686a_group);
668 exit_free:
669 	kfree(data);
670 exit_release:
671 	release_region(res->start, VIA686A_EXTENT);
672 	return err;
673 }
674 
675 static int __devexit via686a_remove(struct platform_device *pdev)
676 {
677 	struct via686a_data *data = platform_get_drvdata(pdev);
678 
679 	hwmon_device_unregister(data->hwmon_dev);
680 	sysfs_remove_group(&pdev->dev.kobj, &via686a_group);
681 
682 	release_region(data->addr, VIA686A_EXTENT);
683 	platform_set_drvdata(pdev, NULL);
684 	kfree(data);
685 
686 	return 0;
687 }
688 
689 static void __devinit via686a_init_device(struct via686a_data *data)
690 {
691 	u8 reg;
692 
693 	/* Start monitoring */
694 	reg = via686a_read_value(data, VIA686A_REG_CONFIG);
695 	via686a_write_value(data, VIA686A_REG_CONFIG, (reg | 0x01) & 0x7F);
696 
697 	/* Configure temp interrupt mode for continuous-interrupt operation */
698 	reg = via686a_read_value(data, VIA686A_REG_TEMP_MODE);
699 	via686a_write_value(data, VIA686A_REG_TEMP_MODE,
700 			    (reg & ~VIA686A_TEMP_MODE_MASK)
701 			    | VIA686A_TEMP_MODE_CONTINUOUS);
702 }
703 
704 static struct via686a_data *via686a_update_device(struct device *dev)
705 {
706 	struct via686a_data *data = dev_get_drvdata(dev);
707 	int i;
708 
709 	mutex_lock(&data->update_lock);
710 
711 	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
712 	    || !data->valid) {
713 		for (i = 0; i <= 4; i++) {
714 			data->in[i] =
715 			    via686a_read_value(data, VIA686A_REG_IN(i));
716 			data->in_min[i] = via686a_read_value(data,
717 							     VIA686A_REG_IN_MIN
718 							     (i));
719 			data->in_max[i] =
720 			    via686a_read_value(data, VIA686A_REG_IN_MAX(i));
721 		}
722 		for (i = 1; i <= 2; i++) {
723 			data->fan[i - 1] =
724 			    via686a_read_value(data, VIA686A_REG_FAN(i));
725 			data->fan_min[i - 1] = via686a_read_value(data,
726 						     VIA686A_REG_FAN_MIN(i));
727 		}
728 		for (i = 0; i <= 2; i++) {
729 			data->temp[i] = via686a_read_value(data,
730 						 VIA686A_REG_TEMP[i]) << 2;
731 			data->temp_over[i] =
732 			    via686a_read_value(data,
733 					       VIA686A_REG_TEMP_OVER[i]);
734 			data->temp_hyst[i] =
735 			    via686a_read_value(data,
736 					       VIA686A_REG_TEMP_HYST[i]);
737 		}
738 		/* add in lower 2 bits
739 		   temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1
740 		   temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23
741 		   temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23
742 		 */
743 		data->temp[0] |= (via686a_read_value(data,
744 						     VIA686A_REG_TEMP_LOW1)
745 				  & 0xc0) >> 6;
746 		data->temp[1] |=
747 		    (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) &
748 		     0x30) >> 4;
749 		data->temp[2] |=
750 		    (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) &
751 		     0xc0) >> 6;
752 
753 		i = via686a_read_value(data, VIA686A_REG_FANDIV);
754 		data->fan_div[0] = (i >> 4) & 0x03;
755 		data->fan_div[1] = i >> 6;
756 		data->alarms =
757 		    via686a_read_value(data,
758 				       VIA686A_REG_ALARM1) |
759 		    (via686a_read_value(data, VIA686A_REG_ALARM2) << 8);
760 		data->last_updated = jiffies;
761 		data->valid = 1;
762 	}
763 
764 	mutex_unlock(&data->update_lock);
765 
766 	return data;
767 }
768 
769 static struct pci_device_id via686a_pci_ids[] = {
770 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
771 	{ 0, }
772 };
773 
774 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
775 
776 static int __devinit via686a_device_add(unsigned short address)
777 {
778 	struct resource res = {
779 		.start	= address,
780 		.end	= address + VIA686A_EXTENT - 1,
781 		.name	= "via686a",
782 		.flags	= IORESOURCE_IO,
783 	};
784 	int err;
785 
786 	pdev = platform_device_alloc("via686a", address);
787 	if (!pdev) {
788 		err = -ENOMEM;
789 		printk(KERN_ERR "via686a: Device allocation failed\n");
790 		goto exit;
791 	}
792 
793 	err = platform_device_add_resources(pdev, &res, 1);
794 	if (err) {
795 		printk(KERN_ERR "via686a: Device resource addition failed "
796 		       "(%d)\n", err);
797 		goto exit_device_put;
798 	}
799 
800 	err = platform_device_add(pdev);
801 	if (err) {
802 		printk(KERN_ERR "via686a: Device addition failed (%d)\n",
803 		       err);
804 		goto exit_device_put;
805 	}
806 
807 	return 0;
808 
809 exit_device_put:
810 	platform_device_put(pdev);
811 exit:
812 	return err;
813 }
814 
815 static int __devinit via686a_pci_probe(struct pci_dev *dev,
816 				       const struct pci_device_id *id)
817 {
818 	u16 address, val;
819 
820 	if (force_addr) {
821 		address = force_addr & ~(VIA686A_EXTENT - 1);
822 		dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", address);
823 		if (PCIBIOS_SUCCESSFUL !=
824 		    pci_write_config_word(dev, VIA686A_BASE_REG, address | 1))
825 			return -ENODEV;
826 	}
827 	if (PCIBIOS_SUCCESSFUL !=
828 	    pci_read_config_word(dev, VIA686A_BASE_REG, &val))
829 		return -ENODEV;
830 
831 	address = val & ~(VIA686A_EXTENT - 1);
832 	if (address == 0) {
833 		dev_err(&dev->dev, "base address not set - upgrade BIOS "
834 			"or use force_addr=0xaddr\n");
835 		return -ENODEV;
836 	}
837 
838 	if (PCIBIOS_SUCCESSFUL !=
839 	    pci_read_config_word(dev, VIA686A_ENABLE_REG, &val))
840 		return -ENODEV;
841 	if (!(val & 0x0001)) {
842 		if (!force_addr) {
843 			dev_warn(&dev->dev, "Sensors disabled, enable "
844 				 "with force_addr=0x%x\n", address);
845 			return -ENODEV;
846 		}
847 
848 		dev_warn(&dev->dev, "Enabling sensors\n");
849 		if (PCIBIOS_SUCCESSFUL !=
850 		    pci_write_config_word(dev, VIA686A_ENABLE_REG,
851 					  val | 0x0001))
852 			return -ENODEV;
853 	}
854 
855 	if (platform_driver_register(&via686a_driver))
856 		goto exit;
857 
858 	/* Sets global pdev as a side effect */
859 	if (via686a_device_add(address))
860 		goto exit_unregister;
861 
862 	/* Always return failure here.  This is to allow other drivers to bind
863 	 * to this pci device.  We don't really want to have control over the
864 	 * pci device, we only wanted to read as few register values from it.
865 	 */
866 	s_bridge = pci_dev_get(dev);
867 	return -ENODEV;
868 
869 exit_unregister:
870 	platform_driver_unregister(&via686a_driver);
871 exit:
872 	return -ENODEV;
873 }
874 
875 static struct pci_driver via686a_pci_driver = {
876 	.name		= "via686a",
877 	.id_table	= via686a_pci_ids,
878 	.probe		= via686a_pci_probe,
879 };
880 
881 static int __init sm_via686a_init(void)
882 {
883 	return pci_register_driver(&via686a_pci_driver);
884 }
885 
886 static void __exit sm_via686a_exit(void)
887 {
888 	pci_unregister_driver(&via686a_pci_driver);
889 	if (s_bridge != NULL) {
890 		platform_device_unregister(pdev);
891 		platform_driver_unregister(&via686a_driver);
892 		pci_dev_put(s_bridge);
893 		s_bridge = NULL;
894 	}
895 }
896 
897 MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>, "
898 	      "Mark Studebaker <mdsxyz123@yahoo.com> "
899 	      "and Bob Dougherty <bobd@stanford.edu>");
900 MODULE_DESCRIPTION("VIA 686A Sensor device");
901 MODULE_LICENSE("GPL");
902 
903 module_init(sm_via686a_init);
904 module_exit(sm_via686a_exit);
905