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

Revision 1708, 18.7 KB (checked in by kmalkki, 10 years ago)

(Kyösti) Clean PCI IDs already defined for 2.4.9.

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