root/lm-sensors/trunk/kernel/busses/i2c-i801.c @ 849

Revision 849, 17.1 KB (checked in by mds, 13 years ago)

(mds) add support for Intel 82801BA ICH2 (815E chipset).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    i801.c - Part of lm_sensors, Linux kernel modules for hardware
3              monitoring
4    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
5    Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
6    <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    This driver supports the Intel 82801AA, 82801AB, and 82801BA
25    I/O Controller Hubs (ICH). They are similar to the PIIX4 and are part
26    of Intel's '810' and other chipsets.
27    See the doc/busses/i2c-i801 file for details.
28*/
29
30/* Note: we assume there can only be one I801, with one SMBus interface */
31
32#include <linux/version.h>
33#include <linux/module.h>
34#include <linux/pci.h>
35#include <asm/io.h>
36#include <linux/kernel.h>
37#include <linux/stddef.h>
38#include <linux/sched.h>
39#include <linux/ioport.h>
40#include <linux/init.h>
41#include <linux/i2c.h>
42#include "version.h"
43
44#ifndef PCI_DEVICE_ID_INTEL_82801AA_3
45#define PCI_DEVICE_ID_INTEL_82801AA_3   0x2413
46#endif
47#ifndef PCI_DEVICE_ID_INTEL_82801AB_3
48#define PCI_DEVICE_ID_INTEL_82801AB_3   0x2423
49#endif
50#ifndef PCI_DEVICE_ID_INTEL_82801BA_3
51#define PCI_DEVICE_ID_INTEL_82801BA_3   0x2443
52#endif
53
54/* I801 SMBus address offsets */
55#define SMBHSTSTS (0 + i801_smba)
56#define SMBHSTCNT (2 + i801_smba)
57#define SMBHSTCMD (3 + i801_smba)
58#define SMBHSTADD (4 + i801_smba)
59#define SMBHSTDAT0 (5 + i801_smba)
60#define SMBHSTDAT1 (6 + i801_smba)
61#define SMBBLKDAT (7 + i801_smba)
62
63/* PCI Address Constants */
64#define SMBBA     0x020
65#define SMBHSTCFG 0x040
66#define SMBREV    0x008
67
68/* Other settings */
69#define MAX_TIMEOUT 500
70#define  ENABLE_INT9 0
71
72/* I801 command constants */
73#define I801_QUICK          0x00
74#define I801_BYTE           0x04
75#define I801_BYTE_DATA      0x08
76#define I801_WORD_DATA      0x0C
77#define I801_BLOCK_DATA     0x14
78#define I801_I2C_BLOCK_DATA 0x18        /* unimplemented */
79#define I801_BLOCK_LAST     0x34
80#define I801_I2C_BLOCK_LAST 0x38        /* unimplemented */
81
82/* insmod parameters */
83
84/* If force is set to anything different from 0, we forcibly enable the
85   I801. DANGEROUS! */
86static int force = 0;
87MODULE_PARM(force, "i");
88MODULE_PARM_DESC(force, "Forcibly enable the I801. DANGEROUS!");
89
90/* If force_addr is set to anything different from 0, we forcibly enable
91   the I801 at the given address. VERY DANGEROUS! */
92static int force_addr = 0;
93MODULE_PARM(force_addr, "i");
94MODULE_PARM_DESC(force_addr,
95                 "Forcibly enable the I801 at the given address. "
96                 "EXTREMELY DANGEROUS!");
97
98static int __init i801_cleanup(void);
99static int i801_setup(void);
100static s32 i801_access(struct i2c_adapter *adap, u16 addr,
101                       unsigned short flags, char read_write,
102                       u8 command, int size, union i2c_smbus_data *data);
103static void i801_do_pause(unsigned int amount);
104static int i801_transaction(void);
105static int i801_block_transaction(union i2c_smbus_data *data,
106                                  char read_write);
107static void i801_inc(struct i2c_adapter *adapter);
108static void i801_dec(struct i2c_adapter *adapter);
109static u32 i801_func(struct i2c_adapter *adapter);
110
111#ifdef MODULE
112extern int init_module(void);
113extern int cleanup_module(void);
114#endif                          /* MODULE */
115
116static struct i2c_algorithm smbus_algorithm = {
117        /* name */ "Non-I2C SMBus adapter",
118        /* id */ I2C_ALGO_SMBUS,
119        /* master_xfer */ NULL,
120        /* smbus_access */ i801_access,
121        /* slave_send */ NULL,
122        /* slave_rcv */ NULL,
123        /* algo_control */ NULL,
124        /* functionality */ i801_func,
125};
126
127static struct i2c_adapter i801_adapter = {
128        "unset",
129        I2C_ALGO_SMBUS | I2C_HW_SMBUS_I801,
130        &smbus_algorithm,
131        NULL,
132        i801_inc,
133        i801_dec,
134        NULL,
135        NULL,
136};
137
138static int __initdata i801_initialized;
139static unsigned short i801_smba = 0;
140
141
142/* Detect whether a I801 can be found, and initialize it, where necessary.
143   Note the differences between kernels with the old PCI BIOS interface and
144   newer kernels with the real PCI interface. In compat.h some things are
145   defined to make the transition easier. */
146int i801_setup(void)
147{
148        int error_return = 0;
149        unsigned char temp;
150
151        struct pci_dev *I801_dev;
152
153        /* First check whether we can access PCI at all */
154        if (pci_present() == 0) {
155                printk("i2c-i801.o: Error: No PCI-bus found!\n");
156                error_return = -ENODEV;
157                goto END;
158        }
159
160        /* Look for the I801, function 3 */
161        /* Have to check for both the 82801AA and 82801AB */
162        /* Note: we keep on searching until we have found 'function 3' */
163        I801_dev = NULL;
164        do
165                I801_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
166                                           PCI_DEVICE_ID_INTEL_82801AA_3,
167                                           I801_dev);
168        while (I801_dev && (PCI_FUNC(I801_dev->devfn) != 3));
169        if (I801_dev == NULL) {
170                do
171                        I801_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
172                                           PCI_DEVICE_ID_INTEL_82801AB_3,
173                                           I801_dev);
174                while (I801_dev && (PCI_FUNC(I801_dev->devfn) != 3));
175        }
176        if (I801_dev == NULL) {
177                do
178                        I801_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
179                                           PCI_DEVICE_ID_INTEL_82801BA_3,
180                                           I801_dev);
181                while (I801_dev && (PCI_FUNC(I801_dev->devfn) != 3));
182        }
183        if (I801_dev == NULL) {
184                printk
185                    ("i2c-i801.o: Error: Can't detect I801, function 3!\n");
186                error_return = -ENODEV;
187                goto END;
188        }
189
190/* Determine the address of the SMBus areas */
191        if (force_addr) {
192                i801_smba = force_addr & 0xfff0;
193                force = 0;
194        } else {
195                pci_read_config_word(I801_dev, SMBBA, &i801_smba);
196                i801_smba &= 0xfff0;
197        }
198
199        if (check_region(i801_smba, 8)) {
200                printk
201                    ("i2c-i801.o: I801_smb region 0x%x already in use!\n",
202                     i801_smba);
203                error_return = -ENODEV;
204                goto END;
205        }
206
207        pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
208/* If force_addr is set, we program the new address here. Just to make
209   sure, we disable the I801 first. */
210        if (force_addr) {
211                pci_write_config_byte(I801_dev, SMBHSTCFG, temp & 0xfe);
212                pci_write_config_word(I801_dev, SMBBA, i801_smba);
213                pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 0x01);
214                printk
215                    ("i2c-i801.o: WARNING: I801 SMBus interface set to new "
216                     "address %04x!\n", i801_smba);
217        } else if ((temp & 1) == 0) {
218                if (force) {
219/* This should never need to be done, but has been noted that
220   many Dell machines have the SMBus interface on the PIIX4
221   disabled!? NOTE: This assumes I/O space and other allocations WERE
222   done by the Bios!  Don't complain if your hardware does weird
223   things after enabling this. :') Check for Bios updates before
224   resorting to this.  */
225                        pci_write_config_byte(I801_dev, SMBHSTCFG,
226                                              temp | 1);
227                        printk
228                            ("i2c-i801.o: WARNING: I801 SMBus interface has been FORCEFULLY "
229                             "ENABLED!\n");
230                } else {
231                        printk
232                            ("SMBUS: Error: Host SMBus controller not enabled!\n");
233                        error_return = -ENODEV;
234                        goto END;
235                }
236        }
237
238        /* note: we assumed that the BIOS picked SMBus or I2C Bus timing
239           appropriately (bit 2 in SMBHSTCFG) */
240        /* Everything is happy, let's grab the memory and set things up. */
241        request_region(i801_smba, 8, "i801-smbus");
242
243#ifdef DEBUG
244        if (temp & 0x02)
245                printk
246                    ("i2c-i801.o: I801 using Interrupt SMI# for SMBus.\n");
247        else
248                printk
249                    ("i2c-i801.o: I801 using PCI Interrupt for SMBus.\n");
250
251        pci_read_config_byte(I801_dev, SMBREV, &temp);
252        printk("i2c-i801.o: SMBREV = 0x%X\n", temp);
253        printk("i2c-i801.o: I801_smba = 0x%X\n", i801_smba);
254#endif                          /* DEBUG */
255
256      END:
257        return error_return;
258}
259
260
261/* Internally used pause function */
262void i801_do_pause(unsigned int amount)
263{
264        current->state = TASK_INTERRUPTIBLE;
265        schedule_timeout(amount);
266}
267
268/* Another internally used function */
269int i801_transaction(void)
270{
271        int temp;
272        int result = 0;
273        int timeout = 0;
274
275#ifdef DEBUG
276        printk
277            ("i2c-i801.o: Transaction (pre): CNT=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, "
278             "DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD),
279             inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
280#endif
281
282        /* Make sure the SMBus host is ready to start transmitting */
283        /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
284        if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
285#ifdef DEBUG
286                printk("i2c-i801.o: SMBus busy (%02x). Resetting... \n",
287                       temp);
288#endif
289                outb_p(temp, SMBHSTSTS);
290                if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
291#ifdef DEBUG
292                        printk("i2c-i801.o: Failed! (%02x)\n", temp);
293#endif
294                        return -1;
295                } else {
296#ifdef DEBUG
297                        printk("i2c-i801.o: Successfull!\n");
298#endif
299                }
300        }
301
302        /* start the transaction by setting bit 6 */
303        outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
304
305        /* We will always wait for a fraction of a second! */
306        do {
307                i801_do_pause(1);
308                temp = inb_p(SMBHSTSTS);
309        } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
310
311        /* If the SMBus is still busy, we give up */
312        if (timeout >= MAX_TIMEOUT) {
313#ifdef DEBUG
314                printk("i2c-i801.o: SMBus Timeout!\n");
315                result = -1;
316#endif
317        }
318
319        if (temp & 0x10) {
320                result = -1;
321#ifdef DEBUG
322                printk("i2c-i801.o: Error: Failed bus transaction\n");
323#endif
324        }
325
326        if (temp & 0x08) {
327                result = -1;
328                printk
329                    ("i2c-i801.o: Bus collision! SMBus may be locked until next hard\n"
330                     "reset. (sorry!)\n");
331                /* Clock stops and slave is stuck in mid-transmission */
332        }
333
334        if (temp & 0x04) {
335                result = -1;
336#ifdef DEBUG
337                printk("i2c-i801.o: Error: no response!\n");
338#endif
339        }
340
341        if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00)
342                outb_p(inb(SMBHSTSTS), SMBHSTSTS);
343
344        if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
345#ifdef DEBUG
346                printk
347                    ("i2c-i801.o: Failed reset at end of transaction (%02x)\n",
348                     temp);
349#endif
350        }
351#ifdef DEBUG
352        printk
353            ("i2c-i801.o: Transaction (post): CNT=%02x, CMD=%02x, ADD=%02x, "
354             "DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD),
355             inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
356#endif
357        return result;
358}
359
360/* All-inclusive block transaction function */
361int i801_block_transaction(union i2c_smbus_data *data, char read_write)
362{
363        int i, len;
364        int smbcmd;
365        int temp;
366        int result = 0;
367        int timeout = 0;
368
369        if (read_write == I2C_SMBUS_WRITE) {
370                len = data->block[0];
371                if (len < 1)
372                        len = 1;
373                if (len > 32)
374                        len = 32;
375                outb_p(len, SMBHSTDAT0);
376                outb_p(data->block[1], SMBBLKDAT);
377        } else {
378                len = 32;       /* max for reads */
379        }
380
381        for (i = 1; i <= len; i++) {
382                if (i == len && read_write == I2C_SMBUS_READ)
383                        smbcmd = I801_BLOCK_LAST;
384                else
385                        smbcmd = I801_BLOCK_DATA;
386                if (read_write == I2C_SMBUS_WRITE)
387                        outb_p(data->block[i], SMBBLKDAT);
388                outb_p((smbcmd & 0x3C) + (ENABLE_INT9 & 1), SMBHSTCNT);
389
390#ifdef DEBUG
391                printk
392                    ("i2c-i801.o: Transaction (pre): CNT=%02x, CMD=%02x, ADD=%02x, "
393                     "DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
394                     inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
395                     inb_p(SMBHSTDAT1));
396#endif
397
398                /* Make sure the SMBus host is ready to start transmitting */
399                /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
400                /* 0x9e = Byte_Done, Failed, Bus_Err, Dev_Err, Intr */
401                temp = inb_p(SMBHSTSTS);
402                if (((i == 1) && ((temp & 0x1f) != 0x00)) ||
403                    ((i != 1) && ((temp & 0x9e) != 0x00))) {
404#ifdef DEBUG
405                        printk
406                            ("i2c-i801.o: SMBus busy (%02x). Resetting... \n",
407                             temp);
408#endif
409                        outb_p(temp, SMBHSTSTS);
410                        if (((temp = inb_p(SMBHSTSTS)) & 0x9f) != 0x00) {
411                                printk
412                                    ("i2c-i801.o: Reset failed! (%02x)\n",
413                                     temp);
414                                return -1;
415                        }
416                        if (i != 1)
417                                return -1;      /* if die in middle of block transaction, fail */
418                }
419
420                /* start the transaction by setting bit 6 */
421                outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
422
423                /* We will always wait for a fraction of a second! */
424                do {
425                        i801_do_pause(1);
426                        temp = inb_p(SMBHSTSTS);
427                }
428                    while (
429                           (((i >= len) && (temp & 0x01))
430                            || ((i < len) && (temp & 0x80)))
431                           && (timeout++ < MAX_TIMEOUT));
432
433                /* If the SMBus is still busy, we give up */
434                if (timeout >= MAX_TIMEOUT) {
435                        result = -1;
436#ifdef DEBUG
437                        printk("i2c-i801.o: SMBus Timeout!\n");
438#endif
439                }
440
441                if (temp & 0x10) {
442                        result = -1;
443#ifdef DEBUG
444                        printk
445                            ("i2c-i801.o: Error: Failed bus transaction\n");
446#endif
447                } else if (temp & 0x08) {
448                        result = -1;
449                        printk
450                            ("i2c-i801.o: Bus collision! SMBus may be locked until next hard"
451                             " reset. (sorry!)\n");
452                        /* Clock stops and slave is stuck in mid-transmission */
453                } else if (temp & 0x04) {
454                        result = -1;
455#ifdef DEBUG
456                        printk("i2c-i801.o: Error: no response!\n");
457#endif
458                } else if (temp & 0x80) {
459                        result = -1;
460#ifdef DEBUG
461                        printk
462                            ("i2c-i801.o: Error: Failed in middle of block!\n");
463#endif
464                }
465
466                if ((temp & 0x9f) != 0x00)
467                        outb_p(temp, SMBHSTSTS);
468
469                if ((temp = (0x9f & inb_p(SMBHSTSTS))) != 0x00) {
470#ifdef DEBUG
471                        printk
472                            ("i2c-i801.o: Failed reset at end of transaction (%02x)\n",
473                             temp);
474#endif
475                }
476#ifdef DEBUG
477                printk
478                    ("i2c-i801.o: Transaction (post): CNT=%02x, CMD=%02x, ADD=%02x, "
479                     "DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
480                     inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
481                     inb_p(SMBHSTDAT1));
482#endif
483
484                if (i == 1 && read_write == I2C_SMBUS_READ) {
485                        len = inb_p(SMBHSTDAT0);
486                        if (len < 1)
487                                len = 1;
488                        if (len > 32)
489                                len = 32;
490                        data->block[0] = len;
491                }
492                if (read_write == I2C_SMBUS_READ)
493                        data->block[i] = inb_p(SMBBLKDAT);
494
495                if (result < 0)
496                        return (result);
497        }
498        return (0);
499}
500
501/* Return -1 on error. See smbus.h for more information */
502s32 i801_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
503                char read_write, u8 command, int size,
504                union i2c_smbus_data * data)
505{
506
507        switch (size) {
508        case I2C_SMBUS_PROC_CALL:
509                printk("i2c-i801.o: I2C_SMBUS_PROC_CALL not supported!\n");
510                return -1;
511        case I2C_SMBUS_QUICK:
512                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
513                       SMBHSTADD);
514                size = I801_QUICK;
515                break;
516        case I2C_SMBUS_BYTE:
517                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
518                       SMBHSTADD);
519                if (read_write == I2C_SMBUS_WRITE)
520                        outb_p(command, SMBHSTCMD);
521                size = I801_BYTE;
522                break;
523        case I2C_SMBUS_BYTE_DATA:
524                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
525                       SMBHSTADD);
526                outb_p(command, SMBHSTCMD);
527                if (read_write == I2C_SMBUS_WRITE)
528                        outb_p(data->byte, SMBHSTDAT0);
529                size = I801_BYTE_DATA;
530                break;
531        case I2C_SMBUS_WORD_DATA:
532                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
533                       SMBHSTADD);
534                outb_p(command, SMBHSTCMD);
535                if (read_write == I2C_SMBUS_WRITE) {
536                        outb_p(data->word & 0xff, SMBHSTDAT0);
537                        outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
538                }
539                size = I801_WORD_DATA;
540                break;
541        case I2C_SMBUS_BLOCK_DATA:
542                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
543                       SMBHSTADD);
544                outb_p(command, SMBHSTCMD);
545                /* Block transactions are very different from piix4 block
546                   and from the other i801 transactions. Handle in the
547                   i801_block_transaction() routine. */
548                return (i801_block_transaction(data, read_write));
549        }
550
551        /* 'size' is really the transaction type */
552        outb_p((size & 0x3C) + (ENABLE_INT9 & 1), SMBHSTCNT);
553
554        if (i801_transaction()) /* Error in transaction */
555                return -1;
556
557        if ((read_write == I2C_SMBUS_WRITE) || (size == I801_QUICK))
558                return 0;
559
560
561        switch (size) {
562        case I801_BYTE: /* Result put in SMBHSTDAT0 */
563                data->byte = inb_p(SMBHSTDAT0);
564                break;
565        case I801_BYTE_DATA:
566                data->byte = inb_p(SMBHSTDAT0);
567                break;
568        case I801_WORD_DATA:
569                data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
570                break;
571        }
572        return 0;
573}
574
575void i801_inc(struct i2c_adapter *adapter)
576{
577        MOD_INC_USE_COUNT;
578}
579
580void i801_dec(struct i2c_adapter *adapter)
581{
582        MOD_DEC_USE_COUNT;
583}
584
585u32 i801_func(struct i2c_adapter *adapter)
586{
587        return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
588            I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
589            I2C_FUNC_SMBUS_BLOCK_DATA;
590}
591
592int __init i2c_i801_init(void)
593{
594        int res;
595        printk("i801.o version %s (%s)\n", LM_VERSION, LM_DATE);
596#ifdef DEBUG
597/* PE- It might be good to make this a permanent part of the code! */
598        if (i801_initialized) {
599                printk
600                    ("i2c-i801.o: Oops, i801_init called a second time!\n");
601                return -EBUSY;
602        }
603#endif
604        i801_initialized = 0;
605        if ((res = i801_setup())) {
606                printk
607                    ("i2c-i801.o: I801 not detected, module not inserted.\n");
608                i801_cleanup();
609                return res;
610        }
611        i801_initialized++;
612        sprintf(i801_adapter.name, "SMBus I801 adapter at %04x",
613                i801_smba);
614        if ((res = i2c_add_adapter(&i801_adapter))) {
615                printk
616                    ("i2c-i801.o: Adapter registration failed, module not inserted.\n");
617                i801_cleanup();
618                return res;
619        }
620        i801_initialized++;
621        printk("i2c-i801.o: I801 bus detected and initialized\n");
622        return 0;
623}
624
625int __init i801_cleanup(void)
626{
627        int res;
628        if (i801_initialized >= 2) {
629                if ((res = i2c_del_adapter(&i801_adapter))) {
630                        printk
631                            ("i2c-i801.o: i2c_del_adapter failed, module not removed\n");
632                        return res;
633                } else
634                        i801_initialized--;
635        }
636        if (i801_initialized >= 1) {
637                release_region(i801_smba, 8);
638                i801_initialized--;
639        }
640        return 0;
641}
642
643EXPORT_NO_SYMBOLS;
644
645#ifdef MODULE
646
647MODULE_AUTHOR
648    ("Frodo Looijaard <frodol@dds.nl>, Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker <mdsxyz123@yahoo.com>");
649MODULE_DESCRIPTION("I801 SMBus driver");
650
651int init_module(void)
652{
653        return i2c_i801_init();
654}
655
656int cleanup_module(void)
657{
658        return i801_cleanup();
659}
660
661#endif                          /* MODULE */
Note: See TracBrowser for help on using the browser.