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

Revision 2313, 70.4 KB (checked in by khali, 9 years ago)

w83781d driver doesn't support ASB100 anymore.

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