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

Revision 2867, 68.6 KB (checked in by khali, 8 years ago)

Drop unused client id.

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