root/lm-sensors/trunk/kernel/chips/it87.c @ 4651

Revision 4651, 35.2 KB (checked in by khali, 6 years ago)

Add missing new line at end of log messages. Indirectly reported
by Joe Perches.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    it87.c - Part of lm_sensors, Linux kernel modules for hardware
3             monitoring.
4
5    Supports: IT8705F  Super I/O chip w/LPC interface
6              IT8712F  Super I/O chip w/LPC interface & SMBus
7              SiS950   A clone of the IT8705F
8
9    Copyright (c) 2001 Chris Gauthron <chrisg@0-in.com>
10    Largely inspired by lm78.c of the same package
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 2 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software
24    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25*/
26
27/*
28    djg@pdp8.net David Gesswein 7/18/01
29    Modified to fix bug with not all alarms enabled.
30    Added ability to read battery voltage and select temperature sensor
31    type at module load time.
32*/
33
34/*
35    michael.hufer@gmx.de Michael Hufer 09/07/03
36    Modified configure (enable/disable) chip reset at module load time.
37    Added ability to read and set fan pwm registers and the smart
38    guardian (sg) features of the chip.
39*/
40
41#include <linux/module.h>
42#include <linux/slab.h>
43#include <linux/ioport.h>
44#include <linux/i2c.h>
45#include <linux/i2c-proc.h>
46#include <linux/init.h>
47#include <asm/io.h>
48#include "version.h"
49
50MODULE_LICENSE("GPL");
51
52/* Addresses to scan */
53static unsigned short normal_i2c[] = { SENSORS_I2C_END };
54static unsigned short normal_i2c_range[] = { 0x28, 0x2f, SENSORS_I2C_END };
55static unsigned int normal_isa[] = { 0x0290, SENSORS_ISA_END };
56static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
57
58/* Insmod parameters */
59SENSORS_INSMOD_2(it87, it8712);
60
61
62#define REG     0x2e    /* The register to read/write */
63#define DEV     0x07    /* Register: Logical device select */
64#define VAL     0x2f    /* The value to read/write */
65#define PME     0x04    /* The device with the fan registers in it */
66#define DEVID   0x20    /* Register: Device ID */
67#define DEVREV  0x22    /* Register: Device Revision */
68
69static inline int
70superio_inb(int reg)
71{
72        outb(reg, REG);
73        return inb(VAL);
74}
75
76static int superio_inw(int reg)
77{
78        int val;
79        outb(reg++, REG);
80        val = inb(VAL) << 8;
81        outb(reg, REG);
82        val |= inb(VAL);
83        return val;
84}
85
86static inline void
87superio_select(void)
88{
89        outb(DEV, REG);
90        outb(PME, VAL);
91}
92
93static inline void
94superio_enter(void)
95{
96        outb(0x87, REG);
97        outb(0x01, REG);
98        outb(0x55, REG);
99        outb(0x55, REG);
100}
101
102static inline void
103superio_exit(void)
104{
105        outb(0x02, REG);
106        outb(0x02, VAL);
107}
108
109#define IT87_DEVID_MATCH(id) ((id) == 0x8712 || (id) == 0x8705)
110
111#define IT87_ACT_REG  0x30
112#define IT87_BASE_REG 0x60
113
114/* Update battery voltage after every reading if true */
115static int update_vbat = 0;
116
117/* Reset the registers on init */
118static int reset = 0;
119
120/* Many IT87 constants specified below */
121
122/* Length of ISA address segment */
123#define IT87_EXTENT 8
124
125/* Where are the ISA address/data registers relative to the base address */
126#define IT87_ADDR_REG_OFFSET 5
127#define IT87_DATA_REG_OFFSET 6
128
129/*----- The IT87 registers -----*/
130
131#define IT87_REG_CONFIG        0x00
132
133#define IT87_REG_ALARM1        0x01
134#define IT87_REG_ALARM2        0x02
135#define IT87_REG_ALARM3        0x03
136
137#define IT87_REG_VID           0x0a
138#define IT87_REG_FAN_DIV       0x0b
139
140#define IT87_REG_FAN(nr)       (0x0c + (nr))
141#define IT87_REG_FAN_MIN(nr)   (0x0f + (nr))
142#define IT87_REG_FAN_CTRL      0x13
143
144/* pwm and smart guardian registers */
145
146#define IT87_REG_FAN_ONOFF     0x14
147#define IT87_REG_PWM(nr)       (0x14 + (nr))
148#define IT87_REG_SG_TL_OFF(nr) (0x58 + (nr)*8)
149#define IT87_REG_SG_TL_LOW(nr) (0x59 + (nr)*8)
150#define IT87_REG_SG_TL_MED(nr) (0x5a + (nr)*8)
151#define IT87_REG_SG_TL_HI(nr)  (0x5b + (nr)*8)
152#define IT87_REG_SG_TL_OVR(nr) (0x5c + (nr)*8)
153#define IT87_REG_SG_PWM_LOW(nr) (0x5d + (nr)*8)
154#define IT87_REG_SG_PWM_MED(nr) (0x5e + (nr)*8)
155#define IT87_REG_SG_PWM_HI(nr)  (0x5f + (nr)*8)
156
157/* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */
158
159#define IT87_REG_VIN(nr)       (0x20 + (nr))
160#define IT87_REG_TEMP(nr)      (0x28 + (nr))
161
162#define IT87_REG_VIN_MAX(nr)   (0x30 + (nr) * 2)
163#define IT87_REG_VIN_MIN(nr)   (0x31 + (nr) * 2)
164#define IT87_REG_TEMP_HIGH(nr) (0x3e + (nr) * 2)
165#define IT87_REG_TEMP_LOW(nr)  (0x3f + (nr) * 2)
166
167#define IT87_REG_I2C_ADDR      0x48
168
169#define IT87_REG_VIN_ENABLE    0x50
170#define IT87_REG_TEMP_ENABLE   0x51
171
172#define IT87_REG_CHIPID        0x58
173#define IT87_REG_CHIPID2       0x5b /* IT8712F only */
174
175/* sensor pin types */
176#define UNUSED          0
177#define THERMISTOR      2
178#define PIIDIODE        3
179
180/* Conversions. Limit checking is only done on the TO_REG
181   variants. Note that you should be a bit careful with which arguments
182   these macros are called: arguments may be evaluated more than once.
183   Fixing this is just not worth it. */
184#define IN_TO_REG(val)  (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255))
185#define IN_FROM_REG(val) (((val) *  16 + 5) / 10)
186
187static inline u8 FAN_TO_REG(long rpm, int div)
188{
189        if (rpm == 0)
190                return 255;
191        rpm = SENSORS_LIMIT(rpm, 1, 1000000);
192        return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
193                             254);
194}
195
196#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
197
198#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\
199                                                 ((val)+5)/10),-127,127))
200#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10)
201
202#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\
203                           205-(val)*5)
204#define ALARMS_FROM_REG(val) (val)
205
206extern inline u8 DIV_TO_REG(long val)
207{
208        u8 i;
209        for( i = 0; i <= 7; i++ )
210        {
211                if( val>>i == 1 )
212                        return i;
213        }
214        return 1;
215}
216#define DIV_FROM_REG(val) (1 << (val))
217
218/* For each registered IT87, we need to keep some data in memory. It is
219   dynamically allocated, at the same time when a new it87 client is
220   allocated. */
221struct it87_data {
222        struct i2c_client client;
223        struct semaphore lock;
224        int sysctl_id;
225        enum chips type;
226
227        struct semaphore update_lock;
228        char valid;             /* !=0 if following fields are valid */
229        unsigned long last_updated;     /* In jiffies */
230
231        u8 in[9];               /* Register value */
232        u8 in_max[9];           /* Register value */
233        u8 in_min[9];           /* Register value */
234        u8 fan[3];              /* Register value */
235        u8 fan_min[3];          /* Register value */
236        u8 temp[3];             /* Register value */
237        u8 temp_high[3];        /* Register value */
238        u8 temp_low[3];         /* Register value */
239        u8 fan_div[3];          /* Register encoding, shifted right */
240        u8 vid;                 /* Register encoding, combined */
241        u32 alarms;             /* Register encoding, combined */
242        u8 pwm[3];              /* Register value */
243        u8 fan_ctl[2];          /* Register encoding */
244        u8 sg_tl[3][5];         /* Register value */
245        u8 sg_pwm[3][3];        /* Register value */
246        u8 sens[3];             /* 2 = Thermistor,
247                                   3 = PII/Celeron diode */
248};
249
250
251static int it87_attach_adapter(struct i2c_adapter *adapter);
252static int it87_detect(struct i2c_adapter *adapter, int address,
253                       unsigned short flags, int kind);
254static int it87_detach_client(struct i2c_client *client);
255
256static int it87_read_value(struct i2c_client *client, u8 register);
257static int it87_write_value(struct i2c_client *client, u8 register,
258                            u8 value);
259static void it87_update_client(struct i2c_client *client);
260static void it87_init_client(struct i2c_client *client);
261
262
263static void it87_in(struct i2c_client *client, int operation, int ctl_name,
264                    int *nrels_mag, long *results);
265static void it87_fan(struct i2c_client *client, int operation,
266                     int ctl_name, int *nrels_mag, long *results);
267static void it87_temp(struct i2c_client *client, int operation,
268                      int ctl_name, int *nrels_mag, long *results);
269static void it87_vid(struct i2c_client *client, int operation,
270                     int ctl_name, int *nrels_mag, long *results);
271static void it87_alarms(struct i2c_client *client, int operation,
272                            int ctl_name, int *nrels_mag, long *results);
273static void it87_fan_div(struct i2c_client *client, int operation,
274                         int ctl_name, int *nrels_mag, long *results);
275static void it87_fan_ctl(struct i2c_client *client, int operation,
276                         int ctl_name, int *nrels_mag, long *results);
277static void it87_pwm(struct i2c_client *client, int operation,
278                         int ctl_name, int *nrels_mag, long *results);
279static void it87_sgpwm(struct i2c_client *client, int operation,
280                         int ctl_name, int *nrels_mag, long *results);
281static void it87_sgtl(struct i2c_client *client, int operation,
282                         int ctl_name, int *nrels_mag, long *results);
283static void it87_sens(struct i2c_client *client, int operation,
284                         int ctl_name, int *nrels_mag, long *results);
285
286static struct i2c_driver it87_driver = {
287        .name           = "IT87xx sensor driver",
288        .id             = I2C_DRIVERID_IT87,
289        .flags          = I2C_DF_NOTIFY,
290        .attach_adapter = it87_attach_adapter,
291        .detach_client  = it87_detach_client,
292};
293
294/* The /proc/sys entries */
295
296/* -- SENSORS SYSCTL START -- */
297#define IT87_SYSCTL_IN0 1000    /* Volts * 100 */
298#define IT87_SYSCTL_IN1 1001
299#define IT87_SYSCTL_IN2 1002
300#define IT87_SYSCTL_IN3 1003
301#define IT87_SYSCTL_IN4 1004
302#define IT87_SYSCTL_IN5 1005
303#define IT87_SYSCTL_IN6 1006
304#define IT87_SYSCTL_IN7 1007
305#define IT87_SYSCTL_IN8 1008
306#define IT87_SYSCTL_FAN1 1101   /* Rotations/min */
307#define IT87_SYSCTL_FAN2 1102
308#define IT87_SYSCTL_FAN3 1103
309#define IT87_SYSCTL_TEMP1 1200  /* Degrees Celsius * 10 */
310#define IT87_SYSCTL_TEMP2 1201  /* Degrees Celsius * 10 */
311#define IT87_SYSCTL_TEMP3 1202  /* Degrees Celsius * 10 */
312#define IT87_SYSCTL_VID 1300    /* Volts * 100 */
313#define IT87_SYSCTL_FAN_DIV 2000        /* 1, 2, 4 or 8 */
314#define IT87_SYSCTL_ALARMS 2004    /* bitvector */
315
316#define IT87_SYSCTL_PWM1 1401
317#define IT87_SYSCTL_PWM2 1402
318#define IT87_SYSCTL_PWM3 1403
319#define IT87_SYSCTL_FAN_CTL  1501
320#define IT87_SYSCTL_FAN_ON_OFF  1502
321#define IT87_SYSCTL_SENS1 1601  /* 1, 2, or Beta (3000-5000) */
322#define IT87_SYSCTL_SENS2 1602
323#define IT87_SYSCTL_SENS3 1603
324
325#define IT87_ALARM_IN0 0x000100
326#define IT87_ALARM_IN1 0x000200
327#define IT87_ALARM_IN2 0x000400
328#define IT87_ALARM_IN3 0x000800
329#define IT87_ALARM_IN4 0x001000
330#define IT87_ALARM_IN5 0x002000
331#define IT87_ALARM_IN6 0x004000
332#define IT87_ALARM_IN7 0x008000
333#define IT87_ALARM_FAN1 0x0001
334#define IT87_ALARM_FAN2 0x0002
335#define IT87_ALARM_FAN3 0x0004
336#define IT87_ALARM_FAN4 0x0008
337#define IT87_ALARM_FAN5 0x0040
338#define IT87_ALARM_TEMP1 0x00010000
339#define IT87_ALARM_TEMP2 0x00020000
340#define IT87_ALARM_TEMP3 0x00040000
341
342/* -- SENSORS SYSCTL END -- */
343
344/* These files are created for each detected IT87. This is just a template;
345   though at first sight, you might think we could use a statically
346   allocated list, we need some way to get back to the parent - which
347   is done through one of the 'extra' fields which are initialized
348   when a new copy is allocated. */
349static ctl_table it87_dir_table_template[] = {
350        {IT87_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
351         &i2c_sysctl_real, NULL, &it87_in},
352        {IT87_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real,
353         &i2c_sysctl_real, NULL, &it87_in},
354        {IT87_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
355         &i2c_sysctl_real, NULL, &it87_in},
356        {IT87_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
357         &i2c_sysctl_real, NULL, &it87_in},
358        {IT87_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
359         &i2c_sysctl_real, NULL, &it87_in},
360        {IT87_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real,
361         &i2c_sysctl_real, NULL, &it87_in},
362        {IT87_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real,
363         &i2c_sysctl_real, NULL, &it87_in},
364        {IT87_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real,
365         &i2c_sysctl_real, NULL, &it87_in},
366        {IT87_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real,
367         &i2c_sysctl_real, NULL, &it87_in},
368        {IT87_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
369         &i2c_sysctl_real, NULL, &it87_fan},
370        {IT87_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
371         &i2c_sysctl_real, NULL, &it87_fan},
372        {IT87_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real,
373         &i2c_sysctl_real, NULL, &it87_fan},
374        {IT87_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
375         &i2c_sysctl_real, NULL, &it87_temp},
376        {IT87_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real,
377         &i2c_sysctl_real, NULL, &it87_temp},
378        {IT87_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real,
379         &i2c_sysctl_real, NULL, &it87_temp},
380        {IT87_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real,
381         &i2c_sysctl_real, NULL, &it87_vid},
382        {IT87_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
383         &i2c_sysctl_real, NULL, &it87_fan_div},
384        {IT87_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
385         &i2c_sysctl_real, NULL, &it87_alarms},
386        {IT87_SYSCTL_FAN_CTL, "fan_ctl", NULL, 0, 0644, NULL, &i2c_proc_real,
387         &i2c_sysctl_real, NULL, &it87_fan_ctl},
388        {IT87_SYSCTL_FAN_ON_OFF, "fan_on_off", NULL, 0, 0644, NULL, &i2c_proc_real,
389         &i2c_sysctl_real, NULL, &it87_fan_ctl},
390        {IT87_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
391         &i2c_sysctl_real, NULL, &it87_pwm},
392        {IT87_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real,
393         &i2c_sysctl_real, NULL, &it87_pwm},
394        {IT87_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, &i2c_proc_real,
395         &i2c_sysctl_real, NULL, &it87_pwm},
396        {IT87_SYSCTL_PWM1, "sg_pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
397         &i2c_sysctl_real, NULL, &it87_sgpwm},
398        {IT87_SYSCTL_PWM2, "sg_pwm2", NULL, 0, 0644, NULL, &i2c_proc_real,
399         &i2c_sysctl_real, NULL, &it87_sgpwm},
400        {IT87_SYSCTL_PWM3, "sg_pwm3", NULL, 0, 0644, NULL, &i2c_proc_real,
401         &i2c_sysctl_real, NULL, &it87_sgpwm},
402        {IT87_SYSCTL_PWM1, "sg_tl1", NULL, 0, 0644, NULL, &i2c_proc_real,
403         &i2c_sysctl_real, NULL, &it87_sgtl},
404        {IT87_SYSCTL_PWM2, "sg_tl2", NULL, 0, 0644, NULL, &i2c_proc_real,
405         &i2c_sysctl_real, NULL, &it87_sgtl},
406        {IT87_SYSCTL_PWM3, "sg_tl3", NULL, 0, 0644, NULL, &i2c_proc_real,
407         &i2c_sysctl_real, NULL, &it87_sgtl},
408        {IT87_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real,
409         &i2c_sysctl_real, NULL, &it87_sens},
410        {IT87_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real,
411         &i2c_sysctl_real, NULL, &it87_sens},
412        {IT87_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &i2c_proc_real,
413         &i2c_sysctl_real, NULL, &it87_sens},
414        {0}
415};
416
417
418/* This function is called when:
419     * it87_driver is inserted (when this module is loaded), for each
420       available adapter
421     * when a new adapter is inserted (and it87_driver is still present) */
422static int it87_attach_adapter(struct i2c_adapter *adapter)
423{
424        return i2c_detect(adapter, &addr_data, it87_detect);
425}
426
427static int __init it87_find(int *address)
428{
429        int err = -ENODEV;
430        u16 devid;
431
432        superio_enter();
433        devid = superio_inw(DEVID);
434        if (!IT87_DEVID_MATCH(devid))
435                goto exit;
436
437        superio_select();
438        if (!(superio_inb(IT87_ACT_REG) & 0x01)) {
439                printk(KERN_INFO "it87: Device not activated, skipping\n");
440                goto exit;
441        }
442
443        *address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1);
444        if (*address == 0) {
445                printk(KERN_INFO "it87: Base address not set, skipping\n");
446                goto exit;
447        }
448
449        err = 0;
450        printk(KERN_INFO "it87: Found IT%04xF chip at 0x%x, revision %d\n",
451               devid, *address, superio_inb(DEVREV) & 0x0f);
452
453exit:
454        superio_exit();
455        return err;
456}
457
458/* This function is called by i2c_detect */
459static int it87_detect(struct i2c_adapter *adapter, int address,
460                       unsigned short flags, int kind)
461{
462        int i;
463        struct i2c_client *new_client;
464        struct it87_data *data;
465        int err = 0;
466        const char *type_name = "";
467        const char *client_name = "";
468        int is_isa = i2c_is_isa_adapter(adapter);
469
470        if (!is_isa
471         && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
472                return 0;
473
474        if (is_isa
475         && check_region(address, IT87_EXTENT))
476                return 0;
477
478        /* Probe whether there is anything available on this address. Already
479           done for SMBus clients */
480        if (is_isa && kind < 0) {
481#define REALLY_SLOW_IO
482                /* We need the timeouts for at least some IT87-like chips.
483                   But only if we read 'undefined' registers. */
484                i = inb_p(address + 1);
485                if (inb_p(address + 2) != i
486                 || inb_p(address + 3) != i
487                 || inb_p(address + 7) != i)
488                        return 0;
489#undef REALLY_SLOW_IO
490
491                /* Let's just hope nothing breaks here */
492                i = inb_p(address + 5) & 0x7f;
493                outb_p(~i & 0x7f, address + 5);
494                if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
495                        outb_p(i, address + 5);
496                        return 0;
497                }
498        }
499
500        /* OK. For now, we presume we have a valid client. We now create the
501           client structure, even though we cannot fill it completely yet.
502           But it allows us to access it87_{read,write}_value. */
503
504        if (!(data = kmalloc(sizeof(struct it87_data), GFP_KERNEL))) {
505                err = -ENOMEM;
506                goto ERROR0;
507        }
508
509        new_client = &data->client;
510        if (is_isa)
511                init_MUTEX(&data->lock);
512        new_client->addr = address;
513        new_client->data = data;
514        new_client->adapter = adapter;
515        new_client->driver = &it87_driver;
516        new_client->flags = 0;
517
518        /* Now, we do the remaining detection. */
519
520        if (kind < 0) {
521                if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80)
522                 || (!is_isa
523                  && it87_read_value(new_client, IT87_REG_I2C_ADDR) != address))
524                        goto ERROR1;
525        }
526
527        /* Determine the chip type. */
528        if (kind <= 0) {
529                i = it87_read_value(new_client, IT87_REG_CHIPID);
530                if (i == 0x90) {
531                        kind = it87;
532                        i = it87_read_value(new_client, IT87_REG_CHIPID2);
533                        if (i == 0x12)
534                                kind = it8712;
535                }
536                else {
537                        if (kind == 0)
538                                printk
539                                    ("it87.o: Ignoring 'force' parameter for unknown chip at "
540                                     "adapter %d, address 0x%02x\n",
541                                     i2c_adapter_id(adapter), address);
542                        goto ERROR1;
543                }
544        }
545
546        if (kind == it87) {
547                type_name = "it87";
548                client_name = "IT87 chip";
549        } else if (kind == it8712) {
550                type_name = "it8712";
551                client_name = "IT8712 chip";
552        } else {
553#ifdef DEBUG
554                printk("it87.o: Internal error: unknown kind (%d)\n",
555                       kind);
556#endif
557                goto ERROR1;
558        }
559
560        /* Reserve the ISA region */
561        if (is_isa)
562                request_region(address, IT87_EXTENT, type_name);
563
564        /* Fill in the remaining client fields and put it into the global list */
565        strcpy(new_client->name, client_name);
566        data->type = kind;
567        data->valid = 0;
568        init_MUTEX(&data->update_lock);
569
570        /* The IT8705F doesn't have VID capability */
571        data->vid = 0x1f;
572
573        /* Tell the I2C layer a new client has arrived */
574        if ((err = i2c_attach_client(new_client)))
575                goto ERROR3;
576
577        /* Register a new directory entry with module sensors */
578        if ((i = i2c_register_entry(new_client,
579                                    type_name,
580                                    it87_dir_table_template,
581                                    THIS_MODULE)) < 0) {
582                err = i;
583                goto ERROR4;
584        }
585        data->sysctl_id = i;
586
587        /* Initialize the IT87 chip */
588        it87_init_client(new_client);
589        return 0;
590
591/* OK, this is not exactly good programming practice, usually. But it is
592   very code-efficient in this case. */
593
594      ERROR4:
595        i2c_detach_client(new_client);
596      ERROR3:
597        if (is_isa)
598                release_region(address, IT87_EXTENT);
599      ERROR1:
600        kfree(data);
601      ERROR0:
602        return err;
603}
604
605static int it87_detach_client(struct i2c_client *client)
606{
607        int err;
608
609        i2c_deregister_entry(((struct it87_data *) (client->data))->
610                                sysctl_id);
611
612        if ((err = i2c_detach_client(client))) {
613                printk
614                    ("it87.o: Client deregistration failed, client not detached.\n");
615                return err;
616        }
617
618        if(i2c_is_isa_client(client))
619                release_region(client->addr, IT87_EXTENT);
620        kfree(client->data);
621
622        return 0;
623}
624
625/* The SMBus locks itself, but ISA access must be locked explicitly!
626   We don't want to lock the whole ISA bus, so we lock each client
627   separately.
628   We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
629   would slow down the IT87 access and should not be necessary.
630   There are some ugly typecasts here, but the good new is - they should
631   nowhere else be necessary! */
632static int it87_read_value(struct i2c_client *client, u8 reg)
633{
634        int res;
635        if (i2c_is_isa_client(client)) {
636                down(&(((struct it87_data *) (client->data))->lock));
637                outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
638                res = inb_p(client->addr + IT87_DATA_REG_OFFSET);
639                up(&(((struct it87_data *) (client->data))->lock));
640                return res;
641        } else
642                return i2c_smbus_read_byte_data(client, reg);
643}
644
645/* The SMBus locks itself, but ISA access muse be locked explicitly!
646   We don't want to lock the whole ISA bus, so we lock each client
647   separately.
648   We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
649   would slow down the IT87 access and should not be necessary.
650   There are some ugly typecasts here, but the good new is - they should
651   nowhere else be necessary! */
652static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
653{
654        if (i2c_is_isa_client(client)) {
655                down(&(((struct it87_data *) (client->data))->lock));
656                outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
657                outb_p(value, client->addr + IT87_DATA_REG_OFFSET);
658                up(&(((struct it87_data *) (client->data))->lock));
659                return 0;
660        } else
661                return i2c_smbus_write_byte_data(client, reg, value);
662}
663
664/* Called when we have found a new IT87. */
665static void it87_init_client(struct i2c_client *client)
666{
667        int tmp;
668
669        if (reset) {
670                /* Reset all except Watchdog values and last conversion values
671                   This sets fan-divs to 2, among others */
672                it87_write_value(client, IT87_REG_CONFIG, 0x80);
673        }
674
675        /* Check if temperature channnels are reset manually or by some reason */
676        tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE);
677        if ((tmp & 0x3f) == 0) {
678                /* Temp1,Temp3=thermistor; Temp2=thermal diode */
679                tmp = (tmp & 0xc0) | 0x2a;
680                it87_write_value(client, IT87_REG_TEMP_ENABLE, tmp);
681        }
682
683        /* Check if voltage monitors are reset manually or by some reason */
684        tmp = it87_read_value(client, IT87_REG_VIN_ENABLE);
685        if ((tmp & 0xff) == 0) {
686                /* Enable all voltage monitors */
687                it87_write_value(client, IT87_REG_VIN_ENABLE, 0xff);
688        }
689
690        /* Check if tachometers are reset manually or by some reason */
691        tmp = it87_read_value(client, IT87_REG_FAN_CTRL);
692        if ((tmp & 0x70) == 0) {
693                /* Enable all fan tachometers */
694                tmp = (tmp & 0x8f) | 0x70;
695                it87_write_value(client, IT87_REG_FAN_CTRL, tmp);
696        }
697
698        /* Start monitoring */
699        it87_write_value(client, IT87_REG_CONFIG,
700                         (it87_read_value(client, IT87_REG_CONFIG) & 0x36)
701                         | (update_vbat ? 0x41 : 0x01));
702}
703
704static void it87_update_client(struct i2c_client *client)
705{
706        struct it87_data *data = client->data;
707        int i, tmp, tmp2;
708
709        down(&data->update_lock);
710
711        if ((jiffies - data->last_updated > HZ + HZ / 2) ||
712            (jiffies < data->last_updated) || !data->valid) {
713
714                if (update_vbat) {
715        /* Cleared after each update, so reenable.  Value
716           returned by this read will be previous value */
717                        it87_write_value(client, IT87_REG_CONFIG,
718                           it87_read_value(client, IT87_REG_CONFIG) | 0x40);
719                }
720                for (i = 0; i <= 7; i++) {
721                        data->in[i] =
722                            it87_read_value(client, IT87_REG_VIN(i));
723                        data->in_min[i] =
724                            it87_read_value(client, IT87_REG_VIN_MIN(i));
725                        data->in_max[i] =
726                            it87_read_value(client, IT87_REG_VIN_MAX(i));
727                }
728                data->in[8] =
729                    it87_read_value(client, IT87_REG_VIN(8));
730                /* VBAT sensor doesn't have limit registers, set
731                   to min and max value */
732                data->in_min[8] = 0;
733                data->in_max[8] = 255;
734               
735                for (i = 1; i <= 3; i++) {
736                        data->fan[i - 1] =
737                            it87_read_value(client, IT87_REG_FAN(i));
738                        data->fan_min[i - 1] =
739                            it87_read_value(client, IT87_REG_FAN_MIN(i));
740                }
741                for (i = 1; i <= 3; i++) {
742                        data->temp[i - 1] =
743                            it87_read_value(client, IT87_REG_TEMP(i));
744                        data->temp_high[i - 1] =
745                            it87_read_value(client, IT87_REG_TEMP_HIGH(i));
746                        data->temp_low[i - 1] =
747                            it87_read_value(client, IT87_REG_TEMP_LOW(i));
748                }
749
750                if (data->type == it8712) {
751                        data->vid = it87_read_value(client, IT87_REG_VID);
752                        data->vid &= 0x1f;
753                }
754
755                i = it87_read_value(client, IT87_REG_FAN_DIV);
756                data->fan_div[0] = i & 0x07;
757                data->fan_div[1] = (i >> 3) & 0x07;
758                data->fan_div[2] = ( (i&0x40)==0x40 ? 3 : 1 );
759
760                for( i = 1; i <= 3; i++ ) {
761                        data->pwm[i-1] = it87_read_value(client, IT87_REG_PWM(i));
762                        data->sg_tl[i-1][0] = it87_read_value(client, IT87_REG_SG_TL_OFF(i));
763                        data->sg_tl[i-1][1] = it87_read_value(client, IT87_REG_SG_TL_LOW(i));
764                        data->sg_tl[i-1][2] = it87_read_value(client, IT87_REG_SG_TL_MED(i));
765                        data->sg_tl[i-1][3] = it87_read_value(client, IT87_REG_SG_TL_HI(i));
766                        data->sg_tl[i-1][4] = it87_read_value(client, IT87_REG_SG_TL_OVR(i));
767                        data->sg_pwm[i-1][0] = it87_read_value(client, IT87_REG_SG_PWM_LOW(i));
768                        data->sg_pwm[i-1][1] = it87_read_value(client, IT87_REG_SG_PWM_MED(i));
769                        data->sg_pwm[i-1][2] = it87_read_value(client, IT87_REG_SG_PWM_HI(i));
770                }
771                data->alarms =
772                        it87_read_value(client, IT87_REG_ALARM1) |
773                        (it87_read_value(client, IT87_REG_ALARM2) << 8) |
774                        (it87_read_value(client, IT87_REG_ALARM3) << 16);
775                data->fan_ctl[0] = it87_read_value(client, IT87_REG_FAN_CTRL);
776                data->fan_ctl[1] = it87_read_value(client, IT87_REG_FAN_ONOFF);
777
778                tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE);
779                for(i = 0; i < 3; i++) {
780                        tmp2 = (tmp >> i) & 0x09;
781                        if(tmp2 == 0x01)
782                                data->sens[i] = PIIDIODE;
783                        else if(tmp2 == 0x08)
784                                data->sens[i] = THERMISTOR;
785                        else
786                                data->sens[i] = UNUSED;
787                }
788
789                data->last_updated = jiffies;
790                data->valid = 1;
791        }
792
793        up(&data->update_lock);
794}
795
796
797/* The next few functions are the call-back functions of the /proc/sys and
798   sysctl files. Which function is used is defined in the ctl_table in
799   the extra1 field.
800    - Each function must return the magnitude (power of 10 to divide the
801      data with) if it is called with operation==SENSORS_PROC_REAL_INFO.
802    - It must put a maximum of *nrels elements in results reflecting the
803      data of this file, and set *nrels to the number it actually put
804      in it, if operation==SENSORS_PROC_REAL_READ.
805    - Finally, it must get upto *nrels elements from results and write them
806      to the chip, if operations==SENSORS_PROC_REAL_WRITE.
807   Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
808   large enough (by checking the incoming value of *nrels). This is not very
809   good practice, but as long as you put less than about 5 values in results,
810   you can assume it is large enough. */
811void it87_in(struct i2c_client *client, int operation, int ctl_name,
812             int *nrels_mag, long *results)
813{
814        struct it87_data *data = client->data;
815        int nr = ctl_name - IT87_SYSCTL_IN0;
816
817        if (operation == SENSORS_PROC_REAL_INFO)
818                *nrels_mag = 2;
819        else if (operation == SENSORS_PROC_REAL_READ) {
820                it87_update_client(client);
821                results[0] = IN_FROM_REG(data->in_min[nr]);
822                results[1] = IN_FROM_REG(data->in_max[nr]);
823                results[2] = IN_FROM_REG(data->in[nr]);
824                *nrels_mag = 3;
825        } else if (operation == SENSORS_PROC_REAL_WRITE) {
826                if (*nrels_mag >= 1) {
827                        data->in_min[nr] = IN_TO_REG(results[0]);
828                        it87_write_value(client, IT87_REG_VIN_MIN(nr),
829                                         data->in_min[nr]);
830                }
831                if (*nrels_mag >= 2) {
832                        data->in_max[nr] = IN_TO_REG(results[1]);
833                        it87_write_value(client, IT87_REG_VIN_MAX(nr),
834                                         data->in_max[nr]);
835                }
836        }
837}
838
839void it87_fan(struct i2c_client *client, int operation, int ctl_name,
840              int *nrels_mag, long *results)
841{
842        struct it87_data *data = client->data;
843        int nr = ctl_name - IT87_SYSCTL_FAN1 + 1;
844
845        if (operation == SENSORS_PROC_REAL_INFO)
846                *nrels_mag = 0;
847        else if (operation == SENSORS_PROC_REAL_READ) {
848                it87_update_client(client);
849                results[0] = FAN_FROM_REG(data->fan_min[nr - 1],
850                                          DIV_FROM_REG(data->fan_div[nr - 1]));
851                results[1] = FAN_FROM_REG(data->fan[nr - 1],
852                                 DIV_FROM_REG(data->fan_div[nr - 1]));
853                *nrels_mag = 2;
854        } else if (operation == SENSORS_PROC_REAL_WRITE) {
855                if (*nrels_mag >= 1) {
856                        data->fan_min[nr - 1] = FAN_TO_REG(results[0],
857                                                           DIV_FROM_REG(data->fan_div[nr - 1]));
858                        it87_write_value(client, IT87_REG_FAN_MIN(nr),
859                                         data->fan_min[nr - 1]);
860                }
861        }
862}
863
864
865void it87_temp(struct i2c_client *client, int operation, int ctl_name,
866               int *nrels_mag, long *results)
867{
868        struct it87_data *data = client->data;
869        int nr = ctl_name - IT87_SYSCTL_TEMP1 + 1;
870        if (operation == SENSORS_PROC_REAL_INFO)
871                *nrels_mag = 1;
872        else if (operation == SENSORS_PROC_REAL_READ) {
873                it87_update_client(client);
874                results[0] = TEMP_FROM_REG(data->temp_high[nr - 1]);
875                results[1] = TEMP_FROM_REG(data->temp_low[nr - 1]);
876                results[2] = TEMP_FROM_REG(data->temp[nr - 1]);
877                *nrels_mag = 3;
878        } else if (operation == SENSORS_PROC_REAL_WRITE) {
879                if (*nrels_mag >= 1) {
880                        data->temp_high[nr - 1] = TEMP_TO_REG(results[0]);
881                        it87_write_value(client, IT87_REG_TEMP_HIGH(nr),
882                                         data->temp_high[nr - 1]);
883                }
884                if (*nrels_mag >= 2) {
885                        data->temp_low[nr - 1] = TEMP_TO_REG(results[1]);
886                        it87_write_value(client, IT87_REG_TEMP_LOW(nr),
887                                         data->temp_low[nr - 1]);
888                }
889        }
890}
891
892void it87_pwm(struct i2c_client *client, int operation, int ctl_name,
893               int *nrels_mag, long *results)
894{
895        struct it87_data *data = client->data;
896        int nr = ctl_name - IT87_SYSCTL_PWM1 + 1;
897        if (operation == SENSORS_PROC_REAL_INFO)
898                *nrels_mag = 0;
899        else if (operation == SENSORS_PROC_REAL_READ) {
900                it87_update_client(client);
901                results[0] = data->pwm[nr - 1];
902                *nrels_mag = 1;
903        } else if (operation == SENSORS_PROC_REAL_WRITE) {
904                if (*nrels_mag >= 1) {
905                        data->pwm[nr - 1] = results[0];
906                        it87_write_value(client, IT87_REG_PWM(nr), data->pwm[nr - 1]);
907                }
908        }
909}
910
911void it87_sgpwm(struct i2c_client *client, int operation, int ctl_name,
912               int *nrels_mag, long *results)
913{
914        struct it87_data *data = client->data;
915        int nr = ctl_name - IT87_SYSCTL_PWM1 + 1;
916        if (operation == SENSORS_PROC_REAL_INFO)
917                *nrels_mag = 0;
918        else if (operation == SENSORS_PROC_REAL_READ) {
919                it87_update_client(client);
920                results[0] = data->sg_pwm[nr - 1][0];
921                results[1] = data->sg_pwm[nr - 1][1];
922                results[2] = data->sg_pwm[nr - 1][2];
923                *nrels_mag = 3;
924        } else if (operation == SENSORS_PROC_REAL_WRITE) {
925                if (*nrels_mag >= 1) {
926                        data->sg_pwm[nr - 1][0] = results[0];
927                        it87_write_value(client, IT87_REG_SG_PWM_LOW(nr), data->sg_pwm[nr - 1][0]);
928                }
929                if (*nrels_mag >= 2) {
930                        data->sg_pwm[nr - 1][1] = results[1];
931                        it87_write_value(client, IT87_REG_SG_PWM_MED(nr), data->sg_pwm[nr - 1][1]);
932                }
933                if (*nrels_mag >= 3) {
934                        data->sg_pwm[nr - 1][2] = results[2];
935                        it87_write_value(client, IT87_REG_SG_PWM_HI(nr), data->sg_pwm[nr - 1][2]);
936                }
937        }
938}
939
940void it87_sgtl(struct i2c_client *client, int operation, int ctl_name,
941               int *nrels_mag, long *results)
942{
943        struct it87_data *data = client->data;
944        int nr = ctl_name - IT87_SYSCTL_PWM1 + 1;
945        if (operation == SENSORS_PROC_REAL_INFO)
946                *nrels_mag = 1;
947        else if (operation == SENSORS_PROC_REAL_READ) {
948                it87_update_client(client);
949                results[0] = TEMP_FROM_REG(data->sg_tl[nr - 1][0]);
950                results[1] = TEMP_FROM_REG(data->sg_tl[nr - 1][1]);
951                results[2] = TEMP_FROM_REG(data->sg_tl[nr - 1][2]);
952                results[3] = TEMP_FROM_REG(data->sg_tl[nr - 1][3]);
953                results[4] = TEMP_FROM_REG(data->sg_tl[nr - 1][4]);
954                *nrels_mag = 5;
955        } else if (operation == SENSORS_PROC_REAL_WRITE) {
956                if (*nrels_mag >= 1) {
957                        data->sg_tl[nr - 1][0] = TEMP_TO_REG(results[0]);
958                        it87_write_value(client, IT87_REG_SG_TL_OFF(nr), data->sg_tl[nr - 1][0]);
959                }
960                if (*nrels_mag >= 2) {
961                        data->sg_tl[nr - 1][1] = TEMP_TO_REG(results[1]);
962                        it87_write_value(client, IT87_REG_SG_TL_LOW(nr), data->sg_tl[nr - 1][1]);
963                }
964                if (*nrels_mag >= 3) {
965                        data->sg_tl[nr - 1][2] = TEMP_TO_REG(results[2]);
966                        it87_write_value(client, IT87_REG_SG_TL_MED(nr), data->sg_tl[nr - 1][2]);
967                }
968                if (*nrels_mag >= 4) {
969                        data->sg_tl[nr - 1][3] = TEMP_TO_REG(results[3]);
970                        it87_write_value(client, IT87_REG_SG_TL_HI(nr), data->sg_tl[nr - 1][3]);
971                }
972                if (*nrels_mag >= 5) {
973                        data->sg_tl[nr - 1][4] = TEMP_TO_REG(results[4]);
974                        it87_write_value(client, IT87_REG_SG_TL_OVR(nr), data->sg_tl[nr - 1][4]);
975                }
976        }
977}
978
979void it87_vid(struct i2c_client *client, int operation, int ctl_name,
980              int *nrels_mag, long *results)
981{
982        struct it87_data *data = client->data;
983        if (operation == SENSORS_PROC_REAL_INFO)
984                *nrels_mag = 2;
985        else if (operation == SENSORS_PROC_REAL_READ) {
986                it87_update_client(client);
987                results[0] = VID_FROM_REG(data->vid);
988                *nrels_mag = 1;
989        }
990}
991
992void it87_alarms(struct i2c_client *client, int operation,
993                     int ctl_name, int *nrels_mag, long *results)
994{
995        struct it87_data *data = client->data;
996        if (operation == SENSORS_PROC_REAL_INFO)
997                *nrels_mag = 0;
998        else if (operation == SENSORS_PROC_REAL_READ) {
999                it87_update_client(client);
1000                results[0] = ALARMS_FROM_REG(data->alarms);
1001                *nrels_mag = 1;
1002        }
1003}
1004
1005void it87_fan_div(struct i2c_client *client, int operation, int ctl_name,
1006                  int *nrels_mag, long *results)
1007{
1008        struct it87_data *data = client->data;
1009        int old;
1010
1011        if (operation == SENSORS_PROC_REAL_INFO)
1012                *nrels_mag = 0;
1013        else if (operation == SENSORS_PROC_REAL_READ) {
1014                it87_update_client(client);
1015                results[0] = DIV_FROM_REG(data->fan_div[0]);
1016                results[1] = DIV_FROM_REG(data->fan_div[1]);
1017                results[2] = DIV_FROM_REG(data->fan_div[2]);;
1018                *nrels_mag = 3;
1019        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1020                old = it87_read_value(client, IT87_REG_FAN_DIV);
1021                if (*nrels_mag >= 3) {
1022                        data->fan_div[2] = DIV_TO_REG(results[2]);
1023                        if (data->fan_div[2] != 3) {
1024                                data->fan_div[2] = 1;
1025                                old = (old & 0xbf);
1026                        } else {
1027                                old = (old | 0x40);
1028                        }
1029                }
1030                if (*nrels_mag >= 2) {
1031                        data->fan_div[1] = DIV_TO_REG(results[1]);
1032                        old = (old & 0xc3) | (data->fan_div[1] << 3);
1033                }
1034                if (*nrels_mag >= 1) {
1035                        data->fan_div[0] = DIV_TO_REG(results[0]);
1036                        old = (old & 0xf8) | data->fan_div[0];
1037                        it87_write_value(client, IT87_REG_FAN_DIV, old);
1038                }
1039        }
1040}
1041
1042void it87_fan_ctl(struct i2c_client *client, int operation, int ctl_name,
1043               int *nrels_mag, long *results)
1044{
1045        struct it87_data *data = client->data;
1046        int index = ctl_name - IT87_SYSCTL_FAN_CTL;
1047        if (operation == SENSORS_PROC_REAL_INFO)
1048                *nrels_mag = 0;
1049        else if (operation == SENSORS_PROC_REAL_READ) {
1050                it87_update_client(client);
1051                results[0] = data->fan_ctl[index];
1052                *nrels_mag = 1;
1053        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1054                if (*nrels_mag >= 1) {
1055                        data->fan_ctl[index] = results[0];
1056                        if( index == 0 )
1057                                it87_write_value(client, IT87_REG_FAN_CTRL, data->fan_ctl[index] );
1058                        else
1059                                it87_write_value(client, IT87_REG_FAN_ONOFF, data->fan_ctl[index] );
1060                }
1061        }
1062}
1063
1064void it87_sens(struct i2c_client *client, int operation, int ctl_name,
1065                  int *nrels_mag, long *results)
1066{
1067        struct it87_data *data = client->data;
1068        int nr = 1 + ctl_name - IT87_SYSCTL_SENS1;
1069        u8 tmp, val1, val2;
1070
1071        if (operation == SENSORS_PROC_REAL_INFO)
1072                *nrels_mag = 0;
1073        else if (operation == SENSORS_PROC_REAL_READ) {
1074                results[0] = data->sens[nr - 1];
1075                *nrels_mag = 1;
1076        } else if (operation == SENSORS_PROC_REAL_WRITE) {
1077                if (*nrels_mag >= 1) {
1078                        val1 = 0x01 << (nr - 1);
1079                        val2 = 0x08 << (nr - 1);
1080                        tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE);
1081                        switch (results[0]) {
1082                        case PIIDIODE:
1083                                tmp &= ~ val2;
1084                                tmp |= val1;
1085                                break;
1086                        case THERMISTOR:
1087                                tmp &= ~ val1;
1088                                tmp |= val2;
1089                                break;
1090                        case UNUSED:
1091                                tmp &= ~ val1;
1092                                tmp &= ~ val2;
1093                                break;
1094                        default:
1095                                printk(KERN_ERR "it87.o: Invalid sensor type %ld; "
1096                                       "must be 0 (unused), 2 (thermistor) "
1097                                       "or 3 (diode)\n", results[0]);
1098                                return;
1099                        }
1100                        it87_write_value(client,
1101                                         IT87_REG_TEMP_ENABLE, tmp);
1102                        data->sens[nr - 1] = results[0];
1103                }
1104        }
1105}
1106
1107static int __init sm_it87_init(void)
1108{
1109        int addr;
1110
1111        printk("it87.o version %s (%s)\n", LM_VERSION, LM_DATE);
1112        if (!it87_find(&addr)) {
1113                normal_isa[0] = addr;
1114        }
1115        return i2c_add_driver(&it87_driver);
1116}
1117
1118static void __exit sm_it87_exit(void)
1119{
1120        i2c_del_driver(&it87_driver);
1121}
1122
1123
1124MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>");
1125MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver");
1126MODULE_PARM(update_vbat, "i");
1127MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
1128MODULE_PARM(reset, "i");
1129MODULE_PARM_DESC(reset, "Reset the chip's registers, default no");
1130
1131module_init(sm_it87_init);
1132module_exit(sm_it87_exit);
Note: See TracBrowser for help on using the browser.