root/lm-sensors/trunk/kernel/chips/via686a.c @ 1378

Revision 1378, 34.0 KB (checked in by mds, 11 years ago)

add support for 8231

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    via686a.c - Part of lm_sensors, Linux kernel modules
3                for hardware monitoring
4               
5    Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
6                        Kyösti Mälkki <kmalkki@cc.hut.fi>,
7                        Mark Studebaker <mdsxyz123@yahoo.com>,
8                        and Bob Dougherty <bobd@stanford.edu>
9    (Some conversion-factor data were contributed by Jonathan Teh Soon Yew
10    <j.teh@iname.com> and Alex van Kaam <darkside@chello.nl>.)
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 2 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software
24    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25*/
26
27/*
28    Supports the Via VT82C686A, VT82C686B, and VT8231 south bridges.
29    Reports all as a 686A.
30    8231-specific features not yet supported.
31    See doc/chips/via686a for details.
32    Warning - only supports a single device.
33*/
34#include <linux/version.h>
35#include <linux/module.h>
36#include <linux/slab.h>
37#include <linux/proc_fs.h>
38#include <linux/ioport.h>
39#include <linux/sysctl.h>
40#include <linux/pci.h>
41#include <asm/errno.h>
42#include <asm/io.h>
43#include <linux/types.h>
44#include <linux/delay.h>
45#include <linux/i2c.h>
46#include "version.h"
47#include "sensors.h"
48#include <linux/init.h>
49
50#ifdef MODULE_LICENSE
51MODULE_LICENSE("GPL");
52#endif
53
54#ifndef PCI_DEVICE_ID_VIA_82C686_4
55#define PCI_DEVICE_ID_VIA_82C686_4 0x3057
56#endif
57
58#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)) || \
59    (LINUX_VERSION_CODE == KERNEL_VERSION(2,3,0))
60#define init_MUTEX(s) do { *(s) = MUTEX; } while(0)
61#endif
62
63#ifndef THIS_MODULE
64#define THIS_MODULE NULL
65#endif
66
67/* If force_addr is set to anything different from 0, we forcibly enable
68   the device at the given address. */
69static int force_addr = 0;
70MODULE_PARM(force_addr, "i");
71MODULE_PARM_DESC(force_addr,
72                 "Initialize the base address of the sensors");
73
74/* Addresses to scan.
75   Note that we can't determine the ISA address until we have initialized
76   our module */
77static unsigned short normal_i2c[] = { SENSORS_I2C_END };
78static unsigned short normal_i2c_range[] = { SENSORS_I2C_END };
79static unsigned int normal_isa[] = { 0x0000, SENSORS_ISA_END };
80static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
81
82/* Insmod parameters */
83SENSORS_INSMOD_1(via686a);
84
85/*
86   The Via 686a southbridge has a LM78-like chip integrated on the same IC.
87   This driver is a customized copy of lm78.c
88*/
89
90/* Many VIA686A constants specified below */
91
92/* Length of ISA address segment */
93#define VIA686A_EXTENT 0x80
94#define VIA686A_BASE_REG 0x70
95#define VIA686A_ENABLE_REG 0x74
96
97/* The VIA686A registers */
98/* ins numbered 0-4 */
99#define VIA686A_REG_IN_MAX(nr) (0x2b + ((nr) * 2))
100#define VIA686A_REG_IN_MIN(nr) (0x2c + ((nr) * 2))
101#define VIA686A_REG_IN(nr)     (0x22 + (nr))
102
103/* fans numbered 1-2 */
104#define VIA686A_REG_FAN_MIN(nr) (0x3a + (nr))
105#define VIA686A_REG_FAN(nr)     (0x28 + (nr))
106
107// the following values are as speced by VIA:
108static const u8 regtemp[] = { 0x20, 0x21, 0x1f };
109static const u8 regover[] = { 0x39, 0x3d, 0x1d };
110static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e };
111
112/* temps numbered 1-3 */
113#define VIA686A_REG_TEMP(nr)            (regtemp[(nr) - 1])
114#define VIA686A_REG_TEMP_OVER(nr)       (regover[(nr) - 1])
115#define VIA686A_REG_TEMP_HYST(nr)       (reghyst[(nr) - 1])
116#define VIA686A_REG_TEMP_LOW1   0x4b    // bits 7-6
117#define VIA686A_REG_TEMP_LOW23  0x49    // 2 = bits 5-4, 3 = bits 7-6
118
119#define VIA686A_REG_ALARM1 0x41
120#define VIA686A_REG_ALARM2 0x42
121#define VIA686A_REG_FANDIV 0x47
122#define VIA686A_REG_CONFIG 0x40
123// The following register sets temp interrupt mode (bits 1-0 for temp1,
124// 3-2 for temp2, 5-4 for temp3).  Modes are:
125//    00 interrupt stays as long as value is out-of-range
126//    01 interrupt is cleared once register is read (default)
127//    10 comparator mode- like 00, but ignores hysteresis
128//    11 same as 00
129#define VIA686A_REG_TEMP_MODE 0x4b
130// We'll just assume that you want to set all 3 simulataneously:
131#define VIA686A_TEMP_MODE_MASK 0x3F
132#define VIA686A_TEMP_MODE_CONTINUOUS (0x00)
133
134/* Conversions. Rounding and limit checking is only done on the TO_REG
135   variants. */
136
137/********* VOLTAGE CONVERSIONS (Bob Dougherty) ********/
138// From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew):
139// voltagefactor[0]=1.25/2628; (2628/1.25=2102.4)   // Vccp
140// voltagefactor[1]=1.25/2628; (2628/1.25=2102.4)   // +2.5V
141// voltagefactor[2]=1.67/2628; (2628/1.67=1573.7)   // +3.3V
142// voltagefactor[3]=2.6/2628;  (2628/2.60=1010.8)   // +5V
143// voltagefactor[4]=6.3/2628;  (2628/6.30=417.14)   // +12V
144// in[i]=(data[i+2]*25.0+133)*voltagefactor[i];
145// That is:
146// volts = (25*regVal+133)*factor
147// regVal = (volts/factor-133)/25
148// (These conversions were contributed by Jonathan Teh Soon Yew
149// <j.teh@iname.com>)
150//
151// These get us close, but they don't completely agree with what my BIOS
152// says- they are all a bit low.  But, it all we have to go on...
153extern inline u8 IN_TO_REG(long val, int inNum)
154{
155        // to avoid floating point, we multiply everything by 100.
156        // val is guaranteed to be positive, so we can achieve the effect of
157        // rounding by (...*10+5)/10.  Note that the *10 is hidden in the
158        // /250 (which should really be /2500).
159        // At the end, we need to /100 because we *100 everything and we need
160        // to /10 because of the rounding thing, so we /1000. 
161        if (inNum <= 1)
162                return (u8)
163                    SENSORS_LIMIT(((val * 210240 - 13300) / 250 + 5) / 1000, 
164                                  0, 255);
165        else if (inNum == 2)
166                return (u8)
167                    SENSORS_LIMIT(((val * 157370 - 13300) / 250 + 5) / 1000, 
168                                  0, 255);
169        else if (inNum == 3)
170                return (u8)
171                    SENSORS_LIMIT(((val * 101080 - 13300) / 250 + 5) / 1000, 
172                                  0, 255);
173        else
174                return (u8) SENSORS_LIMIT(((val * 41714 - 13300) / 250 + 5)
175                                          / 1000, 0, 255);
176}
177
178extern inline long IN_FROM_REG(u8 val, int inNum)
179{
180        // to avoid floating point, we multiply everything by 100.
181        // val is guaranteed to be positive, so we can achieve the effect of
182        // rounding by adding 0.5.  Or, to avoid fp math, we do (...*10+5)/10.
183        // We need to scale with *100 anyway, so no need to /100 at the end.
184        if (inNum <= 1)
185                return (long) (((250000 * val + 13300) / 210240 * 10 + 5) /10);
186        else if (inNum == 2)
187                return (long) (((250000 * val + 13300) / 157370 * 10 + 5) /10);
188        else if (inNum == 3)
189                return (long) (((250000 * val + 13300) / 101080 * 10 + 5) /10);
190        else
191                return (long) (((250000 * val + 13300) / 41714 * 10 + 5) /10);
192}
193
194/********* FAN RPM CONVERSIONS ********/
195// Higher register values = slower fans (the fan's strobe gates a counter).
196// But this chip saturates back at 0, not at 255 like all the other chips.
197// So, 0 means 0 RPM
198extern inline u8 FAN_TO_REG(long rpm, int div)
199{
200        if (rpm == 0)
201                return 0;
202        rpm = SENSORS_LIMIT(rpm, 1, 1000000);
203        return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 255);
204}
205
206#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1350000/((val)*(div)))
207
208/******** TEMP CONVERSIONS (Bob Dougherty) *********/
209// linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew)
210//      if(temp<169)
211//              return double(temp)*0.427-32.08;
212//      else if(temp>=169 && temp<=202)
213//              return double(temp)*0.582-58.16;
214//      else
215//              return double(temp)*0.924-127.33;
216//
217// A fifth-order polynomial fits the unofficial data (provided by Alex van
218// Kaam <darkside@chello.nl>) a bit better.  It also give more reasonable
219// numbers on my machine (ie. they agree with what my BIOS tells me). 
220// Here's the fifth-order fit to the 8-bit data:
221// temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 -
222//        2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
223//
224// (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for
225// finding my typos in this formula!)
226//
227// Alas, none of the elegant function-fit solutions will work because we
228// aren't allowed to use floating point in the kernel and doing it with
229// integers doesn't rpovide enough precision.  So we'll do boring old
230// look-up table stuff.  The unofficial data (see below) have effectively
231// 7-bit resolution (they are rounded to the nearest degree).  I'm assuming
232// that the transfer function of the device is monotonic and smooth, so a
233// smooth function fit to the data will allow us to get better precision. 
234// I used the 5th-order poly fit described above and solved for
235// VIA register values 0-255.  I *10 before rounding, so we get tenth-degree
236// precision.  (I could have done all 1024 values for our 10-bit readings,
237// but the function is very linear in the useful range (0-80 deg C), so
238// we'll just use linear interpolation for 10-bit readings.)  So, tempLUT
239// is the temp at via register values 0-255:
240static const long tempLUT[] =
241    { -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
242            -503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
243            -362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
244            -255, -246, -237, -229, -220, -212, -204, -196, -188, -180,
245            -173, -166, -159, -152, -145, -139, -132, -126, -120, -114,
246            -108, -102, -96, -91, -85, -80, -74, -69, -64, -59, -54, -49,
247            -44, -39, -34, -29, -25, -20, -15, -11, -6, -2, 3, 7, 12, 16,
248            20, 25, 29, 33, 37, 42, 46, 50, 54, 59, 63, 67, 71, 75, 79, 84,
249            88, 92, 96, 100, 104, 109, 113, 117, 121, 125, 130, 134, 138,
250            142, 146, 151, 155, 159, 163, 168, 172, 176, 181, 185, 189,
251            193, 198, 202, 206, 211, 215, 219, 224, 228, 232, 237, 241,
252            245, 250, 254, 259, 263, 267, 272, 276, 281, 285, 290, 294,
253            299, 303, 307, 312, 316, 321, 325, 330, 334, 339, 344, 348,
254            353, 357, 362, 366, 371, 376, 380, 385, 390, 395, 399, 404,
255            409, 414, 419, 423, 428, 433, 438, 443, 449, 454, 459, 464,
256            469, 475, 480, 486, 491, 497, 502, 508, 514, 520, 526, 532,
257            538, 544, 551, 557, 564, 571, 578, 584, 592, 599, 606, 614,
258            621, 629, 637, 645, 654, 662, 671, 680, 689, 698, 708, 718,
259            728, 738, 749, 759, 770, 782, 793, 805, 818, 830, 843, 856,
260            870, 883, 898, 912, 927, 943, 958, 975, 991, 1008, 1026, 1044,
261            1062, 1081, 1101, 1121, 1141, 1162, 1184, 1206, 1229, 1252,
262            1276, 1301, 1326, 1352, 1378, 1406, 1434, 1462
263};
264
265/* the original LUT values from Alex van Kaam <darkside@chello.nl>
266   (for via register values 12-240):
267{-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31,
268-30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,
269-15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,
270-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,
27112,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22,
27222,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33,
27333,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,
27445,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60,
27561,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84,
27685,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110};
277*/
278
279// Here's the reverse LUT.  I got it by doing a 6-th order poly fit (needed
280// an extra term for a good fit to these inverse data!) and then
281// solving for each temp value from -50 to 110 (the useable range for
282// this chip).  Here's the fit:
283// viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4
284// - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01)
285// Note that n=161:
286static const u8 viaLUT[] =
287    { 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23,
288            23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40,
289            41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66,
290            69, 71, 73, 75, 77, 79, 82, 84, 86, 88, 91, 93, 95, 98, 100,
291            103, 105, 107, 110, 112, 115, 117, 119, 122, 124, 126, 129,
292            131, 134, 136, 138, 140, 143, 145, 147, 150, 152, 154, 156,
293            158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180,
294            182, 183, 185, 187, 188, 190, 192, 193, 195, 196, 198, 199,
295            200, 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, 213,
296            214, 215, 216, 217, 218, 219, 220, 221, 222, 222, 223, 224,
297            225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232,
298            233, 233, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239,
299            239, 240
300};
301
302/* Converting temps to (8-bit) hyst and over registers */
303// No interpolation here.  Just check the limits and go.
304// The +5 effectively rounds off properly and the +50 is because
305// the temps start at -50
306extern inline u8 TEMP_TO_REG(long val)
307{
308        return (u8)
309            SENSORS_LIMIT(viaLUT[((val <= -500) ? 0 : (val >= 1100) ? 160 : 
310                                  ((val + 5) / 10 + 50))], 0, 255);
311}
312
313/* for 8-bit temperature hyst and over registers */
314// The temp values are already *10, so we don't need to do that.
315// But we _will_ round these off to the nearest degree with (...*10+5)/10
316#define TEMP_FROM_REG(val) ((tempLUT[(val)]*10+5)/10)
317
318/* for 10-bit temperature readings */
319// You might _think_ this is too long to inline, but's it's really only
320// called once...
321extern inline long TEMP_FROM_REG10(u16 val)
322{
323        // the temp values are already *10, so we don't need to do that.
324        long temp;
325        u16 eightBits = val >> 2;
326        u16 twoBits = val & 3;
327
328        // handle the extremes first (they won't interpolate well! ;-)
329        if (val == 0)
330                return (long) tempLUT[0];
331        if (val == 1023)
332                return (long) tempLUT[255];
333
334        if (twoBits == 0)
335                return (long) tempLUT[eightBits];
336        else {
337                // do some interpolation by multipying the lower and upper
338                // bounds by 25, 50 or 75, then /100.
339                temp = ((25 * (4 - twoBits)) * tempLUT[eightBits]
340                        + (25 * twoBits) * tempLUT[eightBits + 1]);
341                // increase the magnitude by 50 to achieve rounding.
342                if (temp > 0)
343                        temp += 50;
344                else
345                        temp -= 50;
346                return (temp / 100);
347        }
348}
349
350#define ALARMS_FROM_REG(val) (val)
351
352#define DIV_FROM_REG(val) (1 << (val))
353#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
354
355/* Initial limits */
356#define VIA686A_INIT_IN_0 200
357#define VIA686A_INIT_IN_1 250
358#define VIA686A_INIT_IN_2 330
359#define VIA686A_INIT_IN_3 500
360#define VIA686A_INIT_IN_4 1200
361
362#define VIA686A_INIT_IN_PERCENTAGE 10
363
364#define VIA686A_INIT_IN_MIN_0 (VIA686A_INIT_IN_0 - VIA686A_INIT_IN_0 \
365        * VIA686A_INIT_IN_PERCENTAGE / 100)
366#define VIA686A_INIT_IN_MAX_0 (VIA686A_INIT_IN_0 + VIA686A_INIT_IN_0 \
367        * VIA686A_INIT_IN_PERCENTAGE / 100)
368#define VIA686A_INIT_IN_MIN_1 (VIA686A_INIT_IN_1 - VIA686A_INIT_IN_1 \
369        * VIA686A_INIT_IN_PERCENTAGE / 100)
370#define VIA686A_INIT_IN_MAX_1 (VIA686A_INIT_IN_1 + VIA686A_INIT_IN_1 \
371        * VIA686A_INIT_IN_PERCENTAGE / 100)
372#define VIA686A_INIT_IN_MIN_2 (VIA686A_INIT_IN_2 - VIA686A_INIT_IN_2 \
373        * VIA686A_INIT_IN_PERCENTAGE / 100)
374#define VIA686A_INIT_IN_MAX_2 (VIA686A_INIT_IN_2 + VIA686A_INIT_IN_2 \
375        * VIA686A_INIT_IN_PERCENTAGE / 100)
376#define VIA686A_INIT_IN_MIN_3 (VIA686A_INIT_IN_3 - VIA686A_INIT_IN_3 \
377        * VIA686A_INIT_IN_PERCENTAGE / 100)
378#define VIA686A_INIT_IN_MAX_3 (VIA686A_INIT_IN_3 + VIA686A_INIT_IN_3 \
379        * VIA686A_INIT_IN_PERCENTAGE / 100)
380#define VIA686A_INIT_IN_MIN_4 (VIA686A_INIT_IN_4 - VIA686A_INIT_IN_4 \
381        * VIA686A_INIT_IN_PERCENTAGE / 100)
382#define VIA686A_INIT_IN_MAX_4 (VIA686A_INIT_IN_4 + VIA686A_INIT_IN_4 \
383        * VIA686A_INIT_IN_PERCENTAGE / 100)
384
385#define VIA686A_INIT_FAN_MIN    3000
386
387#define VIA686A_INIT_TEMP_OVER 600
388#define VIA686A_INIT_TEMP_HYST 500
389
390#ifdef MODULE
391extern int init_module(void);
392extern int cleanup_module(void);
393#endif                          /* MODULE */
394
395/* For the VIA686A, we need to keep some data in memory. That
396   data is pointed to by via686a_list[NR]->data. The structure itself is
397   dynamically allocated, at the same time when a new via686a client is
398   allocated. */
399struct via686a_data {
400        struct semaphore lock;
401        int sysctl_id;
402
403        struct semaphore update_lock;
404        char valid;             /* !=0 if following fields are valid */
405        unsigned long last_updated;     /* In jiffies */
406
407        u8 in[5];               /* Register value */
408        u8 in_max[5];           /* Register value */
409        u8 in_min[5];           /* Register value */
410        u8 fan[2];              /* Register value */
411        u8 fan_min[2];          /* Register value */
412        u16 temp[3];            /* Register value 10 bit */
413        u8 temp_over[3];        /* Register value */
414        u8 temp_hyst[3];        /* Register value */
415        u8 fan_div[2];          /* Register encoding, shifted right */
416        u16 alarms;             /* Register encoding, combined */
417};
418
419static struct pci_dev *s_bridge;        /* pointer to the (only) via686a */
420
421#ifdef MODULE
422static
423#else
424extern
425#endif
426int __init sensors_via686a_init(void);
427static int __init via686a_cleanup(void);
428
429static int via686a_attach_adapter(struct i2c_adapter *adapter);
430static int via686a_detect(struct i2c_adapter *adapter, int address,
431                          unsigned short flags, int kind);
432static int via686a_detach_client(struct i2c_client *client);
433static int via686a_command(struct i2c_client *client, unsigned int cmd,
434                           void *arg);
435static void via686a_inc_use(struct i2c_client *client);
436static void via686a_dec_use(struct i2c_client *client);
437
438static int via686a_read_value(struct i2c_client *client, u8 register);
439static void via686a_write_value(struct i2c_client *client, u8 register,
440                                u8 value);
441static void via686a_update_client(struct i2c_client *client);
442static void via686a_init_client(struct i2c_client *client);
443static int via686a_find(int *address);
444
445
446static void via686a_in(struct i2c_client *client, int operation,
447                       int ctl_name, int *nrels_mag, long *results);
448static void via686a_fan(struct i2c_client *client, int operation,
449                        int ctl_name, int *nrels_mag, long *results);
450static void via686a_temp(struct i2c_client *client, int operation,
451                         int ctl_name, int *nrels_mag, long *results);
452static void via686a_alarms(struct i2c_client *client, int operation,
453                           int ctl_name, int *nrels_mag, long *results);
454static void via686a_fan_div(struct i2c_client *client, int operation,
455                            int ctl_name, int *nrels_mag, long *results);
456
457static int via686a_id = 0;
458
459/* The driver. I choose to use type i2c_driver, as at is identical to both
460   smbus_driver and isa_driver, and clients could be of either kind */
461static struct i2c_driver via686a_driver = {
462        /* name */ "VIA 686A",
463        /* id */ I2C_DRIVERID_VIA686A,
464        /* flags */ I2C_DF_NOTIFY,
465        /* attach_adapter */ &via686a_attach_adapter,
466        /* detach_client */ &via686a_detach_client,
467        /* command */ &via686a_command,
468        /* inc_use */ &via686a_inc_use,
469        /* dec_use */ &via686a_dec_use
470};
471
472/* Used by via686a_init/cleanup */
473static int __initdata via686a_initialized = 0;
474
475/* The /proc/sys entries */
476/* These files are created for each detected VIA686A. This is just a template;
477   though at first sight, you might think we could use a statically
478   allocated list, we need some way to get back to the parent - which
479   is done through one of the 'extra' fields which are initialized
480   when a new copy is allocated. */
481static ctl_table via686a_dir_table_template[] = {
482        {VIA686A_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
483         &i2c_sysctl_real, NULL, &via686a_in},
484        {VIA686A_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real,
485         &i2c_sysctl_real, NULL, &via686a_in},
486        {VIA686A_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
487         &i2c_sysctl_real, NULL, &via686a_in},
488        {VIA686A_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
489         &i2c_sysctl_real, NULL, &via686a_in},
490        {VIA686A_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
491         &i2c_sysctl_real, NULL, &via686a_in},
492        {VIA686A_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
493         &i2c_sysctl_real, NULL, &via686a_fan},
494        {VIA686A_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
495         &i2c_sysctl_real, NULL, &via686a_fan},
496        {VIA686A_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
497         &i2c_sysctl_real, NULL, &via686a_temp},
498        {VIA686A_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL,
499         &i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_temp},
500        {VIA686A_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL,
501         &i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_temp},
502        {VIA686A_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL,
503         &i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_fan_div},
504        {VIA686A_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL,
505         &i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_alarms},
506        {0}
507};
508
509static inline int via686a_read_value(struct i2c_client *client, u8 reg)
510{
511        return (inb_p(client->addr + reg));
512}
513
514static inline void via686a_write_value(struct i2c_client *client, u8 reg,
515                                       u8 value)
516{
517        outb_p(value, client->addr + reg);
518}
519
520/* This is called when the module is loaded */
521int via686a_attach_adapter(struct i2c_adapter *adapter)
522{
523        return i2c_detect(adapter, &addr_data, via686a_detect);
524}
525
526/* Locate chip and get correct base address */
527int via686a_find(int *address)
528{
529        u16 val;
530
531        if (!pci_present())
532                return -ENODEV;
533
534        if (!(s_bridge = pci_find_device(PCI_VENDOR_ID_VIA,
535                                         PCI_DEVICE_ID_VIA_82C686_4,
536                                         NULL)))
537                if (!(s_bridge = pci_find_device(PCI_VENDOR_ID_VIA,
538                                                 0x8235,
539                                                 NULL))) return -ENODEV;
540
541        if (PCIBIOS_SUCCESSFUL !=
542            pci_read_config_word(s_bridge, VIA686A_BASE_REG, &val))
543                return -ENODEV;
544        *address = val & ~(VIA686A_EXTENT - 1);
545        if (*address == 0 && force_addr == 0) {
546                printk("via686a.o: base address not set - upgrade BIOS or use force_addr=0xaddr\n");
547                return -ENODEV;
548        }
549        if (force_addr)
550                *address = force_addr;  /* so detect will get called */
551
552        return 0;
553}
554
555int via686a_detect(struct i2c_adapter *adapter, int address,
556                   unsigned short flags, int kind)
557{
558        int i;
559        struct i2c_client *new_client;
560        struct via686a_data *data;
561        int err = 0;
562        const char *type_name = "via686a";
563        u16 val;
564
565        /* Make sure we are probing the ISA bus!!  */
566        if (!i2c_is_isa_adapter(adapter)) {
567                printk
568                ("via686a.o: via686a_detect called for an I2C bus adapter?!?\n");
569                return 0;
570        }
571
572        /* 8231 requires multiple of 256, we enforce that on 686 as well */
573        if(force_addr)
574                address = force_addr & 0xFF00;
575        if (check_region(address, VIA686A_EXTENT)) {
576                printk("via686a.o: region 0x%x already in use!\n",
577                       address);
578                return -ENODEV;
579        }
580
581        if(force_addr) {
582                printk("via686a.o: forcing ISA address 0x%04X\n", address);
583                if (PCIBIOS_SUCCESSFUL !=
584                    pci_write_config_word(s_bridge, VIA686A_BASE_REG, address))
585                        return -ENODEV;
586        }
587        if (PCIBIOS_SUCCESSFUL !=
588            pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val))
589                return -ENODEV;
590        if (!(val & 0x0001)) {
591                printk("via686a.o: enabling sensors\n");
592                if (PCIBIOS_SUCCESSFUL !=
593                    pci_write_config_word(s_bridge, VIA686A_ENABLE_REG,
594                                      val | 0x0001))
595                        return -ENODEV;
596        }
597
598        if (!(new_client = kmalloc(sizeof(struct i2c_client) +
599                                   sizeof(struct via686a_data),
600                                   GFP_KERNEL))) {
601                err = -ENOMEM;
602                goto ERROR0;
603        }
604
605        data = (struct via686a_data *) (new_client + 1);
606        new_client->addr = address;
607        init_MUTEX(&data->lock);
608        new_client->data = data;
609        new_client->adapter = adapter;
610        new_client->driver = &via686a_driver;
611        new_client->flags = 0;
612
613        /* Reserve the ISA region */
614        request_region(address, VIA686A_EXTENT, "via686a-sensors");
615
616        /* Fill in the remaining client fields and put into the global list */
617        strcpy(new_client->name, "Via 686A Integrated Sensors");
618
619        new_client->id = via686a_id++;
620        data->valid = 0;
621        init_MUTEX(&data->update_lock);
622
623        /* Tell the I2C layer a new client has arrived */
624        if ((err = i2c_attach_client(new_client)))
625                goto ERROR3;
626
627        /* Register a new directory entry with module sensors */
628        if ((i = i2c_register_entry((struct i2c_client *) new_client,
629                                        type_name,
630                                        via686a_dir_table_template,
631                                        THIS_MODULE)) < 0) {
632                err = i;
633                goto ERROR4;
634        }
635        data->sysctl_id = i;
636
637        /* Initialize the VIA686A chip */
638        via686a_init_client(new_client);
639        return 0;
640
641      ERROR4:
642        i2c_detach_client(new_client);
643      ERROR3:
644        release_region(address, VIA686A_EXTENT);
645        kfree(new_client);
646      ERROR0:
647        return err;
648}
649
650int via686a_detach_client(struct i2c_client *client)
651{
652        int err;
653
654        i2c_deregister_entry(((struct via686a_data *) 
655                                  (client->data))->sysctl_id);
656
657        if ((err = i2c_detach_client(client))) {
658                printk
659                ("via686a.o: Client deregistration failed, client not detached.\n");
660                return err;
661        }
662
663        release_region(client->addr, VIA686A_EXTENT);
664        kfree(client);
665
666        return 0;
667}
668
669/* No commands defined yet */
670int via686a_command(struct i2c_client *client, unsigned int cmd, void *arg)
671{
672        return 0;
673}
674
675void via686a_inc_use(struct i2c_client *client)
676{
677        MOD_INC_USE_COUNT;
678}
679
680void via686a_dec_use(struct i2c_client *client)
681{
682        MOD_DEC_USE_COUNT;
683}
684
685/* Called when we have found a new VIA686A. Set limits, etc. */
686void via686a_init_client(struct i2c_client *client)
687{
688        int i;
689
690        /* Reset the device */
691        via686a_write_value(client, VIA686A_REG_CONFIG, 0x80);
692
693        /* Have to wait for reset to complete or else the following
694           initializations won't work reliably. The delay was arrived at
695           empirically, the datasheet doesn't tell you.
696           Waiting for the reset bit to clear doesn't work, it
697           clears in about 2-4 udelays and that isn't nearly enough. */
698        udelay(50);
699
700        via686a_write_value(client, VIA686A_REG_IN_MIN(0),
701                            IN_TO_REG(VIA686A_INIT_IN_MIN_0, 0));
702        via686a_write_value(client, VIA686A_REG_IN_MAX(0),
703                            IN_TO_REG(VIA686A_INIT_IN_MAX_0, 0));
704        via686a_write_value(client, VIA686A_REG_IN_MIN(1),
705                            IN_TO_REG(VIA686A_INIT_IN_MIN_1, 1));
706        via686a_write_value(client, VIA686A_REG_IN_MAX(1),
707                            IN_TO_REG(VIA686A_INIT_IN_MAX_1, 1));
708        via686a_write_value(client, VIA686A_REG_IN_MIN(2),
709                            IN_TO_REG(VIA686A_INIT_IN_MIN_2, 2));
710        via686a_write_value(client, VIA686A_REG_IN_MAX(2),
711                            IN_TO_REG(VIA686A_INIT_IN_MAX_2, 2));
712        via686a_write_value(client, VIA686A_REG_IN_MIN(3),
713                            IN_TO_REG(VIA686A_INIT_IN_MIN_3, 3));
714        via686a_write_value(client, VIA686A_REG_IN_MAX(3),
715                            IN_TO_REG(VIA686A_INIT_IN_MAX_3, 3));
716        via686a_write_value(client, VIA686A_REG_IN_MIN(4),
717                            IN_TO_REG(VIA686A_INIT_IN_MIN_4, 4));
718        via686a_write_value(client, VIA686A_REG_IN_MAX(4),
719                            IN_TO_REG(VIA686A_INIT_IN_MAX_4, 4));
720        via686a_write_value(client, VIA686A_REG_FAN_MIN(1),
721                            FAN_TO_REG(VIA686A_INIT_FAN_MIN, 2));
722        via686a_write_value(client, VIA686A_REG_FAN_MIN(2),
723                            FAN_TO_REG(VIA686A_INIT_FAN_MIN, 2));
724        for (i = 1; i <= 3; i++) {
725                via686a_write_value(client, VIA686A_REG_TEMP_OVER(i),
726                                    TEMP_TO_REG(VIA686A_INIT_TEMP_OVER));
727                via686a_write_value(client, VIA686A_REG_TEMP_HYST(i),
728                                    TEMP_TO_REG(VIA686A_INIT_TEMP_HYST));
729        }
730
731        /* Start monitoring */
732        via686a_write_value(client, VIA686A_REG_CONFIG, 0x01);
733
734        /* Cofigure temp interrupt mode for continuous-interrupt operation */
735        via686a_write_value(client, VIA686A_REG_TEMP_MODE, 
736                            via686a_read_value(client, VIA686A_REG_TEMP_MODE) &
737                            !(VIA686A_TEMP_MODE_MASK | VIA686A_TEMP_MODE_CONTINUOUS));
738}
739
740void via686a_update_client(struct i2c_client *client)
741{
742        struct via686a_data *data = client->data;
743        int i;
744
745        down(&data->update_lock);
746
747        if ((jiffies - data->last_updated > HZ + HZ / 2) ||
748            (jiffies < data->last_updated) || !data->valid) {
749
750                for (i = 0; i <= 4; i++) {
751                        data->in[i] =
752                            via686a_read_value(client, VIA686A_REG_IN(i));
753                        data->in_min[i] = via686a_read_value(client,
754                                                             VIA686A_REG_IN_MIN
755                                                             (i));
756                        data->in_max[i] =
757                            via686a_read_value(client, VIA686A_REG_IN_MAX(i));
758                }
759                for (i = 1; i <= 2; i++) {
760                        data->fan[i - 1] =
761                            via686a_read_value(client, VIA686A_REG_FAN(i));
762                        data->fan_min[i - 1] = via686a_read_value(client,
763                                                     VIA686A_REG_FAN_MIN(i));
764                }
765                for (i = 1; i <= 3; i++) {
766                        data->temp[i - 1] = via686a_read_value(client,
767                                                 VIA686A_REG_TEMP(i)) << 2;
768                        data->temp_over[i - 1] =
769                            via686a_read_value(client,
770                                               VIA686A_REG_TEMP_OVER(i));
771                        data->temp_hyst[i - 1] =
772                            via686a_read_value(client,
773                                               VIA686A_REG_TEMP_HYST(i));
774                }
775                /* add in lower 2 bits
776                   temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1
777                   temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23
778                   temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23
779                 */
780                data->temp[0] |= (via686a_read_value(client,
781                                                     VIA686A_REG_TEMP_LOW1)
782                                  & 0xc0) >> 6;
783                data->temp[1] |=
784                    (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) &
785                     0x30) >> 4;
786                data->temp[2] |=
787                    (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) &
788                     0xc0) >> 6;
789
790                i = via686a_read_value(client, VIA686A_REG_FANDIV);
791                data->fan_div[0] = (i >> 4) & 0x03;
792                data->fan_div[1] = i >> 6;
793                data->alarms =
794                    via686a_read_value(client,
795                                       VIA686A_REG_ALARM1) |
796                    (via686a_read_value(client, VIA686A_REG_ALARM2) << 8);
797                data->last_updated = jiffies;
798                data->valid = 1;
799        }
800
801        up(&data->update_lock);
802}
803
804
805/* The next few functions are the call-back functions of the /proc/sys and
806   sysctl files. Which function is used is defined in the ctl_table in
807   the extra1 field.
808   Each function must return the magnitude (power of 10 to divide the date
809   with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must
810   put a maximum of *nrels elements in results reflecting the data of this
811   file, and set *nrels to the number it actually put in it, if operation==
812   SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from
813   results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE.
814   Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
815   large enough (by checking the incoming value of *nrels). This is not very
816   good practice, but as long as you put less than about 5 values in results,
817   you can assume it is large enough. */
818void via686a_in(struct i2c_client *client, int operation, int ctl_name,
819                int *nrels_mag, long *results)
820{
821        struct via686a_data *data = client->data;
822        int nr = ctl_name - VIA686A_SYSCTL_IN0;
823
824        if (operation == SENSORS_PROC_REAL_INFO)
825                *nrels_mag = 2;
826        else if (operation == SENSORS_PROC_REAL_READ) {
827                via686a_update_client(client);
828                results[0] = IN_FROM_REG(data->in_min[nr], nr);
829                results[1] = IN_FROM_REG(data->in_max[nr], nr);
830                results[2] = IN_FROM_REG(data->in[nr], nr);
831                *nrels_mag = 3;
832        } else if (operation == SENSORS_PROC_REAL_WRITE) {
833                if (*nrels_mag >= 1) {
834                        data->in_min[nr] = IN_TO_REG(results[0], nr);
835                        via686a_write_value(client, VIA686A_REG_IN_MIN(nr),
836                                            data->in_min[nr]);
837                }
838                if (*nrels_mag >= 2) {
839                        data->in_max[nr] = IN_TO_REG(results[1], nr);
840                        via686a_write_value(client, VIA686A_REG_IN_MAX(nr),
841                                            data->in_max[nr]);
842                }
843        }
844}
845
846void via686a_fan(struct i2c_client *client, int operation, int ctl_name,
847                 int *nrels_mag, long *results)
848{
849        struct via686a_data *data = client->data;
850        int nr = ctl_name - VIA686A_SYSCTL_FAN1 + 1;
851
852        if (operation == SENSORS_PROC_REAL_INFO)
853                *nrels_mag = 0;
854        else if (operation == SENSORS_PROC_REAL_READ) {
855                via686a_update_client(client);
856                results[0] = FAN_FROM_REG(data->fan_min[nr - 1],
857                                          DIV_FROM_REG(data->fan_div
858                                                       [nr - 1]));
859                results[1] =
860                    FAN_FROM_REG(data->fan[nr - 1],
861                                 DIV_FROM_REG(data->fan_div[nr - 1]));
862                *nrels_mag = 2;
863        } else if (operation == SENSORS_PROC_REAL_WRITE) {
864                if (*nrels_mag >= 1) {
865                        data->fan_min[nr - 1] = FAN_TO_REG(results[0], 
866                                                           DIV_FROM_REG(data->
867                                                              fan_div[nr -1]));
868                        via686a_write_value(client,
869                                            VIA686A_REG_FAN_MIN(nr),
870                                            data->fan_min[nr - 1]);
871                }
872        }
873}
874
875void via686a_temp(struct i2c_client *client, int operation, int ctl_name,
876                  int *nrels_mag, long *results)
877{
878        struct via686a_data *data = client->data;
879        int nr = ctl_name - VIA686A_SYSCTL_TEMP;
880
881        if (operation == SENSORS_PROC_REAL_INFO)
882                *nrels_mag = 1;
883        else if (operation == SENSORS_PROC_REAL_READ) {
884                via686a_update_client(client);
885                results[0] = TEMP_FROM_REG(data->temp_over[nr]);
886                results[1] = TEMP_FROM_REG(data->temp_hyst[nr]);
887                results[2] = TEMP_FROM_REG10(data->temp[nr]);
888                *nrels_mag = 3;
889        } else if (operation == SENSORS_PROC_REAL_WRITE) {
890                if (*nrels_mag >= 1) {
891                        data->temp_over[nr] = TEMP_TO_REG(results[0]);
892                        via686a_write_value(client,
893                                            VIA686A_REG_TEMP_OVER(nr + 1),
894                                            data->temp_over[nr]);
895                }
896                if (*nrels_mag >= 2) {
897                        data->temp_hyst[nr] = TEMP_TO_REG(results[1]);
898                        via686a_write_value(client,
899                                            VIA686A_REG_TEMP_HYST(nr + 1),
900                                            data->temp_hyst[nr]);
901                }
902        }
903}
904
905void via686a_alarms(struct i2c_client *client, int operation, int ctl_name,
906                    int *nrels_mag, long *results)
907{
908        struct via686a_data *data = client->data;
909        if (operation == SENSORS_PROC_REAL_INFO)
910                *nrels_mag = 0;
911        else if (operation == SENSORS_PROC_REAL_READ) {
912                via686a_update_client(client);
913                results[0] = ALARMS_FROM_REG(data->alarms);
914                *nrels_mag = 1;
915        }
916}
917
918void via686a_fan_div(struct i2c_client *client, int operation,
919                     int ctl_name, int *nrels_mag, long *results)
920{
921        struct via686a_data *data = client->data;
922        int old;
923
924        if (operation == SENSORS_PROC_REAL_INFO)
925                *nrels_mag = 0;
926        else if (operation == SENSORS_PROC_REAL_READ) {
927                via686a_update_client(client);
928                results[0] = DIV_FROM_REG(data->fan_div[0]);
929                results[1] = DIV_FROM_REG(data->fan_div[1]);
930                *nrels_mag = 2;
931        } else if (operation == SENSORS_PROC_REAL_WRITE) {
932                old = via686a_read_value(client, VIA686A_REG_FANDIV);
933                if (*nrels_mag >= 2) {
934                        data->fan_div[1] = DIV_TO_REG(results[1]);
935                        old = (old & 0x3f) | (data->fan_div[1] << 6);
936                }
937                if (*nrels_mag >= 1) {
938                        data->fan_div[0] = DIV_TO_REG(results[0]);
939                        old = (old & 0xcf) | (data->fan_div[0] << 4);
940                        via686a_write_value(client, VIA686A_REG_FANDIV,
941                                            old);
942                }
943        }
944}
945
946int __init sensors_via686a_init(void)
947{
948        int res, addr;
949
950        printk("via686a.o version %s (%s)\n", LM_VERSION, LM_DATE);
951        via686a_initialized = 0;
952
953        if (via686a_find(&addr)) {
954                printk("via686a.o: No Via 686A sensors found.\n");
955                return -ENODEV;
956        }
957        normal_isa[0] = addr;
958
959        if ((res = i2c_add_driver(&via686a_driver))) {
960                printk("via686a.o: Driver registration failed.\n");
961                via686a_cleanup();
962                return res;
963        }
964        via686a_initialized++;
965        return 0;
966}
967
968int __init via686a_cleanup(void)
969{
970        int res;
971
972        if (via686a_initialized >= 1) {
973                if ((res = i2c_del_driver(&via686a_driver))) {
974                        printk
975                            ("via686a.o: Driver deregistration failed.\n");
976                        return res;
977                }
978                via686a_initialized--;
979        }
980        return 0;
981}
982
983EXPORT_NO_SYMBOLS;
984
985#ifdef MODULE
986
987MODULE_AUTHOR
988    ("Kyösti Mälkki <kmalkki@cc.hut.fi>, Mark Studebaker <mdsxyz123@yahoo.com>, Bob Dougherty <bobd@stanford.edu>");
989MODULE_DESCRIPTION("VIA 686A Sensor device");
990
991int init_module(void)
992{
993        return sensors_via686a_init();
994}
995
996int cleanup_module(void)
997{
998        return via686a_cleanup();
999}
1000
1001#endif                          /* MODULE */
Note: See TracBrowser for help on using the browser.