diff options
-rw-r--r-- | Documentation/i2c/busses/i2c-piix4 | 9 | ||||
-rw-r--r-- | drivers/i2c/busses/Kconfig | 6 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 71 |
3 files changed, 82 insertions, 4 deletions
diff --git a/Documentation/i2c/busses/i2c-piix4 b/Documentation/i2c/busses/i2c-piix4 index 475bb4ae0720..1e6634f54c50 100644 --- a/Documentation/i2c/busses/i2c-piix4 +++ b/Documentation/i2c/busses/i2c-piix4 | |||
@@ -8,6 +8,11 @@ Supported adapters: | |||
8 | Datasheet: Only available via NDA from ServerWorks | 8 | Datasheet: Only available via NDA from ServerWorks |
9 | * ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges | 9 | * ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges |
10 | Datasheet: Not publicly available | 10 | Datasheet: Not publicly available |
11 | SB700 register reference available at: | ||
12 | http://support.amd.com/us/Embedded_TechDocs/43009_sb7xx_rrg_pub_1.00.pdf | ||
13 | * AMD SP5100 (SB700 derivative found on some server mainboards) | ||
14 | Datasheet: Publicly available at the AMD website | ||
15 | http://support.amd.com/us/Embedded_TechDocs/44413.pdf | ||
11 | * AMD Hudson-2 | 16 | * AMD Hudson-2 |
12 | Datasheet: Not publicly available | 17 | Datasheet: Not publicly available |
13 | * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge | 18 | * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge |
@@ -68,6 +73,10 @@ this driver on those mainboards. | |||
68 | The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are | 73 | The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are |
69 | identical to the PIIX4 in I2C/SMBus support. | 74 | identical to the PIIX4 in I2C/SMBus support. |
70 | 75 | ||
76 | The AMD SB700 and SP5100 chipsets implement two PIIX4-compatible SMBus | ||
77 | controllers. If your BIOS initializes the secondary controller, it will | ||
78 | be detected by this driver as an "Auxiliary SMBus Host Controller". | ||
79 | |||
71 | If you own Force CPCI735 motherboard or other OSB4 based systems you may need | 80 | If you own Force CPCI735 motherboard or other OSB4 based systems you may need |
72 | to change the SMBus Interrupt Select register so the SMBus controller uses | 81 | to change the SMBus Interrupt Select register so the SMBus controller uses |
73 | the SMI mode. | 82 | the SMI mode. |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 7244c8be6063..2e7530a4e7b8 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -133,7 +133,7 @@ config I2C_PIIX4 | |||
133 | ATI IXP300 | 133 | ATI IXP300 |
134 | ATI IXP400 | 134 | ATI IXP400 |
135 | ATI SB600 | 135 | ATI SB600 |
136 | ATI SB700 | 136 | ATI SB700/SP5100 |
137 | ATI SB800 | 137 | ATI SB800 |
138 | AMD Hudson-2 | 138 | AMD Hudson-2 |
139 | Serverworks OSB4 | 139 | Serverworks OSB4 |
@@ -143,6 +143,10 @@ config I2C_PIIX4 | |||
143 | Serverworks HT-1100 | 143 | Serverworks HT-1100 |
144 | SMSC Victory66 | 144 | SMSC Victory66 |
145 | 145 | ||
146 | Some AMD chipsets contain two PIIX4-compatible SMBus | ||
147 | controllers. This driver will attempt to use both controllers | ||
148 | on the SB700/SP5100, if they have been initialized by the BIOS. | ||
149 | |||
146 | This driver can also be built as a module. If so, the module | 150 | This driver can also be built as a module. If so, the module |
147 | will be called i2c-piix4. | 151 | will be called i2c-piix4. |
148 | 152 | ||
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 42ed0af10efd..ef511df2c965 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
@@ -21,11 +21,12 @@ | |||
21 | Supports: | 21 | Supports: |
22 | Intel PIIX4, 440MX | 22 | Intel PIIX4, 440MX |
23 | Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 | 23 | Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 |
24 | ATI IXP200, IXP300, IXP400, SB600, SB700, SB800 | 24 | ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800 |
25 | AMD Hudson-2 | 25 | AMD Hudson-2 |
26 | SMSC Victory66 | 26 | SMSC Victory66 |
27 | 27 | ||
28 | Note: we assume there can only be one device, with one SMBus interface. | 28 | Note: we assume there can only be one device, with one or more |
29 | SMBus interfaces. | ||
29 | */ | 30 | */ |
30 | 31 | ||
31 | #include <linux/module.h> | 32 | #include <linux/module.h> |
@@ -293,6 +294,46 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev, | |||
293 | return piix4_smba; | 294 | return piix4_smba; |
294 | } | 295 | } |
295 | 296 | ||
297 | static int __devinit piix4_setup_aux(struct pci_dev *PIIX4_dev, | ||
298 | const struct pci_device_id *id, | ||
299 | unsigned short base_reg_addr) | ||
300 | { | ||
301 | /* Set up auxiliary SMBus controllers found on some | ||
302 | * AMD chipsets e.g. SP5100 (SB700 derivative) */ | ||
303 | |||
304 | unsigned short piix4_smba; | ||
305 | |||
306 | /* Read address of auxiliary SMBus controller */ | ||
307 | pci_read_config_word(PIIX4_dev, base_reg_addr, &piix4_smba); | ||
308 | if ((piix4_smba & 1) == 0) { | ||
309 | dev_dbg(&PIIX4_dev->dev, | ||
310 | "Auxiliary SMBus controller not enabled\n"); | ||
311 | return -ENODEV; | ||
312 | } | ||
313 | |||
314 | piix4_smba &= 0xfff0; | ||
315 | if (piix4_smba == 0) { | ||
316 | dev_dbg(&PIIX4_dev->dev, | ||
317 | "Auxiliary SMBus base address uninitialized\n"); | ||
318 | return -ENODEV; | ||
319 | } | ||
320 | |||
321 | if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) | ||
322 | return -ENODEV; | ||
323 | |||
324 | if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { | ||
325 | dev_err(&PIIX4_dev->dev, "Auxiliary SMBus region 0x%x " | ||
326 | "already in use!\n", piix4_smba); | ||
327 | return -EBUSY; | ||
328 | } | ||
329 | |||
330 | dev_info(&PIIX4_dev->dev, | ||
331 | "Auxiliary SMBus Host Controller at 0x%x\n", | ||
332 | piix4_smba); | ||
333 | |||
334 | return piix4_smba; | ||
335 | } | ||
336 | |||
296 | static int piix4_transaction(struct i2c_adapter *piix4_adapter) | 337 | static int piix4_transaction(struct i2c_adapter *piix4_adapter) |
297 | { | 338 | { |
298 | struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter); | 339 | struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter); |
@@ -497,6 +538,7 @@ static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = { | |||
497 | MODULE_DEVICE_TABLE (pci, piix4_ids); | 538 | MODULE_DEVICE_TABLE (pci, piix4_ids); |
498 | 539 | ||
499 | static struct i2c_adapter *piix4_main_adapter; | 540 | static struct i2c_adapter *piix4_main_adapter; |
541 | static struct i2c_adapter *piix4_aux_adapter; | ||
500 | 542 | ||
501 | static int __devinit piix4_add_adapter(struct pci_dev *dev, | 543 | static int __devinit piix4_add_adapter(struct pci_dev *dev, |
502 | unsigned short smba, | 544 | unsigned short smba, |
@@ -560,10 +602,28 @@ static int __devinit piix4_probe(struct pci_dev *dev, | |||
560 | else | 602 | else |
561 | retval = piix4_setup(dev, id); | 603 | retval = piix4_setup(dev, id); |
562 | 604 | ||
605 | /* If no main SMBus found, give up */ | ||
563 | if (retval < 0) | 606 | if (retval < 0) |
564 | return retval; | 607 | return retval; |
565 | 608 | ||
566 | return piix4_add_adapter(dev, retval, &piix4_main_adapter); | 609 | /* Try to register main SMBus adapter, give up if we can't */ |
610 | retval = piix4_add_adapter(dev, retval, &piix4_main_adapter); | ||
611 | if (retval < 0) | ||
612 | return retval; | ||
613 | |||
614 | /* Check for auxiliary SMBus on some AMD chipsets */ | ||
615 | if (dev->vendor == PCI_VENDOR_ID_ATI && | ||
616 | dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && | ||
617 | dev->revision < 0x40) { | ||
618 | retval = piix4_setup_aux(dev, id, 0x58); | ||
619 | if (retval > 0) { | ||
620 | /* Try to add the aux adapter if it exists, | ||
621 | * piix4_add_adapter will clean up if this fails */ | ||
622 | piix4_add_adapter(dev, retval, &piix4_aux_adapter); | ||
623 | } | ||
624 | } | ||
625 | |||
626 | return 0; | ||
567 | } | 627 | } |
568 | 628 | ||
569 | static void __devexit piix4_adap_remove(struct i2c_adapter *adap) | 629 | static void __devexit piix4_adap_remove(struct i2c_adapter *adap) |
@@ -584,6 +644,11 @@ static void __devexit piix4_remove(struct pci_dev *dev) | |||
584 | piix4_adap_remove(piix4_main_adapter); | 644 | piix4_adap_remove(piix4_main_adapter); |
585 | piix4_main_adapter = NULL; | 645 | piix4_main_adapter = NULL; |
586 | } | 646 | } |
647 | |||
648 | if (piix4_aux_adapter) { | ||
649 | piix4_adap_remove(piix4_aux_adapter); | ||
650 | piix4_aux_adapter = NULL; | ||
651 | } | ||
587 | } | 652 | } |
588 | 653 | ||
589 | static struct pci_driver piix4_driver = { | 654 | static struct pci_driver piix4_driver = { |