root/lm-sensors/trunk/kernel/busses/i2c-ali15x3.c @ 247

Revision 247, 19.6 KB (checked in by frodo, 14 years ago)

Two insignificant patches to remove 2.0.x kernel compile warnings.

It compiles now cleanly against kernel 2.0.36; I checked, double-checked and
cross-checked.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    ali15x3.c - Part of lm_sensors, Linux kernel modules for hardware
3              monitoring
4    Copyright (c) 1999  Frodo Looijaard <frodol@dds.nl> and
5    Philip Edelbrock <phil@netroedge.com> and
6    Mark D. Studebaker <mds@eng.paradyne.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 is the driver for the SMB Host controller on
25    Acer Labs Inc. (ALI) M1541 and M1543C South Bridges.
26
27    The M1543C is a South bridge for desktop systems.
28    The M1541 is a South bridge for portable systems.
29    They are part of the following ALI chipsets:
30       "Aladdin Pro 2": Includes the M1621 Slot 1 North bridge
31       with AGP and 100MHz CPU Front Side bus
32       "Aladdin V": Includes the M1541 Socket 7 North bridge
33       with AGP and 100MHz CPU Front Side bus
34       "Aladdin IV": Includes the M1541 Socket 7 North bridge
35       with host bus up to 83.3 MHz.
36    For an overview of these chips see http://www.acerlabs.com
37
38    The M1533/M1543C devices appear as FOUR separate devices
39    on the PCI bus. An output of lspci will show something similar
40    to the following:
41
42        00:02.0 USB Controller: Acer Laboratories Inc. M5237
43        00:03.0 Bridge: Acer Laboratories Inc. M7101
44        00:07.0 ISA bridge: Acer Laboratories Inc. M1533
45        00:0f.0 IDE interface: Acer Laboratories Inc. M5229
46
47    The SMB controller is part of the 7101 device, which is an
48    ACPI-compliant Power Management Unit (PMU).
49
50    The whole 7101 device has to be enabled for the SMB to work.
51    You can't just enable the SMB alone.
52    The SMB and the ACPI have separate I/O spaces.
53    So we have to make sure that both the SMB and the ACPI
54    are mapped and enabled.
55
56    This driver controls the SMB Host only.
57    The SMB Slave controller on the M15X3 is not enabled.
58
59    This driver requests the I/O space both for the SMB and the ACPI
60    registers, just to be safe. It doesn't actually use the ACPI region.
61    It will therefore conflict with separate software
62    that accesses the ACPI registers?
63    To fix this, undefine MAP_ACPI.
64
65    This driver does not use interrupts.
66*/
67
68/* Note: we assume there can only be one ALI15X3, with one SMBus interface */
69
70#include <linux/module.h>
71#include <linux/pci.h>
72#include <asm/io.h>
73#include <linux/kernel.h>
74#include <linux/stddef.h>
75#include <linux/sched.h>
76#include <linux/ioport.h>
77#include "smbus.h"
78#include "version.h"
79#include "compat.h"
80
81#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,54))
82#include <linux/bios32.h>
83#endif
84
85/* undefine this if separate ACPI software is accessing the
86   registers at the offset defined at 0x10.
87*/
88#define MAP_ACPI 1
89#undef FORCE_ALI15X3_ENABLE
90#undef DEBUG
91
92/* ALI15X3 SMBus address offsets */
93#define SMBHSTSTS (0 + ali15x3_smba)
94#define SMBHSTCNT (1 + ali15x3_smba)
95#define SMBHSTSTART (2 + ali15x3_smba)
96#define SMBHSTCMD (7 + ali15x3_smba)
97#define SMBHSTADD (3 + ali15x3_smba)
98#define SMBHSTDAT0 (4 + ali15x3_smba)
99#define SMBHSTDAT1 (5 + ali15x3_smba)
100#define SMBBLKDAT (6 + ali15x3_smba)
101
102/* PCI Address Constants */
103#define SMBCOM    0x004
104#define ACPIBA     0x010
105#define SMBBA     0x014
106#define SMBATPC   0x05B         /* used to unlock xxxBA registers */
107#define SMBHSTCFG 0x0E0
108#define SMBSLVC   0x0E1
109#define SMBCLK    0x0E2
110#define SMBREV    0x008
111
112/* Other settings */
113#define MAX_TIMEOUT 500         /* times 1/100 sec */
114#define ALI15X3_ACPI_IOSIZE 64
115#define ALI15X3_SMB_IOSIZE 32
116
117/* this is what the Award 1004 BIOS sets them to on a ASUS P5A MB.
118   We don't use these here. If the bases aren't set to some value we
119   tell user to upgrade BIOS and we fail.
120*/
121#define ALI15X3_ACPI_DEFAULTBASE 0xEC00
122#define ALI15X3_SMB_DEFAULTBASE 0xE800
123
124/* ALI15X3 address lock bits */
125#define ALI15X3_LOCK    0x06
126
127/* ALI15X3 command constants */
128#define ALI15X3_ABORT      0x02
129#define ALI15X3_T_OUT      0x04
130#define ALI15X3_QUICK      0x00
131#define ALI15X3_BYTE       0x10
132#define ALI15X3_BYTE_DATA  0x20
133#define ALI15X3_WORD_DATA  0x30
134#define ALI15X3_BLOCK_DATA 0x40
135#define ALI15X3_BLOCK_CLR  0x80
136
137/* ALI15X3 status register bits */
138#define ALI15X3_STS_IDLE        0x04         
139#define ALI15X3_STS_BUSY        0x08         
140#define ALI15X3_STS_DONE        0x10         
141#define ALI15X3_STS_DEV         0x20    /* device error */
142#define ALI15X3_STS_COLL        0x40    /* collision or no response */
143#define ALI15X3_STS_TERM        0x80    /* terminated by abort */
144#define ALI15X3_STS_ERR         0xE0    /* all the bad error bits */
145
146
147static int ali15x3_init(void);
148static int ali15x3_cleanup(void);
149static int ali15x3_setup(void);
150static s32 ali15x3_access(u8 addr, char read_write,
151                        u8 command, int size, union smbus_data * data);
152static void ali15x3_do_pause( unsigned int amount );
153static int ali15x3_transaction(void);
154
155#ifdef MODULE
156extern int init_module(void);
157extern int cleanup_module(void);
158#endif /* MODULE */
159
160static struct smbus_adapter ali15x3_adapter;
161static int ali15x3_initialized;
162#ifdef MAP_ACPI
163static unsigned short ali15x3_acpia = 0;
164#endif
165static unsigned short ali15x3_smba = 0;
166
167
168/* Detect whether a ALI15X3 can be found, and initialize it, where necessary.
169   Note the differences between kernels with the old PCI BIOS interface and
170   newer kernels with the real PCI interface. In compat.h some things are
171   defined to make the transition easier. */
172int ali15x3_setup(void)
173{
174  int error_return=0;
175  unsigned char temp;
176
177#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,54))
178  struct pci_dev *ALI15X3_dev;
179#else
180  unsigned char ALI15X3_bus, ALI15X3_devfn = 0;
181  int res;
182#endif
183
184  /* First check whether we can access PCI at all */
185  if (pci_present() == 0) {
186    printk("ali15x3.o: Error: No PCI-bus found!\n");
187    error_return=-ENODEV;
188    goto END;
189  }
190
191  /* Look for the ALI15X3, M7101 device */
192#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,54))
193  ALI15X3_dev = NULL;
194  ALI15X3_dev = pci_find_device(PCI_VENDOR_ID_AL, 
195                                PCI_DEVICE_ID_AL_M7101, ALI15X3_dev);
196  if(ALI15X3_dev == NULL) {
197#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,54) */
198    res = pcibios_find_device(PCI_VENDOR_ID_AL,
199                                    PCI_DEVICE_ID_AL_M7101,
200                                    0,&ALI15X3_bus, &ALI15X3_devfn);
201     
202  if (res) {
203#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,54) */
204    printk("ali15x3.o: Error: Can't detect ali15x3!\n");
205    error_return=-ENODEV;
206    goto END;
207  } 
208
209/* Check the following things:
210        - ACPI and SMB I/O addresses are initialized
211        - Device is enabled
212        - We can use the addresses
213*/
214
215/* Unlock the register.
216   The data sheet says that the address registers are read-only
217   if the lock bits are 1, but in fact the address registers
218   are zero unless you clear the lock bits.
219*/
220  pci_read_config_byte_united(ALI15X3_dev, ALI15X3_bus ,ALI15X3_devfn,
221                              SMBATPC, &temp);
222  if(temp & ALI15X3_LOCK)
223  {   
224    temp &= ~ALI15X3_LOCK;
225    pci_write_config_byte_united(ALI15X3_dev, ALI15X3_bus ,ALI15X3_devfn,
226                                 SMBATPC, temp);
227  }
228
229/* Determine the address of the ACPI and SMBus areas */
230#ifdef MAP_ACPI
231  pci_read_config_word_united(ALI15X3_dev, ALI15X3_bus ,ALI15X3_devfn,
232                              ACPIBA,&ali15x3_acpia);
233  ali15x3_acpia &= (0xffff & ~ (ALI15X3_ACPI_IOSIZE - 1));
234  if(ali15x3_acpia == 0) {
235    printk("ali15x3.o: ALI15X3_acpi region uninitialized - upgrade BIOS?\n");
236    error_return=-ENODEV;
237  }
238#endif
239
240  pci_read_config_word_united(ALI15X3_dev, ALI15X3_bus ,ALI15X3_devfn,
241                              SMBBA,&ali15x3_smba);
242  ali15x3_smba &= (0xffff & ~ (ALI15X3_SMB_IOSIZE - 1));
243  if(ali15x3_smba == 0) {
244    printk("ali15x3.o: ALI15X3_smb region uninitialized - upgrade BIOS?\n");
245    error_return=-ENODEV;
246  }
247
248  if(error_return == -ENODEV)
249    goto END;
250
251#ifdef MAP_ACPI
252  if (check_region(ali15x3_acpia, ALI15X3_ACPI_IOSIZE)) {
253    printk("ali15x3.o: ALI15X3_acpi region 0x%x already in use!\n", ali15x3_acpia);
254    printk("ali15x3.o: If conflicting ACPI software is installed, undefine MAP_ACPI and recompile!\n");
255    error_return=-ENODEV;
256  }
257#endif
258
259  if (check_region(ali15x3_smba, ALI15X3_SMB_IOSIZE)) {
260    printk("ali15x3.o: ALI15X3_smb region 0x%x already in use!\n", ali15x3_smba);
261    error_return=-ENODEV;
262  }
263
264  if(error_return == -ENODEV)
265    goto END;
266
267/* check if whole device is enabled */
268    pci_read_config_byte_united(ALI15X3_dev, ALI15X3_bus ,ALI15X3_devfn,
269                                SMBCOM, &temp);
270  if ((temp & 1) == 0) {
271    printk("SMBUS: Error: ACPI/SMB device not enabled - upgrade BIOS?\n");     
272    error_return=-ENODEV;
273    goto END;
274  }
275
276/* Is SMB Host controller enabled? */
277  pci_read_config_byte_united(ALI15X3_dev, ALI15X3_bus, ALI15X3_devfn,
278                              SMBHSTCFG, &temp);
279#ifdef FORCE_ALI15X3_ENABLE
280/* This should never need to be done.
281   NOTE: This assumes I/O space and other allocations WERE
282   done by the Bios!  Don't complain if your hardware does weird
283   things after enabling this. :') Check for Bios updates before
284   resorting to this.  */
285  if ((temp & 1) == 0) {
286    pci_write_config_byte_united(ALI15X3_dev, ALI15X3_bus, ALI15X3_devfn,
287                                     SMBHSTCFG, temp | 1);
288    printk("ali15x3.0: WARNING: ALI15X3 SMBus interface has been FORCEFULLY "
289           "ENABLED!!\n");
290  }
291#else /* FORCE_ALI15X3_ENABLE */
292  if ((temp & 1) == 0) {
293    printk("SMBUS: Error: Host SMBus controller not enabled - upgrade BIOS?\n");     
294    error_return=-ENODEV;
295    goto END;
296  }
297#endif /* FORCE_ALI15X3_ENABLE */
298
299/* set SMB clock to 74KHz as recommended in data sheet */
300  pci_write_config_byte_united(ALI15X3_dev, ALI15X3_bus ,ALI15X3_devfn,
301                               SMBCLK, 0x20);
302
303  /* Everything is happy, let's grab the memory and set things up. */
304#ifdef MAP_ACPI
305  request_region(ali15x3_acpia, ALI15X3_ACPI_IOSIZE, "ali15x3-acpi");       
306#endif
307  request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, "ali15x3-smb");       
308
309#ifdef DEBUG
310/*
311  The interrupt routing for SMB is set up in register 0x77 in the
312  1533 ISA Bridge device, NOT in the 7101 device.
313  Don't bother with finding the 1533 device and reading the register.
314  if ((....... & 0x0F) == 1)
315     printk("ali15x3.o: ALI15X3 using Interrupt 9 for SMBus.\n");
316*/
317  pci_read_config_byte_united(ALI15X3_dev, ALI15X3_bus, ALI15X3_devfn, SMBREV, 
318                              &temp);
319  printk("ali15x3.o: SMBREV = 0x%X\n",temp);
320  printk("ali15x3.o: ALI15X3_smba = 0x%X\n",ali15x3_smba);
321#endif /* DEBUG */
322
323END:
324  return error_return;
325}
326
327
328/* Internally used pause function */
329void ali15x3_do_pause( unsigned int amount )
330{
331      current->state = TASK_INTERRUPTIBLE;
332      schedule_timeout(amount);
333}
334
335/* Another internally used function */
336int ali15x3_transaction(void) 
337{
338  int temp;
339  int result=0;
340  int timeout=0;
341
342#ifdef DEBUG
343  printk("ali15x3.o: Transaction (pre): STS=%02x, CNT=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, "
344         "DAT1=%02x\n",
345         inb_p(SMBHSTSTS), inb_p(SMBHSTCNT),inb_p(SMBHSTCMD),inb_p(SMBHSTADD),inb_p(SMBHSTDAT0),
346         inb_p(SMBHSTDAT1));
347#endif
348
349  /* get status */
350  temp = inb_p(SMBHSTSTS);
351
352  /* Make sure the SMBus host is ready to start transmitting */
353  /* Check the busy bit first */
354  if (temp & ALI15X3_STS_BUSY) {
355/*
356   If the host controller is still busy, it may have timed out in the previous transaction,
357   resulting in a "SMBus Timeout" printk.
358   I've tried the following to reset a stuck busy bit.
359        1. Reset the controller with an ABORT command.
360           (this doesn't seem to clear the controller if an external device is hung)
361        2. Reset the controller and the other SMBus devices with a T_OUT command.
362           (this clears the host busy bit if an external device is hung,
363           but it comes back upon a new access to a device)
364        3. Disable and reenable the controller in SMBHSTCFG
365   Worst case, nothing seems to work except power reset.
366*/
367/* Abort - reset the host controller */
368/*
369#ifdef DEBUG
370    printk("ali15x3.o: Resetting host controller to clear busy condition\n",temp);
371#endif
372    outb_p(ALI15X3_ABORT, SMBHSTCNT);
373    temp = inb_p(SMBHSTSTS);
374    if (temp & ALI15X3_STS_BUSY) {
375*/
376 
377/*
378   Try resetting entire SMB bus, including other devices -
379   This may not work either - it clears the BUSY bit but
380   then the BUSY bit may come back on when you try and use the chip again.
381   If that's the case you are stuck.
382*/
383       printk("ali15x3.o: Resetting entire SMB Bus to clear busy condition (%02x)\n",temp);
384       outb_p(ALI15X3_T_OUT, SMBHSTCNT);
385       temp = inb_p(SMBHSTSTS);
386     }
387/*
388  }
389*/
390
391  /* now check the error bits and the busy bit */
392  if (temp & (ALI15X3_STS_ERR | ALI15X3_STS_BUSY)) {
393    /* do a clear-on-write */
394    outb_p(0xFF, SMBHSTSTS);
395    if ((temp = inb_p(SMBHSTSTS)) & (ALI15X3_STS_ERR | ALI15X3_STS_BUSY)) {
396      /* this is probably going to be correctable only by a power reset
397         as one of the bits now appears to be stuck */
398      /* This may be a bus or device with electrical problems. */
399      printk("ali15x3.o: SMBus reset failed! (0x%02x) - controller or device on bus is probably hung\n",temp);
400      return -1;
401    }
402  } else {
403    /* check and clear done bit */
404    if (temp & ALI15X3_STS_DONE) {
405      outb_p(temp, SMBHSTSTS);
406    }
407  }
408
409  /* start the transaction by writing anything to the start register */
410  outb_p(0xFF, SMBHSTSTART); 
411
412  /* We will always wait for a fraction of a second! */
413  timeout = 0;
414  do {
415    ali15x3_do_pause(1);
416    temp=inb_p(SMBHSTSTS);
417  } while ((!(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE))) && (timeout++ < MAX_TIMEOUT));
418
419  /* If the SMBus is still busy, we give up */
420  if (timeout >= MAX_TIMEOUT) {
421    result = -1;
422    printk("ali15x3.o: SMBus Timeout!\n"); 
423  }
424
425  if (temp & ALI15X3_STS_TERM) {
426    result = -1;
427#ifdef DEBUG
428    printk("ali15x3.o: Error: Failed bus transaction\n");
429#endif
430  }
431
432/*
433  Unfortunately the ALI SMB controller maps "no response" and "bus collision"
434  into a single bit. No reponse is the usual case so don't
435  do a printk.
436  This means that bus collisions go unreported.
437*/
438  if (temp & ALI15X3_STS_COLL) {
439    result = -1;
440#ifdef DEBUG
441    printk("ali15x3.o: Error: no response or bus collision ADD=%02x\n", inb_p(SMBHSTADD));
442#endif
443  }
444
445/* haven't ever seen this */
446  if (temp & ALI15X3_STS_DEV) {
447    result = -1;
448    printk("ali15x3.o: Error: device error\n");
449  }
450
451#ifdef DEBUG
452  printk("ali15x3.o: Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, ADD=%02x, "
453         "DAT0=%02x, DAT1=%02x\n",
454         inb_p(SMBHSTSTS), inb_p(SMBHSTCNT),inb_p(SMBHSTCMD),inb_p(SMBHSTADD),inb_p(SMBHSTDAT0),
455         inb_p(SMBHSTDAT1));
456#endif
457  return result;
458}
459
460/* Return -1 on error. See smbus.h for more information */
461s32 ali15x3_access(u8 addr, char read_write,
462                 u8 command, int size, union smbus_data * data)
463{
464  int i,len;
465  int temp;
466  int timeout;
467
468/* clear all the bits (clear-on-write) */
469  outb_p(0xFF, SMBHSTSTS); 
470/* make sure SMBus is idle */
471  temp = inb_p(SMBHSTSTS);
472  for(timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE); timeout++)
473  {
474    ali15x3_do_pause(1);
475    temp=inb_p(SMBHSTSTS);
476  }
477  if (timeout >= MAX_TIMEOUT) {
478    printk("ali15x3.o: Idle wait Timeout! STS=0x%02x\n", temp); 
479  }
480
481  switch(size) {
482    case SMBUS_PROC_CALL:
483      printk("ali15x3.o: SMBUS_PROC_CALL not supported!\n");
484      return -1;
485    case SMBUS_QUICK:
486      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD);
487      size = ALI15X3_QUICK;
488      break;
489    case SMBUS_BYTE:
490      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD);
491      if (read_write == SMBUS_WRITE)
492        outb_p(command, SMBHSTCMD);
493      size = ALI15X3_BYTE;
494      break;
495    case SMBUS_BYTE_DATA:
496      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD);
497      outb_p(command, SMBHSTCMD);
498      if (read_write == SMBUS_WRITE)
499        outb_p(data->byte,SMBHSTDAT0);
500      size = ALI15X3_BYTE_DATA;
501      break;
502    case SMBUS_WORD_DATA:
503      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD);
504      outb_p(command, SMBHSTCMD);
505      if (read_write == SMBUS_WRITE) {
506        outb_p(data->word & 0xff,SMBHSTDAT0);
507        outb_p((data->word & 0xff00) >> 8,SMBHSTDAT1);
508      }
509      size = ALI15X3_WORD_DATA;
510      break;
511    case SMBUS_BLOCK_DATA:
512      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD);
513      outb_p(command, SMBHSTCMD);
514      if (read_write == SMBUS_WRITE) {
515        len = data->block[0];
516        if (len < 0) 
517          len = 0;
518        if (len > 32)
519          len = 32;
520        outb_p(len,SMBHSTDAT0);
521        outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT); /* Reset SMBBLKDAT */
522        for (i = 1; i <= len; i ++)
523          outb_p(data->block[i],SMBBLKDAT);
524      }
525      size = ALI15X3_BLOCK_DATA;
526      break;
527  }
528
529  outb_p(size, SMBHSTCNT);      /* output command */
530
531  if (ali15x3_transaction()) /* Error in transaction */ 
532    return -1; 
533 
534  if ((read_write == SMBUS_WRITE) || (size == ALI15X3_QUICK))
535    return 0;
536 
537
538  switch(size) {
539    case ALI15X3_BYTE: /* Result put in SMBHSTDAT0 */
540      data->byte = inb_p(SMBHSTDAT0);
541      break;
542    case ALI15X3_BYTE_DATA:
543      data->byte = inb_p(SMBHSTDAT0);
544      break;
545    case ALI15X3_WORD_DATA:
546      data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
547      break;
548    case ALI15X3_BLOCK_DATA:
549      data->block[0] = inb_p(SMBHSTDAT0);
550      outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT); /* Reset SMBBLKDAT */
551      for (i = 1; i <= data->block[0]; i++)
552        data->block[i] = inb_p(SMBBLKDAT);
553      break;
554  }
555  return 0;
556}
557
558
559int ali15x3_init(void)
560{
561  int res;
562  printk("ali15x3.o version %s (%s)\n",LM_VERSION,LM_DATE);
563#ifdef DEBUG
564/* PE- It might be good to make this a permanent part of the code! */
565  if (ali15x3_initialized) {
566    printk("ali15x3.o: Oops, ali15x3_init called a second time!\n");
567    return -EBUSY;
568  }
569#endif
570  ali15x3_initialized = 0;
571  if ((res = ali15x3_setup())) {
572    printk("ali15x3.o: ALI15X3 not detected, module not inserted.\n");
573    ali15x3_cleanup();
574    return res;
575  }
576  ali15x3_initialized ++;
577#ifdef MAP_ACPI
578  sprintf(ali15x3_adapter.name,"ACPI ALI15X3 at %04x",ali15x3_acpia);
579#endif
580  sprintf(ali15x3_adapter.name,"SMBus ALI15X3 adapter at %04x",ali15x3_smba);
581  ali15x3_adapter.id = ALGO_SMBUS | SMBUS_PIIX4;
582  ali15x3_adapter.algo = &smbus_algorithm;
583  ali15x3_adapter.smbus_access = &ali15x3_access;
584  if ((res = smbus_add_adapter(&ali15x3_adapter))) {
585    printk("ali15x3.o: Adapter registration failed, module not inserted.\n");
586    ali15x3_cleanup();
587    return res;
588  }
589  ali15x3_initialized++;
590  printk("ali15x3.o: ALI15X3 SMBus Controller detected and initialized\n");
591  return 0;
592}
593
594int ali15x3_cleanup(void)
595{
596  int res;
597  if (ali15x3_initialized >= 2)
598  {
599    if ((res = smbus_del_adapter(&ali15x3_adapter))) {
600      printk("ali15x3.o: smbus_del_adapter failed, module not removed\n");
601      return res;
602    } else
603      ali15x3_initialized--;
604  }
605  if (ali15x3_initialized >= 1) {
606#ifdef MAP_ACPI
607    release_region(ali15x3_acpia, ALI15X3_ACPI_IOSIZE);
608#endif
609    release_region(ali15x3_smba, ALI15X3_SMB_IOSIZE);
610    ali15x3_initialized--;
611  }
612  return 0;
613}
614
615#ifdef MODULE
616
617MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker <mds@eng.paradyne.com>");
618MODULE_DESCRIPTION("ALI15X3 SMBus driver");
619
620int init_module(void)
621{
622  return ali15x3_init();
623}
624
625int cleanup_module(void)
626{
627  return ali15x3_cleanup();
628}
629
630#endif /* MODULE */
Note: See TracBrowser for help on using the browser.