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