root/lm-sensors/trunk/kernel/chips/w83781d.c @ 2302

Revision 2302, 70.5 KB (checked in by khali, 9 years ago)

Preserve other bits when forcing temp2/3 to comparator mode.

Backported from Linux 2.6. Requested by Keith Duthie.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    w83781d.c - Part of lm_sensors, Linux kernel modules for hardware
3                monitoring
4    Copyright (c) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
5    Philip Edelbrock <phil@netroedge.com>,
6    and Mark Studebaker <mdsxyz123@yahoo.com>
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23/*
24    Supports following chips:
25
26    Chip        #vin    #fanin  #pwm    #temp   wchipid vendid  i2c     ISA
27    as99127f    7       3       1?      3       0x31    0x12c3  yes     no
28    as99127f rev.2 (type name = as99127f)       0x31    0x5ca3  yes     no
29    asb100 "bach" (type_name = as99127f)        0x31    0x0694  yes     no
30    w83627hf    9       3       2       3       0x21    0x5ca3  yes     yes(LPC)
31    w83697hf    8       2       2       2       0x60    0x5ca3  no      yes(LPC)
32    w83781d     7       3       0       3       0x10-1  0x5ca3  yes     yes
33    w83782d     9       3       2-4     3       0x30    0x5ca3  yes     yes
34    w83783s     5-6     3       2       1-2     0x40    0x5ca3  yes     no
35    w83791d     10      5       5       3       0x71    0x5ca3  yes     no
36
37*/
38
39#include <linux/module.h>
40#include <linux/slab.h>
41#include <linux/ioport.h>
42#include <linux/i2c.h>
43#include <linux/i2c-proc.h>
44#include <linux/init.h>
45#include <asm/io.h>
46#include "version.h"
47#include "sensors_vid.h"
48#include "lm75.h"
49
50/* RT Table support #defined so we can take it out if it gets bothersome */
51#define W83781D_RT 1
52
53/* Addresses to scan */
54static unsigned short normal_i2c[] = { SENSORS_I2C_END };
55static unsigned short normal_i2c_range[] = { 0x20, 0x2f, SENSORS_I2C_END };
56static unsigned int normal_isa[] = { 0x0290, SENSORS_ISA_END };
57static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
58
59/* Insmod parameters */
60SENSORS_INSMOD_7(w83781d, w83782d, w83783s, w83627hf, as99127f, w83697hf, w83791d);
61SENSORS_MODULE_PARM(force_subclients, "List of subclient addresses: " \
62                      "{bus, clientaddr, subclientaddr1, subclientaddr2}");
63
64static int init = 1;
65MODULE_PARM(init, "i");
66MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
67
68/* Constants specified below */
69
70/* Length of ISA address segment */
71#define W83781D_EXTENT 8
72
73/* Where are the ISA address/data registers relative to the base address */
74#define W83781D_ADDR_REG_OFFSET 5
75#define W83781D_DATA_REG_OFFSET 6
76
77/* The W83781D registers */
78/* The W83782D registers for nr=7,8 are in bank 5 */
79#define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \
80                                           (0x554 + (((nr) - 7) * 2)))
81#define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \
82                                           (0x555 + (((nr) - 7) * 2)))
83#define W83781D_REG_IN(nr)     ((nr < 7) ? (0x20 + (nr)) : \
84                                           (0x550 + (nr) - 7))
85
86#define W83791D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \
87                                           (0xb4 + (((nr) - 7) * 2)))
88#define W83791D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \
89                                           (0xb5 + (((nr) - 7) * 2)))
90#define W83791D_REG_IN(nr)     ((nr < 7) ? (0x20 + (nr)) : \
91                                           (0xb0 + (nr) - 7))
92
93#define W83781D_REG_FAN_MIN(nr) ((nr < 4) ? (0x3a + (nr)) : \
94                                            (0xba + (nr) - 4))
95#define W83781D_REG_FAN(nr)     ((nr < 4) ? (0x27 + (nr)) : \
96                                            (0xbc + (nr) - 4))
97
98#define W83781D_REG_TEMP2 0x0150
99#define W83781D_REG_TEMP3 0x0250
100#define W83781D_REG_TEMP2_HYST 0x153
101#define W83781D_REG_TEMP3_HYST 0x253
102#define W83781D_REG_TEMP2_CONFIG 0x152
103#define W83781D_REG_TEMP3_CONFIG 0x252
104#define W83781D_REG_TEMP2_OVER 0x155
105#define W83781D_REG_TEMP3_OVER 0x255
106
107#define W83781D_REG_TEMP 0x27
108#define W83781D_REG_TEMP_OVER 0x39
109#define W83781D_REG_TEMP_HYST 0x3A
110#define W83781D_REG_BANK 0x4E
111
112#define W83781D_REG_CONFIG 0x40
113#define W83781D_REG_ALARM1 0x41
114#define W83781D_REG_ALARM2 0x42
115#define W83781D_REG_ALARM3 0x450        /* not on W83781D */
116
117#define W83781D_REG_IRQ 0x4C
118#define W83781D_REG_BEEP_CONFIG 0x4D
119#define W83781D_REG_BEEP_INTS1 0x56
120#define W83781D_REG_BEEP_INTS2 0x57
121#define W83781D_REG_BEEP_INTS3 0x453    /* not on W83781D */
122
123#define W83781D_REG_VID_FANDIV 0x47
124
125#define W83781D_REG_CHIPID 0x49
126#define W83781D_REG_WCHIPID 0x58
127#define W83781D_REG_CHIPMAN 0x4F
128#define W83781D_REG_PIN 0x4B
129
130/* 782D/783S only */
131#define W83781D_REG_VBAT 0x5D
132
133/* PWM 782D (1-4) and 783S (1-2) only */
134#define W83781D_REG_PWM1 0x5B   /* 782d and 783s/627hf datasheets disagree */
135                                /* on which is which; */
136#define W83781D_REG_PWM2 0x5A   /* We follow the 782d convention here, */
137                                /* However 782d is probably wrong. */
138#define W83781D_REG_PWM3 0x5E
139#define W83781D_REG_PWM4 0x5F
140#define W83781D_REG_PWMCLK12 0x5C
141#define W83781D_REG_PWMCLK34 0x45C
142
143#define W83791D_REG_PWM1 0x81
144#define W83791D_REG_PWM2 0x83
145#define W83791D_REG_PWM3 0x94
146
147#define W83627HF_REG_PWM1 0x01
148#define W83627HF_REG_PWM2 0x03
149#define W83627HF_REG_PWMCLK1 0x00
150#define W83627HF_REG_PWMCLK2 0x02
151
152static const u8 regpwm[] = { W83781D_REG_PWM1, W83781D_REG_PWM2,
153        W83781D_REG_PWM3, W83781D_REG_PWM4
154};
155
156static const u8 regpwm_w83791d[] = { W83791D_REG_PWM1, W83791D_REG_PWM2,
157                                   W83791D_REG_PWM3
158};
159       
160#define W83781D_REG_PWM(type, nr) (((type) == w83791d) ? \
161                                         regpwm_w83791d[(nr) - 1] : \
162                                   ((type) == w83697hf) ? \
163                                         (((nr) * 2) - 1) : \
164                                         regpwm[(nr) - 1])
165
166#define W83781D_REG_I2C_ADDR 0x48
167#define W83781D_REG_I2C_SUBADDR 0x4A
168
169/* The following are undocumented in the data sheets however we
170   received the information in an email from Winbond tech support */
171/* Sensor selection - not on 781d */
172#define W83781D_REG_SCFG1 0x5D
173static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 };
174#define W83781D_REG_SCFG2 0x59
175static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
176#define W83781D_DEFAULT_BETA 3435
177
178/* RT Table registers */
179#define W83781D_REG_RT_IDX 0x50
180#define W83781D_REG_RT_VAL 0x51
181
182/* Conversions. Rounding and limit checking is only done on the TO_REG
183   variants. Note that you should be a bit careful with which arguments
184   these macros are called: arguments may be evaluated more than once.
185   Fixing this is just not worth it. */
186#define IN_TO_REG(val)  (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255))
187#define IN_FROM_REG(val) (((val) * 16 + 5) / 10)
188
189static inline u8 FAN_TO_REG(long rpm, int div)
190{
191        if (rpm == 0)
192                return 255;
193        rpm = SENSORS_LIMIT(rpm, 1, 1000000);
194        return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
195                             254);
196}
197
198#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
199
200#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\
201                                                 ((val)+5)/10),0,255))
202#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10)
203
204#define AS99127_TEMP_ADD_TO_REG(val) (SENSORS_LIMIT((((((val) + 2)*4)/10) \
205                                               << 7),0,0xffff))
206#define AS99127_TEMP_ADD_FROM_REG(val) ((((val) >> 7) * 10) / 4)
207
208#define ALARMS_FROM_REG(val) (val)
209#define PWM_FROM_REG(val) (val)
210#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255))
211#define BEEPS_FROM_REG(val) (val)
212#define BEEPS_TO_REG(val) ((val) & 0xffffff)
213
214#define BEEP_ENABLE_TO_REG(val)   ((val)?1:0)
215#define BEEP_ENABLE_FROM_REG(val) ((val)?1:0)
216
217#define DIV_FROM_REG(val) (1 << (val))
218
219static inline u8 DIV_TO_REG(long val, enum chips type)
220{
221        int i;
222        val = SENSORS_LIMIT(val, 1,
223                ((type == w83781d || type == as99127f) ? 8 : 128)) >> 1;
224        for (i = 0; i < 6; i++) {
225                if (val == 0)
226                        break;
227                val >>= 1;
228        }
229        return ((u8) i);
230}
231
232/* There are some complications in a module like this. First off, W83781D chips
233   may be both present on the SMBus and the ISA bus, and we have to handle
234   those cases separately at some places. Second, there might be several
235   W83781D chips available (well, actually, that is probably never done; but
236   it is a clean illustration of how to handle a case like that). Finally,
237   a specific chip may be attached to *both* ISA and SMBus, and we would
238   not like to detect it double. Fortunately, in the case of the W83781D at
239   least, a register tells us what SMBus address we are on, so that helps
240   a bit - except if there could be more than one SMBus. Groan. No solution
241   for this yet. */
242
243/* This module may seem overly long and complicated. In fact, it is not so
244   bad. Quite a lot of bookkeeping is done. A real driver can often cut
245   some corners. */
246
247/* For each registered W83781D, we need to keep some data in memory. That
248   data is pointed to by w83781d_list[NR]->data. The structure itself is
249   dynamically allocated, at the same time when a new w83781d client is
250   allocated. */
251struct w83781d_data {
252        struct semaphore lock;
253        int sysctl_id;
254        enum chips type;
255
256        struct semaphore update_lock;
257        char valid;             /* !=0 if following fields are valid */
258        unsigned long last_updated;     /* In jiffies */
259
260        struct i2c_client *lm75;        /* for secondary I2C addresses */
261        /* pointer to array of 2 subclients */
262
263        u8 in[10];              /* Register value - 8 & 9 for 782D and 791D only 10 for 791D */
264        u8 in_max[10];          /* Register value - 8 & 9 for 782D and 791D only 10 for 791D */
265        u8 in_min[10];          /* Register value - 8 & 9 for 782D and 791D only 10 for 791D */
266        u8 fan[5];              /* Register value - 4 & 5 for 791D only */
267        u8 fan_min[5];          /* Register value - 4 & 5 for 791D only */
268        u8 temp;
269        u8 temp_over;           /* Register value */
270        u8 temp_hyst;           /* Register value */
271        u16 temp_add[2];        /* Register value */
272        u16 temp_add_over[2];   /* Register value */
273        u16 temp_add_hyst[2];   /* Register value */
274        u8 fan_div[3];          /* Register encoding, shifted right */
275        u8 vid;                 /* Register encoding, combined */
276        u32 alarms;             /* Register encoding, combined */
277        u32 beeps;              /* Register encoding, combined */
278        u8 beep_enable;         /* Boolean */
279        u8 pwm[4];              /* Register value */
280        u8 pwmenable[4];        /* bool */
281        u16 sens[3];            /* 782D/783S only.
282                                   1 = pentium diode; 2 = 3904 diode;
283                                   3000-5000 = thermistor beta.
284                                   Default = 3435.
285                                   Other Betas unimplemented */
286#ifdef W83781D_RT
287        u8 rt[3][32];           /* Register value */
288#endif
289        u8 vrm;
290};
291
292
293static int w83781d_attach_adapter(struct i2c_adapter *adapter);
294static int w83781d_detect(struct i2c_adapter *adapter, int address,
295                          unsigned short flags, int kind);
296static int w83781d_detach_client(struct i2c_client *client);
297
298static int w83781d_read_value(struct i2c_client *client, u16 register);
299static int w83781d_write_value(struct i2c_client *client, u16 register,
300                               u16 value);
301static void w83781d_update_client(struct i2c_client *client);
302static void w83781d_init_client(struct i2c_client *client);
303
304
305static void w83781d_in(struct i2c_client *client, int operation,
306                       int ctl_name, int *nrels_mag, long *results);
307static void w83781d_fan(struct i2c_client *client, int operation,
308                        int ctl_name, int *nrels_mag, long *results);
309static void w83781d_temp(struct i2c_client *client, int operation,
310                         int ctl_name, int *nrels_mag, long *results);
311static void w83781d_temp_add(struct i2c_client *client, int operation,
312                             int ctl_name, int *nrels_mag, long *results);
313static void w83781d_vid(struct i2c_client *client, int operation,
314                        int ctl_name, int *nrels_mag, long *results);
315static void w83781d_vrm(struct i2c_client *client, int operation,
316                        int ctl_name, int *nrels_mag, long *results);
317static void w83781d_alarms(struct i2c_client *client, int operation,
318                           int ctl_name, int *nrels_mag, long *results);
319static void w83781d_beep(struct i2c_client *client, int operation,
320                         int ctl_name, int *nrels_mag, long *results);
321static void w83781d_fan_div(struct i2c_client *client, int operation,
322                            int ctl_name, int *nrels_mag, long *results);
323static void w83781d_pwm(struct i2c_client *client, int operation,
324                        int ctl_name, int *nrels_mag, long *results);
325static void w83781d_sens(struct i2c_client *client, int operation,
326                         int ctl_name, int *nrels_mag, long *results);
327#ifdef W83781D_RT
328static void w83781d_rt(struct i2c_client *client, int operation,
329                       int ctl_name, int *nrels_mag, long *results);
330#endif
331static u16 swap_bytes(u16 val);
332
333static int w83781d_id = 0;
334
335static struct i2c_driver w83781d_driver = {
336        .owner          = THIS_MODULE,
337        .name           = "W83781D sensor driver",
338        .id             = I2C_DRIVERID_W83781D,
339        .flags          = I2C_DF_NOTIFY,
340        .attach_adapter = w83781d_attach_adapter,
341        .detach_client  = w83781d_detach_client,
342};
343
344/* The /proc/sys entries */
345/* -- SENSORS SYSCTL START -- */
346
347#define W83781D_SYSCTL_IN0 1000 /* Volts * 100 */
348#define W83781D_SYSCTL_IN1 1001
349#define W83781D_SYSCTL_IN2 1002
350#define W83781D_SYSCTL_IN3 1003
351#define W83781D_SYSCTL_IN4 1004
352#define W83781D_SYSCTL_IN5 1005
353#define W83781D_SYSCTL_IN6 1006
354#define W83781D_SYSCTL_IN7 1007
355#define W83781D_SYSCTL_IN8 1008
356#define W83781D_SYSCTL_IN9 1009
357#define W83781D_SYSCTL_FAN1 1101        /* Rotations/min */
358#define W83781D_SYSCTL_FAN2 1102
359#define W83781D_SYSCTL_FAN3 1103
360#define W83781D_SYSCTL_FAN4 1104
361#define W83781D_SYSCTL_FAN5 1105
362
363#define W83781D_SYSCTL_TEMP1 1200       /* Degrees Celcius * 10 */
364#define W83781D_SYSCTL_TEMP2 1201       /* Degrees Celcius * 10 */
365#define W83781D_SYSCTL_TEMP3 1202       /* Degrees Celcius * 10 */
366#define W83781D_SYSCTL_VID 1300         /* Volts * 1000 */
367#define W83781D_SYSCTL_VRM 1301
368#define W83781D_SYSCTL_PWM1 1401
369#define W83781D_SYSCTL_PWM2 1402
370#define W83781D_SYSCTL_PWM3 1403
371#define W83781D_SYSCTL_PWM4 1404
372#define W83781D_SYSCTL_SENS1 1501       /* 1, 2, or Beta (3000-5000) */
373#define W83781D_SYSCTL_SENS2 1502
374#define W83781D_SYSCTL_SENS3 1503
375#define W83781D_SYSCTL_RT1   1601       /* 32-entry table */
376#define W83781D_SYSCTL_RT2   1602       /* 32-entry table */
377#define W83781D_SYSCTL_RT3   1603       /* 32-entry table */
378#define W83781D_SYSCTL_FAN_DIV 2000     /* 1, 2, 4 or 8 */
379#define W83781D_SYSCTL_ALARMS 2001      /* bitvector */
380#define W83781D_SYSCTL_BEEP 2002        /* bitvector */
381
382#define W83781D_ALARM_IN0 0x0001
383#define W83781D_ALARM_IN1 0x0002
384#define W83781D_ALARM_IN2 0x0004
385#define W83781D_ALARM_IN3 0x0008
386#define W83781D_ALARM_IN4 0x0100
387#define W83781D_ALARM_IN5 0x0200
388#define W83781D_ALARM_IN6 0x0400
389#define W83782D_ALARM_IN7 0x10000
390#define W83782D_ALARM_IN8 0x20000
391#define W83781D_ALARM_FAN1 0x0040
392#define W83781D_ALARM_FAN2 0x0080
393#define W83781D_ALARM_FAN3 0x0800
394#define W83781D_ALARM_TEMP1 0x0010
395#define W83781D_ALARM_TEMP23 0x0020     /* 781D only */
396#define W83781D_ALARM_TEMP2 0x0020      /* 782D/783S */
397#define W83781D_ALARM_TEMP3 0x2000      /* 782D only */
398#define W83781D_ALARM_CHAS 0x1000
399
400/* -- SENSORS SYSCTL END -- */
401
402/* These files are created for each detected chip. This is just a template;
403   though at first sight, you might think we could use a statically
404   allocated list, we need some way to get back to the parent - which
405   is done through one of the 'extra' fields which are initialized
406   when a new copy is allocated. */
407
408/* just a guess - no datasheet */
409static ctl_table as99127f_dir_table_template[] = {
410        {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
411         &i2c_sysctl_real, NULL, &w83781d_in},
412        {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real,
413         &i2c_sysctl_real, NULL, &w83781d_in},
414        {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
415         &i2c_sysctl_real, NULL, &w83781d_in},
416        {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
417         &i2c_sysctl_real, NULL, &w83781d_in},
418        {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
419         &i2c_sysctl_real, NULL, &w83781d_in},
420        {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real,
421         &i2c_sysctl_real, NULL, &w83781d_in},
422        {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real,
423         &i2c_sysctl_real, NULL, &w83781d_in},
424        {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
425         &i2c_sysctl_real, NULL, &w83781d_fan},
426        {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
427         &i2c_sysctl_real, NULL, &w83781d_fan},
428        {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real,
429         &i2c_sysctl_real, NULL, &w83781d_fan},
430        {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
431         &i2c_sysctl_real, NULL, &w83781d_temp},
432        {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real,
433         &i2c_sysctl_real, NULL, &w83781d_temp_add},
434        {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real,
435         &i2c_sysctl_real, NULL, &w83781d_temp_add},
436        {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real,
437         &i2c_sysctl_real, NULL, &w83781d_vid},
438        {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real,
439         &i2c_sysctl_real, NULL, &w83781d_vrm},
440        {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
441         &i2c_sysctl_real, NULL, &w83781d_fan_div},
442        {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
443         &i2c_sysctl_real, NULL, &w83781d_alarms},
444        {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real,
445         &i2c_sysctl_real, NULL, &w83781d_beep},
446        {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
447         &i2c_sysctl_real, NULL, &w83781d_pwm},
448        {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real,
449         &i2c_sysctl_real, NULL, &w83781d_pwm},
450        {0}
451};
452
453static ctl_table w83781d_dir_table_template[] = {
454        {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
455         &i2c_sysctl_real, NULL, &w83781d_in},
456        {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real,
457         &i2c_sysctl_real, NULL, &w83781d_in},
458        {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
459         &i2c_sysctl_real, NULL, &w83781d_in},
460        {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
461         &i2c_sysctl_real, NULL, &w83781d_in},
462        {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
463         &i2c_sysctl_real, NULL, &w83781d_in},
464        {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real,
465         &i2c_sysctl_real, NULL, &w83781d_in},
466        {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real,
467         &i2c_sysctl_real, NULL, &w83781d_in},
468        {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
469         &i2c_sysctl_real, NULL, &w83781d_fan},
470        {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
471         &i2c_sysctl_real, NULL, &w83781d_fan},
472        {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real,
473         &i2c_sysctl_real, NULL, &w83781d_fan},
474        {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
475         &i2c_sysctl_real, NULL, &w83781d_temp},
476        {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real,
477         &i2c_sysctl_real, NULL, &w83781d_temp_add},
478        {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real,
479         &i2c_sysctl_real, NULL, &w83781d_temp_add},
480        {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real,
481         &i2c_sysctl_real, NULL, &w83781d_vid},
482        {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real,
483         &i2c_sysctl_real, NULL, &w83781d_vrm},
484        {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
485         &i2c_sysctl_real, NULL, &w83781d_fan_div},
486        {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
487         &i2c_sysctl_real, NULL, &w83781d_alarms},
488        {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real,
489         &i2c_sysctl_real, NULL, &w83781d_beep},
490#ifdef W83781D_RT
491        {W83781D_SYSCTL_RT1, "rt1", NULL, 0, 0644, NULL, &i2c_proc_real,
492         &i2c_sysctl_real, NULL, &w83781d_rt},
493        {W83781D_SYSCTL_RT2, "rt2", NULL, 0, 0644, NULL, &i2c_proc_real,
494         &i2c_sysctl_real, NULL, &w83781d_rt},
495        {W83781D_SYSCTL_RT3, "rt3", NULL, 0, 0644, NULL, &i2c_proc_real,
496         &i2c_sysctl_real, NULL, &w83781d_rt},
497#endif
498        {0}
499};
500
501/* without pwm3-4 */
502static ctl_table w83782d_isa_dir_table_template[] = {
503        {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
504         &i2c_sysctl_real, NULL, &w83781d_in},
505        {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real,
506         &i2c_sysctl_real, NULL, &w83781d_in},
507        {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
508         &i2c_sysctl_real, NULL, &w83781d_in},
509        {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
510         &i2c_sysctl_real, NULL, &w83781d_in},
511        {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
512         &i2c_sysctl_real, NULL, &w83781d_in},
513        {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real,
514         &i2c_sysctl_real, NULL, &w83781d_in},
515        {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real,
516         &i2c_sysctl_real, NULL, &w83781d_in},
517        {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real,
518         &i2c_sysctl_real, NULL, &w83781d_in},
519        {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real,
520         &i2c_sysctl_real, NULL, &w83781d_in},
521        {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
522         &i2c_sysctl_real, NULL, &w83781d_fan},
523        {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
524         &i2c_sysctl_real, NULL, &w83781d_fan},
525        {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real,
526         &i2c_sysctl_real, NULL, &w83781d_fan},
527        {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
528         &i2c_sysctl_real, NULL, &w83781d_temp},
529        {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real,
530         &i2c_sysctl_real, NULL, &w83781d_temp_add},
531        {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real,
532         &i2c_sysctl_real, NULL, &w83781d_temp_add},
533        {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real,
534         &i2c_sysctl_real, NULL, &w83781d_vid},
535        {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real,
536         &i2c_sysctl_real, NULL, &w83781d_vrm},
537        {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
538         &i2c_sysctl_real, NULL, &w83781d_fan_div},
539        {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
540         &i2c_sysctl_real, NULL, &w83781d_alarms},
541        {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real,
542         &i2c_sysctl_real, NULL, &w83781d_beep},
543        {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
544         &i2c_sysctl_real, NULL, &w83781d_pwm},
545        {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real,
546         &i2c_sysctl_real, NULL, &w83781d_pwm},
547        {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real,
548         &i2c_sysctl_real, NULL, &w83781d_sens},
549        {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real,
550         &i2c_sysctl_real, NULL, &w83781d_sens},
551        {W83781D_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &i2c_proc_real,
552         &i2c_sysctl_real, NULL, &w83781d_sens},
553        {0}
554};
555
556/* with pwm3-4 */
557static ctl_table w83782d_i2c_dir_table_template[] = {
558        {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
559         &i2c_sysctl_real, NULL, &w83781d_in},
560        {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real,
561         &i2c_sysctl_real, NULL, &w83781d_in},
562        {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
563         &i2c_sysctl_real, NULL, &w83781d_in},
564        {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
565         &i2c_sysctl_real, NULL, &w83781d_in},
566        {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
567         &i2c_sysctl_real, NULL, &w83781d_in},
568        {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real,
569         &i2c_sysctl_real, NULL, &w83781d_in},
570        {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real,
571         &i2c_sysctl_real, NULL, &w83781d_in},
572        {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real,
573         &i2c_sysctl_real, NULL, &w83781d_in},
574        {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real,
575         &i2c_sysctl_real, NULL, &w83781d_in},
576        {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
577         &i2c_sysctl_real, NULL, &w83781d_fan},
578        {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
579         &i2c_sysctl_real, NULL, &w83781d_fan},
580        {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real,
581         &i2c_sysctl_real, NULL, &w83781d_fan},
582        {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
583         &i2c_sysctl_real, NULL, &w83781d_temp},
584        {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real,
585         &i2c_sysctl_real, NULL, &w83781d_temp_add},
586        {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real,
587         &i2c_sysctl_real, NULL, &w83781d_temp_add},
588        {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real,
589         &i2c_sysctl_real, NULL, &w83781d_vid},
590        {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real,
591         &i2c_sysctl_real, NULL, &w83781d_vrm},
592        {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
593         &i2c_sysctl_real, NULL, &w83781d_fan_div},
594        {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
595         &i2c_sysctl_real, NULL, &w83781d_alarms},
596        {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real,
597         &i2c_sysctl_real, NULL, &w83781d_beep},
598        {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
599         &i2c_sysctl_real, NULL, &w83781d_pwm},
600        {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real,
601         &i2c_sysctl_real, NULL, &w83781d_pwm},
602        {W83781D_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, &i2c_proc_real,
603         &i2c_sysctl_real, NULL, &w83781d_pwm},
604        {W83781D_SYSCTL_PWM4, "pwm4", NULL, 0, 0644, NULL, &i2c_proc_real,
605         &i2c_sysctl_real, NULL, &w83781d_pwm},
606        {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real,
607         &i2c_sysctl_real, NULL, &w83781d_sens},
608        {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real,
609         &i2c_sysctl_real, NULL, &w83781d_sens},
610        {W83781D_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &i2c_proc_real,
611         &i2c_sysctl_real, NULL, &w83781d_sens},
612        {0}
613};
614
615/* w83791D has 10 voltages 5 fans and 3 temps.  2 of the temps are on other
616 devices. */
617static ctl_table w83791d_dir_table_template[] = {
618        {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
619         &i2c_sysctl_real, NULL, &w83781d_in},
620        {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real,
621         &i2c_sysctl_real, NULL, &w83781d_in},
622        {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
623         &i2c_sysctl_real, NULL, &w83781d_in},
624        {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
625         &i2c_sysctl_real, NULL, &w83781d_in},
626        {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
627         &i2c_sysctl_real, NULL, &w83781d_in},
628        {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real,
629         &i2c_sysctl_real, NULL, &w83781d_in},
630        {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real,
631         &i2c_sysctl_real, NULL, &w83781d_in},
632        {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real,
633         &i2c_sysctl_real, NULL, &w83781d_in},
634        {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real,
635         &i2c_sysctl_real, NULL, &w83781d_in},
636        {W83781D_SYSCTL_IN9, "in9", NULL, 0, 0644, NULL, &i2c_proc_real,
637         &i2c_sysctl_real, NULL, &w83781d_in},
638        {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
639         &i2c_sysctl_real, NULL, &w83781d_fan},
640        {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
641         &i2c_sysctl_real, NULL, &w83781d_fan},
642        {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real,
643         &i2c_sysctl_real, NULL, &w83781d_fan},
644        {W83781D_SYSCTL_FAN4, "fan4", NULL, 0, 0644, NULL, &i2c_proc_real,
645         &i2c_sysctl_real, NULL, &w83781d_fan},
646        {W83781D_SYSCTL_FAN5, "fan5", NULL, 0, 0644, NULL, &i2c_proc_real,
647         &i2c_sysctl_real, NULL, &w83781d_fan},
648        {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
649         &i2c_sysctl_real, NULL, &w83781d_temp},
650        {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real,
651         &i2c_sysctl_real, NULL, &w83781d_temp_add},
652        {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real,
653         &i2c_sysctl_real, NULL, &w83781d_temp_add},
654        {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real,
655         &i2c_sysctl_real, NULL, &w83781d_vid},
656        {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
657         &i2c_sysctl_real, NULL, &w83781d_fan_div},
658        {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
659         &i2c_sysctl_real, NULL, &w83781d_alarms},
660        {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real,
661         &i2c_sysctl_real, NULL, &w83781d_beep},
662        {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
663         &i2c_sysctl_real, NULL, &w83781d_pwm},
664        {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real,
665         &i2c_sysctl_real, NULL, &w83781d_pwm},
666        {W83781D_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, &i2c_proc_real,
667         &i2c_sysctl_real, NULL, &w83781d_pwm},
668        {W83781D_SYSCTL_PWM4, "pwm4", NULL, 0, 0644, NULL, &i2c_proc_real,
669         &i2c_sysctl_real, NULL, &w83781d_pwm},
670        {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real,
671         &i2c_sysctl_real, NULL, &w83781d_vrm},
672        {0}
673};
674
675static ctl_table w83783s_dir_table_template[] = {
676        {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
677         &i2c_sysctl_real, NULL, &w83781d_in},
678        /* no in1 to maintain compatibility with 781d and 782d. */
679        {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
680         &i2c_sysctl_real, NULL, &w83781d_in},
681        {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
682         &i2c_sysctl_real, NULL, &w83781d_in},
683        {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
684         &i2c_sysctl_real, NULL, &w83781d_in},
685        {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real,
686         &i2c_sysctl_real, NULL, &w83781d_in},
687        {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real,
688         &i2c_sysctl_real, NULL, &w83781d_in},
689        {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
690         &i2c_sysctl_real, NULL, &w83781d_fan},
691        {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
692         &i2c_sysctl_real, NULL, &w83781d_fan},
693        {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real,
694         &i2c_sysctl_real, NULL, &w83781d_fan},
695        {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
696         &i2c_sysctl_real, NULL, &w83781d_temp},
697        {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real,
698         &i2c_sysctl_real, NULL, &w83781d_temp_add},
699        {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real,
700         &i2c_sysctl_real, NULL, &w83781d_vid},
701        {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real,
702         &i2c_sysctl_real, NULL, &w83781d_vrm},
703        {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
704         &i2c_sysctl_real, NULL, &w83781d_fan_div},
705        {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
706         &i2c_sysctl_real, NULL, &w83781d_alarms},
707        {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real,
708         &i2c_sysctl_real, NULL, &w83781d_beep},
709        {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
710         &i2c_sysctl_real, NULL, &w83781d_pwm},
711        {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real,
712         &i2c_sysctl_real, NULL, &w83781d_pwm},
713        {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real,
714         &i2c_sysctl_real, NULL, &w83781d_sens},
715        {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real,
716         &i2c_sysctl_real, NULL, &w83781d_sens},
717        {0}
718};
719
720/* similar to w83782d but no fan3, no vid */
721static ctl_table w83697hf_dir_table_template[] = {
722        {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
723         &i2c_sysctl_real, NULL, &w83781d_in},
724        /* no in1 to maintain compatibility with 781d and 782d. */
725        {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
726         &i2c_sysctl_real, NULL, &w83781d_in},
727        {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
728         &i2c_sysctl_real, NULL, &w83781d_in},
729        {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
730         &i2c_sysctl_real, NULL, &w83781d_in},
731        {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real,
732         &i2c_sysctl_real, NULL, &w83781d_in},
733        {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real,
734         &i2c_sysctl_real, NULL, &w83781d_in},
735        {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real,
736         &i2c_sysctl_real, NULL, &w83781d_in},
737        {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real,
738         &i2c_sysctl_real, NULL, &w83781d_in},
739        {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
740         &i2c_sysctl_real, NULL, &w83781d_fan},
741        {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
742         &i2c_sysctl_real, NULL, &w83781d_fan},
743        {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
744         &i2c_sysctl_real, NULL, &w83781d_temp},
745        {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real,
746         &i2c_sysctl_real, NULL, &w83781d_temp_add},
747        {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
748         &i2c_sysctl_real, NULL, &w83781d_fan_div},
749        {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
750         &i2c_sysctl_real, NULL, &w83781d_alarms},
751        {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real,
752         &i2c_sysctl_real, NULL, &w83781d_beep},
753        {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
754         &i2c_sysctl_real, NULL, &w83781d_pwm},
755        {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real,
756         &i2c_sysctl_real, NULL, &w83781d_pwm},
757        {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real,
758         &i2c_sysctl_real, NULL, &w83781d_sens},
759        {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real,
760         &i2c_sysctl_real, NULL, &w83781d_sens},
761        {0}
762};
763
764
765/* This function is called when:
766     * w83781d_driver is inserted (when this module is loaded), for each
767       available adapter
768     * when a new adapter is inserted (and w83781d_driver is still present) */
769static int w83781d_attach_adapter(struct i2c_adapter *adapter)
770{
771        return i2c_detect(adapter, &addr_data, w83781d_detect);
772}
773
774static int w83781d_detect(struct i2c_adapter *adapter, int address,
775                  unsigned short flags, int kind)
776{
777        int i, val1 = 0, val2, id;
778        struct i2c_client *new_client;
779        struct w83781d_data *data;
780        int err = 0;
781        const char *type_name = "";
782        const char *client_name = "";
783        int is_isa = i2c_is_isa_adapter(adapter);
784        enum vendor { winbond, asus } vendid;
785
786        if (!is_isa
787            && !i2c_check_functionality(adapter,
788                                        I2C_FUNC_SMBUS_BYTE_DATA)) goto
789                    ERROR0;
790
791       if (is_isa) {
792               if (!request_region(address, W83781D_EXTENT, "w83781d"))
793                       goto ERROR0;
794               release_region(address, W83781D_EXTENT);
795       }
796
797        /* Probe whether there is anything available on this address. Already
798           done for SMBus clients */
799        if (kind < 0) {
800                if (is_isa) {
801
802#define REALLY_SLOW_IO
803                        /* We need the timeouts for at least some LM78-like chips. But only
804                           if we read 'undefined' registers. */
805                        i = inb_p(address + 1);
806                        if (inb_p(address + 2) != i)
807                                goto ERROR0;
808                        if (inb_p(address + 3) != i)
809                                goto ERROR0;
810                        if (inb_p(address + 7) != i)
811                                goto ERROR0;
812#undef REALLY_SLOW_IO
813
814                        /* Let's just hope nothing breaks here */
815                        i = inb_p(address + 5) & 0x7f;
816                        outb_p(~i & 0x7f, address + 5);
817                        if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
818                                outb_p(i, address + 5);
819                                return 0;
820                        }
821                }
822        }
823
824        /* OK. For now, we presume we have a valid client. We now create the
825           client structure, even though we cannot fill it completely yet.
826           But it allows us to access w83781d_{read,write}_value. */
827
828        if (!(new_client = kmalloc(sizeof(struct i2c_client) +
829                                   sizeof(struct w83781d_data),
830                                   GFP_KERNEL))) {
831                err = -ENOMEM;
832                goto ERROR0;
833        }
834
835        data = (struct w83781d_data *) (new_client + 1);
836        new_client->addr = address;
837        init_MUTEX(&data->lock);
838        new_client->data = data;
839        new_client->adapter = adapter;
840        new_client->driver = &w83781d_driver;
841        new_client->flags = 0;
842
843        /* Now, we do the remaining detection. */
844
845        /* The w8378?d may be stuck in some other bank than bank 0. This may
846           make reading other information impossible. Specify a force=... or
847           force_*=... parameter, and the Winbond will be reset to the right
848           bank. */
849        if (kind < 0) {
850                if (w83781d_read_value(new_client, W83781D_REG_CONFIG) &
851                    0x80) {
852                        err = -ENODEV;
853                        goto ERROR1;
854                }
855                val1 = w83781d_read_value(new_client, W83781D_REG_BANK);
856                val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN);
857                /* Check for Winbond or Asus ID if in bank 0 */
858                if ((!(val1 & 0x07)) &&
859                    (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3) 
860                         && (val2 != 0x94))
861                     || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)
862                         && (val2 != 0x06)))) {
863                        err = -ENODEV;
864                        goto ERROR1;
865                }
866                /* If Winbond SMBus, check address at 0x48. Asus doesn't support
867                   except maybe (hopefully) for the as99127f rev.2 */
868                if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) ||
869                                  ((val1 & 0x80) && (val2 == 0x5c)))) {
870                        if (w83781d_read_value
871                            (new_client, W83781D_REG_I2C_ADDR) != address) {
872                                err = -ENODEV;
873                                goto ERROR1;
874                        }
875                }
876        }
877
878        /* We have either had a force parameter, or we have already detected the
879           Winbond. Put it now into bank 0 and Vendor ID High Byte */
880        w83781d_write_value(new_client, W83781D_REG_BANK,
881                            (w83781d_read_value(new_client,
882                                                W83781D_REG_BANK) & 0x78) |
883                            0x80);
884
885        /* Determine the chip type. */
886        if (kind <= 0) {
887                /* get vendor ID */
888                val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN);
889                if (val2 == 0x5c)
890                        vendid = winbond;
891                else if ((val2 == 0x12) || (val2 == 0x06))
892                        vendid = asus;
893                else {
894                        err = -ENODEV;
895                        goto ERROR1;
896                }
897                val1 =
898                    w83781d_read_value(new_client, W83781D_REG_WCHIPID);
899                if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
900                        kind = w83781d;
901                else if (val1 == 0x30 && vendid == winbond)
902                        kind = w83782d;
903                else if (val1 == 0x40 && vendid == winbond && !is_isa && address == 0x2d)
904                        kind = w83783s;
905                else if (val1 == 0x21 && vendid == winbond)
906                        kind = w83627hf;
907                else if (val1 == 0x71 && vendid == winbond && address >= 0x2c)
908                        kind = w83791d;
909                else if (val1 == 0x31 && !is_isa && address >= 0x28)
910                        kind = as99127f;
911                else if (val1 == 0x60 && vendid == winbond && is_isa)
912                        kind = w83697hf;
913                else {
914                        if (kind == 0)
915                                printk
916                                    (KERN_WARNING "w83781d.o: Ignoring 'force' parameter for unknown chip at"
917                                     "adapter %d, address 0x%02x\n",
918                                     i2c_adapter_id(adapter), address);
919                        err = -EINVAL;
920                        goto ERROR1;
921                }
922        }
923
924        if (kind == w83781d) {
925                type_name = "w83781d";
926                client_name = "W83781D chip";
927        } else if (kind == w83782d) {
928                type_name = "w83782d";
929                client_name = "W83782D chip";
930        } else if (kind == w83783s) {
931                type_name = "w83783s";
932                client_name = "W83783S chip";
933        } else if (kind == w83627hf) {
934                type_name = "w83627hf";
935                client_name = "W83627HF chip";
936        } else if (kind == as99127f) {
937                type_name = "as99127f";
938                client_name = "AS99127F chip";
939        } else if (kind == w83697hf) {
940                type_name = "w83697hf";
941                client_name = "W83697HF chip";
942        } else if (kind == w83791d) {
943                type_name = "w83791d";
944                client_name = "W83791D chip";
945        } else {
946#ifdef DEBUG
947                printk(KERN_ERR "w83781d.o: Internal error: unknown kind (%d)?!?",
948                       kind);
949#endif
950                err = -ENODEV;
951                goto ERROR1;
952        }
953
954        /* Reserve the ISA region */
955        if (is_isa)
956                request_region(address, W83781D_EXTENT, type_name);
957
958        /* Fill in the remaining client fields and put it into the global list */
959        strcpy(new_client->name, client_name);
960        data->type = kind;
961
962        new_client->id = w83781d_id++;
963        data->valid = 0;
964        init_MUTEX(&data->update_lock);
965
966        /* Tell the I2C layer a new client has arrived */
967        if ((err = i2c_attach_client(new_client)))
968                goto ERROR3;
969
970        /* attach secondary i2c lm75-like clients */
971        if (!is_isa) {
972                if (!(data->lm75 = kmalloc(2 * sizeof(struct i2c_client),
973                                           GFP_KERNEL))) {
974                        err = -ENOMEM;
975                        goto ERROR4;
976                }
977                id = i2c_adapter_id(adapter);
978                if(force_subclients[0] == id && force_subclients[1] == address) {
979                        for(i = 2; i <= 3; i++) {
980                                if(force_subclients[i] < 0x48 ||
981                                   force_subclients[i] > 0x4f) {
982                                        printk(KERN_ERR "w83781d.o: Invalid subclient address %d; must be 0x48-0x4f\n",
983                                                force_subclients[i]);
984                                        err = -EINVAL;
985                                        goto ERROR5;
986                                }
987                        }
988                        w83781d_write_value(new_client,
989                                            W83781D_REG_I2C_SUBADDR,
990                                            (force_subclients[2] & 0x07) |
991                                            ((force_subclients[3] & 0x07) <<4));
992                        data->lm75[0].addr = force_subclients[2];
993                } else {
994                        val1 = w83781d_read_value(new_client,
995                                                  W83781D_REG_I2C_SUBADDR);
996                        data->lm75[0].addr = 0x48 + (val1 & 0x07);
997                }
998                if (kind != w83783s) {
999                        if(force_subclients[0] == id &&
1000                           force_subclients[1] == address) {
1001                                data->lm75[1].addr = force_subclients[3];
1002                        } else {
1003                                data->lm75[1].addr = 0x48 + ((val1 >> 4) & 0x07);
1004                        }
1005                        if(data->lm75[0].addr == data->lm75[1].addr) {
1006                                printk(KERN_ERR "w83781d.o: Duplicate addresses 0x%x for subclients.\n",
1007                                        data->lm75[0].addr);
1008                                err = -EBUSY;
1009                                goto ERROR5;
1010                        }
1011                }
1012                if (kind == w83781d)
1013                        client_name = "W83781D subclient";
1014                else if (kind == w83782d)
1015                        client_name = "W83782D subclient";
1016                else if (kind == w83783s)
1017                        client_name = "W83783S subclient";
1018                else if (kind == w83627hf)
1019                        client_name = "W83627HF subclient";
1020                else if (kind == as99127f)
1021                        client_name = "AS99127F subclient";
1022                else if (kind == w83791d)
1023                        client_name = "W83791D subclient";
1024
1025
1026                for (i = 0; i <= 1; i++) {
1027                        data->lm75[i].data = NULL;      /* store all data in w83781d */
1028                        data->lm75[i].adapter = adapter;
1029                        data->lm75[i].driver = &w83781d_driver;
1030                        data->lm75[i].flags = 0;
1031                        strcpy(data->lm75[i].name, client_name);
1032                        data->lm75[i].id = w83781d_id++;
1033                        if ((err = i2c_attach_client(&(data->lm75[i])))) {
1034                                printk(KERN_ERR "w83781d.o: Subclient %d registration at address 0x%x failed.\n",
1035                                       i, data->lm75[i].addr);
1036                                if (i == 1)
1037                                        goto ERROR6;
1038                                goto ERROR5;
1039                        }
1040                        if (kind == w83783s)
1041                                break;
1042                }
1043        } else {
1044                data->lm75 = NULL;
1045        }
1046
1047        /* Register a new directory entry with module sensors */
1048        if ((i = i2c_register_entry(new_client,
1049                                        type_name,
1050                                        (kind == as99127f) ?
1051                                           as99127f_dir_table_template :
1052                                        (kind == w83781d) ?
1053                                           w83781d_dir_table_template :
1054                                        (kind == w83783s) ?
1055                                           w83783s_dir_table_template :
1056                                        (kind == w83697hf) ?
1057                                           w83697hf_dir_table_template :
1058                                        (kind == w83791d ) ?
1059                                            w83791d_dir_table_template :
1060                                        (is_isa || kind == w83627hf) ?
1061                                           w83782d_isa_dir_table_template :
1062                                           w83782d_i2c_dir_table_template)) < 0) {
1063                err = i;
1064                goto ERROR7;
1065        }
1066        data->sysctl_id = i;
1067
1068        /* Initialize the chip */
1069        w83781d_init_client(new_client);
1070        return 0;
1071
1072/* OK, this is not exactly good programming practice, usually. But it is
1073   very code-efficient in this case. */
1074
1075      ERROR7:
1076        if (!is_isa)
1077                i2c_detach_client(&
1078                                  (((struct
1079                                     w83781d_data *) (new_client->data))->
1080                                   lm75[1]));
1081      ERROR6:
1082        if (!is_isa)
1083                i2c_detach_client(&
1084                                  (((struct
1085                                     w83781d_data *) (new_client->data))->
1086                                   lm75[0]));
1087      ERROR5:
1088        if (!is_isa)
1089                kfree(((struct w83781d_data *) (new_client->data))->lm75);
1090      ERROR4:
1091        i2c_detach_client(new_client);
1092      ERROR3:
1093        if (is_isa)
1094                release_region(address, W83781D_EXTENT);
1095      ERROR1:
1096        kfree(new_client);
1097      ERROR0:
1098        return err;
1099}
1100
1101static int w83781d_detach_client(struct i2c_client *client)
1102{
1103        int err;
1104
1105        i2c_deregister_entry(((struct w83781d_data *) (client->data))->
1106                                 sysctl_id);
1107
1108        if ((err = i2c_detach_client(client))) {
1109                printk
1110                    (KERN_ERR "w83781d.o: Client deregistration failed, client not detached.\n");
1111                return err;
1112        }
1113
1114        if(i2c_is_isa_client(client)) {
1115                release_region(client->addr, W83781D_EXTENT);
1116        } else {
1117                i2c_detach_client(&
1118                                  (((struct
1119                                     w83781d_data *) (client->data))->
1120                                   lm75[0]));
1121                if((((struct w83781d_data *) (client->data))->type) != w83783s)
1122                        i2c_detach_client(&
1123                                  (((struct
1124                                     w83781d_data *) (client->data))->
1125                                   lm75[1]));
1126                kfree(((struct w83781d_data *) (client->data))->lm75);
1127        }
1128        kfree(client);
1129
1130        return 0;
1131}
1132
1133static inline u16 swap_bytes(u16 val)
1134{
1135        return (val >> 8) | (val << 8);
1136}
1137
1138/* The SMBus locks itself, usually, but nothing may access the Winbond between
1139   bank switches. ISA access must always be locked explicitly!
1140   We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
1141   would slow down the W83781D access and should not be necessary.
1142   There are some ugly typecasts here, but the good news is - they should
1143   nowhere else be necessary! */
1144static int w83781d_read_value(struct i2c_client *client, u16 reg)
1145{
1146        int res, word_sized, bank;
1147        struct i2c_client *cl;
1148
1149        down(&(((struct w83781d_data *) (client->data))->lock));
1150        if (i2c_is_isa_client(client)) {
1151                word_sized = (((reg & 0xff00) == 0x100)
1152                              || ((reg & 0xff00) == 0x200))
1153                    && (((reg & 0x00ff) == 0x50)
1154                        || ((reg & 0x00ff) == 0x53)
1155                        || ((reg & 0x00ff) == 0x55));
1156                if (reg & 0xff00) {
1157                        outb_p(W83781D_REG_BANK,
1158                               client->addr + W83781D_ADDR_REG_OFFSET);
1159                        outb_p(reg >> 8,
1160                               client->addr + W83781D_DATA_REG_OFFSET);
1161                }
1162                outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
1163                res = inb_p(client->addr + W83781D_DATA_REG_OFFSET);
1164                if (word_sized) {
1165                        outb_p((reg & 0xff) + 1,
1166                               client->addr + W83781D_ADDR_REG_OFFSET);
1167                        res =
1168                            (res << 8) + inb_p(client->addr +
1169                                               W83781D_DATA_REG_OFFSET);
1170                }
1171                if (reg & 0xff00) {
1172                        outb_p(W83781D_REG_BANK,
1173                               client->addr + W83781D_ADDR_REG_OFFSET);
1174                        outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
1175                }
1176        } else {
1177                bank = (reg >> 8) & 0x0f;
1178                if (bank > 2)
1179                        /* switch banks */
1180                        i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
1181                                                  bank);
1182                if (bank == 0 || bank > 2) {
1183                        res = i2c_smbus_read_byte_data(client, reg & 0xff);
1184                } else {
1185                        /* switch to subclient */
1186                        cl =
1187                            &(((struct w83781d_data *) (client->data))->
1188                              lm75[bank - 1]);
1189                        /* convert from ISA to LM75 I2C addresses */
1190                        switch (reg & 0xff) {
1191                        case 0x50: /* TEMP */
1192                                res =
1193                                    swap_bytes(i2c_smbus_read_word_data
1194                                               (cl, 0));
1195                                break;
1196                        case 0x52: /* CONFIG */
1197                                res = i2c_smbus_read_byte_data(cl, 1);
1198                                break;
1199                        case 0x53: /* HYST */
1200                                res =
1201                                    swap_bytes(i2c_smbus_read_word_data
1202                                               (cl, 2));
1203                                break;
1204                        case 0x55: /* OVER */
1205                        default:
1206                                res =
1207                                    swap_bytes(i2c_smbus_read_word_data
1208                                               (cl, 3));
1209                                break;
1210                        }
1211                }
1212                if (bank > 2)
1213                        i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
1214                                                  0);
1215        }
1216        up(&(((struct w83781d_data *) (client->data))->lock));
1217        return res;
1218}
1219
1220static int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
1221{
1222        int word_sized, bank;
1223        struct i2c_client *cl;
1224
1225        down(&(((struct w83781d_data *) (client->data))->lock));
1226        if (i2c_is_isa_client(client)) {
1227                word_sized = (((reg & 0xff00) == 0x100)
1228                              || ((reg & 0xff00) == 0x200))
1229                    && (((reg & 0x00ff) == 0x53)
1230                        || ((reg & 0x00ff) == 0x55));
1231                if (reg & 0xff00) {
1232                        outb_p(W83781D_REG_BANK,
1233                               client->addr + W83781D_ADDR_REG_OFFSET);
1234                        outb_p(reg >> 8,
1235                               client->addr + W83781D_DATA_REG_OFFSET);
1236                }
1237                outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
1238                if (word_sized) {
1239                        outb_p(value >> 8,
1240                               client->addr + W83781D_DATA_REG_OFFSET);
1241                        outb_p((reg & 0xff) + 1,
1242                               client->addr + W83781D_ADDR_REG_OFFSET);
1243                }
1244                outb_p(value & 0xff,
1245                       client->addr + W83781D_DATA_REG_OFFSET);
1246                if (reg & 0xff00) {
1247                        outb_p(W83781D_REG_BANK,
1248                               client->addr + W83781D_ADDR_REG_OFFSET);
1249                        outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
1250                }
1251        } else {
1252                bank = (reg >> 8) & 0x0f;
1253                if (bank > 2)
1254                        /* switch banks */
1255                        i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
1256                                                  bank);
1257                if (bank == 0 || bank > 2) {
1258                        i2c_smbus_write_byte_data(client, reg & 0xff,
1259                                                  value & 0xff);
1260                } else {
1261                        /* switch to subclient */
1262                        cl = &(((struct w83781d_data *) (client->data))->
1263                              lm75[bank - 1]);
1264                        /* convert from ISA to LM75 I2C addresses */
1265                        switch (reg & 0xff) {
1266                        case 0x52: /* CONFIG */
1267                                i2c_smbus_write_byte_data(cl, 1,
1268                                                          value & 0xff);
1269                                break;
1270                        case 0x53: /* HYST */
1271                                i2c_smbus_write_word_data(cl, 2,
1272                                                          swap_bytes(value));
1273                                break;
1274                        case 0x55: /* OVER */
1275                                i2c_smbus_write_word_data(cl, 3,
1276                                                          swap_bytes(value));
1277                                break;
1278                        }
1279                }
1280                if (bank > 2)
1281                        i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
1282                                                  0);
1283        }
1284        up(&(((struct w83781d_data *) (client->data))->lock));
1285        return 0;
1286}
1287
1288/* Called when we have found a new W83781D. It should set limits, etc. */
1289static void w83781d_init_client(struct i2c_client *client)
1290{
1291        struct w83781d_data *data = client->data;
1292        int vid = 0, i, p;
1293        int type = data->type;
1294        u8 tmp;
1295
1296        if(init && type != as99127f) { /* this resets registers we don't have
1297                                          documentation for on the as99127f */
1298                /* save these registers */
1299                i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
1300                p = w83781d_read_value(client, W83781D_REG_PWMCLK12);
1301                /* Reset all except Watchdog values and last conversion values
1302                   This sets fan-divs to 2, among others */
1303                w83781d_write_value(client, W83781D_REG_CONFIG, 0x80);
1304                /* Restore the registers and disable power-on abnormal beep.
1305                   This saves FAN 1/2/3 input/output values set by BIOS. */
1306                w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80);
1307                w83781d_write_value(client, W83781D_REG_PWMCLK12, p);
1308                /* Disable master beep-enable (reset turns it on).
1309                   Individual beeps should be reset to off but for some reason
1310                   disabling this bit helps some people not get beeped */
1311                w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0);
1312        }
1313
1314        if (type != w83697hf) {
1315                vid = w83781d_read_value(client, W83781D_REG_VID_FANDIV) & 0x0f;
1316                vid |=
1317                    (w83781d_read_value(client, W83781D_REG_CHIPID) & 0x01) << 4;
1318                if (type == w83791d) {
1319                        data->vrm = 92;
1320                } else {
1321                data->vrm = DEFAULT_VRM;
1322                }
1323                vid = vid_from_reg(vid, data->vrm);
1324        }
1325
1326        if ((type != w83781d) && (type != as99127f)) {
1327                tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
1328                for (i = 1; i <= 3; i++) {
1329                        if (!(tmp & BIT_SCFG1[i - 1])) {
1330                                data->sens[i - 1] = W83781D_DEFAULT_BETA;
1331                        } else {
1332                                if (w83781d_read_value
1333                                    (client,
1334                                     W83781D_REG_SCFG2) & BIT_SCFG2[i - 1])
1335                                        data->sens[i - 1] = 1;
1336                                else
1337                                        data->sens[i - 1] = 2;
1338                        }
1339                        if ((type == w83783s || type == w83697hf) && (i == 2))
1340                                break;
1341                }
1342        }
1343#ifdef W83781D_RT
1344/*
1345   Fill up the RT Tables.
1346   We assume that they are 32 bytes long, in order for temp 1-3.
1347   Data sheet documentation is sparse.
1348   We also assume that it is only for the 781D although I suspect
1349   that the others support it as well....
1350*/
1351
1352        if (init && type == w83781d) {
1353                u16 k = 0;
1354/*
1355    Auto-indexing doesn't seem to work...
1356    w83781d_write_value(client,W83781D_REG_RT_IDX,0);
1357*/
1358                for (i = 0; i < 3; i++) {
1359                        int j;
1360                        for (j = 0; j < 32; j++) {
1361                                w83781d_write_value(client,
1362                                                    W83781D_REG_RT_IDX,
1363                                                    k++);
1364                                data->rt[i][j] =
1365                                    w83781d_read_value(client,
1366                                                       W83781D_REG_RT_VAL);
1367                        }
1368                }
1369        }
1370#endif                          /* W83781D_RT */
1371
1372        if(init) {
1373                w83781d_write_value(client, W83781D_REG_TEMP2_CONFIG, 0x00);
1374                if (type != w83783s && type != w83697hf) {
1375                        w83781d_write_value(client, W83781D_REG_TEMP3_CONFIG,
1376                                            0x00);
1377                }
1378                if (type != w83781d) {
1379                        /* enable comparator mode for temp2 and temp3 so
1380                           alarm indication will work correctly */
1381                        i = w83781d_read_value(client, W83781D_REG_IRQ);
1382                        if (!(i & 0x40))
1383                                w83781d_write_value(client, W83781D_REG_IRQ,
1384                                                    i | 0x40);
1385
1386                        for(i = 0; i < 3; i++)
1387                                data->pwmenable[i] = 1;
1388                }
1389        }
1390
1391        /* Start monitoring */
1392        w83781d_write_value(client, W83781D_REG_CONFIG,
1393                            (w83781d_read_value(client,
1394                                                W83781D_REG_CONFIG) & 0xf7)
1395                            | 0x01);
1396}
1397
1398static void w83781d_update_client(struct i2c_client *client)
1399{
1400       struct w83781d_data *data = client->data;
1401       int i;
1402
1403       down(&data->update_lock);
1404
1405       if (time_after(jiffies - data->last_updated, HZ + HZ / 2) ||
1406           time_before(jiffies, data->last_updated) || !data->valid) {
1407               pr_debug(KERN_DEBUG "Starting device update\n");
1408
1409               for (i = 0; i <= 9; i++) {
1410                       if ((data->type == w83783s || data->type == w83697hf)
1411                           && (i == 1))
1412                               continue;       /* 783S has no in1 */
1413                       if (data->type == w83791d) {
1414                                data->in[i] =
1415                                        w83781d_read_value(client, W83791D_REG_IN(i));
1416                                data->in_min[i] =
1417                                        w83781d_read_value(client,
1418                                                           W83791D_REG_IN_MIN(i));
1419                                data->in_max[i] =
1420                                        w83781d_read_value(client,
1421                                                           W83791D_REG_IN_MAX(i));
1422                       } else {
1423                       data->in[i] =
1424                           w83781d_read_value(client, W83781D_REG_IN(i));
1425                       data->in_min[i] =
1426                           w83781d_read_value(client,
1427                                              W83781D_REG_IN_MIN(i));
1428                       data->in_max[i] =
1429                           w83781d_read_value(client,
1430                                              W83781D_REG_IN_MAX(i));
1431                       }
1432                       if ((data->type != w83782d) && (data->type != w83697hf)
1433                           && (data->type != w83627hf) && (i == 6)
1434                           && (data->type != w83791d))
1435                               break;
1436
1437                       if (data->type != w83791d && i == 8) 
1438                         break;
1439               }
1440               for (i = 1; i <= 5; i++) {
1441                       data->fan[i - 1] =
1442                           w83781d_read_value(client, W83781D_REG_FAN(i));
1443                       data->fan_min[i - 1] =
1444                           w83781d_read_value(client,
1445                                              W83781D_REG_FAN_MIN(i));
1446                       if (data->type != w83791d && i == 3) break;
1447               }
1448               if (data->type != w83781d) {
1449                       for (i = 1; i <= 4; i++) {
1450                               data->pwm[i - 1] =
1451                                   w83781d_read_value(client,
1452                                             W83781D_REG_PWM(data->type, i));
1453                               if (((data->type == w83783s)
1454                                    || (data->type == w83627hf)
1455                                    || (data->type == as99127f)
1456                                    || (data->type == w83697hf)
1457                                    || ((data->type == w83782d)
1458                                       && i2c_is_isa_client(client)))
1459                                   && i == 2)
1460                                       break;
1461                       }
1462               }
1463
1464               data->temp = w83781d_read_value(client, W83781D_REG_TEMP);
1465               data->temp_over =
1466                   w83781d_read_value(client, W83781D_REG_TEMP_OVER);
1467               data->temp_hyst =
1468                   w83781d_read_value(client, W83781D_REG_TEMP_HYST);
1469               data->temp_add[0] =
1470                   w83781d_read_value(client, W83781D_REG_TEMP2);
1471               data->temp_add_over[0] =
1472                   w83781d_read_value(client, W83781D_REG_TEMP2_OVER);
1473               data->temp_add_hyst[0] =
1474                   w83781d_read_value(client, W83781D_REG_TEMP2_HYST);
1475               if (data->type != w83783s && data->type != w83697hf) {
1476                       data->temp_add[1] =
1477                           w83781d_read_value(client, W83781D_REG_TEMP3);
1478                       data->temp_add_over[1] =
1479                           w83781d_read_value(client, W83781D_REG_TEMP3_OVER);
1480                       data->temp_add_hyst[1] =
1481                           w83781d_read_value(client, W83781D_REG_TEMP3_HYST);
1482               }
1483               i = w83781d_read_value(client, W83781D_REG_VID_FANDIV);
1484               if (data->type != w83697hf) {
1485                       data->vid = i & 0x0f;
1486                       data->vid |=
1487                           (w83781d_read_value(client, W83781D_REG_CHIPID) & 0x01)
1488                           << 4;
1489               }
1490               data->fan_div[0] = (i >> 4) & 0x03;
1491               data->fan_div[1] = (i >> 6) & 0x03;
1492               if (data->type != w83697hf) {
1493                       data->fan_div[2] = (w83781d_read_value(client,
1494                                              W83781D_REG_PIN) >> 6) & 0x03;
1495               }
1496               if ((data->type != w83781d) && (data->type != as99127f)) {
1497                       i = w83781d_read_value(client, W83781D_REG_VBAT);
1498                       data->fan_div[0] |= (i >> 3) & 0x04;
1499                       data->fan_div[1] |= (i >> 4) & 0x04;
1500                       if (data->type != w83697hf)
1501                               data->fan_div[2] |= (i >> 5) & 0x04;
1502               }
1503               data->alarms =
1504                   w83781d_read_value(client,
1505                                      W83781D_REG_ALARM1) +
1506                   (w83781d_read_value(client, W83781D_REG_ALARM2) << 8);
1507               if ((data->type == w83782d) || (data->type == w83627hf) ||
1508                   (data->type == w83697hf)) {
1509                       data->alarms |=
1510                           w83781d_read_value(client,
1511                                              W83781D_REG_ALARM3) << 16;
1512               }
1513               i = w83781d_read_value(client, W83781D_REG_BEEP_INTS2);
1514               data->beep_enable = i >> 7;
1515               data->beeps = ((i & 0x7f) << 8) +
1516                   w83781d_read_value(client, W83781D_REG_BEEP_INTS1);
1517               if ((data->type != w83781d) && (data->type != as99127f)
1518                   && (data->type != w83791d)) {
1519                       data->beeps |=
1520                           w83781d_read_value(client,
1521                                              W83781D_REG_BEEP_INTS3) << 16;
1522               }
1523               data->last_updated = jiffies;
1524               data->valid = 1;
1525       }
1526
1527        up(&data->update_lock);
1528}
1529
1530
1531/* The next few functions are the call-back functions of the /proc/sys and
1532   sysctl files. Which function is used is defined in the ctl_table in
1533   the extra1 field.
1534   Each function must return the magnitude (power of 10 to divide the date
1535   with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must
1536   put a maximum of *nrels elements in results reflecting the data of this
1537   file, and set *nrels to the number it actually put in it, if operation==
1538   SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from
1539   results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE.
1540   Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
1541   large enough (by checking the incoming value of *nrels). This is not very
1542   good practice, but as long as you put less than about 5 values in results,
1543   you can assume it is large enough. */
1544static void w83781d_in(struct i2c_client *client, int operation, int ctl_name,
1545               int *nrels_mag, long *results)
1546{
1547        struct w83781d_data *data = client->data;
1548        int nr = ctl_name - W83781D_SYSCTL_IN0;
1549
1550        if (operation == SENSORS_PROC_REAL_INFO)
1551                *nrels_mag = 2;
1552        else if (operation == SENSORS_PROC_REAL_READ) {
1553                w83781d_update_client(client);
1554                results[0] = IN_FROM_REG(data->in_min[nr]);
1555                results[1] = IN_FROM_REG(data->in_max[nr]);
1556                results[2] = IN_FROM_REG(data->in[nr]);
1557                *nrels_mag = 3;
1558        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1559                if (*nrels_mag >= 1) {
1560                        data->in_min[nr] = IN_TO_REG(results[0]);
1561                        w83781d_write_value(client, W83781D_REG_IN_MIN(nr),
1562                                            data->in_min[nr]);
1563                }
1564                if (*nrels_mag >= 2) {
1565                        data->in_max[nr] = IN_TO_REG(results[1]);
1566                        w83781d_write_value(client, W83781D_REG_IN_MAX(nr),
1567                                            data->in_max[nr]);
1568                }
1569        }
1570}
1571
1572void w83781d_fan(struct i2c_client *client, int operation, int ctl_name,
1573                 int *nrels_mag, long *results)
1574{
1575        struct w83781d_data *data = client->data;
1576        int nr = ctl_name - W83781D_SYSCTL_FAN1 + 1;
1577
1578        if (operation == SENSORS_PROC_REAL_INFO)
1579                *nrels_mag = 0;
1580        else if (operation == SENSORS_PROC_REAL_READ) {
1581                w83781d_update_client(client);
1582                results[0] = FAN_FROM_REG(data->fan_min[nr - 1],
1583                                  DIV_FROM_REG(data->fan_div[nr - 1]));
1584                results[1] = FAN_FROM_REG(data->fan[nr - 1],
1585                                  DIV_FROM_REG(data->fan_div[nr - 1]));
1586                *nrels_mag = 2;
1587        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1588                if (*nrels_mag >= 1) {
1589                        data->fan_min[nr - 1] =
1590                             FAN_TO_REG(results[0],
1591                                    DIV_FROM_REG(data->fan_div[nr-1]));
1592                        w83781d_write_value(client,
1593                                            W83781D_REG_FAN_MIN(nr),
1594                                            data->fan_min[nr - 1]);
1595                }
1596        }
1597}
1598
1599void w83781d_temp(struct i2c_client *client, int operation, int ctl_name,
1600                  int *nrels_mag, long *results)
1601{
1602        struct w83781d_data *data = client->data;
1603        if (operation == SENSORS_PROC_REAL_INFO)
1604                *nrels_mag = 1;
1605        else if (operation == SENSORS_PROC_REAL_READ) {
1606                w83781d_update_client(client);
1607                results[0] = TEMP_FROM_REG(data->temp_over);
1608                results[1] = TEMP_FROM_REG(data->temp_hyst);
1609                results[2] = TEMP_FROM_REG(data->temp);
1610                *nrels_mag = 3;
1611        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1612                if (*nrels_mag >= 1) {
1613                        data->temp_over = TEMP_TO_REG(results[0]);
1614                        w83781d_write_value(client, W83781D_REG_TEMP_OVER,
1615                                            data->temp_over);
1616                }
1617                if (*nrels_mag >= 2) {
1618                        data->temp_hyst = TEMP_TO_REG(results[1]);
1619                        w83781d_write_value(client, W83781D_REG_TEMP_HYST,
1620                                            data->temp_hyst);
1621                }
1622        }
1623}
1624
1625void w83781d_temp_add(struct i2c_client *client, int operation,
1626                      int ctl_name, int *nrels_mag, long *results)
1627{
1628        struct w83781d_data *data = client->data;
1629        int nr = ctl_name - W83781D_SYSCTL_TEMP2;
1630
1631        if (operation == SENSORS_PROC_REAL_INFO)
1632                *nrels_mag = 1;
1633        else if (operation == SENSORS_PROC_REAL_READ) {
1634                w83781d_update_client(client);
1635                if (data->type == as99127f) {
1636                        results[0] =
1637                            AS99127_TEMP_ADD_FROM_REG(data->
1638                                                      temp_add_over[nr]);
1639                        results[1] =
1640                            AS99127_TEMP_ADD_FROM_REG(data->
1641                                                      temp_add_hyst[nr]);
1642                        results[2] =
1643                            AS99127_TEMP_ADD_FROM_REG(data->temp_add[nr]);
1644                } else {
1645                        results[0] =
1646                            LM75_TEMP_FROM_REG(data->temp_add_over[nr]);
1647                        results[1] =
1648                            LM75_TEMP_FROM_REG(data->temp_add_hyst[nr]);
1649                        results[2] = LM75_TEMP_FROM_REG(data->temp_add[nr]);
1650                }
1651                *nrels_mag = 3;
1652        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1653                if (*nrels_mag >= 1) {
1654                        if (data->type == as99127f)
1655                                data->temp_add_over[nr] =
1656                                    AS99127_TEMP_ADD_TO_REG(results[0]);
1657                        else
1658                                data->temp_add_over[nr] =
1659                                    LM75_TEMP_TO_REG(results[0]);
1660                        w83781d_write_value(client,
1661                                            nr ? W83781D_REG_TEMP3_OVER :
1662                                            W83781D_REG_TEMP2_OVER,
1663                                            data->temp_add_over[nr]);
1664                }
1665                if (*nrels_mag >= 2) {
1666                        if (data->type == as99127f)
1667                                data->temp_add_hyst[nr] =
1668                                    AS99127_TEMP_ADD_TO_REG(results[1]);
1669                        else
1670                                data->temp_add_hyst[nr] =
1671                                    LM75_TEMP_TO_REG(results[1]);
1672                        w83781d_write_value(client,
1673                                            nr ? W83781D_REG_TEMP3_HYST :
1674                                            W83781D_REG_TEMP2_HYST,
1675                                            data->temp_add_hyst[nr]);
1676                }
1677        }
1678}
1679
1680
1681void w83781d_vid(struct i2c_client *client, int operation, int ctl_name,
1682                 int *nrels_mag, long *results)
1683{
1684        struct w83781d_data *data = client->data;
1685        if (operation == SENSORS_PROC_REAL_INFO)
1686                *nrels_mag = 3;
1687        else if (operation == SENSORS_PROC_REAL_READ) {
1688                w83781d_update_client(client);
1689                results[0] = vid_from_reg(data->vid, data->vrm);
1690                *nrels_mag = 1;
1691        }
1692}
1693
1694void w83781d_vrm(struct i2c_client *client, int operation, int ctl_name,
1695                 int *nrels_mag, long *results)
1696{
1697        struct w83781d_data *data = client->data;
1698        if (operation == SENSORS_PROC_REAL_INFO)
1699                *nrels_mag = 1;
1700        else if (operation == SENSORS_PROC_REAL_READ) {
1701                results[0] = data->vrm;
1702                *nrels_mag = 1;
1703        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1704                if (*nrels_mag >= 1)
1705                        data->vrm = results[0];
1706        }
1707}
1708
1709void w83781d_alarms(struct i2c_client *client, int operation, int ctl_name,
1710                    int *nrels_mag, long *results)
1711{
1712        struct w83781d_data *data = client->data;
1713        if (operation == SENSORS_PROC_REAL_INFO)
1714                *nrels_mag = 0;
1715        else if (operation == SENSORS_PROC_REAL_READ) {
1716                w83781d_update_client(client);
1717                results[0] = ALARMS_FROM_REG(data->alarms);
1718                *nrels_mag = 1;
1719        }
1720}
1721
1722void w83781d_beep(struct i2c_client *client, int operation, int ctl_name,
1723                  int *nrels_mag, long *results)
1724{
1725        struct w83781d_data *data = client->data;
1726        int val;
1727
1728        if (operation == SENSORS_PROC_REAL_INFO)
1729                *nrels_mag = 0;
1730        else if (operation == SENSORS_PROC_REAL_READ) {
1731                w83781d_update_client(client);
1732                results[0] = BEEP_ENABLE_FROM_REG(data->beep_enable);
1733                results[1] = BEEPS_FROM_REG(data->beeps);
1734                *nrels_mag = 2;
1735        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1736                if (*nrels_mag >= 2) {
1737                        data->beeps = BEEPS_TO_REG(results[1]);
1738                        w83781d_write_value(client, W83781D_REG_BEEP_INTS1,
1739                                            data->beeps & 0xff);
1740                        if ((data->type != w83781d) &&
1741                            (data->type != as99127f)) {
1742                                w83781d_write_value(client,
1743                                                    W83781D_REG_BEEP_INTS3,
1744                                                    ((data-> beeps) >> 16) &
1745                                                      0xff);
1746                        }
1747                        val = (data->beeps >> 8) & 0x7f;
1748                } else if (*nrels_mag >= 1)
1749                        val =
1750                            w83781d_read_value(client,
1751                                               W83781D_REG_BEEP_INTS2) &
1752                            0x7f;
1753                if (*nrels_mag >= 1) {
1754                        data->beep_enable = BEEP_ENABLE_TO_REG(results[0]);
1755                        w83781d_write_value(client, W83781D_REG_BEEP_INTS2,
1756                                            val | data->beep_enable << 7);
1757                }
1758        }
1759}
1760
1761/* w83697hf only has two fans */
1762void w83781d_fan_div(struct i2c_client *client, int operation,
1763                     int ctl_name, int *nrels_mag, long *results)
1764{
1765        struct w83781d_data *data = client->data;
1766        int old, old2, old3 = 0;
1767
1768        if (operation == SENSORS_PROC_REAL_INFO)
1769                *nrels_mag = 0;
1770        else if (operation == SENSORS_PROC_REAL_READ) {
1771                w83781d_update_client(client);
1772                results[0] = DIV_FROM_REG(data->fan_div[0]);
1773                results[1] = DIV_FROM_REG(data->fan_div[1]);
1774                if (data->type == w83697hf) {
1775                        *nrels_mag = 2;
1776                } else {
1777                        results[2] = DIV_FROM_REG(data->fan_div[2]);
1778                        *nrels_mag = 3;
1779                }
1780        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1781                old = w83781d_read_value(client, W83781D_REG_VID_FANDIV);
1782                /* w83781d and as99127f don't have extended divisor bits */
1783                if ((data->type != w83781d) && data->type != as99127f) {
1784                        old3 =
1785                            w83781d_read_value(client, W83781D_REG_VBAT);
1786                }
1787                if (*nrels_mag >= 3 && data->type != w83697hf) {
1788                        data->fan_div[2] =
1789                            DIV_TO_REG(results[2], data->type);
1790                        old2 = w83781d_read_value(client, W83781D_REG_PIN);
1791                        old2 =
1792                            (old2 & 0x3f) | ((data->fan_div[2] & 0x03) << 6);
1793                        w83781d_write_value(client, W83781D_REG_PIN, old2);
1794                        if ((data->type != w83781d) &&
1795                            (data->type != as99127f)) {
1796                                old3 =
1797                                    (old3 & 0x7f) |
1798                                    ((data->fan_div[2] & 0x04) << 5);
1799                        }
1800                }
1801                if (*nrels_mag >= 2) {
1802                        data->fan_div[1] =
1803                            DIV_TO_REG(results[1], data->type);
1804                        old =
1805                            (old & 0x3f) | ((data->fan_div[1] & 0x03) << 6);
1806                        if ((data->type != w83781d) &&
1807                            (data->type != as99127f)) {
1808                                old3 =
1809                                    (old3 & 0xbf) |
1810                                    ((data->fan_div[1] & 0x04) << 4);
1811                        }
1812                }
1813                if (*nrels_mag >= 1) {
1814                        data->fan_div[0] =
1815                            DIV_TO_REG(results[0], data->type);
1816                        old =
1817                            (old & 0xcf) | ((data->fan_div[0] & 0x03) << 4);
1818                        w83781d_write_value(client, W83781D_REG_VID_FANDIV,
1819                                            old);
1820                        if ((data->type != w83781d) &&
1821                            (data->type != as99127f)) {
1822                                old3 =
1823                                    (old3 & 0xdf) |
1824                                    ((data->fan_div[0] & 0x04) << 3);
1825                                w83781d_write_value(client,
1826                                                    W83781D_REG_VBAT,
1827                                                    old3);
1828                        }
1829                }
1830        }
1831}
1832
1833void w83781d_pwm(struct i2c_client *client, int operation, int ctl_name,
1834                 int *nrels_mag, long *results)
1835{
1836        struct w83781d_data *data = client->data;
1837        int nr = 1 + ctl_name - W83781D_SYSCTL_PWM1;
1838        int j, k;
1839
1840        if (operation == SENSORS_PROC_REAL_INFO)
1841                *nrels_mag = 0;
1842        else if (operation == SENSORS_PROC_REAL_READ) {
1843                w83781d_update_client(client);
1844                results[0] = PWM_FROM_REG(data->pwm[nr - 1]);
1845                results[1] = data->pwmenable[nr - 1];
1846                *nrels_mag = 2;
1847        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1848                if (*nrels_mag >= 1) {
1849                        data->pwm[nr - 1] = PWM_TO_REG(results[0]);
1850                        w83781d_write_value(client,
1851                                            W83781D_REG_PWM(data->type, nr),
1852                                            data->pwm[nr - 1]);
1853                }
1854                /* only PWM2 can be enabled/disabled */
1855                if (*nrels_mag >= 2 && nr == 2) {
1856                        j = w83781d_read_value(client, W83781D_REG_PWMCLK12);
1857                        k = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
1858                        if(results[1]) {
1859                                if(!(j & 0x08))
1860                                        w83781d_write_value(client,
1861                                             W83781D_REG_PWMCLK12, j | 0x08);
1862                                if(k & 0x10)
1863                                        w83781d_write_value(client,
1864                                             W83781D_REG_BEEP_CONFIG, k & 0xef);
1865                                data->pwmenable[1] = 1;
1866                        } else {
1867                                if(j & 0x08)
1868                                        w83781d_write_value(client,
1869                                             W83781D_REG_PWMCLK12, j & 0xf7);
1870                                if(!(k & 0x10))
1871                                        w83781d_write_value(client,
1872                                             W83781D_REG_BEEP_CONFIG, j | 0x10);
1873                                data->pwmenable[1] = 0;
1874                        }
1875                }
1876        }
1877}
1878
1879void w83781d_sens(struct i2c_client *client, int operation, int ctl_name,
1880                  int *nrels_mag, long *results)
1881{
1882        struct w83781d_data *data = client->data;
1883        int nr = 1 + ctl_name - W83781D_SYSCTL_SENS1;
1884        u8 tmp;
1885
1886        if (operation == SENSORS_PROC_REAL_INFO)
1887                *nrels_mag = 0;
1888        else if (operation == SENSORS_PROC_REAL_READ) {
1889                results[0] = data->sens[nr - 1];
1890                *nrels_mag = 1;
1891        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1892                if (*nrels_mag >= 1) {
1893                        switch (results[0]) {
1894                        case 1: /* PII/Celeron diode */
1895                                tmp = w83781d_read_value(client,
1896                                                       W83781D_REG_SCFG1);
1897                                w83781d_write_value(client,
1898                                                    W83781D_REG_SCFG1,
1899                                                    tmp | BIT_SCFG1[nr -
1900                                                                    1]);
1901                                tmp = w83781d_read_value(client,
1902                                                       W83781D_REG_SCFG2);
1903                                w83781d_write_value(client,
1904                                                    W83781D_REG_SCFG2,
1905                                                    tmp | BIT_SCFG2[nr -
1906                                                                    1]);
1907                                data->sens[nr - 1] = results[0];
1908                                break;
1909                        case 2: /* 3904 */
1910                                tmp = w83781d_read_value(client,
1911                                                       W83781D_REG_SCFG1);
1912                                w83781d_write_value(client,
1913                                                    W83781D_REG_SCFG1,
1914                                                    tmp | BIT_SCFG1[nr -
1915                                                                    1]);
1916                                tmp = w83781d_read_value(client,
1917                                                       W83781D_REG_SCFG2);
1918                                w83781d_write_value(client,
1919                                                    W83781D_REG_SCFG2,
1920                                                    tmp & ~BIT_SCFG2[nr -
1921                                                                     1]);
1922                                data->sens[nr - 1] = results[0];
1923                                break;
1924                        case W83781D_DEFAULT_BETA:      /* thermistor */
1925                                tmp = w83781d_read_value(client,
1926                                                       W83781D_REG_SCFG1);
1927                                w83781d_write_value(client,
1928                                                    W83781D_REG_SCFG1,
1929                                                    tmp & ~BIT_SCFG1[nr -
1930                                                                     1]);
1931                                data->sens[nr - 1] = results[0];
1932                                break;
1933                        default:
1934                                printk
1935                                    (KERN_ERR "w83781d.o: Invalid sensor type %ld; must be 1, 2, or %d\n",
1936                                     results[0], W83781D_DEFAULT_BETA);
1937                                break;
1938                        }
1939                }
1940        }
1941}
1942
1943#ifdef W83781D_RT
1944static void w83781d_rt(struct i2c_client *client, int operation, int ctl_name,
1945               int *nrels_mag, long *results)
1946{
1947        struct w83781d_data *data = client->data;
1948        int nr = 1 + ctl_name - W83781D_SYSCTL_RT1;
1949        int i;
1950
1951        if (operation == SENSORS_PROC_REAL_INFO)
1952                *nrels_mag = 0;
1953        else if (operation == SENSORS_PROC_REAL_READ) {
1954                for (i = 0; i < 32; i++) {
1955                        results[i] = data->rt[nr - 1][i];
1956                }
1957                *nrels_mag = 32;
1958        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1959                if (*nrels_mag > 32)
1960                        *nrels_mag = 32;
1961                for (i = 0; i < *nrels_mag; i++) {
1962                        /* fixme: no bounds checking 0-255 */
1963                        data->rt[nr - 1][i] = results[i];
1964                        w83781d_write_value(client, W83781D_REG_RT_IDX, i);
1965                        w83781d_write_value(client, W83781D_REG_RT_VAL,
1966                                            data->rt[nr - 1][i]);
1967                }
1968        }
1969}
1970#endif
1971
1972static int __init sm_w83781d_init(void)
1973{
1974        printk(KERN_INFO "w83781d.o version %s (%s)\n", LM_VERSION, LM_DATE);
1975        return i2c_add_driver(&w83781d_driver);
1976}
1977
1978static void __exit sm_w83781d_exit(void)
1979{
1980        i2c_del_driver(&w83781d_driver);
1981}
1982
1983
1984
1985MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
1986              "Philip Edelbrock <phil@netroedge.com>, "
1987              "and Mark Studebaker <mdsxyz123@yahoo.com>");
1988MODULE_DESCRIPTION("W83781D driver");
1989MODULE_LICENSE("GPL");
1990
1991module_init(sm_w83781d_init);
1992module_exit(sm_w83781d_exit);
Note: See TracBrowser for help on using the browser.