This patch enables ACA device detection on Intel MID platform. There's no real ACA device yet so it has not been fully tested. Signed-off-by: JiebingLi <jiebing.li@xxxxxxxxx> --- drivers/usb/otg/penwell_otg.c | 96 +++++++++++++++++++++++++++++++++++++++ include/linux/usb/penwell_otg.h | 5 ++ 2 files changed, 101 insertions(+), 0 deletions(-) diff --git a/drivers/usb/otg/penwell_otg.c b/drivers/usb/otg/penwell_otg.c index 3b8fa77..869e1ae 100644 --- a/drivers/usb/otg/penwell_otg.c +++ b/drivers/usb/otg/penwell_otg.c @@ -1190,6 +1190,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); @@ -1245,6 +1249,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 these 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(); @@ -2593,6 +2640,49 @@ static struct attribute_group debug_dev_attr_group = { .attrs = inputs_attrs, }; +static int penwell_otg_aca_enable(void) +{ + int retval = 0; + + 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) + return retval; + + 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); + if (retval) + return retval; + + penwell_otg_msic_spi_access(false); + + return 0; +} + +static int penwell_otg_aca_disable(void) +{ + int retval = 0; + + 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) + return retval; + + retval = intel_scu_ipc_update_register(SPI_TI_VS4, + 0, TI_ACA_DET_EN); + if (retval) + return retval; + + penwell_otg_msic_spi_access(false); + + return 0; +} + static int penwell_otg_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -2703,6 +2793,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(); @@ -2765,6 +2858,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 f4284d0..73ce4b2 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.3 -- 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 -- 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