blob: 0d5374cce9ccc7bb71b138ea3445b48958d08532 [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
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
96static int i801_transaction(void);
Jean Delvare585b3162005-10-26 21:31:15 +020097static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
98 int command, int hwpec);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
100static unsigned short i801_smba;
Jean Delvared6072f82005-09-25 16:37:04 +0200101static struct pci_driver i801_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102static struct pci_dev *I801_dev;
103static int isich4;
104
105static int i801_setup(struct pci_dev *dev)
106{
107 int error_return = 0;
108 unsigned char temp;
109
110 /* Note: we keep on searching until we have found 'function 3' */
111 if(PCI_FUNC(dev->devfn) != 3)
112 return -ENODEV;
113
114 I801_dev = dev;
115 if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
116 (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
117 (dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
118 isich4 = 1;
119 else
120 isich4 = 0;
121
122 /* Determine the address of the SMBus areas */
Jean Delvared8db8f92006-06-12 21:50:11 +0200123 pci_read_config_word(I801_dev, SMBBA, &i801_smba);
124 i801_smba &= 0xfff0;
125 if (!i801_smba) {
126 dev_err(&dev->dev, "SMBus base address uninitialized, "
127 "upgrade BIOS\n");
128 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 }
130
Jean Delvared6072f82005-09-25 16:37:04 +0200131 if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n",
133 i801_smba);
134 error_return = -EBUSY;
135 goto END;
136 }
137
138 pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
139 temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
140 pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
141
Jean Delvared8db8f92006-06-12 21:50:11 +0200142 if (!(temp & 1)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143 pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1);
144 dev_warn(&dev->dev, "enabling SMBus device\n");
145 }
146
147 if (temp & 0x02)
148 dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n");
149 else
150 dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n");
151
152 pci_read_config_byte(I801_dev, SMBREV, &temp);
153 dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
154 dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba);
155
156END:
157 return error_return;
158}
159
160static int i801_transaction(void)
161{
162 int temp;
163 int result = 0;
164 int timeout = 0;
165
Jean Delvare368609c2005-07-29 12:15:07 -0700166 dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
168 inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
169 inb_p(SMBHSTDAT1));
170
171 /* Make sure the SMBus host is ready to start transmitting */
172 /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
173 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
Jean Delvare541e6a02005-06-23 22:18:08 +0200174 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting...\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 temp);
176 outb_p(temp, SMBHSTSTS);
177 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
178 dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp);
179 return -1;
180 } else {
181 dev_dbg(&I801_dev->dev, "Successfull!\n");
182 }
183 }
184
185 outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
186
187 /* We will always wait for a fraction of a second! */
188 do {
189 msleep(1);
190 temp = inb_p(SMBHSTSTS);
191 } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
192
193 /* If the SMBus is still busy, we give up */
194 if (timeout >= MAX_TIMEOUT) {
195 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
196 result = -1;
197 }
198
199 if (temp & 0x10) {
200 result = -1;
201 dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
202 }
203
204 if (temp & 0x08) {
205 result = -1;
206 dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
207 "until next hard reset. (sorry!)\n");
208 /* Clock stops and slave is stuck in mid-transmission */
209 }
210
211 if (temp & 0x04) {
212 result = -1;
213 dev_dbg(&I801_dev->dev, "Error: no response!\n");
214 }
215
216 if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00)
217 outb_p(inb(SMBHSTSTS), SMBHSTSTS);
218
219 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
Jean Delvare368609c2005-07-29 12:15:07 -0700220 dev_dbg(&I801_dev->dev, "Failed reset at end of transaction "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 "(%02x)\n", temp);
222 }
223 dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, "
224 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
225 inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
226 inb_p(SMBHSTDAT1));
227 return result;
228}
229
230/* All-inclusive block transaction function */
231static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
Jean Delvare585b3162005-10-26 21:31:15 +0200232 int command, int hwpec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233{
234 int i, len;
235 int smbcmd;
236 int temp;
237 int result = 0;
238 int timeout;
239 unsigned char hostc, errmask;
240
241 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
242 if (read_write == I2C_SMBUS_WRITE) {
243 /* set I2C_EN bit in configuration register */
244 pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
245 pci_write_config_byte(I801_dev, SMBHSTCFG,
246 hostc | SMBHSTCFG_I2C_EN);
247 } else {
248 dev_err(&I801_dev->dev,
249 "I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
250 return -1;
251 }
252 }
253
254 if (read_write == I2C_SMBUS_WRITE) {
255 len = data->block[0];
256 if (len < 1)
257 len = 1;
258 if (len > 32)
259 len = 32;
260 outb_p(len, SMBHSTDAT0);
261 outb_p(data->block[1], SMBBLKDAT);
262 } else {
263 len = 32; /* max for reads */
264 }
265
266 if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
267 /* set 32 byte buffer */
268 }
269
270 for (i = 1; i <= len; i++) {
271 if (i == len && read_write == I2C_SMBUS_READ)
272 smbcmd = I801_BLOCK_LAST;
273 else
274 smbcmd = I801_BLOCK_DATA;
275 outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT);
276
277 dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, "
278 "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
279 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
280 inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
281
282 /* Make sure the SMBus host is ready to start transmitting */
283 temp = inb_p(SMBHSTSTS);
284 if (i == 1) {
285 /* Erronenous conditions before transaction:
286 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
287 errmask=0x9f;
288 } else {
289 /* Erronenous conditions during transaction:
290 * Failed, Bus_Err, Dev_Err, Intr */
291 errmask=0x1e;
292 }
293 if (temp & errmask) {
294 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
Jean Delvare541e6a02005-06-23 22:18:08 +0200295 "Resetting...\n", temp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 outb_p(temp, SMBHSTSTS);
297 if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
298 dev_err(&I801_dev->dev,
299 "Reset failed! (%02x)\n", temp);
300 result = -1;
301 goto END;
302 }
303 if (i != 1) {
304 /* if die in middle of block transaction, fail */
305 result = -1;
306 goto END;
307 }
308 }
309
310 if (i == 1)
311 outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
312
313 /* We will always wait for a fraction of a second! */
314 timeout = 0;
315 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 msleep(1);
Jean Delvare397e2f62006-06-12 21:49:36 +0200317 temp = inb_p(SMBHSTSTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 }
319 while ((!(temp & 0x80))
320 && (timeout++ < MAX_TIMEOUT));
321
322 /* If the SMBus is still busy, we give up */
323 if (timeout >= MAX_TIMEOUT) {
324 result = -1;
325 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
326 }
327
328 if (temp & 0x10) {
329 result = -1;
330 dev_dbg(&I801_dev->dev,
331 "Error: Failed bus transaction\n");
332 } else if (temp & 0x08) {
333 result = -1;
334 dev_err(&I801_dev->dev, "Bus collision!\n");
335 } else if (temp & 0x04) {
336 result = -1;
337 dev_dbg(&I801_dev->dev, "Error: no response!\n");
338 }
339
340 if (i == 1 && read_write == I2C_SMBUS_READ) {
341 len = inb_p(SMBHSTDAT0);
342 if (len < 1)
343 len = 1;
344 if (len > 32)
345 len = 32;
346 data->block[0] = len;
347 }
348
349 /* Retrieve/store value in SMBBLKDAT */
350 if (read_write == I2C_SMBUS_READ)
351 data->block[i] = inb_p(SMBBLKDAT);
352 if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
353 outb_p(data->block[i+1], SMBBLKDAT);
354 if ((temp & 0x9e) != 0x00)
355 outb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */
356
357 if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) {
358 dev_dbg(&I801_dev->dev,
359 "Bad status (%02x) at end of transaction\n",
360 temp);
361 }
362 dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, "
363 "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
364 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
365 inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
366
367 if (result < 0)
368 goto END;
369 }
370
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200371 if (hwpec) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 /* wait for INTR bit as advised by Intel */
373 timeout = 0;
374 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 msleep(1);
Jean Delvare397e2f62006-06-12 21:49:36 +0200376 temp = inb_p(SMBHSTSTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 } while ((!(temp & 0x02))
378 && (timeout++ < MAX_TIMEOUT));
379
380 if (timeout >= MAX_TIMEOUT) {
381 dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
382 }
383 outb_p(temp, SMBHSTSTS);
384 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 result = 0;
386END:
387 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
388 /* restore saved configuration register value */
389 pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
390 }
391 return result;
392}
393
394/* Return -1 on error. */
395static s32 i801_access(struct i2c_adapter * adap, u16 addr,
396 unsigned short flags, char read_write, u8 command,
397 int size, union i2c_smbus_data * data)
398{
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200399 int hwpec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 int block = 0;
401 int ret, xact = 0;
402
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200403 hwpec = isich4 && (flags & I2C_CLIENT_PEC)
404 && size != I2C_SMBUS_QUICK
405 && size != I2C_SMBUS_I2C_BLOCK_DATA;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
407 switch (size) {
408 case I2C_SMBUS_QUICK:
409 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
410 SMBHSTADD);
411 xact = I801_QUICK;
412 break;
413 case I2C_SMBUS_BYTE:
414 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
415 SMBHSTADD);
416 if (read_write == I2C_SMBUS_WRITE)
417 outb_p(command, SMBHSTCMD);
418 xact = I801_BYTE;
419 break;
420 case I2C_SMBUS_BYTE_DATA:
421 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
422 SMBHSTADD);
423 outb_p(command, SMBHSTCMD);
424 if (read_write == I2C_SMBUS_WRITE)
425 outb_p(data->byte, SMBHSTDAT0);
426 xact = I801_BYTE_DATA;
427 break;
428 case I2C_SMBUS_WORD_DATA:
429 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
430 SMBHSTADD);
431 outb_p(command, SMBHSTCMD);
432 if (read_write == I2C_SMBUS_WRITE) {
433 outb_p(data->word & 0xff, SMBHSTDAT0);
434 outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
435 }
436 xact = I801_WORD_DATA;
437 break;
438 case I2C_SMBUS_BLOCK_DATA:
439 case I2C_SMBUS_I2C_BLOCK_DATA:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
441 SMBHSTADD);
442 outb_p(command, SMBHSTCMD);
443 block = 1;
444 break;
445 case I2C_SMBUS_PROC_CALL:
446 default:
447 dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
448 return -1;
449 }
450
Mark M. Hoffman2e3e13f2005-11-06 23:04:51 +0100451 outb_p(hwpec, SMBAUXCTL); /* enable/disable hardware PEC */
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200452
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 if(block)
Jean Delvare585b3162005-10-26 21:31:15 +0200454 ret = i801_block_transaction(data, read_write, size, hwpec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 else {
456 outb_p(xact | ENABLE_INT9, SMBHSTCNT);
457 ret = i801_transaction();
458 }
459
Jean Delvarec79cfba2006-04-20 02:43:18 -0700460 /* Some BIOSes don't like it when PEC is enabled at reboot or resume
461 time, so we forcibly disable it after every transaction. */
462 if (hwpec)
463 outb_p(0, SMBAUXCTL);
464
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 if(block)
466 return ret;
467 if(ret)
468 return -1;
469 if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
470 return 0;
471
472 switch (xact & 0x7f) {
473 case I801_BYTE: /* Result put in SMBHSTDAT0 */
474 case I801_BYTE_DATA:
475 data->byte = inb_p(SMBHSTDAT0);
476 break;
477 case I801_WORD_DATA:
478 data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
479 break;
480 }
481 return 0;
482}
483
484
485static u32 i801_func(struct i2c_adapter *adapter)
486{
487 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
488 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
489 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
Jean Delvareb8095542005-10-26 21:25:04 +0200490 | (isich4 ? I2C_FUNC_SMBUS_HWPEC_CALC : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491}
492
493static struct i2c_algorithm smbus_algorithm = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 .smbus_xfer = i801_access,
495 .functionality = i801_func,
496};
497
498static struct i2c_adapter i801_adapter = {
499 .owner = THIS_MODULE,
500 .class = I2C_CLASS_HWMON,
501 .algo = &smbus_algorithm,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502};
503
504static struct pci_device_id i801_ids[] = {
505 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
506 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
507 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) },
508 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_3) },
509 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_3) },
510 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) },
511 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
512 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
513 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
Jason Gastonb0a70b52005-04-16 15:24:45 -0700514 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
Jason Gaston8254fc42006-01-09 10:58:08 -0800515 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 { 0, }
517};
518
519MODULE_DEVICE_TABLE (pci, i801_ids);
520
521static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
522{
523
524 if (i801_setup(dev)) {
525 dev_warn(&dev->dev,
526 "I801 not detected, module not inserted.\n");
527 return -ENODEV;
528 }
529
530 /* set up the driverfs linkage to our parent device */
531 i801_adapter.dev.parent = &dev->dev;
532
533 snprintf(i801_adapter.name, I2C_NAME_SIZE,
534 "SMBus I801 adapter at %04x", i801_smba);
535 return i2c_add_adapter(&i801_adapter);
536}
537
538static void __devexit i801_remove(struct pci_dev *dev)
539{
540 i2c_del_adapter(&i801_adapter);
541 release_region(i801_smba, (isich4 ? 16 : 8));
542}
543
544static struct pci_driver i801_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 .name = "i801_smbus",
546 .id_table = i801_ids,
547 .probe = i801_probe,
548 .remove = __devexit_p(i801_remove),
549};
550
551static int __init i2c_i801_init(void)
552{
553 return pci_register_driver(&i801_driver);
554}
555
556static void __exit i2c_i801_exit(void)
557{
558 pci_unregister_driver(&i801_driver);
559}
560
561MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, "
562 "Philip Edelbrock <phil@netroedge.com>, "
563 "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
564MODULE_DESCRIPTION("I801 SMBus driver");
565MODULE_LICENSE("GPL");
566
567module_init(i2c_i801_init);
568module_exit(i2c_i801_exit);