diff options
-rw-r--r-- | drivers/usb/dwc3/dwc3-omap.c | 60 | ||||
-rw-r--r-- | include/linux/usb/dwc3-omap.h | 30 |
2 files changed, 90 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 @@ | |||
43 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
44 | #include <linux/platform_device.h> | 44 | #include <linux/platform_device.h> |
45 | #include <linux/platform_data/dwc3-omap.h> | 45 | #include <linux/platform_data/dwc3-omap.h> |
46 | #include <linux/usb/dwc3-omap.h> | ||
46 | #include <linux/pm_runtime.h> | 47 | #include <linux/pm_runtime.h> |
47 | #include <linux/dma-mapping.h> | 48 | #include <linux/dma-mapping.h> |
48 | #include <linux/ioport.h> | 49 | #include <linux/ioport.h> |
@@ -131,6 +132,8 @@ struct dwc3_omap { | |||
131 | u32 dma_status:1; | 132 | u32 dma_status:1; |
132 | }; | 133 | }; |
133 | 134 | ||
135 | struct dwc3_omap *_omap; | ||
136 | |||
134 | static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset) | 137 | static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset) |
135 | { | 138 | { |
136 | return readl(base + offset); | 139 | return readl(base + offset); |
@@ -141,6 +144,57 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value) | |||
141 | writel(value, base + offset); | 144 | writel(value, base + offset); |
142 | } | 145 | } |
143 | 146 | ||
147 | void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status) | ||
148 | { | ||
149 | u32 val; | ||
150 | struct dwc3_omap *omap = _omap; | ||
151 | |||
152 | switch (status) { | ||
153 | case OMAP_DWC3_ID_GROUND: | ||
154 | dev_dbg(omap->dev, "ID GND\n"); | ||
155 | |||
156 | val = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); | ||
157 | val &= ~(USBOTGSS_UTMI_OTG_STATUS_IDDIG | ||
158 | | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID | ||
159 | | USBOTGSS_UTMI_OTG_STATUS_SESSEND); | ||
160 | val |= USBOTGSS_UTMI_OTG_STATUS_SESSVALID | ||
161 | | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT; | ||
162 | dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, val); | ||
163 | break; | ||
164 | |||
165 | case OMAP_DWC3_VBUS_VALID: | ||
166 | dev_dbg(omap->dev, "VBUS Connect\n"); | ||
167 | |||
168 | val = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); | ||
169 | val &= ~USBOTGSS_UTMI_OTG_STATUS_SESSEND; | ||
170 | val |= USBOTGSS_UTMI_OTG_STATUS_IDDIG | ||
171 | | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID | ||
172 | | USBOTGSS_UTMI_OTG_STATUS_SESSVALID | ||
173 | | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT; | ||
174 | dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, val); | ||
175 | break; | ||
176 | |||
177 | case OMAP_DWC3_ID_FLOAT: | ||
178 | case OMAP_DWC3_VBUS_OFF: | ||
179 | dev_dbg(omap->dev, "VBUS Disconnect\n"); | ||
180 | |||
181 | val = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); | ||
182 | val &= ~(USBOTGSS_UTMI_OTG_STATUS_SESSVALID | ||
183 | | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID | ||
184 | | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT); | ||
185 | val |= USBOTGSS_UTMI_OTG_STATUS_SESSEND | ||
186 | | USBOTGSS_UTMI_OTG_STATUS_IDDIG; | ||
187 | dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, val); | ||
188 | break; | ||
189 | |||
190 | default: | ||
191 | dev_dbg(omap->dev, "ID float\n"); | ||
192 | } | ||
193 | |||
194 | return; | ||
195 | } | ||
196 | EXPORT_SYMBOL_GPL(dwc3_omap_mailbox); | ||
197 | |||
144 | static int dwc3_omap_register_phys(struct dwc3_omap *omap) | 198 | static int dwc3_omap_register_phys(struct dwc3_omap *omap) |
145 | { | 199 | { |
146 | struct nop_usb_xceiv_platform_data pdata; | 200 | struct nop_usb_xceiv_platform_data pdata; |
@@ -320,6 +374,12 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
320 | omap->irq = irq; | 374 | omap->irq = irq; |
321 | omap->base = base; | 375 | omap->base = base; |
322 | 376 | ||
377 | /* | ||
378 | * REVISIT if we ever have two instances of the wrapper, we will be | ||
379 | * in big trouble | ||
380 | */ | ||
381 | _omap = omap; | ||
382 | |||
323 | pm_runtime_enable(dev); | 383 | pm_runtime_enable(dev); |
324 | ret = pm_runtime_get_sync(dev); | 384 | ret = pm_runtime_get_sync(dev); |
325 | if (ret < 0) { | 385 | if (ret < 0) { |
diff --git a/include/linux/usb/dwc3-omap.h b/include/linux/usb/dwc3-omap.h new file mode 100644 index 000000000000..51eae14477f7 --- /dev/null +++ b/include/linux/usb/dwc3-omap.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 by Texas Instruments | ||
3 | * | ||
4 | * The Inventra Controller Driver for Linux is free software; you | ||
5 | * can redistribute it and/or modify it under the terms of the GNU | ||
6 | * General Public License version 2 as published by the Free Software | ||
7 | * Foundation. | ||
8 | */ | ||
9 | |||
10 | #ifndef __DWC3_OMAP_H__ | ||
11 | #define __DWC3_OMAP_H__ | ||
12 | |||
13 | enum omap_dwc3_vbus_id_status { | ||
14 | OMAP_DWC3_UNKNOWN = 0, | ||
15 | OMAP_DWC3_ID_GROUND, | ||
16 | OMAP_DWC3_ID_FLOAT, | ||
17 | OMAP_DWC3_VBUS_VALID, | ||
18 | OMAP_DWC3_VBUS_OFF, | ||
19 | }; | ||
20 | |||
21 | #if (defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_DWC3_MODULE)) | ||
22 | extern void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status); | ||
23 | #else | ||
24 | static inline void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status) | ||
25 | { | ||
26 | return; | ||
27 | } | ||
28 | #endif | ||
29 | |||
30 | #endif /* __DWC3_OMAP_H__ */ | ||