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