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

Revision 689, 18.4 KB (checked in by mds, 13 years ago)

(mds) change my email addr.

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