aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/imx_udc.h
diff options
context:
space:
mode:
authorDarius Augulis <augulis.darius@gmail.com>2008-11-12 16:38:31 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-07 13:00:11 -0500
commit2a4f136fbdcd89d44d83ed54df2c492a89f5ba9c (patch)
tree5e51cdbbe6024ba35e4fef3809a761f30d272942 /drivers/usb/gadget/imx_udc.h
parent856395d6e137b4e7194972cb7765f3de6a72ba61 (diff)
USB: add imx udc gadget driver
Implementation of USB device driver integrated in Freescale's i.MXL processor. Adds USB device driver for i.MXL. Signed-off-by: Darius Augulis <augulis.darius@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/imx_udc.h')
-rw-r--r--drivers/usb/gadget/imx_udc.h344
1 files changed, 344 insertions, 0 deletions
diff --git a/drivers/usb/gadget/imx_udc.h b/drivers/usb/gadget/imx_udc.h
new file mode 100644
index 000000000000..850076937d8d
--- /dev/null
+++ b/drivers/usb/gadget/imx_udc.h
@@ -0,0 +1,344 @@
1/*
2 * Copyright (C) 2005 Mike Lee(eemike@gmail.com)
3 *
4 * This udc driver is now under testing and code is based on pxa2xx_udc.h
5 * Please use it with your own risk!
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#ifndef __LINUX_USB_GADGET_IMX_H
19#define __LINUX_USB_GADGET_IMX_H
20
21#include <linux/types.h>
22
23/* Helper macros */
24#define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */
25#define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0)
26#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
27#define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0)
28#define IMX_USB_NB_EP 6
29
30/* Driver structures */
31struct imx_request {
32 struct usb_request req;
33 struct list_head queue;
34 unsigned int in_use;
35};
36
37enum ep0_state {
38 EP0_IDLE,
39 EP0_IN_DATA_PHASE,
40 EP0_OUT_DATA_PHASE,
41 EP0_CONFIG,
42 EP0_STALL,
43};
44
45struct imx_ep_struct {
46 struct usb_ep ep;
47 struct imx_udc_struct *imx_usb;
48 struct list_head queue;
49 unsigned char stopped;
50 unsigned char fifosize;
51 unsigned char bEndpointAddress;
52 unsigned char bmAttributes;
53};
54
55struct imx_udc_struct {
56 struct usb_gadget gadget;
57 struct usb_gadget_driver *driver;
58 struct device *dev;
59 struct imx_ep_struct imx_ep[IMX_USB_NB_EP];
60 struct clk *clk;
61 enum ep0_state ep0state;
62 struct resource *res;
63 void __iomem *base;
64 unsigned char set_config;
65 int cfg,
66 intf,
67 alt,
68 usbd_int[7];
69};
70
71/* USB registers */
72#define USB_FRAME (0x00) /* USB frame */
73#define USB_SPEC (0x04) /* USB Spec */
74#define USB_STAT (0x08) /* USB Status */
75#define USB_CTRL (0x0C) /* USB Control */
76#define USB_DADR (0x10) /* USB Desc RAM addr */
77#define USB_DDAT (0x14) /* USB Desc RAM/EP buffer data */
78#define USB_INTR (0x18) /* USB interrupt */
79#define USB_MASK (0x1C) /* USB Mask */
80#define USB_ENAB (0x24) /* USB Enable */
81#define USB_EP_STAT(x) (0x30 + (x*0x30)) /* USB status/control */
82#define USB_EP_INTR(x) (0x34 + (x*0x30)) /* USB interrupt */
83#define USB_EP_MASK(x) (0x38 + (x*0x30)) /* USB mask */
84#define USB_EP_FDAT(x) (0x3C + (x*0x30)) /* USB FIFO data */
85#define USB_EP_FDAT0(x) (0x3C + (x*0x30)) /* USB FIFO data */
86#define USB_EP_FDAT1(x) (0x3D + (x*0x30)) /* USB FIFO data */
87#define USB_EP_FDAT2(x) (0x3E + (x*0x30)) /* USB FIFO data */
88#define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */
89#define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */
90#define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */
91#define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last read frame pointer */
92#define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last write frame pointer */
93#define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */
94#define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */
95#define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */
96/* USB Control Register Bit Fields.*/
97#define CTRL_CMDOVER (1<<6) /* UDC status */
98#define CTRL_CMDERROR (1<<5) /* UDC status */
99#define CTRL_FE_ENA (1<<3) /* Enable Font End logic */
100#define CTRL_UDC_RST (1<<2) /* UDC reset */
101#define CTRL_AFE_ENA (1<<1) /* Analog Font end enable */
102#define CTRL_RESUME (1<<0) /* UDC resume */
103/* USB Status Register Bit Fields.*/
104#define STAT_RST (1<<8)
105#define STAT_SUSP (1<<7)
106#define STAT_CFG (3<<5)
107#define STAT_INTF (3<<3)
108#define STAT_ALTSET (7<<0)
109/* USB Interrupt Status/Mask Registers Bit fields */
110#define INTR_WAKEUP (1<<31) /* Wake up Interrupt */
111#define INTR_MSOF (1<<7) /* Missed Start of Frame */
112#define INTR_SOF (1<<6) /* Start of Frame */
113#define INTR_RESET_STOP (1<<5) /* Reset Signaling stop */
114#define INTR_RESET_START (1<<4) /* Reset Signaling start */
115#define INTR_RESUME (1<<3) /* Suspend to resume */
116#define INTR_SUSPEND (1<<2) /* Active to suspend */
117#define INTR_FRAME_MATCH (1<<1) /* Frame matched */
118#define INTR_CFG_CHG (1<<0) /* Configuration change occurred */
119/* USB Enable Register Bit Fields.*/
120#define ENAB_RST (1<<31) /* Reset USB modules */
121#define ENAB_ENAB (1<<30) /* Enable USB modules*/
122#define ENAB_SUSPEND (1<<29) /* Suspend USB modules */
123#define ENAB_ENDIAN (1<<28) /* Endian of USB modules */
124#define ENAB_PWRMD (1<<0) /* Power mode of USB modules */
125/* USB Descriptor Ram Address Register bit fields */
126#define DADR_CFG (1<<31) /* Configuration */
127#define DADR_BSY (1<<30) /* Busy status */
128#define DADR_DADR (0x1FF) /* Descriptor Ram Address */
129/* USB Descriptor RAM/Endpoint Buffer Data Register bit fields */
130#define DDAT_DDAT (0xFF) /* Descriptor Endpoint Buffer */
131/* USB Endpoint Status Register bit fields */
132#define EPSTAT_BCOUNT (0x7F<<16) /* Endpoint FIFO byte count */
133#define EPSTAT_SIP (1<<8) /* Endpoint setup in progress */
134#define EPSTAT_DIR (1<<7) /* Endpoint transfer direction */
135#define EPSTAT_MAX (3<<5) /* Endpoint Max packet size */
136#define EPSTAT_TYP (3<<3) /* Endpoint type */
137#define EPSTAT_ZLPS (1<<2) /* Send zero length packet */
138#define EPSTAT_FLUSH (1<<1) /* Endpoint FIFO Flush */
139#define EPSTAT_STALL (1<<0) /* Force stall */
140/* USB Endpoint FIFO Status Register bit fields */
141#define FSTAT_FRAME_STAT (0xF<<24) /* Frame status bit [0-3] */
142#define FSTAT_ERR (1<<22) /* FIFO error */
143#define FSTAT_UF (1<<21) /* FIFO underflow */
144#define FSTAT_OF (1<<20) /* FIFO overflow */
145#define FSTAT_FR (1<<19) /* FIFO frame ready */
146#define FSTAT_FULL (1<<18) /* FIFO full */
147#define FSTAT_ALRM (1<<17) /* FIFO alarm */
148#define FSTAT_EMPTY (1<<16) /* FIFO empty */
149/* USB Endpoint FIFO Control Register bit fields */
150#define FCTRL_WFR (1<<29) /* Write frame end */
151/* USB Endpoint Interrupt Status Regsiter bit fields */
152#define EPINTR_FIFO_FULL (1<<8) /* fifo full */
153#define EPINTR_FIFO_EMPTY (1<<7) /* fifo empty */
154#define EPINTR_FIFO_ERROR (1<<6) /* fifo error */
155#define EPINTR_FIFO_HIGH (1<<5) /* fifo high */
156#define EPINTR_FIFO_LOW (1<<4) /* fifo low */
157#define EPINTR_MDEVREQ (1<<3) /* multi Device request */
158#define EPINTR_EOT (1<<2) /* fifo end of transfer */
159#define EPINTR_DEVREQ (1<<1) /* Device request */
160#define EPINTR_EOF (1<<0) /* fifo end of frame */
161
162/* Debug macros */
163#ifdef DEBUG
164
165/* #define DEBUG_REQ */
166/* #define DEBUG_TRX */
167/* #define DEBUG_INIT */
168/* #define DEBUG_EP0 */
169/* #define DEBUG_EPX */
170/* #define DEBUG_IRQ */
171/* #define DEBUG_EPIRQ */
172/* #define DEBUG_DUMP */
173#define DEBUG_ERR
174
175#ifdef DEBUG_REQ
176 #define D_REQ(dev, args...) dev_dbg(dev, ## args)
177#else
178 #define D_REQ(dev, args...) do {} while (0)
179#endif /* DEBUG_REQ */
180
181#ifdef DEBUG_TRX
182 #define D_TRX(dev, args...) dev_dbg(dev, ## args)
183#else
184 #define D_TRX(dev, args...) do {} while (0)
185#endif /* DEBUG_TRX */
186
187#ifdef DEBUG_INIT
188 #define D_INI(dev, args...) dev_dbg(dev, ## args)
189#else
190 #define D_INI(dev, args...) do {} while (0)
191#endif /* DEBUG_INIT */
192
193#ifdef DEBUG_EP0
194 static const char *state_name[] = {
195 "EP0_IDLE",
196 "EP0_IN_DATA_PHASE",
197 "EP0_OUT_DATA_PHASE",
198 "EP0_CONFIG",
199 "EP0_STALL"
200 };
201 #define D_EP0(dev, args...) dev_dbg(dev, ## args)
202#else
203 #define D_EP0(dev, args...) do {} while (0)
204#endif /* DEBUG_EP0 */
205
206#ifdef DEBUG_EPX
207 #define D_EPX(dev, args...) dev_dbg(dev, ## args)
208#else
209 #define D_EPX(dev, args...) do {} while (0)
210#endif /* DEBUG_EP0 */
211
212#ifdef DEBUG_IRQ
213 static void dump_intr(const char *label, int irqreg, struct device *dev)
214 {
215 dev_dbg(dev, "<%s> USB_INTR=[%s%s%s%s%s%s%s%s%s]\n", label,
216 (irqreg & INTR_WAKEUP) ? " wake" : "",
217 (irqreg & INTR_MSOF) ? " msof" : "",
218 (irqreg & INTR_SOF) ? " sof" : "",
219 (irqreg & INTR_RESUME) ? " resume" : "",
220 (irqreg & INTR_SUSPEND) ? " suspend" : "",
221 (irqreg & INTR_RESET_STOP) ? " noreset" : "",
222 (irqreg & INTR_RESET_START) ? " reset" : "",
223 (irqreg & INTR_FRAME_MATCH) ? " fmatch" : "",
224 (irqreg & INTR_CFG_CHG) ? " config" : "");
225 }
226#else
227 #define dump_intr(x, y, z) do {} while (0)
228#endif /* DEBUG_IRQ */
229
230#ifdef DEBUG_EPIRQ
231 static void dump_ep_intr(const char *label, int nr, int irqreg, struct device *dev)
232 {
233 dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr,
234 (irqreg & EPINTR_FIFO_FULL) ? " full" : "",
235 (irqreg & EPINTR_FIFO_EMPTY) ? " fempty" : "",
236 (irqreg & EPINTR_FIFO_ERROR) ? " ferr" : "",
237 (irqreg & EPINTR_FIFO_HIGH) ? " fhigh" : "",
238 (irqreg & EPINTR_FIFO_LOW) ? " flow" : "",
239 (irqreg & EPINTR_MDEVREQ) ? " mreq" : "",
240 (irqreg & EPINTR_EOF) ? " eof" : "",
241 (irqreg & EPINTR_DEVREQ) ? " devreq" : "",
242 (irqreg & EPINTR_EOT) ? " eot" : "");
243 }
244#else
245 #define dump_ep_intr(x, y, z, i) do {} while (0)
246#endif /* DEBUG_IRQ */
247
248#ifdef DEBUG_DUMP
249 static void dump_usb_stat(const char *label, struct imx_udc_struct *imx_usb)
250 {
251 int temp = __raw_readl(imx_usb->base + USB_STAT);
252
253 dev_dbg(imx_usb->dev,
254 "<%s> USB_STAT=[%s%s CFG=%d, INTF=%d, ALTR=%d]\n", label,
255 (temp & STAT_RST) ? " reset" : "",
256 (temp & STAT_SUSP) ? " suspend" : "",
257 (temp & STAT_CFG) >> 5,
258 (temp & STAT_INTF) >> 3,
259 (temp & STAT_ALTSET));
260 }
261
262 static void dump_ep_stat(const char *label, struct imx_ep_struct *imx_ep)
263 {
264 int temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_INTR(EP_NO(imx_ep)));
265
266 dev_dbg(imx_ep->imx_usb->dev,
267 "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
268 (temp & EPINTR_FIFO_FULL) ? " full" : "",
269 (temp & EPINTR_FIFO_EMPTY) ? " fempty" : "",
270 (temp & EPINTR_FIFO_ERROR) ? " ferr" : "",
271 (temp & EPINTR_FIFO_HIGH) ? " fhigh" : "",
272 (temp & EPINTR_FIFO_LOW) ? " flow" : "",
273 (temp & EPINTR_MDEVREQ) ? " mreq" : "",
274 (temp & EPINTR_EOF) ? " eof" : "",
275 (temp & EPINTR_DEVREQ) ? " devreq" : "",
276 (temp & EPINTR_EOT) ? " eot" : "");
277
278 temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
279
280 dev_dbg(imx_ep->imx_usb->dev,
281 "<%s> EP%d_STAT=[%s%s bcount=%d]\n", label, EP_NO(imx_ep),
282 (temp & EPSTAT_SIP) ? " sip" : "",
283 (temp & EPSTAT_STALL) ? " stall" : "",
284 (temp & EPSTAT_BCOUNT) >> 16);
285
286 temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep)));
287
288 dev_dbg(imx_ep->imx_usb->dev,
289 "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
290 (temp & FSTAT_ERR) ? " ferr" : "",
291 (temp & FSTAT_UF) ? " funder" : "",
292 (temp & FSTAT_OF) ? " fover" : "",
293 (temp & FSTAT_FR) ? " fready" : "",
294 (temp & FSTAT_FULL) ? " ffull" : "",
295 (temp & FSTAT_ALRM) ? " falarm" : "",
296 (temp & FSTAT_EMPTY) ? " fempty" : "");
297 }
298
299 static void dump_req(const char *label, struct imx_ep_struct *imx_ep, struct usb_request *req)
300 {
301 int i;
302
303 if (!req || !req->buf) {
304 dev_dbg(imx_ep->imx_usb->dev, "<%s> req or req buf is free\n", label);
305 return;
306 }
307
308 if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
309 || (EP_NO(imx_ep) && EP_DIR(imx_ep))) {
310
311 dev_dbg(imx_ep->imx_usb->dev, "<%s> request dump <", label);
312 for (i = 0; i < req->length; i++)
313 printk("%02x-", *((u8 *)req->buf + i));
314 printk(">\n");
315 }
316 }
317
318#else
319 #define dump_ep_stat(x, y) do {} while (0)
320 #define dump_usb_stat(x, y) do {} while (0)
321 #define dump_req(x, y, z) do {} while (0)
322#endif /* DEBUG_DUMP */
323
324#ifdef DEBUG_ERR
325 #define D_ERR(dev, args...) dev_dbg(dev, ## args)
326#else
327 #define D_ERR(dev, args...) do {} while (0)
328#endif
329
330#else
331 #define D_REQ(dev, args...) do {} while (0)
332 #define D_TRX(dev, args...) do {} while (0)
333 #define D_INI(dev, args...) do {} while (0)
334 #define D_EP0(dev, args...) do {} while (0)
335 #define D_EPX(dev, args...) do {} while (0)
336 #define dump_ep_intr(x, y, z, i) do {} while (0)
337 #define dump_intr(x, y, z) do {} while (0)
338 #define dump_ep_stat(x, y) do {} while (0)
339 #define dump_usb_stat(x, y) do {} while (0)
340 #define dump_req(x, y, z) do {} while (0)
341 #define D_ERR(dev, args...) do {} while (0)
342#endif /* DEBUG */
343
344#endif /* __LINUX_USB_GADGET_IMX_H */