summaryrefslogtreecommitdiff
path: root/firmware/drivers/isp1583.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/isp1583.c')
-rw-r--r--firmware/drivers/isp1583.c741
1 files changed, 741 insertions, 0 deletions
diff --git a/firmware/drivers/isp1583.c b/firmware/drivers/isp1583.c
new file mode 100644
index 0000000000..8cc440dc4c
--- /dev/null
+++ b/firmware/drivers/isp1583.c
@@ -0,0 +1,741 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Tomasz Malesinski
11 * Copyright (C) 2008 by Maurus Cuelenaere
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include "config.h"
22#include "usb-target.h"
23#include "usb_ch9.h"
24#include "usb_drv.h"
25#include "usb_core.h"
26#include "isp1583.h"
27#include "thread.h"
28
29#define printf
30#define logf printf
31
32#define DIR_RX 0
33#define DIR_TX 1
34
35#define DIR_OUT 0
36#define DIR_IN 1
37
38struct usb_endpoint
39{
40 unsigned char *out_buf;
41 short out_len;
42 short out_ptr;
43 void (*out_done)(int, unsigned char *, int);
44 unsigned char out_in_progress;
45
46 unsigned char *in_buf;
47 short in_min_len;
48 short in_max_len;
49 short in_ptr;
50 void (*in_done)(int, unsigned char *, int);
51 unsigned char in_ack;
52
53 unsigned char halt[2];
54 unsigned char enabled[2];
55 short max_pkt_size[2];
56 short type;
57};
58
59static unsigned char setup_pkt_buf[8];
60static struct usb_endpoint endpoints[NUM_ENDPOINTS];
61
62static bool high_speed_mode = false;
63
64static inline void or_int_value(volatile unsigned short *a, volatile unsigned short *b, unsigned long r, unsigned long value)
65{
66 set_int_value(*a, *b, (r | value));
67}
68static inline void bc_int_value(volatile unsigned short *a, volatile unsigned short *b, unsigned long r, unsigned long value)
69{
70 set_int_value(*a, *b, (r & ~value));
71}
72
73static inline void nop_f(void)
74{
75 yield();
76}
77
78#define NOP asm volatile("nop\n");
79
80static inline int ep_index(int n, bool dir)
81{
82 return (n << 1) | dir;
83}
84
85static inline bool epidx_dir(int idx)
86{
87 return idx & 1;
88}
89
90static inline int epidx_n(int idx)
91{
92 return idx >> 1;
93}
94
95static inline void usb_select_endpoint(int idx)
96{
97 /* Select the endpoint */
98 ISP1583_DFLOW_EPINDEX = idx;
99 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
100 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
101 */
102 NOP;
103}
104
105static inline void usb_select_setup_endpoint(void)
106{
107 /* Select the endpoint */
108 ISP1583_DFLOW_EPINDEX = DFLOW_EPINDEX_EP0SETUP;
109 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
110 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
111 */
112 NOP;
113}
114
115static void usb_setup_endpoint(int idx, int max_pkt_size, int type)
116{
117 if(epidx_n(idx)!=0)
118 {
119 usb_select_endpoint(idx);
120 ISP1583_DFLOW_MAXPKSZ = max_pkt_size & 0x7FF;
121 ISP1583_DFLOW_EPTYPE = (DFLOW_EPTYPE_NOEMPKT | DFLOW_EPTYPE_DBLBUF | (type & 0x3));
122
123 /* clear buffer ... */
124 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
125 /* ... twice because of double buffering */
126 usb_select_endpoint(idx);
127 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
128 }
129
130 struct usb_endpoint *ep;
131 ep = &(endpoints[epidx_n(idx)]);
132 ep->halt[epidx_dir(idx)] = 0;
133 ep->enabled[epidx_dir(idx)] = 0;
134 ep->out_in_progress = 0;
135 ep->in_min_len = -1;
136 ep->in_ack = 0;
137 ep->type = type;
138 ep->max_pkt_size[epidx_dir(idx)] = max_pkt_size;
139}
140
141static void usb_enable_endpoint(int idx)
142{
143 if(epidx_n(idx)!=0)
144 {
145 usb_select_endpoint(idx);
146 /* Enable interrupt */
147 or_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
148 /* Enable endpoint */
149 ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE;
150 }
151
152 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 1;
153}
154
155static void usb_disable_endpoint(int idx, bool set_struct)
156{
157 usb_select_endpoint(idx);
158 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
159 bc_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
160
161 if(set_struct)
162 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 0;
163}
164
165static int usb_get_packet(unsigned char *buf, int max_len)
166{
167 int len, i;
168 len = ISP1583_DFLOW_BUFLEN;
169
170 if (max_len < 0 || max_len > len)
171 max_len = len;
172
173 i = 0;
174 while (i < len)
175 {
176 unsigned short d = ISP1583_DFLOW_DATA;
177 if (i < max_len)
178 buf[i] = d & 0xff;
179 i++;
180 if (i < max_len)
181 buf[i] = (d >> 8) & 0xff;
182 i++;
183 }
184 return max_len;
185}
186
187static int usb_receive(int n)
188{
189 logf("usb_receive(%d)", n);
190 int len;
191
192 if (endpoints[n].halt[DIR_RX]
193 || !endpoints[n].enabled[DIR_RX]
194 || endpoints[n].in_min_len < 0
195 || !endpoints[n].in_ack)
196 return -1;
197
198 endpoints[n].in_ack = 0;
199
200 usb_select_endpoint(ep_index(n, DIR_RX));
201
202 len = usb_get_packet(endpoints[n].in_buf + endpoints[n].in_ptr,
203 endpoints[n].in_max_len - endpoints[n].in_ptr);
204 endpoints[n].in_ptr += len;
205 if (endpoints[n].in_ptr >= endpoints[n].in_min_len) {
206 endpoints[n].in_min_len = -1;
207 if (endpoints[n].in_done)
208 (*(endpoints[n].in_done))(n, endpoints[n].in_buf,
209 endpoints[n].in_ptr);
210 }
211 logf("receive_end");
212 return 0;
213}
214
215static bool usb_out_buffer_full(int ep)
216{
217 usb_select_endpoint(ep_index(ep, DIR_TX));
218 if (ISP1583_DFLOW_EPTYPE & 4) /* Check if type=bulk and double buffering is set */
219 return (ISP1583_DFLOW_BUFSTAT & 3) == 3; /* Return true if both buffers are filled */
220 else
221 return (ISP1583_DFLOW_BUFSTAT & 3) != 0; /* Return true if one of the buffers are filled */
222}
223
224static int usb_send(int n)
225{
226 logf("usb_send(%d)", n);
227 int max_pkt_size, len;
228 int i;
229 unsigned char *p;
230
231 if (endpoints[n].halt[DIR_TX]
232 || !endpoints[n].enabled[DIR_TX]
233 || !endpoints[n].out_in_progress)
234 {
235 logf("NOT SEND TO EP!");
236 return -1;
237 }
238
239 if (endpoints[n].out_ptr < 0)
240 {
241 endpoints[n].out_in_progress = 0;
242 if (endpoints[n].out_done)
243 (*(endpoints[n].out_done))(n, endpoints[n].out_buf,
244 endpoints[n].out_len);
245 logf("ALREADY SENT TO EP!");
246 return -1;
247 }
248
249 if (usb_out_buffer_full(n))
250 {
251 logf("BUFFER FULL!");
252 return -1;
253 }
254
255 usb_select_endpoint(ep_index(n, DIR_TX));
256 max_pkt_size = endpoints[n].max_pkt_size[DIR_TX];
257 len = endpoints[n].out_len - endpoints[n].out_ptr;
258 if (len > max_pkt_size)
259 len = max_pkt_size;
260
261 if(len < max_pkt_size)
262 ISP1583_DFLOW_BUFLEN = len;
263
264 p = endpoints[n].out_buf + endpoints[n].out_ptr;
265 i = 0;
266 while (len - i >= 2) {
267 ISP1583_DFLOW_DATA = p[i] | (p[i + 1] << 8);
268 i += 2;
269 }
270 if (i < len)
271 ISP1583_DFLOW_DATA = p[i];
272
273 endpoints[n].out_ptr += len;
274
275/*
276 if (endpoints[n].out_ptr == endpoints[n].out_len
277 && len < max_pkt_size)
278*/
279 if (endpoints[n].out_ptr == endpoints[n].out_len)
280 endpoints[n].out_ptr = -1;
281
282 logf("send_end");
283 return 0;
284}
285
286static void usb_stall_endpoint(int idx)
287{
288 usb_select_endpoint(idx);
289 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STALL;
290 endpoints[epidx_n(idx)].halt[epidx_dir(idx)] = 1;
291}
292
293static void usb_unstall_endpoint(int idx)
294{
295 usb_select_endpoint(idx);
296 ISP1583_DFLOW_CTRLFUN &= ~DFLOW_CTRLFUN_STALL;
297 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
298 ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE;
299 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
300 if (epidx_dir(idx) == DIR_TX)
301 endpoints[epidx_n(idx)].out_in_progress = 0;
302 else
303 {
304 endpoints[epidx_n(idx)].in_min_len = -1;
305 endpoints[epidx_n(idx)].in_ack = 0;
306 }
307 endpoints[epidx_n(idx)].halt[epidx_dir(idx)] = 0;
308}
309
310static void usb_status_ack(int ep, int dir)
311{
312 logf("usb_status_ack(%d)", dir);
313 usb_select_endpoint(ep_index(ep, dir));
314 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STATUS;
315}
316
317static void usb_data_stage_enable(int ep, int dir)
318{
319 logf("usb_data_stage_enable(%d)", dir);
320 usb_select_endpoint(ep_index(ep, dir));
321 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_DSEN;
322}
323
324static void usb_handle_setup_rx(void)
325{
326 int len;
327 usb_select_setup_endpoint();
328 len = usb_get_packet(setup_pkt_buf, 8);
329
330 if (len == 8)
331 usb_core_control_request((struct usb_ctrlrequest*)setup_pkt_buf);
332 else
333 {
334 usb_drv_stall(0, true, false);
335 usb_drv_stall(0, true, true);
336 logf("usb_handle_setup_rx() failed");
337 return;
338 }
339
340 logf("usb_handle_setup_rx(): %02x %02x %02x %02x %02x %02x %02x %02x", setup_pkt_buf[0], setup_pkt_buf[1], setup_pkt_buf[2], setup_pkt_buf[3], setup_pkt_buf[4], setup_pkt_buf[5], setup_pkt_buf[6], setup_pkt_buf[7]);
341}
342
343static void usb_handle_data_int(int ep, int dir)
344{
345 int len;
346 if (dir == DIR_TX)
347 len = usb_send(ep);
348 else
349 {
350 len = usb_receive(ep);
351 endpoints[ep].in_ack = 1;
352 }
353 logf("usb_handle_data_int(%d, %d) finished", ep, dir);
354}
355
356bool usb_drv_powered(void)
357{
358#if 0
359 return (ISP1583_INIT_OTG & INIT_OTG_BSESS_VALID) ? true : false;
360#else
361 return (ISP1583_INIT_MODE & INIT_MODE_VBUSSTAT) ? true : false;
362#endif
363}
364
365static void setup_endpoints(void)
366{
367 usb_setup_endpoint(ep_index(0, DIR_RX), 64, 0);
368 usb_setup_endpoint(ep_index(0, DIR_TX), 64, 0);
369
370 int i;
371 for(i = 1; i < NUM_ENDPOINTS-1; i++)
372 {
373 usb_setup_endpoint(ep_index(i, DIR_RX), (high_speed_mode ? 512 : 64), 2); /* 2 = TYPE_BULK */
374 usb_setup_endpoint(ep_index(i, DIR_TX), (high_speed_mode ? 512 : 64), 2);
375 }
376
377 usb_enable_endpoint(ep_index(0, DIR_RX));
378 usb_enable_endpoint(ep_index(0, DIR_TX));
379
380 for (i = 1; i < NUM_ENDPOINTS-1; i++)
381 {
382 usb_enable_endpoint(ep_index(i, DIR_RX));
383 usb_enable_endpoint(ep_index(i, DIR_TX));
384 }
385
386 ZVM_SPECIFIC;
387}
388
389void usb_helper(void)
390{
391 if(ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ)
392 {
393 #ifdef DEBUG
394 //logf("Helper detected interrupt... [%d]", current_tick);
395 #endif
396 usb_drv_int();
397 }
398 return;
399}
400
401void usb_drv_init(void)
402{
403 /* Disable interrupt at CPU level */
404 DIS_INT_CPU_TARGET;
405
406 /* Unlock the device's registers */
407 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE;
408
409 /* Soft reset the device */
410 ISP1583_INIT_MODE = INIT_MODE_SFRESET;
411 sleep(10);
412 /* Enable CLKAON & GLINTENA */
413 ISP1583_INIT_MODE = STANDARD_INIT_MODE;
414
415 /* Disable all OTG functions */
416 ISP1583_INIT_OTG = 0;
417
418#if 0
419 #ifdef USE_HIGH_SPEED
420 /* Force device to high speed */
421 ISP1583_GEN_TSTMOD = GEN_TSTMOD_FORCEHS;
422 high_speed_mode = true;
423 #endif
424#endif
425
426 #ifdef DEBUG
427 logf("BUS_CONF/DA0:%d MODE0/DA1: %d MODE1: %d", (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST0), (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST1), (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST2));
428 logf("Chip ID: 0x%x", ISP1583_GEN_CHIPID);
429 //logf("INV0: 0x% IRQEDGE: 0x%x IRQPORT: 0x%x", IO_GIO_INV0, IO_GIO_IRQEDGE, IO_GIO_IRQPORT);
430 #endif
431
432 /*Set interrupt generation to target-specific mode +
433 * Set the control pipe to ACK only interrupt +
434 * Set the IN pipe to ACK only interrupt +
435 * Set OUT pipe to ACK and NYET interrupt
436 */
437
438 ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET;
439 /* Clear all interrupts */
440 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, 0xFFFFFFFF);
441 /* Enable USB interrupts */
442 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN);
443
444 ZVM_SPECIFIC;
445
446 /* Enable interrupt at CPU level */
447 EN_INT_CPU_TARGET;
448
449 setup_endpoints();
450
451 /* Clear device address and disable it */
452 ISP1583_INIT_ADDRESS = 0;
453
454 /* Turn SoftConnect on */
455 ISP1583_INIT_MODE |= INIT_MODE_SOFTCT;
456
457 ZVM_SPECIFIC;
458
459 tick_add_task(usb_helper);
460
461 logf("usb_init_device() finished");
462}
463
464int usb_drv_port_speed(void)
465{
466 return (int)high_speed_mode;
467}
468
469void usb_drv_exit(void)
470{
471 logf("usb_drv_exit()");
472
473 /* Disable device */
474 ISP1583_INIT_MODE &= ~INIT_MODE_SOFTCT;
475 ISP1583_INIT_ADDRESS = 0;
476
477 /* Disable interrupts */
478 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, 0);
479 /* and the CPU's one... */
480 DIS_INT_CPU_TARGET;
481
482
483 /* Send usb controller to suspend mode */
484 ISP1583_INIT_MODE = INIT_MODE_GOSUSP;
485 ISP1583_INIT_MODE = 0;
486
487 tick_remove_task(usb_helper);
488
489 ZVM_SPECIFIC;
490}
491
492void usb_drv_stall(int endpoint, bool stall, bool in)
493{
494 logf("%sstall EP%d %s", (stall ? "" : "un"), endpoint, (in ? "RX" : "TX" ));
495 if (stall)
496 usb_stall_endpoint(ep_index(endpoint, (int)in));
497 else
498 usb_unstall_endpoint(ep_index(endpoint, (int)in));
499}
500
501bool usb_drv_stalled(int endpoint, bool in)
502{
503 return (endpoints[endpoint].halt[(int)in] == 1);
504}
505
506static void out_callback(int ep, unsigned char *buf, int len)
507{
508 (void)buf;
509 logf("out_callback(%d, 0x%x, %d)", ep, &buf, len);
510 usb_status_ack(ep, DIR_RX);
511 usb_core_transfer_complete(ep, true, 0, len); /* 0=>status succeeded, haven't worked out status failed yet... */
512}
513
514static void in_callback(int ep, unsigned char *buf, int len)
515{
516 (void)buf;
517 logf("in_callback(%d, 0x%x, %d)", ep, &buf, len);
518 usb_status_ack(ep, DIR_TX);
519 usb_core_transfer_complete(ep, false, 0, len);
520}
521
522int usb_drv_recv(int ep, void* ptr, int length)
523{
524 logf("usb_drv_recv(%d, 0x%x, %d)", ep, &ptr, length);
525 if(ep == 0 && length == 0 && ptr == NULL)
526 {
527 usb_status_ack(ep, DIR_TX);
528 return 0;
529 }
530 endpoints[ep].in_done = in_callback;
531 endpoints[ep].in_buf = ptr;
532 endpoints[ep].in_max_len = length;
533 endpoints[ep].in_min_len = length;
534 endpoints[ep].in_ptr = 0;
535 if(ep == 0)
536 {
537 usb_data_stage_enable(ep, DIR_RX);
538 return usb_receive(ep);
539 }
540 else
541 return usb_receive(ep);
542}
543
544int usb_drv_send_nonblocking(int ep, void* ptr, int length)
545{
546 /* First implement DMA... */
547 return usb_drv_send(ep, ptr, length);
548}
549
550int usb_drv_send(int ep, void* ptr, int length)
551{
552 logf("usb_drv_send_nb(%d, 0x%x, %d)", ep, &ptr, length);
553 if(ep == 0 && length == 0 && ptr == NULL)
554 {
555 usb_status_ack(ep, DIR_RX);
556 return 0;
557 }
558 if(endpoints[ep].out_in_progress == 1)
559 return -1;
560 endpoints[ep].out_done = out_callback;
561 endpoints[ep].out_buf = ptr;
562 endpoints[ep].out_len = length;
563 endpoints[ep].out_ptr = 0;
564 endpoints[ep].out_in_progress = 1;
565 if(ep == 0)
566 {
567 int rc = usb_send(ep);
568 usb_data_stage_enable(ep, DIR_TX);
569 usb_drv_wait(ep, DIR_TX);
570 return rc;
571 }
572 else
573 return usb_send(ep);
574}
575
576void usb_drv_reset_endpoint(int ep, bool send)
577{
578 logf("reset endpoint(%d, %d)", ep, send);
579 usb_setup_endpoint(ep_index(ep, (int)send), endpoints[ep].max_pkt_size[(int)send], endpoints[ep].type);
580 usb_enable_endpoint(ep_index(ep, (int)send));
581}
582
583void usb_drv_wait(int ep, bool send)
584{
585 logf("usb_drv_wait(%d, %d)", ep, send);
586 if(send)
587 {
588 while (endpoints[ep].out_in_progress)
589 nop_f();
590 }
591 else
592 {
593 while (endpoints[ep].in_ack)
594 nop_f();
595 }
596}
597
598void usb_drv_cancel_all_transfers(void)
599{
600 logf("usb_drv_cancel_all_tranfers()");
601 int i;
602
603 for(i=0;i<NUM_ENDPOINTS-1;i++)
604 endpoints[i].halt[0] = endpoints[i].halt[1] = 1;
605}
606
607static void bus_reset(void)
608{
609 /* Enable CLKAON & GLINTENA */
610 ISP1583_INIT_MODE = STANDARD_INIT_MODE;
611 /* Enable USB interrupts */
612 ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET;
613 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN);
614
615 /* Disable all OTG functions */
616 ISP1583_INIT_OTG = 0;
617
618 /* Clear device address and enable it */
619 ISP1583_INIT_ADDRESS = INIT_ADDRESS_DEVEN;
620
621 ZVM_SPECIFIC;
622
623 /* Reset endpoints to default */
624 setup_endpoints();
625
626 logf("bus reset->done");
627}
628
629/* Method for handling interrupts, must be called from usb-<target>.c */
630void usb_drv_int(void)
631{
632 unsigned long ints;
633 ints = ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ;
634
635 if(!ints)
636 return;
637
638 /* Unlock the device's registers */
639 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE;
640
641 #if 0
642 logf(" handling int [0x%x & 0x%x = 0x%x]", ISP1583_GEN_INT_READ, ISP1583_INIT_INTEN_READ, ints);
643 #endif
644
645 if(ints & INT_IEBRST) /* Bus reset */
646 {
647 logf("BRESET");
648 high_speed_mode = false;
649 bus_reset();
650 usb_core_bus_reset();
651 /* Mask bus reset interrupt */
652 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, INT_IEBRST);
653 return;
654 }
655 if(ints & INT_IEP0SETUP) /* EP0SETUP interrupt */
656 {
657 logf("EP0SETUP");
658 usb_handle_setup_rx();
659 }
660 if(ints & INT_IEHS_STA) /* change from full-speed to high-speed mode -> endpoints need to get reconfigured!! */
661 {
662 logf("HS_STA");
663 high_speed_mode = true;
664 setup_endpoints();
665 }
666 if(ints & INT_EP_MASK) /* Endpoints interrupt */
667 {
668 unsigned long ep_event;
669 unsigned short i = 10;
670 ep_event = ints & INT_EP_MASK;
671 while(ep_event)
672 {
673 if(i>25)
674 break;
675
676 if(ep_event & (1 << i))
677 {
678 logf("EP%d %s interrupt", (i - 10) / 2, i % 2 ? "RX" : "TX");
679 usb_handle_data_int((i - 10) / 2, i % 2);
680 ep_event &= ~(1 << i);
681 }
682 i++;
683 }
684 }
685 if(ints & INT_IERESM && !(ints & INT_IESUSP)) /* Resume status: status change from suspend to resume (active) */
686 {
687 logf("RESM");
688 }
689 if(ints & INT_IESUSP && !(ints & INT_IERESM)) /* Suspend status: status change from active to suspend */
690 {
691 logf("SUSP");
692 }
693 if(ints & INT_IEDMA) /* change in the DMA Interrupt Reason register */
694 {
695 logf("DMA");
696 }
697 if(ints & INT_IEVBUS) /* transition from LOW to HIGH on VBUS */
698 {
699 logf("VBUS");
700 }
701 /* Mask all (enabled) interrupts */
702 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, ints);
703
704 ZVM_SPECIFIC;
705}
706
707void usb_drv_set_address(int address)
708{
709 logf("usb_drv_set_address(0x%x)", address);
710 ISP1583_INIT_ADDRESS = (address & 0x7F) | INIT_ADDRESS_DEVEN;
711
712 ZVM_SPECIFIC;
713
714 usb_status_ack(0, DIR_TX);
715}
716
717void usb_drv_set_test_mode(int mode)
718{
719 logf("usb_drv_set_test_mode(%d)", mode);
720 switch(mode){
721 case 0:
722 ISP1583_GEN_TSTMOD = 0;
723 /* Power cycle... */
724 break;
725 case 1:
726 ISP1583_GEN_TSTMOD = GEN_TSTMOD_JSTATE;
727 break;
728 case 2:
729 ISP1583_GEN_TSTMOD = GEN_TSTMOD_KSTATE;
730 break;
731 case 3:
732 ISP1583_GEN_TSTMOD = GEN_TSTMOD_SE0_NAK;
733 break;
734 case 4:
735 //REG_PORTSC1 |= PORTSCX_PTC_PACKET;
736 break;
737 case 5:
738 //REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
739 break;
740 }
741}