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

Revision 856, 18.7 KB (checked in by mds, 13 years ago)

(mds) smbus block write fixes, i2c block write support from Rickard Westman.

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