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

Revision 516, 20.8 KB (checked in by frodo, 14 years ago)

(Frodo) Massive commit of all things related to mkpatch. Let's just say

it works great now.

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