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