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 <linux/acpi.h>
45#include <linux/io.h>
46
47
48
49
50static unsigned short force_addr;
51module_param(force_addr, ushort, 0);
52MODULE_PARM_DESC(force_addr,
53 "Initialize the base address of the sensors");
54
55static struct platform_device *pdev;
56
57
58
59
60
61
62
63
64
65#define VIA686A_EXTENT 0x80
66#define VIA686A_BASE_REG 0x70
67#define VIA686A_ENABLE_REG 0x74
68
69
70
71#define VIA686A_REG_IN_MAX(nr) (0x2b + ((nr) * 2))
72#define VIA686A_REG_IN_MIN(nr) (0x2c + ((nr) * 2))
73#define VIA686A_REG_IN(nr) (0x22 + (nr))
74
75
76#define VIA686A_REG_FAN_MIN(nr) (0x3a + (nr))
77#define VIA686A_REG_FAN(nr) (0x28 + (nr))
78
79
80static const u8 VIA686A_REG_TEMP[] = { 0x20, 0x21, 0x1f };
81static const u8 VIA686A_REG_TEMP_OVER[] = { 0x39, 0x3d, 0x1d };
82static const u8 VIA686A_REG_TEMP_HYST[] = { 0x3a, 0x3e, 0x1e };
83
84#define VIA686A_REG_TEMP_LOW1 0x4b
85
86#define VIA686A_REG_TEMP_LOW23 0x49
87
88#define VIA686A_REG_ALARM1 0x41
89#define VIA686A_REG_ALARM2 0x42
90#define VIA686A_REG_FANDIV 0x47
91#define VIA686A_REG_CONFIG 0x40
92
93
94
95
96
97
98#define VIA686A_REG_TEMP_MODE 0x4b
99
100#define VIA686A_TEMP_MODE_MASK 0x3F
101#define VIA686A_TEMP_MODE_CONTINUOUS 0x00
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119static inline u8 IN_TO_REG(long val, int inNum)
120{
121
122
123
124
125
126 if (inNum <= 1)
127 return (u8)
128 SENSORS_LIMIT((val * 21024 - 1205000) / 250000, 0, 255);
129 else if (inNum == 2)
130 return (u8)
131 SENSORS_LIMIT((val * 15737 - 1205000) / 250000, 0, 255);
132 else if (inNum == 3)
133 return (u8)
134 SENSORS_LIMIT((val * 10108 - 1205000) / 250000, 0, 255);
135 else
136 return (u8)
137 SENSORS_LIMIT((val * 41714 - 12050000) / 2500000, 0, 255);
138}
139
140static inline long IN_FROM_REG(u8 val, int inNum)
141{
142
143
144
145 if (inNum <= 1)
146 return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024);
147 else if (inNum == 2)
148 return (long) ((250000 * val + 1330000 + 15737 / 2) / 15737);
149 else if (inNum == 3)
150 return (long) ((250000 * val + 1330000 + 10108 / 2) / 10108);
151 else
152 return (long) ((2500000 * val + 13300000 + 41714 / 2) / 41714);
153}
154
155
156
157
158
159static inline u8 FAN_TO_REG(long rpm, int div)
160{
161 if (rpm == 0)
162 return 0;
163 rpm = SENSORS_LIMIT(rpm, 1, 1000000);
164 return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 255);
165}
166
167#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1350000/((val)*(div)))
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
200
201static const s16 tempLUT[] =
202{ -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
203 -503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
204 -362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
205 -255, -246, -237, -229, -220, -212, -204, -196, -188, -180,
206 -173, -166, -159, -152, -145, -139, -132, -126, -120, -114,
207 -108, -102, -96, -91, -85, -80, -74, -69, -64, -59, -54, -49,
208 -44, -39, -34, -29, -25, -20, -15, -11, -6, -2, 3, 7, 12, 16,
209 20, 25, 29, 33, 37, 42, 46, 50, 54, 59, 63, 67, 71, 75, 79, 84,
210 88, 92, 96, 100, 104, 109, 113, 117, 121, 125, 130, 134, 138,
211 142, 146, 151, 155, 159, 163, 168, 172, 176, 181, 185, 189,
212 193, 198, 202, 206, 211, 215, 219, 224, 228, 232, 237, 241,
213 245, 250, 254, 259, 263, 267, 272, 276, 281, 285, 290, 294,
214 299, 303, 307, 312, 316, 321, 325, 330, 334, 339, 344, 348,
215 353, 357, 362, 366, 371, 376, 380, 385, 390, 395, 399, 404,
216 409, 414, 419, 423, 428, 433, 438, 443, 449, 454, 459, 464,
217 469, 475, 480, 486, 491, 497, 502, 508, 514, 520, 526, 532,
218 538, 544, 551, 557, 564, 571, 578, 584, 592, 599, 606, 614,
219 621, 629, 637, 645, 654, 662, 671, 680, 689, 698, 708, 718,
220 728, 738, 749, 759, 770, 782, 793, 805, 818, 830, 843, 856,
221 870, 883, 898, 912, 927, 943, 958, 975, 991, 1008, 1026, 1044,
222 1062, 1081, 1101, 1121, 1141, 1162, 1184, 1206, 1229, 1252,
223 1276, 1301, 1326, 1352, 1378, 1406, 1434, 1462
224};
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247static const u8 viaLUT[] =
248{ 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23,
249 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40,
250 41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66,
251 69, 71, 73, 75, 77, 79, 82, 84, 86, 88, 91, 93, 95, 98, 100,
252 103, 105, 107, 110, 112, 115, 117, 119, 122, 124, 126, 129,
253 131, 134, 136, 138, 140, 143, 145, 147, 150, 152, 154, 156,
254 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180,
255 182, 183, 185, 187, 188, 190, 192, 193, 195, 196, 198, 199,
256 200, 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, 213,
257 214, 215, 216, 217, 218, 219, 220, 221, 222, 222, 223, 224,
258 225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232,
259 233, 233, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239,
260 239, 240
261};
262
263
264
265
266static inline u8 TEMP_TO_REG(long val)
267{
268 return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 :
269 (val < 0 ? val - 500 : val + 500) / 1000 + 50];
270}
271
272
273#define TEMP_FROM_REG(val) ((long)tempLUT[val] * 100)
274
275
276static inline long TEMP_FROM_REG10(u16 val)
277{
278 u16 eightBits = val >> 2;
279 u16 twoBits = val & 3;
280
281
282 if (twoBits == 0 || eightBits == 255)
283 return TEMP_FROM_REG(eightBits);
284
285
286 return (tempLUT[eightBits] * (4 - twoBits) +
287 tempLUT[eightBits + 1] * twoBits) * 25;
288}
289
290#define DIV_FROM_REG(val) (1 << (val))
291#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
292
293
294
295struct via686a_data {
296 unsigned short addr;
297 const char *name;
298 struct device *hwmon_dev;
299 struct mutex update_lock;
300 char valid;
301 unsigned long last_updated;
302
303 u8 in[5];
304 u8 in_max[5];
305 u8 in_min[5];
306 u8 fan[2];
307 u8 fan_min[2];
308 u16 temp[3];
309 u8 temp_over[3];
310 u8 temp_hyst[3];
311 u8 fan_div[2];
312 u16 alarms;
313};
314
315static struct pci_dev *s_bridge;
316
317static int via686a_probe(struct platform_device *pdev);
318static int __devexit via686a_remove(struct platform_device *pdev);
319
320static inline int via686a_read_value(struct via686a_data *data, u8 reg)
321{
322 return inb_p(data->addr + reg);
323}
324
325static inline void via686a_write_value(struct via686a_data *data, u8 reg,
326 u8 value)
327{
328 outb_p(value, data->addr + reg);
329}
330
331static struct via686a_data *via686a_update_device(struct device *dev);
332static void via686a_init_device(struct via686a_data *data);
333
334
335
336
337static ssize_t show_in(struct device *dev, struct device_attribute *da,
338 char *buf) {
339 struct via686a_data *data = via686a_update_device(dev);
340 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
341 int nr = attr->index;
342 return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr));
343}
344
345static ssize_t show_in_min(struct device *dev, struct device_attribute *da,
346 char *buf) {
347 struct via686a_data *data = via686a_update_device(dev);
348 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
349 int nr = attr->index;
350 return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr));
351}
352
353static ssize_t show_in_max(struct device *dev, struct device_attribute *da,
354 char *buf) {
355 struct via686a_data *data = via686a_update_device(dev);
356 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
357 int nr = attr->index;
358 return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr));
359}
360
361static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
362 const char *buf, size_t count) {
363 struct via686a_data *data = dev_get_drvdata(dev);
364 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
365 int nr = attr->index;
366 unsigned long val = simple_strtoul(buf, NULL, 10);
367
368 mutex_lock(&data->update_lock);
369 data->in_min[nr] = IN_TO_REG(val, nr);
370 via686a_write_value(data, VIA686A_REG_IN_MIN(nr),
371 data->in_min[nr]);
372 mutex_unlock(&data->update_lock);
373 return count;
374}
375static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
376 const char *buf, size_t count) {
377 struct via686a_data *data = dev_get_drvdata(dev);
378 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
379 int nr = attr->index;
380 unsigned long val = simple_strtoul(buf, NULL, 10);
381
382 mutex_lock(&data->update_lock);
383 data->in_max[nr] = IN_TO_REG(val, nr);
384 via686a_write_value(data, VIA686A_REG_IN_MAX(nr),
385 data->in_max[nr]);
386 mutex_unlock(&data->update_lock);
387 return count;
388}
389#define show_in_offset(offset) \
390static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
391 show_in, NULL, offset); \
392static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
393 show_in_min, set_in_min, offset); \
394static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
395 show_in_max, set_in_max, offset);
396
397show_in_offset(0);
398show_in_offset(1);
399show_in_offset(2);
400show_in_offset(3);
401show_in_offset(4);
402
403
404static ssize_t show_temp(struct device *dev, struct device_attribute *da,
405 char *buf) {
406 struct via686a_data *data = via686a_update_device(dev);
407 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
408 int nr = attr->index;
409 return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr]));
410}
411static ssize_t show_temp_over(struct device *dev, struct device_attribute *da,
412 char *buf) {
413 struct via686a_data *data = via686a_update_device(dev);
414 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
415 int nr = attr->index;
416 return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr]));
417}
418static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da,
419 char *buf) {
420 struct via686a_data *data = via686a_update_device(dev);
421 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
422 int nr = attr->index;
423 return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr]));
424}
425static ssize_t set_temp_over(struct device *dev, struct device_attribute *da,
426 const char *buf, size_t count) {
427 struct via686a_data *data = dev_get_drvdata(dev);
428 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
429 int nr = attr->index;
430 int val = simple_strtol(buf, NULL, 10);
431
432 mutex_lock(&data->update_lock);
433 data->temp_over[nr] = TEMP_TO_REG(val);
434 via686a_write_value(data, VIA686A_REG_TEMP_OVER[nr],
435 data->temp_over[nr]);
436 mutex_unlock(&data->update_lock);
437 return count;
438}
439static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da,
440 const char *buf, size_t count) {
441 struct via686a_data *data = dev_get_drvdata(dev);
442 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
443 int nr = attr->index;
444 int val = simple_strtol(buf, NULL, 10);
445
446 mutex_lock(&data->update_lock);
447 data->temp_hyst[nr] = TEMP_TO_REG(val);
448 via686a_write_value(data, VIA686A_REG_TEMP_HYST[nr],
449 data->temp_hyst[nr]);
450 mutex_unlock(&data->update_lock);
451 return count;
452}
453#define show_temp_offset(offset) \
454static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
455 show_temp, NULL, offset - 1); \
456static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
457 show_temp_over, set_temp_over, offset - 1); \
458static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \
459 show_temp_hyst, set_temp_hyst, offset - 1);
460
461show_temp_offset(1);
462show_temp_offset(2);
463show_temp_offset(3);
464
465
466static ssize_t show_fan(struct device *dev, struct device_attribute *da,
467 char *buf) {
468 struct via686a_data *data = via686a_update_device(dev);
469 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
470 int nr = attr->index;
471 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
472 DIV_FROM_REG(data->fan_div[nr])) );
473}
474static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
475 char *buf) {
476 struct via686a_data *data = via686a_update_device(dev);
477 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
478 int nr = attr->index;
479 return sprintf(buf, "%d\n",
480 FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) );
481}
482static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
483 char *buf) {
484 struct via686a_data *data = via686a_update_device(dev);
485 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
486 int nr = attr->index;
487 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
488}
489static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
490 const char *buf, size_t count) {
491 struct via686a_data *data = dev_get_drvdata(dev);
492 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
493 int nr = attr->index;
494 int val = simple_strtol(buf, NULL, 10);
495
496 mutex_lock(&data->update_lock);
497 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
498 via686a_write_value(data, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]);
499 mutex_unlock(&data->update_lock);
500 return count;
501}
502static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
503 const char *buf, size_t count) {
504 struct via686a_data *data = dev_get_drvdata(dev);
505 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
506 int nr = attr->index;
507 int val = simple_strtol(buf, NULL, 10);
508 int old;
509
510 mutex_lock(&data->update_lock);
511 old = via686a_read_value(data, VIA686A_REG_FANDIV);
512 data->fan_div[nr] = DIV_TO_REG(val);
513 old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
514 via686a_write_value(data, VIA686A_REG_FANDIV, old);
515 mutex_unlock(&data->update_lock);
516 return count;
517}
518
519#define show_fan_offset(offset) \
520static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
521 show_fan, NULL, offset - 1); \
522static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
523 show_fan_min, set_fan_min, offset - 1); \
524static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
525 show_fan_div, set_fan_div, offset - 1);
526
527show_fan_offset(1);
528show_fan_offset(2);
529
530
531static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) {
532 struct via686a_data *data = via686a_update_device(dev);
533 return sprintf(buf, "%u\n", data->alarms);
534}
535static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
536
537static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
538 char *buf)
539{
540 int bitnr = to_sensor_dev_attr(attr)->index;
541 struct via686a_data *data = via686a_update_device(dev);
542 return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
543}
544static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
545static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
546static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
547static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
548static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
549static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
550static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11);
551static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 15);
552static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
553static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
554
555static ssize_t show_name(struct device *dev, struct device_attribute
556 *devattr, char *buf)
557{
558 struct via686a_data *data = dev_get_drvdata(dev);
559 return sprintf(buf, "%s\n", data->name);
560}
561static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
562
563static struct attribute *via686a_attributes[] = {
564 &sensor_dev_attr_in0_input.dev_attr.attr,
565 &sensor_dev_attr_in1_input.dev_attr.attr,
566 &sensor_dev_attr_in2_input.dev_attr.attr,
567 &sensor_dev_attr_in3_input.dev_attr.attr,
568 &sensor_dev_attr_in4_input.dev_attr.attr,
569 &sensor_dev_attr_in0_min.dev_attr.attr,
570 &sensor_dev_attr_in1_min.dev_attr.attr,
571 &sensor_dev_attr_in2_min.dev_attr.attr,
572 &sensor_dev_attr_in3_min.dev_attr.attr,
573 &sensor_dev_attr_in4_min.dev_attr.attr,
574 &sensor_dev_attr_in0_max.dev_attr.attr,
575 &sensor_dev_attr_in1_max.dev_attr.attr,
576 &sensor_dev_attr_in2_max.dev_attr.attr,
577 &sensor_dev_attr_in3_max.dev_attr.attr,
578 &sensor_dev_attr_in4_max.dev_attr.attr,
579 &sensor_dev_attr_in0_alarm.dev_attr.attr,
580 &sensor_dev_attr_in1_alarm.dev_attr.attr,
581 &sensor_dev_attr_in2_alarm.dev_attr.attr,
582 &sensor_dev_attr_in3_alarm.dev_attr.attr,
583 &sensor_dev_attr_in4_alarm.dev_attr.attr,
584
585 &sensor_dev_attr_temp1_input.dev_attr.attr,
586 &sensor_dev_attr_temp2_input.dev_attr.attr,
587 &sensor_dev_attr_temp3_input.dev_attr.attr,
588 &sensor_dev_attr_temp1_max.dev_attr.attr,
589 &sensor_dev_attr_temp2_max.dev_attr.attr,
590 &sensor_dev_attr_temp3_max.dev_attr.attr,
591 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
592 &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
593 &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
594 &sensor_dev_attr_temp1_alarm.dev_attr.attr,
595 &sensor_dev_attr_temp2_alarm.dev_attr.attr,
596 &sensor_dev_attr_temp3_alarm.dev_attr.attr,
597
598 &sensor_dev_attr_fan1_input.dev_attr.attr,
599 &sensor_dev_attr_fan2_input.dev_attr.attr,
600 &sensor_dev_attr_fan1_min.dev_attr.attr,
601 &sensor_dev_attr_fan2_min.dev_attr.attr,
602 &sensor_dev_attr_fan1_div.dev_attr.attr,
603 &sensor_dev_attr_fan2_div.dev_attr.attr,
604 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
605 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
606
607 &dev_attr_alarms.attr,
608 &dev_attr_name.attr,
609 NULL
610};
611
612static const struct attribute_group via686a_group = {
613 .attrs = via686a_attributes,
614};
615
616static struct platform_driver via686a_driver = {
617 .driver = {
618 .owner = THIS_MODULE,
619 .name = "via686a",
620 },
621 .probe = via686a_probe,
622 .remove = __devexit_p(via686a_remove),
623};
624
625
626
627static int __devinit via686a_probe(struct platform_device *pdev)
628{
629 struct via686a_data *data;
630 struct resource *res;
631 int err;
632
633
634 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
635 if (!request_region(res->start, VIA686A_EXTENT,
636 via686a_driver.driver.name)) {
637 dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n",
638 (unsigned long)res->start, (unsigned long)res->end);
639 return -ENODEV;
640 }
641
642 if (!(data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
643 err = -ENOMEM;
644 goto exit_release;
645 }
646
647 platform_set_drvdata(pdev, data);
648 data->addr = res->start;
649 data->name = "via686a";
650 mutex_init(&data->update_lock);
651
652
653 via686a_init_device(data);
654
655
656 if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group)))
657 goto exit_free;
658
659 data->hwmon_dev = hwmon_device_register(&pdev->dev);
660 if (IS_ERR(data->hwmon_dev)) {
661 err = PTR_ERR(data->hwmon_dev);
662 goto exit_remove_files;
663 }
664
665 return 0;
666
667exit_remove_files:
668 sysfs_remove_group(&pdev->dev.kobj, &via686a_group);
669exit_free:
670 kfree(data);
671exit_release:
672 release_region(res->start, VIA686A_EXTENT);
673 return err;
674}
675
676static int __devexit via686a_remove(struct platform_device *pdev)
677{
678 struct via686a_data *data = platform_get_drvdata(pdev);
679
680 hwmon_device_unregister(data->hwmon_dev);
681 sysfs_remove_group(&pdev->dev.kobj, &via686a_group);
682
683 release_region(data->addr, VIA686A_EXTENT);
684 platform_set_drvdata(pdev, NULL);
685 kfree(data);
686
687 return 0;
688}
689
690static void __devinit via686a_init_device(struct via686a_data *data)
691{
692 u8 reg;
693
694
695 reg = via686a_read_value(data, VIA686A_REG_CONFIG);
696 via686a_write_value(data, VIA686A_REG_CONFIG, (reg | 0x01) & 0x7F);
697
698
699 reg = via686a_read_value(data, VIA686A_REG_TEMP_MODE);
700 via686a_write_value(data, VIA686A_REG_TEMP_MODE,
701 (reg & ~VIA686A_TEMP_MODE_MASK)
702 | VIA686A_TEMP_MODE_CONTINUOUS);
703}
704
705static struct via686a_data *via686a_update_device(struct device *dev)
706{
707 struct via686a_data *data = dev_get_drvdata(dev);
708 int i;
709
710 mutex_lock(&data->update_lock);
711
712 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
713 || !data->valid) {
714 for (i = 0; i <= 4; i++) {
715 data->in[i] =
716 via686a_read_value(data, VIA686A_REG_IN(i));
717 data->in_min[i] = via686a_read_value(data,
718 VIA686A_REG_IN_MIN
719 (i));
720 data->in_max[i] =
721 via686a_read_value(data, VIA686A_REG_IN_MAX(i));
722 }
723 for (i = 1; i <= 2; i++) {
724 data->fan[i - 1] =
725 via686a_read_value(data, VIA686A_REG_FAN(i));
726 data->fan_min[i - 1] = via686a_read_value(data,
727 VIA686A_REG_FAN_MIN(i));
728 }
729 for (i = 0; i <= 2; i++) {
730 data->temp[i] = via686a_read_value(data,
731 VIA686A_REG_TEMP[i]) << 2;
732 data->temp_over[i] =
733 via686a_read_value(data,
734 VIA686A_REG_TEMP_OVER[i]);
735 data->temp_hyst[i] =
736 via686a_read_value(data,
737 VIA686A_REG_TEMP_HYST[i]);
738 }
739
740
741
742
743
744 data->temp[0] |= (via686a_read_value(data,
745 VIA686A_REG_TEMP_LOW1)
746 & 0xc0) >> 6;
747 data->temp[1] |=
748 (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) &
749 0x30) >> 4;
750 data->temp[2] |=
751 (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) &
752 0xc0) >> 6;
753
754 i = via686a_read_value(data, VIA686A_REG_FANDIV);
755 data->fan_div[0] = (i >> 4) & 0x03;
756 data->fan_div[1] = i >> 6;
757 data->alarms =
758 via686a_read_value(data,
759 VIA686A_REG_ALARM1) |
760 (via686a_read_value(data, VIA686A_REG_ALARM2) << 8);
761 data->last_updated = jiffies;
762 data->valid = 1;
763 }
764
765 mutex_unlock(&data->update_lock);
766
767 return data;
768}
769
770static struct pci_device_id via686a_pci_ids[] = {
771 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
772 { 0, }
773};
774
775MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
776
777static int __devinit via686a_device_add(unsigned short address)
778{
779 struct resource res = {
780 .start = address,
781 .end = address + VIA686A_EXTENT - 1,
782 .name = "via686a",
783 .flags = IORESOURCE_IO,
784 };
785 int err;
786
787 err = acpi_check_resource_conflict(&res);
788 if (err)
789 goto exit;
790
791 pdev = platform_device_alloc("via686a", address);
792 if (!pdev) {
793 err = -ENOMEM;
794 printk(KERN_ERR "via686a: Device allocation failed\n");
795 goto exit;
796 }
797
798 err = platform_device_add_resources(pdev, &res, 1);
799 if (err) {
800 printk(KERN_ERR "via686a: Device resource addition failed "
801 "(%d)\n", err);
802 goto exit_device_put;
803 }
804
805 err = platform_device_add(pdev);
806 if (err) {
807 printk(KERN_ERR "via686a: Device addition failed (%d)\n",
808 err);
809 goto exit_device_put;
810 }
811
812 return 0;
813
814exit_device_put:
815 platform_device_put(pdev);
816exit:
817 return err;
818}
819
820static int __devinit via686a_pci_probe(struct pci_dev *dev,
821 const struct pci_device_id *id)
822{
823 u16 address, val;
824
825 if (force_addr) {
826 address = force_addr & ~(VIA686A_EXTENT - 1);
827 dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", address);
828 if (PCIBIOS_SUCCESSFUL !=
829 pci_write_config_word(dev, VIA686A_BASE_REG, address | 1))
830 return -ENODEV;
831 }
832 if (PCIBIOS_SUCCESSFUL !=
833 pci_read_config_word(dev, VIA686A_BASE_REG, &val))
834 return -ENODEV;
835
836 address = val & ~(VIA686A_EXTENT - 1);
837 if (address == 0) {
838 dev_err(&dev->dev, "base address not set - upgrade BIOS "
839 "or use force_addr=0xaddr\n");
840 return -ENODEV;
841 }
842
843 if (PCIBIOS_SUCCESSFUL !=
844 pci_read_config_word(dev, VIA686A_ENABLE_REG, &val))
845 return -ENODEV;
846 if (!(val & 0x0001)) {
847 if (!force_addr) {
848 dev_warn(&dev->dev, "Sensors disabled, enable "
849 "with force_addr=0x%x\n", address);
850 return -ENODEV;
851 }
852
853 dev_warn(&dev->dev, "Enabling sensors\n");
854 if (PCIBIOS_SUCCESSFUL !=
855 pci_write_config_word(dev, VIA686A_ENABLE_REG,
856 val | 0x0001))
857 return -ENODEV;
858 }
859
860 if (platform_driver_register(&via686a_driver))
861 goto exit;
862
863
864 if (via686a_device_add(address))
865 goto exit_unregister;
866
867
868
869
870
871 s_bridge = pci_dev_get(dev);
872 return -ENODEV;
873
874exit_unregister:
875 platform_driver_unregister(&via686a_driver);
876exit:
877 return -ENODEV;
878}
879
880static struct pci_driver via686a_pci_driver = {
881 .name = "via686a",
882 .id_table = via686a_pci_ids,
883 .probe = via686a_pci_probe,
884};
885
886static int __init sm_via686a_init(void)
887{
888 return pci_register_driver(&via686a_pci_driver);
889}
890
891static void __exit sm_via686a_exit(void)
892{
893 pci_unregister_driver(&via686a_pci_driver);
894 if (s_bridge != NULL) {
895 platform_device_unregister(pdev);
896 platform_driver_unregister(&via686a_driver);
897 pci_dev_put(s_bridge);
898 s_bridge = NULL;
899 }
900}
901
902MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>, "
903 "Mark Studebaker <mdsxyz123@yahoo.com> "
904 "and Bob Dougherty <bobd@stanford.edu>");
905MODULE_DESCRIPTION("VIA 686A Sensor device");
906MODULE_LICENSE("GPL");
907
908module_init(sm_via686a_init);
909module_exit(sm_via686a_exit);
910