MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / i2c / busses / i2c-i801.c
blobe873ba0018b850be7fe57a88ff231228ac38a47b
1 /*
2 i801.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring
4 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
5 Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
6 <mdsxyz123@yahoo.com>
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.
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.
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.
24 SUPPORTED DEVICES PCI ID
25 82801AA 2413
26 82801AB 2423
27 82801BA 2443
28 82801CA/CAM 2483
29 82801DB 24C3 (HW PEC supported, 32 byte buffer not supported)
30 82801EB 24D3 (HW PEC supported, 32 byte buffer not supported)
31 6300ESB 25A4
32 ICH6 266A
33 This driver supports several versions of Intel's I/O Controller Hubs (ICH).
34 For SMBus support, they are similar to the PIIX4 and are part
35 of Intel's '810' and other chipsets.
36 See the doc/busses/i2c-i801 file for details.
37 I2C Block Read and Process Call are not supported.
40 /* Note: we assume there can only be one I801, with one SMBus interface */
42 #include <linux/config.h>
43 #include <linux/module.h>
44 #include <linux/pci.h>
45 #include <linux/kernel.h>
46 #include <linux/stddef.h>
47 #include <linux/delay.h>
48 #include <linux/sched.h>
49 #include <linux/ioport.h>
50 #include <linux/init.h>
51 #include <linux/i2c.h>
52 #include <asm/io.h>
54 #ifdef I2C_FUNC_SMBUS_BLOCK_DATA_PEC
55 #define HAVE_PEC
56 #endif
58 /* I801 SMBus address offsets */
59 #define SMBHSTSTS (0 + i801_smba)
60 #define SMBHSTCNT (2 + i801_smba)
61 #define SMBHSTCMD (3 + i801_smba)
62 #define SMBHSTADD (4 + i801_smba)
63 #define SMBHSTDAT0 (5 + i801_smba)
64 #define SMBHSTDAT1 (6 + i801_smba)
65 #define SMBBLKDAT (7 + i801_smba)
66 #define SMBPEC (8 + i801_smba) /* ICH4 only */
67 #define SMBAUXSTS (12 + i801_smba) /* ICH4 only */
68 #define SMBAUXCTL (13 + i801_smba) /* ICH4 only */
70 /* PCI Address Constants */
71 #define SMBBA 0x020
72 #define SMBHSTCFG 0x040
73 #define SMBREV 0x008
75 /* Host configuration bits for SMBHSTCFG */
76 #define SMBHSTCFG_HST_EN 1
77 #define SMBHSTCFG_SMB_SMI_EN 2
78 #define SMBHSTCFG_I2C_EN 4
80 /* Other settings */
81 #define MAX_TIMEOUT 100
82 #define ENABLE_INT9 0 /* set to 0x01 to enable - untested */
84 /* I801 command constants */
85 #define I801_QUICK 0x00
86 #define I801_BYTE 0x04
87 #define I801_BYTE_DATA 0x08
88 #define I801_WORD_DATA 0x0C
89 #define I801_PROC_CALL 0x10 /* later chips only, unimplemented */
90 #define I801_BLOCK_DATA 0x14
91 #define I801_I2C_BLOCK_DATA 0x18 /* unimplemented */
92 #define I801_BLOCK_LAST 0x34
93 #define I801_I2C_BLOCK_LAST 0x38 /* unimplemented */
94 #define I801_START 0x40
95 #define I801_PEC_EN 0x80 /* ICH4 only */
97 /* insmod parameters */
99 /* If force_addr is set to anything different from 0, we forcibly enable
100 the I801 at the given address. VERY DANGEROUS! */
101 static u16 force_addr;
102 module_param(force_addr, ushort, 0);
103 MODULE_PARM_DESC(force_addr,
104 "Forcibly enable the I801 at the given address. "
105 "EXTREMELY DANGEROUS!");
107 static int i801_transaction(void);
108 static int i801_block_transaction(union i2c_smbus_data *data,
109 char read_write, int command);
111 static unsigned short i801_smba;
112 static struct pci_dev *I801_dev;
113 static int isich4;
115 static int i801_setup(struct pci_dev *dev)
117 int error_return = 0;
118 unsigned char temp;
120 /* Note: we keep on searching until we have found 'function 3' */
121 if(PCI_FUNC(dev->devfn) != 3)
122 return -ENODEV;
124 I801_dev = dev;
125 if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
126 (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
127 (dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
128 isich4 = 1;
129 else
130 isich4 = 0;
132 /* Determine the address of the SMBus areas */
133 if (force_addr) {
134 i801_smba = force_addr & 0xfff0;
135 } else {
136 pci_read_config_word(I801_dev, SMBBA, &i801_smba);
137 i801_smba &= 0xfff0;
138 if(i801_smba == 0) {
139 dev_err(&dev->dev, "SMB base address uninitialized"
140 "- upgrade BIOS or use force_addr=0xaddr\n");
141 return -ENODEV;
145 if (!request_region(i801_smba, (isich4 ? 16 : 8), "i801-smbus")) {
146 dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n",
147 i801_smba);
148 error_return = -EBUSY;
149 goto END;
152 pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
153 temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
154 pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
156 /* If force_addr is set, we program the new address here. Just to make
157 sure, we disable the device first. */
158 if (force_addr) {
159 pci_write_config_byte(I801_dev, SMBHSTCFG, temp & 0xfe);
160 pci_write_config_word(I801_dev, SMBBA, i801_smba);
161 pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 0x01);
162 dev_warn(&dev->dev, "WARNING: I801 SMBus interface set to "
163 "new address %04x!\n", i801_smba);
164 } else if ((temp & 1) == 0) {
165 pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1);
166 dev_warn(&dev->dev, "enabling SMBus device\n");
169 if (temp & 0x02)
170 dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n");
171 else
172 dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n");
174 pci_read_config_byte(I801_dev, SMBREV, &temp);
175 dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
176 dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba);
178 END:
179 return error_return;
182 static int i801_transaction(void)
184 int temp;
185 int result = 0;
186 int timeout = 0;
188 dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x,"
189 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
190 inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
191 inb_p(SMBHSTDAT1));
193 /* Make sure the SMBus host is ready to start transmitting */
194 /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
195 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
196 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting... \n",
197 temp);
198 outb_p(temp, SMBHSTSTS);
199 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
200 dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp);
201 return -1;
202 } else {
203 dev_dbg(&I801_dev->dev, "Successfull!\n");
207 outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
209 /* We will always wait for a fraction of a second! */
210 do {
211 msleep(1);
212 temp = inb_p(SMBHSTSTS);
213 } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
215 /* If the SMBus is still busy, we give up */
216 if (timeout >= MAX_TIMEOUT) {
217 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
218 result = -1;
221 if (temp & 0x10) {
222 result = -1;
223 dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
226 if (temp & 0x08) {
227 result = -1;
228 dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
229 "until next hard reset. (sorry!)\n");
230 /* Clock stops and slave is stuck in mid-transmission */
233 if (temp & 0x04) {
234 result = -1;
235 dev_dbg(&I801_dev->dev, "Error: no response!\n");
238 if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00)
239 outb_p(inb(SMBHSTSTS), SMBHSTSTS);
241 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
242 dev_dbg(&I801_dev->dev, "Failed reset at end of transaction"
243 "(%02x)\n", temp);
245 dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, "
246 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
247 inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
248 inb_p(SMBHSTDAT1));
249 return result;
252 /* All-inclusive block transaction function */
253 static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
254 int command)
256 int i, len;
257 int smbcmd;
258 int temp;
259 int result = 0;
260 int timeout;
261 unsigned char hostc, errmask;
263 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
264 if (read_write == I2C_SMBUS_WRITE) {
265 /* set I2C_EN bit in configuration register */
266 pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
267 pci_write_config_byte(I801_dev, SMBHSTCFG,
268 hostc | SMBHSTCFG_I2C_EN);
269 } else {
270 dev_err(&I801_dev->dev,
271 "I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
272 return -1;
276 if (read_write == I2C_SMBUS_WRITE) {
277 len = data->block[0];
278 if (len < 1)
279 len = 1;
280 if (len > 32)
281 len = 32;
282 outb_p(len, SMBHSTDAT0);
283 outb_p(data->block[1], SMBBLKDAT);
284 } else {
285 len = 32; /* max for reads */
288 if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
289 /* set 32 byte buffer */
292 for (i = 1; i <= len; i++) {
293 if (i == len && read_write == I2C_SMBUS_READ)
294 smbcmd = I801_BLOCK_LAST;
295 else
296 smbcmd = I801_BLOCK_DATA;
297 outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT);
299 dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, "
300 "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
301 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
302 inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
304 /* Make sure the SMBus host is ready to start transmitting */
305 temp = inb_p(SMBHSTSTS);
306 if (i == 1) {
307 /* Erronenous conditions before transaction:
308 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
309 errmask=0x9f;
310 } else {
311 /* Erronenous conditions during transaction:
312 * Failed, Bus_Err, Dev_Err, Intr */
313 errmask=0x1e;
315 if (temp & errmask) {
316 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
317 "Resetting... \n", temp);
318 outb_p(temp, SMBHSTSTS);
319 if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
320 dev_err(&I801_dev->dev,
321 "Reset failed! (%02x)\n", temp);
322 result = -1;
323 goto END;
325 if (i != 1) {
326 /* if die in middle of block transaction, fail */
327 result = -1;
328 goto END;
332 if (i == 1)
333 outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
335 /* We will always wait for a fraction of a second! */
336 timeout = 0;
337 do {
338 temp = inb_p(SMBHSTSTS);
339 msleep(1);
341 while ((!(temp & 0x80))
342 && (timeout++ < MAX_TIMEOUT));
344 /* If the SMBus is still busy, we give up */
345 if (timeout >= MAX_TIMEOUT) {
346 result = -1;
347 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
350 if (temp & 0x10) {
351 result = -1;
352 dev_dbg(&I801_dev->dev,
353 "Error: Failed bus transaction\n");
354 } else if (temp & 0x08) {
355 result = -1;
356 dev_err(&I801_dev->dev, "Bus collision!\n");
357 } else if (temp & 0x04) {
358 result = -1;
359 dev_dbg(&I801_dev->dev, "Error: no response!\n");
362 if (i == 1 && read_write == I2C_SMBUS_READ) {
363 len = inb_p(SMBHSTDAT0);
364 if (len < 1)
365 len = 1;
366 if (len > 32)
367 len = 32;
368 data->block[0] = len;
371 /* Retrieve/store value in SMBBLKDAT */
372 if (read_write == I2C_SMBUS_READ)
373 data->block[i] = inb_p(SMBBLKDAT);
374 if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
375 outb_p(data->block[i+1], SMBBLKDAT);
376 if ((temp & 0x9e) != 0x00)
377 outb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */
379 if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) {
380 dev_dbg(&I801_dev->dev,
381 "Bad status (%02x) at end of transaction\n",
382 temp);
384 dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, "
385 "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
386 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
387 inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
389 if (result < 0)
390 goto END;
393 #ifdef HAVE_PEC
394 if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) {
395 /* wait for INTR bit as advised by Intel */
396 timeout = 0;
397 do {
398 temp = inb_p(SMBHSTSTS);
399 msleep(1);
400 } while ((!(temp & 0x02))
401 && (timeout++ < MAX_TIMEOUT));
403 if (timeout >= MAX_TIMEOUT) {
404 dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
406 outb_p(temp, SMBHSTSTS);
408 #endif
409 result = 0;
410 END:
411 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
412 /* restore saved configuration register value */
413 pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
415 return result;
418 /* Return -1 on error. */
419 static s32 i801_access(struct i2c_adapter * adap, u16 addr,
420 unsigned short flags, char read_write, u8 command,
421 int size, union i2c_smbus_data * data)
423 int hwpec = 0;
424 int block = 0;
425 int ret, xact = 0;
427 #ifdef HAVE_PEC
428 if(isich4)
429 hwpec = (flags & I2C_CLIENT_PEC) != 0;
430 #endif
432 switch (size) {
433 case I2C_SMBUS_QUICK:
434 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
435 SMBHSTADD);
436 xact = I801_QUICK;
437 break;
438 case I2C_SMBUS_BYTE:
439 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
440 SMBHSTADD);
441 if (read_write == I2C_SMBUS_WRITE)
442 outb_p(command, SMBHSTCMD);
443 xact = I801_BYTE;
444 break;
445 case I2C_SMBUS_BYTE_DATA:
446 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
447 SMBHSTADD);
448 outb_p(command, SMBHSTCMD);
449 if (read_write == I2C_SMBUS_WRITE)
450 outb_p(data->byte, SMBHSTDAT0);
451 xact = I801_BYTE_DATA;
452 break;
453 case I2C_SMBUS_WORD_DATA:
454 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
455 SMBHSTADD);
456 outb_p(command, SMBHSTCMD);
457 if (read_write == I2C_SMBUS_WRITE) {
458 outb_p(data->word & 0xff, SMBHSTDAT0);
459 outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
461 xact = I801_WORD_DATA;
462 break;
463 case I2C_SMBUS_BLOCK_DATA:
464 case I2C_SMBUS_I2C_BLOCK_DATA:
465 #ifdef HAVE_PEC
466 case I2C_SMBUS_BLOCK_DATA_PEC:
467 if(hwpec && size == I2C_SMBUS_BLOCK_DATA)
468 size = I2C_SMBUS_BLOCK_DATA_PEC;
469 #endif
470 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
471 SMBHSTADD);
472 outb_p(command, SMBHSTCMD);
473 block = 1;
474 break;
475 case I2C_SMBUS_PROC_CALL:
476 default:
477 dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
478 return -1;
481 #ifdef HAVE_PEC
482 if(isich4 && hwpec) {
483 if(size != I2C_SMBUS_QUICK &&
484 size != I2C_SMBUS_I2C_BLOCK_DATA)
485 outb_p(1, SMBAUXCTL); /* enable HW PEC */
487 #endif
488 if(block)
489 ret = i801_block_transaction(data, read_write, size);
490 else {
491 outb_p(xact | ENABLE_INT9, SMBHSTCNT);
492 ret = i801_transaction();
495 #ifdef HAVE_PEC
496 if(isich4 && hwpec) {
497 if(size != I2C_SMBUS_QUICK &&
498 size != I2C_SMBUS_I2C_BLOCK_DATA)
499 outb_p(0, SMBAUXCTL);
501 #endif
503 if(block)
504 return ret;
505 if(ret)
506 return -1;
507 if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
508 return 0;
510 switch (xact & 0x7f) {
511 case I801_BYTE: /* Result put in SMBHSTDAT0 */
512 case I801_BYTE_DATA:
513 data->byte = inb_p(SMBHSTDAT0);
514 break;
515 case I801_WORD_DATA:
516 data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
517 break;
519 return 0;
523 static u32 i801_func(struct i2c_adapter *adapter)
525 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
526 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
527 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
528 #ifdef HAVE_PEC
529 | (isich4 ? I2C_FUNC_SMBUS_BLOCK_DATA_PEC |
530 I2C_FUNC_SMBUS_HWPEC_CALC
531 : 0)
532 #endif
536 static struct i2c_algorithm smbus_algorithm = {
537 .name = "Non-I2C SMBus adapter",
538 .id = I2C_ALGO_SMBUS,
539 .smbus_xfer = i801_access,
540 .functionality = i801_func,
543 static struct i2c_adapter i801_adapter = {
544 .owner = THIS_MODULE,
545 .class = I2C_CLASS_HWMON,
546 .algo = &smbus_algorithm,
547 .name = "unset",
550 static struct pci_device_id i801_ids[] = {
552 .vendor = PCI_VENDOR_ID_INTEL,
553 .device = PCI_DEVICE_ID_INTEL_82801AA_3,
554 .subvendor = PCI_ANY_ID,
555 .subdevice = PCI_ANY_ID,
558 .vendor = PCI_VENDOR_ID_INTEL,
559 .device = PCI_DEVICE_ID_INTEL_82801AB_3,
560 .subvendor = PCI_ANY_ID,
561 .subdevice = PCI_ANY_ID,
564 .vendor = PCI_VENDOR_ID_INTEL,
565 .device = PCI_DEVICE_ID_INTEL_82801BA_2,
566 .subvendor = PCI_ANY_ID,
567 .subdevice = PCI_ANY_ID,
570 .vendor = PCI_VENDOR_ID_INTEL,
571 .device = PCI_DEVICE_ID_INTEL_82801CA_3,
572 .subvendor = PCI_ANY_ID,
573 .subdevice = PCI_ANY_ID,
576 .vendor = PCI_VENDOR_ID_INTEL,
577 .device = PCI_DEVICE_ID_INTEL_82801DB_3,
578 .subvendor = PCI_ANY_ID,
579 .subdevice = PCI_ANY_ID,
582 .vendor = PCI_VENDOR_ID_INTEL,
583 .device = PCI_DEVICE_ID_INTEL_82801EB_3,
584 .subvendor = PCI_ANY_ID,
585 .subdevice = PCI_ANY_ID,
588 .vendor = PCI_VENDOR_ID_INTEL,
589 .device = PCI_DEVICE_ID_INTEL_ESB_4,
590 .subvendor = PCI_ANY_ID,
591 .subdevice = PCI_ANY_ID,
594 .vendor = PCI_VENDOR_ID_INTEL,
595 .device = PCI_DEVICE_ID_INTEL_ICH6_16,
596 .subvendor = PCI_ANY_ID,
597 .subdevice = PCI_ANY_ID,
599 { 0, }
602 static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
605 if (i801_setup(dev)) {
606 dev_warn(&dev->dev,
607 "I801 not detected, module not inserted.\n");
608 return -ENODEV;
611 /* set up the driverfs linkage to our parent device */
612 i801_adapter.dev.parent = &dev->dev;
614 snprintf(i801_adapter.name, I2C_NAME_SIZE,
615 "SMBus I801 adapter at %04x", i801_smba);
616 return i2c_add_adapter(&i801_adapter);
619 static void __devexit i801_remove(struct pci_dev *dev)
621 i2c_del_adapter(&i801_adapter);
622 release_region(i801_smba, (isich4 ? 16 : 8));
625 static struct pci_driver i801_driver = {
626 .name = "i801_smbus",
627 .id_table = i801_ids,
628 .probe = i801_probe,
629 .remove = __devexit_p(i801_remove),
632 static int __init i2c_i801_init(void)
634 return pci_module_init(&i801_driver);
637 static void __exit i2c_i801_exit(void)
639 pci_unregister_driver(&i801_driver);
642 MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, "
643 "Philip Edelbrock <phil@netroedge.com>, "
644 "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
645 MODULE_DESCRIPTION("I801 SMBus driver");
646 MODULE_LICENSE("GPL");
648 module_init(i2c_i801_init);
649 module_exit(i2c_i801_exit);