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

Revision 583, 18.3 KB (checked in by frodo, 14 years ago)

`functionality' support for all bus drivers

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