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

Revision 1698, 18.9 KB (checked in by kmalkki, 10 years ago)

(Kyösti) some cleanups for 2.4+

Module refcounting using .owner, removing of inc/dec_use.
These require (yet unreleased) i2c 2.8.0+.

Named initializers everywhere. Unified namespace.

Cleanup for 2.5, remove EXPORT_NO_SYMBOLS, declare everything
static. Apply initcalls.

PCI device registration changes for busses started, replicating
from i2c-amd*. While everything does compile, nothing really
works. Well, maybe i2c-amd* ported back from 2.5 tree.

After updating your work directory, run

> cvs diff -u -r LAST-PRE-2-8-I2C > lm-2.8-patches-1

BEWARE: I have not even insmoded any of these yet.

To compile, you need i2c from cvs too.
For 2.4 kernel :

> cvs co -r lk2-4 i2c

For 2.5 kernel :

> cvs co i2c

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