diff options
author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2009-05-20 12:37:56 +0000 |
---|---|---|
committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2009-05-20 12:37:56 +0000 |
commit | 8bcb4a69715f04886b669d154f58bb2cc38ffd24 (patch) | |
tree | d54650f0fdd90acbdd00a5bf9c6d83c8c01b67ea | |
parent | e71c67f3407598302a8b554fa83ea4ca3cba7152 (diff) | |
download | rockbox-8bcb4a69715f04886b669d154f58bb2cc38ffd24.tar.gz rockbox-8bcb4a69715f04886b669d154f58bb2cc38ffd24.zip |
Fix Ingenic Jz4740 USB driver (USB IN <-> OUT) and some whitespace cleaning
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20996 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | 244 |
1 files changed, 122 insertions, 122 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c index 93350e3281..e519efc4ab 100644 --- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | |||
@@ -74,12 +74,13 @@ struct usb_endpoint | |||
74 | static unsigned char ep0_rx_buf[64]; | 74 | static unsigned char ep0_rx_buf[64]; |
75 | static unsigned char ep0state = USB_EP0_IDLE; | 75 | static unsigned char ep0state = USB_EP0_IDLE; |
76 | static struct usb_endpoint endpoints[] = | 76 | static struct usb_endpoint endpoints[] = |
77 | {/* buf length sent busy type use_dma wait fifo_addr fifo_size */ | 77 | { |
78 | {&ep0_rx_buf, 0, {0}, false, ep_control, false, false, USB_FIFO_EP0, 64 }, | 78 | /* buf length sent busy type use_dma wait fifo_addr fifo_size */ |
79 | {NULL, 0, {0}, false, ep_control, false, false, USB_FIFO_EP0, 64 }, | 79 | {NULL, 0, {0}, false, ep_control, false, false, USB_FIFO_EP0, 64 }, |
80 | {NULL, 0, {0}, false, ep_interrupt, false, false, USB_FIFO_EP1, 64 }, | 80 | {&ep0_rx_buf, 0, {0}, false, ep_control, false, false, USB_FIFO_EP0, 64 }, |
81 | {NULL, 0, {0}, false, ep_bulk, false, false, USB_FIFO_EP1, 512}, | 81 | {NULL, 0, {0}, false, ep_bulk, false, false, USB_FIFO_EP1, 512}, |
82 | {NULL, 0, {0}, false, ep_bulk, false, false, USB_FIFO_EP2, 512} | 82 | {NULL, 0, {0}, false, ep_bulk, false, false, USB_FIFO_EP1, 512}, |
83 | {NULL, 0, {0}, false, ep_interrupt, false, false, USB_FIFO_EP2, 64 } | ||
83 | }; | 84 | }; |
84 | static struct wakeup ep_wkup[TOTAL_EP()]; | 85 | static struct wakeup ep_wkup[TOTAL_EP()]; |
85 | 86 | ||
@@ -91,19 +92,19 @@ static inline void select_endpoint(int ep) | |||
91 | static void readFIFO(struct usb_endpoint *ep, unsigned int size) | 92 | static void readFIFO(struct usb_endpoint *ep, unsigned int size) |
92 | { | 93 | { |
93 | logf("readFIFO(EP%d, %d)", EP_NUMBER2(ep), size); | 94 | logf("readFIFO(EP%d, %d)", EP_NUMBER2(ep), size); |
94 | 95 | ||
95 | register unsigned char *ptr = (unsigned char*)EP_PTR(ep); | 96 | register unsigned char *ptr = (unsigned char*)EP_PTR(ep); |
96 | register unsigned int *ptr32 = (unsigned int*)ptr; | 97 | register unsigned int *ptr32 = (unsigned int*)ptr; |
97 | register unsigned int s = size >> 2; | 98 | register unsigned int s = size >> 2; |
98 | register unsigned int x; | 99 | register unsigned int x; |
99 | 100 | ||
100 | if(size > 0) | 101 | if(size > 0) |
101 | { | 102 | { |
102 | if( ((unsigned int)ptr & 3) == 0 ) | 103 | if( ((unsigned int)ptr & 3) == 0 ) |
103 | { | 104 | { |
104 | while(s--) | 105 | while(s--) |
105 | *ptr32++ = REG32(ep->fifo_addr); | 106 | *ptr32++ = REG32(ep->fifo_addr); |
106 | 107 | ||
107 | ptr = (unsigned char*)ptr32; | 108 | ptr = (unsigned char*)ptr32; |
108 | } | 109 | } |
109 | else | 110 | else |
@@ -117,7 +118,7 @@ static void readFIFO(struct usb_endpoint *ep, unsigned int size) | |||
117 | *ptr++ = (x >> 24) & 0xFF; | 118 | *ptr++ = (x >> 24) & 0xFF; |
118 | } | 119 | } |
119 | } | 120 | } |
120 | 121 | ||
121 | s = size & 3; | 122 | s = size & 3; |
122 | while(s--) | 123 | while(s--) |
123 | *ptr++ = REG8(ep->fifo_addr); | 124 | *ptr++ = REG8(ep->fifo_addr); |
@@ -127,7 +128,7 @@ static void readFIFO(struct usb_endpoint *ep, unsigned int size) | |||
127 | static void writeFIFO(struct usb_endpoint *ep, unsigned int size) | 128 | static void writeFIFO(struct usb_endpoint *ep, unsigned int size) |
128 | { | 129 | { |
129 | logf("writeFIFO(EP%d, %d)", EP_NUMBER2(ep), size); | 130 | logf("writeFIFO(EP%d, %d)", EP_NUMBER2(ep), size); |
130 | 131 | ||
131 | register unsigned int *d32 = (unsigned int *)EP_PTR(ep); | 132 | register unsigned int *d32 = (unsigned int *)EP_PTR(ep); |
132 | register unsigned char *d8 = (unsigned char *)EP_PTR(ep); | 133 | register unsigned char *d8 = (unsigned char *)EP_PTR(ep); |
133 | register unsigned int s; | 134 | register unsigned int s; |
@@ -145,7 +146,7 @@ static void writeFIFO(struct usb_endpoint *ep, unsigned int size) | |||
145 | s = size >> 2; | 146 | s = size >> 2; |
146 | while (s--) | 147 | while (s--) |
147 | REG32(ep->fifo_addr) = *d32++; | 148 | REG32(ep->fifo_addr) = *d32++; |
148 | 149 | ||
149 | if( (s = size & 3) ) | 150 | if( (s = size & 3) ) |
150 | { | 151 | { |
151 | d8 = (unsigned char *)d32; | 152 | d8 = (unsigned char *)d32; |
@@ -164,7 +165,7 @@ static void flushFIFO(struct usb_endpoint *ep) | |||
164 | { | 165 | { |
165 | case ep_control: | 166 | case ep_control: |
166 | break; | 167 | break; |
167 | 168 | ||
168 | case ep_bulk: | 169 | case ep_bulk: |
169 | case ep_interrupt: | 170 | case ep_interrupt: |
170 | if(EP_IS_IN(ep)) | 171 | if(EP_IS_IN(ep)) |
@@ -177,34 +178,34 @@ static void flushFIFO(struct usb_endpoint *ep) | |||
177 | 178 | ||
178 | static void EP0_send(void) | 179 | static void EP0_send(void) |
179 | { | 180 | { |
180 | struct usb_endpoint* ep = &endpoints[1]; | 181 | struct usb_endpoint* ep = &endpoints[0]; |
181 | unsigned int length; | 182 | unsigned int length; |
182 | unsigned char csr0; | 183 | unsigned char csr0; |
183 | 184 | ||
184 | select_endpoint(0); | 185 | select_endpoint(0); |
185 | csr0 = REG_USB_REG_CSR0; | 186 | csr0 = REG_USB_REG_CSR0; |
186 | 187 | ||
187 | if(ep->length == 0) | 188 | if(ep->length == 0) |
188 | { | 189 | { |
189 | //REG_USB_REG_CSR0 = (csr0 | USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND); | 190 | //REG_USB_REG_CSR0 = (csr0 | USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND); |
190 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_SVDOUTPKTRDY); | 191 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_SVDOUTPKTRDY); |
191 | return; | 192 | return; |
192 | } | 193 | } |
193 | 194 | ||
194 | if(ep->sent == 0) | 195 | if(ep->sent == 0) |
195 | length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size); | 196 | length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size); |
196 | else | 197 | else |
197 | length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size); | 198 | length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size); |
198 | 199 | ||
199 | writeFIFO(ep, length); | 200 | writeFIFO(ep, length); |
200 | ep->sent += length; | 201 | ep->sent += length; |
201 | 202 | ||
202 | if(ep->sent >= ep->length) | 203 | if(ep->sent >= ep->length) |
203 | { | 204 | { |
204 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */ | 205 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */ |
205 | ep0state = USB_EP0_IDLE; | 206 | ep0state = USB_EP0_IDLE; |
206 | if(ep->wait) | 207 | if(ep->wait) |
207 | wakeup_signal(&ep_wkup[1]); | 208 | wakeup_signal(&ep_wkup[0]); |
208 | } | 209 | } |
209 | else | 210 | else |
210 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_INPKTRDY); | 211 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_INPKTRDY); |
@@ -213,9 +214,9 @@ static void EP0_send(void) | |||
213 | static void EP0_handler(void) | 214 | static void EP0_handler(void) |
214 | { | 215 | { |
215 | logf("EP0_handler"); | 216 | logf("EP0_handler"); |
216 | 217 | ||
217 | unsigned char csr0; | 218 | unsigned char csr0; |
218 | 219 | ||
219 | /* Read CSR0 */ | 220 | /* Read CSR0 */ |
220 | select_endpoint(0); | 221 | select_endpoint(0); |
221 | csr0 = REG_USB_REG_CSR0; | 222 | csr0 = REG_USB_REG_CSR0; |
@@ -241,17 +242,17 @@ static void EP0_handler(void) | |||
241 | ep0state = USB_EP0_IDLE; | 242 | ep0state = USB_EP0_IDLE; |
242 | return; | 243 | return; |
243 | } | 244 | } |
244 | 245 | ||
245 | /* Call relevant routines for endpoint 0 state */ | 246 | /* Call relevant routines for endpoint 0 state */ |
246 | if(ep0state == USB_EP0_IDLE) | 247 | if(ep0state == USB_EP0_IDLE) |
247 | { | 248 | { |
248 | if(csr0 & USB_CSR0_OUTPKTRDY) /* There is a packet in the fifo */ | 249 | if(csr0 & USB_CSR0_OUTPKTRDY) /* There is a packet in the fifo */ |
249 | { | 250 | { |
250 | readFIFO(&endpoints[0], REG_USB_REG_COUNT0); | 251 | readFIFO(&endpoints[1], REG_USB_REG_COUNT0); |
251 | REG_USB_REG_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */ | 252 | REG_USB_REG_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */ |
252 | usb_core_control_request((struct usb_ctrlrequest*)endpoints[0].buf); | 253 | usb_core_control_request((struct usb_ctrlrequest*)endpoints[1].buf); |
253 | if(endpoints[0].wait) | 254 | if(endpoints[1].wait) |
254 | wakeup_signal(&ep_wkup[0]); | 255 | wakeup_signal(&ep_wkup[1]); |
255 | } | 256 | } |
256 | } | 257 | } |
257 | else if(ep0state == USB_EP0_TX) | 258 | else if(ep0state == USB_EP0_TX) |
@@ -260,47 +261,47 @@ static void EP0_handler(void) | |||
260 | 261 | ||
261 | static void EPIN_handler(unsigned int endpoint) | 262 | static void EPIN_handler(unsigned int endpoint) |
262 | { | 263 | { |
263 | struct usb_endpoint* ep = &endpoints[endpoint*2+1]; | 264 | struct usb_endpoint* ep = &endpoints[endpoint*2]; |
264 | unsigned int length, csr; | 265 | unsigned int length, csr; |
265 | 266 | ||
266 | select_endpoint(endpoint); | 267 | select_endpoint(endpoint); |
267 | csr = REG_USB_REG_INCSR; | 268 | csr = REG_USB_REG_INCSR; |
268 | logf("EPIN_handler(%d): 0x%x", endpoint, csr); | 269 | logf("EPIN_handler(%d): 0x%x", endpoint, csr); |
269 | 270 | ||
270 | if(!ep->busy) | 271 | if(!ep->busy) |
271 | return; | 272 | return; |
272 | 273 | ||
273 | if(csr & USB_INCSR_SENTSTALL) | 274 | if(csr & USB_INCSR_SENTSTALL) |
274 | { | 275 | { |
275 | REG_USB_REG_INCSR = csr & ~USB_INCSR_SENTSTALL; | 276 | REG_USB_REG_INCSR = csr & ~USB_INCSR_SENTSTALL; |
276 | return; | 277 | return; |
277 | } | 278 | } |
278 | 279 | ||
279 | if(ep->use_dma) | 280 | if(ep->use_dma) |
280 | return; | 281 | return; |
281 | 282 | ||
282 | if(csr & USB_INCSR_FFNOTEMPT) | 283 | if(csr & USB_INCSR_FFNOTEMPT) |
283 | { | 284 | { |
284 | logf("FIFO is not empty! 0x%x", csr); | 285 | logf("FIFO is not empty! 0x%x", csr); |
285 | return; | 286 | return; |
286 | } | 287 | } |
287 | 288 | ||
288 | logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length); | 289 | logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length); |
289 | 290 | ||
290 | if(ep->sent == 0) | 291 | if(ep->sent == 0) |
291 | length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size); | 292 | length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size); |
292 | else | 293 | else |
293 | length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size); | 294 | length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size); |
294 | 295 | ||
295 | writeFIFO(ep, length); | 296 | writeFIFO(ep, length); |
296 | REG_USB_REG_INCSR = csr | USB_INCSR_INPKTRDY; | 297 | REG_USB_REG_INCSR = csr | USB_INCSR_INPKTRDY; |
297 | ep->sent += length; | 298 | ep->sent += length; |
298 | 299 | ||
299 | if(ep->sent >= ep->length) | 300 | if(ep->sent >= ep->length) |
300 | { | 301 | { |
301 | usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent); | 302 | usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent); |
302 | if(ep->wait) | 303 | if(ep->wait) |
303 | wakeup_signal(&ep_wkup[endpoint*2+1]); | 304 | wakeup_signal(&ep_wkup[endpoint*2]); |
304 | logf("sent complete"); | 305 | logf("sent complete"); |
305 | ep->sent = 0; | 306 | ep->sent = 0; |
306 | ep->length = 0; | 307 | ep->length = 0; |
@@ -311,12 +312,12 @@ static void EPIN_handler(unsigned int endpoint) | |||
311 | 312 | ||
312 | static void EPOUT_handler(unsigned int endpoint) | 313 | static void EPOUT_handler(unsigned int endpoint) |
313 | { | 314 | { |
314 | struct usb_endpoint* ep = &endpoints[endpoint*2]; | 315 | struct usb_endpoint* ep = &endpoints[endpoint*2+1]; |
315 | unsigned int size, csr; | 316 | unsigned int size, csr; |
316 | 317 | ||
317 | if(!ep->busy) | 318 | if(!ep->busy) |
318 | return; | 319 | return; |
319 | 320 | ||
320 | select_endpoint(endpoint); | 321 | select_endpoint(endpoint); |
321 | while((csr = REG_USB_REG_OUTCSR) & (USB_OUTCSR_SENTSTALL|USB_OUTCSR_OUTPKTRDY)) | 322 | while((csr = REG_USB_REG_OUTCSR) & (USB_OUTCSR_SENTSTALL|USB_OUTCSR_OUTPKTRDY)) |
322 | { | 323 | { |
@@ -328,29 +329,29 @@ static void EPOUT_handler(unsigned int endpoint) | |||
328 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL; | 329 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL; |
329 | return; | 330 | return; |
330 | } | 331 | } |
331 | 332 | ||
332 | if(ep->use_dma) | 333 | if(ep->use_dma) |
333 | return; | 334 | return; |
334 | 335 | ||
335 | if(csr & USB_OUTCSR_OUTPKTRDY) /* There is a packet in the fifo */ | 336 | if(csr & USB_OUTCSR_OUTPKTRDY) /* There is a packet in the fifo */ |
336 | { | 337 | { |
337 | size = REG_USB_REG_OUTCOUNT; | 338 | size = REG_USB_REG_OUTCOUNT; |
338 | 339 | ||
339 | readFIFO(ep, size); | 340 | readFIFO(ep, size); |
340 | ep->received += size; | 341 | ep->received += size; |
341 | 342 | ||
342 | /*if(csr & USB_OUTCSR_FFFULL) | 343 | /*if(csr & USB_OUTCSR_FFFULL) |
343 | csr &= ~USB_OUTCSR_FFFULL;*/ | 344 | csr &= ~USB_OUTCSR_FFFULL;*/ |
344 | 345 | ||
345 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY; | 346 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY; |
346 | 347 | ||
347 | logf("received: %d max length: %d", ep->received, ep->length); | 348 | logf("received: %d max length: %d", ep->received, ep->length); |
348 | 349 | ||
349 | if(size < ep->fifo_size || ep->received >= ep->length) | 350 | if(size < ep->fifo_size || ep->received >= ep->length) |
350 | { | 351 | { |
351 | usb_core_transfer_complete(endpoint, USB_DIR_OUT, 0, ep->received); | 352 | usb_core_transfer_complete(endpoint, USB_DIR_OUT, 0, ep->received); |
352 | if(ep->wait) | 353 | if(ep->wait) |
353 | wakeup_signal(&ep_wkup[endpoint*2]); | 354 | wakeup_signal(&ep_wkup[endpoint*2+1]); |
354 | logf("receive transfer_complete"); | 355 | logf("receive transfer_complete"); |
355 | ep->received = 0; | 356 | ep->received = 0; |
356 | ep->length = 0; | 357 | ep->length = 0; |
@@ -370,22 +371,22 @@ static void EPDMA_handler(int number) | |||
370 | endpoint = (REG_USB_REG_CNTL1 >> 4) & 0xF; | 371 | endpoint = (REG_USB_REG_CNTL1 >> 4) & 0xF; |
371 | else if(number == USB_INTR_DMA_BULKOUT) | 372 | else if(number == USB_INTR_DMA_BULKOUT) |
372 | endpoint = (REG_USB_REG_CNTL2 >> 4) & 0xF; | 373 | endpoint = (REG_USB_REG_CNTL2 >> 4) & 0xF; |
373 | 374 | ||
374 | struct usb_endpoint* ep = &endpoints[endpoint]; | 375 | struct usb_endpoint* ep = &endpoints[endpoint]; |
375 | logf("DMA_BULK%d %d", number, endpoint); | 376 | logf("DMA_BULK%d %d", number, endpoint); |
376 | 377 | ||
377 | if(number == USB_INTR_DMA_BULKIN) | 378 | if(number == USB_INTR_DMA_BULKIN) |
378 | size = (unsigned int)ep->buf - REG_USB_REG_ADDR1; | 379 | size = (unsigned int)ep->buf - REG_USB_REG_ADDR1; |
379 | else if(number == USB_INTR_DMA_BULKOUT) | 380 | else if(number == USB_INTR_DMA_BULKOUT) |
380 | size = (unsigned int)ep->buf - REG_USB_REG_ADDR2; | 381 | size = (unsigned int)ep->buf - REG_USB_REG_ADDR2; |
381 | 382 | ||
382 | if(number == USB_INTR_DMA_BULKOUT) | 383 | if(number == USB_INTR_DMA_BULKOUT) |
383 | { | 384 | { |
384 | /* Disable DMA */ | 385 | /* Disable DMA */ |
385 | REG_USB_REG_CNTL2 = 0; | 386 | REG_USB_REG_CNTL2 = 0; |
386 | 387 | ||
387 | __dcache_invalidate_all(); | 388 | __dcache_invalidate_all(); |
388 | 389 | ||
389 | select_endpoint(endpoint); | 390 | select_endpoint(endpoint); |
390 | /* Read out last packet manually */ | 391 | /* Read out last packet manually */ |
391 | unsigned int lpack_size = REG_USB_REG_OUTCOUNT; | 392 | unsigned int lpack_size = REG_USB_REG_OUTCOUNT; |
@@ -399,10 +400,10 @@ static void EPDMA_handler(int number) | |||
399 | else if(number == USB_INTR_DMA_BULKIN && size % ep->fifo_size) | 400 | else if(number == USB_INTR_DMA_BULKIN && size % ep->fifo_size) |
400 | /* If the last packet is less than MAXP, set INPKTRDY manually */ | 401 | /* If the last packet is less than MAXP, set INPKTRDY manually */ |
401 | REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY; | 402 | REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY; |
402 | 403 | ||
403 | usb_core_transfer_complete(endpoint, EP_IS_IN(ep) ? USB_DIR_IN : USB_DIR_OUT, | 404 | usb_core_transfer_complete(endpoint, EP_IS_IN(ep) ? USB_DIR_IN : USB_DIR_OUT, |
404 | 0, ep->length); | 405 | 0, ep->length); |
405 | 406 | ||
406 | ep->busy = false; | 407 | ep->busy = false; |
407 | ep->sent = 0; | 408 | ep->sent = 0; |
408 | ep->length = 0; | 409 | ep->length = 0; |
@@ -414,14 +415,14 @@ static void EPDMA_handler(int number) | |||
414 | static void setup_endpoint(struct usb_endpoint *ep) | 415 | static void setup_endpoint(struct usb_endpoint *ep) |
415 | { | 416 | { |
416 | int csr, csrh; | 417 | int csr, csrh; |
417 | 418 | ||
418 | select_endpoint(EP_NUMBER2(ep)); | 419 | select_endpoint(EP_NUMBER2(ep)); |
419 | 420 | ||
420 | ep->busy = false; | 421 | ep->busy = false; |
421 | ep->wait = false; | 422 | ep->wait = false; |
422 | ep->sent = 0; | 423 | ep->sent = 0; |
423 | ep->length = 0; | 424 | ep->length = 0; |
424 | 425 | ||
425 | if(ep->type == ep_bulk) | 426 | if(ep->type == ep_bulk) |
426 | { | 427 | { |
427 | if(REG_USB_REG_POWER & USB_POWER_HSMODE) | 428 | if(REG_USB_REG_POWER & USB_POWER_HSMODE) |
@@ -429,14 +430,14 @@ static void setup_endpoint(struct usb_endpoint *ep) | |||
429 | else | 430 | else |
430 | ep->fifo_size = 64; | 431 | ep->fifo_size = 64; |
431 | } | 432 | } |
432 | 433 | ||
433 | if(EP_IS_IN(ep)) | 434 | if(EP_IS_IN(ep)) |
434 | { | 435 | { |
435 | csr = (USB_INCSR_FF | USB_INCSR_CDT); | 436 | csr = (USB_INCSR_FF | USB_INCSR_CDT); |
436 | csrh = USB_INCSRH_MODE; | 437 | csrh = USB_INCSRH_MODE; |
437 | if(ep->use_dma) | 438 | if(ep->use_dma) |
438 | csrh |= (USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQMODE); | 439 | csrh |= (USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQMODE); |
439 | 440 | ||
440 | if(ep->type == ep_interrupt) | 441 | if(ep->type == ep_interrupt) |
441 | csrh |= USB_INCSRH_FRCDATATOG; | 442 | csrh |= USB_INCSRH_FRCDATATOG; |
442 | 443 | ||
@@ -449,13 +450,13 @@ static void setup_endpoint(struct usb_endpoint *ep) | |||
449 | { | 450 | { |
450 | csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT); | 451 | csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT); |
451 | csrh = 0; | 452 | csrh = 0; |
452 | 453 | ||
453 | if(ep->type == ep_interrupt) | 454 | if(ep->type == ep_interrupt) |
454 | csrh |= USB_OUTCSRH_DNYT; | 455 | csrh |= USB_OUTCSRH_DNYT; |
455 | 456 | ||
456 | if(ep->use_dma) | 457 | if(ep->use_dma) |
457 | csrh |= (USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE); | 458 | csrh |= (USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE); |
458 | 459 | ||
459 | REG_USB_REG_OUTMAXP = ep->fifo_size; | 460 | REG_USB_REG_OUTMAXP = ep->fifo_size; |
460 | REG_USB_REG_OUTCSR = csr; | 461 | REG_USB_REG_OUTCSR = csr; |
461 | REG_USB_REG_OUTCSRH = csrh; | 462 | REG_USB_REG_OUTCSRH = csrh; |
@@ -466,7 +467,7 @@ static void setup_endpoint(struct usb_endpoint *ep) | |||
466 | static void udc_reset(void) | 467 | static void udc_reset(void) |
467 | { | 468 | { |
468 | /* From the datasheet: | 469 | /* From the datasheet: |
469 | 470 | ||
470 | When a reset condition is detected on the USB, the controller performs the following actions: | 471 | When a reset condition is detected on the USB, the controller performs the following actions: |
471 | * Sets FAddr to 0. | 472 | * Sets FAddr to 0. |
472 | * Sets Index to 0. | 473 | * Sets Index to 0. |
@@ -479,37 +480,37 @@ static void udc_reset(void) | |||
479 | logf("udc_reset()"); | 480 | logf("udc_reset()"); |
480 | 481 | ||
481 | unsigned int i; | 482 | unsigned int i; |
482 | 483 | ||
483 | /* EP0 init */ | 484 | /* EP0 init */ |
484 | ep0state = USB_EP0_IDLE; | 485 | ep0state = USB_EP0_IDLE; |
485 | 486 | ||
486 | /* Disable interrupts */ | 487 | /* Disable interrupts */ |
487 | REG_USB_REG_INTRINE = 0; | 488 | REG_USB_REG_INTRINE = 0; |
488 | REG_USB_REG_INTROUTE = 0; | 489 | REG_USB_REG_INTROUTE = 0; |
489 | REG_USB_REG_INTRUSBE = 0; | 490 | REG_USB_REG_INTRUSBE = 0; |
490 | 491 | ||
491 | /* Disable DMA */ | 492 | /* Disable DMA */ |
492 | REG_USB_REG_CNTL1 = 0; | 493 | REG_USB_REG_CNTL1 = 0; |
493 | REG_USB_REG_CNTL2 = 0; | 494 | REG_USB_REG_CNTL2 = 0; |
494 | 495 | ||
495 | /* Reset address */ | 496 | /* Reset address */ |
496 | REG_USB_REG_FADDR = 0; | 497 | REG_USB_REG_FADDR = 0; |
497 | 498 | ||
498 | /* High speed, softconnect and suspend/resume */ | 499 | /* High speed, softconnect and suspend/resume */ |
499 | REG_USB_REG_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB | USB_POWER_SUSPENDM); | 500 | REG_USB_REG_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB | USB_POWER_SUSPENDM); |
500 | 501 | ||
501 | /* Reset EP0 */ | 502 | /* Reset EP0 */ |
502 | select_endpoint(0); | 503 | select_endpoint(0); |
503 | REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND); | 504 | REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND); |
504 | 505 | ||
505 | /* Reset other endpoints */ | 506 | /* Reset other endpoints */ |
506 | for(i=2; i<TOTAL_EP(); i++) | 507 | for(i=2; i<TOTAL_EP(); i++) |
507 | setup_endpoint(&endpoints[i]); | 508 | setup_endpoint(&endpoints[i]); |
508 | 509 | ||
509 | /* Enable interrupts */ | 510 | /* Enable interrupts */ |
510 | REG_USB_REG_INTRINE |= USB_INTR_EP0; | 511 | REG_USB_REG_INTRINE |= USB_INTR_EP0; |
511 | REG_USB_REG_INTRUSBE |= USB_INTR_RESET; | 512 | REG_USB_REG_INTRUSBE |= USB_INTR_RESET; |
512 | 513 | ||
513 | usb_core_bus_reset(); | 514 | usb_core_bus_reset(); |
514 | } | 515 | } |
515 | 516 | ||
@@ -524,7 +525,7 @@ void UDC(void) | |||
524 | 525 | ||
525 | if(UNLIKELY(intrUSB == 0 && intrIn == 0 && intrOut == 0 && intrDMA == 0)) | 526 | if(UNLIKELY(intrUSB == 0 && intrIn == 0 && intrOut == 0 && intrDMA == 0)) |
526 | return; | 527 | return; |
527 | 528 | ||
528 | logf("%x %x %x %x", intrUSB, intrIn, intrOut, intrDMA); | 529 | logf("%x %x %x %x", intrUSB, intrIn, intrOut, intrDMA); |
529 | 530 | ||
530 | /* EPIN & EPOUT are all handled in DMA */ | 531 | /* EPIN & EPOUT are all handled in DMA */ |
@@ -557,11 +558,11 @@ void UDC(void) | |||
557 | bool usb_drv_stalled(int endpoint, bool in) | 558 | bool usb_drv_stalled(int endpoint, bool in) |
558 | { | 559 | { |
559 | endpoint &= 0x7F; | 560 | endpoint &= 0x7F; |
560 | 561 | ||
561 | logf("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT"); | 562 | logf("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT"); |
562 | 563 | ||
563 | select_endpoint(endpoint); | 564 | select_endpoint(endpoint); |
564 | 565 | ||
565 | if(endpoint == EP_CONTROL) | 566 | if(endpoint == EP_CONTROL) |
566 | return (REG_USB_REG_CSR0 & USB_CSR0_SENDSTALL) != 0; | 567 | return (REG_USB_REG_CSR0 & USB_CSR0_SENDSTALL) != 0; |
567 | else | 568 | else |
@@ -576,11 +577,11 @@ bool usb_drv_stalled(int endpoint, bool in) | |||
576 | void usb_drv_stall(int endpoint, bool stall, bool in) | 577 | void usb_drv_stall(int endpoint, bool stall, bool in) |
577 | { | 578 | { |
578 | endpoint &= 0x7F; | 579 | endpoint &= 0x7F; |
579 | 580 | ||
580 | logf("usb_drv_stall(%d,%s,%s)", endpoint, stall?"Y":"N", in?"IN":"OUT"); | 581 | logf("usb_drv_stall(%d,%s,%s)", endpoint, stall?"Y":"N", in?"IN":"OUT"); |
581 | 582 | ||
582 | select_endpoint(endpoint); | 583 | select_endpoint(endpoint); |
583 | 584 | ||
584 | if(endpoint == EP_CONTROL) | 585 | if(endpoint == EP_CONTROL) |
585 | { | 586 | { |
586 | if(stall) | 587 | if(stall) |
@@ -620,13 +621,13 @@ int usb_detect(void) | |||
620 | void usb_init_device(void) | 621 | void usb_init_device(void) |
621 | { | 622 | { |
622 | unsigned int i; | 623 | unsigned int i; |
623 | 624 | ||
624 | USB_INIT_GPIO(); | 625 | USB_INIT_GPIO(); |
625 | #ifdef USB_GPIO_IRQ | 626 | #ifdef USB_GPIO_IRQ |
626 | system_enable_irq(IRQ_GPIO_UDC_DETE); | 627 | system_enable_irq(IRQ_GPIO_UDC_DETE); |
627 | #endif | 628 | #endif |
628 | system_enable_irq(IRQ_UDC); | 629 | system_enable_irq(IRQ_UDC); |
629 | 630 | ||
630 | for(i=0; i<TOTAL_EP(); i++) | 631 | for(i=0; i<TOTAL_EP(); i++) |
631 | wakeup_init(&ep_wkup[i]); | 632 | wakeup_init(&ep_wkup[i]); |
632 | } | 633 | } |
@@ -654,7 +655,7 @@ void usb_attach(void) | |||
654 | void usb_drv_init(void) | 655 | void usb_drv_init(void) |
655 | { | 656 | { |
656 | logf("usb_drv_init()"); | 657 | logf("usb_drv_init()"); |
657 | 658 | ||
658 | /* Set this bit to allow the UDC entering low-power mode when | 659 | /* Set this bit to allow the UDC entering low-power mode when |
659 | * there are no actions on the USB bus. | 660 | * there are no actions on the USB bus. |
660 | * UDC still works during this bit was set. | 661 | * UDC still works during this bit was set. |
@@ -664,18 +665,18 @@ void usb_drv_init(void) | |||
664 | 665 | ||
665 | /* Enable the USB PHY */ | 666 | /* Enable the USB PHY */ |
666 | REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; | 667 | REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; |
667 | 668 | ||
668 | /* Dis- and reconnect from USB */ | 669 | /* Dis- and reconnect from USB */ |
669 | REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; | 670 | REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; |
670 | REG_USB_REG_POWER |= USB_POWER_SOFTCONN; | 671 | REG_USB_REG_POWER |= USB_POWER_SOFTCONN; |
671 | 672 | ||
672 | udc_reset(); | 673 | udc_reset(); |
673 | } | 674 | } |
674 | 675 | ||
675 | void usb_drv_exit(void) | 676 | void usb_drv_exit(void) |
676 | { | 677 | { |
677 | logf("usb_drv_exit()"); | 678 | logf("usb_drv_exit()"); |
678 | 679 | ||
679 | /* Disable interrupts */ | 680 | /* Disable interrupts */ |
680 | REG_USB_REG_INTRINE = 0; | 681 | REG_USB_REG_INTRINE = 0; |
681 | REG_USB_REG_INTROUTE = 0; | 682 | REG_USB_REG_INTROUTE = 0; |
@@ -684,20 +685,20 @@ void usb_drv_exit(void) | |||
684 | /* Disable DMA */ | 685 | /* Disable DMA */ |
685 | REG_USB_REG_CNTL1 = 0; | 686 | REG_USB_REG_CNTL1 = 0; |
686 | REG_USB_REG_CNTL2 = 0; | 687 | REG_USB_REG_CNTL2 = 0; |
687 | 688 | ||
688 | /* Disconnect from USB */ | 689 | /* Disconnect from USB */ |
689 | REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; | 690 | REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; |
690 | 691 | ||
691 | /* Disable the USB PHY */ | 692 | /* Disable the USB PHY */ |
692 | REG_CPM_SCR &= ~CPM_SCR_USBPHY_ENABLE; | 693 | REG_CPM_SCR &= ~CPM_SCR_USBPHY_ENABLE; |
693 | 694 | ||
694 | __cpm_stop_udc(); | 695 | __cpm_stop_udc(); |
695 | } | 696 | } |
696 | 697 | ||
697 | void usb_drv_set_address(int address) | 698 | void usb_drv_set_address(int address) |
698 | { | 699 | { |
699 | logf("set adr: %d", address); | 700 | logf("set adr: %d", address); |
700 | 701 | ||
701 | REG_USB_REG_FADDR = address; | 702 | REG_USB_REG_FADDR = address; |
702 | } | 703 | } |
703 | 704 | ||
@@ -705,32 +706,32 @@ int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) | |||
705 | { | 706 | { |
706 | int flags; | 707 | int flags; |
707 | endpoint &= 0x7F; | 708 | endpoint &= 0x7F; |
708 | 709 | ||
709 | logf("usb_drv_send(%d, 0x%x, %d)", endpoint, (int)ptr, length); | 710 | logf("usb_drv_send(%d, 0x%x, %d)", endpoint, (int)ptr, length); |
710 | 711 | ||
711 | if(endpoint == EP_CONTROL && ptr == NULL && length == 0) | 712 | if(endpoint == EP_CONTROL && ptr == NULL && length == 0) |
712 | return 0; /* ACK request, handled by the USB controller */ | 713 | return 0; /* ACK request, handled by the USB controller */ |
713 | 714 | ||
714 | if(endpoint == EP_CONTROL) | 715 | if(endpoint == EP_CONTROL) |
715 | { | 716 | { |
716 | flags = disable_irq_save(); | 717 | flags = disable_irq_save(); |
717 | endpoints[1].buf = ptr; | 718 | endpoints[0].buf = ptr; |
718 | endpoints[1].sent = 0; | 719 | endpoints[0].sent = 0; |
719 | endpoints[1].length = length; | 720 | endpoints[0].length = length; |
720 | ep0state = USB_EP0_TX; | 721 | ep0state = USB_EP0_TX; |
721 | EP0_send(); | 722 | EP0_send(); |
722 | restore_irq(flags); | 723 | restore_irq(flags); |
723 | 724 | ||
724 | return 0; | 725 | return 0; |
725 | } | 726 | } |
726 | else | 727 | else |
727 | { | 728 | { |
728 | flags = disable_irq_save(); | 729 | flags = disable_irq_save(); |
729 | endpoints[endpoint*2+1].buf = ptr; | 730 | endpoints[endpoint*2].buf = ptr; |
730 | endpoints[endpoint*2+1].sent = 0; | 731 | endpoints[endpoint*2].sent = 0; |
731 | endpoints[endpoint*2+1].length = length; | 732 | endpoints[endpoint*2].length = length; |
732 | endpoints[endpoint*2+1].busy = true; | 733 | endpoints[endpoint*2].busy = true; |
733 | if(endpoints[endpoint*2+1].use_dma) | 734 | if(endpoints[endpoint*2].use_dma) |
734 | { | 735 | { |
735 | //dma_cache_wback_inv((unsigned long)ptr, length); | 736 | //dma_cache_wback_inv((unsigned long)ptr, length); |
736 | __dcache_writeback_all(); | 737 | __dcache_writeback_all(); |
@@ -742,7 +743,7 @@ int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) | |||
742 | } | 743 | } |
743 | else | 744 | else |
744 | EPIN_handler(endpoint); | 745 | EPIN_handler(endpoint); |
745 | 746 | ||
746 | restore_irq(flags); | 747 | restore_irq(flags); |
747 | return 0; | 748 | return 0; |
748 | } | 749 | } |
@@ -752,14 +753,14 @@ int usb_drv_send(int endpoint, void* ptr, int length) | |||
752 | { | 753 | { |
753 | int ret; | 754 | int ret; |
754 | endpoint &= 0x7F; | 755 | endpoint &= 0x7F; |
755 | 756 | ||
756 | if(endpoint == EP_CONTROL && ptr == NULL && length == 0) | 757 | if(endpoint == EP_CONTROL && ptr == NULL && length == 0) |
757 | return 0; /* ACK request, handled by the USB controller */ | 758 | return 0; /* ACK request, handled by the USB controller */ |
758 | 759 | ||
759 | endpoints[endpoint*2+1].wait = true; | 760 | endpoints[endpoint*2].wait = true; |
760 | ret = usb_drv_send_nonblocking(endpoint, ptr, length); | 761 | ret = usb_drv_send_nonblocking(endpoint, ptr, length); |
761 | wakeup_wait(&ep_wkup[endpoint*2+1], TIMEOUT_BLOCK); | 762 | wakeup_wait(&ep_wkup[endpoint*2], TIMEOUT_BLOCK); |
762 | endpoints[endpoint*2+1].wait = false; | 763 | endpoints[endpoint*2].wait = false; |
763 | 764 | ||
764 | return ret; | 765 | return ret; |
765 | } | 766 | } |
@@ -768,7 +769,7 @@ int usb_drv_recv(int endpoint, void* ptr, int length) | |||
768 | { | 769 | { |
769 | int flags; | 770 | int flags; |
770 | endpoint &= 0x7F; | 771 | endpoint &= 0x7F; |
771 | 772 | ||
772 | logf("usb_drv_recv(%d, 0x%x, %d)", endpoint, (int)ptr, length); | 773 | logf("usb_drv_recv(%d, 0x%x, %d)", endpoint, (int)ptr, length); |
773 | 774 | ||
774 | if(endpoint == EP_CONTROL && ptr == NULL && length == 0) | 775 | if(endpoint == EP_CONTROL && ptr == NULL && length == 0) |
@@ -776,11 +777,11 @@ int usb_drv_recv(int endpoint, void* ptr, int length) | |||
776 | else | 777 | else |
777 | { | 778 | { |
778 | flags = disable_irq_save(); | 779 | flags = disable_irq_save(); |
779 | endpoints[endpoint*2].buf = ptr; | 780 | endpoints[endpoint*2+1].buf = ptr; |
780 | endpoints[endpoint*2].received = 0; | 781 | endpoints[endpoint*2+1].received = 0; |
781 | endpoints[endpoint*2].length = length; | 782 | endpoints[endpoint*2+1].length = length; |
782 | endpoints[endpoint*2].busy = true; | 783 | endpoints[endpoint*2+1].busy = true; |
783 | if(endpoints[endpoint*2].use_dma) | 784 | if(endpoints[endpoint*2+1].use_dma) |
784 | { | 785 | { |
785 | //dma_cache_wback_inv((unsigned long)ptr, length); | 786 | //dma_cache_wback_inv((unsigned long)ptr, length); |
786 | __dcache_writeback_all(); | 787 | __dcache_writeback_all(); |
@@ -792,7 +793,7 @@ int usb_drv_recv(int endpoint, void* ptr, int length) | |||
792 | } | 793 | } |
793 | else | 794 | else |
794 | EPOUT_handler(endpoint); | 795 | EPOUT_handler(endpoint); |
795 | 796 | ||
796 | restore_irq(flags); | 797 | restore_irq(flags); |
797 | return 0; | 798 | return 0; |
798 | } | 799 | } |
@@ -801,7 +802,7 @@ int usb_drv_recv(int endpoint, void* ptr, int length) | |||
801 | void usb_drv_set_test_mode(int mode) | 802 | void usb_drv_set_test_mode(int mode) |
802 | { | 803 | { |
803 | logf("usb_drv_set_test_mode(%d)", mode); | 804 | logf("usb_drv_set_test_mode(%d)", mode); |
804 | 805 | ||
805 | switch(mode) | 806 | switch(mode) |
806 | { | 807 | { |
807 | case 0: | 808 | case 0: |
@@ -830,23 +831,23 @@ int usb_drv_port_speed(void) | |||
830 | void usb_drv_cancel_all_transfers(void) | 831 | void usb_drv_cancel_all_transfers(void) |
831 | { | 832 | { |
832 | logf("usb_drv_cancel_all_transfers()"); | 833 | logf("usb_drv_cancel_all_transfers()"); |
833 | 834 | ||
834 | unsigned int i, flags; | 835 | unsigned int i, flags; |
835 | flags = disable_irq_save(); | 836 | flags = disable_irq_save(); |
836 | 837 | ||
837 | for(i=0; i<TOTAL_EP(); i++) | 838 | for(i=0; i<TOTAL_EP(); i++) |
838 | { | 839 | { |
839 | if(i > 2) | 840 | if(i >= 2) |
840 | endpoints[i].buf = NULL; | 841 | endpoints[i].buf = NULL; |
841 | 842 | ||
842 | endpoints[i].sent = 0; | 843 | endpoints[i].sent = 0; |
843 | endpoints[i].length = 0; | 844 | endpoints[i].length = 0; |
844 | 845 | ||
845 | select_endpoint(i/2); | 846 | select_endpoint(i/2); |
846 | flushFIFO(&endpoints[i]); | 847 | flushFIFO(&endpoints[i]); |
847 | } | 848 | } |
848 | restore_irq(flags); | 849 | restore_irq(flags); |
849 | 850 | ||
850 | ep0state = USB_EP0_IDLE; | 851 | ep0state = USB_EP0_IDLE; |
851 | } | 852 | } |
852 | 853 | ||
@@ -864,18 +865,17 @@ int usb_drv_request_endpoint(int type, int dir) | |||
864 | type &= USB_ENDPOINT_XFERTYPE_MASK; | 865 | type &= USB_ENDPOINT_XFERTYPE_MASK; |
865 | 866 | ||
866 | /* There are only 3+2 endpoints, so hardcode this ... */ | 867 | /* There are only 3+2 endpoints, so hardcode this ... */ |
867 | /* Use the endpoint combinations from the Ingenic Linux USB driver */ | ||
868 | switch(type) | 868 | switch(type) |
869 | { | 869 | { |
870 | case USB_ENDPOINT_XFER_BULK: | 870 | case USB_ENDPOINT_XFER_BULK: |
871 | if(dir == USB_DIR_IN) | 871 | if(dir == USB_DIR_IN) |
872 | return (2 | USB_DIR_IN); | 872 | return (1 | USB_DIR_IN); |
873 | else | 873 | else |
874 | return (1 | USB_DIR_OUT); | 874 | return (1 | USB_DIR_OUT); |
875 | 875 | ||
876 | case USB_ENDPOINT_XFER_INT: | 876 | case USB_ENDPOINT_XFER_INT: |
877 | if(dir == USB_DIR_IN) | 877 | if(dir == USB_DIR_IN) |
878 | return (1 | USB_DIR_IN); | 878 | return (2 | USB_DIR_IN); |
879 | 879 | ||
880 | default: | 880 | default: |
881 | return -1; | 881 | return -1; |