From: Jiebing Li <jiebing.li@xxxxxxxxx> ACA (Accessory Charger Adapter) is one kind of USB adapter which is defined in Battery Charging Spec 1.1. This patch implements ACA device detection in transceiver driver. There's no real ACA device yet so the function has not been fully tested. Signed-off-by: Jiebing Li <jiebing.li@xxxxxxxxx> --- drivers/usb/otg/penwell_otg.c | 102 +++++++++++++++++++++++++++++++++++++++ include/linux/usb/penwell_otg.h | 5 ++ 2 files changed, 107 insertions(+), 0 deletions(-) diff --git a/drivers/usb/otg/penwell_otg.c b/drivers/usb/otg/penwell_otg.c index 1c6212e..e26393c 100644 --- a/drivers/usb/otg/penwell_otg.c +++ b/drivers/usb/otg/penwell_otg.c @@ -1045,6 +1045,10 @@ static irqreturn_t otg_irq(int irq, void *_dev) struct intel_mid_otg_xceiv *iotg = &pnw->iotg; int flag = 0; u32 int_sts, int_en, int_mask = 0; + u8 int_vs4_aca = 0; + u8 int_vs5_aca = 0; + u8 int_vs2_aca = 0; + struct iotg_ulpi_access_ops *ops; /* Check VBUS/SRP interrup */ int_sts = readl(pnw->iotg.base + CI_OTGSC); @@ -1100,6 +1104,49 @@ static irqreturn_t otg_irq(int irq, void *_dev) pnw->iotg.base + CI_OTGSC); } + /* ACA device detection */ + ops = &iotg->ulpi_ops; + + ops->read(iotg, ULPI_TI_VS4, &int_vs4_aca); + + if (int_vs4_aca & TI_ACA_DET_EN) { + ops->read(iotg, ULPI_TI_VS5, &int_vs5_aca); + + /* ulpi read will clear related bits according to TI spec*/ + ops->read(iotg, ULPI_TI_VS2_LATCH, &int_vs2_aca); + + /* + * not sure if OTGSC_IDIS can cover this + * when no charger is attached + if (int_vs5_aca & TI_ID_FLOAT_EN) { + iotg->hsm.id = + (int_vs2_aca & TI_ID_FLOAT_STS) ? ID_B : ID_A; + flag = 1; + } + */ + + if (int_vs5_aca & TI_ID_RES_EN) + switch (TI_ID_RARBRC_STS(int_vs2_aca)) { + case TI_ID_RARBRC_A: + iotg->hsm.id = ID_ACA_A; + flag = 1; + break; + case TI_ID_RARBRC_B: + iotg->hsm.id = ID_ACA_B; + flag = 1; + break; + case TI_ID_RARBRC_C: + iotg->hsm.id = ID_ACA_C; + flag = 1; + break; + default: + break; + } + + dev_dbg(pnw->dev, "%s: id change int = %d\n", + __func__, iotg->hsm.id); + } + if (flag) penwell_update_transceiver(); @@ -2449,6 +2496,55 @@ static struct attribute_group debug_dev_attr_group = { .attrs = inputs_attrs, }; +static int penwell_otg_aca_enable(void) +{ + int retval = 0; + struct penwell_otg *pnw = the_transceiver; + + penwell_otg_msic_spi_access(true); + + retval = intel_scu_ipc_update_register(SPI_TI_VS4, + TI_ACA_DET_EN, TI_ACA_DET_EN); + if (retval) + goto done; + + retval = intel_scu_ipc_update_register(SPI_TI_VS5, + TI_ID_FLOAT_EN | TI_ID_RES_EN, + TI_ID_FLOAT_EN | TI_ID_RES_EN); + +done: + penwell_otg_msic_spi_access(false); + + if (retval) + dev_warn(pnw->dev, "Failed to enable ACA device detection\n"); + + return retval; +} + +static int penwell_otg_aca_disable(void) +{ + int retval = 0; + struct penwell_otg *pnw = the_transceiver; + + penwell_otg_msic_spi_access(true); + + retval = intel_scu_ipc_update_register(SPI_TI_VS5, + 0, TI_ID_FLOAT_EN | TI_ID_RES_EN); + if (retval) + goto done; + + retval = intel_scu_ipc_update_register(SPI_TI_VS4, + 0, TI_ACA_DET_EN); + +done: + penwell_otg_msic_spi_access(false); + + if (retval) + dev_warn(pnw->dev, "Failed to disable ACA device detection\n"); + + return retval; +} + static int penwell_otg_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -2546,6 +2642,9 @@ static int penwell_otg_probe(struct pci_dev *pdev, mutex_init(&pnw->msic_mutex); pnw->msic = penwell_otg_check_msic(); + /* enable ACA device detection */ + penwell_otg_aca_enable(); + penwell_otg_phy_enable(1); reset_otg(); @@ -2608,6 +2707,9 @@ static void penwell_otg_remove(struct pci_dev *pdev) { struct penwell_otg *pnw = the_transceiver; + /* ACA device detection disable */ + penwell_otg_aca_disable(); + if (pnw->qwork) { flush_workqueue(pnw->qwork); destroy_workqueue(pnw->qwork); diff --git a/include/linux/usb/penwell_otg.h b/include/linux/usb/penwell_otg.h index 77776ca..f4e8d5b 100644 --- a/include/linux/usb/penwell_otg.h +++ b/include/linux/usb/penwell_otg.h @@ -143,7 +143,12 @@ # define SPIMODE BIT(0) /* MSIC TI implementation for ADP/ACA */ +#define SPI_TI_VS2 0x3B7 +#define SPI_TI_VS2_LATCH 0x3B8 +#define SPI_TI_VS4 0x3BA +#define SPI_TI_VS5 0x3BB #define ULPI_TI_VS2 0x83 +#define ULPI_TI_VS2_LATCH 0x84 # define TI_ID_FLOAT_STS BIT(4) # define TI_ID_RARBRC_STS(d) (((d)>>2)&3) # define TI_ID_RARBRC_STS_MASK (BIT(3) | BIT(2)) -- 1.6.0.6 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html