1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
48
49static unsigned short force_addr;
50module_param(force_addr, ushort, 0);
51MODULE_PARM_DESC(force_addr,
52 "Initialize the base address of the sensors");
53
54static struct platform_device *pdev;
55
56
57
58
59
60
61
62
63
64#define VIA686A_EXTENT 0x80
65#define VIA686A_BASE_REG 0x70
66#define VIA686A_ENABLE_REG 0x74
67
68
69
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
75#define VIA686A_REG_FAN_MIN(nr) (0x3a + (nr))
76#define VIA686A_REG_FAN(nr) (0x28 + (nr))
77
78
79static const u8 VIA686A_REG_TEMP[] = { 0x20, 0x21, 0x1f };
80static const u8 VIA686A_REG_TEMP_OVER[] = { 0x39, 0x3d, 0x1d };
81static const u8 VIA686A_REG_TEMP_HYST[] = { 0x3a, 0x3e, 0x1e };
82
83#define VIA686A_REG_TEMP_LOW1 0x4b
84
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
92
93
94
95
96
97#define VIA686A_REG_TEMP_MODE 0x4b
98
99#define VIA686A_TEMP_MODE_MASK 0x3F
100#define VIA686A_TEMP_MODE_CONTINUOUS 0x00
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118static inline u8 IN_TO_REG(long val, int inNum)
119{
120
121
122
123
124
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
139static inline long IN_FROM_REG(u8 val, int inNum)
140{
141
142
143
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
155
156
157
158static 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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200static 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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246static 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
263
264
265static 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
272#define TEMP_FROM_REG(val) ((long)tempLUT[val] * 100)
273
274
275static inline long TEMP_FROM_REG10(u16 val)
276{
277 u16 eightBits = val >> 2;
278 u16 twoBits = val & 3;
279
280
281 if (twoBits == 0 || eightBits == 255)
282 return TEMP_FROM_REG(eightBits);
283
284
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
293
294struct via686a_data {
295 unsigned short addr;
296 const char *name;
297 struct device *hwmon_dev;
298 struct mutex update_lock;
299 char valid;
300 unsigned long last_updated;
301
302 u8 in[5];
303 u8 in_max[5];
304 u8 in_min[5];
305 u8 fan[2];
306 u8 fan_min[2];
307 u16 temp[3];
308 u8 temp_over[3];
309 u8 temp_hyst[3];
310 u8 fan_div[2];
311 u16 alarms;
312};
313
314static struct pci_dev *s_bridge;
315
316static int via686a_probe(struct platform_device *pdev);
317static int __devexit via686a_remove(struct platform_device *pdev);
318
319static inline int via686a_read_value(struct via686a_data *data, u8 reg)
320{
321 return inb_p(data->addr + reg);
322}
323
324static inline void via686a_write_value(struct via686a_data *data, u8 reg,
325 u8 value)
326{
327 outb_p(value, data->addr + reg);
328}
329
330static struct via686a_data *via686a_update_device(struct device *dev);
331static void via686a_init_device(struct via686a_data *data);
332
333
334
335
336static 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
344static 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
352static 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
360static 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}
374static 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) \
389static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
390 show_in, NULL, offset); \
391static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
392 show_in_min, set_in_min, offset); \
393static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
394 show_in_max, set_in_max, offset);
395
396show_in_offset(0);
397show_in_offset(1);
398show_in_offset(2);
399show_in_offset(3);
400show_in_offset(4);
401
402
403static 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}
410static 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}
417static 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}
424static 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}
438static 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) \
453static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
454 show_temp, NULL, offset - 1); \
455static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
456 show_temp_over, set_temp_over, offset - 1); \
457static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \
458 show_temp_hyst, set_temp_hyst, offset - 1);
459
460show_temp_offset(1);
461show_temp_offset(2);
462show_temp_offset(3);
463
464
465static 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}
473static 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}
481static 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}
488static 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}
501static 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) \
519static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
520 show_fan, NULL, offset - 1); \
521static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
522 show_fan_min, set_fan_min, offset - 1); \
523static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
524 show_fan_div, set_fan_div, offset - 1);
525
526show_fan_offset(1);
527show_fan_offset(2);
528
529
530static 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}
534static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
535
536static 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}
543static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
544static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
545static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
546static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
547static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
548static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
549static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11);
550static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 15);
551static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
552static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
553
554static 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}
560static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
561
562static 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
611static const struct attribute_group via686a_group = {
612 .attrs = via686a_attributes,
613};
614
615static 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
626static int __devinit via686a_probe(struct platform_device *pdev)
627{
628 struct via686a_data *data;
629 struct resource *res;
630 int err;
631
632
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
652 via686a_init_device(data);
653
654
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
666exit_remove_files:
667 sysfs_remove_group(&pdev->dev.kobj, &via686a_group);
668exit_free:
669 kfree(data);
670exit_release:
671 release_region(res->start, VIA686A_EXTENT);
672 return err;
673}
674
675static 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
689static void __devinit via686a_init_device(struct via686a_data *data)
690{
691 u8 reg;
692
693
694 reg = via686a_read_value(data, VIA686A_REG_CONFIG);
695 via686a_write_value(data, VIA686A_REG_CONFIG, (reg | 0x01) & 0x7F);
696
697
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
704static 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
739
740
741
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
769static struct pci_device_id via686a_pci_ids[] = {
770 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
771 { 0, }
772};
773
774MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
775
776static 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
809exit_device_put:
810 platform_device_put(pdev);
811exit:
812 return err;
813}
814
815static 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
859 if (via686a_device_add(address))
860 goto exit_unregister;
861
862
863
864
865
866 s_bridge = pci_dev_get(dev);
867 return -ENODEV;
868
869exit_unregister:
870 platform_driver_unregister(&via686a_driver);
871exit:
872 return -ENODEV;
873}
874
875static struct pci_driver via686a_pci_driver = {
876 .name = "via686a",
877 .id_table = via686a_pci_ids,
878 .probe = via686a_pci_probe,
879};
880
881static int __init sm_via686a_init(void)
882{
883 return pci_register_driver(&via686a_pci_driver);
884}
885
886static 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
897MODULE_AUTHOR("Ky��sti M��lkki <kmalkki@cc.hut.fi>, "
898 "Mark Studebaker <mdsxyz123@yahoo.com> "
899 "and Bob Dougherty <bobd@stanford.edu>");
900MODULE_DESCRIPTION("VIA 686A Sensor device");
901MODULE_LICENSE("GPL");
902
903module_init(sm_via686a_init);
904module_exit(sm_via686a_exit);