blob: dfca74933625e0c1c629778f0af1f9f8f00351b3 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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 82801EB 24D3 (HW PEC supported, 32 byte buffer not supported)
31 6300ESB 25A4
32 ICH6 266A
33 ICH7 27DA
Jason Gastonb0a70b52005-04-16 15:24:45 -070034 ESB2 269B
Jason Gaston8254fc42006-01-09 10:58:08 -080035 ICH8 283E
Linus Torvalds1da177e2005-04-16 15:20:36 -070036 This driver supports several versions of Intel's I/O Controller Hubs (ICH).
37 For SMBus support, they are similar to the PIIX4 and are part
38 of Intel's '810' and other chipsets.
39 See the doc/busses/i2c-i801 file for details.
40 I2C Block Read and Process Call are not supported.
41*/
42
43/* Note: we assume there can only be one I801, with one SMBus interface */
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <linux/module.h>
46#include <linux/pci.h>
47#include <linux/kernel.h>
48#include <linux/stddef.h>
49#include <linux/delay.h>
50#include <linux/sched.h>
51#include <linux/ioport.h>
52#include <linux/init.h>
53#include <linux/i2c.h>
54#include <asm/io.h>
55
Linus Torvalds1da177e2005-04-16 15:20:36 -070056/* I801 SMBus address offsets */
57#define SMBHSTSTS (0 + i801_smba)
58#define SMBHSTCNT (2 + i801_smba)
59#define SMBHSTCMD (3 + i801_smba)
60#define SMBHSTADD (4 + i801_smba)
61#define SMBHSTDAT0 (5 + i801_smba)
62#define SMBHSTDAT1 (6 + i801_smba)
63#define SMBBLKDAT (7 + i801_smba)
64#define SMBPEC (8 + i801_smba) /* ICH4 only */
65#define SMBAUXSTS (12 + i801_smba) /* ICH4 only */
66#define SMBAUXCTL (13 + i801_smba) /* ICH4 only */
67
68/* PCI Address Constants */
69#define SMBBA 0x020
70#define SMBHSTCFG 0x040
71#define SMBREV 0x008
72
73/* Host configuration bits for SMBHSTCFG */
74#define SMBHSTCFG_HST_EN 1
75#define SMBHSTCFG_SMB_SMI_EN 2
76#define SMBHSTCFG_I2C_EN 4
77
78/* Other settings */
79#define MAX_TIMEOUT 100
80#define ENABLE_INT9 0 /* set to 0x01 to enable - untested */
81
82/* I801 command constants */
83#define I801_QUICK 0x00
84#define I801_BYTE 0x04
85#define I801_BYTE_DATA 0x08
86#define I801_WORD_DATA 0x0C
87#define I801_PROC_CALL 0x10 /* later chips only, unimplemented */
88#define I801_BLOCK_DATA 0x14
89#define I801_I2C_BLOCK_DATA 0x18 /* unimplemented */
90#define I801_BLOCK_LAST 0x34
91#define I801_I2C_BLOCK_LAST 0x38 /* unimplemented */
92#define I801_START 0x40
93#define I801_PEC_EN 0x80 /* ICH4 only */
94
95/* insmod parameters */
96
97/* If force_addr is set to anything different from 0, we forcibly enable
98 the I801 at the given address. VERY DANGEROUS! */
99static u16 force_addr;
100module_param(force_addr, ushort, 0);
101MODULE_PARM_DESC(force_addr,
102 "Forcibly enable the I801 at the given address. "
103 "EXTREMELY DANGEROUS!");
104
105static int i801_transaction(void);
Jean Delvare585b3162005-10-26 21:31:15 +0200106static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
107 int command, int hwpec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108
109static unsigned short i801_smba;
Jean Delvared6072f82005-09-25 16:37:04 +0200110static struct pci_driver i801_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111static struct pci_dev *I801_dev;
112static int isich4;
113
114static int i801_setup(struct pci_dev *dev)
115{
116 int error_return = 0;
117 unsigned char temp;
118
119 /* Note: we keep on searching until we have found 'function 3' */
120 if(PCI_FUNC(dev->devfn) != 3)
121 return -ENODEV;
122
123 I801_dev = dev;
124 if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
125 (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
126 (dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
127 isich4 = 1;
128 else
129 isich4 = 0;
130
131 /* Determine the address of the SMBus areas */
132 if (force_addr) {
133 i801_smba = force_addr & 0xfff0;
134 } else {
135 pci_read_config_word(I801_dev, SMBBA, &i801_smba);
136 i801_smba &= 0xfff0;
137 if(i801_smba == 0) {
Jean Delvare368609c2005-07-29 12:15:07 -0700138 dev_err(&dev->dev, "SMB base address uninitialized "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 "- upgrade BIOS or use force_addr=0xaddr\n");
140 return -ENODEV;
141 }
142 }
143
Jean Delvared6072f82005-09-25 16:37:04 +0200144 if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145 dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n",
146 i801_smba);
147 error_return = -EBUSY;
148 goto END;
149 }
150
151 pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
152 temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
153 pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
154
155 /* If force_addr is set, we program the new address here. Just to make
156 sure, we disable the device first. */
157 if (force_addr) {
158 pci_write_config_byte(I801_dev, SMBHSTCFG, temp & 0xfe);
159 pci_write_config_word(I801_dev, SMBBA, i801_smba);
160 pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 0x01);
161 dev_warn(&dev->dev, "WARNING: I801 SMBus interface set to "
162 "new address %04x!\n", i801_smba);
163 } else if ((temp & 1) == 0) {
164 pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1);
165 dev_warn(&dev->dev, "enabling SMBus device\n");
166 }
167
168 if (temp & 0x02)
169 dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n");
170 else
171 dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n");
172
173 pci_read_config_byte(I801_dev, SMBREV, &temp);
174 dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
175 dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba);
176
177END:
178 return error_return;
179}
180
181static int i801_transaction(void)
182{
183 int temp;
184 int result = 0;
185 int timeout = 0;
186
Jean Delvare368609c2005-07-29 12:15:07 -0700187 dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
189 inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
190 inb_p(SMBHSTDAT1));
191
192 /* Make sure the SMBus host is ready to start transmitting */
193 /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
194 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
Jean Delvare541e6a02005-06-23 22:18:08 +0200195 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting...\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 temp);
197 outb_p(temp, SMBHSTSTS);
198 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
199 dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp);
200 return -1;
201 } else {
202 dev_dbg(&I801_dev->dev, "Successfull!\n");
203 }
204 }
205
206 outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
207
208 /* We will always wait for a fraction of a second! */
209 do {
210 msleep(1);
211 temp = inb_p(SMBHSTSTS);
212 } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
213
214 /* If the SMBus is still busy, we give up */
215 if (timeout >= MAX_TIMEOUT) {
216 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
217 result = -1;
218 }
219
220 if (temp & 0x10) {
221 result = -1;
222 dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
223 }
224
225 if (temp & 0x08) {
226 result = -1;
227 dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
228 "until next hard reset. (sorry!)\n");
229 /* Clock stops and slave is stuck in mid-transmission */
230 }
231
232 if (temp & 0x04) {
233 result = -1;
234 dev_dbg(&I801_dev->dev, "Error: no response!\n");
235 }
236
237 if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00)
238 outb_p(inb(SMBHSTSTS), SMBHSTSTS);
239
240 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
Jean Delvare368609c2005-07-29 12:15:07 -0700241 dev_dbg(&I801_dev->dev, "Failed reset at end of transaction "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242 "(%02x)\n", temp);
243 }
244 dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, "
245 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
246 inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
247 inb_p(SMBHSTDAT1));
248 return result;
249}
250
251/* All-inclusive block transaction function */
252static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
Jean Delvare585b3162005-10-26 21:31:15 +0200253 int command, int hwpec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254{
255 int i, len;
256 int smbcmd;
257 int temp;
258 int result = 0;
259 int timeout;
260 unsigned char hostc, errmask;
261
262 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
263 if (read_write == I2C_SMBUS_WRITE) {
264 /* set I2C_EN bit in configuration register */
265 pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
266 pci_write_config_byte(I801_dev, SMBHSTCFG,
267 hostc | SMBHSTCFG_I2C_EN);
268 } else {
269 dev_err(&I801_dev->dev,
270 "I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
271 return -1;
272 }
273 }
274
275 if (read_write == I2C_SMBUS_WRITE) {
276 len = data->block[0];
277 if (len < 1)
278 len = 1;
279 if (len > 32)
280 len = 32;
281 outb_p(len, SMBHSTDAT0);
282 outb_p(data->block[1], SMBBLKDAT);
283 } else {
284 len = 32; /* max for reads */
285 }
286
287 if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
288 /* set 32 byte buffer */
289 }
290
291 for (i = 1; i <= len; i++) {
292 if (i == len && read_write == I2C_SMBUS_READ)
293 smbcmd = I801_BLOCK_LAST;
294 else
295 smbcmd = I801_BLOCK_DATA;
296 outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT);
297
298 dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, "
299 "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
300 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
301 inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
302
303 /* Make sure the SMBus host is ready to start transmitting */
304 temp = inb_p(SMBHSTSTS);
305 if (i == 1) {
306 /* Erronenous conditions before transaction:
307 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
308 errmask=0x9f;
309 } else {
310 /* Erronenous conditions during transaction:
311 * Failed, Bus_Err, Dev_Err, Intr */
312 errmask=0x1e;
313 }
314 if (temp & errmask) {
315 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
Jean Delvare541e6a02005-06-23 22:18:08 +0200316 "Resetting...\n", temp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 outb_p(temp, SMBHSTSTS);
318 if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
319 dev_err(&I801_dev->dev,
320 "Reset failed! (%02x)\n", temp);
321 result = -1;
322 goto END;
323 }
324 if (i != 1) {
325 /* if die in middle of block transaction, fail */
326 result = -1;
327 goto END;
328 }
329 }
330
331 if (i == 1)
332 outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
333
334 /* We will always wait for a fraction of a second! */
335 timeout = 0;
336 do {
337 temp = inb_p(SMBHSTSTS);
338 msleep(1);
339 }
340 while ((!(temp & 0x80))
341 && (timeout++ < MAX_TIMEOUT));
342
343 /* If the SMBus is still busy, we give up */
344 if (timeout >= MAX_TIMEOUT) {
345 result = -1;
346 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
347 }
348
349 if (temp & 0x10) {
350 result = -1;
351 dev_dbg(&I801_dev->dev,
352 "Error: Failed bus transaction\n");
353 } else if (temp & 0x08) {
354 result = -1;
355 dev_err(&I801_dev->dev, "Bus collision!\n");
356 } else if (temp & 0x04) {
357 result = -1;
358 dev_dbg(&I801_dev->dev, "Error: no response!\n");
359 }
360
361 if (i == 1 && read_write == I2C_SMBUS_READ) {
362 len = inb_p(SMBHSTDAT0);
363 if (len < 1)
364 len = 1;
365 if (len > 32)
366 len = 32;
367 data->block[0] = len;
368 }
369
370 /* Retrieve/store value in SMBBLKDAT */
371 if (read_write == I2C_SMBUS_READ)
372 data->block[i] = inb_p(SMBBLKDAT);
373 if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
374 outb_p(data->block[i+1], SMBBLKDAT);
375 if ((temp & 0x9e) != 0x00)
376 outb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */
377
378 if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) {
379 dev_dbg(&I801_dev->dev,
380 "Bad status (%02x) at end of transaction\n",
381 temp);
382 }
383 dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, "
384 "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
385 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
386 inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
387
388 if (result < 0)
389 goto END;
390 }
391
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200392 if (hwpec) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 /* wait for INTR bit as advised by Intel */
394 timeout = 0;
395 do {
396 temp = inb_p(SMBHSTSTS);
397 msleep(1);
398 } while ((!(temp & 0x02))
399 && (timeout++ < MAX_TIMEOUT));
400
401 if (timeout >= MAX_TIMEOUT) {
402 dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
403 }
404 outb_p(temp, SMBHSTSTS);
405 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 result = 0;
407END:
408 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
409 /* restore saved configuration register value */
410 pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
411 }
412 return result;
413}
414
415/* Return -1 on error. */
416static s32 i801_access(struct i2c_adapter * adap, u16 addr,
417 unsigned short flags, char read_write, u8 command,
418 int size, union i2c_smbus_data * data)
419{
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200420 int hwpec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 int block = 0;
422 int ret, xact = 0;
423
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200424 hwpec = isich4 && (flags & I2C_CLIENT_PEC)
425 && size != I2C_SMBUS_QUICK
426 && size != I2C_SMBUS_I2C_BLOCK_DATA;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
428 switch (size) {
429 case I2C_SMBUS_QUICK:
430 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
431 SMBHSTADD);
432 xact = I801_QUICK;
433 break;
434 case I2C_SMBUS_BYTE:
435 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
436 SMBHSTADD);
437 if (read_write == I2C_SMBUS_WRITE)
438 outb_p(command, SMBHSTCMD);
439 xact = I801_BYTE;
440 break;
441 case I2C_SMBUS_BYTE_DATA:
442 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
443 SMBHSTADD);
444 outb_p(command, SMBHSTCMD);
445 if (read_write == I2C_SMBUS_WRITE)
446 outb_p(data->byte, SMBHSTDAT0);
447 xact = I801_BYTE_DATA;
448 break;
449 case I2C_SMBUS_WORD_DATA:
450 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
451 SMBHSTADD);
452 outb_p(command, SMBHSTCMD);
453 if (read_write == I2C_SMBUS_WRITE) {
454 outb_p(data->word & 0xff, SMBHSTDAT0);
455 outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
456 }
457 xact = I801_WORD_DATA;
458 break;
459 case I2C_SMBUS_BLOCK_DATA:
460 case I2C_SMBUS_I2C_BLOCK_DATA:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
462 SMBHSTADD);
463 outb_p(command, SMBHSTCMD);
464 block = 1;
465 break;
466 case I2C_SMBUS_PROC_CALL:
467 default:
468 dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
469 return -1;
470 }
471
Mark M. Hoffman2e3e13f2005-11-06 23:04:51 +0100472 outb_p(hwpec, SMBAUXCTL); /* enable/disable hardware PEC */
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200473
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 if(block)
Jean Delvare585b3162005-10-26 21:31:15 +0200475 ret = i801_block_transaction(data, read_write, size, hwpec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 else {
477 outb_p(xact | ENABLE_INT9, SMBHSTCNT);
478 ret = i801_transaction();
479 }
480
Jean Delvarec79cfba2006-04-20 02:43:18 -0700481 /* Some BIOSes don't like it when PEC is enabled at reboot or resume
482 time, so we forcibly disable it after every transaction. */
483 if (hwpec)
484 outb_p(0, SMBAUXCTL);
485
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486 if(block)
487 return ret;
488 if(ret)
489 return -1;
490 if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
491 return 0;
492
493 switch (xact & 0x7f) {
494 case I801_BYTE: /* Result put in SMBHSTDAT0 */
495 case I801_BYTE_DATA:
496 data->byte = inb_p(SMBHSTDAT0);
497 break;
498 case I801_WORD_DATA:
499 data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
500 break;
501 }
502 return 0;
503}
504
505
506static u32 i801_func(struct i2c_adapter *adapter)
507{
508 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
509 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
510 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
Jean Delvareb8095542005-10-26 21:25:04 +0200511 | (isich4 ? I2C_FUNC_SMBUS_HWPEC_CALC : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512}
513
514static struct i2c_algorithm smbus_algorithm = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 .smbus_xfer = i801_access,
516 .functionality = i801_func,
517};
518
519static struct i2c_adapter i801_adapter = {
520 .owner = THIS_MODULE,
521 .class = I2C_CLASS_HWMON,
522 .algo = &smbus_algorithm,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523};
524
525static struct pci_device_id i801_ids[] = {
526 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
527 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
528 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) },
529 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_3) },
530 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_3) },
531 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) },
532 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
533 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
534 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
Jason Gastonb0a70b52005-04-16 15:24:45 -0700535 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
Jason Gaston8254fc42006-01-09 10:58:08 -0800536 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 { 0, }
538};
539
540MODULE_DEVICE_TABLE (pci, i801_ids);
541
542static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
543{
544
545 if (i801_setup(dev)) {
546 dev_warn(&dev->dev,
547 "I801 not detected, module not inserted.\n");
548 return -ENODEV;
549 }
550
551 /* set up the driverfs linkage to our parent device */
552 i801_adapter.dev.parent = &dev->dev;
553
554 snprintf(i801_adapter.name, I2C_NAME_SIZE,
555 "SMBus I801 adapter at %04x", i801_smba);
556 return i2c_add_adapter(&i801_adapter);
557}
558
559static void __devexit i801_remove(struct pci_dev *dev)
560{
561 i2c_del_adapter(&i801_adapter);
562 release_region(i801_smba, (isich4 ? 16 : 8));
563}
564
565static struct pci_driver i801_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 .name = "i801_smbus",
567 .id_table = i801_ids,
568 .probe = i801_probe,
569 .remove = __devexit_p(i801_remove),
570};
571
572static int __init i2c_i801_init(void)
573{
574 return pci_register_driver(&i801_driver);
575}
576
577static void __exit i2c_i801_exit(void)
578{
579 pci_unregister_driver(&i801_driver);
580}
581
582MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, "
583 "Philip Edelbrock <phil@netroedge.com>, "
584 "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
585MODULE_DESCRIPTION("I801 SMBus driver");
586MODULE_LICENSE("GPL");
587
588module_init(i2c_i801_init);
589module_exit(i2c_i801_exit);