1 /*****************************************************************************
2 ** FILE NAME : ifxhcd_es.c
3 ** PROJECT : IFX USB sub-system V3
4 ** MODULES : IFX USB sub-system Host and Device driver
7 ** AUTHOR : Chen, Howard
8 ** DESCRIPTION : The file contain function to enable host mode USB-IF Electrical Test function.
9 *****************************************************************************/
13 \ingroup IFXUSB_DRIVER_V3
14 \brief The file contain function to enable host mode USB-IF Electrical Test function.
17 #include <linux/version.h>
18 #include "ifxusb_version.h"
20 #include <linux/kernel.h>
22 #include <linux/errno.h>
24 #include <linux/dma-mapping.h>
26 #include "ifxusb_plat.h"
27 #include "ifxusb_regs.h"
28 #include "ifxusb_cif.h"
32 #ifdef __WITH_HS_ELECT_TST__
34 * Quick and dirty hack to implement the HS Electrical Test
35 * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
37 * This code was copied from our userspace app "hset". It sends a
38 * Get Device Descriptor control sequence in two parts, first the
39 * Setup packet by itself, followed some time later by the In and
40 * Ack packets. Rather than trying to figure out how to add this
41 * functionality to the normal driver code, we just hijack the
42 * hardware, using these two function to drive the hardware
47 void do_setup(ifxusb_core_if_t *_core_if)
50 ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
51 ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
52 ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0];
53 uint32_t *data_fifo = _core_if->data_fifo[0];
63 ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
66 ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
69 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
70 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
73 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
74 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
77 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
78 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
81 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
82 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
85 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
88 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
91 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
94 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
95 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
98 * Send Setup packet (Get Device Descriptor)
101 /* Make sure channel is disabled */
102 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
104 //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
106 // hcchar.b.chen = 1;
107 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
112 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
113 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
116 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
117 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
120 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
121 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
124 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
125 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
128 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
131 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
134 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
136 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
137 //if (hcchar.b.chen) {
138 // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
144 hctsiz.b.xfersize = 8;
146 hctsiz.b.pid = IFXUSB_HC_PID_SETUP;
147 ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
150 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
151 hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
156 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
158 /* Fill FIFO with Setup data for Get Device Descriptor */
159 ifxusb_wreg(data_fifo++, 0x01000680);
160 ifxusb_wreg(data_fifo++, 0x00080000);
162 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
163 //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
165 /* Wait for host channel interrupt */
167 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
168 } while (gintsts.b.hcintr == 0);
170 //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
173 ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
176 ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
179 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
180 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
183 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
184 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
187 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
188 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
191 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
194 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
197 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
200 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
201 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
204 void do_in_ack(ifxusb_core_if_t *_core_if)
207 ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
208 ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
209 ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0];
210 uint32_t *data_fifo = _core_if->data_fifo[0];
213 hctsiz_data_t hctsiz;
214 hcchar_data_t hcchar;
217 grxsts_data_t grxsts;
220 ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
223 ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
226 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
227 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
230 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
231 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
234 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
235 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
238 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
239 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
242 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
245 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
248 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
251 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
252 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
255 * Receive Control In packet
258 /* Make sure channel is disabled */
259 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
261 //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
264 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
269 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
270 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
273 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
274 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
277 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
278 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
281 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
282 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
285 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
288 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
291 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
293 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
294 //if (hcchar.b.chen) {
295 // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
301 hctsiz.b.xfersize = 8;
303 hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
304 ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
307 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
308 hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
313 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
315 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
316 //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
318 /* Wait for receive status queue interrupt */
320 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
321 } while (gintsts.b.rxstsqlvl == 0);
323 //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
326 grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
327 //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
329 /* Clear RXSTSQLVL in GINTSTS */
331 gintsts.b.rxstsqlvl = 1;
332 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
334 switch (grxsts.hb.pktsts) {
335 case IFXUSB_HSTS_DATA_UPDT:
336 /* Read the data into the host buffer */
337 if (grxsts.hb.bcnt > 0) {
339 int word_count = (grxsts.hb.bcnt + 3) / 4;
341 for (i = 0; i < word_count; i++) {
342 (void)ifxusb_rreg(data_fifo++);
346 //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.hb.bcnt);
350 //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
354 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
355 //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
357 /* Wait for receive status queue interrupt */
359 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
360 } while (gintsts.b.rxstsqlvl == 0);
362 //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
365 grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
366 //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
368 /* Clear RXSTSQLVL in GINTSTS */
370 gintsts.b.rxstsqlvl = 1;
371 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
373 switch (grxsts.hb.pktsts) {
374 case IFXUSB_HSTS_XFER_COMP:
378 //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
382 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
383 //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
385 /* Wait for host channel interrupt */
387 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
388 } while (gintsts.b.hcintr == 0);
390 //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
393 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
394 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
397 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
398 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
401 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
402 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
405 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
408 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
411 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
414 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
415 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
422 * Send handshake packet
426 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
427 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
430 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
431 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
434 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
435 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
438 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
441 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
444 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
447 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
448 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
450 /* Make sure channel is disabled */
451 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
453 //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
456 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
461 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
462 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
465 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
466 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
469 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
470 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
473 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
474 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
477 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
480 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
483 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
485 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
486 //if (hcchar.b.chen) {
487 // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
493 hctsiz.b.xfersize = 0;
495 hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
496 ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
499 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
500 hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
505 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
507 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
508 //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
510 /* Wait for host channel interrupt */
512 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
513 } while (gintsts.b.hcintr == 0);
515 //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
518 ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
521 ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
524 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
525 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
528 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
529 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
532 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
533 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
536 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
539 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
542 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
545 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
546 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
548 #endif //__WITH_HS_ELECT_TST__