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