diff options
| author | Rudolf Marek <r.marek@assembler.cz> | 2013-07-14 17:17:26 -0400 |
|---|---|---|
| committer | Wolfram Sang <wsa@the-dreams.de> | 2013-08-15 09:17:31 -0400 |
| commit | a94dd00f2e1c20deacffadaaa6eebf73b217c907 (patch) | |
| tree | 904a001e72ac288a1b109c58c95f055c08b68cd5 /drivers/i2c | |
| parent | d63a9e851c2c007d9129b8dbfc1af24722bd18bd (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>
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 41 |
1 files changed, 31 insertions, 10 deletions
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 | ||
| 233 | static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, | 233 | static 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 | ||
