mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-11-07 04:09:21 +00:00
i2c-piix4: Add support to SB800 SMBus changes
Add support for the AMD SB800 Family series of products. Major changes include the changes to addressing the SMBus registers at different location from the locations in the previous compatible parts from AMD such as SB400/SB600/SB700. For SB800, the main features and register definitions of SMBus and other interfaces are still compatible with the previous products with the only change being in how to access the internal registers for these blocks. Signed-off-by: Shane Huang <shane.huang@amd.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
This commit is contained in:
parent
6b110d13aa
commit
87e1960e93
1 changed files with 72 additions and 1 deletions
|
@ -226,6 +226,70 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
unsigned short smba_idx = 0xcd6;
|
||||
u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c;
|
||||
|
||||
/* SB800 SMBus does not support forcing address */
|
||||
if (force || force_addr) {
|
||||
dev_err(&PIIX4_dev->dev, "SB800 SMBus does not support "
|
||||
"forcing address!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Determine the address of the SMBus areas */
|
||||
if (!request_region(smba_idx, 2, "smba_idx")) {
|
||||
dev_err(&PIIX4_dev->dev, "SMBus base address index region "
|
||||
"0x%x already in use!\n", smba_idx);
|
||||
return -EBUSY;
|
||||
}
|
||||
outb_p(smb_en, smba_idx);
|
||||
smba_en_lo = inb_p(smba_idx + 1);
|
||||
outb_p(smb_en + 1, smba_idx);
|
||||
smba_en_hi = inb_p(smba_idx + 1);
|
||||
release_region(smba_idx, 2);
|
||||
|
||||
if ((smba_en_lo & 1) == 0) {
|
||||
dev_err(&PIIX4_dev->dev,
|
||||
"Host SMBus controller not enabled!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
|
||||
if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
|
||||
return -EBUSY;
|
||||
|
||||
if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
|
||||
dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
|
||||
piix4_smba);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Request the SMBus I2C bus config region */
|
||||
if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
|
||||
dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region "
|
||||
"0x%x already in use!\n", piix4_smba + i2ccfg_offset);
|
||||
release_region(piix4_smba, SMBIOSIZE);
|
||||
piix4_smba = 0;
|
||||
return -EBUSY;
|
||||
}
|
||||
i2ccfg = inb_p(piix4_smba + i2ccfg_offset);
|
||||
release_region(piix4_smba + i2ccfg_offset, 1);
|
||||
|
||||
if (i2ccfg & 1)
|
||||
dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n");
|
||||
else
|
||||
dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n");
|
||||
|
||||
dev_info(&PIIX4_dev->dev,
|
||||
"SMBus Host Controller at 0x%x, revision %d\n",
|
||||
piix4_smba, i2ccfg >> 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int piix4_transaction(void)
|
||||
{
|
||||
int temp;
|
||||
|
@ -433,7 +497,14 @@ static int __devinit piix4_probe(struct pci_dev *dev,
|
|||
{
|
||||
int retval;
|
||||
|
||||
retval = piix4_setup(dev, id);
|
||||
if ((dev->vendor == PCI_VENDOR_ID_ATI) &&
|
||||
(dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) &&
|
||||
(dev->revision >= 0x40))
|
||||
/* base address location etc changed in SB800 */
|
||||
retval = piix4_setup_sb800(dev, id);
|
||||
else
|
||||
retval = piix4_setup(dev, id);
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
|
Loading…
Reference in a new issue