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

Revision 1142, 18.5 KB (checked in by mds, 12 years ago)

change ...82801BA_3 to ...82801BA_2 because that's what it was

named in kernel 2.4.6, which broke detection for that chip.

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