Commit a94dd00f authored by Rudolf Marek's avatar Rudolf Marek Committed by Wolfram Sang

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: default avatarRudolf Marek <r.marek@assembler.cz>
Tested-by: default avatarPaul Menzel <paulepanter@users.sourceforge.net>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent d63a9e85
...@@ -73,9 +73,10 @@ this driver on those mainboards. ...@@ -73,9 +73,10 @@ this driver on those mainboards.
The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are
identical to the PIIX4 in I2C/SMBus support. identical to the PIIX4 in I2C/SMBus support.
The AMD SB700 and SP5100 chipsets implement two PIIX4-compatible SMBus The AMD SB700, SB800, SP5100 and Hudson-2 chipsets implement two
controllers. If your BIOS initializes the secondary controller, it will PIIX4-compatible SMBus controllers. If your BIOS initializes the
be detected by this driver as an "Auxiliary SMBus Host Controller". secondary controller, it will be detected by this driver as
an "Auxiliary SMBus Host Controller".
If you own Force CPCI735 motherboard or other OSB4 based systems you may need If you own Force CPCI735 motherboard or other OSB4 based systems you may need
to change the SMBus Interrupt Select register so the SMBus controller uses to change the SMBus Interrupt Select register so the SMBus controller uses
......
...@@ -231,11 +231,11 @@ static int piix4_setup(struct pci_dev *PIIX4_dev, ...@@ -231,11 +231,11 @@ static int piix4_setup(struct pci_dev *PIIX4_dev,
} }
static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
const struct pci_device_id *id) const struct pci_device_id *id, u8 aux)
{ {
unsigned short piix4_smba; unsigned short piix4_smba;
unsigned short smba_idx = 0xcd6; unsigned short smba_idx = 0xcd6;
u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c; u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en;
/* SB800 and later SMBus does not support forcing address */ /* SB800 and later SMBus does not support forcing address */
if (force || force_addr) { if (force || force_addr) {
...@@ -245,6 +245,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, ...@@ -245,6 +245,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
} }
/* Determine the address of the SMBus areas */ /* Determine the address of the SMBus areas */
smb_en = (aux) ? 0x28 : 0x2c;
if (!request_region(smba_idx, 2, "smba_idx")) { if (!request_region(smba_idx, 2, "smba_idx")) {
dev_err(&PIIX4_dev->dev, "SMBus base address index region " dev_err(&PIIX4_dev->dev, "SMBus base address index region "
"0x%x already in use!\n", smba_idx); "0x%x already in use!\n", smba_idx);
...@@ -272,6 +274,13 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, ...@@ -272,6 +274,13 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
return -EBUSY; return -EBUSY;
} }
/* Aux SMBus does not support IRQ information */
if (aux) {
dev_info(&PIIX4_dev->dev,
"SMBus Host Controller at 0x%x\n", piix4_smba);
return piix4_smba;
}
/* Request the SMBus I2C bus config region */ /* Request the SMBus I2C bus config region */
if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) { if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region " 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,7 +606,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
dev->revision >= 0x40) || dev->revision >= 0x40) ||
dev->vendor == PCI_VENDOR_ID_AMD) dev->vendor == PCI_VENDOR_ID_AMD)
/* base address location etc changed in SB800 */ /* base address location etc changed in SB800 */
retval = piix4_setup_sb800(dev, id); retval = piix4_setup_sb800(dev, id, 0);
else else
retval = piix4_setup(dev, id); retval = piix4_setup(dev, id);
...@@ -611,17 +620,29 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -611,17 +620,29 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
return retval; return retval;
/* Check for auxiliary SMBus on some AMD chipsets */ /* Check for auxiliary SMBus on some AMD chipsets */
retval = -ENODEV;
if (dev->vendor == PCI_VENDOR_ID_ATI && if (dev->vendor == PCI_VENDOR_ID_ATI &&
dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) {
dev->revision < 0x40) { if (dev->revision < 0x40) {
retval = piix4_setup_aux(dev, id, 0x58); retval = piix4_setup_aux(dev, id, 0x58);
if (retval > 0) { } else {
/* Try to add the aux adapter if it exists, /* SB800 added aux bus too */
* piix4_add_adapter will clean up if this fails */ retval = piix4_setup_sb800(dev, id, 1);
piix4_add_adapter(dev, retval, &piix4_aux_adapter);
} }
} }
if (dev->vendor == PCI_VENDOR_ID_AMD &&
dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) {
retval = piix4_setup_sb800(dev, id, 1);
}
if (retval > 0) {
/* Try to add the aux adapter if it exists,
* piix4_add_adapter will clean up if this fails */
piix4_add_adapter(dev, retval, &piix4_aux_adapter);
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment