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

Revision 2781, 69.6 KB (checked in by khali, 9 years ago)

Discard owner field from i2c_driver structure. I do not restore
inc_use/dec_use because they are not actually used anywhere.

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