Root/target/linux/lantiq/files/drivers/usb/ifxhcd/ifxhcd_es.c

1/*****************************************************************************
2 ** FILE NAME : ifxhcd_es.c
3 ** PROJECT : IFX USB sub-system V3
4 ** MODULES : IFX USB sub-system Host and Device driver
5 ** SRC VERSION : 1.0
6 ** DATE : 1/Jan/2009
7 ** AUTHOR : Chen, Howard
8 ** DESCRIPTION : The file contain function to enable host mode USB-IF Electrical Test function.
9 *****************************************************************************/
10
11/*!
12 \file ifxhcd_es.c
13 \ingroup IFXUSB_DRIVER_V3
14 \brief The file contain function to enable host mode USB-IF Electrical Test function.
15*/
16
17#include <linux/version.h>
18#include "ifxusb_version.h"
19
20#include <linux/kernel.h>
21
22#include <linux/errno.h>
23
24#include <linux/dma-mapping.h>
25
26#include "ifxusb_plat.h"
27#include "ifxusb_regs.h"
28#include "ifxusb_cif.h"
29#include "ifxhcd.h"
30
31
32#ifdef __WITH_HS_ELECT_TST__
33    /*
34     * Quick and dirty hack to implement the HS Electrical Test
35     * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
36     *
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
43     * directly.
44     */
45
46
47    void do_setup(ifxusb_core_if_t *_core_if)
48    {
49
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];
54
55        gint_data_t gintsts;
56        hctsiz_data_t hctsiz;
57        hcchar_data_t hcchar;
58        haint_data_t haint;
59        hcint_data_t hcint;
60
61
62        /* Enable HAINTs */
63        ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
64
65        /* Enable HCINTs */
66        ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
67
68        /* Read GINTSTS */
69        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
70        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
71
72        /* Read HAINT */
73        haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
74        //fprintf(stderr, "HAINT: %08x\n", haint.d32);
75
76        /* Read HCINT */
77        hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
78        //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
79
80        /* Read HCCHAR */
81        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
82        //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
83
84        /* Clear HCINT */
85        ifxusb_wreg(&hc_regs->hcint, hcint.d32);
86
87        /* Clear HAINT */
88        ifxusb_wreg(&hc_global_regs->haint, haint.d32);
89
90        /* Clear GINTSTS */
91        ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
92
93        /* Read GINTSTS */
94        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
95        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
96
97        /*
98         * Send Setup packet (Get Device Descriptor)
99         */
100
101        /* Make sure channel is disabled */
102        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
103        if (hcchar.b.chen) {
104            //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
105            hcchar.b.chdis = 1;
106    // hcchar.b.chen = 1;
107            ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
108            //sleep(1);
109            mdelay(1000);
110
111            /* Read GINTSTS */
112            gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
113            //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
114
115            /* Read HAINT */
116            haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
117            //fprintf(stderr, "HAINT: %08x\n", haint.d32);
118
119            /* Read HCINT */
120            hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
121            //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
122
123            /* Read HCCHAR */
124            hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
125            //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
126
127            /* Clear HCINT */
128            ifxusb_wreg(&hc_regs->hcint, hcint.d32);
129
130            /* Clear HAINT */
131            ifxusb_wreg(&hc_global_regs->haint, haint.d32);
132
133            /* Clear GINTSTS */
134            ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
135
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);
139            //}
140        }
141
142        /* Set HCTSIZ */
143        hctsiz.d32 = 0;
144        hctsiz.b.xfersize = 8;
145        hctsiz.b.pktcnt = 1;
146        hctsiz.b.pid = IFXUSB_HC_PID_SETUP;
147        ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
148
149        /* Set HCCHAR */
150        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
151        hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
152        hcchar.b.epdir = 0;
153        hcchar.b.epnum = 0;
154        hcchar.b.mps = 8;
155        hcchar.b.chen = 1;
156        ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
157
158        /* Fill FIFO with Setup data for Get Device Descriptor */
159        ifxusb_wreg(data_fifo++, 0x01000680);
160        ifxusb_wreg(data_fifo++, 0x00080000);
161
162        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
163        //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
164
165        /* Wait for host channel interrupt */
166        do {
167            gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
168        } while (gintsts.b.hcintr == 0);
169
170        //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
171
172        /* Disable HCINTs */
173        ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
174
175        /* Disable HAINTs */
176        ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
177
178        /* Read HAINT */
179        haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
180        //fprintf(stderr, "HAINT: %08x\n", haint.d32);
181
182        /* Read HCINT */
183        hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
184        //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
185
186        /* Read HCCHAR */
187        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
188        //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
189
190        /* Clear HCINT */
191        ifxusb_wreg(&hc_regs->hcint, hcint.d32);
192
193        /* Clear HAINT */
194        ifxusb_wreg(&hc_global_regs->haint, haint.d32);
195
196        /* Clear GINTSTS */
197        ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
198
199        /* Read GINTSTS */
200        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
201        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
202    }
203
204    void do_in_ack(ifxusb_core_if_t *_core_if)
205    {
206
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];
211
212        gint_data_t gintsts;
213        hctsiz_data_t hctsiz;
214        hcchar_data_t hcchar;
215        haint_data_t haint;
216        hcint_data_t hcint;
217        grxsts_data_t grxsts;
218
219        /* Enable HAINTs */
220        ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
221
222        /* Enable HCINTs */
223        ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
224
225        /* Read GINTSTS */
226        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
227        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
228
229        /* Read HAINT */
230        haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
231        //fprintf(stderr, "HAINT: %08x\n", haint.d32);
232
233        /* Read HCINT */
234        hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
235        //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
236
237        /* Read HCCHAR */
238        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
239        //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
240
241        /* Clear HCINT */
242        ifxusb_wreg(&hc_regs->hcint, hcint.d32);
243
244        /* Clear HAINT */
245        ifxusb_wreg(&hc_global_regs->haint, haint.d32);
246
247        /* Clear GINTSTS */
248        ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
249
250        /* Read GINTSTS */
251        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
252        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
253
254        /*
255         * Receive Control In packet
256         */
257
258        /* Make sure channel is disabled */
259        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
260        if (hcchar.b.chen) {
261            //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
262            hcchar.b.chdis = 1;
263            hcchar.b.chen = 1;
264            ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
265            //sleep(1);
266            mdelay(1000);
267
268            /* Read GINTSTS */
269            gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
270            //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
271
272            /* Read HAINT */
273            haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
274            //fprintf(stderr, "HAINT: %08x\n", haint.d32);
275
276            /* Read HCINT */
277            hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
278            //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
279
280            /* Read HCCHAR */
281            hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
282            //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
283
284            /* Clear HCINT */
285            ifxusb_wreg(&hc_regs->hcint, hcint.d32);
286
287            /* Clear HAINT */
288            ifxusb_wreg(&hc_global_regs->haint, haint.d32);
289
290            /* Clear GINTSTS */
291            ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
292
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);
296            //}
297        }
298
299        /* Set HCTSIZ */
300        hctsiz.d32 = 0;
301        hctsiz.b.xfersize = 8;
302        hctsiz.b.pktcnt = 1;
303        hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
304        ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
305
306        /* Set HCCHAR */
307        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
308        hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
309        hcchar.b.epdir = 1;
310        hcchar.b.epnum = 0;
311        hcchar.b.mps = 8;
312        hcchar.b.chen = 1;
313        ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
314
315        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
316        //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
317
318        /* Wait for receive status queue interrupt */
319        do {
320            gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
321        } while (gintsts.b.rxstsqlvl == 0);
322
323        //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
324
325        /* Read RXSTS */
326        grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
327        //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
328
329        /* Clear RXSTSQLVL in GINTSTS */
330        gintsts.d32 = 0;
331        gintsts.b.rxstsqlvl = 1;
332        ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
333
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) {
338                    int i;
339                    int word_count = (grxsts.hb.bcnt + 3) / 4;
340
341                    for (i = 0; i < word_count; i++) {
342                        (void)ifxusb_rreg(data_fifo++);
343                    }
344                }
345
346                //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.hb.bcnt);
347                break;
348
349            default:
350                //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
351                break;
352        }
353
354        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
355        //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
356
357        /* Wait for receive status queue interrupt */
358        do {
359            gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
360        } while (gintsts.b.rxstsqlvl == 0);
361
362        //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
363
364        /* Read RXSTS */
365        grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
366        //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
367
368        /* Clear RXSTSQLVL in GINTSTS */
369        gintsts.d32 = 0;
370        gintsts.b.rxstsqlvl = 1;
371        ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
372
373        switch (grxsts.hb.pktsts) {
374            case IFXUSB_HSTS_XFER_COMP:
375                break;
376
377            default:
378                //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
379                break;
380        }
381
382        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
383        //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
384
385        /* Wait for host channel interrupt */
386        do {
387            gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
388        } while (gintsts.b.hcintr == 0);
389
390        //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
391
392        /* Read HAINT */
393        haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
394        //fprintf(stderr, "HAINT: %08x\n", haint.d32);
395
396        /* Read HCINT */
397        hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
398        //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
399
400        /* Read HCCHAR */
401        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
402        //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
403
404        /* Clear HCINT */
405        ifxusb_wreg(&hc_regs->hcint, hcint.d32);
406
407        /* Clear HAINT */
408        ifxusb_wreg(&hc_global_regs->haint, haint.d32);
409
410        /* Clear GINTSTS */
411        ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
412
413        /* Read GINTSTS */
414        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
415        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
416
417    // usleep(100000);
418    // mdelay(100);
419        mdelay(1);
420
421        /*
422         * Send handshake packet
423         */
424
425        /* Read HAINT */
426        haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
427        //fprintf(stderr, "HAINT: %08x\n", haint.d32);
428
429        /* Read HCINT */
430        hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
431        //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
432
433        /* Read HCCHAR */
434        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
435        //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
436
437        /* Clear HCINT */
438        ifxusb_wreg(&hc_regs->hcint, hcint.d32);
439
440        /* Clear HAINT */
441        ifxusb_wreg(&hc_global_regs->haint, haint.d32);
442
443        /* Clear GINTSTS */
444        ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
445
446        /* Read GINTSTS */
447        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
448        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
449
450        /* Make sure channel is disabled */
451        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
452        if (hcchar.b.chen) {
453            //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
454            hcchar.b.chdis = 1;
455            hcchar.b.chen = 1;
456            ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
457            //sleep(1);
458            mdelay(1000);
459
460            /* Read GINTSTS */
461            gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
462            //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
463
464            /* Read HAINT */
465            haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
466            //fprintf(stderr, "HAINT: %08x\n", haint.d32);
467
468            /* Read HCINT */
469            hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
470            //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
471
472            /* Read HCCHAR */
473            hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
474            //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
475
476            /* Clear HCINT */
477            ifxusb_wreg(&hc_regs->hcint, hcint.d32);
478
479            /* Clear HAINT */
480            ifxusb_wreg(&hc_global_regs->haint, haint.d32);
481
482            /* Clear GINTSTS */
483            ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
484
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);
488            //}
489        }
490
491        /* Set HCTSIZ */
492        hctsiz.d32 = 0;
493        hctsiz.b.xfersize = 0;
494        hctsiz.b.pktcnt = 1;
495        hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
496        ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
497
498        /* Set HCCHAR */
499        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
500        hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
501        hcchar.b.epdir = 0;
502        hcchar.b.epnum = 0;
503        hcchar.b.mps = 8;
504        hcchar.b.chen = 1;
505        ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
506
507        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
508        //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
509
510        /* Wait for host channel interrupt */
511        do {
512            gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
513        } while (gintsts.b.hcintr == 0);
514
515        //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
516
517        /* Disable HCINTs */
518        ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
519
520        /* Disable HAINTs */
521        ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
522
523        /* Read HAINT */
524        haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
525        //fprintf(stderr, "HAINT: %08x\n", haint.d32);
526
527        /* Read HCINT */
528        hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
529        //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
530
531        /* Read HCCHAR */
532        hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
533        //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
534
535        /* Clear HCINT */
536        ifxusb_wreg(&hc_regs->hcint, hcint.d32);
537
538        /* Clear HAINT */
539        ifxusb_wreg(&hc_global_regs->haint, haint.d32);
540
541        /* Clear GINTSTS */
542        ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
543
544        /* Read GINTSTS */
545        gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
546        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
547    }
548#endif //__WITH_HS_ELECT_TST__
549
550

Archive Download this file



interactive