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

Revision 4096, 66.4 KB (checked in by khali, 7 years ago)

Enhance w83791d support. Add output for in7, in8, in9, fan4 and fan5.
Also update to display the (beep) properly due to the fact that the
w83791d beep enable mask is different than the alarm mask.
Patch from Sven Anders and Charles Spirakis.

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