mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 15:19:51 +00:00
i2c-piix4: Support AMD auxiliary SMBus controller
Some AMD chipsets, such as the SP5100, have an auxiliary SMBus controller with a second set of registers. This patch adds support for this auxiliary controller. Tested on ASUS KCMA-D8 motherboard. Signed-off-by: Andrew Armenia <andrew@asquaredlabs.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
This commit is contained in:
parent
e154bf6fbf
commit
2a2f7404a1
@ -8,6 +8,11 @@ Supported adapters:
|
|||||||
Datasheet: Only available via NDA from ServerWorks
|
Datasheet: Only available via NDA from ServerWorks
|
||||||
* ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
|
* ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
|
||||||
Datasheet: Not publicly available
|
Datasheet: Not publicly available
|
||||||
|
SB700 register reference available at:
|
||||||
|
http://support.amd.com/us/Embedded_TechDocs/43009_sb7xx_rrg_pub_1.00.pdf
|
||||||
|
* AMD SP5100 (SB700 derivative found on some server mainboards)
|
||||||
|
Datasheet: Publicly available at the AMD website
|
||||||
|
http://support.amd.com/us/Embedded_TechDocs/44413.pdf
|
||||||
* AMD Hudson-2
|
* AMD Hudson-2
|
||||||
Datasheet: Not publicly available
|
Datasheet: Not publicly available
|
||||||
* Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
|
* Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
|
||||||
@ -68,6 +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
|
||||||
|
controllers. If your BIOS initializes the 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
|
||||||
the SMI mode.
|
the SMI mode.
|
||||||
|
@ -133,7 +133,7 @@ config I2C_PIIX4
|
|||||||
ATI IXP300
|
ATI IXP300
|
||||||
ATI IXP400
|
ATI IXP400
|
||||||
ATI SB600
|
ATI SB600
|
||||||
ATI SB700
|
ATI SB700/SP5100
|
||||||
ATI SB800
|
ATI SB800
|
||||||
AMD Hudson-2
|
AMD Hudson-2
|
||||||
Serverworks OSB4
|
Serverworks OSB4
|
||||||
@ -143,6 +143,10 @@ config I2C_PIIX4
|
|||||||
Serverworks HT-1100
|
Serverworks HT-1100
|
||||||
SMSC Victory66
|
SMSC Victory66
|
||||||
|
|
||||||
|
Some AMD chipsets contain two PIIX4-compatible SMBus
|
||||||
|
controllers. This driver will attempt to use both controllers
|
||||||
|
on the SB700/SP5100, if they have been initialized by the BIOS.
|
||||||
|
|
||||||
This driver can also be built as a module. If so, the module
|
This driver can also be built as a module. If so, the module
|
||||||
will be called i2c-piix4.
|
will be called i2c-piix4.
|
||||||
|
|
||||||
|
@ -21,11 +21,12 @@
|
|||||||
Supports:
|
Supports:
|
||||||
Intel PIIX4, 440MX
|
Intel PIIX4, 440MX
|
||||||
Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
|
Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
|
||||||
ATI IXP200, IXP300, IXP400, SB600, SB700, SB800
|
ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800
|
||||||
AMD Hudson-2
|
AMD Hudson-2
|
||||||
SMSC Victory66
|
SMSC Victory66
|
||||||
|
|
||||||
Note: we assume there can only be one device, with one SMBus interface.
|
Note: we assume there can only be one device, with one or more
|
||||||
|
SMBus interfaces.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@ -293,6 +294,46 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
|||||||
return piix4_smba;
|
return piix4_smba;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __devinit piix4_setup_aux(struct pci_dev *PIIX4_dev,
|
||||||
|
const struct pci_device_id *id,
|
||||||
|
unsigned short base_reg_addr)
|
||||||
|
{
|
||||||
|
/* Set up auxiliary SMBus controllers found on some
|
||||||
|
* AMD chipsets e.g. SP5100 (SB700 derivative) */
|
||||||
|
|
||||||
|
unsigned short piix4_smba;
|
||||||
|
|
||||||
|
/* Read address of auxiliary SMBus controller */
|
||||||
|
pci_read_config_word(PIIX4_dev, base_reg_addr, &piix4_smba);
|
||||||
|
if ((piix4_smba & 1) == 0) {
|
||||||
|
dev_dbg(&PIIX4_dev->dev,
|
||||||
|
"Auxiliary SMBus controller not enabled\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
piix4_smba &= 0xfff0;
|
||||||
|
if (piix4_smba == 0) {
|
||||||
|
dev_dbg(&PIIX4_dev->dev,
|
||||||
|
"Auxiliary SMBus base address uninitialized\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
|
||||||
|
dev_err(&PIIX4_dev->dev, "Auxiliary SMBus region 0x%x "
|
||||||
|
"already in use!\n", piix4_smba);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(&PIIX4_dev->dev,
|
||||||
|
"Auxiliary SMBus Host Controller at 0x%x\n",
|
||||||
|
piix4_smba);
|
||||||
|
|
||||||
|
return piix4_smba;
|
||||||
|
}
|
||||||
|
|
||||||
static int piix4_transaction(struct i2c_adapter *piix4_adapter)
|
static int piix4_transaction(struct i2c_adapter *piix4_adapter)
|
||||||
{
|
{
|
||||||
struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter);
|
struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter);
|
||||||
@ -497,6 +538,7 @@ static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = {
|
|||||||
MODULE_DEVICE_TABLE (pci, piix4_ids);
|
MODULE_DEVICE_TABLE (pci, piix4_ids);
|
||||||
|
|
||||||
static struct i2c_adapter *piix4_main_adapter;
|
static struct i2c_adapter *piix4_main_adapter;
|
||||||
|
static struct i2c_adapter *piix4_aux_adapter;
|
||||||
|
|
||||||
static int __devinit piix4_add_adapter(struct pci_dev *dev,
|
static int __devinit piix4_add_adapter(struct pci_dev *dev,
|
||||||
unsigned short smba,
|
unsigned short smba,
|
||||||
@ -560,10 +602,28 @@ static int __devinit piix4_probe(struct pci_dev *dev,
|
|||||||
else
|
else
|
||||||
retval = piix4_setup(dev, id);
|
retval = piix4_setup(dev, id);
|
||||||
|
|
||||||
|
/* If no main SMBus found, give up */
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
return piix4_add_adapter(dev, retval, &piix4_main_adapter);
|
/* Try to register main SMBus adapter, give up if we can't */
|
||||||
|
retval = piix4_add_adapter(dev, retval, &piix4_main_adapter);
|
||||||
|
if (retval < 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
/* Check for auxiliary SMBus on some AMD chipsets */
|
||||||
|
if (dev->vendor == PCI_VENDOR_ID_ATI &&
|
||||||
|
dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
|
||||||
|
dev->revision < 0x40) {
|
||||||
|
retval = piix4_setup_aux(dev, id, 0x58);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit piix4_adap_remove(struct i2c_adapter *adap)
|
static void __devexit piix4_adap_remove(struct i2c_adapter *adap)
|
||||||
@ -584,6 +644,11 @@ static void __devexit piix4_remove(struct pci_dev *dev)
|
|||||||
piix4_adap_remove(piix4_main_adapter);
|
piix4_adap_remove(piix4_main_adapter);
|
||||||
piix4_main_adapter = NULL;
|
piix4_main_adapter = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (piix4_aux_adapter) {
|
||||||
|
piix4_adap_remove(piix4_aux_adapter);
|
||||||
|
piix4_aux_adapter = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pci_driver piix4_driver = {
|
static struct pci_driver piix4_driver = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user