aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-i801.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-i801.c')
-rw-r--r--drivers/i2c/busses/i2c-i801.c154
1 files changed, 64 insertions, 90 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index dfca74933625..3e0d04d5a800 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -1,5 +1,5 @@
1/* 1/*
2 i801.c - Part of lm_sensors, Linux kernel modules for hardware 2 i2c-i801.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring 3 monitoring
4 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, 4 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
5 Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker 5 Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
@@ -36,7 +36,7 @@
36 This driver supports several versions of Intel's I/O Controller Hubs (ICH). 36 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 37 For SMBus support, they are similar to the PIIX4 and are part
38 of Intel's '810' and other chipsets. 38 of Intel's '810' and other chipsets.
39 See the doc/busses/i2c-i801 file for details. 39 See the file Documentation/i2c/busses/i2c-i801 for details.
40 I2C Block Read and Process Call are not supported. 40 I2C Block Read and Process Call are not supported.
41*/ 41*/
42 42
@@ -66,9 +66,8 @@
66#define SMBAUXCTL (13 + i801_smba) /* ICH4 only */ 66#define SMBAUXCTL (13 + i801_smba) /* ICH4 only */
67 67
68/* PCI Address Constants */ 68/* PCI Address Constants */
69#define SMBBA 0x020 69#define SMBBAR 4
70#define SMBHSTCFG 0x040 70#define SMBHSTCFG 0x040
71#define SMBREV 0x008
72 71
73/* Host configuration bits for SMBHSTCFG */ 72/* Host configuration bits for SMBHSTCFG */
74#define SMBHSTCFG_HST_EN 1 73#define SMBHSTCFG_HST_EN 1
@@ -92,92 +91,16 @@
92#define I801_START 0x40 91#define I801_START 0x40
93#define I801_PEC_EN 0x80 /* ICH4 only */ 92#define I801_PEC_EN 0x80 /* ICH4 only */
94 93
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 94
105static int i801_transaction(void); 95static int i801_transaction(void);
106static int i801_block_transaction(union i2c_smbus_data *data, char read_write, 96static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
107 int command, int hwpec); 97 int command, int hwpec);
108 98
109static unsigned short i801_smba; 99static unsigned long i801_smba;
110static struct pci_driver i801_driver; 100static struct pci_driver i801_driver;
111static struct pci_dev *I801_dev; 101static struct pci_dev *I801_dev;
112static int isich4; 102static int isich4;
113 103
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) {
138 dev_err(&dev->dev, "SMB base address uninitialized "
139 "- upgrade BIOS or use force_addr=0xaddr\n");
140 return -ENODEV;
141 }
142 }
143
144 if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) {
145 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) 104static int i801_transaction(void)
182{ 105{
183 int temp; 106 int temp;
@@ -334,8 +257,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
334 /* We will always wait for a fraction of a second! */ 257 /* We will always wait for a fraction of a second! */
335 timeout = 0; 258 timeout = 0;
336 do { 259 do {
337 temp = inb_p(SMBHSTSTS);
338 msleep(1); 260 msleep(1);
261 temp = inb_p(SMBHSTSTS);
339 } 262 }
340 while ((!(temp & 0x80)) 263 while ((!(temp & 0x80))
341 && (timeout++ < MAX_TIMEOUT)); 264 && (timeout++ < MAX_TIMEOUT));
@@ -393,8 +316,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
393 /* wait for INTR bit as advised by Intel */ 316 /* wait for INTR bit as advised by Intel */
394 timeout = 0; 317 timeout = 0;
395 do { 318 do {
396 temp = inb_p(SMBHSTSTS);
397 msleep(1); 319 msleep(1);
320 temp = inb_p(SMBHSTSTS);
398 } while ((!(temp & 0x02)) 321 } while ((!(temp & 0x02))
399 && (timeout++ < MAX_TIMEOUT)); 322 && (timeout++ < MAX_TIMEOUT));
400 323
@@ -541,25 +464,76 @@ MODULE_DEVICE_TABLE (pci, i801_ids);
541 464
542static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) 465static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
543{ 466{
467 unsigned char temp;
468 int err;
469
470 I801_dev = dev;
471 if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
472 (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
473 (dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
474 isich4 = 1;
475 else
476 isich4 = 0;
477
478 err = pci_enable_device(dev);
479 if (err) {
480 dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
481 err);
482 goto exit;
483 }
484
485 /* Determine the address of the SMBus area */
486 i801_smba = pci_resource_start(dev, SMBBAR);
487 if (!i801_smba) {
488 dev_err(&dev->dev, "SMBus base address uninitialized, "
489 "upgrade BIOS\n");
490 err = -ENODEV;
491 goto exit_disable;
492 }
493
494 err = pci_request_region(dev, SMBBAR, i801_driver.name);
495 if (err) {
496 dev_err(&dev->dev, "Failed to request SMBus region "
497 "0x%lx-0x%lx\n", i801_smba,
498 pci_resource_end(dev, SMBBAR));
499 goto exit_disable;
500 }
544 501
545 if (i801_setup(dev)) { 502 pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
546 dev_warn(&dev->dev, 503 temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
547 "I801 not detected, module not inserted.\n"); 504 if (!(temp & SMBHSTCFG_HST_EN)) {
548 return -ENODEV; 505 dev_info(&dev->dev, "Enabling SMBus device\n");
506 temp |= SMBHSTCFG_HST_EN;
549 } 507 }
508 pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
509
510 if (temp & SMBHSTCFG_SMB_SMI_EN)
511 dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
512 else
513 dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n");
550 514
551 /* set up the driverfs linkage to our parent device */ 515 /* set up the driverfs linkage to our parent device */
552 i801_adapter.dev.parent = &dev->dev; 516 i801_adapter.dev.parent = &dev->dev;
553 517
554 snprintf(i801_adapter.name, I2C_NAME_SIZE, 518 snprintf(i801_adapter.name, I2C_NAME_SIZE,
555 "SMBus I801 adapter at %04x", i801_smba); 519 "SMBus I801 adapter at %04lx", i801_smba);
556 return i2c_add_adapter(&i801_adapter); 520 err = i2c_add_adapter(&i801_adapter);
521 if (err) {
522 dev_err(&dev->dev, "Failed to add SMBus adapter\n");
523 goto exit_disable;
524 }
525
526exit_disable:
527 pci_disable_device(dev);
528exit:
529 return err;
557} 530}
558 531
559static void __devexit i801_remove(struct pci_dev *dev) 532static void __devexit i801_remove(struct pci_dev *dev)
560{ 533{
561 i2c_del_adapter(&i801_adapter); 534 i2c_del_adapter(&i801_adapter);
562 release_region(i801_smba, (isich4 ? 16 : 8)); 535 pci_release_region(dev, SMBBAR);
536 pci_disable_device(dev);
563} 537}
564 538
565static struct pci_driver i801_driver = { 539static struct pci_driver i801_driver = {