aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRudolf Marek <r.marek@assembler.cz>2013-07-14 17:17:26 -0400
committerWolfram Sang <wsa@the-dreams.de>2013-08-15 09:17:31 -0400
commita94dd00f2e1c20deacffadaaa6eebf73b217c907 (patch)
tree904a001e72ac288a1b109c58c95f055c08b68cd5
parentd63a9e851c2c007d9129b8dbfc1af24722bd18bd (diff)
i2c: piix4: Add support for secondary SMBus on AMD SB800 and AMD FCH chipsets
Add support for the secondary SMBus controller on the AMD SB800 and AMD FCH chipsets. Signed-off-by: Rudolf Marek <r.marek@assembler.cz> Tested-by: Paul Menzel <paulepanter@users.sourceforge.net> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--Documentation/i2c/busses/i2c-piix47
-rw-r--r--drivers/i2c/busses/i2c-piix4.c41
2 files changed, 35 insertions, 13 deletions
diff --git a/Documentation/i2c/busses/i2c-piix4 b/Documentation/i2c/busses/i2c-piix4
index a370b2047cf3..c097e0f020fe 100644
--- a/Documentation/i2c/busses/i2c-piix4
+++ b/Documentation/i2c/busses/i2c-piix4
@@ -73,9 +73,10 @@ this driver on those mainboards.
73The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are 73The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are
74identical to the PIIX4 in I2C/SMBus support. 74identical to the PIIX4 in I2C/SMBus support.
75 75
76The AMD SB700 and SP5100 chipsets implement two PIIX4-compatible SMBus 76The AMD SB700, SB800, SP5100 and Hudson-2 chipsets implement two
77controllers. If your BIOS initializes the secondary controller, it will 77PIIX4-compatible SMBus controllers. If your BIOS initializes the
78be detected by this driver as an "Auxiliary SMBus Host Controller". 78secondary controller, it will be detected by this driver as
79an "Auxiliary SMBus Host Controller".
79 80
80If you own Force CPCI735 motherboard or other OSB4 based systems you may need 81If you own Force CPCI735 motherboard or other OSB4 based systems you may need
81to change the SMBus Interrupt Select register so the SMBus controller uses 82to change the SMBus Interrupt Select register so the SMBus controller uses
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index d05ad590af29..a028617b8f13 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -231,11 +231,11 @@ static int piix4_setup(struct pci_dev *PIIX4_dev,
231} 231}
232 232
233static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, 233static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
234 const struct pci_device_id *id) 234 const struct pci_device_id *id, u8 aux)
235{ 235{
236 unsigned short piix4_smba; 236 unsigned short piix4_smba;
237 unsigned short smba_idx = 0xcd6; 237 unsigned short smba_idx = 0xcd6;
238 u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c; 238 u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en;
239 239
240 /* SB800 and later SMBus does not support forcing address */ 240 /* SB800 and later SMBus does not support forcing address */
241 if (force || force_addr) { 241 if (force || force_addr) {
@@ -245,6 +245,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
245 } 245 }
246 246
247 /* Determine the address of the SMBus areas */ 247 /* Determine the address of the SMBus areas */
248 smb_en = (aux) ? 0x28 : 0x2c;
249
248 if (!request_region(smba_idx, 2, "smba_idx")) { 250 if (!request_region(smba_idx, 2, "smba_idx")) {
249 dev_err(&PIIX4_dev->dev, "SMBus base address index region " 251 dev_err(&PIIX4_dev->dev, "SMBus base address index region "
250 "0x%x already in use!\n", smba_idx); 252 "0x%x already in use!\n", smba_idx);
@@ -272,6 +274,13 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
272 return -EBUSY; 274 return -EBUSY;
273 } 275 }
274 276
277 /* Aux SMBus does not support IRQ information */
278 if (aux) {
279 dev_info(&PIIX4_dev->dev,
280 "SMBus Host Controller at 0x%x\n", piix4_smba);
281 return piix4_smba;
282 }
283
275 /* Request the SMBus I2C bus config region */ 284 /* Request the SMBus I2C bus config region */
276 if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) { 285 if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
277 dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region " 286 dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region "
@@ -597,7 +606,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
597 dev->revision >= 0x40) || 606 dev->revision >= 0x40) ||
598 dev->vendor == PCI_VENDOR_ID_AMD) 607 dev->vendor == PCI_VENDOR_ID_AMD)
599 /* base address location etc changed in SB800 */ 608 /* base address location etc changed in SB800 */
600 retval = piix4_setup_sb800(dev, id); 609 retval = piix4_setup_sb800(dev, id, 0);
601 else 610 else
602 retval = piix4_setup(dev, id); 611 retval = piix4_setup(dev, id);
603 612
@@ -611,17 +620,29 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
611 return retval; 620 return retval;
612 621
613 /* Check for auxiliary SMBus on some AMD chipsets */ 622 /* Check for auxiliary SMBus on some AMD chipsets */
623 retval = -ENODEV;
624
614 if (dev->vendor == PCI_VENDOR_ID_ATI && 625 if (dev->vendor == PCI_VENDOR_ID_ATI &&
615 dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && 626 dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) {
616 dev->revision < 0x40) { 627 if (dev->revision < 0x40) {
617 retval = piix4_setup_aux(dev, id, 0x58); 628 retval = piix4_setup_aux(dev, id, 0x58);
618 if (retval > 0) { 629 } else {
619 /* Try to add the aux adapter if it exists, 630 /* SB800 added aux bus too */
620 * piix4_add_adapter will clean up if this fails */ 631 retval = piix4_setup_sb800(dev, id, 1);
621 piix4_add_adapter(dev, retval, &piix4_aux_adapter);
622 } 632 }
623 } 633 }
624 634
635 if (dev->vendor == PCI_VENDOR_ID_AMD &&
636 dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) {
637 retval = piix4_setup_sb800(dev, id, 1);
638 }
639
640 if (retval > 0) {
641 /* Try to add the aux adapter if it exists,
642 * piix4_add_adapter will clean up if this fails */
643 piix4_add_adapter(dev, retval, &piix4_aux_adapter);
644 }
645
625 return 0; 646 return 0;
626} 647}
627 648