|
@@ -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) {
|