summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2013-01-25 08:30:49 +0530
committerFelipe Balbi <balbi@ti.com>2013-01-25 09:17:09 +0200
commit7e41bba94617b7e4f77d3531a63fbfacdf6842a6 (patch)
treec22c597e17fa0c4e109bb2787a8051079f6334ee /drivers/usb/dwc3
parent6373218da195e9baade9416727720646b3a622aa (diff)
usb: dwc3: omap: Add an API to write to dwc mailbox
Add an API in the omap glue layer to write to the mailbox register which can be used by comparator driver(twl). To pass the detection of the attached device (signified by VBUS, ID) to the dwc3 core, dwc3 core has to write to the mailbox regiter. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index f85ae5e6129d..831b75fa4386 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -43,6 +43,7 @@
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/platform_data/dwc3-omap.h>
+#include <linux/usb/dwc3-omap.h>
#include <linux/pm_runtime.h>
#include <linux/dma-mapping.h>
#include <linux/ioport.h>
@@ -131,6 +132,8 @@ struct dwc3_omap {
u32 dma_status:1;
};
+struct dwc3_omap *_omap;
+
static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset)
{
return readl(base + offset);
@@ -141,6 +144,57 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
writel(value, base + offset);
}
+void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status)
+{
+ u32 val;
+ struct dwc3_omap *omap = _omap;
+
+ switch (status) {
+ case OMAP_DWC3_ID_GROUND:
+ dev_dbg(omap->dev, "ID GND\n");
+
+ val = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS);
+ val &= ~(USBOTGSS_UTMI_OTG_STATUS_IDDIG
+ | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID
+ | USBOTGSS_UTMI_OTG_STATUS_SESSEND);
+ val |= USBOTGSS_UTMI_OTG_STATUS_SESSVALID
+ | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT;
+ dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, val);
+ break;
+
+ case OMAP_DWC3_VBUS_VALID:
+ dev_dbg(omap->dev, "VBUS Connect\n");
+
+ val = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS);
+ val &= ~USBOTGSS_UTMI_OTG_STATUS_SESSEND;
+ val |= USBOTGSS_UTMI_OTG_STATUS_IDDIG
+ | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID
+ | USBOTGSS_UTMI_OTG_STATUS_SESSVALID
+ | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT;
+ dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, val);
+ break;
+
+ case OMAP_DWC3_ID_FLOAT:
+ case OMAP_DWC3_VBUS_OFF:
+ dev_dbg(omap->dev, "VBUS Disconnect\n");
+
+ val = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS);
+ val &= ~(USBOTGSS_UTMI_OTG_STATUS_SESSVALID
+ | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID
+ | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT);
+ val |= USBOTGSS_UTMI_OTG_STATUS_SESSEND
+ | USBOTGSS_UTMI_OTG_STATUS_IDDIG;
+ dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, val);
+ break;
+
+ default:
+ dev_dbg(omap->dev, "ID float\n");
+ }
+
+ return;
+}
+EXPORT_SYMBOL_GPL(dwc3_omap_mailbox);
+
static int dwc3_omap_register_phys(struct dwc3_omap *omap)
{
struct nop_usb_xceiv_platform_data pdata;
@@ -320,6 +374,12 @@ static int dwc3_omap_probe(struct platform_device *pdev)
omap->irq = irq;
omap->base = base;
+ /*
+ * REVISIT if we ever have two instances of the wrapper, we will be
+ * in big trouble
+ */
+ _omap = omap;
+
pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
if (ret < 0) {