aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-piix4.c
diff options
context:
space:
mode:
authorAndrew Armenia <andrew@asquaredlabs.com>2012-07-24 08:13:57 -0400
committerJean Delvare <khali@endymion.delvare>2012-07-24 08:13:57 -0400
commit2a2f7404a1946be62290292ca5d6438c4b50567f (patch)
tree79c458c163f378de8704bb7ea7529d3957f39c56 /drivers/i2c/busses/i2c-piix4.c
parente154bf6fbfc167426ee938111a5ffa36bd8541a1 (diff)
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>
Diffstat (limited to 'drivers/i2c/busses/i2c-piix4.c')
-rw-r--r--drivers/i2c/busses/i2c-piix4.c71
1 files changed, 68 insertions, 3 deletions
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 42ed0af10efd..ef511df2c965 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -21,11 +21,12 @@
21 Supports: 21 Supports:
22 Intel PIIX4, 440MX 22 Intel PIIX4, 440MX
23 Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 23 Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
24 ATI IXP200, IXP300, IXP400, SB600, SB700, SB800 24 ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800
25 AMD Hudson-2 25 AMD Hudson-2
26 SMSC Victory66 26 SMSC Victory66
27 27
28 Note: we assume there can only be one device, with one SMBus interface. 28 Note: we assume there can only be one device, with one or more
29 SMBus interfaces.
29*/ 30*/
30 31
31#include <linux/module.h> 32#include <linux/module.h>
@@ -293,6 +294,46 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
293 return piix4_smba; 294 return piix4_smba;
294} 295}
295 296
297static int __devinit piix4_setup_aux(struct pci_dev *PIIX4_dev,
298 const struct pci_device_id *id,
299 unsigned short base_reg_addr)
300{
301 /* Set up auxiliary SMBus controllers found on some
302 * AMD chipsets e.g. SP5100 (SB700 derivative) */
303
304 unsigned short piix4_smba;
305
306 /* Read address of auxiliary SMBus controller */
307 pci_read_config_word(PIIX4_dev, base_reg_addr, &piix4_smba);
308 if ((piix4_smba & 1) == 0) {
309 dev_dbg(&PIIX4_dev->dev,
310 "Auxiliary SMBus controller not enabled\n");
311 return -ENODEV;
312 }
313
314 piix4_smba &= 0xfff0;
315 if (piix4_smba == 0) {
316 dev_dbg(&PIIX4_dev->dev,
317 "Auxiliary SMBus base address uninitialized\n");
318 return -ENODEV;
319 }
320
321 if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
322 return -ENODEV;
323
324 if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
325 dev_err(&PIIX4_dev->dev, "Auxiliary SMBus region 0x%x "
326 "already in use!\n", piix4_smba);
327 return -EBUSY;
328 }
329
330 dev_info(&PIIX4_dev->dev,
331 "Auxiliary SMBus Host Controller at 0x%x\n",
332 piix4_smba);
333
334 return piix4_smba;
335}
336
296static int piix4_transaction(struct i2c_adapter *piix4_adapter) 337static int piix4_transaction(struct i2c_adapter *piix4_adapter)
297{ 338{
298 struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter); 339 struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter);
@@ -497,6 +538,7 @@ static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = {
497MODULE_DEVICE_TABLE (pci, piix4_ids); 538MODULE_DEVICE_TABLE (pci, piix4_ids);
498 539
499static struct i2c_adapter *piix4_main_adapter; 540static struct i2c_adapter *piix4_main_adapter;
541static struct i2c_adapter *piix4_aux_adapter;
500 542
501static int __devinit piix4_add_adapter(struct pci_dev *dev, 543static int __devinit piix4_add_adapter(struct pci_dev *dev,
502 unsigned short smba, 544 unsigned short smba,
@@ -560,10 +602,28 @@ static int __devinit piix4_probe(struct pci_dev *dev,
560 else 602 else
561 retval = piix4_setup(dev, id); 603 retval = piix4_setup(dev, id);
562 604
605 /* If no main SMBus found, give up */
563 if (retval < 0) 606 if (retval < 0)
564 return retval; 607 return retval;
565 608
566 return piix4_add_adapter(dev, retval, &piix4_main_adapter); 609 /* Try to register main SMBus adapter, give up if we can't */
610 retval = piix4_add_adapter(dev, retval, &piix4_main_adapter);
611 if (retval < 0)
612 return retval;
613
614 /* Check for auxiliary SMBus on some AMD chipsets */
615 if (dev->vendor == PCI_VENDOR_ID_ATI &&
616 dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
617 dev->revision < 0x40) {
618 retval = piix4_setup_aux(dev, id, 0x58);
619 if (retval > 0) {
620 /* Try to add the aux adapter if it exists,
621 * piix4_add_adapter will clean up if this fails */
622 piix4_add_adapter(dev, retval, &piix4_aux_adapter);
623 }
624 }
625
626 return 0;
567} 627}
568 628
569static void __devexit piix4_adap_remove(struct i2c_adapter *adap) 629static void __devexit piix4_adap_remove(struct i2c_adapter *adap)
@@ -584,6 +644,11 @@ static void __devexit piix4_remove(struct pci_dev *dev)
584 piix4_adap_remove(piix4_main_adapter); 644 piix4_adap_remove(piix4_main_adapter);
585 piix4_main_adapter = NULL; 645 piix4_main_adapter = NULL;
586 } 646 }
647
648 if (piix4_aux_adapter) {
649 piix4_adap_remove(piix4_aux_adapter);
650 piix4_aux_adapter = NULL;
651 }
587} 652}
588 653
589static struct pci_driver piix4_driver = { 654static struct pci_driver piix4_driver = {