aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/busses/i2c-i801.c121
1 files changed, 55 insertions, 66 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 94a30f5de776..3e0d04d5a800 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -68,7 +68,6 @@
68/* PCI Address Constants */ 68/* PCI Address Constants */
69#define SMBBAR 4 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
@@ -102,68 +101,6 @@ static struct pci_driver i801_driver;
102static struct pci_dev *I801_dev; 101static struct pci_dev *I801_dev;
103static int isich4; 102static int isich4;
104 103
105static int __devinit i801_setup(struct pci_dev *dev)
106{
107 unsigned char temp;
108 int err;
109
110 I801_dev = dev;
111 if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
112 (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
113 (dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
114 isich4 = 1;
115 else
116 isich4 = 0;
117
118 err = pci_enable_device(dev);
119 if (err) {
120 dev_err(&dev->dev, "Failed to enable SMBus device (%d)\n",
121 err);
122 goto exit;
123 }
124
125 /* Determine the address of the SMBus area */
126 i801_smba = pci_resource_start(dev, SMBBAR);
127 if (!i801_smba) {
128 dev_err(&dev->dev, "SMBus base address uninitialized, "
129 "upgrade BIOS\n");
130 err = -ENODEV;
131 goto exit_disable;
132 }
133
134 err = pci_request_region(dev, SMBBAR, i801_driver.name);
135 if (err) {
136 dev_err(&dev->dev, "Failed to request SMBus region "
137 "0x%lx-0x%lx\n", i801_smba,
138 pci_resource_end(dev, SMBBAR));
139 goto exit_disable;
140 }
141
142 pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
143 temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
144 if (!(temp & SMBHSTCFG_HST_EN)) {
145 dev_warn(&dev->dev, "enabling SMBus device\n");
146 temp |= SMBHSTCFG_HST_EN;
147 }
148 pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
149
150 if (temp & SMBHSTCFG_SMB_SMI_EN)
151 dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n");
152 else
153 dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n");
154
155 pci_read_config_byte(I801_dev, SMBREV, &temp);
156 dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
157 dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba);
158
159 return 0;
160
161exit_disable:
162 pci_disable_device(dev);
163exit:
164 return err;
165}
166
167static int i801_transaction(void) 104static int i801_transaction(void)
168{ 105{
169 int temp; 106 int temp;
@@ -527,17 +464,69 @@ MODULE_DEVICE_TABLE (pci, i801_ids);
527 464
528static 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)
529{ 466{
467 unsigned char temp;
530 int err; 468 int err;
531 469
532 if ((err = i801_setup(dev))) 470 I801_dev = dev;
533 return err; 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 }
501
502 pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
503 temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
504 if (!(temp & SMBHSTCFG_HST_EN)) {
505 dev_info(&dev->dev, "Enabling SMBus device\n");
506 temp |= SMBHSTCFG_HST_EN;
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");
534 514
535 /* set up the driverfs linkage to our parent device */ 515 /* set up the driverfs linkage to our parent device */
536 i801_adapter.dev.parent = &dev->dev; 516 i801_adapter.dev.parent = &dev->dev;
537 517
538 snprintf(i801_adapter.name, I2C_NAME_SIZE, 518 snprintf(i801_adapter.name, I2C_NAME_SIZE,
539 "SMBus I801 adapter at %04lx", i801_smba); 519 "SMBus I801 adapter at %04lx", i801_smba);
540 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;
541} 530}
542 531
543static void __devexit i801_remove(struct pci_dev *dev) 532static void __devexit i801_remove(struct pci_dev *dev)