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

Revision 586, 18.4 KB (checked in by frodo, 14 years ago)

Better 10-bit addresses support changes

* Enlarged addresses from 8 to 16 bits at some places.

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