Commit | Line | Data |
---|---|---|
2a4f136f DA |
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) | |
593bef6c DA |
26 | #define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) \ |
27 | ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/ | |
2a4f136f DA |
28 | #define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0) |
29 | #define IMX_USB_NB_EP 6 | |
30 | ||
31 | /* Driver structures */ | |
32 | struct imx_request { | |
33 | struct usb_request req; | |
34 | struct list_head queue; | |
35 | unsigned int in_use; | |
36 | }; | |
37 | ||
38 | enum ep0_state { | |
39 | EP0_IDLE, | |
40 | EP0_IN_DATA_PHASE, | |
41 | EP0_OUT_DATA_PHASE, | |
42 | EP0_CONFIG, | |
43 | EP0_STALL, | |
44 | }; | |
45 | ||
46 | struct imx_ep_struct { | |
47 | struct usb_ep ep; | |
48 | struct imx_udc_struct *imx_usb; | |
49 | struct list_head queue; | |
50 | unsigned char stopped; | |
51 | unsigned char fifosize; | |
52 | unsigned char bEndpointAddress; | |
53 | unsigned char bmAttributes; | |
54 | }; | |
55 | ||
56 | struct imx_udc_struct { | |
57 | struct usb_gadget gadget; | |
58 | struct usb_gadget_driver *driver; | |
59 | struct device *dev; | |
60 | struct imx_ep_struct imx_ep[IMX_USB_NB_EP]; | |
61 | struct clk *clk; | |
b633d28e | 62 | struct timer_list timer; |
2a4f136f DA |
63 | enum ep0_state ep0state; |
64 | struct resource *res; | |
65 | void __iomem *base; | |
66 | unsigned char set_config; | |
67 | int cfg, | |
68 | intf, | |
69 | alt, | |
70 | usbd_int[7]; | |
71 | }; | |
72 | ||
73 | /* USB registers */ | |
74 | #define USB_FRAME (0x00) /* USB frame */ | |
75 | #define USB_SPEC (0x04) /* USB Spec */ | |
76 | #define USB_STAT (0x08) /* USB Status */ | |
77 | #define USB_CTRL (0x0C) /* USB Control */ | |
78 | #define USB_DADR (0x10) /* USB Desc RAM addr */ | |
79 | #define USB_DDAT (0x14) /* USB Desc RAM/EP buffer data */ | |
80 | #define USB_INTR (0x18) /* USB interrupt */ | |
81 | #define USB_MASK (0x1C) /* USB Mask */ | |
82 | #define USB_ENAB (0x24) /* USB Enable */ | |
83 | #define USB_EP_STAT(x) (0x30 + (x*0x30)) /* USB status/control */ | |
84 | #define USB_EP_INTR(x) (0x34 + (x*0x30)) /* USB interrupt */ | |
85 | #define USB_EP_MASK(x) (0x38 + (x*0x30)) /* USB mask */ | |
86 | #define USB_EP_FDAT(x) (0x3C + (x*0x30)) /* USB FIFO data */ | |
87 | #define USB_EP_FDAT0(x) (0x3C + (x*0x30)) /* USB FIFO data */ | |
88 | #define USB_EP_FDAT1(x) (0x3D + (x*0x30)) /* USB FIFO data */ | |
89 | #define USB_EP_FDAT2(x) (0x3E + (x*0x30)) /* USB FIFO data */ | |
90 | #define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */ | |
91 | #define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */ | |
92 | #define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */ | |
593bef6c DA |
93 | #define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last rd f. pointer */ |
94 | #define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last wr f. pointer */ | |
2a4f136f DA |
95 | #define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */ |
96 | #define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */ | |
97 | #define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */ | |
98 | /* USB Control Register Bit Fields.*/ | |
99 | #define CTRL_CMDOVER (1<<6) /* UDC status */ | |
100 | #define CTRL_CMDERROR (1<<5) /* UDC status */ | |
101 | #define CTRL_FE_ENA (1<<3) /* Enable Font End logic */ | |
102 | #define CTRL_UDC_RST (1<<2) /* UDC reset */ | |
103 | #define CTRL_AFE_ENA (1<<1) /* Analog Font end enable */ | |
104 | #define CTRL_RESUME (1<<0) /* UDC resume */ | |
105 | /* USB Status Register Bit Fields.*/ | |
106 | #define STAT_RST (1<<8) | |
107 | #define STAT_SUSP (1<<7) | |
108 | #define STAT_CFG (3<<5) | |
109 | #define STAT_INTF (3<<3) | |
110 | #define STAT_ALTSET (7<<0) | |
111 | /* USB Interrupt Status/Mask Registers Bit fields */ | |
112 | #define INTR_WAKEUP (1<<31) /* Wake up Interrupt */ | |
113 | #define INTR_MSOF (1<<7) /* Missed Start of Frame */ | |
114 | #define INTR_SOF (1<<6) /* Start of Frame */ | |
115 | #define INTR_RESET_STOP (1<<5) /* Reset Signaling stop */ | |
116 | #define INTR_RESET_START (1<<4) /* Reset Signaling start */ | |
117 | #define INTR_RESUME (1<<3) /* Suspend to resume */ | |
118 | #define INTR_SUSPEND (1<<2) /* Active to suspend */ | |
119 | #define INTR_FRAME_MATCH (1<<1) /* Frame matched */ | |
120 | #define INTR_CFG_CHG (1<<0) /* Configuration change occurred */ | |
121 | /* USB Enable Register Bit Fields.*/ | |
122 | #define ENAB_RST (1<<31) /* Reset USB modules */ | |
123 | #define ENAB_ENAB (1<<30) /* Enable USB modules*/ | |
124 | #define ENAB_SUSPEND (1<<29) /* Suspend USB modules */ | |
125 | #define ENAB_ENDIAN (1<<28) /* Endian of USB modules */ | |
126 | #define ENAB_PWRMD (1<<0) /* Power mode of USB modules */ | |
127 | /* USB Descriptor Ram Address Register bit fields */ | |
128 | #define DADR_CFG (1<<31) /* Configuration */ | |
129 | #define DADR_BSY (1<<30) /* Busy status */ | |
130 | #define DADR_DADR (0x1FF) /* Descriptor Ram Address */ | |
131 | /* USB Descriptor RAM/Endpoint Buffer Data Register bit fields */ | |
132 | #define DDAT_DDAT (0xFF) /* Descriptor Endpoint Buffer */ | |
133 | /* USB Endpoint Status Register bit fields */ | |
134 | #define EPSTAT_BCOUNT (0x7F<<16) /* Endpoint FIFO byte count */ | |
135 | #define EPSTAT_SIP (1<<8) /* Endpoint setup in progress */ | |
136 | #define EPSTAT_DIR (1<<7) /* Endpoint transfer direction */ | |
137 | #define EPSTAT_MAX (3<<5) /* Endpoint Max packet size */ | |
138 | #define EPSTAT_TYP (3<<3) /* Endpoint type */ | |
139 | #define EPSTAT_ZLPS (1<<2) /* Send zero length packet */ | |
140 | #define EPSTAT_FLUSH (1<<1) /* Endpoint FIFO Flush */ | |
141 | #define EPSTAT_STALL (1<<0) /* Force stall */ | |
142 | /* USB Endpoint FIFO Status Register bit fields */ | |
143 | #define FSTAT_FRAME_STAT (0xF<<24) /* Frame status bit [0-3] */ | |
144 | #define FSTAT_ERR (1<<22) /* FIFO error */ | |
145 | #define FSTAT_UF (1<<21) /* FIFO underflow */ | |
146 | #define FSTAT_OF (1<<20) /* FIFO overflow */ | |
147 | #define FSTAT_FR (1<<19) /* FIFO frame ready */ | |
148 | #define FSTAT_FULL (1<<18) /* FIFO full */ | |
149 | #define FSTAT_ALRM (1<<17) /* FIFO alarm */ | |
150 | #define FSTAT_EMPTY (1<<16) /* FIFO empty */ | |
151 | /* USB Endpoint FIFO Control Register bit fields */ | |
152 | #define FCTRL_WFR (1<<29) /* Write frame end */ | |
153 | /* USB Endpoint Interrupt Status Regsiter bit fields */ | |
154 | #define EPINTR_FIFO_FULL (1<<8) /* fifo full */ | |
155 | #define EPINTR_FIFO_EMPTY (1<<7) /* fifo empty */ | |
156 | #define EPINTR_FIFO_ERROR (1<<6) /* fifo error */ | |
157 | #define EPINTR_FIFO_HIGH (1<<5) /* fifo high */ | |
158 | #define EPINTR_FIFO_LOW (1<<4) /* fifo low */ | |
159 | #define EPINTR_MDEVREQ (1<<3) /* multi Device request */ | |
160 | #define EPINTR_EOT (1<<2) /* fifo end of transfer */ | |
161 | #define EPINTR_DEVREQ (1<<1) /* Device request */ | |
162 | #define EPINTR_EOF (1<<0) /* fifo end of frame */ | |
163 | ||
164 | /* Debug macros */ | |
165 | #ifdef DEBUG | |
166 | ||
167 | /* #define DEBUG_REQ */ | |
168 | /* #define DEBUG_TRX */ | |
169 | /* #define DEBUG_INIT */ | |
170 | /* #define DEBUG_EP0 */ | |
171 | /* #define DEBUG_EPX */ | |
172 | /* #define DEBUG_IRQ */ | |
173 | /* #define DEBUG_EPIRQ */ | |
174 | /* #define DEBUG_DUMP */ | |
8f182e5d | 175 | /* #define DEBUG_ERR */ |
2a4f136f DA |
176 | |
177 | #ifdef DEBUG_REQ | |
178 | #define D_REQ(dev, args...) dev_dbg(dev, ## args) | |
179 | #else | |
180 | #define D_REQ(dev, args...) do {} while (0) | |
181 | #endif /* DEBUG_REQ */ | |
182 | ||
183 | #ifdef DEBUG_TRX | |
184 | #define D_TRX(dev, args...) dev_dbg(dev, ## args) | |
185 | #else | |
186 | #define D_TRX(dev, args...) do {} while (0) | |
187 | #endif /* DEBUG_TRX */ | |
188 | ||
189 | #ifdef DEBUG_INIT | |
190 | #define D_INI(dev, args...) dev_dbg(dev, ## args) | |
191 | #else | |
192 | #define D_INI(dev, args...) do {} while (0) | |
193 | #endif /* DEBUG_INIT */ | |
194 | ||
195 | #ifdef DEBUG_EP0 | |
196 | static const char *state_name[] = { | |
197 | "EP0_IDLE", | |
198 | "EP0_IN_DATA_PHASE", | |
199 | "EP0_OUT_DATA_PHASE", | |
200 | "EP0_CONFIG", | |
201 | "EP0_STALL" | |
202 | }; | |
203 | #define D_EP0(dev, args...) dev_dbg(dev, ## args) | |
204 | #else | |
205 | #define D_EP0(dev, args...) do {} while (0) | |
206 | #endif /* DEBUG_EP0 */ | |
207 | ||
208 | #ifdef DEBUG_EPX | |
209 | #define D_EPX(dev, args...) dev_dbg(dev, ## args) | |
210 | #else | |
211 | #define D_EPX(dev, args...) do {} while (0) | |
212 | #endif /* DEBUG_EP0 */ | |
213 | ||
214 | #ifdef DEBUG_IRQ | |
215 | static void dump_intr(const char *label, int irqreg, struct device *dev) | |
216 | { | |
217 | dev_dbg(dev, "<%s> USB_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, | |
218 | (irqreg & INTR_WAKEUP) ? " wake" : "", | |
219 | (irqreg & INTR_MSOF) ? " msof" : "", | |
220 | (irqreg & INTR_SOF) ? " sof" : "", | |
221 | (irqreg & INTR_RESUME) ? " resume" : "", | |
222 | (irqreg & INTR_SUSPEND) ? " suspend" : "", | |
223 | (irqreg & INTR_RESET_STOP) ? " noreset" : "", | |
224 | (irqreg & INTR_RESET_START) ? " reset" : "", | |
225 | (irqreg & INTR_FRAME_MATCH) ? " fmatch" : "", | |
226 | (irqreg & INTR_CFG_CHG) ? " config" : ""); | |
227 | } | |
228 | #else | |
229 | #define dump_intr(x, y, z) do {} while (0) | |
230 | #endif /* DEBUG_IRQ */ | |
231 | ||
232 | #ifdef DEBUG_EPIRQ | |
593bef6c DA |
233 | static void dump_ep_intr(const char *label, int nr, int irqreg, |
234 | struct device *dev) | |
2a4f136f DA |
235 | { |
236 | dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr, | |
237 | (irqreg & EPINTR_FIFO_FULL) ? " full" : "", | |
238 | (irqreg & EPINTR_FIFO_EMPTY) ? " fempty" : "", | |
239 | (irqreg & EPINTR_FIFO_ERROR) ? " ferr" : "", | |
240 | (irqreg & EPINTR_FIFO_HIGH) ? " fhigh" : "", | |
241 | (irqreg & EPINTR_FIFO_LOW) ? " flow" : "", | |
242 | (irqreg & EPINTR_MDEVREQ) ? " mreq" : "", | |
243 | (irqreg & EPINTR_EOF) ? " eof" : "", | |
244 | (irqreg & EPINTR_DEVREQ) ? " devreq" : "", | |
245 | (irqreg & EPINTR_EOT) ? " eot" : ""); | |
246 | } | |
247 | #else | |
248 | #define dump_ep_intr(x, y, z, i) do {} while (0) | |
249 | #endif /* DEBUG_IRQ */ | |
250 | ||
251 | #ifdef DEBUG_DUMP | |
593bef6c DA |
252 | static void dump_usb_stat(const char *label, |
253 | struct imx_udc_struct *imx_usb) | |
2a4f136f DA |
254 | { |
255 | int temp = __raw_readl(imx_usb->base + USB_STAT); | |
256 | ||
257 | dev_dbg(imx_usb->dev, | |
258 | "<%s> USB_STAT=[%s%s CFG=%d, INTF=%d, ALTR=%d]\n", label, | |
259 | (temp & STAT_RST) ? " reset" : "", | |
260 | (temp & STAT_SUSP) ? " suspend" : "", | |
261 | (temp & STAT_CFG) >> 5, | |
262 | (temp & STAT_INTF) >> 3, | |
263 | (temp & STAT_ALTSET)); | |
264 | } | |
265 | ||
593bef6c DA |
266 | static void dump_ep_stat(const char *label, |
267 | struct imx_ep_struct *imx_ep) | |
2a4f136f | 268 | { |
593bef6c DA |
269 | int temp = __raw_readl(imx_ep->imx_usb->base |
270 | + USB_EP_INTR(EP_NO(imx_ep))); | |
2a4f136f DA |
271 | |
272 | dev_dbg(imx_ep->imx_usb->dev, | |
593bef6c DA |
273 | "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", |
274 | label, EP_NO(imx_ep), | |
2a4f136f DA |
275 | (temp & EPINTR_FIFO_FULL) ? " full" : "", |
276 | (temp & EPINTR_FIFO_EMPTY) ? " fempty" : "", | |
277 | (temp & EPINTR_FIFO_ERROR) ? " ferr" : "", | |
278 | (temp & EPINTR_FIFO_HIGH) ? " fhigh" : "", | |
279 | (temp & EPINTR_FIFO_LOW) ? " flow" : "", | |
280 | (temp & EPINTR_MDEVREQ) ? " mreq" : "", | |
281 | (temp & EPINTR_EOF) ? " eof" : "", | |
282 | (temp & EPINTR_DEVREQ) ? " devreq" : "", | |
283 | (temp & EPINTR_EOT) ? " eot" : ""); | |
284 | ||
593bef6c DA |
285 | temp = __raw_readl(imx_ep->imx_usb->base |
286 | + USB_EP_STAT(EP_NO(imx_ep))); | |
2a4f136f DA |
287 | |
288 | dev_dbg(imx_ep->imx_usb->dev, | |
593bef6c DA |
289 | "<%s> EP%d_STAT=[%s%s bcount=%d]\n", |
290 | label, EP_NO(imx_ep), | |
2a4f136f DA |
291 | (temp & EPSTAT_SIP) ? " sip" : "", |
292 | (temp & EPSTAT_STALL) ? " stall" : "", | |
293 | (temp & EPSTAT_BCOUNT) >> 16); | |
294 | ||
593bef6c DA |
295 | temp = __raw_readl(imx_ep->imx_usb->base |
296 | + USB_EP_FSTAT(EP_NO(imx_ep))); | |
2a4f136f DA |
297 | |
298 | dev_dbg(imx_ep->imx_usb->dev, | |
593bef6c DA |
299 | "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", |
300 | label, EP_NO(imx_ep), | |
2a4f136f DA |
301 | (temp & FSTAT_ERR) ? " ferr" : "", |
302 | (temp & FSTAT_UF) ? " funder" : "", | |
303 | (temp & FSTAT_OF) ? " fover" : "", | |
304 | (temp & FSTAT_FR) ? " fready" : "", | |
305 | (temp & FSTAT_FULL) ? " ffull" : "", | |
306 | (temp & FSTAT_ALRM) ? " falarm" : "", | |
307 | (temp & FSTAT_EMPTY) ? " fempty" : ""); | |
308 | } | |
309 | ||
593bef6c DA |
310 | static void dump_req(const char *label, struct imx_ep_struct *imx_ep, |
311 | struct usb_request *req) | |
2a4f136f DA |
312 | { |
313 | int i; | |
314 | ||
315 | if (!req || !req->buf) { | |
593bef6c DA |
316 | dev_dbg(imx_ep->imx_usb->dev, |
317 | "<%s> req or req buf is free\n", label); | |
2a4f136f DA |
318 | return; |
319 | } | |
320 | ||
593bef6c DA |
321 | if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state |
322 | == EP0_IN_DATA_PHASE) | |
2a4f136f DA |
323 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) { |
324 | ||
593bef6c DA |
325 | dev_dbg(imx_ep->imx_usb->dev, |
326 | "<%s> request dump <", label); | |
2a4f136f DA |
327 | for (i = 0; i < req->length; i++) |
328 | printk("%02x-", *((u8 *)req->buf + i)); | |
329 | printk(">\n"); | |
330 | } | |
331 | } | |
332 | ||
333 | #else | |
334 | #define dump_ep_stat(x, y) do {} while (0) | |
335 | #define dump_usb_stat(x, y) do {} while (0) | |
336 | #define dump_req(x, y, z) do {} while (0) | |
337 | #endif /* DEBUG_DUMP */ | |
338 | ||
339 | #ifdef DEBUG_ERR | |
340 | #define D_ERR(dev, args...) dev_dbg(dev, ## args) | |
341 | #else | |
342 | #define D_ERR(dev, args...) do {} while (0) | |
343 | #endif | |
344 | ||
345 | #else | |
346 | #define D_REQ(dev, args...) do {} while (0) | |
347 | #define D_TRX(dev, args...) do {} while (0) | |
348 | #define D_INI(dev, args...) do {} while (0) | |
349 | #define D_EP0(dev, args...) do {} while (0) | |
350 | #define D_EPX(dev, args...) do {} while (0) | |
351 | #define dump_ep_intr(x, y, z, i) do {} while (0) | |
352 | #define dump_intr(x, y, z) do {} while (0) | |
353 | #define dump_ep_stat(x, y) do {} while (0) | |
354 | #define dump_usb_stat(x, y) do {} while (0) | |
355 | #define dump_req(x, y, z) do {} while (0) | |
356 | #define D_ERR(dev, args...) do {} while (0) | |
357 | #endif /* DEBUG */ | |
358 | ||
359 | #endif /* __LINUX_USB_GADGET_IMX_H */ |