1 From 518d6418815f8ee4189b5ac3455a580fa5f3d3a6 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Sun, 11 Mar 2012 15:59:39 +0100
4 Subject: [PATCH 46/70] MIPS: adds ifxhcd
7 arch/mips/lantiq/xway/Makefile | 2 +-
8 arch/mips/lantiq/xway/dev-ifxhcd.c | 45 +
9 arch/mips/lantiq/xway/dev-ifxhcd.h | 17 +
10 arch/mips/lantiq/xway/sysctrl.c | 2 +
11 drivers/usb/Kconfig | 2 +
12 drivers/usb/Makefile | 2 +
13 drivers/usb/ifxhcd/Kconfig | 58 +
14 drivers/usb/ifxhcd/Makefile | 85 +
15 drivers/usb/ifxhcd/TagHistory | 171 ++
16 drivers/usb/ifxhcd/ifxhcd.c | 2523 +++++++++++++++++++++++
17 drivers/usb/ifxhcd/ifxhcd.h | 628 ++++++
18 drivers/usb/ifxhcd/ifxhcd_es.c | 549 +++++
19 drivers/usb/ifxhcd/ifxhcd_intr.c | 3742 +++++++++++++++++++++++++++++++++++
20 drivers/usb/ifxhcd/ifxhcd_queue.c | 418 ++++
21 drivers/usb/ifxhcd/ifxusb_cif.c | 1458 ++++++++++++++
22 drivers/usb/ifxhcd/ifxusb_cif.h | 665 +++++++
23 drivers/usb/ifxhcd/ifxusb_cif_d.c | 458 +++++
24 drivers/usb/ifxhcd/ifxusb_cif_h.c | 846 ++++++++
25 drivers/usb/ifxhcd/ifxusb_ctl.c | 1385 +++++++++++++
26 drivers/usb/ifxhcd/ifxusb_driver.c | 970 +++++++++
27 drivers/usb/ifxhcd/ifxusb_plat.h | 1018 ++++++++++
28 drivers/usb/ifxhcd/ifxusb_regs.h | 1420 +++++++++++++
29 drivers/usb/ifxhcd/ifxusb_version.h | 5 +
30 23 files changed, 16468 insertions(+), 1 deletions(-)
31 create mode 100644 arch/mips/lantiq/xway/dev-ifxhcd.c
32 create mode 100644 arch/mips/lantiq/xway/dev-ifxhcd.h
33 create mode 100644 drivers/usb/ifxhcd/Kconfig
34 create mode 100644 drivers/usb/ifxhcd/Makefile
35 create mode 100644 drivers/usb/ifxhcd/TagHistory
36 create mode 100644 drivers/usb/ifxhcd/ifxhcd.c
37 create mode 100644 drivers/usb/ifxhcd/ifxhcd.h
38 create mode 100644 drivers/usb/ifxhcd/ifxhcd_es.c
39 create mode 100644 drivers/usb/ifxhcd/ifxhcd_intr.c
40 create mode 100644 drivers/usb/ifxhcd/ifxhcd_queue.c
41 create mode 100644 drivers/usb/ifxhcd/ifxusb_cif.c
42 create mode 100644 drivers/usb/ifxhcd/ifxusb_cif.h
43 create mode 100644 drivers/usb/ifxhcd/ifxusb_cif_d.c
44 create mode 100644 drivers/usb/ifxhcd/ifxusb_cif_h.c
45 create mode 100644 drivers/usb/ifxhcd/ifxusb_ctl.c
46 create mode 100644 drivers/usb/ifxhcd/ifxusb_driver.c
47 create mode 100644 drivers/usb/ifxhcd/ifxusb_plat.h
48 create mode 100644 drivers/usb/ifxhcd/ifxusb_regs.h
49 create mode 100644 drivers/usb/ifxhcd/ifxusb_version.h
51 diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
52 index 4c3106f..c9baf91 100644
53 --- a/arch/mips/lantiq/xway/Makefile
54 +++ b/arch/mips/lantiq/xway/Makefile
56 -obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o prom.o nand.o timer.o
57 +obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o prom.o nand.o timer.o dev-ifxhcd.o
59 obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
60 obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
61 diff --git a/arch/mips/lantiq/xway/dev-ifxhcd.c b/arch/mips/lantiq/xway/dev-ifxhcd.c
63 index 0000000..ea08a35
65 +++ b/arch/mips/lantiq/xway/dev-ifxhcd.c
68 + * This program is free software; you can redistribute it and/or modify
69 + * it under the terms of the GNU General Public License as published by
70 + * the Free Software Foundation; either version 2 of the License, or
71 + * (at your option) any later version.
73 + * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
76 +#include <linux/init.h>
77 +#include <linux/module.h>
78 +#include <linux/types.h>
79 +#include <linux/string.h>
80 +#include <linux/mtd/physmap.h>
81 +#include <linux/kernel.h>
82 +#include <linux/reboot.h>
83 +#include <linux/platform_device.h>
84 +#include <linux/leds.h>
85 +#include <linux/etherdevice.h>
86 +#include <linux/reboot.h>
87 +#include <linux/time.h>
88 +#include <linux/io.h>
89 +#include <linux/gpio.h>
90 +#include <linux/leds.h>
92 +#include <asm/bootinfo.h>
95 +#include <lantiq_soc.h>
96 +#include <lantiq_irq.h>
97 +#include <lantiq_platform.h>
99 +static u64 dmamask = (u32)0x1fffffff;
101 +static struct platform_device platform_dev = {
102 + .name = "ifxusb_hcd",
103 + .dev.dma_mask = &dmamask,
107 +xway_register_hcd(int *pins)
109 + platform_dev.dev.platform_data = pins;
110 + return platform_device_register(&platform_dev);
112 diff --git a/arch/mips/lantiq/xway/dev-ifxhcd.h b/arch/mips/lantiq/xway/dev-ifxhcd.h
114 index 0000000..18b3d2d
116 +++ b/arch/mips/lantiq/xway/dev-ifxhcd.h
119 + * This program is free software; you can redistribute it and/or modify
120 + * it under the terms of the GNU General Public License as published by
121 + * the Free Software Foundation; either version 2 of the License, or
122 + * (at your option) any later version.
124 + * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
127 +#ifndef _LTQ_DEV_HCD_H__
128 +#define _LTQ_DEV_HCD_H__
130 +#include <lantiq_platform.h>
132 +extern void __init xway_register_hcd(int *pin);
135 diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
136 index 1a2e2d4..ac7383f 100644
137 --- a/arch/mips/lantiq/xway/sysctrl.c
138 +++ b/arch/mips/lantiq/xway/sysctrl.c
139 @@ -166,6 +166,8 @@ void __init ltq_soc_init(void)
140 clkdev_add_pmu("ltq_pcie", "pdi", 1, PMU1_PCIE_PDI);
141 clkdev_add_pmu("ltq_pcie", "ctl", 1, PMU1_PCIE_CTL);
142 clkdev_add_pmu("ltq_pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
143 + clkdev_add_pmu("usb0", NULL, 0, (1<<6) | 1);
144 + clkdev_add_pmu("usb1", NULL, 0, (1<<26) | (1<<27));
146 clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
147 ltq_danube_io_region_clock());
148 diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
149 index 8469e23..f69cc4a 100644
150 --- a/drivers/usb/Kconfig
151 +++ b/drivers/usb/Kconfig
152 @@ -184,4 +184,6 @@ source "drivers/usb/gadget/Kconfig"
154 source "drivers/usb/otg/Kconfig"
156 +source "drivers/usb/ifxhcd/Kconfig"
159 diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
160 index d46b792..7068e99 100644
161 --- a/drivers/usb/Makefile
162 +++ b/drivers/usb/Makefile
163 @@ -58,3 +58,5 @@ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/
164 obj-$(CONFIG_USB_GADGET) += gadget/
166 obj-$(CONFIG_USB_COMMON) += usb-common.o
168 +obj-$(CONFIG_USB_HOST_IFX) += ifxhcd/
169 diff --git a/drivers/usb/ifxhcd/Kconfig b/drivers/usb/ifxhcd/Kconfig
171 index 0000000..7eb8ceb
173 +++ b/drivers/usb/ifxhcd/Kconfig
177 + tristate "Infineon USB Host Controller Driver"
181 + Infineon USB Host Controller
183 +config USB_HOST_IFX_B
184 + bool "USB host mode on core 1 and 2"
185 + depends on USB_HOST_IFX
187 + Both cores run as host
189 +#config USB_HOST_IFX_1
190 +#config USB_HOST_IFX_2
193 +#config IFX_AMAZON_SE
195 + depends on USB_HOST_IFX
199 + depends on USB_HOST_IFX
202 +#config USB_HOST_IFX_FORCE_USB11
203 +# bool "Forced USB1.1"
204 +# depends on USB_HOST_IFX
207 +# force to be USB 1.1
209 +#config USB_HOST_IFX_WITH_HS_ELECT_TST
210 +# bool "With HS_Electrical Test"
211 +# depends on USB_HOST_IFX
214 +# With USBIF HSET routines
216 +#config USB_HOST_IFX_WITH_ISO
217 +# bool "With ISO transfer"
218 +# depends on USB_HOST_IFX
221 +# With USBIF ISO transfer
223 +config USB_HOST_IFX_UNALIGNED_ADJ
225 + depends on USB_HOST_IFX
227 + USB_HOST_IFX_UNALIGNED_ADJ
229 +#config USB_HOST_IFX_UNALIGNED_CHK
230 +#config USB_HOST_IFX_UNALIGNED_NONE
233 diff --git a/drivers/usb/ifxhcd/Makefile b/drivers/usb/ifxhcd/Makefile
235 index 0000000..0a2ac99
237 +++ b/drivers/usb/ifxhcd/Makefile
241 +# Makefile for USB Core files and filesystem
243 + ifxusb_host-objs := ifxusb_driver.o
244 + ifxusb_host-objs += ifxusb_ctl.o
245 + ifxusb_host-objs += ifxusb_cif.o
246 + ifxusb_host-objs += ifxusb_cif_h.o
247 + ifxusb_host-objs += ifxhcd.o
248 + ifxusb_host-objs += ifxhcd_es.o
249 + ifxusb_host-objs += ifxhcd_intr.o
250 + ifxusb_host-objs += ifxhcd_queue.o
252 +ifeq ($(CONFIG_IFX_TWINPASS),y)
253 + EXTRA_CFLAGS += -D__IS_TWINPASS__
255 +ifeq ($(CONFIG_IFX_DANUBE),y)
256 + EXTRA_CFLAGS += -D__IS_DANUBE__
258 +ifeq ($(CONFIG_IFX_AMAZON_SE),y)
259 + EXTRA_CFLAGS += -D__IS_AMAZON_SE__
261 +ifeq ($(CONFIG_IFX_AR9),y)
262 + EXTRA_CFLAGS += -D__IS_AR9__
264 +ifeq ($(CONFIG_IFX_AMAZON_S),y)
265 + EXTRA_CFLAGS += -D__IS_AR9__
267 +ifeq ($(CONFIG_IFX_VR9),y)
268 + EXTRA_CFLAGS += -D__IS_VR9__
271 +ifeq ($(CONFIG_USB_HOST_IFX),y)
272 + EXTRA_CFLAGS += -Dlinux -D__LINUX__
273 + EXTRA_CFLAGS += -D__IS_HOST__
274 + EXTRA_CFLAGS += -D__KERNEL__
277 +ifeq ($(CONFIG_USB_HOST_IFX),m)
278 + EXTRA_CFLAGS += -Dlinux -D__LINUX__
279 + EXTRA_CFLAGS += -D__IS_HOST__
280 + EXTRA_CFLAGS += -D__KERNEL__
283 +ifeq ($(CONFIG_USB_DEBUG),y)
284 + EXTRA_CFLAGS += -D__DEBUG__
285 + EXTRA_CFLAGS += -D__ENABLE_DUMP__
288 +ifeq ($(CONFIG_USB_HOST_IFX_B),y)
289 + EXTRA_CFLAGS += -D__IS_DUAL__
291 +ifeq ($(CONFIG_USB_HOST_IFX_1),y)
292 + EXTRA_CFLAGS += -D__IS_FIRST__
294 +ifeq ($(CONFIG_USB_HOST_IFX_2),y)
295 + EXTRA_CFLAGS += -D__IS_SECOND__
298 +ifeq ($(CONFIG_USB_HOST_IFX_FORCE_USB11),y)
299 + EXTRA_CFLAGS += -D__FORCE_USB11__
301 +ifeq ($(CONFIG_USB_HOST_IFX_WITH_HS_ELECT_TST),y)
302 + EXTRA_CFLAGS += -D__WITH_HS_ELECT_TST__
304 +ifeq ($(CONFIG_USB_HOST_IFX_WITH_ISO),y)
305 + EXTRA_CFLAGS += -D__EN_ISOC__
307 +ifeq ($(CONFIG_USB_HOST_IFX_UNALIGNED_ADJ),y)
308 + EXTRA_CFLAGS += -D__UNALIGNED_BUFFER_ADJ__
310 +ifeq ($(CONFIG_USB_HOST_IFX_UNALIGNED_CHK),y)
311 + EXTRA_CFLAGS += -D__UNALIGNED_BUFFER_CHK__
314 +# EXTRA_CFLAGS += -D__DYN_SOF_INTR__
315 + EXTRA_CFLAGS += -D__UEIP__
316 +# EXTRA_CFLAGS += -D__EN_ISOC__
317 +# EXTRA_CFLAGS += -D__EN_ISOC_SPLIT__
319 +## 20110628 AVM/WK New flag for less SOF IRQs
320 + EXTRA_CFLAGS += -D__USE_TIMER_4_SOF__
322 +obj-$(CONFIG_USB_HOST_IFX) += ifxusb_host.o
324 diff --git a/drivers/usb/ifxhcd/TagHistory b/drivers/usb/ifxhcd/TagHistory
326 index 0000000..3820d70
328 +++ b/drivers/usb/ifxhcd/TagHistory
332 ++----------------------------------------------------------------------+
333 +| TAG: svn://embeddedvm/home/SVN/drivers/usb_host20/tags/5.18-r240-non_musb_ar9_vr9-SOF_Timer_Fixed
334 +| Erzeugt mit SVN-Tagger Version 3.74.
335 ++----------------------------------------------------------------------+
336 +FIX - Korrektur bei der SOF-Timer/IRQ Steuerung. (Bug in Tag 5.17)
337 +FIX - Fehlerbehandlung an mehreren Stellen korrigiert bzw. eingebaut.
341 ++----------------------------------------------------------------------+
342 +| TAG: svn://embeddedvm/home/SVN/drivers/usb_host20/tags/5.17-r237-non_musb_ar9_vr9-2_6_32_41_Kompatibel
343 +| Erzeugt mit SVN-Tagger Version 3.73.
344 ++----------------------------------------------------------------------+
345 +FIX - Kompatiblität zum Update auf Kernel 2.6.32-41. Weiterhin für 28er geeignet.
346 +ENH - Reduktion der Interrruptlast durch Nutzung eines hrtimers anstatt SOF-IRQ.
350 ++----------------------------------------------------------------------+
351 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.16-r208-non_musb_ar9_vr9-20110421_Zero_Paket_Optimiert
352 +| Erzeugt mit SVN-Tagger Version 3.66.
353 ++----------------------------------------------------------------------+
355 +FIX - VR9 / AR9 - Zero Packet. Optimierung korrigiert.
359 ++----------------------------------------------------------------------+
360 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.15-r205-non_musb_ar9_vr9-20110421_Zero_Paket_WA_funktioniert
361 +| Erzeugt mit SVN-Tagger Version 3.66.
362 ++----------------------------------------------------------------------+
364 +FIX - VR9 / AR9 - "Zero Packet" funktioniert nun wirklich. Letzter Tag hatte einen Bug.
368 ++----------------------------------------------------------------------+
369 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.14-r202-non_musb_ar9_vr9-20110420_Zero_Paket_WA
370 +| Erzeugt mit SVN-Tagger Version 3.66.
371 ++----------------------------------------------------------------------+
373 +FIX - VR9 / AR9 - Zero Packet Workaround: ZLP wird nun geschickt wenn URB_ZERO_PACKET aktiv ist.
374 + Wird von LTE Altair Firmware benoetig.
378 ++----------------------------------------------------------------------+
379 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.13-r199-non_musb_ar9_vr9-20110310_Init_Fix
380 +| Erzeugt mit SVN-Tagger Version 3.64.
381 ++----------------------------------------------------------------------+
383 +FIX - VR9 / AR9 - Timing der Initialisierungsphase angepasst zum Kernel 2.6.28 mit UGW-4.3.1.
387 ++----------------------------------------------------------------------+
388 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.12-r184-non_musb_ar9_vr9-20110118_Full_Speed_Fix
389 +| Erzeugt mit SVN-Tagger Version 3.58.
390 ++----------------------------------------------------------------------+
391 +AR9/VR9 (3370,6840,7320):
392 +Makefile - FIX - (Workaround) Debug Modus hilft gegen Enumerationsfehler bei Full Speed Drucker.
396 ++----------------------------------------------------------------------+
397 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.11-r175-non_musb_ar9_vr9-20101220_VR9_2_Ports_DMA_Fix
398 +| Erzeugt mit SVN-Tagger Version 3.58.
399 ++----------------------------------------------------------------------+
401 +FIX - VR9 - Workaround DMA Burst Size. Wenn beiden USB Ports benutzt werden, geht der USB Host nicht mehr.
405 ++----------------------------------------------------------------------+
406 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.10-r169-non_musb_ar9_vr9-Fix_Spontan_Reboot
407 +| Erzeugt mit SVN-Tagger Version 3.58.
408 ++----------------------------------------------------------------------+
410 +FIX - Endlosschleife führte zu einem spontanen Reboot.
414 ++----------------------------------------------------------------------+
415 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.9-r166-non_musb_ar9_vr9-20101112_deferred_completion
416 +| Erzeugt mit SVN-Tagger Version 3.58.
417 ++----------------------------------------------------------------------+
419 +ENH - Deferred URB Completion Mechanismus eingebaut. Nun ca. 10% schneller bei usb-storage.
421 +FIX - PING Flow Control gefixt.
422 +FIX - Channel Halt wird nun immer angerufen. (Split Transaction wurde nicht erfolgreich gestoppt).
423 +FIX - Spinlock Benutzung verbessert. Mehr Stabilitaet.
425 +CHG - Ubersetztungsoption __DEBUG__ ist nun abhaengig von CONFIG_USB_DEBUG
429 ++----------------------------------------------------------------------+
430 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.8-r149-non_musb_ar9_vr9-20100827_LTE_Interrupt_EP_Fix
431 +| Erzeugt mit SVN-Tagger Version 3.57.
432 ++----------------------------------------------------------------------+
433 +AR9/VR9 - FIX - Interrupt Packets gingen verloren, wegen falschem Timing beim OddFrame Bit.
437 ++----------------------------------------------------------------------+
438 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.7-r142-non_musb_ar9_vr9-20100728_Unaligned_Buf_Fix
439 +| Erzeugt mit SVN-Tagger Version 3.57.
440 ++----------------------------------------------------------------------+
441 +FIX - "Unaligned Data" Flag wieder nach Transfer geloescht.
445 ++----------------------------------------------------------------------+
446 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.6-r133-non_musb_ar9_vr9-20100714_Toggle_Datenverlust_Fix
447 +| Erzeugt mit SVN-Tagger Version 3.57.
448 ++----------------------------------------------------------------------+
449 +TL5508 - Einige UMTS Modems funktionierten nicht korrekt an der 7320 (AR9).
450 +FIX - USB Data Toggle des usbcore benutzen. Datenverlust nach EP-Halt.
454 ++----------------------------------------------------------------------+
455 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.5-r130-non_musb_ar9_vr9-20100712_USB_Ports_abschaltbar
456 +| Erzeugt mit SVN-Tagger Version 3.57.
457 ++----------------------------------------------------------------------+
458 +Power - Fix - Beide USB Port abschaltbar bei rmmod.
459 +rmmod - FIX - URB_Dequeue funktionierte beim Entladen des Treibers nicht (mehrere Ursachen).
463 ++----------------------------------------------------------------------+
464 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.4-r126-non_musb_ar9_vr9-20100701_Lost_Interrupt_Workaround
465 +| Erzeugt mit SVN-Tagger Version 3.57.
466 ++----------------------------------------------------------------------+
467 +FIX - Workaround wegen verpasstem Interrupt, bei Full-Speed Interrupt EP.
470 ++----------------------------------------------------------------------+
471 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.3-r123-non_musb_ar9_vr9-20100630_UMTS_Fixes
472 +| Erzeugt mit SVN-Tagger Version 3.57.
473 ++----------------------------------------------------------------------+
474 +FIX - Full-Speed Interrupt Endpoint hinter Hi-Speed Hub funktioniert nun (UMTS Modems)
475 +FIX - usb_hcd_link_urb_from_ep API von USBCore muss benutzt werden.
476 +FIX - Interrupt URBs nicht bei NAK completen.
479 ++----------------------------------------------------------------------+
480 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.2-r114-non_musb_ar9_vr9-20100520_StickAndSurf_funktioniert
481 +| Erzeugt mit SVN-Tagger Version 3.56.
482 ++----------------------------------------------------------------------+
483 +- Merge mit neuen LANTIQ Sourcen "3.0alpha B100312"
484 +- Fix - Spin_lock eingebaut, Stick&Surf funktioniert nun
486 +- DEP - CONFIG_USB_HOST_IFX_WITH_ISO wird nicht unterstuetzt: In der Kernel Config deaktivieren.
490 ++----------------------------------------------------------------------+
491 +| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.1-r107-non_musb_ar9_vr9-20100505_IFXUSB_Host_mit_Energiemonitor
492 +| Erzeugt mit SVN-Tagger Version 3.56.
493 ++----------------------------------------------------------------------+
494 +USB Host Treiber für AR9 und VR9
495 +--------------------------------
496 +FIX - Toggle Error nach STALL - Einfacher Workaround - Nun werden Massenspeicherpartitionen erkannt!
497 +AVM_POWERMETER - USB Energiemonitor Support.
499 +Bekanntes Problem: Stick and Surf funktioniert nur sporadisch, weil CONTROL_IRQ manchmal ausbleibt.
501 diff --git a/drivers/usb/ifxhcd/ifxhcd.c b/drivers/usb/ifxhcd/ifxhcd.c
503 index 0000000..d2ae125
505 +++ b/drivers/usb/ifxhcd/ifxhcd.c
507 +/*****************************************************************************
508 + ** FILE NAME : ifxhcd.c
509 + ** PROJECT : IFX USB sub-system V3
510 + ** MODULES : IFX USB sub-system Host and Device driver
511 + ** SRC VERSION : 1.0
512 + ** DATE : 1/Jan/2009
513 + ** AUTHOR : Chen, Howard
514 + ** DESCRIPTION : This file contains the structures, constants, and interfaces for
515 + ** the Host Contoller Driver (HCD).
517 + ** The Host Controller Driver (HCD) is responsible for translating requests
518 + ** from the USB Driver into the appropriate actions on the IFXUSB controller.
519 + ** It isolates the USBD from the specifics of the controller by providing an
520 + ** API to the USBD.
521 + *****************************************************************************/
525 + \ingroup IFXUSB_DRIVER_V3
526 + \brief This file contains the implementation of the HCD. In Linux,
527 + the HCD implements the hc_driver API.
530 +#include <linux/version.h>
531 +#include "ifxusb_version.h"
533 +#include <linux/kernel.h>
534 +#include <linux/module.h>
535 +#include <linux/moduleparam.h>
536 +#include <linux/init.h>
538 +#include <linux/device.h>
540 +#include <linux/errno.h>
541 +#include <linux/list.h>
542 +#include <linux/interrupt.h>
543 +#include <linux/string.h>
545 +#include <linux/dma-mapping.h>
548 +#include "ifxusb_plat.h"
549 +#include "ifxusb_regs.h"
550 +#include "ifxusb_cif.h"
553 +#include <asm/irq.h>
555 +#ifdef CONFIG_AVM_POWERMETER
556 +#include <linux/avm_power.h>
557 +#endif /*--- #ifdef CONFIG_AVM_POWERMETER ---*/
560 + static void dump_urb_info(struct urb *_urb, char* _fn_name);
561 + static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh);
566 + \brief Sets the final status of an URB and returns it to the device driver. Any
567 + required cleanup of the URB is performed.
569 +void ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status)
571 + struct urb *urb=NULL;
572 + unsigned long flags = 0;
574 + /*== AVM/BC 20101111 Function called with Lock ==*/
575 + //SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
577 + if (!list_empty(&_urbd->urbd_list_entry))
578 + list_del_init (&_urbd->urbd_list_entry);
582 + IFX_ERROR("%s: invalid urb\n",__func__);
583 + /*== AVM/BC 20101111 Function called with Lock ==*/
584 + //SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
591 + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
593 + IFX_PRINT("%s: _urbd %p, urb %p, device %d, ep %d %s/%s, status=%d\n",
594 + __func__, _urbd,_urbd->urb, usb_pipedevice(_urbd->urb->pipe),
595 + usb_pipeendpoint(_urbd->urb->pipe),
596 + usb_pipein(_urbd->urb->pipe) ? "IN" : "OUT",
597 + (_urbd->is_in) ? "IN" : "OUT",
599 + if (_urbd->epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
602 + for (i = 0; i < _urbd->urb->number_of_packets; i++)
603 + IFX_PRINT(" ISO Desc %d status: %d\n", i, _urbd->urb->iso_frame_desc[i].status);
609 + IFX_ERROR("%s: invalid epqd\n",__func__);
611 + #if defined(__UNALIGNED_BUFFER_ADJ__)
612 + else if(_urbd->is_active)
614 + if( _urbd->epqh->aligned_checked &&
615 + _urbd->epqh->using_aligned_buf &&
616 + _urbd->xfer_buff &&
618 + memcpy(_urbd->xfer_buff,_urbd->epqh->aligned_buf,_urbd->xfer_len);
619 + _urbd->epqh->using_aligned_buf=0;
620 + _urbd->epqh->using_aligned_setup=0;
621 + _urbd->epqh->aligned_checked=0;
625 + urb->status = _status;
629 + usb_hcd_unlink_urb_from_ep(ifxhcd_to_syshcd(_ifxhcd), urb);
630 + SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
632 +// usb_hcd_giveback_urb(ifxhcd_to_syshcd(_ifxhcd), urb);
633 + usb_hcd_giveback_urb(ifxhcd_to_syshcd(_ifxhcd), urb, _status);
635 + /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/
636 + SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
639 +/*== AVM/BC 20101111 URB Complete deferred
640 + * Must be called with Spinlock
644 + \brief Inserts an urbd structur in the completion list. The urbd will be
645 + later completed by select_eps_sub
647 +void defer_ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status)
650 + _urbd->status = _status;
652 + //Unlink Urbd from epqh / Insert it into the complete list
653 + list_move_tail(&_urbd->urbd_list_entry, &_ifxhcd->urbd_complete_list);
658 + \brief Processes all the URBs in a single EPQHs. Completes them with
659 + status and frees the URBD.
662 +void kill_all_urbs_in_epqh(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh, int _status)
664 + struct list_head *urbd_item;
665 + ifxhcd_urbd_t *urbd;
670 + for (urbd_item = _epqh->urbd_list.next;
671 + urbd_item != &_epqh->urbd_list;
672 + urbd_item = _epqh->urbd_list.next)
674 + urbd = list_entry(urbd_item, ifxhcd_urbd_t, urbd_list_entry);
675 + ifxhcd_complete_urb(_ifxhcd, urbd, _status);
681 + \brief Free all EPS in one Processes all the URBs in a single list of EPQHs. Completes them with
682 + -ETIMEDOUT and frees the URBD.
685 +void epqh_list_free(ifxhcd_hcd_t *_ifxhcd, struct list_head *_epqh_list)
687 + struct list_head *item;
688 + ifxhcd_epqh_t *epqh;
692 + if (_epqh_list->next == NULL) /* The list hasn't been initialized yet. */
695 + /* Ensure there are no URBDs or URBs left. */
696 + for (item = _epqh_list->next; item != _epqh_list; item = _epqh_list->next)
698 + epqh = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
699 + kill_all_urbs_in_epqh(_ifxhcd, epqh, -ETIMEDOUT);
700 + ifxhcd_epqh_free(epqh);
707 +void epqh_list_free_all(ifxhcd_hcd_t *_ifxhcd)
709 + unsigned long flags;
711 + /*== AVM/BC 20101111 - 2.6.28 Needs Spinlock ==*/
712 + SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
714 + epqh_list_free(_ifxhcd, &_ifxhcd->epqh_np_active );
715 + epqh_list_free(_ifxhcd, &_ifxhcd->epqh_np_ready );
716 + epqh_list_free(_ifxhcd, &_ifxhcd->epqh_intr_active );
717 + epqh_list_free(_ifxhcd, &_ifxhcd->epqh_intr_ready );
719 + epqh_list_free(_ifxhcd, &_ifxhcd->epqh_isoc_active );
720 + epqh_list_free(_ifxhcd, &_ifxhcd->epqh_isoc_ready );
722 + epqh_list_free(_ifxhcd, &_ifxhcd->epqh_stdby );
724 + SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
730 + \brief This function is called to handle the disconnection of host port.
732 +int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd)
734 + IFX_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _ifxhcd);
736 + /* Set status flags for the hub driver. */
737 + _ifxhcd->flags.b.port_connect_status_change = 1;
738 + _ifxhcd->flags.b.port_connect_status = 0;
741 + * Shutdown any transfers in process by clearing the Tx FIFO Empty
742 + * interrupt mask and status bits and disabling subsequent host
743 + * channel interrupts.
746 + gint_data_t intr = { .d32 = 0 };
747 + intr.b.nptxfempty = 1;
748 + intr.b.ptxfempty = 1;
750 + ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gintmsk, intr.d32, 0);
751 + ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gintsts, intr.d32, 0);
754 + /* Respond with an error status to all URBs in the schedule. */
755 + epqh_list_free_all(_ifxhcd);
757 + /* Clean up any host channels that were in use. */
760 + ifxhcd_hc_t *channel;
761 + ifxusb_hc_regs_t *hc_regs;
762 + hcchar_data_t hcchar;
765 + num_channels = _ifxhcd->core_if.params.host_channels;
767 + for (i = 0; i < num_channels; i++)
769 + channel = &_ifxhcd->ifxhc[i];
770 + if (list_empty(&channel->hc_list_entry))
772 + hc_regs = _ifxhcd->core_if.hc_regs[i];
773 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
776 + /* Halt the channel. */
777 + hcchar.b.chdis = 1;
778 + ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
780 + list_add_tail(&channel->hc_list_entry, &_ifxhcd->free_hc_list);
781 + ifxhcd_hc_cleanup(&_ifxhcd->core_if, channel);
790 + \brief Frees secondary storage associated with the ifxhcd_hcd structure contained
791 + in the struct usb_hcd field.
793 +static void ifxhcd_freeextra(struct usb_hcd *_syshcd)
795 + ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
797 + IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD FREE\n");
799 + /* Free memory for EPQH/URBD lists */
800 + epqh_list_free_all(ifxhcd);
802 + /* Free memory for the host channels. */
803 + ifxusb_free_buf(ifxhcd->status_buf);
806 +#ifdef __USE_TIMER_4_SOF__
807 +static enum hrtimer_restart ifxhcd_timer_func(struct hrtimer *timer) {
808 + ifxhcd_hcd_t *ifxhcd = container_of(timer, ifxhcd_hcd_t, hr_timer);
810 + ifxhcd_handle_intr(ifxhcd);
812 + return HRTIMER_NORESTART;
817 + \brief Initializes the HCD. This function allocates memory for and initializes the
818 + static parts of the usb_hcd and ifxhcd_hcd structures. It also registers the
819 + USB bus with the core and calls the hc_driver->start() function. It returns
820 + a negative error on failure.
822 +int ifxhcd_init(ifxhcd_hcd_t *_ifxhcd)
825 + struct usb_hcd *syshcd = NULL;
827 + IFX_DEBUGPL(DBG_HCD, "IFX USB HCD INIT\n");
829 + spin_lock_init(&_ifxhcd->lock);
830 +#ifdef __USE_TIMER_4_SOF__
831 + hrtimer_init(&_ifxhcd->hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
832 + _ifxhcd->hr_timer.function = ifxhcd_timer_func;
834 + _ifxhcd->hc_driver.description = _ifxhcd->core_if.core_name;
835 + _ifxhcd->hc_driver.product_desc = "IFX USB Controller";
836 + //_ifxhcd->hc_driver.hcd_priv_size = sizeof(ifxhcd_hcd_t);
837 + _ifxhcd->hc_driver.hcd_priv_size = sizeof(unsigned long);
838 + _ifxhcd->hc_driver.irq = ifxhcd_irq;
839 + _ifxhcd->hc_driver.flags = HCD_MEMORY | HCD_USB2;
840 + _ifxhcd->hc_driver.start = ifxhcd_start;
841 + _ifxhcd->hc_driver.stop = ifxhcd_stop;
842 + //_ifxhcd->hc_driver.reset =
843 + //_ifxhcd->hc_driver.suspend =
844 + //_ifxhcd->hc_driver.resume =
845 + _ifxhcd->hc_driver.urb_enqueue = ifxhcd_urb_enqueue;
846 + _ifxhcd->hc_driver.urb_dequeue = ifxhcd_urb_dequeue;
847 + _ifxhcd->hc_driver.endpoint_disable = ifxhcd_endpoint_disable;
848 + _ifxhcd->hc_driver.get_frame_number = ifxhcd_get_frame_number;
849 + _ifxhcd->hc_driver.hub_status_data = ifxhcd_hub_status_data;
850 + _ifxhcd->hc_driver.hub_control = ifxhcd_hub_control;
851 + //_ifxhcd->hc_driver.hub_suspend =
852 + //_ifxhcd->hc_driver.hub_resume =
854 + /* Allocate memory for and initialize the base HCD and */
855 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
856 + syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->core_if.core_name);
858 + syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->dev->bus_id);
861 + if (syshcd == NULL)
867 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
868 + syshcd->has_tt = 1;
871 + syshcd->rsrc_start = (unsigned long)_ifxhcd->core_if.core_global_regs;
872 + syshcd->regs = (void *)_ifxhcd->core_if.core_global_regs;
873 + syshcd->self.otg_port = 0;
875 + //*((unsigned long *)(&(syshcd->hcd_priv)))=(unsigned long)_ifxhcd;
876 + //*((unsigned long *)(&(syshcd->hcd_priv[0])))=(unsigned long)_ifxhcd;
877 + syshcd->hcd_priv[0]=(unsigned long)_ifxhcd;
878 + _ifxhcd->syshcd=syshcd;
880 + INIT_LIST_HEAD(&_ifxhcd->epqh_np_active );
881 + INIT_LIST_HEAD(&_ifxhcd->epqh_np_ready );
882 + INIT_LIST_HEAD(&_ifxhcd->epqh_intr_active );
883 + INIT_LIST_HEAD(&_ifxhcd->epqh_intr_ready );
885 + INIT_LIST_HEAD(&_ifxhcd->epqh_isoc_active );
886 + INIT_LIST_HEAD(&_ifxhcd->epqh_isoc_ready );
888 + INIT_LIST_HEAD(&_ifxhcd->epqh_stdby );
889 + INIT_LIST_HEAD(&_ifxhcd->urbd_complete_list);
892 + * Create a host channel descriptor for each host channel implemented
893 + * in the controller. Initialize the channel descriptor array.
895 + INIT_LIST_HEAD(&_ifxhcd->free_hc_list);
897 + int num_channels = _ifxhcd->core_if.params.host_channels;
899 + for (i = 0; i < num_channels; i++)
901 + _ifxhcd->ifxhc[i].hc_num = i;
902 + IFX_DEBUGPL(DBG_HCDV, "HCD Added channel #%d\n", i);
906 + /* Set device flags indicating whether the HCD supports DMA. */
907 + if(_ifxhcd->dev->dma_mask)
908 + *(_ifxhcd->dev->dma_mask) = ~0;
909 + _ifxhcd->dev->coherent_dma_mask = ~0;
912 + * Finish generic HCD initialization and start the HCD. This function
913 + * allocates the DMA buffer pool, registers the USB bus, requests the
914 + * IRQ line, and calls ifxusb_hcd_start method.
916 +// retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, SA_INTERRUPT|SA_SHIRQ);
917 + retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, IRQF_DISABLED | IRQF_SHARED );
922 + * Allocate space for storing data on status transactions. Normally no
923 + * data is sent, but this space acts as a bit bucket. This must be
924 + * done after usb_add_hcd since that function allocates the DMA buffer
927 + _ifxhcd->status_buf = ifxusb_alloc_buf(IFXHCD_STATUS_BUF_SIZE, 1);
929 + if (_ifxhcd->status_buf)
931 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
932 + IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd->core_if.core_name, syshcd->self.busnum);
934 + IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd->dev->bus_id, syshcd->self.busnum);
938 + IFX_ERROR("%s: status_buf allocation failed\n", __func__);
940 + /* Error conditions */
941 + usb_remove_hcd(syshcd);
943 + ifxhcd_freeextra(syshcd);
944 + usb_put_hcd(syshcd);
950 + \brief Removes the HCD.
951 + Frees memory and resources associated with the HCD and deregisters the bus.
953 +void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd)
955 + struct usb_hcd *syshcd = ifxhcd_to_syshcd(_ifxhcd);
957 + IFX_DEBUGPL(DBG_HCD, "IFX USB HCD REMOVE\n");
959 +/* == AVM/WK 20100709 - Fix: Order changed, disable IRQs not before remove_hcd == */
961 + usb_remove_hcd(syshcd);
963 + /* Turn off all interrupts */
964 + ifxusb_wreg (&_ifxhcd->core_if.core_global_regs->gintmsk, 0);
965 + ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gahbcfg, 1, 0);
967 + ifxhcd_freeextra(syshcd);
969 + usb_put_hcd(syshcd);
975 +/* =========================================================================
976 + * Linux HC Driver Functions
977 + * ========================================================================= */
980 + \brief Initializes the IFXUSB controller and its root hub and prepares it for host
981 + mode operation. Activates the root port. Returns 0 on success and a negative
982 + error code on failure.
983 + Called by USB stack.
985 +int ifxhcd_start(struct usb_hcd *_syshcd)
987 + ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
988 + ifxusb_core_if_t *core_if = &ifxhcd->core_if;
989 + struct usb_bus *bus;
991 + IFX_DEBUGPL(DBG_HCD, "IFX USB HCD START\n");
993 + bus = hcd_to_bus(_syshcd);
995 + /* Initialize the bus state. */
996 + _syshcd->state = HC_STATE_RUNNING;
998 + /* Initialize and connect root hub if one is not already attached */
1001 + IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Has Root Hub\n");
1002 + /* Inform the HUB driver to resume. */
1003 + usb_hcd_resume_root_hub(_syshcd);
1006 + ifxhcd->flags.d32 = 0;
1008 + /* Put all channels in the free channel list and clean up channel states.*/
1010 + struct list_head *item;
1011 + item = ifxhcd->free_hc_list.next;
1012 + while (item != &ifxhcd->free_hc_list)
1015 + item = ifxhcd->free_hc_list.next;
1019 + int num_channels = ifxhcd->core_if.params.host_channels;
1021 + for (i = 0; i < num_channels; i++)
1023 + ifxhcd_hc_t *channel;
1024 + channel = &ifxhcd->ifxhc[i];
1025 + list_add_tail(&channel->hc_list_entry, &ifxhcd->free_hc_list);
1026 + ifxhcd_hc_cleanup(&ifxhcd->core_if, channel);
1029 + /* Initialize the USB core for host mode operation. */
1031 + ifxusb_host_enable_interrupts(core_if);
1032 + ifxusb_enable_global_interrupts(core_if);
1033 + ifxusb_phy_power_on (core_if);
1035 + ifxusb_vbus_init(core_if);
1037 + /* Turn on the vbus power. */
1039 + hprt0_data_t hprt0;
1040 + hprt0.d32 = ifxusb_read_hprt0(core_if);
1042 + IFX_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
1043 + if (hprt0.b.prtpwr == 0 )
1045 + hprt0.b.prtpwr = 1;
1046 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1047 + ifxusb_vbus_on(core_if);
1055 + \brief Halts the IFXUSB host mode operations in a clean manner. USB transfers are
1058 +void ifxhcd_stop(struct usb_hcd *_syshcd)
1060 + ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
1061 + hprt0_data_t hprt0 = { .d32=0 };
1063 + IFX_DEBUGPL(DBG_HCD, "IFX USB HCD STOP\n");
1065 + /* Turn off all interrupts. */
1066 + ifxusb_disable_global_interrupts(&ifxhcd->core_if );
1067 + ifxusb_host_disable_interrupts(&ifxhcd->core_if );
1068 +#ifdef __USE_TIMER_4_SOF__
1069 + hrtimer_cancel(&ifxhcd->hr_timer);
1072 + * The root hub should be disconnected before this function is called.
1073 + * The disconnect will clear the URBD lists (via ..._hcd_urb_dequeue)
1074 + * and the EPQH lists (via ..._hcd_endpoint_disable).
1077 + /* Turn off the vbus power */
1078 + IFX_PRINT("PortPower off\n");
1080 + ifxusb_vbus_off(&ifxhcd->core_if );
1082 + ifxusb_vbus_free(&ifxhcd->core_if );
1084 + hprt0.b.prtpwr = 0;
1085 + ifxusb_wreg(ifxhcd->core_if.hprt0, hprt0.d32);
1090 + \brief Returns the current frame number
1092 +int ifxhcd_get_frame_number(struct usb_hcd *_syshcd)
1094 + ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
1095 + hfnum_data_t hfnum;
1097 + hfnum.d32 = ifxusb_rreg(&ifxhcd->core_if.host_global_regs->hfnum);
1099 + return hfnum.b.frnum;
1103 + \brief Starts processing a USB transfer request specified by a USB Request Block
1104 + (URB). mem_flags indicates the type of memory allocation to use while
1105 + processing this URB.
1107 +int ifxhcd_urb_enqueue( struct usb_hcd *_syshcd,
1108 + /*--- struct usb_host_endpoint *_sysep, Parameter im 2.6.28 entfallen ---*/
1113 + ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
1114 + struct usb_host_endpoint *_sysep = ifxhcd_urb_to_endpoint(_urb);
1115 + ifxhcd_epqh_t *epqh;
1118 + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
1119 + dump_urb_info(_urb, "ifxusb_hcd_urb_enqueue");
1120 + #endif //__DEBUG__
1122 + if (!ifxhcd->flags.b.port_connect_status) /* No longer connected. */
1125 + #ifndef __EN_ISOC__
1126 + if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
1128 + IFX_ERROR("ISOC transfer not supported!!!\n");
1133 + retval=ifxhcd_urbd_create (ifxhcd,_urb);
1137 + IFX_ERROR("IFXUSB HCD URB Enqueue failed creating URBD\n");
1140 + epqh = (ifxhcd_epqh_t *) _sysep->hcpriv;
1141 + ifxhcd_epqh_ready(ifxhcd, epqh);
1143 + select_eps(ifxhcd);
1144 + //enable_sof(ifxhcd);
1146 + gint_data_t gintsts;
1148 + gintsts.b.sofintr = 1;
1149 + ifxusb_mreg(&ifxhcd->core_if.core_global_regs->gintmsk, 0,gintsts.d32);
1156 + \brief Aborts/cancels a USB transfer request. Always returns 0 to indicate
1159 +int ifxhcd_urb_dequeue( struct usb_hcd *_syshcd,
1160 + struct urb *_urb, int status /* Parameter neu in 2.6.28 */)
1162 + unsigned long flags;
1163 + ifxhcd_hcd_t *ifxhcd;
1164 + ifxhcd_urbd_t *urbd;
1165 + ifxhcd_epqh_t *epqh;
1169 + struct usb_host_endpoint *_sysep;
1171 + IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD URB Dequeue\n");
1173 + #ifndef __EN_ISOC__
1174 + if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
1178 + _sysep = ifxhcd_urb_to_endpoint(_urb);
1180 + ifxhcd = syshcd_to_ifxhcd(_syshcd);
1182 + SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
1184 + /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/
1185 + rc = usb_hcd_check_unlink_urb(_syshcd, _urb, status);
1187 + SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
1191 + urbd = (ifxhcd_urbd_t *) _urb->hcpriv;
1194 + epqh = (ifxhcd_epqh_t *) _sysep->hcpriv;
1196 + epqh = (ifxhcd_epqh_t *) urbd->epqh;
1198 + if(epqh!=urbd->epqh)
1199 + IFX_ERROR("%s inconsistant epqh %p %p\n",__func__,epqh,urbd->epqh);
1202 + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
1204 + dump_urb_info(_urb, "ifxhcd_urb_dequeue");
1205 + if (epqh->is_active)
1206 + dump_channel_info(ifxhcd, epqh);
1208 + #endif //__DEBUG__
1211 + epqh->is_active=0;
1212 + else if (!ifxhcd->flags.b.port_connect_status)
1213 + epqh->is_active=0;
1214 + else if (epqh->is_active && urbd->is_active)
1216 + /*== AVM/WK 20100709 - halt channel only if really started ==*/
1217 + //if (epqh->hc->xfer_started && !epqh->hc->wait_for_sof) {
1218 + /*== AVM/WK 20101112 - halt channel if started ==*/
1219 + if (epqh->hc->xfer_started) {
1221 + * If still connected (i.e. in host mode), halt the
1222 + * channel so it can be used for other transfers. If
1223 + * no longer connected, the host registers can't be
1224 + * written to halt the channel since the core is in
1227 + /* == 20110803 AVM/WK FIX propagate status == */
1228 + if (_urb->status == -EINPROGRESS) {
1229 + _urb->status = status;
1231 + ifxhcd_hc_halt(&ifxhcd->core_if, epqh->hc, HC_XFER_URB_DEQUEUE);
1239 + SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
1243 + list_del_init(&urbd->urbd_list_entry);
1246 + /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/
1247 + usb_hcd_unlink_urb_from_ep(_syshcd, _urb);
1249 + SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
1250 + _urb->hcpriv = NULL;
1251 +// usb_hcd_giveback_urb(_syshcd, _urb);
1252 + usb_hcd_giveback_urb(_syshcd, _urb, status /* neu in 2.6.28 */);
1253 + select_eps(ifxhcd);
1262 + \brief Frees resources in the IFXUSB controller related to a given endpoint. Also
1263 + clears state in the HCD related to the endpoint. Any URBs for the endpoint
1264 + must already be dequeued.
1266 +void ifxhcd_endpoint_disable( struct usb_hcd *_syshcd,
1267 + struct usb_host_endpoint *_sysep)
1269 + ifxhcd_epqh_t *epqh;
1270 + ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
1271 + unsigned long flags;
1275 + IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD EP DISABLE: _bEndpointAddress=0x%02x, "
1276 + "endpoint=%d\n", _sysep->desc.bEndpointAddress,
1277 + ifxhcd_ep_addr_to_endpoint(_sysep->desc.bEndpointAddress));
1279 + SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
1280 + if((uint32_t)_sysep>=0x80000000 && (uint32_t)_sysep->hcpriv>=(uint32_t)0x80000000)
1282 + epqh = (ifxhcd_epqh_t *)(_sysep->hcpriv);
1283 + if (epqh && epqh->sysep==_sysep)
1286 +#if 1 /*== AVM/BC 20101111 CHG Option active: Kill URBs when disabling EP ==*/
1287 + while (!list_empty(&epqh->urbd_list))
1289 + if (retry++ > 250)
1291 + IFX_WARN("IFXUSB HCD EP DISABLE:"
1292 + " URBD List for this endpoint is not empty\n");
1295 + kill_all_urbs_in_epqh(ifxhcd, epqh, -ETIMEDOUT);
1298 + while (!list_empty(&epqh->urbd_list))
1300 + /** Check that the QTD list is really empty */
1301 + if (retry++ > 250)
1303 + IFX_WARN("IFXUSB HCD EP DISABLE:"
1304 + " URBD List for this endpoint is not empty\n");
1307 + SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
1308 + schedule_timeout_uninterruptible(1);
1309 + SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
1313 + ifxhcd_epqh_free(epqh);
1314 + _sysep->hcpriv = NULL;
1317 + SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
1322 + \brief Handles host mode interrupts for the IFXUSB controller. Returns IRQ_NONE if
1323 + * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
1326 + * This function is called by the USB core when an interrupt occurs
1328 +irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd)
1330 + ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
1333 + //mask_and_ack_ifx_irq (ifxhcd->core_if.irq);
1334 + retval = ifxhcd_handle_intr(ifxhcd);
1335 + return IRQ_RETVAL(retval);
1340 + \brief Handles host mode Over Current Interrupt
1342 +irqreturn_t ifxhcd_oc_irq(int _irq , void *_dev)
1344 + ifxhcd_hcd_t *ifxhcd = _dev;
1347 + ifxhcd->flags.b.port_over_current_change = 1;
1348 + ifxusb_vbus_off(&ifxhcd->core_if);
1349 + IFX_DEBUGP("OC INTERRUPT # %d\n",ifxhcd->core_if.core_no);
1351 + //mask_and_ack_ifx_irq (_irq);
1352 + return IRQ_RETVAL(retval);
1356 + \brief Creates Status Change bitmap for the root hub and root port. The bitmap is
1357 + returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
1358 + is the status change indicator for the single root port. Returns 1 if either
1359 + change indicator is 1, otherwise returns 0.
1361 +int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf)
1363 + ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
1366 + _buf[0] |= (ifxhcd->flags.b.port_connect_status_change ||
1367 + ifxhcd->flags.b.port_reset_change ||
1368 + ifxhcd->flags.b.port_enable_change ||
1369 + ifxhcd->flags.b.port_suspend_change ||
1370 + ifxhcd->flags.b.port_over_current_change) << 1;
1375 + IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD HUB STATUS DATA:"
1376 + " Root port status changed\n");
1377 + IFX_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
1378 + ifxhcd->flags.b.port_connect_status_change);
1379 + IFX_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
1380 + ifxhcd->flags.b.port_reset_change);
1381 + IFX_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
1382 + ifxhcd->flags.b.port_enable_change);
1383 + IFX_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
1384 + ifxhcd->flags.b.port_suspend_change);
1385 + IFX_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
1386 + ifxhcd->flags.b.port_over_current_change);
1388 + #endif //__DEBUG__
1389 + return (_buf[0] != 0);
1392 +#ifdef __WITH_HS_ELECT_TST__
1393 + extern void do_setup(ifxusb_core_if_t *_core_if) ;
1394 + extern void do_in_ack(ifxusb_core_if_t *_core_if);
1395 +#endif //__WITH_HS_ELECT_TST__
1398 + \brief Handles hub class-specific requests.
1400 +int ifxhcd_hub_control( struct usb_hcd *_syshcd,
1409 + ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
1410 + ifxusb_core_if_t *core_if = &ifxhcd->core_if;
1411 + struct usb_hub_descriptor *desc;
1412 + hprt0_data_t hprt0 = {.d32 = 0};
1414 + uint32_t port_status;
1418 + case ClearHubFeature:
1419 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1420 + "ClearHubFeature 0x%x\n", _wValue);
1423 + case C_HUB_LOCAL_POWER:
1424 + case C_HUB_OVER_CURRENT:
1425 + /* Nothing required here */
1429 + IFX_ERROR ("IFXUSB HCD - "
1430 + "ClearHubFeature request %xh unknown\n", _wValue);
1433 + case ClearPortFeature:
1434 + if (!_wIndex || _wIndex > 1)
1439 + case USB_PORT_FEAT_ENABLE:
1440 + IFX_DEBUGPL (DBG_ANY, "IFXUSB HCD HUB CONTROL - "
1441 + "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
1442 + hprt0.d32 = ifxusb_read_hprt0 (core_if);
1443 + hprt0.b.prtena = 1;
1444 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1446 + case USB_PORT_FEAT_SUSPEND:
1447 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1448 + "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
1449 + hprt0.d32 = ifxusb_read_hprt0 (core_if);
1450 + hprt0.b.prtres = 1;
1451 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1452 + /* Clear Resume bit */
1454 + hprt0.b.prtres = 0;
1455 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1457 + case USB_PORT_FEAT_POWER:
1458 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1459 + "ClearPortFeature USB_PORT_FEAT_POWER\n");
1460 + #ifdef __IS_DUAL__
1461 + ifxusb_vbus_off(core_if);
1463 + ifxusb_vbus_off(core_if);
1465 + hprt0.d32 = ifxusb_read_hprt0 (core_if);
1466 + hprt0.b.prtpwr = 0;
1467 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1469 + case USB_PORT_FEAT_INDICATOR:
1470 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1471 + "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
1472 + /* Port inidicator not supported */
1474 + case USB_PORT_FEAT_C_CONNECTION:
1475 + /* Clears drivers internal connect status change
1477 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1478 + "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
1479 + ifxhcd->flags.b.port_connect_status_change = 0;
1481 + case USB_PORT_FEAT_C_RESET:
1482 + /* Clears the driver's internal Port Reset Change
1484 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1485 + "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
1486 + ifxhcd->flags.b.port_reset_change = 0;
1488 + case USB_PORT_FEAT_C_ENABLE:
1489 + /* Clears the driver's internal Port
1490 + * Enable/Disable Change flag */
1491 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1492 + "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
1493 + ifxhcd->flags.b.port_enable_change = 0;
1495 + case USB_PORT_FEAT_C_SUSPEND:
1496 + /* Clears the driver's internal Port Suspend
1497 + * Change flag, which is set when resume signaling on
1498 + * the host port is complete */
1499 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1500 + "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
1501 + ifxhcd->flags.b.port_suspend_change = 0;
1503 + case USB_PORT_FEAT_C_OVER_CURRENT:
1504 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1505 + "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
1506 + ifxhcd->flags.b.port_over_current_change = 0;
1510 + IFX_ERROR ("IFXUSB HCD - "
1511 + "ClearPortFeature request %xh "
1512 + "unknown or unsupported\n", _wValue);
1515 + case GetHubDescriptor:
1516 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1517 + "GetHubDescriptor\n");
1518 + desc = (struct usb_hub_descriptor *)_buf;
1519 + desc->bDescLength = 9;
1520 + desc->bDescriptorType = 0x29;
1521 + desc->bNbrPorts = 1;
1522 + desc->wHubCharacteristics = 0x08;
1523 + desc->bPwrOn2PwrGood = 1;
1524 + desc->bHubContrCurrent = 0;
1525 +// desc->bitmap[0] = 0;
1526 +// desc->bitmap[1] = 0xff;
1528 + case GetHubStatus:
1529 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1530 + "GetHubStatus\n");
1531 + memset (_buf, 0, 4);
1533 + case GetPortStatus:
1534 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1535 + "GetPortStatus\n");
1536 + if (!_wIndex || _wIndex > 1)
1539 +# ifdef CONFIG_AVM_POWERMETER
1541 + /* first port only, but 2 Hosts */
1542 + static unsigned char ucOldPower1 = 255;
1543 + static unsigned char ucOldPower2 = 255;
1545 + unsigned char ucNewPower = 0;
1546 + struct usb_device *childdev = _syshcd->self.root_hub->children[0];
1548 + if (childdev != NULL) {
1549 + ucNewPower = (childdev->actconfig != NULL)
1550 + ? childdev->actconfig->desc.bMaxPower
1551 + : 50;/* default: 50 means 100 mA*/
1553 + if (_syshcd->self.busnum == 1) {
1554 + if (ucOldPower1 != ucNewPower) {
1555 + ucOldPower1 = ucNewPower;
1556 + printk (KERN_INFO "IFXHCD#1: AVM Powermeter changed to %u mA\n", ucNewPower*2);
1557 + PowerManagmentRessourceInfo(powerdevice_usb_host, ucNewPower*2);
1560 + if (ucOldPower2 != ucNewPower) {
1561 + ucOldPower2 = ucNewPower;
1562 + printk (KERN_INFO "IFXHCD#2: AVM Powermeter changed to %u mA\n", ucNewPower*2);
1563 + PowerManagmentRessourceInfo(powerdevice_usb_host2, ucNewPower*2);
1567 +# endif /*--- #ifdef CONFIG_AVM_POWERMETER ---*/
1570 + if (ifxhcd->flags.b.port_connect_status_change)
1571 + port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
1572 + if (ifxhcd->flags.b.port_enable_change)
1573 + port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
1574 + if (ifxhcd->flags.b.port_suspend_change)
1575 + port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
1576 + if (ifxhcd->flags.b.port_reset_change)
1577 + port_status |= (1 << USB_PORT_FEAT_C_RESET);
1578 + if (ifxhcd->flags.b.port_over_current_change)
1580 + IFX_ERROR("Device Not Supported\n");
1581 + port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
1583 + if (!ifxhcd->flags.b.port_connect_status)
1586 + * The port is disconnected, which means the core is
1587 + * either in device mode or it soon will be. Just
1588 + * return 0's for the remainder of the port status
1589 + * since the port register can't be read if the core
1590 + * is in device mode.
1592 + *((u32 *) _buf) = cpu_to_le32(port_status);
1596 + hprt0.d32 = ifxusb_rreg(core_if->hprt0);
1597 + IFX_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
1598 + if (hprt0.b.prtconnsts)
1599 + port_status |= (1 << USB_PORT_FEAT_CONNECTION);
1600 + if (hprt0.b.prtena)
1601 + port_status |= (1 << USB_PORT_FEAT_ENABLE);
1602 + if (hprt0.b.prtsusp)
1603 + port_status |= (1 << USB_PORT_FEAT_SUSPEND);
1604 + if (hprt0.b.prtovrcurract)
1605 + port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
1606 + if (hprt0.b.prtrst)
1607 + port_status |= (1 << USB_PORT_FEAT_RESET);
1608 + if (hprt0.b.prtpwr)
1609 + port_status |= (1 << USB_PORT_FEAT_POWER);
1610 +/* if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
1611 + port_status |= (1 << USB_PORT_FEAT_HIGHSPEED);
1612 + else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
1613 + port_status |= (1 << USB_PORT_FEAT_LOWSPEED);*/
1614 + if (hprt0.b.prttstctl)
1615 + port_status |= (1 << USB_PORT_FEAT_TEST);
1616 + /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
1617 + *((u32 *) _buf) = cpu_to_le32(port_status);
1619 + case SetHubFeature:
1620 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1621 + "SetHubFeature\n");
1622 + /* No HUB features supported */
1624 + case SetPortFeature:
1625 + if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
1628 + * The port is disconnected, which means the core is
1629 + * either in device mode or it soon will be. Just
1630 + * return without doing anything since the port
1631 + * register can't be written if the core is in device
1634 + if (!ifxhcd->flags.b.port_connect_status)
1638 + case USB_PORT_FEAT_SUSPEND:
1639 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1640 + "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
1641 + hprt0.d32 = ifxusb_read_hprt0 (core_if);
1642 + hprt0.b.prtsusp = 1;
1643 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1644 + //IFX_PRINT( "SUSPEND: HPRT0=%0x\n", hprt0.d32);
1645 + /* Suspend the Phy Clock */
1647 + pcgcctl_data_t pcgcctl = {.d32=0};
1648 + pcgcctl.b.stoppclk = 1;
1649 + ifxusb_wreg(core_if->pcgcctl, pcgcctl.d32);
1652 + case USB_PORT_FEAT_POWER:
1653 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1654 + "SetPortFeature - USB_PORT_FEAT_POWER\n");
1655 + ifxusb_vbus_on (core_if);
1656 + hprt0.d32 = ifxusb_read_hprt0 (core_if);
1657 + hprt0.b.prtpwr = 1;
1658 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1660 + case USB_PORT_FEAT_RESET:
1661 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1662 + "SetPortFeature - USB_PORT_FEAT_RESET\n");
1663 + hprt0.d32 = ifxusb_read_hprt0 (core_if);
1664 + hprt0.b.prtrst = 1;
1665 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1666 + /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
1668 + hprt0.b.prtrst = 0;
1669 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1671 + #ifdef __WITH_HS_ELECT_TST__
1672 + case USB_PORT_FEAT_TEST:
1675 + gint_data_t gintmsk;
1676 + t = (_wIndex >> 8); /* MSB wIndex USB */
1677 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1678 + "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
1679 + warn("USB_PORT_FEAT_TEST %d\n", t);
1682 + hprt0.d32 = ifxusb_read_hprt0 (core_if);
1683 + hprt0.b.prttstctl = t;
1684 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1686 + else if (t == 6) /* HS_HOST_PORT_SUSPEND_RESUME */
1688 + /* Save current interrupt mask */
1689 + gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1691 + /* Disable all interrupts while we muck with
1692 + * the hardware directly
1694 + ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1696 + /* 15 second delay per the test spec */
1699 + /* Drive suspend on the root port */
1700 + hprt0.d32 = ifxusb_read_hprt0 (core_if);
1701 + hprt0.b.prtsusp = 1;
1702 + hprt0.b.prtres = 0;
1703 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1705 + /* 15 second delay per the test spec */
1708 + /* Drive resume on the root port */
1709 + hprt0.d32 = ifxusb_read_hprt0 (core_if);
1710 + hprt0.b.prtsusp = 0;
1711 + hprt0.b.prtres = 1;
1712 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1715 + /* Clear the resume bit */
1716 + hprt0.b.prtres = 0;
1717 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
1719 + /* Restore interrupts */
1720 + ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1722 + else if (t == 7) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
1724 + /* Save current interrupt mask */
1725 + gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1727 + /* Disable all interrupts while we muck with
1728 + * the hardware directly
1730 + ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1732 + /* 15 second delay per the test spec */
1735 + /* Send the Setup packet */
1736 + do_setup(core_if);
1738 + /* 15 second delay so nothing else happens for awhile */
1741 + /* Restore interrupts */
1742 + ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1745 + else if (t == 8) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
1747 + /* Save current interrupt mask */
1748 + gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1750 + /* Disable all interrupts while we muck with
1751 + * the hardware directly
1753 + ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1755 + /* Send the Setup packet */
1756 + do_setup(core_if);
1758 + /* 15 second delay so nothing else happens for awhile */
1761 + /* Send the In and Ack packets */
1762 + do_in_ack(core_if);
1764 + /* 15 second delay so nothing else happens for awhile */
1767 + /* Restore interrupts */
1768 + ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1772 + #endif //__WITH_HS_ELECT_TST__
1773 + case USB_PORT_FEAT_INDICATOR:
1774 + IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1775 + "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
1776 + /* Not supported */
1780 + IFX_ERROR ("IFXUSB HCD - "
1781 + "SetPortFeature request %xh "
1782 + "unknown or unsupported\n", _wValue);
1788 + IFX_WARN ("IFXUSB HCD - "
1789 + "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
1790 + _typeReq, _wIndex, _wValue);
1797 + \brief Assigns transactions from a URBD to a free host channel and initializes the
1798 + host channel to perform the transactions. The host channel is removed from
1800 + \param _ifxhcd The HCD state structure.
1801 + \param _epqh Transactions from the first URBD for this EPQH are selected and assigned to a free host channel.
1803 +static int assign_and_init_hc(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
1805 + ifxhcd_hc_t *ifxhc;
1806 + ifxhcd_urbd_t *urbd;
1809 + IFX_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, _ifxhcd, _epqh);
1811 + if(list_empty(&_epqh->urbd_list))
1814 + ifxhc = list_entry(_ifxhcd->free_hc_list.next, ifxhcd_hc_t, hc_list_entry);
1815 + /* Remove the host channel from the free list. */
1816 + list_del_init(&ifxhc->hc_list_entry);
1818 + urbd = list_entry(_epqh->urbd_list.next, ifxhcd_urbd_t, urbd_list_entry);
1821 + _epqh->hc = ifxhc;
1822 + _epqh->urbd = urbd;
1823 + ifxhc->epqh = _epqh;
1825 + urbd->is_active=1;
1828 + * Use usb_pipedevice to determine device address. This address is
1829 + * 0 before the SET_ADDRESS command and the correct address afterward.
1831 + ifxhc->dev_addr = usb_pipedevice(urb->pipe);
1832 + ifxhc->ep_num = usb_pipeendpoint(urb->pipe);
1834 + ifxhc->xfer_started = 0;
1836 + if (urb->dev->speed == USB_SPEED_LOW) ifxhc->speed = IFXUSB_EP_SPEED_LOW;
1837 + else if (urb->dev->speed == USB_SPEED_FULL) ifxhc->speed = IFXUSB_EP_SPEED_FULL;
1838 + else ifxhc->speed = IFXUSB_EP_SPEED_HIGH;
1840 + ifxhc->mps = _epqh->mps;
1841 + ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1843 + ifxhc->ep_type = _epqh->ep_type;
1845 + if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
1847 + ifxhc->control_phase=IFXHCD_CONTROL_SETUP;
1849 + ifxhc->data_pid_start = IFXUSB_HC_PID_SETUP;
1850 + ifxhc->xfer_buff = urbd->setup_buff;
1851 + ifxhc->xfer_len = 8;
1852 + ifxhc->xfer_count = 0;
1853 + ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
1857 + ifxhc->is_in = urbd->is_in;
1858 + ifxhc->xfer_buff = urbd->xfer_buff;
1859 + ifxhc->xfer_len = urbd->xfer_len;
1860 + ifxhc->xfer_count = 0;
1861 + /* == AVM/WK 20100710 Fix - Use toggle of usbcore ==*/
1862 + //ifxhc->data_pid_start = _epqh->data_toggle;
1863 + ifxhc->data_pid_start = usb_gettoggle (urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout (urb->pipe))
1864 + ? IFXUSB_HC_PID_DATA1
1865 + : IFXUSB_HC_PID_DATA0;
1867 + ifxhc->short_rw =0;
1869 + ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
1871 + #ifdef __EN_ISOC__
1872 + if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
1874 + struct usb_iso_packet_descriptor *frame_desc;
1875 + frame_desc = &urb->iso_frame_desc[urbd->isoc_frame_index];
1876 + ifxhc->xfer_buff += frame_desc->offset + urbd->isoc_split_offset;
1877 + ifxhc->xfer_len = frame_desc->length - urbd->isoc_split_offset;
1878 + if (ifxhc->isoc_xact_pos == IFXUSB_HCSPLIT_XACTPOS_ALL)
1880 + if (ifxhc->xfer_len <= 188)
1881 + ifxhc->isoc_xact_pos = IFXUSB_HCSPLIT_XACTPOS_ALL;
1883 + ifxhc->isoc_xact_pos = IFXUSB_HCSPLIT_XACTPOS_BEGIN;
1890 + if (_ifxhcd->core_if.snpsid < 0x4f54271a && ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1894 + /* Set the split attributes */
1896 + if (_epqh->need_split) {
1898 + ifxhc->hub_addr = urb->dev->tt->hub->devnum;
1899 + ifxhc->port_addr = urb->dev->ttport;
1902 + //ifxhc->uint16_t pkt_count_limit
1905 + hcint_data_t hc_intr_mask;
1906 + uint8_t hc_num = ifxhc->hc_num;
1907 + ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[hc_num];
1909 + /* Clear old interrupt conditions for this host channel. */
1910 + hc_intr_mask.d32 = 0xFFFFFFFF;
1911 + hc_intr_mask.b.reserved = 0;
1912 + ifxusb_wreg(&hc_regs->hcint, hc_intr_mask.d32);
1914 + /* Enable channel interrupts required for this transfer. */
1915 + hc_intr_mask.d32 = 0;
1916 + hc_intr_mask.b.chhltd = 1;
1917 + hc_intr_mask.b.ahberr = 1;
1919 + ifxusb_wreg(&hc_regs->hcintmsk, hc_intr_mask.d32);
1921 + /* Enable the top level host channel interrupt. */
1923 + uint32_t intr_enable;
1924 + intr_enable = (1 << hc_num);
1925 + ifxusb_mreg(&_ifxhcd->core_if.host_global_regs->haintmsk, 0, intr_enable);
1928 + /* Make sure host channel interrupts are enabled. */
1930 + gint_data_t gintmsk ={.d32 = 0};
1931 + gintmsk.b.hcintr = 1;
1932 + ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, 0, gintmsk.d32);
1936 + * Program the HCCHARn register with the endpoint characteristics for
1937 + * the current transfer.
1940 + hcchar_data_t hcchar;
1943 + hcchar.b.devaddr = ifxhc->dev_addr;
1944 + hcchar.b.epnum = ifxhc->ep_num;
1945 + hcchar.b.lspddev = (ifxhc->speed == IFXUSB_EP_SPEED_LOW);
1946 + hcchar.b.eptype = ifxhc->ep_type;
1947 + hcchar.b.mps = ifxhc->mps;
1948 + ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
1950 + IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, ifxhc->hc_num);
1951 + IFX_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n" , hcchar.b.devaddr);
1952 + IFX_DEBUGPL(DBG_HCDV, " Ep Num: %d\n" , hcchar.b.epnum);
1953 + IFX_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
1954 + IFX_DEBUGPL(DBG_HCDV, " Ep Type: %d\n" , hcchar.b.eptype);
1955 + IFX_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n" , hcchar.b.mps);
1956 + IFX_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n" , hcchar.b.multicnt);
1958 + /* Program the HCSPLIT register for SPLITs */
1960 + hcsplt_data_t hcsplt;
1965 + IFX_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", ifxhc->hc_num,
1966 + (ifxhc->split==2) ? "CSPLIT" : "SSPLIT");
1967 + hcsplt.b.spltena = 1;
1968 + hcsplt.b.compsplt = (ifxhc->split==2);
1969 + #ifdef __EN_ISOC__
1970 + if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
1971 + hcsplt.b.xactpos = ifxhc->isoc_xact_pos;
1974 + hcsplt.b.xactpos = IFXUSB_HCSPLIT_XACTPOS_ALL;
1975 + hcsplt.b.hubaddr = ifxhc->hub_addr;
1976 + hcsplt.b.prtaddr = ifxhc->port_addr;
1977 + IFX_DEBUGPL(DBG_HCDV, " comp split %d\n" , hcsplt.b.compsplt);
1978 + IFX_DEBUGPL(DBG_HCDV, " xact pos %d\n" , hcsplt.b.xactpos);
1979 + IFX_DEBUGPL(DBG_HCDV, " hub addr %d\n" , hcsplt.b.hubaddr);
1980 + IFX_DEBUGPL(DBG_HCDV, " port addr %d\n" , hcsplt.b.prtaddr);
1981 + IFX_DEBUGPL(DBG_HCDV, " is_in %d\n" , ifxhc->is_in);
1982 + IFX_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n" , ifxhc->mps);
1983 + IFX_DEBUGPL(DBG_HCDV, " xferlen: %d\n" , ifxhc->xfer_len);
1985 + ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32);
1989 + ifxhc->nak_retry_r=ifxhc->nak_retry=0;
1990 + ifxhc->nak_countdown_r=ifxhc->nak_countdown=0;
2001 + else if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
2010 + else if(_epqh->ep_type==IFXUSB_EP_TYPE_BULK)
2014 +// ifxhc->nak_retry_r=ifxhc->nak_retry=nak_retry_max;
2015 +// ifxhc->nak_countdown_r=ifxhc->nak_countdown=nak_countdown_max;
2021 + else if(_epqh->ep_type==IFXUSB_EP_TYPE_INTR)
2030 + else if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
2044 + \brief This function selects transactions from the HCD transfer schedule and
2045 + assigns them to available host channels. It is called from HCD interrupt
2046 + handler functions.
2048 +static void select_eps_sub(ifxhcd_hcd_t *_ifxhcd)
2050 + struct list_head *epqh_ptr;
2051 + struct list_head *urbd_ptr;
2052 + ifxhcd_epqh_t *epqh;
2053 + ifxhcd_urbd_t *urbd;
2056 + /*== AVM/BC 20101111 Function called with Lock ==*/
2058 +// #ifdef __DEBUG__
2059 +// IFX_DEBUGPL(DBG_HCD, " ifxhcd_select_ep\n");
2062 + /* Process entries in the periodic ready list. */
2063 + #ifdef __EN_ISOC__
2064 + epqh_ptr = _ifxhcd->epqh_isoc_ready.next;
2065 + while (epqh_ptr != &_ifxhcd->epqh_isoc_ready && !list_empty(&_ifxhcd->free_hc_list))
2067 + epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry);
2068 + epqh_ptr = epqh_ptr->next;
2069 + if(epqh->period_do)
2071 + if(assign_and_init_hc(_ifxhcd, epqh))
2073 + IFX_DEBUGPL(DBG_HCD, " select_eps ISOC\n");
2074 + list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_active);
2075 + epqh->is_active=1;
2077 + epqh->period_do=0;
2083 + epqh_ptr = _ifxhcd->epqh_intr_ready.next;
2084 + while (epqh_ptr != &_ifxhcd->epqh_intr_ready && !list_empty(&_ifxhcd->free_hc_list))
2086 + epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry);
2087 + epqh_ptr = epqh_ptr->next;
2088 + if(epqh->period_do)
2090 + if(assign_and_init_hc(_ifxhcd, epqh))
2092 + IFX_DEBUGPL(DBG_HCD, " select_eps INTR\n");
2093 + list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_intr_active);
2094 + epqh->is_active=1;
2096 + epqh->period_do=0;
2101 + epqh_ptr = _ifxhcd->epqh_np_ready.next;
2102 + while (epqh_ptr != &_ifxhcd->epqh_np_ready && !list_empty(&_ifxhcd->free_hc_list)) // may need to preserve at lease one for period
2104 + epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry);
2105 + epqh_ptr = epqh_ptr->next;
2106 + if(assign_and_init_hc(_ifxhcd, epqh))
2108 + IFX_DEBUGPL(DBG_HCD, " select_eps CTRL/BULK\n");
2109 + list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_np_active);
2110 + epqh->is_active=1;
2115 + /*== AVM/BC 20101111 Function called with Lock ==*/
2116 + process_channels_sub(_ifxhcd);
2118 + /* AVM/BC 20101111 Urbds completion loop */
2119 + while (!list_empty(&_ifxhcd->urbd_complete_list))
2121 + urbd_ptr = _ifxhcd->urbd_complete_list.next;
2122 + list_del_init(urbd_ptr);
2124 + urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, urbd_list_entry);
2126 + ifxhcd_complete_urb(_ifxhcd, urbd, urbd->status);
2132 +static void select_eps_func(unsigned long data)
2134 + unsigned long flags;
2136 + ifxhcd_hcd_t *ifxhcd;
2137 + ifxhcd=((ifxhcd_hcd_t *)data);
2139 + /* AVM/BC 20101111 select_eps_in_use flag removed */
2141 + SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
2143 + /*if(ifxhcd->select_eps_in_use){
2144 + SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
2147 + ifxhcd->select_eps_in_use=1;
2150 + select_eps_sub(ifxhcd);
2152 + //ifxhcd->select_eps_in_use=0;
2154 + SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
2157 +void select_eps(ifxhcd_hcd_t *_ifxhcd)
2161 + if(!_ifxhcd->select_eps.func)
2163 + _ifxhcd->select_eps.next = NULL;
2164 + _ifxhcd->select_eps.state = 0;
2165 + atomic_set( &_ifxhcd->select_eps.count, 0);
2166 + _ifxhcd->select_eps.func = select_eps_func;
2167 + _ifxhcd->select_eps.data = (unsigned long)_ifxhcd;
2169 + tasklet_schedule(&_ifxhcd->select_eps);
2173 + unsigned long flags;
2175 + /* AVM/BC 20101111 select_eps_in_use flag removed */
2177 + SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
2179 + /*if(_ifxhcd->select_eps_in_use){
2180 + printk ("select_eps non_irq: busy\n");
2181 + SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
2184 + _ifxhcd->select_eps_in_use=1;
2187 + select_eps_sub(_ifxhcd);
2189 + //_ifxhcd->select_eps_in_use=0;
2191 + SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
2198 +static void process_unaligned( ifxhcd_epqh_t *_epqh)
2200 + #if defined(__UNALIGNED_BUFFER_ADJ__)
2201 + if(!_epqh->aligned_checked)
2203 + uint32_t xfer_len;
2204 + xfer_len=_epqh->urbd->xfer_len;
2205 + if(_epqh->urbd->is_in && xfer_len<_epqh->mps)
2206 + xfer_len = _epqh->mps;
2207 + _epqh->using_aligned_buf=0;
2209 + if(xfer_len > 0 && ((unsigned long)_epqh->urbd->xfer_buff) & 3)
2211 + if( _epqh->aligned_buf
2212 + && _epqh->aligned_buf_len > 0
2213 + && _epqh->aligned_buf_len < xfer_len
2216 + ifxusb_free_buf(_epqh->aligned_buf);
2217 + _epqh->aligned_buf=NULL;
2218 + _epqh->aligned_buf_len=0;
2220 + if(! _epqh->aligned_buf || ! _epqh->aligned_buf_len)
2222 + _epqh->aligned_buf = ifxusb_alloc_buf(xfer_len, _epqh->urbd->is_in);
2223 + if(_epqh->aligned_buf)
2224 + _epqh->aligned_buf_len = xfer_len;
2226 + if(_epqh->aligned_buf)
2228 + if(!_epqh->urbd->is_in)
2229 + memcpy(_epqh->aligned_buf, _epqh->urbd->xfer_buff, xfer_len);
2230 + _epqh->using_aligned_buf=1;
2231 + _epqh->hc->xfer_buff = _epqh->aligned_buf;
2234 + IFX_WARN("%s():%d\n",__func__,__LINE__);
2236 + if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
2238 + _epqh->using_aligned_setup=0;
2239 + if(((unsigned long)_epqh->urbd->setup_buff) & 3)
2241 + if(! _epqh->aligned_setup)
2242 + _epqh->aligned_setup = ifxusb_alloc_buf(8,0);
2243 + if(_epqh->aligned_setup)
2245 + memcpy(_epqh->aligned_setup, _epqh->urbd->setup_buff, 8);
2246 + _epqh->using_aligned_setup=1;
2249 + IFX_WARN("%s():%d\n",__func__,__LINE__);
2250 + _epqh->hc->xfer_buff = _epqh->aligned_setup;
2254 + #elif defined(__UNALIGNED_BUFFER_CHK__)
2255 + if(!_epqh->aligned_checked)
2257 + if(_epqh->urbd->is_in)
2259 + if(_epqh->urbd->xfer_len==0)
2260 + IFX_WARN("%s():%d IN xfer while length is zero \n",__func__,__LINE__);
2262 + if(_epqh->urbd->xfer_len < _epqh->mps)
2263 + IFX_WARN("%s():%d IN xfer while length < mps \n",__func__,__LINE__);
2265 + if(((unsigned long)_epqh->urbd->xfer_buff) & 3)
2266 + IFX_WARN("%s():%d IN xfer Buffer UNALIGNED\n",__func__,__LINE__);
2271 + if(_epqh->urbd->xfer_len > 0 && (((unsigned long)_epqh->urbd->xfer_buff) & 3) )
2272 + IFX_WARN("%s():%d OUT xfer Buffer UNALIGNED\n",__func__,__LINE__);
2275 + if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
2277 + if(((unsigned long)_epqh->urbd->setup_buff) & 3)
2278 + IFX_WARN("%s():%d SETUP xfer Buffer UNALIGNED\n",__func__,__LINE__);
2282 + _epqh->aligned_checked=1;
2289 +void process_channels_sub(ifxhcd_hcd_t *_ifxhcd)
2291 + ifxhcd_epqh_t *epqh;
2292 + struct list_head *epqh_item;
2293 + struct ifxhcd_hc *hc;
2295 + #ifdef __EN_ISOC__
2296 + if (!list_empty(&_ifxhcd->epqh_isoc_active))
2298 + for (epqh_item = _ifxhcd->epqh_isoc_active.next;
2299 + epqh_item != &_ifxhcd->epqh_isoc_active;
2302 + epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry);
2303 + epqh_item = epqh_item->next;
2305 + if(hc && !hc->xfer_started && epqh->period_do)
2311 + //epqh->ping_state = 0;
2312 + process_unaligned(epqh);
2313 + hc->wait_for_sof=epqh->wait_for_sof;
2314 + epqh->wait_for_sof=0;
2315 + ifxhcd_hc_start(&_ifxhcd->core_if, hc);
2316 + epqh->period_do=0;
2318 + gint_data_t gintsts = {.d32 = 0};
2319 + gintsts.b.sofintr = 1;
2320 + ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk,0, gintsts.d32);
2328 + if (!list_empty(&_ifxhcd->epqh_intr_active))
2330 + for (epqh_item = _ifxhcd->epqh_intr_active.next;
2331 + epqh_item != &_ifxhcd->epqh_intr_active;
2334 + epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry);
2335 + epqh_item = epqh_item->next;
2337 + if(hc && !hc->xfer_started && epqh->period_do)
2343 + //epqh->ping_state = 0;
2344 + process_unaligned(epqh);
2345 + hc->wait_for_sof=epqh->wait_for_sof;
2346 + epqh->wait_for_sof=0;
2347 + ifxhcd_hc_start(&_ifxhcd->core_if, hc);
2348 + epqh->period_do=0;
2349 +#ifdef __USE_TIMER_4_SOF__
2350 + /* AVM/WK change: let hc_start decide, if irq is needed */
2353 + gint_data_t gintsts = {.d32 = 0};
2354 + gintsts.b.sofintr = 1;
2355 + ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk,0, gintsts.d32);
2364 + if (!list_empty(&_ifxhcd->epqh_np_active))
2366 + for (epqh_item = _ifxhcd->epqh_np_active.next;
2367 + epqh_item != &_ifxhcd->epqh_np_active;
2370 + epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry);
2371 + epqh_item = epqh_item->next;
2375 + if(!hc->xfer_started)
2379 + //|| hc->split_counter == 0
2382 + //epqh->ping_state = 0;
2383 + process_unaligned(epqh);
2384 + hc->wait_for_sof=epqh->wait_for_sof;
2385 + epqh->wait_for_sof=0;
2386 + ifxhcd_hc_start(&_ifxhcd->core_if, hc);
2394 +void process_channels(ifxhcd_hcd_t *_ifxhcd)
2396 + unsigned long flags;
2398 + /* AVM/WK Fix: use spin_lock instead busy flag
2400 + SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
2402 + //if(_ifxhcd->process_channels_in_use)
2404 + //_ifxhcd->process_channels_in_use=1;
2406 + process_channels_sub(_ifxhcd);
2407 + //_ifxhcd->process_channels_in_use=0;
2408 + SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
2412 +#ifdef __HC_XFER_TIMEOUT__
2413 + static void hc_xfer_timeout(unsigned long _ptr)
2415 + hc_xfer_info_t *xfer_info = (hc_xfer_info_t *)_ptr;
2416 + int hc_num = xfer_info->hc->hc_num;
2417 + IFX_WARN("%s: timeout on channel %d\n", __func__, hc_num);
2418 + IFX_WARN(" start_hcchar_val 0x%08x\n", xfer_info->hc->start_hcchar_val);
2422 +void ifxhcd_hc_dumb_rx(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc,uint8_t *dump_buf)
2424 + ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
2425 + hctsiz_data_t hctsiz= { .d32=0 };
2426 + hcchar_data_t hcchar;
2429 + _ifxhc->xfer_len = _ifxhc->mps;
2430 + hctsiz.b.xfersize = _ifxhc->mps;
2431 + hctsiz.b.pktcnt = 0;
2432 + hctsiz.b.pid = _ifxhc->data_pid_start;
2433 + ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
2435 + ifxusb_wreg(&hc_regs->hcdma, (uint32_t)(CPHYSADDR( ((uint32_t)(dump_buf)))));
2438 + hcint_data_t hcint= { .d32=0 };
2442 + hcint.d32 =0xFFFFFFFF;
2443 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
2446 + /* Set host channel enable after all other setup is complete. */
2447 + hcchar.b.chen = 1;
2448 + hcchar.b.chdis = 0;
2449 + hcchar.b.epdir = 1;
2450 + IFX_DEBUGPL(DBG_HCDV, " HCCHART: 0x%08x\n", hcchar.d32);
2451 + ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
2455 + \brief This function trigger a data transfer for a host channel and
2456 + starts the transfer.
2458 + For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
2459 + register along with a packet count of 1 and the channel is enabled. This
2460 + causes a single PING transaction to occur. Other fields in HCTSIZ are
2461 + simply set to 0 since no data transfer occurs in this case.
2463 + For a PING transfer in DMA mode, the HCTSIZ register is initialized with
2464 + all the information required to perform the subsequent data transfer. In
2465 + addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
2466 + controller performs the entire PING protocol, then starts the data
2468 + \param _core_if Pointer of core_if structure
2469 + \param _ifxhc Information needed to initialize the host channel. The xfer_len
2470 + value may be reduced to accommodate the max widths of the XferSize and
2471 + PktCnt fields in the HCTSIZn register. The multi_count value may be changed
2472 + to reflect the final xfer_len value.
2474 +void ifxhcd_hc_start(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc)
2476 + hctsiz_data_t hctsiz= { .d32=0 };
2477 + hcchar_data_t hcchar;
2478 + uint32_t max_hc_xfer_size = _core_if->params.max_transfer_size;
2479 + uint16_t max_hc_pkt_count = _core_if->params.max_packet_count;
2480 + ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
2481 + hfnum_data_t hfnum;
2483 + hctsiz.b.dopng = 0;
2484 +// if(_ifxhc->do_ping && !_ifxhc->is_in) hctsiz.b.dopng = 1;
2486 + _ifxhc->nak_countdown=_ifxhc->nak_countdown_r;
2488 + /* AVM/BC 20101111 Workaround: Always PING if HI-Speed Out and xfer_len > 0 */
2489 + if(/*_ifxhc->do_ping &&*/
2490 + (!_ifxhc->is_in) &&
2491 + (_ifxhc->speed == IFXUSB_EP_SPEED_HIGH) &&
2492 + ((_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK) || ((_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL) && (_ifxhc->control_phase != IFXHCD_CONTROL_SETUP))) &&
2495 + hctsiz.b.dopng = 1;
2497 + _ifxhc->xfer_started = 1;
2499 + if(_ifxhc->epqh->pkt_count_limit > 0 && _ifxhc->epqh->pkt_count_limit < max_hc_pkt_count )
2501 + max_hc_pkt_count=_ifxhc->epqh->pkt_count_limit;
2502 + if(max_hc_pkt_count * _ifxhc->mps < max_hc_xfer_size)
2503 + max_hc_xfer_size = max_hc_pkt_count * _ifxhc->mps;
2505 + if (_ifxhc->split > 0)
2508 + gint_data_t gintsts = {.d32 = 0};
2509 + gintsts.b.sofintr = 1;
2510 + ifxusb_mreg(&_core_if->core_global_regs->gintmsk,0, gintsts.d32);
2513 + _ifxhc->start_pkt_count = 1;
2514 + if(!_ifxhc->is_in && _ifxhc->split>1) // OUT CSPLIT
2515 + _ifxhc->xfer_len = 0;
2516 + if (_ifxhc->xfer_len > _ifxhc->mps)
2517 + _ifxhc->xfer_len = _ifxhc->mps;
2518 + if (_ifxhc->xfer_len > 188)
2519 + _ifxhc->xfer_len = 188;
2521 + else if(_ifxhc->is_in)
2523 + _ifxhc->short_rw = 0;
2524 + if (_ifxhc->xfer_len > 0)
2526 + if (_ifxhc->xfer_len > max_hc_xfer_size)
2527 + _ifxhc->xfer_len = max_hc_xfer_size - _ifxhc->mps + 1;
2528 + _ifxhc->start_pkt_count = (_ifxhc->xfer_len + _ifxhc->mps - 1) / _ifxhc->mps;
2529 + if (_ifxhc->start_pkt_count > max_hc_pkt_count)
2530 + _ifxhc->start_pkt_count = max_hc_pkt_count;
2532 + else /* Need 1 packet for transfer length of 0. */
2533 + _ifxhc->start_pkt_count = 1;
2534 + _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
2536 + else //non-split out
2538 + if (_ifxhc->xfer_len == 0)
2540 + /*== AVM/BC WK 20110421 ZERO PACKET Workaround: Is not an error ==*/
2541 + //if(_ifxhc->short_rw==0)
2542 + // printk(KERN_INFO "%s() line %d: ZLP write without short_rw set!\n",__func__,__LINE__);
2543 + _ifxhc->start_pkt_count = 1;
2547 + if (_ifxhc->xfer_len > max_hc_xfer_size)
2549 + _ifxhc->start_pkt_count = (max_hc_xfer_size / _ifxhc->mps);
2550 + _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
2554 + _ifxhc->start_pkt_count = (_ifxhc->xfer_len+_ifxhc->mps-1) / _ifxhc->mps;
2555 +// if(_ifxhc->start_pkt_count * _ifxhc->mps == _ifxhc->xfer_len )
2556 +// _ifxhc->start_pkt_count += _ifxhc->short_rw;
2557 + /*== AVM/BC WK 20110421 ZERO PACKET Workaround / check if short_rw is needed ==*/
2558 + if(_ifxhc->start_pkt_count * _ifxhc->mps != _ifxhc->xfer_len )
2559 + _ifxhc->short_rw = 0;
2564 + #ifdef __EN_ISOC__
2565 + if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
2567 + /* Set up the initial PID for the transfer. */
2569 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2571 + if (_ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2573 + if (_ifxhc->is_in)
2575 + if (_ifxhc->multi_count == 1)
2576 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2577 + else if (_ifxhc->multi_count == 2)
2578 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
2580 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA2;
2584 + if (_ifxhc->multi_count == 1)
2585 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2587 + _ifxhc->data_pid_start = IFXUSB_HC_PID_MDATA;
2591 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2596 + hctsiz.b.xfersize = _ifxhc->xfer_len;
2597 + hctsiz.b.pktcnt = _ifxhc->start_pkt_count;
2598 + hctsiz.b.pid = _ifxhc->data_pid_start;
2600 + ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
2603 + IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _ifxhc->hc_num);
2604 + IFX_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
2605 + IFX_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n" , hctsiz.b.pktcnt);
2606 + IFX_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
2607 + IFX_DEBUGPL(DBG_HCDV, " DMA: 0x%08x\n", (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count )));
2608 + ifxusb_wreg(&hc_regs->hcdma, (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count )));
2610 + /* Start the split */
2611 + if (_ifxhc->split>0)
2613 + hcsplt_data_t hcsplt;
2614 + hcsplt.d32 = ifxusb_rreg (&hc_regs->hcsplt);
2615 + hcsplt.b.spltena = 1;
2616 + if (_ifxhc->split>1)
2617 + hcsplt.b.compsplt = 1;
2619 + hcsplt.b.compsplt = 0;
2621 + #ifdef __EN_ISOC__
2622 + if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
2623 + hcsplt.b.xactpos = _ifxhc->isoc_xact_pos;
2626 + hcsplt.b.xactpos = IFXUSB_HCSPLIT_XACTPOS_ALL;// if not ISO
2627 + ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32);
2628 + IFX_DEBUGPL(DBG_HCDV, " SPLIT: XACT_POS:0x%08x\n", hcsplt.d32);
2631 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2632 +// hcchar.b.multicnt = _ifxhc->multi_count;
2633 + hcchar.b.multicnt = 1;
2636 + _ifxhc->start_hcchar_val = hcchar.d32;
2637 + if (hcchar.b.chdis)
2638 + IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2639 + __func__, _ifxhc->hc_num, hcchar.d32);
2642 + /* Set host channel enable after all other setup is complete. */
2643 + hcchar.b.chen = 1;
2644 + hcchar.b.chdis = 0;
2645 + hcchar.b.epdir = _ifxhc->is_in;
2646 + _ifxhc->hcchar=hcchar.d32;
2648 + IFX_DEBUGPL(DBG_HCDV, " HCCHART: 0x%08x\n", _ifxhc->hcchar);
2650 + /* == 20110901 AVM/WK Fix: Clear IRQ flags in any case ==*/
2652 + hcint_data_t hcint= { .d32=0 };
2653 + hcint.d32 =0xFFFFFFFF;
2654 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
2657 + if(_ifxhc->wait_for_sof==0)
2659 + hcint_data_t hcint;
2661 + hcint.d32=ifxusb_rreg(&hc_regs->hcintmsk);
2665 + /* == 20110901 AVM/WK Fix: We don't need NOT YET IRQ ==*/
2667 + if(_ifxhc->nak_countdown_r)
2669 + ifxusb_wreg(&hc_regs->hcintmsk, hcint.d32);
2671 + /* AVM WK / BC 20100827
2672 + * MOVED. Oddframe updated inmediatly before write HCChar Register.
2674 + if (_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
2676 + hfnum.d32 = ifxusb_rreg(&_core_if->host_global_regs->hfnum);
2677 + /* 1 if _next_ frame is odd, 0 if it's even */
2678 + hcchar.b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
2679 + _ifxhc->hcchar=hcchar.d32;
2682 + ifxusb_wreg(&hc_regs->hcchar, _ifxhc->hcchar);
2683 +#ifdef __USE_TIMER_4_SOF__
2685 + //activate SOF IRQ
2686 + gint_data_t gintsts = {.d32 = 0};
2687 + gintsts.b.sofintr = 1;
2688 + ifxusb_mreg(&_core_if->core_global_regs->gintmsk,0, gintsts.d32);
2692 + #ifdef __HC_XFER_TIMEOUT__
2693 + /* Start a timer for this transfer. */
2694 + init_timer(&_ifxhc->hc_xfer_timer);
2695 + _ifxhc->hc_xfer_timer.function = hc_xfer_timeout;
2696 + _ifxhc->hc_xfer_timer.core_if = _core_if;
2697 + _ifxhc->hc_xfer_timer.hc = _ifxhc;
2698 + _ifxhc->hc_xfer_timer.data = (unsigned long)(&_ifxhc->hc_xfer_info);
2699 + _ifxhc->hc_xfer_timer.expires = jiffies + (HZ*10);
2700 + add_timer(&_ifxhc->hc_xfer_timer);
2705 + \brief Attempts to halt a host channel. This function should only be called
2706 + to abort a transfer in DMA mode. Under normal circumstances in DMA mode, the
2707 + controller halts the channel when the transfer is complete or a condition
2708 + occurs that requires application intervention.
2710 + In DMA mode, always sets the Channel Enable and Channel Disable bits of the
2711 + HCCHARn register. The controller ensures there is space in the request
2712 + queue before submitting the halt request.
2714 + Some time may elapse before the core flushes any posted requests for this
2715 + host channel and halts. The Channel Halted interrupt handler completes the
2716 + deactivation of the host channel.
2718 +void ifxhcd_hc_halt(ifxusb_core_if_t *_core_if,
2719 + ifxhcd_hc_t *_ifxhc,
2720 + ifxhcd_halt_status_e _halt_status)
2722 + hcchar_data_t hcchar;
2723 + ifxusb_hc_regs_t *hc_regs;
2725 + hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
2727 + WARN_ON(_halt_status == HC_XFER_NO_HALT_STATUS);
2729 + if (_halt_status == HC_XFER_URB_DEQUEUE ||
2730 + _halt_status == HC_XFER_AHB_ERR)
2733 + * Disable all channel interrupts except Ch Halted. The URBD
2734 + * and EPQH state associated with this transfer has been cleared
2735 + * (in the case of URB_DEQUEUE), so the channel needs to be
2736 + * shut down carefully to prevent crashes.
2738 + hcint_data_t hcintmsk;
2740 + hcintmsk.b.chhltd = 1;
2741 + ifxusb_wreg(&hc_regs->hcintmsk, hcintmsk.d32);
2744 + * Make sure no other interrupts besides halt are currently
2745 + * pending. Handling another interrupt could cause a crash due
2746 + * to the URBD and EPQH state.
2748 + ifxusb_wreg(&hc_regs->hcint, ~hcintmsk.d32);
2751 + * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
2752 + * even if the channel was already halted for some other
2755 + _ifxhc->halt_status = _halt_status;
2757 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2758 + if (hcchar.b.chen == 0)
2761 + * The channel is either already halted or it hasn't
2762 + * started yet. In DMA mode, the transfer may halt if
2763 + * it finishes normally or a condition occurs that
2764 + * requires driver intervention. Don't want to halt
2765 + * the channel again. In either Slave or DMA mode,
2766 + * it's possible that the transfer has been assigned
2767 + * to a channel, but not started yet when an URB is
2768 + * dequeued. Don't want to halt a channel that hasn't
2775 + if (_ifxhc->halting)
2778 + * A halt has already been issued for this channel. This might
2779 + * happen when a transfer is aborted by a higher level in
2783 + IFX_PRINT("*** %s: Channel %d, _hc->halting already set ***\n",
2784 + __func__, _ifxhc->hc_num);
2786 + //ifxusb_dump_global_registers(_core_if); */
2787 + //ifxusb_dump_host_registers(_core_if); */
2790 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2791 + /* == AVM/WK 20100709 halt channel only if enabled ==*/
2792 + if (hcchar.b.chen) {
2793 + _ifxhc->halting = 1;
2794 + hcchar.b.chdis = 1;
2796 + ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
2797 + _ifxhc->halt_status = _halt_status;
2800 + IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n" , __func__, _ifxhc->hc_num);
2801 + IFX_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n" , hcchar.d32);
2802 + IFX_DEBUGPL(DBG_HCDV, " halting: %d\n" , _ifxhc->halting);
2803 + IFX_DEBUGPL(DBG_HCDV, " halt_status: %d\n" , _ifxhc->halt_status);
2809 + \brief Clears a host channel.
2811 +void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc)
2813 + ifxusb_hc_regs_t *hc_regs;
2815 + _ifxhc->xfer_started = 0;
2817 + * Clear channel interrupt enables and any unhandled channel interrupt
2820 + hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
2821 + ifxusb_wreg(&hc_regs->hcintmsk, 0);
2822 + ifxusb_wreg(&hc_regs->hcint, 0xFFFFFFFF);
2824 + #ifdef __HC_XFER_TIMEOUT__
2825 + del_timer(&_ifxhc->hc_xfer_timer);
2829 + hcchar_data_t hcchar;
2830 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2831 + if (hcchar.b.chdis)
2832 + IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", __func__, _ifxhc->hc_num, hcchar.d32);
2845 + static void dump_urb_info(struct urb *_urb, char* _fn_name)
2847 + IFX_PRINT("%s, urb %p\n" , _fn_name, _urb);
2848 + IFX_PRINT(" Device address: %d\n", usb_pipedevice(_urb->pipe));
2849 + IFX_PRINT(" Endpoint: %d, %s\n" , usb_pipeendpoint(_urb->pipe),
2850 + (usb_pipein(_urb->pipe) ? "IN" : "OUT"));
2851 + IFX_PRINT(" Endpoint type: %s\n",
2852 + ({ char *pipetype;
2853 + switch (usb_pipetype(_urb->pipe)) {
2854 + case PIPE_CONTROL: pipetype = "CONTROL"; break;
2855 + case PIPE_BULK: pipetype = "BULK"; break;
2856 + case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
2857 + case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
2858 + default: pipetype = "UNKNOWN"; break;
2862 + IFX_PRINT(" Speed: %s\n",
2864 + switch (_urb->dev->speed) {
2865 + case USB_SPEED_HIGH: speed = "HIGH"; break;
2866 + case USB_SPEED_FULL: speed = "FULL"; break;
2867 + case USB_SPEED_LOW: speed = "LOW"; break;
2868 + default: speed = "UNKNOWN"; break;
2872 + IFX_PRINT(" Max packet size: %d\n",
2873 + usb_maxpacket(_urb->dev, _urb->pipe, usb_pipeout(_urb->pipe)));
2874 + IFX_PRINT(" Data buffer length: %d\n", _urb->transfer_buffer_length);
2875 + IFX_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n",
2876 + _urb->transfer_buffer, (void *)_urb->transfer_dma);
2877 + IFX_PRINT(" Setup buffer: %p, Setup DMA: %p\n",
2878 + _urb->setup_packet, (void *)_urb->setup_dma);
2879 + IFX_PRINT(" Interval: %d\n", _urb->interval);
2880 + if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
2883 + for (i = 0; i < _urb->number_of_packets; i++)
2885 + IFX_PRINT(" ISO Desc %d:\n", i);
2886 + IFX_PRINT(" offset: %d, length %d\n",
2887 + _urb->iso_frame_desc[i].offset,
2888 + _urb->iso_frame_desc[i].length);
2893 + static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
2895 + if (_epqh->hc != NULL)
2897 + ifxhcd_hc_t *hc = _epqh->hc;
2898 + struct list_head *item;
2899 + ifxhcd_epqh_t *epqh_item;
2901 + ifxusb_hc_regs_t *hc_regs;
2903 + hcchar_data_t hcchar;
2904 + hcsplt_data_t hcsplt;
2905 + hctsiz_data_t hctsiz;
2908 + hc_regs = _ifxhcd->core_if.hc_regs[hc->hc_num];
2909 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2910 + hcsplt.d32 = ifxusb_rreg(&hc_regs->hcsplt);
2911 + hctsiz.d32 = ifxusb_rreg(&hc_regs->hctsiz);
2912 + hcdma = ifxusb_rreg(&hc_regs->hcdma);
2914 + IFX_PRINT(" Assigned to channel %d:\n" , hc->hc_num);
2915 + IFX_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
2916 + IFX_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n" , hctsiz.d32, hcdma);
2917 + IFX_PRINT(" dev_addr: %d, ep_num: %d, is_in: %d\n",
2918 + hc->dev_addr, hc->ep_num, hc->is_in);
2919 + IFX_PRINT(" ep_type: %d\n" , hc->ep_type);
2920 + IFX_PRINT(" max_packet_size: %d\n", hc->mps);
2921 + IFX_PRINT(" data_pid_start: %d\n" , hc->data_pid_start);
2922 + IFX_PRINT(" xfer_started: %d\n" , hc->xfer_started);
2923 + IFX_PRINT(" halt_status: %d\n" , hc->halt_status);
2924 + IFX_PRINT(" xfer_buff: %p\n" , hc->xfer_buff);
2925 + IFX_PRINT(" xfer_len: %d\n" , hc->xfer_len);
2926 + IFX_PRINT(" epqh: %p\n" , hc->epqh);
2927 + IFX_PRINT(" NP Active:\n");
2928 + list_for_each(item, &_ifxhcd->epqh_np_active)
2930 + epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2931 + IFX_PRINT(" %p\n", epqh_item);
2933 + IFX_PRINT(" NP Ready:\n");
2934 + list_for_each(item, &_ifxhcd->epqh_np_ready)
2936 + epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2937 + IFX_PRINT(" %p\n", epqh_item);
2939 + IFX_PRINT(" INTR Active:\n");
2940 + list_for_each(item, &_ifxhcd->epqh_intr_active)
2942 + epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2943 + IFX_PRINT(" %p\n", epqh_item);
2945 + IFX_PRINT(" INTR Ready:\n");
2946 + list_for_each(item, &_ifxhcd->epqh_intr_ready)
2948 + epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2949 + IFX_PRINT(" %p\n", epqh_item);
2951 + #ifdef __EN_ISOC__
2952 + IFX_PRINT(" ISOC Active:\n");
2953 + list_for_each(item, &_ifxhcd->epqh_isoc_active)
2955 + epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2956 + IFX_PRINT(" %p\n", epqh_item);
2958 + IFX_PRINT(" ISOC Ready:\n");
2959 + list_for_each(item, &_ifxhcd->epqh_isoc_ready)
2961 + epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2962 + IFX_PRINT(" %p\n", epqh_item);
2965 + IFX_PRINT(" Standby:\n");
2966 + list_for_each(item, &_ifxhcd->epqh_stdby)
2968 + epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2969 + IFX_PRINT(" %p\n", epqh_item);
2977 + \brief This function writes a packet into the Tx FIFO associated with the Host
2978 + Channel. For a channel associated with a non-periodic EP, the non-periodic
2979 + Tx FIFO is written. For a channel associated with a periodic EP, the
2980 + periodic Tx FIFO is written. This function should only be called in Slave
2983 + Upon return the xfer_buff and xfer_count fields in _hc are incremented by
2984 + then number of bytes written to the Tx FIFO.
2987 +#ifdef __ENABLE_DUMP__
2988 + void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd)
2992 + num_channels = _ifxhcd->core_if.params.host_channels;
2994 + IFX_PRINT("************************************************************\n");
2995 + IFX_PRINT("HCD State:\n");
2996 + IFX_PRINT(" Num channels: %d\n", num_channels);
2997 + for (i = 0; i < num_channels; i++) {
2998 + ifxhcd_hc_t *hc = &_ifxhcd->ifxhc[i];
2999 + IFX_PRINT(" Channel %d:\n", hc->hc_num);
3000 + IFX_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
3001 + hc->dev_addr, hc->ep_num, hc->is_in);
3002 + IFX_PRINT(" speed: %d\n" , hc->speed);
3003 + IFX_PRINT(" ep_type: %d\n" , hc->ep_type);
3004 + IFX_PRINT(" mps: %d\n", hc->mps);
3005 + IFX_PRINT(" data_pid_start: %d\n" , hc->data_pid_start);
3006 + IFX_PRINT(" xfer_started: %d\n" , hc->xfer_started);
3007 + IFX_PRINT(" xfer_buff: %p\n" , hc->xfer_buff);
3008 + IFX_PRINT(" xfer_len: %d\n" , hc->xfer_len);
3009 + IFX_PRINT(" xfer_count: %d\n" , hc->xfer_count);
3010 + IFX_PRINT(" halting: %d\n" , hc->halting);
3011 + IFX_PRINT(" halt_status: %d\n" , hc->halt_status);
3012 + IFX_PRINT(" split: %d\n" , hc->split);
3013 + IFX_PRINT(" hub_addr: %d\n" , hc->hub_addr);
3014 + IFX_PRINT(" port_addr: %d\n" , hc->port_addr);
3015 + #ifdef __EN_ISOC__
3016 + IFX_PRINT(" isoc_xact_pos: %d\n" , hc->isoc_xact_pos);
3018 + IFX_PRINT(" epqh: %p\n" , hc->epqh);
3019 + IFX_PRINT(" short_rw: %d\n" , hc->short_rw);
3020 + IFX_PRINT(" do_ping: %d\n" , hc->do_ping);
3021 + IFX_PRINT(" control_phase: %d\n" , hc->control_phase);
3022 + IFX_PRINT(" pkt_count_limit: %d\n", hc->epqh->pkt_count_limit);
3023 + IFX_PRINT(" start_pkt_count: %d\n" , hc->start_pkt_count);
3025 + IFX_PRINT("************************************************************\n");
3028 +#endif //__ENABLE_DUMP__
3030 diff --git a/drivers/usb/ifxhcd/ifxhcd.h b/drivers/usb/ifxhcd/ifxhcd.h
3031 new file mode 100644
3032 index 0000000..3a40851
3034 +++ b/drivers/usb/ifxhcd/ifxhcd.h
3036 +/*****************************************************************************
3037 + ** FILE NAME : ifxhcd.h
3038 + ** PROJECT : IFX USB sub-system V3
3039 + ** MODULES : IFX USB sub-system Host and Device driver
3040 + ** SRC VERSION : 1.0
3041 + ** DATE : 1/Jan/2009
3042 + ** AUTHOR : Chen, Howard
3043 + ** DESCRIPTION : This file contains the structures, constants, and interfaces for
3044 + ** the Host Contoller Driver (HCD).
3046 + ** The Host Controller Driver (HCD) is responsible for translating requests
3047 + ** from the USB Driver into the appropriate actions on the IFXUSB controller.
3048 + ** It isolates the USBD from the specifics of the controller by providing an
3049 + ** API to the USBD.
3052 + ** REFERENCE : Synopsys DWC-OTG Driver 2.7
3054 + ** Version Control Section **
3058 + ** $Log$ Revision history
3059 +*****************************************************************************/
3062 + \defgroup IFXUSB_HCD HCD Interface
3063 + \ingroup IFXUSB_DRIVER_V3
3064 + \brief The Host Controller Driver (HCD) is responsible for translating requests
3065 + from the USB Driver into the appropriate actions on the IFXUSB controller.
3066 + It isolates the USBD from the specifics of the controller by providing an
3073 + \ingroup IFXUSB_DRIVER_V3
3074 + \brief This file contains the structures, constants, and interfaces for
3075 + the Host Contoller Driver (HCD).
3078 +#if !defined(__IFXHCD_H__)
3079 +#define __IFXHCD_H__
3081 +#include <linux/list.h>
3082 +#include <linux/usb.h>
3084 +#ifdef __USE_TIMER_4_SOF__
3085 +#include <linux/hrtimer.h>
3087 +#include <linux/usb/hcd.h>
3089 +#include "ifxusb_cif.h"
3090 +#include "ifxusb_plat.h"
3095 + \addtogroup IFXUSB_HCD
3099 +/* Phases for control transfers.*/
3100 +typedef enum ifxhcd_control_phase {
3101 + IFXHCD_CONTROL_SETUP,
3102 + IFXHCD_CONTROL_DATA,
3103 + IFXHCD_CONTROL_STATUS
3104 +} ifxhcd_control_phase_e;
3106 +/* Reasons for halting a host channel. */
3107 +typedef enum ifxhcd_halt_status
3109 + HC_XFER_NO_HALT_STATUS, // Initial
3110 + HC_XFER_COMPLETE, // Xact complete without error, upward
3111 + HC_XFER_URB_COMPLETE, // Xfer complete without error, short upward
3112 + HC_XFER_STALL, // HC stopped abnormally, upward/downward
3113 + HC_XFER_XACT_ERR, // HC stopped abnormally, upward
3114 + HC_XFER_FRAME_OVERRUN, // HC stopped abnormally, upward
3115 + HC_XFER_BABBLE_ERR, // HC stopped abnormally, upward
3116 + HC_XFER_AHB_ERR, // HC stopped abnormally, upward
3117 + HC_XFER_DATA_TOGGLE_ERR,
3118 + HC_XFER_URB_DEQUEUE, // HC stopper manually, downward
3119 + HC_XFER_NAK // HC stopped by nak monitor, downward
3120 +} ifxhcd_halt_status_e;
3122 +struct ifxhcd_urbd;
3124 +struct ifxhcd_epqh ;
3128 + \brief A URB Descriptor (URBD) holds the state of a bulk, control,
3129 + interrupt, or isochronous transfer. A single URBD is created for each URB
3130 + (of one of these types) submitted to the HCD. The transfer associated with
3131 + a URBD may require one or multiple transactions.
3133 + A URBD is linked to a EP Queue Head, which is entered in either the
3134 + isoc, intr or non-periodic schedule for execution. When a URBD is chosen for
3135 + execution, some or all of its transactions may be executed. After
3136 + execution, the state of the URBD is updated. The URBD may be retired if all
3137 + its transactions are complete or if an error occurred. Otherwise, it
3138 + remains in the schedule so more transactions can be executed later.
3140 +typedef struct ifxhcd_urbd {
3141 + struct list_head urbd_list_entry; // Hook for EPQH->urbd_list and ifxhcd->urbd_complete_list
3142 + struct urb *urb; /*!< URB for this transfer */
3144 + // struct list_head urb_list;
3145 + // struct list_head anchor_list;
3146 + // struct usb_anchor * anchor;
3147 + // struct usb_device * dev;
3148 + // struct usb_host_endpoint * ep;
3149 + // unsigned int pipe;
3151 + // unsigned int transfer_flags;
3152 + // void * transfer_buffer;
3153 + // dma_addr_t transfer_dma;
3154 + // u32 transfer_buffer_length;
3155 + // u32 actual_length;
3156 + // unsigned char * setup_packet;
3157 + // dma_addr_t setup_dma;
3158 + // int start_frame;
3159 + // int number_of_packets;
3161 + // int error_count;
3162 + // void * context;
3163 + // usb_complete_t complete;
3164 + // struct usb_iso_packet_descriptor iso_frame_desc[0];
3166 + //urb_list For use by current owner of the URB.
3167 + //anchor_list membership in the list of an anchor
3168 + //anchor to anchor URBs to a common mooring
3169 + //dev Identifies the USB device to perform the request.
3170 + //ep Points to the endpoint's data structure. Will
3171 + // eventually replace pipe.
3172 + //pipe Holds endpoint number, direction, type, and more.
3173 + // Create these values with the eight macros available; u
3174 + // sb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is
3175 + // "ctrl", "bulk", "int" or "iso". For example
3176 + // usb_sndbulkpipe or usb_rcvintpipe. Endpoint numbers
3177 + // range from zero to fifteen. Note that "in" endpoint two
3178 + // is a different endpoint (and pipe) from "out" endpoint
3179 + // two. The current configuration controls the existence,
3180 + // type, and maximum packet size of any given endpoint.
3181 + //status This is read in non-iso completion functions to get
3182 + // the status of the particular request. ISO requests
3183 + // only use it to tell whether the URB was unlinked;
3184 + // detailed status for each frame is in the fields of
3185 + // the iso_frame-desc.
3186 + //transfer_flags A variety of flags may be used to affect how URB
3187 + // submission, unlinking, or operation are handled.
3188 + // Different kinds of URB can use different flags.
3189 + // URB_SHORT_NOT_OK
3191 + // URB_NO_TRANSFER_DMA_MAP
3192 + // URB_NO_SETUP_DMA_MAP
3194 + // URB_ZERO_PACKET
3195 + // URB_NO_INTERRUPT
3196 + //transfer_buffer This identifies the buffer to (or from) which the I/O
3197 + // request will be performed (unless URB_NO_TRANSFER_DMA_MAP
3198 + // is set). This buffer must be suitable for DMA; allocate it
3199 + // with kmalloc or equivalent. For transfers to "in"
3200 + // endpoints, contents of this buffer will be modified. This
3201 + // buffer is used for the data stage of control transfers.
3202 + //transfer_dma When transfer_flags includes URB_NO_TRANSFER_DMA_MAP, the
3203 + // device driver is saying that it provided this DMA address,
3204 + // which the host controller driver should use in preference
3205 + // to the transfer_buffer.
3206 + //transfer_buffer_length How big is transfer_buffer. The transfer may be broken
3207 + // up into chunks according to the current maximum packet size
3208 + // for the endpoint, which is a function of the configuration
3209 + // and is encoded in the pipe. When the length is zero, neither
3210 + // transfer_buffer nor transfer_dma is used.
3211 + //actual_length This is read in non-iso completion functions, and it tells
3212 + // how many bytes (out of transfer_buffer_length) were transferred.
3213 + // It will normally be the same as requested, unless either an error
3214 + // was reported or a short read was performed. The URB_SHORT_NOT_OK
3215 + // transfer flag may be used to make such short reads be reported
3217 + //setup_packet Only used for control transfers, this points to eight bytes of
3218 + // setup data. Control transfers always start by sending this data
3219 + // to the device. Then transfer_buffer is read or written, if needed.
3220 + //setup_dma For control transfers with URB_NO_SETUP_DMA_MAP set, the device
3221 + // driver has provided this DMA address for the setup packet. The
3222 + // host controller driver should use this in preference to setup_packet.
3223 + //start_frame Returns the initial frame for isochronous transfers.
3224 + //number_of_packets Lists the number of ISO transfer buffers.
3225 + //interval Specifies the polling interval for interrupt or isochronous transfers.
3226 + // The units are frames (milliseconds) for for full and low speed devices,
3227 + // and microframes (1/8 millisecond) for highspeed ones.
3228 + //error_count Returns the number of ISO transfers that reported errors.
3229 + //context For use in completion functions. This normally points to request-specific
3230 + // driver context.
3231 + //complete Completion handler. This URB is passed as the parameter to the completion
3232 + // function. The completion function may then do what it likes with the URB,
3233 + // including resubmitting or freeing it.
3234 + //iso_frame_desc[0] Used to provide arrays of ISO transfer buffers and to collect the transfer
3235 + // status for each buffer.
3237 + struct ifxhcd_epqh *epqh;
3238 + // Actual data portion, not SETUP or STATUS in case of CTRL XFER
3240 + uint8_t *setup_buff; /*!< Pointer to the entire transfer buffer. (CPU accessable)*/
3241 + uint8_t *xfer_buff; /*!< Pointer to the entire transfer buffer. (CPU accessable)*/
3242 + uint32_t xfer_len; /*!< Total number of bytes to transfer in this xfer. */
3243 + unsigned is_in :1;
3244 + unsigned is_active:1;
3247 + uint8_t error_count; /*!< Holds the number of bus errors that have occurred for a transaction
3248 + within this transfer.
3250 + /*== AVM/BC 20101111 Needed for URB Complete List ==*/
3252 + // For ISOC XFER only
3253 + #ifdef __EN_ISOC__
3254 + int isoc_frame_index; /*!< Index of the next frame descriptor for an isochronous transfer. A
3255 + frame descriptor describes the buffer position and length of the
3256 + data to be transferred in the next scheduled (micro)frame of an
3257 + isochronous transfer. It also holds status for that transaction.
3258 + The frame index starts at 0.
3260 + // For SPLITed ISOC XFER only
3261 + uint8_t isoc_split_pos; /*!< Position of the ISOC split on full/low speed */
3262 + uint16_t isoc_split_offset;/*!< Position of the ISOC split in the buffer for the current frame */
3267 + \brief A EP Queue Head (EPQH) holds the static characteristics of an endpoint and
3268 + maintains a list of transfers (URBDs) for that endpoint. A EPQH structure may
3269 + be entered in either the isoc, intr or non-periodic schedule.
3272 +typedef struct ifxhcd_epqh {
3273 + struct list_head epqh_list_entry; // Hook for EP Queues
3274 + struct list_head urbd_list; /*!< List of URBDs for this EPQH. */
3275 + struct ifxhcd_hc *hc; /*!< Host channel currently processing transfers for this EPQH. */
3276 + struct ifxhcd_urbd *urbd; /*!< URBD currently assigned to a host channel for this EPQH. */
3277 + struct usb_host_endpoint *sysep;
3278 + uint8_t ep_type; /*!< Endpoint type. One of the following values:
3279 + - IFXUSB_EP_TYPE_CTRL
3280 + - IFXUSB_EP_TYPE_ISOC
3281 + - IFXUSB_EP_TYPE_BULK
3282 + - IFXUSB_EP_TYPE_INTR
3284 + uint16_t mps; /*!< wMaxPacketSize Field of Endpoint Descriptor. */
3286 + /* == AVM/WK 20100710 Fix - Use toggle of usbcore ==*/
3287 + /*uint8_t data_toggle;*/ /*!< Determines the PID of the next data packet
3288 + One of the following values:
3289 + - IFXHCD_HC_PID_DATA0
3290 + - IFXHCD_HC_PID_DATA1
3292 + uint8_t is_active;
3294 + uint8_t pkt_count_limit;
3295 + #ifdef __EPQD_DESTROY_TIMEOUT__
3296 + struct timer_list destroy_timer;
3299 + uint16_t wait_for_sof;
3300 + uint8_t need_split; /*!< Full/low speed endpoint on high-speed hub requires split. */
3301 + uint16_t interval; /*!< Interval between transfers in (micro)frames. (for INTR)*/
3303 + uint16_t period_counter; /*!< Interval between transfers in (micro)frames. */
3304 + uint8_t period_do;
3306 + uint8_t aligned_checked;
3308 + #if defined(__UNALIGNED_BUFFER_ADJ__)
3309 + uint8_t using_aligned_setup;
3310 + uint8_t *aligned_setup;
3311 + uint8_t using_aligned_buf;
3312 + uint8_t *aligned_buf;
3313 + unsigned aligned_buf_len : 19;
3316 + uint8_t *dump_buf;
3320 +#if defined(__HC_XFER_TIMEOUT__)
3321 + struct ifxusb_core_if;
3323 + typedef struct hc_xfer_info
3325 + struct ifxusb_core_if *core_if;
3326 + struct ifxhcd_hc *hc;
3328 +#endif //defined(__HC_XFER_TIMEOUT__)
3332 + \brief Host channel descriptor. This structure represents the state of a single
3333 + host channel when acting in host mode. It contains the data items needed to
3334 + transfer packets to an endpoint via a host channel.
3336 +typedef struct ifxhcd_hc
3338 + struct list_head hc_list_entry ; // Hook to free hc
3339 + struct ifxhcd_epqh *epqh ; /*!< EP Queue Head for the transfer being processed by this channel. */
3341 + uint8_t hc_num ; /*!< Host channel number used for register address lookup */
3342 + uint8_t *xfer_buff ; /*!< Pointer to the entire transfer buffer. */
3343 + uint32_t xfer_count ; /*!< Number of bytes transferred so far. The offset of the begin of the buf */
3344 + uint32_t xfer_len ; /*!< Total number of bytes to transfer in this xfer. */
3345 + uint16_t start_pkt_count ; /*!< Packet count at start of transfer. Used to calculate the actual xfer size*/
3346 + ifxhcd_halt_status_e halt_status; /*!< Reason for halting the host channel. */
3348 + unsigned dev_addr : 7; /*!< Device to access */
3349 + unsigned ep_num : 4; /*!< EP to access */
3350 + unsigned is_in : 1; /*!< EP direction. 0: OUT, 1: IN */
3351 + unsigned speed : 2; /*!< EP speed. */
3352 + unsigned ep_type : 2; /*!< Endpoint type. */
3353 + unsigned mps :11; /*!< Max packet size in bytes */
3354 + unsigned data_pid_start : 2; /*!< PID for initial transaction. */
3355 + unsigned do_ping : 1; /*!< Set to 1 to indicate that a PING request should be issued on this
3356 + channel. If 0, process normally.
3359 + unsigned xfer_started : 1; /*!< Flag to indicate whether the transfer has been started. Set to 1 if
3360 + it has been started, 0 otherwise.
3362 + unsigned halting : 1; /*!< Set to 1 if the host channel has been halted, but the core is not
3363 + finished flushing queued requests. Otherwise 0.
3365 + unsigned short_rw : 1; /*!< When Tx, means termination needed.
3366 + When Rx, indicate Short Read */
3367 + /* Split settings for the host channel */
3368 + unsigned split : 2; /*!< Split: 0-Non Split, 1-SSPLIT, 2&3 CSPLIT */
3370 + /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/
3371 + unsigned nyet_count;
3374 + unsigned nak_retry_r : 16;
3375 + unsigned nak_retry : 16;
3376 + #define nak_retry_max 40000
3377 + unsigned nak_countdown : 8;
3378 + unsigned nak_countdown_r: 8;
3379 + #define nak_countdown_max 1
3381 + uint16_t wait_for_sof;
3382 + ifxhcd_control_phase_e control_phase; /*!< Current phase for control transfers (Setup, Data, or Status). */
3383 + uint32_t ssplit_out_xfer_count; /*!< How many bytes transferred during SSPLIT OUT */
3385 + uint32_t start_hcchar_val;
3387 + #ifdef __HC_XFER_TIMEOUT__
3388 + hc_xfer_info_t hc_xfer_info;
3389 + struct timer_list hc_xfer_timer;
3393 + /* Split settings for the host channel */
3394 + uint8_t hub_addr; /*!< Address of high speed hub */
3395 + uint8_t port_addr; /*!< Port of the low/full speed device */
3396 + #ifdef __EN_ISOC__
3397 + uint8_t isoc_xact_pos; /*!< Split transaction position */
3403 + \brief This structure holds the state of the HCD, including the non-periodic and
3404 + periodic schedules.
3406 +typedef struct ifxhcd_hcd
3408 + struct device *dev;
3409 + struct hc_driver hc_driver;
3410 + ifxusb_core_if_t core_if; /*!< Pointer to the core interface structure. */
3411 + struct usb_hcd *syshcd;
3413 + volatile union ifxhcd_internal_flags
3418 + unsigned port_connect_status_change : 1;
3419 + unsigned port_connect_status : 1;
3420 + unsigned port_reset_change : 1;
3421 + unsigned port_enable_change : 1;
3422 + unsigned port_suspend_change : 1;
3423 + unsigned port_over_current_change : 1;
3424 + unsigned reserved : 27;
3426 + } flags; /*!< Internal HCD Flags */
3428 + struct ifxhcd_hc ifxhc[MAX_EPS_CHANNELS]; /*!< Array of pointers to the host channel descriptors. Allows accessing
3429 + a host channel descriptor given the host channel number. This is
3430 + useful in interrupt handlers.
3432 + struct list_head free_hc_list; /*!< Free host channels in the controller. This is a list of ifxhcd_hc_t items. */
3433 + uint8_t *status_buf; /*!< Buffer to use for any data received during the status phase of a
3434 + control transfer. Normally no data is transferred during the status
3435 + phase. This buffer is used as a bit bucket.
3437 + #define IFXHCD_STATUS_BUF_SIZE 64
3439 + struct list_head epqh_np_active; // with URBD, with HC
3440 + struct list_head epqh_np_ready; // with URBD, No HC
3442 + struct list_head epqh_intr_active; // with URBD, with HC
3443 + struct list_head epqh_intr_ready; // with URBD, no pass, No HC
3445 + #ifdef __EN_ISOC__
3446 + struct list_head epqh_isoc_active; // with URBD, with HC
3447 + struct list_head epqh_isoc_ready; // with URBD, no pass, No HC
3450 + /*== AVM/BC 20101111 URB Complete List ==*/
3451 + struct list_head urbd_complete_list;
3453 + struct list_head epqh_stdby;
3455 + /* AVM/BC 20101111 flags removed */
3456 + //unsigned process_channels_in_use : 1;
3457 + //unsigned select_eps_in_use : 1;
3459 + struct tasklet_struct select_eps; /*!< Tasket to do a reset */
3460 + uint32_t lastframe;
3462 +#ifdef __USE_TIMER_4_SOF__
3463 + struct hrtimer hr_timer;
3467 +/* Gets the ifxhcd_hcd from a struct usb_hcd */
3468 +static inline ifxhcd_hcd_t *syshcd_to_ifxhcd(struct usb_hcd *syshcd)
3470 + return (ifxhcd_hcd_t *)(syshcd->hcd_priv[0]);
3473 +/* Gets the struct usb_hcd that contains a ifxhcd_hcd_t. */
3474 +static inline struct usb_hcd *ifxhcd_to_syshcd(ifxhcd_hcd_t *ifxhcd)
3476 + return (struct usb_hcd *)(ifxhcd->syshcd);
3479 +/*! \brief HCD Create/Destroy Functions */
3481 + extern int ifxhcd_init (ifxhcd_hcd_t *_ifxhcd);
3482 + extern void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd);
3485 +/*! \brief Linux HC Driver API Functions */
3487 +extern int ifxhcd_start(struct usb_hcd *hcd);
3488 +extern void ifxhcd_stop (struct usb_hcd *hcd);
3489 +extern int ifxhcd_get_frame_number(struct usb_hcd *hcd);
3493 + \brief This function does the setup for a data transfer for a host channel and
3494 + starts the transfer. May be called in either Slave mode or DMA mode. In
3495 + Slave mode, the caller must ensure that there is sufficient space in the
3496 + request queue and Tx Data FIFO.
3498 + For an OUT transfer in Slave mode, it loads a data packet into the
3499 + appropriate FIFO. If necessary, additional data packets will be loaded in
3502 + For an IN transfer in Slave mode, a data packet is requested. The data
3503 + packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
3504 + additional data packets are requested in the Host ISR.
3506 + For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
3507 + register along with a packet count of 1 and the channel is enabled. This
3508 + causes a single PING transaction to occur. Other fields in HCTSIZ are
3509 + simply set to 0 since no data transfer occurs in this case.
3511 + For a PING transfer in DMA mode, the HCTSIZ register is initialized with
3512 + all the information required to perform the subsequent data transfer. In
3513 + addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
3514 + controller performs the entire PING protocol, then starts the data
3517 + @param _ifxhc Information needed to initialize the host channel. The xfer_len
3518 + value may be reduced to accommodate the max widths of the XferSize and
3519 + PktCnt fields in the HCTSIZn register. The multi_count value may be changed
3520 + to reflect the final xfer_len value.
3522 +extern void ifxhcd_hc_start(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc);
3524 +//extern int ifxhcd_urb_enqueue(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep, struct urb *_urb, gfp_t mem_flags);
3525 +//extern int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb);
3526 +extern irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd);
3527 +int ifxhcd_urb_enqueue( struct usb_hcd *_syshcd,
3528 + /*--- struct usb_host_endpoint *_sysep, Parameter im 2.6.28 entfallen ---*/
3530 + gfp_t _mem_flags);
3531 +int ifxhcd_urb_dequeue( struct usb_hcd *_syshcd,
3532 + struct urb *_urb, int status /* Parameter neu in 2.6.28 */);
3534 +extern void ifxhcd_endpoint_disable(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep);
3536 +extern int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf);
3537 +extern int ifxhcd_hub_control( struct usb_hcd *_syshcd,
3546 +/*! \brief Transaction Execution Functions */
3548 +extern void ifxhcd_complete_urb (ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status);
3552 +/*! \brief Deferred Transaction Execution Functions */
3555 +/*== AVM/BC 20101111 URB Complete List ==*/
3556 +extern void defer_ifxhcd_complete_urb (ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status);
3559 + \brief Clears the transfer state for a host channel. This function is normally
3560 + called after a transfer is done and the host channel is being released.
3562 +extern void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc);
3565 + \brief Attempts to halt a host channel. This function should only be called in
3566 + Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
3567 + normal circumstances in DMA mode, the controller halts the channel when the
3568 + transfer is complete or a condition occurs that requires application
3571 + In slave mode, checks for a free request queue entry, then sets the Channel
3572 + Enable and Channel Disable bits of the Host Channel Characteristics
3573 + register of the specified channel to intiate the halt. If there is no free
3574 + request queue entry, sets only the Channel Disable bit of the HCCHARn
3575 + register to flush requests for this channel. In the latter case, sets a
3576 + flag to indicate that the host channel needs to be halted when a request
3577 + queue slot is open.
3579 + In DMA mode, always sets the Channel Enable and Channel Disable bits of the
3580 + HCCHARn register. The controller ensures there is space in the request
3581 + queue before submitting the halt request.
3583 + Some time may elapse before the core flushes any posted requests for this
3584 + host channel and halts. The Channel Halted interrupt handler completes the
3585 + deactivation of the host channel.
3587 +extern void ifxhcd_hc_halt(ifxusb_core_if_t *_core_if,
3588 + ifxhcd_hc_t *_ifxhc,
3589 + ifxhcd_halt_status_e _halt_status);
3592 + \brief Prepares a host channel for transferring packets to/from a specific
3593 + endpoint. The HCCHARn register is set up with the characteristics specified
3594 + in _ifxhc. Host channel interrupts that may need to be serviced while this
3595 + transfer is in progress are enabled.
3597 +extern void ifxhcd_hc_init(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc);
3600 + \brief This function is called to handle the disconnection of host port.
3602 +int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd);
3605 +/*! \brief Interrupt Handler Functions */
3607 +extern irqreturn_t ifxhcd_oc_irq(int _irq, void *_dev);
3609 +extern int32_t ifxhcd_handle_oc_intr(ifxhcd_hcd_t *_ifxhcd);
3610 +extern int32_t ifxhcd_handle_intr (ifxhcd_hcd_t *_ifxhcd);
3614 +/*! \brief Schedule Queue Functions */
3616 +extern ifxhcd_epqh_t *ifxhcd_epqh_create (ifxhcd_hcd_t *_ifxhcd, struct urb *_urb);
3617 +extern void ifxhcd_epqh_free ( ifxhcd_epqh_t *_epqh);
3618 +extern void select_eps (ifxhcd_hcd_t *_ifxhcd);
3619 +extern void process_channels(ifxhcd_hcd_t *_ifxhcd);
3620 +extern void process_channels_sub(ifxhcd_hcd_t *_ifxhcd);
3621 +extern void complete_channel(ifxhcd_hcd_t *_ifxhcd, ifxhcd_hc_t *_ifxhc, ifxhcd_urbd_t *_urbd);
3622 +extern void ifxhcd_epqh_ready(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh);
3623 +extern void ifxhcd_epqh_active(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh);
3624 +extern void ifxhcd_epqh_idle(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh);
3625 +extern void ifxhcd_epqh_idle_periodic(ifxhcd_epqh_t *_epqh);
3626 +extern int ifxhcd_urbd_create (ifxhcd_hcd_t *_ifxhcd,struct urb *_urb);
3629 +/*! \brief Gets the usb_host_endpoint associated with an URB. */
3630 +static inline struct usb_host_endpoint *ifxhcd_urb_to_endpoint(struct urb *_urb)
3632 + struct usb_device *dev = _urb->dev;
3633 + int ep_num = usb_pipeendpoint(_urb->pipe);
3635 + return (usb_pipein(_urb->pipe))?(dev->ep_in[ep_num]):(dev->ep_out[ep_num]);
3639 + * \brief Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
3640 + * qualified with its direction (possible 32 endpoints per device).
3642 +#define ifxhcd_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
3643 + ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
3646 +/* AVM/WK: not needed?
3648 +extern struct usb_device *usb_alloc_dev (struct usb_device *parent, struct usb_bus *, unsigned port);
3649 +extern int usb_add_hcd (struct usb_hcd *syshcd, unsigned int irqnum, unsigned long irqflags);
3650 +extern void usb_remove_hcd (struct usb_hcd *syshcd);
3651 +extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, struct device *dev, char *bus_name);
3652 +extern void usb_hcd_giveback_urb (struct usb_hcd *syshcd, struct urb *urb);
3653 +extern void usb_put_hcd (struct usb_hcd *syshcd);
3654 +extern long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount);
3657 +/** Internal Functions */
3658 +void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd);
3659 +extern char *syserr(int errno);
3661 +/*@}*//*IFXUSB_HCD*/
3663 +#endif // __IFXHCD_H__
3664 diff --git a/drivers/usb/ifxhcd/ifxhcd_es.c b/drivers/usb/ifxhcd/ifxhcd_es.c
3665 new file mode 100644
3666 index 0000000..ef9e8c0
3668 +++ b/drivers/usb/ifxhcd/ifxhcd_es.c
3670 +/*****************************************************************************
3671 + ** FILE NAME : ifxhcd_es.c
3672 + ** PROJECT : IFX USB sub-system V3
3673 + ** MODULES : IFX USB sub-system Host and Device driver
3674 + ** SRC VERSION : 1.0
3675 + ** DATE : 1/Jan/2009
3676 + ** AUTHOR : Chen, Howard
3677 + ** DESCRIPTION : The file contain function to enable host mode USB-IF Electrical Test function.
3678 + *****************************************************************************/
3682 + \ingroup IFXUSB_DRIVER_V3
3683 + \brief The file contain function to enable host mode USB-IF Electrical Test function.
3686 +#include <linux/version.h>
3687 +#include "ifxusb_version.h"
3689 +#include <linux/kernel.h>
3691 +#include <linux/errno.h>
3693 +#include <linux/dma-mapping.h>
3695 +#include "ifxusb_plat.h"
3696 +#include "ifxusb_regs.h"
3697 +#include "ifxusb_cif.h"
3698 +#include "ifxhcd.h"
3701 +#ifdef __WITH_HS_ELECT_TST__
3703 + * Quick and dirty hack to implement the HS Electrical Test
3704 + * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
3706 + * This code was copied from our userspace app "hset". It sends a
3707 + * Get Device Descriptor control sequence in two parts, first the
3708 + * Setup packet by itself, followed some time later by the In and
3709 + * Ack packets. Rather than trying to figure out how to add this
3710 + * functionality to the normal driver code, we just hijack the
3711 + * hardware, using these two function to drive the hardware
3716 + void do_setup(ifxusb_core_if_t *_core_if)
3719 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
3720 + ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
3721 + ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0];
3722 + uint32_t *data_fifo = _core_if->data_fifo[0];
3724 + gint_data_t gintsts;
3725 + hctsiz_data_t hctsiz;
3726 + hcchar_data_t hcchar;
3727 + haint_data_t haint;
3728 + hcint_data_t hcint;
3731 + /* Enable HAINTs */
3732 + ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
3734 + /* Enable HCINTs */
3735 + ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
3737 + /* Read GINTSTS */
3738 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3739 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
3742 + haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
3743 + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
3746 + hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
3747 + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
3750 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3751 + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
3754 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
3757 + ifxusb_wreg(&hc_global_regs->haint, haint.d32);
3759 + /* Clear GINTSTS */
3760 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
3762 + /* Read GINTSTS */
3763 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3764 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
3767 + * Send Setup packet (Get Device Descriptor)
3770 + /* Make sure channel is disabled */
3771 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3772 + if (hcchar.b.chen) {
3773 + //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
3774 + hcchar.b.chdis = 1;
3775 + // hcchar.b.chen = 1;
3776 + ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
3780 + /* Read GINTSTS */
3781 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3782 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
3785 + haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
3786 + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
3789 + hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
3790 + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
3793 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3794 + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
3797 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
3800 + ifxusb_wreg(&hc_global_regs->haint, haint.d32);
3802 + /* Clear GINTSTS */
3803 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
3805 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3806 + //if (hcchar.b.chen) {
3807 + // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
3813 + hctsiz.b.xfersize = 8;
3814 + hctsiz.b.pktcnt = 1;
3815 + hctsiz.b.pid = IFXUSB_HC_PID_SETUP;
3816 + ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
3819 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3820 + hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
3821 + hcchar.b.epdir = 0;
3822 + hcchar.b.epnum = 0;
3824 + hcchar.b.chen = 1;
3825 + ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
3827 + /* Fill FIFO with Setup data for Get Device Descriptor */
3828 + ifxusb_wreg(data_fifo++, 0x01000680);
3829 + ifxusb_wreg(data_fifo++, 0x00080000);
3831 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3832 + //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
3834 + /* Wait for host channel interrupt */
3836 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3837 + } while (gintsts.b.hcintr == 0);
3839 + //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
3841 + /* Disable HCINTs */
3842 + ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
3844 + /* Disable HAINTs */
3845 + ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
3848 + haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
3849 + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
3852 + hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
3853 + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
3856 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3857 + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
3860 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
3863 + ifxusb_wreg(&hc_global_regs->haint, haint.d32);
3865 + /* Clear GINTSTS */
3866 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
3868 + /* Read GINTSTS */
3869 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3870 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
3873 + void do_in_ack(ifxusb_core_if_t *_core_if)
3876 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
3877 + ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
3878 + ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0];
3879 + uint32_t *data_fifo = _core_if->data_fifo[0];
3881 + gint_data_t gintsts;
3882 + hctsiz_data_t hctsiz;
3883 + hcchar_data_t hcchar;
3884 + haint_data_t haint;
3885 + hcint_data_t hcint;
3886 + grxsts_data_t grxsts;
3888 + /* Enable HAINTs */
3889 + ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
3891 + /* Enable HCINTs */
3892 + ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
3894 + /* Read GINTSTS */
3895 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3896 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
3899 + haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
3900 + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
3903 + hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
3904 + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
3907 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3908 + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
3911 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
3914 + ifxusb_wreg(&hc_global_regs->haint, haint.d32);
3916 + /* Clear GINTSTS */
3917 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
3919 + /* Read GINTSTS */
3920 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3921 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
3924 + * Receive Control In packet
3927 + /* Make sure channel is disabled */
3928 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3929 + if (hcchar.b.chen) {
3930 + //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
3931 + hcchar.b.chdis = 1;
3932 + hcchar.b.chen = 1;
3933 + ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
3937 + /* Read GINTSTS */
3938 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3939 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
3942 + haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
3943 + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
3946 + hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
3947 + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
3950 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3951 + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
3954 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
3957 + ifxusb_wreg(&hc_global_regs->haint, haint.d32);
3959 + /* Clear GINTSTS */
3960 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
3962 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3963 + //if (hcchar.b.chen) {
3964 + // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
3970 + hctsiz.b.xfersize = 8;
3971 + hctsiz.b.pktcnt = 1;
3972 + hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
3973 + ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
3976 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3977 + hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
3978 + hcchar.b.epdir = 1;
3979 + hcchar.b.epnum = 0;
3981 + hcchar.b.chen = 1;
3982 + ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
3984 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3985 + //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
3987 + /* Wait for receive status queue interrupt */
3989 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
3990 + } while (gintsts.b.rxstsqlvl == 0);
3992 + //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
3995 + grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
3996 + //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
3998 + /* Clear RXSTSQLVL in GINTSTS */
4000 + gintsts.b.rxstsqlvl = 1;
4001 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
4003 + switch (grxsts.hb.pktsts) {
4004 + case IFXUSB_HSTS_DATA_UPDT:
4005 + /* Read the data into the host buffer */
4006 + if (grxsts.hb.bcnt > 0) {
4008 + int word_count = (grxsts.hb.bcnt + 3) / 4;
4010 + for (i = 0; i < word_count; i++) {
4011 + (void)ifxusb_rreg(data_fifo++);
4015 + //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.hb.bcnt);
4019 + //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
4023 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
4024 + //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
4026 + /* Wait for receive status queue interrupt */
4028 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
4029 + } while (gintsts.b.rxstsqlvl == 0);
4031 + //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
4034 + grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
4035 + //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
4037 + /* Clear RXSTSQLVL in GINTSTS */
4039 + gintsts.b.rxstsqlvl = 1;
4040 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
4042 + switch (grxsts.hb.pktsts) {
4043 + case IFXUSB_HSTS_XFER_COMP:
4047 + //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
4051 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
4052 + //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
4054 + /* Wait for host channel interrupt */
4056 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
4057 + } while (gintsts.b.hcintr == 0);
4059 + //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
4062 + haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
4063 + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
4066 + hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
4067 + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
4070 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
4071 + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
4074 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
4077 + ifxusb_wreg(&hc_global_regs->haint, haint.d32);
4079 + /* Clear GINTSTS */
4080 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
4082 + /* Read GINTSTS */
4083 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
4084 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
4086 + // usleep(100000);
4091 + * Send handshake packet
4095 + haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
4096 + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
4099 + hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
4100 + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
4103 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
4104 + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
4107 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
4110 + ifxusb_wreg(&hc_global_regs->haint, haint.d32);
4112 + /* Clear GINTSTS */
4113 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
4115 + /* Read GINTSTS */
4116 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
4117 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
4119 + /* Make sure channel is disabled */
4120 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
4121 + if (hcchar.b.chen) {
4122 + //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
4123 + hcchar.b.chdis = 1;
4124 + hcchar.b.chen = 1;
4125 + ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
4129 + /* Read GINTSTS */
4130 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
4131 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
4134 + haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
4135 + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
4138 + hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
4139 + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
4142 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
4143 + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
4146 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
4149 + ifxusb_wreg(&hc_global_regs->haint, haint.d32);
4151 + /* Clear GINTSTS */
4152 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
4154 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
4155 + //if (hcchar.b.chen) {
4156 + // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
4162 + hctsiz.b.xfersize = 0;
4163 + hctsiz.b.pktcnt = 1;
4164 + hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
4165 + ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
4168 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
4169 + hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
4170 + hcchar.b.epdir = 0;
4171 + hcchar.b.epnum = 0;
4173 + hcchar.b.chen = 1;
4174 + ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
4176 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
4177 + //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
4179 + /* Wait for host channel interrupt */
4181 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
4182 + } while (gintsts.b.hcintr == 0);
4184 + //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
4186 + /* Disable HCINTs */
4187 + ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
4189 + /* Disable HAINTs */
4190 + ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
4193 + haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
4194 + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
4197 + hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
4198 + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
4201 + hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
4202 + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
4205 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
4208 + ifxusb_wreg(&hc_global_regs->haint, haint.d32);
4210 + /* Clear GINTSTS */
4211 + ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
4213 + /* Read GINTSTS */
4214 + gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
4215 + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
4217 +#endif //__WITH_HS_ELECT_TST__
4219 diff --git a/drivers/usb/ifxhcd/ifxhcd_intr.c b/drivers/usb/ifxhcd/ifxhcd_intr.c
4220 new file mode 100644
4221 index 0000000..76fe602
4223 +++ b/drivers/usb/ifxhcd/ifxhcd_intr.c
4225 +/*****************************************************************************
4226 + ** FILE NAME : ifxhcd_intr.c
4227 + ** PROJECT : IFX USB sub-system V3
4228 + ** MODULES : IFX USB sub-system Host and Device driver
4229 + ** SRC VERSION : 1.0
4230 + ** DATE : 1/Jan/2009
4231 + ** AUTHOR : Chen, Howard
4232 + ** DESCRIPTION : This file contains the implementation of the HCD Interrupt handlers.
4233 + *****************************************************************************/
4236 + \file ifxhcd_intr.c
4237 + \ingroup IFXUSB_DRIVER_V3
4238 + \brief This file contains the implementation of the HCD Interrupt handlers.
4242 +#include <linux/version.h>
4243 +#include "ifxusb_version.h"
4245 +#include "ifxusb_plat.h"
4246 +#include "ifxusb_regs.h"
4247 +#include "ifxusb_cif.h"
4249 +#include "ifxhcd.h"
4251 +/* AVM/WK 20100520*/
4253 +#error AVM/WK: CONFIG_USB_HOST_IFX_WITH_ISO currently not supported!
4256 +/* Macro used to clear one channel interrupt */
4257 +#define clear_hc_int(_hc_regs_,_intr_) \
4259 + hcint_data_t hcint_clear = {.d32 = 0}; \
4260 + hcint_clear.b._intr_ = 1; \
4261 + ifxusb_wreg(&((_hc_regs_)->hcint), hcint_clear.d32); \
4265 + * Macro used to disable one channel interrupt. Channel interrupts are
4266 + * disabled when the channel is halted or released by the interrupt handler.
4267 + * There is no need to handle further interrupts of that type until the
4268 + * channel is re-assigned. In fact, subsequent handling may cause crashes
4269 + * because the channel structures are cleaned up when the channel is released.
4271 +#define disable_hc_int(_hc_regs_,_intr_) \
4273 + hcint_data_t hcintmsk = {.d32 = 0}; \
4274 + hcintmsk.b._intr_ = 1; \
4275 + ifxusb_mreg(&((_hc_regs_)->hcintmsk), hcintmsk.d32, 0); \
4278 +#define enable_hc_int(_hc_regs_,_intr_) \
4280 + hcint_data_t hcintmsk = {.d32 = 0}; \
4281 + hcintmsk.b._intr_ = 1; \
4282 + ifxusb_mreg(&((_hc_regs_)->hcintmsk),0, hcintmsk.d32); \
4286 + * Save the starting data toggle for the next transfer. The data toggle is
4287 + * saved in the QH for non-control transfers and it's saved in the QTD for
4288 + * control transfers.
4290 +uint8_t read_data_toggle(ifxusb_hc_regs_t *_hc_regs)
4292 + hctsiz_data_t hctsiz;
4293 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
4294 + return(hctsiz.b.pid);
4298 +static void release_channel_dump(ifxhcd_hc_t *ifxhc,
4300 + ifxhcd_epqh_t *epqh,
4301 + ifxhcd_urbd_t *urbd,
4302 + ifxhcd_halt_status_e halt_status)
4305 + printk(KERN_INFO);
4306 + switch (halt_status)
4308 + case HC_XFER_NO_HALT_STATUS:
4309 + printk("HC_XFER_NO_HALT_STATUS");break;
4310 + case HC_XFER_URB_COMPLETE:
4311 + printk("HC_XFER_URB_COMPLETE");break;
4312 + case HC_XFER_AHB_ERR:
4313 + printk("HC_XFER_AHB_ERR");break;
4314 + case HC_XFER_STALL:
4315 + printk("HC_XFER_STALL");break;
4316 + case HC_XFER_BABBLE_ERR:
4317 + printk("HC_XFER_BABBLE_ERR");break;
4318 + case HC_XFER_XACT_ERR:
4319 + printk("HC_XFER_XACT_ERR");break;
4320 + case HC_XFER_URB_DEQUEUE:
4321 + printk("HC_XFER_URB_DEQUEUE");break;
4322 + case HC_XFER_FRAME_OVERRUN:
4323 + printk("HC_XFER_FRAME_OVERRUN");break;
4324 + case HC_XFER_DATA_TOGGLE_ERR:
4325 + printk("HC_XFER_DATA_TOGGLE_ERR");break;
4327 + printk("HC_XFER_NAK");break;
4328 + case HC_XFER_COMPLETE:
4329 + printk("HC_XFER_COMPLETE");break;
4331 + printk("KNOWN");break;
4334 + printk("Ch %d %s%s S%d " , ifxhc->hc_num
4335 + ,(ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL)?"CTRL-":
4336 + ((ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)?"BULK-":
4337 + ((ifxhc->ep_type == IFXUSB_EP_TYPE_INTR)?"INTR-":
4338 + ((ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)?"ISOC-":"????"
4342 + ,(ifxhc->is_in)?"IN":"OUT"
4346 + printk(" [NULL HC] ");
4347 + printk("urb=%p epqh=%p urbd=%p\n",urb,epqh,urbd);
4351 + printk(KERN_INFO " Device address: %d\n", usb_pipedevice(urb->pipe));
4352 + printk(KERN_INFO " Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
4353 + (usb_pipein(urb->pipe) ? "IN" : "OUT"));
4354 + printk(KERN_INFO " Endpoint type: %s\n",
4356 + switch (usb_pipetype(urb->pipe)) {
4357 + case PIPE_CONTROL: pipetype = "CTRL"; break;
4358 + case PIPE_BULK: pipetype = "BULK"; break;
4359 + case PIPE_INTERRUPT: pipetype = "INTR"; break;
4360 + case PIPE_ISOCHRONOUS: pipetype = "ISOC"; break;
4361 + default: pipetype = "????"; break;
4363 + printk(KERN_INFO " Speed: %s\n",
4365 + switch (urb->dev->speed) {
4366 + case USB_SPEED_HIGH: speed = "HS"; break;
4367 + case USB_SPEED_FULL: speed = "FS"; break;
4368 + case USB_SPEED_LOW: speed = "LS"; break;
4369 + default: speed = "????"; break;
4371 + printk(KERN_INFO " Max packet size: %d\n",
4372 + usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
4373 + printk(KERN_INFO " Data buffer length: %d\n", urb->transfer_buffer_length);
4374 + printk(KERN_INFO " Transfer buffer: %p, Transfer DMA: %p\n",
4375 + urb->transfer_buffer, (void *)urb->transfer_dma);
4376 + printk(KERN_INFO " Setup buffer: %p, Setup DMA: %p\n",
4377 + urb->setup_packet, (void *)urb->setup_dma);
4378 + printk(KERN_INFO " Interval: %d\n", urb->interval);
4379 + switch (urb->status)
4381 + case HC_XFER_NO_HALT_STATUS:
4382 + printk(KERN_INFO " STATUS:HC_XFER_NO_HALT_STATUS\n");break;
4383 + case HC_XFER_URB_COMPLETE:
4384 + printk(KERN_INFO " STATUS:HC_XFER_URB_COMPLETE\n");break;
4385 + case HC_XFER_AHB_ERR:
4386 + printk(KERN_INFO " STATUS:HC_XFER_AHB_ERR\n");break;
4387 + case HC_XFER_STALL:
4388 + printk(KERN_INFO " STATUS:HC_XFER_STALL\n");break;
4389 + case HC_XFER_BABBLE_ERR:
4390 + printk(KERN_INFO " STATUS:HC_XFER_BABBLE_ERR\n");break;
4391 + case HC_XFER_XACT_ERR:
4392 + printk(KERN_INFO " STATUS:HC_XFER_XACT_ERR\n");break;
4393 + case HC_XFER_URB_DEQUEUE:
4394 + printk(KERN_INFO " STATUS:HC_XFER_URB_DEQUEUE\n");break;
4395 + case HC_XFER_FRAME_OVERRUN:
4396 + printk(KERN_INFO " STATUS:HC_XFER_FRAME_OVERRUN\n");break;
4397 + case HC_XFER_DATA_TOGGLE_ERR:
4398 + printk(KERN_INFO " STATUS:HC_XFER_DATA_TOGGLE_ERR\n");break;
4399 + case HC_XFER_COMPLETE:
4400 + printk(KERN_INFO " STATUS:HC_XFER_COMPLETE\n");break;
4402 + printk(KERN_INFO " STATUS:KNOWN\n");break;
4409 +static void release_channel(ifxhcd_hcd_t *_ifxhcd,
4410 + ifxhcd_hc_t *_ifxhc,
4411 + ifxhcd_halt_status_e _halt_status)
4413 + ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[_ifxhc->hc_num];
4414 + struct urb *urb = NULL;
4415 + ifxhcd_epqh_t *epqh = NULL;
4416 + ifxhcd_urbd_t *urbd = NULL;
4418 + IFX_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n",
4419 + __func__, _ifxhc->hc_num, _halt_status);
4421 + epqh=_ifxhc->epqh;
4424 + IFX_ERROR("%s epqh=null\n",__func__);
4429 + IFX_ERROR("%s urbd=null\n",__func__);
4434 + IFX_ERROR("%s urb =null\n",__func__);
4436 + /* == AVM/WK 20100710 Fix - Use toggle of usbcore ==*/
4437 + unsigned toggle = (read_data_toggle(hc_regs) == IFXUSB_HC_PID_DATA0)? 0: 1;
4438 + usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), usb_pipeout(urb->pipe), toggle);
4441 + //epqh->data_toggle = read_data_toggle(hc_regs);
4445 + switch (_halt_status)
4447 + case HC_XFER_NO_HALT_STATUS:
4448 + IFX_ERROR("%s: No halt_status, channel %d\n", __func__, _ifxhc->hc_num);
4450 + case HC_XFER_COMPLETE:
4451 + IFX_ERROR("%s: Inavalid halt_status HC_XFER_COMPLETE, channel %d\n", __func__, _ifxhc->hc_num);
4453 + case HC_XFER_URB_COMPLETE:
4454 + case HC_XFER_URB_DEQUEUE:
4455 + case HC_XFER_AHB_ERR:
4456 + case HC_XFER_XACT_ERR:
4457 + case HC_XFER_FRAME_OVERRUN:
4459 + /* == 20110803 AVM/WK FIX set status, if still in progress == */
4460 + if (urb->status == -EINPROGRESS) {
4461 + switch (_halt_status) {
4462 + case HC_XFER_URB_COMPLETE:
4465 + case HC_XFER_URB_DEQUEUE:
4466 + urb->status = -ECONNRESET;
4468 + case HC_XFER_AHB_ERR:
4469 + case HC_XFER_XACT_ERR:
4470 + case HC_XFER_FRAME_OVERRUN:
4471 + urb->status = -EPROTO;
4477 + /*== AVM/BC 20101111 Deferred Complete ==*/
4478 + defer_ifxhcd_complete_urb(_ifxhcd, urbd, urb->status);
4482 + IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
4483 + release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
4486 + ifxhcd_epqh_idle(_ifxhcd, epqh);
4489 + IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh);
4490 + release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
4493 + list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list);
4494 + ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
4496 + case HC_XFER_STALL:
4497 + release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
4499 + /*== AVM/BC 20101111 Deferred Complete ==*/
4500 + defer_ifxhcd_complete_urb(_ifxhcd, urbd, -EPIPE);
4502 + IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
4505 +// epqh->data_toggle = 0;
4506 + ifxhcd_epqh_idle(_ifxhcd, epqh);
4509 + IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh);
4510 + list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list);
4511 + ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
4514 + release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
4517 + //ifxhcd_complete_urb(_ifxhcd, urbd, -ETIMEDOUT);
4519 + /*== AVM/BC 20101111 Deferred Complete ==*/
4520 + defer_ifxhcd_complete_urb(_ifxhcd, urbd, urb->status);
4523 + IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
4525 + ifxhcd_epqh_idle(_ifxhcd, epqh);
4527 + IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh);
4528 + list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list);
4529 + ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
4531 + case HC_XFER_BABBLE_ERR:
4532 + case HC_XFER_DATA_TOGGLE_ERR:
4533 + release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
4535 + /*== AVM/BC 20101111 Deferred Complete ==*/
4536 + defer_ifxhcd_complete_urb(_ifxhcd, urbd, -EOVERFLOW);
4538 + IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
4540 + ifxhcd_epqh_idle(_ifxhcd, epqh);
4542 + IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh);
4543 + list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list);
4544 + ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
4547 + select_eps(_ifxhcd);
4551 + * Updates the state of the URB after a Transfer Complete interrupt on the
4552 + * host channel. Updates the actual_length field of the URB based on the
4553 + * number of bytes transferred via the host channel. Sets the URB status
4554 + * if the data transfer is finished.
4556 + * @return 1 if the data transfer specified by the URB is completely finished,
4559 +static int update_urb_state_xfer_comp(ifxhcd_hc_t *_ifxhc,
4560 + ifxusb_hc_regs_t *_hc_regs,
4562 + ifxhcd_urbd_t *_urbd)
4564 + int xfer_done = 0;
4566 + if (_ifxhc->is_in)
4568 + hctsiz_data_t hctsiz;
4569 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
4570 + _urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
4571 + if ((hctsiz.b.xfersize != 0) || (_urb->actual_length >= _urb->transfer_buffer_length))
4575 + /* 20110805 AVM/WK Workaround: catch overflow error here, hardware does not */
4576 + if (_urb->actual_length > _urb->transfer_buffer_length) {
4577 + _urb->status = -EOVERFLOW;
4580 + if (_urb->actual_length < _urb->transfer_buffer_length && _urb->transfer_flags & URB_SHORT_NOT_OK)
4581 + _urb->status = -EREMOTEIO;
4588 + if (_ifxhc->split)
4589 + _urb->actual_length += _ifxhc->ssplit_out_xfer_count;
4591 + _urb->actual_length += _ifxhc->xfer_len;
4593 + if (_urb->actual_length >= _urb->transfer_buffer_length)
4595 + /*== AVM/BC WK 20110421 ZERO PACKET Workaround ==*/
4596 + if ((_ifxhc->short_rw == 1) && ( _ifxhc->xfer_len > 0) && ( _ifxhc->xfer_len % _ifxhc->mps == 0 ))
4598 + _ifxhc->short_rw = 0;
4599 + //Transfer not finished. Another iteration for ZLP.
4611 + hctsiz_data_t hctsiz;
4612 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
4613 + IFX_DEBUGPL(DBG_HCDV, "IFXUSB: %s: %s, channel %d\n",
4614 + __func__, (_ifxhc->is_in ? "IN" : "OUT"), _ifxhc->hc_num);
4615 + IFX_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", _ifxhc->xfer_len);
4616 + IFX_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", hctsiz.b.xfersize);
4617 + IFX_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
4618 + _urb->transfer_buffer_length);
4619 + IFX_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", _urb->actual_length);
4625 +/*== AVM/BC 20101111 Function called with Lock ==*/
4627 +void complete_channel(ifxhcd_hcd_t *_ifxhcd,
4628 + ifxhcd_hc_t *_ifxhc,
4629 + ifxhcd_urbd_t *_urbd)
4631 + ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[_ifxhc->hc_num];
4632 + struct urb *urb = NULL;
4633 + ifxhcd_epqh_t *epqh = NULL;
4634 + int urb_xfer_done;
4636 + IFX_DEBUGPL(DBG_HCD, "--Complete Channel %d : \n", _ifxhc->hc_num);
4640 + IFX_ERROR("ERROR %s():%d urbd=%p\n",__func__,__LINE__,_urbd);
4645 + epqh = _urbd->epqh;
4649 + IFX_ERROR("ERROR %s():%d urb=%p epqh=%p\n",__func__,__LINE__,urb,epqh);
4653 + _ifxhc->do_ping=0;
4655 + if (_ifxhc->split)
4656 + _ifxhc->split = 1;
4658 + switch (epqh->ep_type)
4660 + case IFXUSB_EP_TYPE_CTRL:
4661 + switch (_ifxhc->control_phase)
4663 + case IFXHCD_CONTROL_SETUP:
4664 + IFX_DEBUGPL(DBG_HCDV, " Control setup transaction done\n");
4665 + if (_urbd->xfer_len > 0)
4667 + _ifxhc->control_phase = IFXHCD_CONTROL_DATA;
4668 + _ifxhc->is_in = _urbd->is_in;
4669 + _ifxhc->xfer_len = _urbd->xfer_len;
4670 + #if defined(__UNALIGNED_BUFFER_ADJ__)
4671 + if(epqh->using_aligned_buf)
4672 + _ifxhc->xfer_buff = epqh->aligned_buf;
4675 + _ifxhc->xfer_buff = _urbd->xfer_buff;
4679 + _ifxhc->control_phase = IFXHCD_CONTROL_STATUS;
4680 + _ifxhc->is_in = 1;
4681 + _ifxhc->xfer_len = 0;
4682 + _ifxhc->xfer_buff = _ifxhcd->status_buf;
4685 + _ifxhc->short_rw =0;
4687 + _ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
4688 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
4689 + _ifxhc->xfer_count = 0;
4690 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
4691 + /*== AVM/BC 20101111 Lock not needed ==*/
4692 + process_channels_sub(_ifxhcd);
4694 + case IFXHCD_CONTROL_DATA:
4695 + urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
4696 + if (urb_xfer_done)
4698 + _ifxhc->control_phase = IFXHCD_CONTROL_STATUS;
4699 + _ifxhc->is_in = (_urbd->is_in)?0:1;
4700 + _ifxhc->xfer_len = 0;
4701 + _ifxhc->xfer_count = 0;
4702 + _ifxhc->xfer_buff = _ifxhcd->status_buf;
4703 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
4704 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
4706 + _ifxhc->short_rw =0;
4708 + _ifxhc->short_rw =1;
4712 + _ifxhc->xfer_len = _urbd->xfer_len - urb->actual_length;
4713 + _ifxhc->xfer_count = urb->actual_length;
4714 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
4715 + _ifxhc->data_pid_start = read_data_toggle(hc_regs);
4717 + /*== AVM/BC 20101111 Lock not needed ==*/
4718 + process_channels_sub(_ifxhcd);
4720 + case IFXHCD_CONTROL_STATUS:
4721 + if (urb->status == -EINPROGRESS)
4723 + release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
4727 + case IFXUSB_EP_TYPE_BULK:
4728 + IFX_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
4729 + urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
4730 + if (urb_xfer_done)
4731 + release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
4734 + _ifxhc->xfer_len = _urbd->xfer_len - urb->actual_length;
4735 + _ifxhc->xfer_count = urb->actual_length;
4736 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
4737 + _ifxhc->data_pid_start = read_data_toggle(hc_regs);
4738 + /*== AVM/BC 20101111 Lock not needed ==*/
4739 + process_channels_sub(_ifxhcd);
4742 + case IFXUSB_EP_TYPE_INTR:
4743 + urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
4744 + release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
4746 + case IFXUSB_EP_TYPE_ISOC:
4747 +// if (_urbd->isoc_split_pos == IFXUSB_HCSPLIT_XACTPOS_ALL)
4748 +// halt_status = update_isoc_urb_state(_ifxhcd, _ifxhc, hc_regs, _urbd, HC_XFER_COMPLETE);
4749 +// complete_periodic_xfer(_ifxhcd, _ifxhc, hc_regs, _urbd, halt_status);
4750 + urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
4751 + release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
4758 +void showint(uint32_t val_hcint
4759 + ,uint32_t val_hcintmsk
4760 + ,uint32_t val_hctsiz)
4763 + hcint_data_t hcint = {.d32 = val_hcint};
4764 + hcint_data_t hcintmsk = {.d32 = val_hcintmsk};
4766 + printk(KERN_INFO " WITH FLAG: Sz:%08x I:%08X/M:%08X %s%s%s%s%s%s%s%s%s%s\n"
4767 + ,val_hctsiz,hcint.d32 ,hcintmsk.d32
4768 + ,(hcint.b.datatglerr || hcintmsk.b.datatglerr)?
4770 + (hcint.b.datatglerr && hcintmsk.b.datatglerr)?"datatglerr[*/*] ":
4772 + (hcint.b.datatglerr)?"datatglerr[*/] ":"datatglerr[/*] "
4776 + ,(hcint.b.frmovrun || hcintmsk.b.frmovrun)?
4778 + (hcint.b.frmovrun && hcintmsk.b.frmovrun)?"frmovrun[*/*] ":
4780 + (hcint.b.frmovrun)?"frmovrun[*/] ":"frmovrun[/*] "
4784 + ,(hcint.b.bblerr || hcintmsk.b.bblerr)?
4786 + (hcint.b.bblerr && hcintmsk.b.bblerr)?"bblerr[*/*] ":
4788 + (hcint.b.bblerr)?"bblerr[*/] ":"bblerr[/*] "
4792 + ,(hcint.b.xacterr || hcintmsk.b.xacterr)?
4794 + (hcint.b.xacterr && hcintmsk.b.xacterr)?"xacterr[*/*] ":
4796 + (hcint.b.xacterr)?"xacterr[*/] ":"xacterr[/*] "
4800 + ,(hcint.b.nyet || hcintmsk.b.nyet)?
4802 + (hcint.b.nyet && hcintmsk.b.nyet)?"nyet[*/*] ":
4804 + (hcint.b.nyet)?"nyet[*/] ":"nyet[/*] "
4808 + ,(hcint.b.nak || hcintmsk.b.nak)?
4810 + (hcint.b.nak && hcintmsk.b.nak)?"nak[*/*] ":
4812 + (hcint.b.nak)?"nak[*/] ":"nak[/*] "
4816 + ,(hcint.b.ack || hcintmsk.b.ack)?
4818 + (hcint.b.ack && hcintmsk.b.ack)?"ack[*/*] ":
4820 + (hcint.b.ack)?"ack[*/] ":"ack[/*] "
4824 + ,(hcint.b.stall || hcintmsk.b.stall)?
4826 + (hcint.b.stall && hcintmsk.b.stall)?"stall[*/*] ":
4828 + (hcint.b.stall)?"stall[*/] ":"stall[/*] "
4832 + ,(hcint.b.ahberr || hcintmsk.b.ahberr)?
4834 + (hcint.b.ahberr && hcintmsk.b.ahberr)?"ahberr[*/*] ":
4836 + (hcint.b.ahberr)?"ahberr[*/] ":"ahberr[/*] "
4840 + ,(hcint.b.xfercomp || hcintmsk.b.xfercomp)?
4842 + (hcint.b.xfercomp && hcintmsk.b.xfercomp)?"xfercomp[*/*] ":
4844 + (hcint.b.xfercomp)?"xfercomp[*/] ":"xfercomp[/*] "
4853 +extern void ifxhcd_hc_dumb_rx(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc,uint8_t *dump_buf);
4855 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4856 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4857 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4858 +static int32_t chhltd_ctrlbulk_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
4859 + ifxhcd_hc_t *_ifxhc,
4860 + ifxusb_hc_regs_t *_hc_regs,
4861 + ifxhcd_urbd_t *_urbd)
4863 + hcint_data_t hcint;
4864 + hcint_data_t hcintmsk;
4865 + hctsiz_data_t hctsiz;
4867 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
4868 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
4869 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
4871 + disable_hc_int(_hc_regs,ack);
4872 + disable_hc_int(_hc_regs,nak);
4873 + disable_hc_int(_hc_regs,nyet);
4874 + _ifxhc->do_ping = 0;
4876 + if(_ifxhc->halt_status == HC_XFER_NAK)
4878 + if(_ifxhc->nak_retry_r)
4880 + _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
4881 + _ifxhc->nak_retry--;
4882 + if(_ifxhc->nak_retry)
4884 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
4885 + _ifxhc->xfer_count = _urbd->urb->actual_length;
4886 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
4887 + _ifxhc->wait_for_sof = 1;
4888 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
4889 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
4893 + _ifxhc->wait_for_sof = 0;
4894 + release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
4899 + _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
4900 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
4901 + _ifxhc->xfer_count = _urbd->urb->actual_length;
4902 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
4903 + _ifxhc->wait_for_sof = 1;
4904 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
4905 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
4910 + if (hcint.b.xfercomp)
4912 + _urbd->error_count =0;
4913 + _ifxhc->wait_for_sof =0;
4914 + complete_channel(_ifxhcd, _ifxhc, _urbd);
4917 + else if (hcint.b.stall)
4919 + _urbd->error_count =0;
4920 + _ifxhc->wait_for_sof =0;
4923 + if(hctsiz.b.pktcnt==0)
4924 + complete_channel(_ifxhcd, _ifxhc, _urbd);
4928 + // Stall FIFO compensation.
4931 + sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt;
4933 + sz1=_ifxhc->xfer_len - hctsiz.b.xfersize;
4936 + ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf);
4938 + _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
4939 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
4943 + else if (hcint.b.bblerr)
4945 + _urbd->error_count =0;
4946 + _ifxhc->wait_for_sof =0;
4950 + if(hctsiz.b.pktcnt==0)
4951 + complete_channel(_ifxhcd, _ifxhc, _urbd);
4954 + _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
4955 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
4958 + else if (hcint.b.xacterr)
4962 + if(hctsiz.b.pktcnt==0)
4964 + _urbd->error_count =0;
4965 + _ifxhc->wait_for_sof =0;
4966 + complete_channel(_ifxhcd, _ifxhc, _urbd);
4971 + _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
4972 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
4973 + _ifxhc->xfer_count = _urbd->urb->actual_length;
4974 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
4976 + /* 20110803 AVM/WK FIX: Reset error count on any handshake */
4977 + if (hcint.b.nak || hcint.b.nyet || hcint.b.ack) {
4978 + _urbd->error_count = 1;
4980 + _urbd->error_count++;
4983 + if (_urbd->error_count >= 3)
4985 + _urbd->error_count =0;
4986 + _ifxhc->wait_for_sof =0;
4987 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
4991 + _ifxhc->wait_for_sof = 1;
4992 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
4997 + else if(hcint.b.datatglerr )
4999 + _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
5001 + if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
5002 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
5004 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
5005 + _ifxhc->wait_for_sof = 1;
5006 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5007 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5008 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5010 + release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
5014 + else if(hcint.b.frmovrun )
5016 +IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT0 FRMOVRUN [should be Period only]\n",__func__,__LINE__);
5017 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5018 + release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
5021 + else if(hcint.b.nyet )
5023 +IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT0 NYET [should be Out only]\n",__func__,__LINE__);
5024 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5028 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5029 +static int32_t chhltd_ctrlbulk_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
5030 + ifxhcd_hc_t *_ifxhc,
5031 + ifxusb_hc_regs_t *_hc_regs,
5032 + ifxhcd_urbd_t *_urbd)
5034 + hcint_data_t hcint;
5035 + hcint_data_t hcintmsk;
5036 + hctsiz_data_t hctsiz;
5037 + int out_nak_enh = 0;
5040 +static int first=0;
5043 + if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
5046 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
5047 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
5048 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
5051 +if(!first&& _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK
5052 + &&(hcint.b.stall || hcint.b.datatglerr || hcint.b.frmovrun || hcint.b.bblerr || hcint.b.xacterr) && !hcint.b.ack)
5054 + showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5056 + printk(KERN_INFO " [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X] \n"
5057 + ,*(_ifxhc->xfer_buff+ 0),*(_ifxhc->xfer_buff+ 1),*(_ifxhc->xfer_buff+ 2),*(_ifxhc->xfer_buff+ 3)
5058 + ,*(_ifxhc->xfer_buff+ 4),*(_ifxhc->xfer_buff+ 5),*(_ifxhc->xfer_buff+ 6),*(_ifxhc->xfer_buff+ 7)
5059 + ,*(_ifxhc->xfer_buff+ 8),*(_ifxhc->xfer_buff+ 9),*(_ifxhc->xfer_buff+10),*(_ifxhc->xfer_buff+11)
5060 + ,*(_ifxhc->xfer_buff+12),*(_ifxhc->xfer_buff+13),*(_ifxhc->xfer_buff+14),*(_ifxhc->xfer_buff+15));
5062 + printk(KERN_INFO " [_urbd->urb->actual_length:%08X _ifxhc->start_pkt_count:%08X hctsiz.b.pktcnt:%08X ,_urbd->xfer_len:%08x] \n"
5063 + ,_urbd->urb->actual_length
5064 + ,_ifxhc->start_pkt_count
5066 + ,_urbd->xfer_len);
5070 + if(_ifxhc->halt_status == HC_XFER_NAK)
5072 + if(_ifxhc->nak_retry_r)
5074 + _ifxhc->nak_retry--;
5075 + if(_ifxhc->nak_retry)
5077 + if(_ifxhc->xfer_len!=0)
5078 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5079 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5080 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5081 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5082 + _ifxhc->wait_for_sof = 1;
5083 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
5084 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5088 + _ifxhc->wait_for_sof = 0;
5089 + release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
5094 + if(_ifxhc->xfer_len!=0)
5095 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5096 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5097 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5098 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5099 + _ifxhc->wait_for_sof = 1;
5100 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
5101 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5106 + if (hcint.b.xfercomp)
5108 + disable_hc_int(_hc_regs,ack);
5109 + disable_hc_int(_hc_regs,nak);
5110 + disable_hc_int(_hc_regs,nyet);
5111 + _urbd->error_count =0;
5112 + if(_ifxhc->xfer_len==0 && !hcint.b.ack && hcint.b.nak)
5114 + // Walkaround: When sending ZLP and receive NAK but also issue CMPT intr
5115 + // Solution: NoSplit: Resend at next SOF
5116 + // Split : Resend at next SOF with SSPLIT
5117 + if(hcint.b.nyet && !out_nak_enh)
5118 + _ifxhc->do_ping = 1;
5120 + _ifxhc->do_ping = 0;
5121 + _ifxhc->xfer_len = 0;
5122 + _ifxhc->xfer_count = 0;
5123 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
5124 + _ifxhc->wait_for_sof = 1;
5125 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5129 + _ifxhc->wait_for_sof = 0;
5130 + _ifxhc->do_ping = 0;
5131 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5135 + else if (hcint.b.stall)
5137 + disable_hc_int(_hc_regs,ack);
5138 + disable_hc_int(_hc_regs,nak);
5139 + disable_hc_int(_hc_regs,nyet);
5140 + _urbd->error_count =0;
5141 + _ifxhc->wait_for_sof =0;
5142 + _ifxhc->do_ping =0;
5146 + if(hctsiz.b.pktcnt==0)
5147 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5151 + if(_ifxhc->xfer_len!=0)
5152 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5153 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
5157 + else if (hcint.b.xacterr)
5161 + if(hctsiz.b.pktcnt==0)
5163 + disable_hc_int(_hc_regs,ack);
5164 + disable_hc_int(_hc_regs,nak);
5165 + disable_hc_int(_hc_regs,nyet);
5166 + _urbd->error_count =0;
5167 + _ifxhc->wait_for_sof =0;
5168 + _ifxhc->do_ping =0;
5169 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5174 + if(_ifxhc->xfer_len!=0)
5175 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5176 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5177 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5178 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5180 + if (hcint.b.nak || hcint.b.nyet || hcint.b.ack)
5182 + _urbd->error_count =0;
5183 + _ifxhc->wait_for_sof =1;
5184 + enable_hc_int(_hc_regs,ack);
5185 + enable_hc_int(_hc_regs,nak);
5186 + enable_hc_int(_hc_regs,nyet);
5188 + _ifxhc->do_ping =1;
5190 + _ifxhc->do_ping =0;
5191 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5195 + _urbd->error_count ++ ;
5196 + if (_urbd->error_count == 3)
5198 + disable_hc_int(_hc_regs,ack);
5199 + disable_hc_int(_hc_regs,nak);
5200 + disable_hc_int(_hc_regs,nyet);
5201 + _urbd->error_count =0;
5202 + _ifxhc->wait_for_sof =0;
5203 + _ifxhc->do_ping =0;
5204 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
5208 + enable_hc_int(_hc_regs,ack);
5209 + enable_hc_int(_hc_regs,nak);
5210 + enable_hc_int(_hc_regs,nyet);
5211 + _ifxhc->wait_for_sof =1;
5213 + _ifxhc->do_ping =1;
5215 + _ifxhc->do_ping =0;
5216 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5222 + else if(hcint.b.bblerr )
5224 +IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT0 BABBLE [should be IN only]\n",__func__,__LINE__);
5225 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5226 + _ifxhc->do_ping = 0;
5227 + if(_ifxhc->xfer_len!=0)
5228 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5229 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
5232 + else if(hcint.b.nak || hcint.b.nyet)
5238 + if(hctsiz.b.pktcnt==0)
5240 + _urbd->error_count =0;
5241 + _ifxhc->wait_for_sof =0;
5242 + _ifxhc->do_ping =0;
5243 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5249 + _ifxhc->do_ping =1;
5251 + _ifxhc->do_ping =0;
5252 + if(_ifxhc->xfer_len!=0)
5254 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5255 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5256 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5258 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5259 + _ifxhc->wait_for_sof = 1;
5260 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5265 + else if(hcint.b.datatglerr )
5267 +IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT0 DATATGLERR [should be IN only]\n",__func__,__LINE__);
5268 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5269 + _urbd->error_count =0;
5270 + _ifxhc->wait_for_sof =0;
5271 + _ifxhc->do_ping =0;
5272 + release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
5275 + else if(hcint.b.frmovrun )
5277 +IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT0 FRMOVRUN [should be PERIODIC only]\n",__func__,__LINE__);
5278 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5279 + _urbd->error_count =0;
5280 + _ifxhc->wait_for_sof =0;
5281 + _ifxhc->do_ping =0;
5282 + release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
5287 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5288 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5289 +static int32_t chhltd_intr_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
5290 + ifxhcd_hc_t *_ifxhc,
5291 + ifxusb_hc_regs_t *_hc_regs,
5292 + ifxhcd_urbd_t *_urbd)
5294 + hcint_data_t hcint;
5295 + hcint_data_t hcintmsk;
5296 + hctsiz_data_t hctsiz;
5298 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
5299 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
5300 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
5301 + disable_hc_int(_hc_regs,ack);
5302 + disable_hc_int(_hc_regs,nak);
5303 + disable_hc_int(_hc_regs,nyet);
5304 + _ifxhc->do_ping =0;
5306 + if(_ifxhc->halt_status == HC_XFER_NAK)
5308 + if(_ifxhc->nak_retry_r)
5310 + _ifxhc->nak_retry--;
5311 + if(_ifxhc->nak_retry)
5313 + if(_ifxhc->xfer_len!=0)
5314 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5315 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5316 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5317 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5318 + _ifxhc->wait_for_sof = 1;
5319 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
5320 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5324 + _ifxhc->wait_for_sof = 0;
5325 + release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
5330 + if(_ifxhc->xfer_len!=0)
5331 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5332 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5333 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5334 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5335 + _ifxhc->wait_for_sof = 1;
5336 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
5337 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5342 + if(hcint.b.xfercomp )
5344 + _urbd->error_count =0;
5345 + //restart INTR immediately
5347 + if(hctsiz.b.pktcnt>0)
5349 + // TODO Re-initialize Channel (in next b_interval - 1 uF/F)
5350 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
5351 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
5352 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5357 + _ifxhc->wait_for_sof =0;
5358 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5362 + else if (hcint.b.stall)
5364 + _urbd->error_count =0;
5365 + _ifxhc->wait_for_sof =0;
5367 + // Don't care shortcut
5369 + if(hctsiz.b.pktcnt==0)
5370 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5374 + // Stall FIFO compensation.
5377 + sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt;
5379 + sz1=_ifxhc->xfer_len - hctsiz.b.xfersize;
5382 + ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf);
5384 + _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
5385 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
5391 + else if (hcint.b.bblerr)
5393 + _urbd->error_count =0;
5394 + _ifxhc->wait_for_sof =0;
5396 + // Don't care shortcut
5398 + if(hctsiz.b.pktcnt==0)
5399 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5403 + _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
5404 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
5408 + else if (hcint.b.nak || hcint.b.datatglerr || hcint.b.frmovrun)
5410 + _urbd->error_count =0;
5411 + //restart INTR immediately
5413 + if(hctsiz.b.pktcnt>0)
5415 + // TODO Re-initialize Channel (in next b_interval - 1 uF/F)
5416 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
5417 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
5418 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5423 + _ifxhc->wait_for_sof =0;
5424 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5428 + else if (hcint.b.xacterr)
5432 + if(hctsiz.b.pktcnt==0)
5434 + _urbd->error_count =0;
5435 + _ifxhc->wait_for_sof =0;
5436 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5441 + /* 20110803 AVM/WK FIX: Reset error count on any handshake */
5442 + if (hcint.b.nak || hcint.b.nyet || hcint.b.ack) {
5443 + _urbd->error_count = 1;
5445 + _urbd->error_count++;
5448 + if(_urbd->error_count>=3)
5450 + _urbd->error_count =0;
5451 + _ifxhc->wait_for_sof =0;
5452 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
5456 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
5457 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5462 + else if(hcint.b.nyet )
5464 +IFX_WARN("%s() %d Warning INTR IN SPLIT0 NYET [should be OUT only]\n",__func__,__LINE__);
5465 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5470 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5471 +static int32_t chhltd_intr_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
5472 + ifxhcd_hc_t *_ifxhc,
5473 + ifxusb_hc_regs_t *_hc_regs,
5474 + ifxhcd_urbd_t *_urbd)
5476 + hcint_data_t hcint;
5477 + hcint_data_t hcintmsk;
5478 + hctsiz_data_t hctsiz;
5479 + int out_nak_enh = 0;
5481 + if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
5484 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
5485 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
5486 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
5488 + if(_ifxhc->halt_status == HC_XFER_NAK)
5490 + if(_ifxhc->nak_retry_r)
5492 + _ifxhc->nak_retry--;
5493 + if(_ifxhc->nak_retry)
5495 + if(_ifxhc->xfer_len!=0)
5496 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5497 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5498 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5499 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5500 + _ifxhc->wait_for_sof = 1;
5501 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
5502 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5506 + _ifxhc->wait_for_sof = 0;
5507 + release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
5512 + if(_ifxhc->xfer_len!=0)
5513 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5514 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5515 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5516 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5517 + _ifxhc->wait_for_sof = 1;
5518 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
5519 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5524 + if(hcint.b.xfercomp )
5526 + disable_hc_int(_hc_regs,ack);
5527 + disable_hc_int(_hc_regs,nak);
5528 + disable_hc_int(_hc_regs,nyet);
5529 + _urbd->error_count =0;
5530 + //restart INTR immediately
5532 + if(hctsiz.b.pktcnt>0)
5534 + // TODO Re-initialize Channel (in next b_interval - 1 uF/F)
5535 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
5536 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
5537 + if(hcint.b.nyet && !out_nak_enh )
5538 + _ifxhc->do_ping =1;
5540 + _ifxhc->do_ping =0;
5541 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5546 + _ifxhc->wait_for_sof =0;
5547 + _ifxhc->do_ping =0;
5548 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5552 + else if (hcint.b.stall)
5554 + disable_hc_int(_hc_regs,ack);
5555 + disable_hc_int(_hc_regs,nyet);
5556 + disable_hc_int(_hc_regs,nak);
5557 + _urbd->error_count =0;
5558 + _ifxhc->wait_for_sof =0;
5559 + _ifxhc->do_ping =0;
5561 + // Don't care shortcut
5563 + if(hctsiz.b.pktcnt==0)
5564 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5568 + if(_ifxhc->xfer_len!=0)// !_ifxhc->is_in
5569 + _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
5570 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
5574 + else if(hcint.b.nak || hcint.b.frmovrun )
5576 + disable_hc_int(_hc_regs,ack);
5577 + disable_hc_int(_hc_regs,nyet);
5578 + disable_hc_int(_hc_regs,nak);
5579 + _urbd->error_count =0;
5580 + //restart INTR immediately
5582 + if(hctsiz.b.pktcnt>0)
5584 + // TODO Re-initialize Channel (in next b_interval - 1 uF/F)
5585 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
5586 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
5588 + _ifxhc->do_ping =1;
5590 + _ifxhc->do_ping =0;
5591 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5596 + _ifxhc->wait_for_sof =0;
5597 + _ifxhc->do_ping =0;
5598 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5602 + else if(hcint.b.xacterr )
5606 + if(hctsiz.b.pktcnt==0)
5608 + _urbd->error_count =0;
5609 + _ifxhc->wait_for_sof =0;
5610 + _ifxhc->do_ping =0;
5611 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5616 + /* 20110803 AVM/WK FIX: Reset error count on any handshake */
5617 + if (hcint.b.nak || hcint.b.nyet || hcint.b.ack) {
5618 + _urbd->error_count = 1;
5620 + _urbd->error_count++;
5623 + if(_urbd->error_count>=3)
5625 + _urbd->error_count =0;
5626 + _ifxhc->wait_for_sof =0;
5627 + _ifxhc->do_ping =0;
5628 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
5632 + //_ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
5633 + //if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
5634 + _ifxhc->wait_for_sof=1;
5636 + _ifxhc->do_ping =1;
5638 + _ifxhc->do_ping =0;
5640 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5645 + else if(hcint.b.bblerr )
5647 +IFX_WARN("%s() %d Warning INTR OUT SPLIT0 BABBLEERR [should be IN only]\n",__func__,__LINE__);
5648 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5649 + _urbd->error_count =0;
5650 + _ifxhc->wait_for_sof =0;
5651 + _ifxhc->do_ping =0;
5652 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
5655 + else if(hcint.b.datatglerr )
5657 +IFX_WARN("%s() %d Warning INTR OUT SPLIT0 DATATGLERR\n",__func__,__LINE__);
5658 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5659 + _urbd->error_count =0;
5660 + _ifxhc->wait_for_sof =0;
5661 + _ifxhc->do_ping =0;
5662 + release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
5667 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5668 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5669 +static int32_t chhltd_isoc_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
5670 + ifxhcd_hc_t *_ifxhc,
5671 + ifxusb_hc_regs_t *_hc_regs,
5672 + ifxhcd_urbd_t *_urbd)
5674 + #if defined(__EN_ISOC__)
5675 + hcint_data_t hcint;
5676 + hcint_data_t hcintmsk;
5677 + hctsiz_data_t hctsiz;
5679 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
5680 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
5681 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
5683 + if (hcint.b.xfercomp || hcint.b.frmovrun)
5685 + _urbd->error_count=0;
5686 + disable_hc_int(_hc_regs,ack);
5687 + disable_hc_int(_hc_regs,nak);
5688 + disable_hc_int(_hc_regs,nyet);
5689 + _ifxhc->wait_for_sof = 0;
5690 + if (hcint.b.xfercomp)
5691 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5693 + release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
5695 + else if (hcint.b.xacterr || hcint.b.bblerr)
5698 + if(hctsiz.b.pktcnt==0)
5700 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5705 + sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt;
5707 + sz1=_ifxhc->xfer_len - hctsiz.b.xfersize;
5710 + ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf);
5711 + _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
5712 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5713 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5714 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5715 + _urbd->error_count++;
5716 + if(_urbd->error_count>=3)
5718 + _urbd->error_count=0;
5719 + _ifxhc->wait_for_sof = 0;
5720 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
5721 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
5725 + _ifxhc->wait_for_sof = 1;
5726 + enable_hc_int(_hc_regs,ack);
5727 + enable_hc_int(_hc_regs,nak);
5728 + enable_hc_int(_hc_regs,nyet);
5729 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5734 + else if(hcint.b.datatglerr )
5738 + else if(hcint.b.stall )
5746 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5747 +static int32_t chhltd_isoc_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
5748 + ifxhcd_hc_t *_ifxhc,
5749 + ifxusb_hc_regs_t *_hc_regs,
5750 + ifxhcd_urbd_t *_urbd)
5752 + #if defined(__EN_ISOC__)
5753 + hcint_data_t hcint;
5754 + hcint_data_t hcintmsk;
5755 + hctsiz_data_t hctsiz;
5756 + int out_nak_enh = 0;
5758 + if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
5761 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
5762 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
5763 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
5765 + if (hcint.b.xfercomp)
5767 + _urbd->error_count=0;
5768 + disable_hc_int(_hc_regs,ack);
5769 + disable_hc_int(_hc_regs,nak);
5770 + disable_hc_int(_hc_regs,nyet);
5771 + _ifxhc->wait_for_sof = 0;
5772 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5775 + else if (hcint.b.frmovrun)
5778 + _urbd->error_count=0;
5779 + disable_hc_int(_hc_regs,ack);
5780 + disable_hc_int(_hc_regs,nak);
5781 + disable_hc_int(_hc_regs,nyet);
5782 + _ifxhc->wait_for_sof = 0;
5783 + release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
5786 + else if(hcint.b.datatglerr )
5790 + else if(hcint.b.bblerr )
5793 + if(hctsiz.b.pktcnt==0)
5795 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5800 + sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt;
5802 + sz1=_ifxhc->xfer_len - hctsiz.b.xfersize;
5805 + ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf);
5806 + _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
5807 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
5808 + _ifxhc->xfer_count = _urbd->urb->actual_length;
5809 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5810 + _urbd->error_count++;
5811 + if(_urbd->error_count>=3)
5813 + _urbd->error_count=0;
5814 + _ifxhc->wait_for_sof = 0;
5815 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
5819 + _ifxhc->wait_for_sof = 1;
5820 + enable_hc_int(_hc_regs,ack);
5821 + enable_hc_int(_hc_regs,nak);
5822 + enable_hc_int(_hc_regs,nyet);
5823 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5828 + else if(hcint.b.xacterr )
5830 + if(hctsiz.b.pktcnt==0)
5832 + complete_channel(_ifxhcd, _ifxhc, _urbd);
5835 + _urbd->error_count++;
5836 + if(_urbd->error_count>=3)
5838 + _urbd->error_count=0;
5839 + _ifxhc->wait_for_sof = 0;
5840 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
5844 + _ifxhc->wait_for_sof = 1;
5845 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5849 + else if(hcint.b.stall )
5857 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5858 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5859 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5860 +static int32_t chhltd_ctrlbulk_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
5861 + ifxhcd_hc_t *_ifxhc,
5862 + ifxusb_hc_regs_t *_hc_regs,
5863 + ifxhcd_urbd_t *_urbd)
5865 + hcint_data_t hcint;
5866 + hcint_data_t hcintmsk;
5867 + hctsiz_data_t hctsiz;
5869 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
5870 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
5871 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
5873 + disable_hc_int(_hc_regs,ack);
5874 + disable_hc_int(_hc_regs,nak);
5875 + disable_hc_int(_hc_regs,nyet);
5877 + _ifxhc->do_ping =0;
5881 + _urbd->error_count=0;
5883 + _ifxhc->wait_for_sof = 8;
5884 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
5885 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5888 + else if (hcint.b.nak)
5890 + _ifxhc->wait_for_sof = 1;
5891 + _urbd->error_count = 0;
5892 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5895 + else if (hcint.b.xacterr)
5897 + _urbd->error_count++;
5898 + if(_urbd->error_count>=3)
5900 + _urbd->error_count=0;
5901 + _ifxhc->wait_for_sof =0;
5902 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
5906 + _ifxhc->wait_for_sof =1;
5907 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
5911 + else if(hcint.b.bblerr )
5913 + _urbd->error_count =0;
5914 + _ifxhc->wait_for_sof =0;
5915 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
5918 + else if(hcint.b.stall )
5920 + _urbd->error_count =0;
5921 + _ifxhc->wait_for_sof =0;
5922 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
5925 + else if(hcint.b.datatglerr )
5927 +IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 HC_XFER_DATA_TOGGLE_ERR\n",__func__,__LINE__);
5928 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5929 + _urbd->error_count =0;
5930 + _ifxhc->wait_for_sof =0;
5931 + release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
5934 + else if(hcint.b.frmovrun )
5936 +IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 HC_XFER_FRAME_OVERRUN\n",__func__,__LINE__);
5937 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5938 + _urbd->error_count =0;
5939 + _ifxhc->wait_for_sof =0;
5940 + release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
5943 + else if(hcint.b.nyet )
5945 +IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 NYET\n",__func__,__LINE__);
5946 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5948 + else if(hcint.b.xfercomp )
5950 +IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 COMPLETE\n",__func__,__LINE__);
5951 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5955 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5956 +static int32_t chhltd_ctrlbulk_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
5957 + ifxhcd_hc_t *_ifxhc,
5958 + ifxusb_hc_regs_t *_hc_regs,
5959 + ifxhcd_urbd_t *_urbd)
5961 + hcint_data_t hcint;
5962 + hcint_data_t hcintmsk;
5963 + hctsiz_data_t hctsiz;
5964 + int out_nak_enh = 0;
5967 +static int first=0;
5970 + if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
5973 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
5974 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
5975 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
5976 + disable_hc_int(_hc_regs,ack);
5977 + disable_hc_int(_hc_regs,nak);
5978 + disable_hc_int(_hc_regs,nyet);
5981 + if(!first&& _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK
5982 + &&(hcint.b.stall || hcint.b.datatglerr || hcint.b.frmovrun || hcint.b.bblerr || hcint.b.xacterr) && !hcint.b.ack)
5984 + showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
5986 + printk(KERN_INFO " [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X] \n"
5987 + ,*(_ifxhc->xfer_buff+ 0),*(_ifxhc->xfer_buff+ 1),*(_ifxhc->xfer_buff+ 2),*(_ifxhc->xfer_buff+ 3)
5988 + ,*(_ifxhc->xfer_buff+ 4),*(_ifxhc->xfer_buff+ 5),*(_ifxhc->xfer_buff+ 6),*(_ifxhc->xfer_buff+ 7)
5989 + ,*(_ifxhc->xfer_buff+ 8),*(_ifxhc->xfer_buff+ 9),*(_ifxhc->xfer_buff+10),*(_ifxhc->xfer_buff+11)
5990 + ,*(_ifxhc->xfer_buff+12),*(_ifxhc->xfer_buff+13),*(_ifxhc->xfer_buff+14),*(_ifxhc->xfer_buff+15));
5992 + printk(KERN_INFO " [_urbd->urb->actual_length:%08X _ifxhc->start_pkt_count:%08X hctsiz.b.pktcnt:%08X ,_urbd->xfer_len:%08x] \n"
5993 + ,_urbd->urb->actual_length
5994 + ,_ifxhc->start_pkt_count
5996 + ,_urbd->xfer_len);
6002 + _urbd->error_count=0;
6003 + if (_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK || _ifxhc->control_phase != IFXHCD_CONTROL_SETUP)
6004 + _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
6006 + _ifxhc->wait_for_sof =8;
6007 + _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
6008 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6011 + else if(hcint.b.nyet)
6013 +IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT1 NYET\n",__func__,__LINE__);
6014 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
6015 + _urbd->error_count=0;
6016 + if (_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK || _ifxhc->control_phase != IFXHCD_CONTROL_SETUP)
6017 + _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
6019 + _ifxhc->wait_for_sof =1;
6020 + _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
6021 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6024 + else if(hcint.b.nak )
6026 + _ifxhc->wait_for_sof =1;
6028 + _ifxhc->do_ping =1;
6030 + _ifxhc->do_ping =0;
6031 + _urbd->error_count =0;
6032 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6035 + else if(hcint.b.xacterr )
6037 + _urbd->error_count++;
6038 + if(_urbd->error_count>=3)
6040 + _urbd->error_count=0;
6041 + _ifxhc->wait_for_sof =0;
6042 + _ifxhc->do_ping =0;
6043 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
6047 + _ifxhc->wait_for_sof =1;
6048 + _ifxhc->do_ping =1;
6049 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6053 + else if(hcint.b.datatglerr )
6055 + _urbd->error_count =0;
6056 + _ifxhc->wait_for_sof =0;
6057 + _ifxhc->do_ping =0;
6058 + release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
6061 + else if(hcint.b.bblerr )
6063 + _urbd->error_count =0;
6064 + _ifxhc->wait_for_sof =0;
6065 + _ifxhc->do_ping =0;
6066 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
6069 + else if(hcint.b.stall )
6071 + _urbd->error_count =0;
6072 + _ifxhc->wait_for_sof =0;
6073 + _ifxhc->do_ping =0;
6074 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
6077 + else if(hcint.b.frmovrun )
6079 +IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT1 HC_XFER_FRAME_OVERRUN\n",__func__,__LINE__);
6080 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
6081 + _urbd->error_count =0;
6082 + _ifxhc->wait_for_sof =0;
6083 + _ifxhc->do_ping =0;
6084 + release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
6087 + else if(hcint.b.xfercomp )
6089 + printk(KERN_INFO "%s() %d Warning CTRLBULK OUT SPLIT1 COMPLETE\n",__func__,__LINE__);
6093 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6094 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6095 +static int32_t chhltd_intr_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
6096 + ifxhcd_hc_t *_ifxhc,
6097 + ifxusb_hc_regs_t *_hc_regs,
6098 + ifxhcd_urbd_t *_urbd)
6100 + hcint_data_t hcint;
6101 + hcint_data_t hcintmsk;
6102 + hctsiz_data_t hctsiz;
6104 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
6105 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
6106 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
6108 + disable_hc_int(_hc_regs,ack);
6109 + disable_hc_int(_hc_regs,nak);
6110 + disable_hc_int(_hc_regs,nyet);
6112 + _ifxhc->do_ping =0;
6116 + /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/
6117 + _ifxhc->nyet_count=0;
6119 + _urbd->error_count=0;
6121 + _ifxhc->wait_for_sof = 0;
6122 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
6123 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6126 + else if(hcint.b.nak )
6128 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6129 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6130 + _urbd->error_count=0;
6131 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6134 + else if(hcint.b.xacterr )
6136 + hcchar_data_t hcchar;
6137 + hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
6138 + _urbd->error_count=hcchar.b.multicnt;
6139 + if(_urbd->error_count>=3)
6141 + _urbd->error_count=0;
6142 + _ifxhc->wait_for_sof = 0;
6143 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
6147 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6148 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6149 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6153 + else if(hcint.b.stall )
6155 + _urbd->error_count =0;
6156 + _ifxhc->wait_for_sof =0;
6157 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
6160 + else if(hcint.b.bblerr )
6162 + _urbd->error_count =0;
6163 + _ifxhc->wait_for_sof =0;
6164 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
6167 + else if(hcint.b.frmovrun )
6169 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6170 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6171 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6174 + else if(hcint.b.datatglerr )
6176 +IFX_WARN( "%s() %d Warning INTR IN SPLIT1 DATATGLERR\n",__func__,__LINE__);
6177 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
6178 + _urbd->error_count =0;
6179 + _ifxhc->wait_for_sof =0;
6180 + release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
6183 + else if(hcint.b.xfercomp )
6185 +IFX_WARN("%s() %d Warning INTR IN SPLIT1 COMPLETE\n",__func__,__LINE__);
6186 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
6190 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6191 +static int32_t chhltd_intr_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
6192 + ifxhcd_hc_t *_ifxhc,
6193 + ifxusb_hc_regs_t *_hc_regs,
6194 + ifxhcd_urbd_t *_urbd)
6196 + hcint_data_t hcint;
6197 + hcint_data_t hcintmsk;
6198 + hctsiz_data_t hctsiz;
6199 + int out_nak_enh = 0;
6201 + if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
6204 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
6205 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
6206 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
6208 + disable_hc_int(_hc_regs,ack);
6209 + disable_hc_int(_hc_regs,nak);
6210 + disable_hc_int(_hc_regs,nyet);
6214 + /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/
6215 + _ifxhc->nyet_count=0;
6217 + _urbd->error_count=0;
6218 + _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
6220 + _ifxhc->wait_for_sof = 0;
6221 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
6222 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6225 + else if(hcint.b.nyet)
6227 +IFX_WARN("%s() %d Warning INTR OUT SPLIT1 NYET\n",__func__,__LINE__);
6228 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
6229 + _urbd->error_count=0;
6230 + _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
6232 + _ifxhc->wait_for_sof = 0;
6233 + _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
6234 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6237 + else if(hcint.b.nak )
6239 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6240 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6241 + _urbd->error_count =0;
6242 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6245 + else if(hcint.b.frmovrun )
6247 + _urbd->error_count =0;
6248 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6249 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6250 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6253 + else if(hcint.b.xacterr )
6255 + hcchar_data_t hcchar;
6256 + hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
6257 + _urbd->error_count=hcchar.b.multicnt;
6258 + if(_urbd->error_count>=3)
6260 + _urbd->error_count=0;
6261 + _ifxhc->wait_for_sof =0;
6262 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
6266 + enable_hc_int(_hc_regs,ack);
6267 + enable_hc_int(_hc_regs,nak);
6268 + enable_hc_int(_hc_regs,nyet);
6269 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6270 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6271 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6275 + else if(hcint.b.datatglerr )
6277 +IFX_WARN("%s() %d Warning INTR IN SPLIT1 DATATGLERR\n",__func__,__LINE__);
6278 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
6279 + _urbd->error_count =0;
6280 + _ifxhc->wait_for_sof =0;
6281 + release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
6284 + else if(hcint.b.bblerr )
6286 +IFX_WARN("%s() %d Warning INTR IN SPLIT1 BABBLEERR\n",__func__,__LINE__);
6287 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
6288 + _urbd->error_count =0;
6289 + _ifxhc->wait_for_sof =0;
6290 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
6293 + else if(hcint.b.stall )
6295 +IFX_WARN("%s() %d Warning INTR IN SPLIT1 STALL\n",__func__,__LINE__);
6296 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
6297 + _urbd->error_count =0;
6298 + _ifxhc->wait_for_sof =0;
6299 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
6302 + else if(hcint.b.xfercomp )
6304 +IFX_WARN("%s() %d Warning INTR IN SPLIT1 COMPLETE\n",__func__,__LINE__);
6305 +showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
6309 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6310 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6311 +static int32_t chhltd_isoc_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
6312 + ifxhcd_hc_t *_ifxhc,
6313 + ifxusb_hc_regs_t *_hc_regs,
6314 + ifxhcd_urbd_t *_urbd)
6316 + #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
6317 + hcint_data_t hcint;
6318 + hcint_data_t hcintmsk;
6319 + hctsiz_data_t hctsiz;
6321 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
6322 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
6323 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
6328 + else if(hcint.b.frmovrun )
6330 + Rewind Buffer Pointers
6331 + Retry Start Split (in next b_interval ¡V 1 uF)
6333 + else if(hcint.b.datatglerr )
6337 + else if(hcint.b.bblerr )
6341 + else if(hcint.b.xacterr )
6345 + else if(hcint.b.stall )
6349 + else if(hcint.b.nak )
6353 + else if(hcint.b.xfercomp )
6357 + else if(hcint.b.nyet)
6364 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6365 +static int32_t chhltd_isoc_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
6366 + ifxhcd_hc_t *_ifxhc,
6367 + ifxusb_hc_regs_t *_hc_regs,
6368 + ifxhcd_urbd_t *_urbd)
6370 + #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
6371 + hcint_data_t hcint;
6372 + hcint_data_t hcintmsk;
6373 + hctsiz_data_t hctsiz;
6374 + int out_nak_enh = 0;
6376 + if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
6379 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
6380 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
6381 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
6384 + Do Next Start Split (in next b_interval ¡V 1 uF)
6386 + else if(hcint.b.frmovrun )
6388 + Do Next Transaction in next frame.
6390 + else if(hcint.b.datatglerr )
6394 + else if(hcint.b.bblerr )
6398 + else if(hcint.b.xacterr )
6402 + else if(hcint.b.stall )
6406 + else if(hcint.b.nak )
6410 + else if(hcint.b.xfercomp )
6414 + else if(hcint.b.nyet)
6421 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6422 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6423 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6424 +static int32_t chhltd_ctrlbulk_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
6425 + ifxhcd_hc_t *_ifxhc,
6426 + ifxusb_hc_regs_t *_hc_regs,
6427 + ifxhcd_urbd_t *_urbd)
6429 + hcint_data_t hcint;
6430 + hcint_data_t hcintmsk;
6431 + hctsiz_data_t hctsiz;
6433 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
6434 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
6435 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
6436 + disable_hc_int(_hc_regs,ack);
6437 + disable_hc_int(_hc_regs,nak);
6438 + disable_hc_int(_hc_regs,nyet);
6440 + _ifxhc->do_ping = 0;
6442 + if (hcint.b.xfercomp)
6444 + _urbd->error_count =0;
6445 + _ifxhc->wait_for_sof = 0;
6447 + complete_channel(_ifxhcd, _ifxhc, _urbd);
6450 + else if (hcint.b.nak)
6452 + _urbd->error_count=0;
6454 + _ifxhc->split = 1;
6455 + _ifxhc->wait_for_sof = 1;
6456 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6457 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6458 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6461 + else if(hcint.b.nyet)
6463 + _urbd->error_count=0;
6464 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
6465 + _ifxhc->wait_for_sof = 1;
6466 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6469 + else if(hcint.b.stall || hcint.b.bblerr )
6471 + _urbd->error_count=0;
6472 + _ifxhc->wait_for_sof = 0;
6473 + if (hcint.b.stall)
6474 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
6475 + else if(hcint.b.bblerr )
6476 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
6479 + else if(hcint.b.xacterr )
6481 + _urbd->error_count++;
6482 + if(_urbd->error_count>=3)
6484 + _urbd->error_count=0;
6485 + _ifxhc->wait_for_sof = 0;
6486 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
6491 + _ifxhc->wait_for_sof = 1;
6492 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6493 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6494 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6498 + else if(hcint.b.datatglerr )
6500 + if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
6501 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
6503 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
6505 + _ifxhc->wait_for_sof = 1;
6506 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6507 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6508 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6511 + else if(hcint.b.frmovrun )
6513 + _urbd->error_count=0;
6514 + _ifxhc->wait_for_sof = 0;
6515 + release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
6520 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6521 +static int32_t chhltd_ctrlbulk_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
6522 + ifxhcd_hc_t *_ifxhc,
6523 + ifxusb_hc_regs_t *_hc_regs,
6524 + ifxhcd_urbd_t *_urbd)
6526 + hcint_data_t hcint;
6527 + hcint_data_t hcintmsk;
6528 + hctsiz_data_t hctsiz;
6529 + int out_nak_enh = 0;
6532 +static int first=0;
6535 + if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
6538 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
6539 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
6540 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
6541 + disable_hc_int(_hc_regs,ack);
6542 + disable_hc_int(_hc_regs,nak);
6543 + disable_hc_int(_hc_regs,nyet);
6546 + if(!first&& _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK
6547 + &&(hcint.b.stall || hcint.b.datatglerr || hcint.b.frmovrun || hcint.b.bblerr || hcint.b.xacterr) && !hcint.b.ack)
6549 + showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
6551 + printk(KERN_INFO " [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X] \n"
6552 + ,*(_ifxhc->xfer_buff+ 0),*(_ifxhc->xfer_buff+ 1),*(_ifxhc->xfer_buff+ 2),*(_ifxhc->xfer_buff+ 3)
6553 + ,*(_ifxhc->xfer_buff+ 4),*(_ifxhc->xfer_buff+ 5),*(_ifxhc->xfer_buff+ 6),*(_ifxhc->xfer_buff+ 7)
6554 + ,*(_ifxhc->xfer_buff+ 8),*(_ifxhc->xfer_buff+ 9),*(_ifxhc->xfer_buff+10),*(_ifxhc->xfer_buff+11)
6555 + ,*(_ifxhc->xfer_buff+12),*(_ifxhc->xfer_buff+13),*(_ifxhc->xfer_buff+14),*(_ifxhc->xfer_buff+15));
6557 + printk(KERN_INFO " [_urbd->urb->actual_length:%08X _ifxhc->start_pkt_count:%08X hctsiz.b.pktcnt:%08X ,_urbd->xfer_len:%08x] \n"
6558 + ,_urbd->urb->actual_length
6559 + ,_ifxhc->start_pkt_count
6561 + ,_urbd->xfer_len);
6565 + if(hcint.b.xfercomp )
6567 + _urbd->error_count=0;
6569 + _ifxhc->do_ping= 0;
6571 + if(_ifxhc->xfer_len==0 && !hcint.b.ack && (hcint.b.nak || hcint.b.nyet))
6573 + // Walkaround: When sending ZLP and receive NYEY or NAK but also issue CMPT intr
6574 + // Solution: NoSplit: Resend at next SOF
6575 + // Split : Resend at next SOF with SSPLIT
6576 + _ifxhc->xfer_len = 0;
6577 + _ifxhc->xfer_count = 0;
6578 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
6579 + _ifxhc->wait_for_sof = 1;
6580 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6585 + _ifxhc->wait_for_sof = 0;
6586 + complete_channel(_ifxhcd, _ifxhc, _urbd);
6590 + else if(hcint.b.nak )
6592 + _urbd->error_count=0;
6594 + _ifxhc->split = 1;
6595 + _ifxhc->wait_for_sof = 1;
6597 + _ifxhc->do_ping =1;
6599 + _ifxhc->do_ping =0;
6600 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6601 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6602 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6605 + else if(hcint.b.nyet)
6607 + //Retry Complete Split
6608 + // Issue Retry instantly on next SOF, without gothrough process_channels
6609 + _urbd->error_count=0;
6610 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
6611 + _ifxhc->wait_for_sof = 1;
6612 + _ifxhc->do_ping = 0;
6613 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6616 + else if(hcint.b.stall )
6618 + _urbd->error_count=0;
6619 + _ifxhc->wait_for_sof = 0;
6620 + _ifxhc->do_ping = 0;
6621 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
6624 + else if(hcint.b.xacterr )
6626 + _urbd->error_count++;
6627 + if(_urbd->error_count>=3)
6629 + _urbd->error_count=0;
6630 + _ifxhc->wait_for_sof = 0;
6631 + _ifxhc->do_ping = 0;
6632 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
6637 + _ifxhc->wait_for_sof = 1;
6639 + _ifxhc->do_ping =1;
6641 + _ifxhc->do_ping =0;
6642 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6643 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6644 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6648 + else if(hcint.b.datatglerr )
6650 + if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
6651 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
6653 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
6655 + _ifxhc->wait_for_sof = 1;
6657 + _ifxhc->do_ping =1;
6659 + _ifxhc->do_ping =0;
6660 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6661 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6662 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6665 + else if(hcint.b.frmovrun )
6667 + _urbd->error_count=0;
6668 + _ifxhc->wait_for_sof = 0;
6669 + _ifxhc->do_ping = 0;
6670 + release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
6673 + else if(hcint.b.bblerr )
6675 + _urbd->error_count=0;
6676 + _ifxhc->wait_for_sof = 0;
6677 + _ifxhc->do_ping = 0;
6678 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
6683 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6684 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6685 +static int32_t chhltd_intr_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
6686 + ifxhcd_hc_t *_ifxhc,
6687 + ifxusb_hc_regs_t *_hc_regs,
6688 + ifxhcd_urbd_t *_urbd)
6690 + hcint_data_t hcint;
6691 + hcint_data_t hcintmsk;
6692 + hctsiz_data_t hctsiz;
6694 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
6695 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
6696 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
6697 + disable_hc_int(_hc_regs,ack);
6698 + disable_hc_int(_hc_regs,nak);
6699 + disable_hc_int(_hc_regs,nyet);
6700 + _ifxhc->do_ping = 0;
6702 + if (hcint.b.xfercomp )
6704 + _urbd->error_count=0;
6705 + _ifxhc->wait_for_sof = 0;
6707 + complete_channel(_ifxhcd, _ifxhc, _urbd);
6710 + else if(hcint.b.nak )
6712 + _urbd->error_count=0;
6713 + _ifxhc->split = 1;
6714 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6715 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6716 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6717 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6718 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6721 + else if(hcint.b.nyet)
6723 + _urbd->error_count=0;
6724 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
6725 + _ifxhc->wait_for_sof = 0;
6727 + /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/
6728 + _ifxhc->nyet_count++;
6729 + if(_ifxhc->nyet_count > 2) {
6730 + _ifxhc->split = 1;
6731 + _ifxhc->nyet_count = 0;
6732 + _ifxhc->wait_for_sof = 5;
6735 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6738 + else if(hcint.b.frmovrun || hcint.b.bblerr || hcint.b.stall )
6740 + _urbd->error_count=0;
6741 + _ifxhc->wait_for_sof = 0;
6742 + if (hcint.b.stall)
6743 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
6744 + else if(hcint.b.bblerr )
6745 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
6746 + else if(hcint.b.frmovrun )
6747 + release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
6750 + else if(hcint.b.xacterr )
6752 + hcchar_data_t hcchar;
6753 + hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
6754 + _urbd->error_count=hcchar.b.multicnt;
6755 + if(_urbd->error_count>=3)
6757 + _urbd->error_count=0;
6758 + _ifxhc->wait_for_sof = 0;
6759 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
6764 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6765 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6766 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6767 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6768 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6772 + else if(hcint.b.datatglerr )
6774 + if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
6775 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
6777 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
6779 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6780 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6781 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6782 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6783 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6788 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6789 +static int32_t chhltd_intr_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
6790 + ifxhcd_hc_t *_ifxhc,
6791 + ifxusb_hc_regs_t *_hc_regs,
6792 + ifxhcd_urbd_t *_urbd)
6794 + hcint_data_t hcint;
6795 + hcint_data_t hcintmsk;
6796 + hctsiz_data_t hctsiz;
6797 + int out_nak_enh = 0;
6799 + if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
6802 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
6803 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
6804 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
6805 + disable_hc_int(_hc_regs,ack);
6806 + disable_hc_int(_hc_regs,nak);
6807 + disable_hc_int(_hc_regs,nyet);
6809 + if(hcint.b.xfercomp )
6811 + _urbd->error_count=0;
6812 + _ifxhc->wait_for_sof = 0;
6814 + _ifxhc->do_ping = 0;
6815 + complete_channel(_ifxhcd, _ifxhc, _urbd);
6818 + else if(hcint.b.nak )
6820 + _urbd->error_count=0;
6821 + _ifxhc->split = 1;
6822 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6823 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6825 + _ifxhc->do_ping =1;
6827 + _ifxhc->do_ping =0;
6828 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6829 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6830 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6833 + else if(hcint.b.nyet)
6835 + _urbd->error_count=0;
6836 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
6837 + _ifxhc->wait_for_sof = 0;
6838 + _ifxhc->do_ping = 0;
6840 + /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/
6841 + _ifxhc->nyet_count++;
6842 + if(_ifxhc->nyet_count > 2) {
6843 + _ifxhc->split = 1;
6844 + _ifxhc->nyet_count = 0;
6845 + _ifxhc->wait_for_sof = 5;
6848 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6851 + else if(hcint.b.stall || hcint.b.frmovrun)
6853 + _urbd->error_count=0;
6854 + _ifxhc->wait_for_sof = 0;
6855 + _ifxhc->do_ping = 0;
6856 + if (hcint.b.stall)
6857 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
6858 + else if(hcint.b.frmovrun )
6859 + release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
6862 + else if(hcint.b.xacterr )
6864 + hcchar_data_t hcchar;
6865 + hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
6866 + _urbd->error_count=hcchar.b.multicnt;
6867 + if(_urbd->error_count>=3)
6869 + _urbd->error_count=0;
6870 + _ifxhc->wait_for_sof = 0;
6871 + _ifxhc->do_ping = 0;
6872 + release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
6877 + _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
6878 + if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
6880 + _ifxhc->do_ping =1;
6882 + _ifxhc->do_ping =0;
6883 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6884 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6885 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6889 + else if(hcint.b.datatglerr )
6891 + if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
6892 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
6894 + _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
6897 + _ifxhc->do_ping =1;
6899 + _ifxhc->do_ping =0;
6900 + _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
6901 + _ifxhc->xfer_count = _urbd->urb->actual_length;
6902 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6905 + else if(hcint.b.bblerr )
6907 + _urbd->error_count=0;
6908 + _ifxhc->wait_for_sof = 0;
6909 + _ifxhc->do_ping = 0;
6910 + release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
6915 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6916 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6917 +static int32_t chhltd_isoc_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
6918 + ifxhcd_hc_t *_ifxhc,
6919 + ifxusb_hc_regs_t *_hc_regs,
6920 + ifxhcd_urbd_t *_urbd)
6922 + #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
6923 + hcint_data_t hcint;
6924 + hcint_data_t hcintmsk;
6925 + hctsiz_data_t hctsiz;
6927 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
6928 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
6929 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
6930 + if(hcint.b.xfercomp )
6932 + disable_hc_int(_hc_regs,ack);
6933 + disable_hc_int(_hc_regs,nak);
6934 + disable_hc_int(_hc_regs,nyet);
6935 + _urbd->error_count=0;
6936 + _ifxhc->wait_for_sof = 0;
6938 + complete_channel(_ifxhcd, _ifxhc, _urbd);
6941 + else if(hcint.b.nak )
6943 + Retry Start Split (in next b_interval ¡V 1 uF)
6945 + else if(hcint.b.nyet)
6947 + //Do Next Complete Split
6948 + // Issue Retry instantly on next SOF, without gothrough process_channels
6949 + _urbd->error_count=0;
6950 + //disable_hc_int(_hc_regs,ack);
6951 + //disable_hc_int(_hc_regs,nak);
6952 + //disable_hc_int(_hc_regs,datatglerr);
6953 + _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
6954 + _ifxhc->wait_for_sof = 1;
6955 + ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
6958 + else if(hcint.b.frmovrun || hcint.b.stall || hcint.b.bblerr)
6960 + _urbd->error_count=0;
6961 + disable_hc_int(_hc_regs,ack);
6962 + disable_hc_int(_hc_regs,nyet);
6963 + disable_hc_int(_hc_regs,nak);
6964 + _ifxhc->wait_for_sof = 0;
6966 + //if(hctsiz.b.pktcnt==0)
6968 + // complete_channel(_ifxhcd, _ifxhc, _urbd);
6972 + // _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
6973 + if (hcint.b.stall)
6974 + release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
6975 + else if(hcint.b.frmovrun )
6976 + else if(hcint.b.bblerr )
6979 + else if(hcint.b.xacterr )
6981 + Rewind Buffer Pointers
6982 + if (HCCHARn.EC = = 3) // ERR response received
6985 + Do Next Start Split (in next frame)
6989 + De-allocate Channel
6992 + else if(hcint.b.datatglerr )
6996 + else if(hcint.b.ack )
7003 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7004 +static int32_t chhltd_isoc_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
7005 + ifxhcd_hc_t *_ifxhc,
7006 + ifxusb_hc_regs_t *_hc_regs,
7007 + ifxhcd_urbd_t *_urbd)
7009 + #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
7010 + hcint_data_t hcint;
7011 + hcint_data_t hcintmsk;
7012 + hctsiz_data_t hctsiz;
7013 + int out_nak_enh = 0;
7015 + if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
7018 + hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
7019 + hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
7020 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
7025 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7026 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7027 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7029 +static int32_t handle_hc_chhltd_intr(ifxhcd_hcd_t *_ifxhcd,
7030 + ifxhcd_hc_t *_ifxhc,
7031 + ifxusb_hc_regs_t *_hc_regs,
7032 + ifxhcd_urbd_t *_urbd)
7034 + IFX_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: Channel Halted--\n", _ifxhc->hc_num);
7036 + _ifxhc->halting = 0;
7037 + _ifxhc->xfer_started = 0;
7039 + if (_ifxhc->halt_status == HC_XFER_URB_DEQUEUE ||
7040 + _ifxhc->halt_status == HC_XFER_AHB_ERR) {
7042 + * Just release the channel. A dequeue can happen on a
7043 + * transfer timeout. In the case of an AHB Error, the channel
7044 + * was forced to halt because there's no way to gracefully
7047 + release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
7051 + if (_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL || _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
7053 + if (_ifxhc->split==0)
7056 + return (chhltd_ctrlbulk_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7058 + return (chhltd_ctrlbulk_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7060 + else if(_ifxhc->split==1)
7063 + return (chhltd_ctrlbulk_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7065 + return (chhltd_ctrlbulk_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7067 + else if(_ifxhc->split==2)
7070 + return (chhltd_ctrlbulk_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7072 + return (chhltd_ctrlbulk_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7075 + else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR)
7077 + if (_ifxhc->split==0)
7080 + return (chhltd_intr_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7082 + return (chhltd_intr_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7084 + else if(_ifxhc->split==1)
7087 + return (chhltd_intr_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7089 + return (chhltd_intr_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7091 + else if(_ifxhc->split==2)
7094 + return (chhltd_intr_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7096 + return (chhltd_intr_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7099 + else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
7101 + if (_ifxhc->split==0)
7104 + return (chhltd_isoc_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7106 + return (chhltd_isoc_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7108 + else if(_ifxhc->split==1)
7111 + return (chhltd_isoc_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7113 + return (chhltd_isoc_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7115 + else if(_ifxhc->split==2)
7118 + return (chhltd_isoc_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7120 + return (chhltd_isoc_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
7127 + * Handles a host channel AHB error interrupt. This handler is only called in
7130 +static void hc_other_intr_dump(ifxhcd_hcd_t *_ifxhcd,
7131 + ifxhcd_hc_t *_ifxhc,
7132 + ifxusb_hc_regs_t *_hc_regs,
7133 + ifxhcd_urbd_t *_urbd)
7136 + hcchar_data_t hcchar;
7137 + hcsplt_data_t hcsplt;
7138 + hctsiz_data_t hctsiz;
7140 + struct urb *urb = _urbd->urb;
7141 + hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
7142 + hcsplt.d32 = ifxusb_rreg(&_hc_regs->hcsplt);
7143 + hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
7144 + hcdma = ifxusb_rreg(&_hc_regs->hcdma);
7146 + IFX_ERROR("Channel %d\n", _ifxhc->hc_num);
7147 + IFX_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
7148 + IFX_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
7149 + IFX_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe));
7150 + IFX_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
7151 + (usb_pipein(urb->pipe) ? "IN" : "OUT"));
7152 + IFX_ERROR(" Endpoint type: %s\n",
7154 + switch (usb_pipetype(urb->pipe)) {
7155 + case PIPE_CONTROL: pipetype = "CTRL"; break;
7156 + case PIPE_BULK: pipetype = "BULK"; break;
7157 + case PIPE_INTERRUPT: pipetype = "INTR"; break;
7158 + case PIPE_ISOCHRONOUS: pipetype = "ISOC"; break;
7159 + default: pipetype = "????"; break;
7161 + IFX_ERROR(" Speed: %s\n",
7163 + switch (urb->dev->speed) {
7164 + case USB_SPEED_HIGH: speed = "HS"; break;
7165 + case USB_SPEED_FULL: speed = "FS"; break;
7166 + case USB_SPEED_LOW: speed = "LS"; break;
7167 + default: speed = "????"; break;
7169 + IFX_ERROR(" Max packet size: %d\n",
7170 + usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
7171 + IFX_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length);
7172 + IFX_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n",
7173 + urb->transfer_buffer, (void *)urb->transfer_dma);
7174 + IFX_ERROR(" Setup buffer: %p, Setup DMA: %p\n",
7175 + urb->setup_packet, (void *)urb->setup_dma);
7176 + IFX_ERROR(" Interval: %d\n", urb->interval);
7177 + #endif //__DEBUG__
7181 + * Handles a host channel ACK interrupt. This interrupt is enabled when
7182 + * errors occur, and during Start Split transactions.
7184 +static int32_t handle_hc_ack_intr(ifxhcd_hcd_t *_ifxhcd,
7185 + ifxhcd_hc_t *_ifxhc,
7186 + ifxusb_hc_regs_t *_hc_regs,
7187 + ifxhcd_urbd_t *_urbd)
7189 + _urbd->error_count=0;
7190 + if(_ifxhc->nak_countdown_r)
7192 + _ifxhc->nak_retry=_ifxhc->nak_retry_r;
7193 + _ifxhc->nak_countdown=_ifxhc->nak_countdown_r;
7196 + disable_hc_int(_hc_regs,nak);
7197 + disable_hc_int(_hc_regs,ack);
7202 + * Handles a host channel ACK interrupt. This interrupt is enabled when
7203 + * errors occur, and during Start Split transactions.
7205 +static int32_t handle_hc_nak_intr(ifxhcd_hcd_t *_ifxhcd,
7206 + ifxhcd_hc_t *_ifxhc,
7207 + ifxusb_hc_regs_t *_hc_regs,
7208 + ifxhcd_urbd_t *_urbd)
7211 + _urbd->error_count=0;
7213 + if(_ifxhc->nak_countdown_r)
7215 + _ifxhc->nak_countdown--;
7216 + if(!_ifxhc->nak_countdown)
7218 + _ifxhc->nak_countdown=_ifxhc->nak_countdown_r;
7219 + disable_hc_int(_hc_regs,ack);
7220 + disable_hc_int(_hc_regs,nak);
7221 + ifxhcd_hc_halt(&_ifxhcd->core_if, _ifxhc, HC_XFER_NAK);
7224 + enable_hc_int(_hc_regs,ack);
7228 + disable_hc_int(_hc_regs,ack);
7229 + disable_hc_int(_hc_regs,nak);
7235 + * Handles a host channel AHB error interrupt. This handler is only called in
7238 +static int32_t handle_hc_ahberr_intr(ifxhcd_hcd_t *_ifxhcd,
7239 + ifxhcd_hc_t *_ifxhc,
7240 + ifxusb_hc_regs_t *_hc_regs,
7241 + ifxhcd_urbd_t *_urbd)
7243 + IFX_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
7244 + "AHB Error--\n", _ifxhc->hc_num);
7245 + hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
7247 + ifxhcd_hc_halt(&_ifxhcd->core_if, _ifxhc, HC_XFER_AHB_ERR);
7254 +static int32_t handle_hc_datatglerr_intr(ifxhcd_hcd_t *_ifxhcd,
7255 + ifxhcd_hc_t *_ifxhc,
7256 + ifxusb_hc_regs_t *_hc_regs,
7257 + ifxhcd_urbd_t *_urbd)
7259 + IFX_ERROR( "--Host Channel %d Interrupt: "
7260 + "DATATOGGLE Error--\n", _ifxhc->hc_num);
7261 + hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
7262 + disable_hc_int(_hc_regs,datatglerr);
7269 + * Interrupts which should not been triggered
7271 +static int32_t handle_hc_frmovrun_intr(ifxhcd_hcd_t *_ifxhcd,
7272 + ifxhcd_hc_t *_ifxhc,
7273 + ifxusb_hc_regs_t *_hc_regs,
7274 + ifxhcd_urbd_t *_urbd)
7276 + IFX_ERROR( "--Host Channel %d Interrupt: "
7277 + "FrameOverRun Error--\n", _ifxhc->hc_num);
7278 + hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
7279 + disable_hc_int(_hc_regs,frmovrun);
7283 +static int32_t handle_hc_bblerr_intr(ifxhcd_hcd_t *_ifxhcd,
7284 + ifxhcd_hc_t *_ifxhc,
7285 + ifxusb_hc_regs_t *_hc_regs,
7286 + ifxhcd_urbd_t *_urbd)
7288 + IFX_ERROR( "--Host Channel %d Interrupt: "
7289 + "BBL Error--\n", _ifxhc->hc_num);
7290 + hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
7291 + disable_hc_int(_hc_regs,bblerr);
7295 +static int32_t handle_hc_xacterr_intr(ifxhcd_hcd_t *_ifxhcd,
7296 + ifxhcd_hc_t *_ifxhc,
7297 + ifxusb_hc_regs_t *_hc_regs,
7298 + ifxhcd_urbd_t *_urbd)
7300 + IFX_ERROR( "--Host Channel %d Interrupt: "
7301 + "XACT Error--\n", _ifxhc->hc_num);
7302 + hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
7303 + disable_hc_int(_hc_regs,xacterr);
7307 +static int32_t handle_hc_nyet_intr(ifxhcd_hcd_t *_ifxhcd,
7308 + ifxhcd_hc_t *_ifxhc,
7309 + ifxusb_hc_regs_t *_hc_regs,
7310 + ifxhcd_urbd_t *_urbd)
7312 + IFX_ERROR( "--Host Channel %d Interrupt: "
7313 + "NYET--\n", _ifxhc->hc_num);
7314 + hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
7315 + _urbd->error_count=0;
7316 + disable_hc_int(_hc_regs,nyet);
7320 +static int32_t handle_hc_stall_intr(ifxhcd_hcd_t *_ifxhcd,
7321 + ifxhcd_hc_t *_ifxhc,
7322 + ifxusb_hc_regs_t *_hc_regs,
7323 + ifxhcd_urbd_t *_urbd)
7325 + IFX_ERROR( "--Host Channel %d Interrupt: "
7326 + "STALL--\n", _ifxhc->hc_num);
7327 + hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
7328 + disable_hc_int(_hc_regs,stall);
7332 +static int32_t handle_hc_xfercomp_intr(ifxhcd_hcd_t *_ifxhcd,
7333 + ifxhcd_hc_t *_ifxhc,
7334 + ifxusb_hc_regs_t *_hc_regs,
7335 + ifxhcd_urbd_t *_urbd)
7337 + IFX_ERROR( "--Host Channel %d Interrupt: "
7338 + "XFERCOMP--\n", _ifxhc->hc_num);
7339 + hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
7340 + disable_hc_int(_hc_regs,xfercomp);
7346 +/* This interrupt indicates that the specified host channels has a pending
7347 + * interrupt. There are multiple conditions that can cause each host channel
7348 + * interrupt. This function determines which conditions have occurred for this
7349 + * host channel interrupt and handles them appropriately. */
7350 +static int32_t handle_hc_n_intr (ifxhcd_hcd_t *_ifxhcd, uint32_t _num)
7352 + uint32_t hcintval,hcintmsk;
7353 + hcint_data_t hcint;
7354 + ifxhcd_hc_t *ifxhc;
7355 + ifxusb_hc_regs_t *hc_regs;
7356 + ifxhcd_urbd_t *urbd;
7357 + unsigned long flags;
7361 + IFX_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", _num);
7363 + /*== AVM/BC 20101111 Lock needed ==*/
7364 + SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
7366 + ifxhc = &_ifxhcd->ifxhc[_num];
7367 + hc_regs = _ifxhcd->core_if.hc_regs[_num];
7369 + hcintval = ifxusb_rreg(&hc_regs->hcint);
7370 + hcintmsk = ifxusb_rreg(&hc_regs->hcintmsk);
7371 + hcint.d32 = hcintval & hcintmsk;
7372 + IFX_DEBUGPL(DBG_HCDV, " 0x%08x & 0x%08x = 0x%08x\n",
7373 + hcintval, hcintmsk, hcint.d32);
7375 + urbd = list_entry(ifxhc->epqh->urbd_list.next, ifxhcd_urbd_t, urbd_list_entry);
7377 + if (hcint.b.datatglerr)
7378 + retval |= handle_hc_datatglerr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7379 + if (hcint.b.frmovrun)
7380 + retval |= handle_hc_frmovrun_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7381 + if (hcint.b.bblerr)
7382 + retval |= handle_hc_bblerr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7383 + if (hcint.b.xacterr)
7384 + retval |= handle_hc_xacterr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7386 + retval |= handle_hc_nyet_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7388 + retval |= handle_hc_ack_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7390 + retval |= handle_hc_nak_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7391 + if (hcint.b.stall)
7392 + retval |= handle_hc_stall_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7393 + if (hcint.b.ahberr) {
7394 + clear_hc_int(hc_regs, ahberr);
7395 + retval |= handle_hc_ahberr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7397 + if (hcint.b.chhltd) {
7398 + /* == 20110901 AVM/WK Fix: Flag must not be cleared after restart of channel ==*/
7399 + clear_hc_int(hc_regs, chhltd);
7400 + retval |= handle_hc_chhltd_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7402 + if (hcint.b.xfercomp)
7403 + retval |= handle_hc_xfercomp_intr(_ifxhcd, ifxhc, hc_regs, urbd);
7405 + /* == 20110901 AVM/WK Fix: Never clear possibly new intvals ==*/
7406 + //ifxusb_wreg(&hc_regs->hcint,hcintval);
7408 + SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
7418 +static uint8_t update_interval_counter(ifxhcd_epqh_t *_epqh,uint32_t _diff)
7420 + if(_diff>=_epqh->period_counter)
7422 + _epqh->period_do=1;
7423 + if(_diff>_epqh->interval)
7424 + _epqh->period_counter=1;
7426 + _epqh->period_counter=_epqh->period_counter+_epqh->interval-_diff;
7429 + _epqh->period_counter=_epqh->period_counter-_diff;
7437 + * Handles the start-of-frame interrupt in host mode. Non-periodic
7438 + * transactions may be queued to the DWC_otg controller for the current
7439 + * (micro)frame. Periodic transactions may be queued to the controller for the
7440 + * next (micro)frame.
7442 +static int32_t handle_sof_intr (ifxhcd_hcd_t *_ifxhcd)
7444 + #ifdef __DYN_SOF_INTR__
7445 + uint8_t with_count_down=0;
7447 + uint8_t active_on=0;
7448 + uint8_t ready_on=0;
7449 + struct list_head *epqh_entry;
7450 + ifxhcd_epqh_t *epqh;
7451 + hfnum_data_t hfnum;
7454 + unsigned long flags;
7455 +#ifdef __USE_TIMER_4_SOF__
7456 + uint32_t wait_for_sof = 0x10000;
7459 + SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
7463 + ifxusb_hc_regs_t *hc_regs;
7465 + num_channels = _ifxhcd->core_if.params.host_channels;
7467 +// AVM/WK moved block here due to use of SOF timer
7468 + hfnum.d32 = ifxusb_rreg(&_ifxhcd->core_if.host_global_regs->hfnum);
7469 + fndiff = hfnum.b.frnum;
7470 + fndiff+= 0x00004000;
7471 + fndiff-= _ifxhcd->lastframe ;
7472 + fndiff&= 0x00003FFF;
7473 + if(!fndiff) fndiff =1;
7475 + for (i = 0; i < num_channels; i++)
7477 + if(_ifxhcd->ifxhc[i].wait_for_sof && _ifxhcd->ifxhc[i].xfer_started)
7479 +#ifdef __USE_TIMER_4_SOF__
7480 + if (_ifxhcd->ifxhc[i].wait_for_sof > fndiff) {
7481 + _ifxhcd->ifxhc[i].wait_for_sof -= fndiff;
7483 + _ifxhcd->ifxhc[i].wait_for_sof = 0;
7486 + _ifxhcd->ifxhc[i].wait_for_sof--;
7488 + if(_ifxhcd->ifxhc[i].wait_for_sof==0)
7490 + hcint_data_t hcint= { .d32=0 };
7491 + hc_regs = _ifxhcd->core_if.hc_regs[i];
7493 + hcint.d32 =0xFFFFFFFF;
7494 + ifxusb_wreg(&hc_regs->hcint, hcint.d32);
7496 + hcint.d32=ifxusb_rreg(&hc_regs->hcintmsk);
7499 + /* == 20110901 AVM/WK Fix: We don't need NOT YET IRQ ==*/
7501 + _ifxhcd->ifxhc[i].nak_countdown=_ifxhcd->ifxhc[i].nak_countdown_r;
7502 + if(_ifxhcd->ifxhc[i].nak_countdown_r)
7504 + ifxusb_wreg(&hc_regs->hcintmsk, hcint.d32);
7506 + /* AVM WK / BC 20100827
7507 + * FIX: Packet was ignored because of wrong Oddframe bit
7509 + if (_ifxhcd->ifxhc[i].ep_type == IFXUSB_EP_TYPE_INTR || _ifxhcd->ifxhc[i].ep_type == IFXUSB_EP_TYPE_ISOC)
7511 + hcchar_data_t hcchar;
7512 + hcchar.d32 = _ifxhcd->ifxhc[i].hcchar;
7513 + hfnum.d32 = ifxusb_rreg(&_ifxhcd->core_if.host_global_regs->hfnum);
7514 + /* 1 if _next_ frame is odd, 0 if it's even */
7515 + hcchar.b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
7516 + _ifxhcd->ifxhc[i].hcchar = hcchar.d32;
7519 + ifxusb_wreg(&hc_regs->hcchar, _ifxhcd->ifxhc[i].hcchar);
7524 + _ifxhcd->ifxhc[i].wait_for_sof=0;
7526 +#ifdef __USE_TIMER_4_SOF__
7527 + if (_ifxhcd->ifxhc[i].wait_for_sof && (wait_for_sof > _ifxhcd->ifxhc[i].wait_for_sof)) {
7528 + wait_for_sof = _ifxhcd->ifxhc[i].wait_for_sof;
7535 + #ifdef __EN_ISOC__
7536 + #error ISOC not supported: missing SOF code
7537 + epqh_entry = _ifxhcd->epqh_isoc_active.next;
7538 + while (epqh_entry != &_ifxhcd->epqh_isoc_active)
7540 + epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry);
7541 + epqh_entry = epqh_entry->next;
7542 + #ifdef __DYN_SOF_INTR__
7543 + with_count_down=1;
7545 + active_on+=update_interval_counter(epqh,fndiff);
7549 + epqh_entry = _ifxhcd->epqh_isoc_ready.next;
7550 + while (epqh_entry != &_ifxhcd->epqh_isoc_ready)
7552 + epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry);
7553 + epqh_entry = epqh_entry->next;
7554 + #ifdef __DYN_SOF_INTR__
7555 + with_count_down=1;
7557 + ready_on+=update_interval_counter(epqh,fndiff);
7562 + epqh_entry = _ifxhcd->epqh_intr_active.next;
7563 + while (epqh_entry != &_ifxhcd->epqh_intr_active)
7565 + epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry);
7566 + epqh_entry = epqh_entry->next;
7567 + #ifdef __DYN_SOF_INTR__
7568 + with_count_down=1;
7570 +#ifdef __USE_TIMER_4_SOF__
7571 + if (update_interval_counter(epqh,fndiff)) {
7575 + if (epqh->period_counter && (wait_for_sof > epqh->period_counter)) {
7576 + wait_for_sof = epqh->period_counter;
7580 + active_on+=update_interval_counter(epqh,fndiff);
7585 + epqh_entry = _ifxhcd->epqh_intr_ready.next;
7586 + while (epqh_entry != &_ifxhcd->epqh_intr_ready)
7588 + epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry);
7589 + epqh_entry = epqh_entry->next;
7590 + #ifdef __DYN_SOF_INTR__
7591 + with_count_down=1;
7593 +#ifdef __USE_TIMER_4_SOF__
7594 + if (update_interval_counter(epqh,fndiff)) {
7598 + if (epqh->period_counter && (wait_for_sof > epqh->period_counter)) {
7599 + wait_for_sof = epqh->period_counter;
7603 + ready_on+=update_interval_counter(epqh,fndiff);
7608 + epqh_entry = _ifxhcd->epqh_stdby.next;
7609 + while (epqh_entry != &_ifxhcd->epqh_stdby)
7611 + epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry);
7612 + epqh_entry = epqh_entry->next;
7613 + if(epqh->period_counter > 0 ) {
7614 +#ifdef __USE_TIMER_4_SOF__
7615 + if (epqh->period_counter > fndiff) {
7616 + epqh->period_counter -= fndiff;
7618 + epqh->period_counter = 0;
7621 + epqh->period_counter --;
7623 + #ifdef __DYN_SOF_INTR__
7624 + with_count_down=1;
7627 + if(epqh->period_counter == 0) {
7628 + ifxhcd_epqh_idle_periodic(epqh);
7630 +#ifdef __USE_TIMER_4_SOF__
7632 + if (wait_for_sof > epqh->period_counter) {
7633 + wait_for_sof = epqh->period_counter;
7638 + SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
7641 + select_eps(_ifxhcd);
7642 + else if(active_on)
7643 + process_channels(_ifxhcd);
7645 + /* Clear interrupt */
7647 + gint_data_t gintsts;
7649 + gintsts.b.sofintr = 1;
7650 + ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
7652 + #ifdef __DYN_SOF_INTR__
7653 + if(!with_count_down)
7654 + ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, gintsts.d32,0);
7656 +#ifdef __USE_TIMER_4_SOF__
7657 + wait_for_sof &= 0xFFFF; // reduce to 16 Bits.
7659 + if(wait_for_sof == 1) {
7661 + gint_data_t gintsts;
7663 + gintsts.b.sofintr = 1;
7664 + ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, 0,gintsts.d32);
7667 + ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, gintsts.d32,0);
7668 + if (wait_for_sof > 1) {
7669 + // use timer, not SOF IRQ
7670 + hprt0_data_t hprt0;
7672 + hprt0.d32 = ifxusb_read_hprt0 (&_ifxhcd->core_if);
7673 + if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED) {
7674 + ktime = ktime_set(0, wait_for_sof * 125 * 1000); /*--- wakeup in n*125usec ---*/
7676 + ktime = ktime_set(0, wait_for_sof * (1000*1000)); /*--- wakeup in n*1000usec ---*/
7678 + hrtimer_start(&_ifxhcd->hr_timer, ktime, HRTIMER_MODE_REL);
7683 + _ifxhcd->lastframe=hfnum.b.frnum;
7689 +/* There are multiple conditions that can cause a port interrupt. This function
7690 + * determines which interrupt conditions have occurred and handles them
7691 + * appropriately. */
7692 +static int32_t handle_port_intr (ifxhcd_hcd_t *_ifxhcd)
7695 + hprt0_data_t hprt0;
7696 + hprt0_data_t hprt0_modify;
7699 + hprt0_modify.d32 = ifxusb_rreg(_ifxhcd->core_if.hprt0);
7701 + /* Clear appropriate bits in HPRT0 to clear the interrupt bit in
7704 + hprt0_modify.b.prtena = 0;
7705 + hprt0_modify.b.prtconndet = 0;
7706 + hprt0_modify.b.prtenchng = 0;
7707 + hprt0_modify.b.prtovrcurrchng = 0;
7709 + /* Port Connect Detected
7710 + * Set flag and clear if detected */
7711 + if (hprt0.b.prtconndet) {
7712 + IFX_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x "
7713 + "Port Connect Detected--\n", hprt0.d32);
7714 + _ifxhcd->flags.b.port_connect_status_change = 1;
7715 + _ifxhcd->flags.b.port_connect_status = 1;
7716 + hprt0_modify.b.prtconndet = 1;
7718 + /* The Hub driver asserts a reset when it sees port connect
7719 + * status change flag */
7723 + /* Port Enable Changed
7724 + * Clear if detected - Set internal flag if disabled */
7725 + if (hprt0.b.prtenchng) {
7727 + IFX_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
7728 + "Port Enable Changed--\n", hprt0.d32);
7729 + hprt0_modify.b.prtenchng = 1;
7730 + if (hprt0.b.prtena == 1)
7731 + /* Port has been enabled set the reset change flag */
7732 + _ifxhcd->flags.b.port_reset_change = 1;
7734 + _ifxhcd->flags.b.port_enable_change = 1;
7738 + /* Overcurrent Change Interrupt */
7740 + if (hprt0.b.prtovrcurrchng) {
7741 + IFX_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
7742 + "Port Overcurrent Changed--\n", hprt0.d32);
7743 + _ifxhcd->flags.b.port_over_current_change = 1;
7744 + hprt0_modify.b.prtovrcurrchng = 1;
7748 + /* Clear Port Interrupts */
7749 + ifxusb_wreg(_ifxhcd->core_if.hprt0, hprt0_modify.d32);
7754 + * This interrupt indicates that SUSPEND state has been detected on
7756 + * No Functioning in Host Mode
7758 +static int32_t handle_usb_suspend_intr(ifxhcd_hcd_t *_ifxhcd)
7760 + gint_data_t gintsts;
7761 + IFX_DEBUGP("USB SUSPEND RECEIVED!\n");
7762 + /* Clear interrupt */
7764 + gintsts.b.usbsuspend = 1;
7765 + ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
7770 + * This interrupt indicates that the IFXUSB controller has detected a
7771 + * resume or remote wakeup sequence. If the IFXUSB controller is in
7772 + * low power mode, the handler must brings the controller out of low
7773 + * power mode. The controller automatically begins resume
7774 + * signaling. The handler schedules a time to stop resume signaling.
7776 +static int32_t handle_wakeup_detected_intr(ifxhcd_hcd_t *_ifxhcd)
7778 + gint_data_t gintsts;
7779 + hprt0_data_t hprt0 = {.d32=0};
7780 + pcgcctl_data_t pcgcctl = {.d32=0};
7781 + ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
7783 + IFX_DEBUGPL(DBG_ANY, "++Resume and Remote Wakeup Detected Interrupt++\n");
7786 + * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
7787 + * so that OPT tests pass with all PHYs).
7789 + /* Restart the Phy Clock */
7790 + pcgcctl.b.stoppclk = 1;
7791 + ifxusb_mreg(core_if->pcgcctl, pcgcctl.d32, 0);
7794 + /* Now wait for 70 ms. */
7795 + hprt0.d32 = ifxusb_read_hprt0( core_if );
7796 + IFX_DEBUGPL(DBG_ANY,"Resume: HPRT0=%0x\n", hprt0.d32);
7798 + hprt0.b.prtres = 0; /* Resume */
7799 + ifxusb_wreg(core_if->hprt0, hprt0.d32);
7800 + IFX_DEBUGPL(DBG_ANY,"Clear Resume: HPRT0=%0x\n", ifxusb_rreg(core_if->hprt0));
7802 + /* Clear interrupt */
7804 + gintsts.b.wkupintr = 1;
7805 + ifxusb_wreg(&core_if->core_global_regs->gintsts, gintsts.d32);
7810 + * This interrupt indicates that a device is initiating the Session
7811 + * Request Protocol to request the host to turn on bus power so a new
7812 + * session can begin. The handler responds by turning on bus power. If
7813 + * the DWC_otg controller is in low power mode, the handler brings the
7814 + * controller out of low power mode before turning on bus power.
7816 +static int32_t handle_session_req_intr(ifxhcd_hcd_t *_ifxhcd)
7818 + /* Clear interrupt */
7819 + gint_data_t gintsts = { .d32 = 0 };
7820 + gintsts.b.sessreqintr = 1;
7821 + ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
7826 + * This interrupt indicates that a device has been disconnected from
7829 +static int32_t handle_disconnect_intr(ifxhcd_hcd_t *_ifxhcd)
7831 + gint_data_t gintsts;
7833 + ifxhcd_disconnect(_ifxhcd);
7836 + gintsts.b.disconnect = 1;
7837 + ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
7842 + * This function handles the Connector ID Status Change Interrupt. It
7843 + * reads the OTG Interrupt Register (GOTCTL) to determine whether this
7844 + * is a Device to Host Mode transition or a Host Mode to Device
7846 + * This only occurs when the cable is connected/removed from the PHY
7849 +static int32_t handle_conn_id_status_change_intr(ifxhcd_hcd_t *_ifxhcd)
7851 + gint_data_t gintsts;
7853 + IFX_WARN("ID Status Change Interrupt: currently in %s mode\n",
7854 + ifxusb_mode(&_ifxhcd->core_if) ? "Host" : "Device");
7857 + gintsts.b.conidstschng = 1;
7858 + ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
7862 +static int32_t handle_otg_intr(ifxhcd_hcd_t *_ifxhcd)
7864 + ifxusb_core_global_regs_t *global_regs = _ifxhcd->core_if.core_global_regs;
7865 + gotgint_data_t gotgint;
7866 + gotgint.d32 = ifxusb_rreg( &global_regs->gotgint);
7867 + /* Clear GOTGINT */
7868 + ifxusb_wreg (&global_regs->gotgint, gotgint.d32);
7872 +/** This function will log a debug message */
7873 +static int32_t handle_mode_mismatch_intr(ifxhcd_hcd_t *_ifxhcd)
7875 + gint_data_t gintsts;
7877 + IFX_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
7878 + ifxusb_mode(&_ifxhcd->core_if) ? "Host" : "Device");
7880 + gintsts.b.modemismatch = 1;
7881 + ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
7885 +/** This function handles interrupts for the HCD. */
7886 +int32_t ifxhcd_handle_intr (ifxhcd_hcd_t *_ifxhcd)
7890 + ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
7891 + /* AVM/BC 20101111 Unnecesary variable removed*/
7892 + //gint_data_t gintsts,gintsts2;
7893 + gint_data_t gintsts;
7895 + /* Check if HOST Mode */
7896 + if (ifxusb_is_device_mode(core_if))
7898 + IFX_ERROR("%s() CRITICAL! IN DEVICE MODE\n", __func__);
7902 + gintsts.d32 = ifxusb_read_core_intr(core_if);
7908 + if (gintsts.b.modemismatch)
7910 + retval |= handle_mode_mismatch_intr(_ifxhcd);
7911 + gintsts.b.modemismatch=0;
7913 + if (gintsts.b.otgintr)
7915 + retval |= handle_otg_intr(_ifxhcd);
7916 + gintsts.b.otgintr=0;
7918 + if (gintsts.b.conidstschng)
7920 + retval |= handle_conn_id_status_change_intr(_ifxhcd);
7921 + gintsts.b.conidstschng=0;
7923 + if (gintsts.b.disconnect)
7925 + retval |= handle_disconnect_intr(_ifxhcd);
7926 + gintsts.b.disconnect=0;
7928 + if (gintsts.b.sessreqintr)
7930 + retval |= handle_session_req_intr(_ifxhcd);
7931 + gintsts.b.sessreqintr=0;
7933 + if (gintsts.b.wkupintr)
7935 + retval |= handle_wakeup_detected_intr(_ifxhcd);
7936 + gintsts.b.wkupintr=0;
7938 + if (gintsts.b.usbsuspend)
7940 + retval |= handle_usb_suspend_intr(_ifxhcd);
7941 + gintsts.b.usbsuspend=0;
7945 + if (gintsts.b.sofintr)
7947 + retval |= handle_sof_intr (_ifxhcd);
7948 + gintsts.b.sofintr=0;
7950 + if (gintsts.b.portintr)
7952 + retval |= handle_port_intr (_ifxhcd);
7953 + gintsts.b.portintr=0;
7955 + if (gintsts.b.hcintr)
7958 + haint_data_t haint;
7959 + haint.d32 = ifxusb_read_host_all_channels_intr(core_if);
7960 + for (i=0; i< core_if->params.host_channels; i++)
7961 + if (haint.b2.chint & (1 << i))
7962 + retval |= handle_hc_n_intr (_ifxhcd, i);
7963 + gintsts.b.hcintr=0;
7967 diff --git a/drivers/usb/ifxhcd/ifxhcd_queue.c b/drivers/usb/ifxhcd/ifxhcd_queue.c
7968 new file mode 100644
7969 index 0000000..8f9dd25
7971 +++ b/drivers/usb/ifxhcd/ifxhcd_queue.c
7973 +/*****************************************************************************
7974 + ** FILE NAME : ifxhcd_queue.c
7975 + ** PROJECT : IFX USB sub-system V3
7976 + ** MODULES : IFX USB sub-system Host and Device driver
7977 + ** SRC VERSION : 1.0
7978 + ** DATE : 1/Jan/2009
7979 + ** AUTHOR : Chen, Howard
7980 + ** DESCRIPTION : This file contains the functions to manage Queue Heads and Queue
7981 + ** Transfer Descriptors.
7982 + *****************************************************************************/
7985 + \file ifxhcd_queue.c
7986 + \ingroup IFXUSB_DRIVER_V3
7987 + \brief This file contains the functions to manage Queue Heads and Queue
7988 + Transfer Descriptors.
7990 +#include <linux/version.h>
7991 +#include "ifxusb_version.h"
7993 +#include <linux/kernel.h>
7994 +#include <linux/module.h>
7995 +#include <linux/moduleparam.h>
7996 +#include <linux/init.h>
7997 +#include <linux/device.h>
7998 +#include <linux/errno.h>
7999 +#include <linux/list.h>
8000 +#include <linux/interrupt.h>
8001 +#include <linux/string.h>
8003 +#include "ifxusb_plat.h"
8004 +#include "ifxusb_regs.h"
8005 +#include "ifxusb_cif.h"
8006 +#include "ifxhcd.h"
8008 +#ifdef __EPQD_DESTROY_TIMEOUT__
8009 + #define epqh_self_destroy_timeout 5
8010 + static void eqph_destroy_func(unsigned long _ptr)
8012 + ifxhcd_epqh_t *epqh=(ifxhcd_epqh_t *)_ptr;
8015 + ifxhcd_epqh_free (epqh);
8020 +#define SCHEDULE_SLOP 10
8023 + \brief This function allocates and initializes a EPQH.
8025 + \param _ifxhcd The HCD state structure for the USB Host controller.
8026 + \param[in] _urb Holds the information about the device/endpoint that we need
8027 + to initialize the EPQH.
8029 + \return Returns pointer to the newly allocated EPQH, or NULL on error.
8031 +ifxhcd_epqh_t *ifxhcd_epqh_create (ifxhcd_hcd_t *_ifxhcd, struct urb *_urb)
8033 + ifxhcd_epqh_t *epqh;
8035 + hprt0_data_t hprt0;
8036 + struct usb_host_endpoint *sysep = ifxhcd_urb_to_endpoint(_urb);
8038 + /* Allocate memory */
8039 +// epqh=(ifxhcd_epqh_t *) kmalloc (sizeof(ifxhcd_epqh_t), GFP_KERNEL);
8040 + epqh=(ifxhcd_epqh_t *) kmalloc (sizeof(ifxhcd_epqh_t), GFP_ATOMIC);
8045 + memset (epqh, 0, sizeof (ifxhcd_epqh_t));
8047 + epqh->sysep=sysep;
8049 + /* Initialize EPQH */
8050 + switch (usb_pipetype(_urb->pipe))
8052 + case PIPE_CONTROL : epqh->ep_type = IFXUSB_EP_TYPE_CTRL; break;
8053 + case PIPE_BULK : epqh->ep_type = IFXUSB_EP_TYPE_BULK; break;
8054 + case PIPE_ISOCHRONOUS: epqh->ep_type = IFXUSB_EP_TYPE_ISOC; break;
8055 + case PIPE_INTERRUPT : epqh->ep_type = IFXUSB_EP_TYPE_INTR; break;
8058 + //epqh->data_toggle = IFXUSB_HC_PID_DATA0;
8060 + epqh->mps = usb_maxpacket(_urb->dev, _urb->pipe, !(usb_pipein(_urb->pipe)));
8062 + hprt0.d32 = ifxusb_read_hprt0 (&_ifxhcd->core_if);
8064 + INIT_LIST_HEAD(&epqh->urbd_list);
8065 + INIT_LIST_HEAD(&epqh->epqh_list_entry);
8068 + epqh->dump_buf = ifxusb_alloc_buf(epqh->mps, 0);
8070 + /* FS/LS Enpoint on HS Hub
8071 + * NOT virtual root hub */
8072 + epqh->need_split = 0;
8073 + epqh->pkt_count_limit=0;
8074 + if(epqh->ep_type == IFXUSB_EP_TYPE_BULK && !(usb_pipein(_urb->pipe)) )
8075 + epqh->pkt_count_limit=4;
8076 + if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED &&
8077 + ((_urb->dev->speed == USB_SPEED_LOW) ||
8078 + (_urb->dev->speed == USB_SPEED_FULL)) &&
8079 + (_urb->dev->tt) && (_urb->dev->tt->hub->devnum != 1))
8081 + IFX_DEBUGPL(DBG_HCD, "QH init: EP %d: TT found at hub addr %d, for port %d\n",
8082 + usb_pipeendpoint(_urb->pipe), _urb->dev->tt->hub->devnum,
8083 + _urb->dev->ttport);
8084 + epqh->need_split = 1;
8085 + epqh->pkt_count_limit=1;
8088 + if (epqh->ep_type == IFXUSB_EP_TYPE_INTR ||
8089 + epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
8091 + /* Compute scheduling parameters once and save them. */
8092 + epqh->interval = _urb->interval;
8093 + if(epqh->need_split)
8094 + epqh->interval *= 8;
8097 + epqh->period_counter=0;
8098 + epqh->is_active=0;
8100 + #ifdef __EPQD_DESTROY_TIMEOUT__
8101 + /* Start a timer for this transfer. */
8102 + init_timer(&epqh->destroy_timer);
8103 + epqh->destroy_timer.function = eqph_destroy_func;
8104 + epqh->destroy_timer.data = (unsigned long)(epqh);
8108 + IFX_DEBUGPL(DBG_HCD , "IFXUSB HCD EPQH Initialized\n");
8109 + IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - epqh = %p\n", epqh);
8110 + IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - Device Address = %d EP %d, %s\n",
8111 + _urb->dev->devnum,
8112 + usb_pipeendpoint(_urb->pipe),
8113 + usb_pipein(_urb->pipe) == USB_DIR_IN ? "IN" : "OUT");
8114 + IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - Speed = %s\n",
8115 + ({ char *speed; switch (_urb->dev->speed) {
8116 + case USB_SPEED_LOW: speed = "low" ; break;
8117 + case USB_SPEED_FULL: speed = "full"; break;
8118 + case USB_SPEED_HIGH: speed = "high"; break;
8119 + default: speed = "?"; break;
8121 + IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - Type = %s\n",
8123 + char *type; switch (epqh->ep_type)
8125 + case IFXUSB_EP_TYPE_ISOC: type = "isochronous"; break;
8126 + case IFXUSB_EP_TYPE_INTR: type = "interrupt" ; break;
8127 + case IFXUSB_EP_TYPE_CTRL: type = "control" ; break;
8128 + case IFXUSB_EP_TYPE_BULK: type = "bulk" ; break;
8129 + default: type = "?"; break;
8133 + if (epqh->ep_type == IFXUSB_EP_TYPE_INTR)
8134 + IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - interval = %d\n", epqh->interval);
8146 + \brief Free the EPQH. EPQH should already be removed from a list.
8147 + URBD list should already be empty if called from URB Dequeue.
8149 + \param[in] _epqh The EPQH to free.
8151 +void ifxhcd_epqh_free (ifxhcd_epqh_t *_epqh)
8153 + unsigned long flags;
8155 + if(_epqh->sysep) _epqh->sysep->hcpriv=NULL;
8156 + _epqh->sysep=NULL;
8161 + /* Free each QTD in the QTD list */
8162 + local_irq_save (flags);
8163 + if (!list_empty(&_epqh->urbd_list))
8164 + IFX_WARN("%s() invalid epqh state\n",__func__);
8166 + #if defined(__UNALIGNED_BUFFER_ADJ__)
8167 + if(_epqh->aligned_buf)
8168 + ifxusb_free_buf(_epqh->aligned_buf);
8169 + if(_epqh->aligned_setup)
8170 + ifxusb_free_buf(_epqh->aligned_setup);
8173 + if (!list_empty(&_epqh->epqh_list_entry))
8174 + list_del_init(&_epqh->epqh_list_entry);
8176 + #ifdef __EPQD_DESTROY_TIMEOUT__
8177 + del_timer(&_epqh->destroy_timer);
8179 + if(_epqh->dump_buf)
8180 + ifxusb_free_buf(_epqh->dump_buf);
8181 + _epqh->dump_buf=0;
8185 + local_irq_restore (flags);
8189 + \brief This function adds a EPQH to
8191 + \return 0 if successful, negative error code otherwise.
8193 +void ifxhcd_epqh_ready(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
8195 + unsigned long flags;
8196 + local_irq_save(flags);
8197 + if (list_empty(&_epqh->epqh_list_entry))
8199 + #ifdef __EN_ISOC__
8200 + if (_epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
8201 + list_add_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_ready);
8204 + if(_epqh->ep_type == IFXUSB_EP_TYPE_INTR)
8205 + list_add_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_intr_ready);
8207 + list_add_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_np_ready);
8208 + _epqh->is_active=0;
8210 + else if(!_epqh->is_active)
8212 + #ifdef __EN_ISOC__
8213 + if (_epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
8214 + list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_ready);
8217 + if(_epqh->ep_type == IFXUSB_EP_TYPE_INTR)
8218 + list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_intr_ready);
8220 + list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_np_ready);
8222 + #ifdef __EPQD_DESTROY_TIMEOUT__
8223 + del_timer(&_epqh->destroy_timer);
8225 + local_irq_restore(flags);
8228 +void ifxhcd_epqh_active(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
8230 + unsigned long flags;
8231 + local_irq_save(flags);
8232 + if (list_empty(&_epqh->epqh_list_entry))
8233 + IFX_WARN("%s() invalid epqh state\n",__func__);
8234 + #ifdef __EN_ISOC__
8235 + if (_epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
8236 + list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_active);
8239 + if(_epqh->ep_type == IFXUSB_EP_TYPE_INTR)
8240 + list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_intr_active);
8242 + list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_np_active);
8243 + _epqh->is_active=1;
8244 + #ifdef __EPQD_DESTROY_TIMEOUT__
8245 + del_timer(&_epqh->destroy_timer);
8247 + local_irq_restore(flags);
8250 +void ifxhcd_epqh_idle(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
8252 + unsigned long flags;
8253 + local_irq_save(flags);
8255 + if (list_empty(&_epqh->urbd_list))
8257 + if(_epqh->ep_type == IFXUSB_EP_TYPE_ISOC || _epqh->ep_type == IFXUSB_EP_TYPE_INTR)
8259 + list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_stdby);
8263 + list_del_init(&_epqh->epqh_list_entry);
8264 + #ifdef __EPQD_DESTROY_TIMEOUT__
8265 + del_timer(&_epqh->destroy_timer);
8266 + _epqh->destroy_timer.expires = jiffies + (HZ*epqh_self_destroy_timeout);
8267 + add_timer(&_epqh->destroy_timer );
8273 + #ifdef __EN_ISOC__
8274 + if (_epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
8275 + list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_ready);
8278 + if(_epqh->ep_type == IFXUSB_EP_TYPE_INTR)
8279 + list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_intr_ready);
8281 + list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_np_ready);
8283 + _epqh->is_active=0;
8284 + local_irq_restore(flags);
8288 +void ifxhcd_epqh_idle_periodic(ifxhcd_epqh_t *_epqh)
8290 + unsigned long flags;
8291 + if(_epqh->ep_type != IFXUSB_EP_TYPE_ISOC && _epqh->ep_type != IFXUSB_EP_TYPE_INTR)
8294 + local_irq_save(flags);
8296 + if (list_empty(&_epqh->epqh_list_entry))
8297 + IFX_WARN("%s() invalid epqh state\n",__func__);
8298 + if (!list_empty(&_epqh->urbd_list))
8299 + IFX_WARN("%s() invalid epqh state(not empty)\n",__func__);
8301 + _epqh->is_active=0;
8302 + list_del_init(&_epqh->epqh_list_entry);
8303 + #ifdef __EPQD_DESTROY_TIMEOUT__
8304 + del_timer(&_epqh->destroy_timer);
8305 + _epqh->destroy_timer.expires = jiffies + (HZ*epqh_self_destroy_timeout);
8306 + add_timer(&_epqh->destroy_timer );
8309 + local_irq_restore(flags);
8313 +int ifxhcd_urbd_create (ifxhcd_hcd_t *_ifxhcd,struct urb *_urb)
8315 + ifxhcd_urbd_t *urbd;
8316 + struct usb_host_endpoint *sysep;
8317 + ifxhcd_epqh_t *epqh;
8318 + unsigned long flags;
8319 + /* == AVM/WK 20100714 retval correctly initialized ==*/
8320 + int retval = -ENOMEM;
8322 + /*== AVM/BC 20100630 - Spinlock ==*/
8323 + //local_irq_save(flags);
8324 + SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
8326 +// urbd = (ifxhcd_urbd_t *) kmalloc (sizeof(ifxhcd_urbd_t), GFP_KERNEL);
8327 + urbd = (ifxhcd_urbd_t *) kmalloc (sizeof(ifxhcd_urbd_t), GFP_ATOMIC);
8328 + if (urbd != NULL) /* Initializes a QTD structure.*/
8331 + memset (urbd, 0, sizeof (ifxhcd_urbd_t));
8333 + sysep = ifxhcd_urb_to_endpoint(_urb);
8334 + epqh = (ifxhcd_epqh_t *)sysep->hcpriv;
8337 + epqh = ifxhcd_epqh_create (_ifxhcd, _urb);
8342 + //local_irq_restore (flags);
8343 + SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
8346 + sysep->hcpriv = epqh;
8349 + INIT_LIST_HEAD(&urbd->urbd_list_entry);
8351 + /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/
8352 + retval = usb_hcd_link_urb_to_ep(ifxhcd_to_syshcd(_ifxhcd), _urb);
8354 + if (unlikely(retval)){
8357 + SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
8361 + list_add_tail(&urbd->urbd_list_entry, &epqh->urbd_list);
8363 + _urb->hcpriv = urbd;
8366 + urbd->is_in=usb_pipein(_urb->pipe) ? 1 : 0;;
8368 + urbd->xfer_len=_urb->transfer_buffer_length;
8369 +#define URB_NO_SETUP_DMA_MAP 0
8371 + if(urbd->xfer_len>0)
8373 + if(_urb->transfer_flags && URB_NO_TRANSFER_DMA_MAP)
8374 + urbd->xfer_buff = (uint8_t *) (KSEG1ADDR((uint32_t *)_urb->transfer_dma));
8376 + urbd->xfer_buff = (uint8_t *) _urb->transfer_buffer;
8378 + if(epqh->ep_type == IFXUSB_EP_TYPE_CTRL)
8380 + if(_urb->transfer_flags && URB_NO_SETUP_DMA_MAP)
8381 + urbd->setup_buff = (uint8_t *) (KSEG1ADDR((uint32_t *)_urb->setup_dma));
8383 + urbd->setup_buff = (uint8_t *) _urb->setup_packet;
8386 + //local_irq_restore (flags);
8387 + SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
8391 diff --git a/drivers/usb/ifxhcd/ifxusb_cif.c b/drivers/usb/ifxhcd/ifxusb_cif.c
8392 new file mode 100644
8393 index 0000000..10b1292
8395 +++ b/drivers/usb/ifxhcd/ifxusb_cif.c
8397 +/*****************************************************************************
8398 + ** FILE NAME : ifxusb_cif.c
8399 + ** PROJECT : IFX USB sub-system V3
8400 + ** MODULES : IFX USB sub-system Host and Device driver
8401 + ** SRC VERSION : 1.0
8402 + ** DATE : 1/Jan/2009
8403 + ** AUTHOR : Chen, Howard
8404 + ** DESCRIPTION : The Core Interface provides basic services for accessing and
8405 + ** managing the IFX USB hardware. These services are used by both the
8406 + ** Host Controller Driver and the Peripheral Controller Driver.
8407 + *****************************************************************************/
8410 + \file ifxusb_cif.c
8411 + \ingroup IFXUSB_DRIVER_V3
8412 + \brief This file contains the interface to the IFX USB Core.
8415 +#include <linux/clk.h>
8416 +#include <linux/version.h>
8417 +#include "ifxusb_version.h"
8419 +#include <asm/byteorder.h>
8420 +#include <asm/unaligned.h>
8423 +#include <linux/jiffies.h>
8424 +#include <linux/platform_device.h>
8425 +#include <linux/kernel.h>
8426 +#include <linux/ioport.h>
8428 +#if defined(__UEIP__)
8429 +// #include <asm/ifx/ifx_pmu.h>
8430 +// #include <ifx_pmu.h>
8434 +#include "ifxusb_plat.h"
8435 +#include "ifxusb_regs.h"
8436 +#include "ifxusb_cif.h"
8439 +#ifdef __IS_DEVICE__
8440 + #include "ifxpcd.h"
8444 + #include "ifxhcd.h"
8447 +#include <linux/mm.h>
8449 +#include <linux/gfp.h>
8451 +#if defined(__UEIP__)
8452 +// #include <asm/ifx/ifx_board.h>
8453 + //#include <ifx_board.h>
8456 +//#include <asm/ifx/ifx_gpio.h>
8457 +//#include <ifx_gpio.h>
8458 +#if defined(__UEIP__)
8459 +// #include <asm/ifx/ifx_led.h>
8460 + //#include <ifx_led.h>
8465 +#if defined(__UEIP__)
8466 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
8467 + #ifndef USB_CTRL_PMU_SETUP
8468 + #define USB_CTRL_PMU_SETUP(__x) USB0_CTRL_PMU_SETUP(__x)
8470 + #ifndef USB_PHY_PMU_SETUP
8471 + #define USB_PHY_PMU_SETUP(__x) USB0_PHY_PMU_SETUP(__x)
8473 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
8474 +#endif // defined(__UEIP__)
8477 + \brief This function is called to allocate buffer of specified size.
8478 + The allocated buffer is mapped into DMA accessable address.
8479 + \param size Size in BYTE to be allocated
8480 + \param clear 0: don't do clear after buffer allocated, other: do clear to zero
8481 + \return 0/NULL: Fail; uncached pointer of allocated buffer
8483 +void *ifxusb_alloc_buf(size_t size, int clear)
8485 + uint32_t *cached,*uncached;
8486 + uint32_t totalsize,page;
8491 + size=(size+3)&0xFFFFFFFC;
8492 + totalsize=size + 12;
8493 + page=get_order(totalsize);
8495 + cached = (void *) __get_free_pages(( GFP_ATOMIC | GFP_DMA), page);
8499 + IFX_PRINT("%s Allocation Failed size:%d\n",__func__,size);
8503 + uncached = (uint32_t *)(KSEG1ADDR(cached));
8505 + memset(uncached, 0, totalsize);
8507 + *(uncached+0)=totalsize;
8508 + *(uncached+1)=page;
8509 + *(uncached+2)=(uint32_t)cached;
8510 + return (void *)(uncached+3);
8515 + \brief This function is called to free allocated buffer.
8516 + \param vaddr the uncached pointer of the buffer
8518 +void ifxusb_free_buf(void *vaddr)
8520 + uint32_t totalsize,page;
8521 + uint32_t *cached,*uncached;
8527 + totalsize=*(uncached+0);
8528 + page=*(uncached+1);
8529 + cached=(uint32_t *)(*(uncached+2));
8530 + if(totalsize && page==get_order(totalsize) && cached==(uint32_t *)(KSEG0ADDR(uncached)))
8532 + free_pages((unsigned long)cached, page);
8535 + // the memory is not allocated by ifxusb_alloc_buf. Allowed but must be careful.
8543 + \brief This function is called to initialize the IFXUSB CSR data
8544 + structures. The register addresses in the device and host
8545 + structures are initialized from the base address supplied by the
8546 + caller. The calling function must make the OS calls to get the
8547 + base address of the IFXUSB controller registers.
8549 + \param _core_if Pointer of core_if structure
8550 + \param _irq irq number
8551 + \param _reg_base_addr Base address of IFXUSB core registers
8552 + \param _fifo_base_addr Fifo base address
8553 + \param _fifo_dbg_addr Fifo debug address
8554 + \return 0: success;
8556 +int ifxusb_core_if_init(ifxusb_core_if_t *_core_if,
8558 + uint32_t _reg_base_addr,
8559 + uint32_t _fifo_base_addr,
8560 + uint32_t _fifo_dbg_addr)
8563 + uint32_t *reg_base =NULL;
8564 + uint32_t *fifo_base =NULL;
8565 + uint32_t *fifo_dbg =NULL;
8569 + IFX_DEBUGPL(DBG_CILV, "%s(%p,%d,0x%08X,0x%08X,0x%08X)\n", __func__,
8576 + if( _core_if == NULL)
8578 + IFX_ERROR("%s() invalid _core_if\n", __func__);
8583 + //memset(_core_if, 0, sizeof(ifxusb_core_if_t));
8585 + _core_if->irq=_irq;
8587 + reg_base =ioremap_nocache(_reg_base_addr , IFXUSB_IOMEM_SIZE );
8588 + fifo_base =ioremap_nocache(_fifo_base_addr, IFXUSB_FIFOMEM_SIZE);
8589 + fifo_dbg =ioremap_nocache(_fifo_dbg_addr , IFXUSB_FIFODBG_SIZE);
8590 + if( reg_base == NULL || fifo_base == NULL || fifo_dbg == NULL)
8592 + IFX_ERROR("%s() usb ioremap() failed\n", __func__);
8597 + _core_if->core_global_regs = (ifxusb_core_global_regs_t *)reg_base;
8600 + * Attempt to ensure this device is really a IFXUSB Controller.
8601 + * Read and verify the SNPSID register contents. The value should be
8606 + snpsid = ifxusb_rreg(&_core_if->core_global_regs->gsnpsid);
8607 + if ((snpsid & 0xFFFFF000) != 0x4F542000)
8609 + IFX_ERROR("%s() snpsid error(0x%08x) failed\n", __func__,snpsid);
8613 + _core_if->snpsid=snpsid;
8616 + #ifdef __IS_HOST__
8617 + _core_if->host_global_regs = (ifxusb_host_global_regs_t *)
8618 + ((uint32_t)reg_base + IFXUSB_HOST_GLOBAL_REG_OFFSET);
8619 + _core_if->hprt0 = (uint32_t*)((uint32_t)reg_base + IFXUSB_HOST_PORT_REGS_OFFSET);
8621 + for (i=0; i<MAX_EPS_CHANNELS; i++)
8623 + _core_if->hc_regs[i] = (ifxusb_hc_regs_t *)
8624 + ((uint32_t)reg_base + IFXUSB_HOST_CHAN_REGS_OFFSET +
8625 + (i * IFXUSB_CHAN_REGS_OFFSET));
8626 + IFX_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
8627 + i, &_core_if->hc_regs[i]->hcchar);
8629 + #endif //__IS_HOST__
8631 + #ifdef __IS_DEVICE__
8632 + _core_if->dev_global_regs =
8633 + (ifxusb_device_global_regs_t *)((uint32_t)reg_base + IFXUSB_DEV_GLOBAL_REG_OFFSET);
8635 + for (i=0; i<MAX_EPS_CHANNELS; i++)
8637 + _core_if->in_ep_regs[i] = (ifxusb_dev_in_ep_regs_t *)
8638 + ((uint32_t)reg_base + IFXUSB_DEV_IN_EP_REG_OFFSET +
8639 + (i * IFXUSB_EP_REG_OFFSET));
8640 + _core_if->out_ep_regs[i] = (ifxusb_dev_out_ep_regs_t *)
8641 + ((uint32_t)reg_base + IFXUSB_DEV_OUT_EP_REG_OFFSET +
8642 + (i * IFXUSB_EP_REG_OFFSET));
8643 + IFX_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p/%p %p/0x%08X/0x%08X\n",
8644 + i, &_core_if->in_ep_regs[i]->diepctl, _core_if->in_ep_regs[i],
8645 + reg_base,IFXUSB_DEV_IN_EP_REG_OFFSET,(i * IFXUSB_EP_REG_OFFSET)
8647 + IFX_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p/%p %p/0x%08X/0x%08X\n",
8648 + i, &_core_if->out_ep_regs[i]->doepctl, _core_if->out_ep_regs[i],
8649 + reg_base,IFXUSB_DEV_OUT_EP_REG_OFFSET,(i * IFXUSB_EP_REG_OFFSET)
8652 + #endif //__IS_DEVICE__
8654 + /* Setting the FIFO and other Address. */
8655 + for (i=0; i<MAX_EPS_CHANNELS; i++)
8657 + _core_if->data_fifo[i] = fifo_base + (i * IFXUSB_DATA_FIFO_SIZE);
8658 + IFX_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08x\n",
8659 + i, (unsigned)_core_if->data_fifo[i]);
8662 + _core_if->data_fifo_dbg = fifo_dbg;
8663 + _core_if->pcgcctl = (uint32_t*)(((uint32_t)reg_base) + IFXUSB_PCGCCTL_OFFSET);
8666 + * Store the contents of the hardware configuration registers here for
8667 + * easy access later.
8669 + _core_if->hwcfg1.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg1);
8670 + _core_if->hwcfg2.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg2);
8671 + _core_if->hwcfg3.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg3);
8672 + _core_if->hwcfg4.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg4);
8674 + IFX_DEBUGPL(DBG_CILV,"hwcfg1=%08x\n",_core_if->hwcfg1.d32);
8675 + IFX_DEBUGPL(DBG_CILV,"hwcfg2=%08x\n",_core_if->hwcfg2.d32);
8676 + IFX_DEBUGPL(DBG_CILV,"hwcfg3=%08x\n",_core_if->hwcfg3.d32);
8677 + IFX_DEBUGPL(DBG_CILV,"hwcfg4=%08x\n",_core_if->hwcfg4.d32);
8680 + #ifdef __DED_FIFO__
8681 + IFX_PRINT("Waiting for PHY Clock Lock!\n");
8682 + while(!( ifxusb_rreg(&_core_if->core_global_regs->grxfsiz) & (1<<9)))
8685 + IFX_PRINT("PHY Clock Locked!\n");
8686 + //ifxusb_clean_spram(_core_if,128*1024/4);
8689 + /* Create new workqueue and init works */
8691 + _core_if->wq_usb = create_singlethread_workqueue(_core_if->core_name);
8693 + if(_core_if->wq_usb == 0)
8695 + IFX_DEBUGPL(DBG_CIL, "Creation of wq_usb failed\n");
8700 + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
8701 + INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change, core_if);
8702 + INIT_WORK(&core_if->w_wkp, w_wakeup_detected, core_if);
8704 + INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change);
8705 + INIT_DELAYED_WORK(&core_if->w_wkp, w_wakeup_detected);
8711 + if( reg_base != NULL) iounmap(reg_base );
8712 + if( fifo_base != NULL) iounmap(fifo_base);
8713 + if( fifo_dbg != NULL) iounmap(fifo_dbg );
8718 + \brief This function free the mapped address in the IFXUSB CSR data structures.
8719 + \param _core_if Pointer of core_if structure
8721 +void ifxusb_core_if_remove(ifxusb_core_if_t *_core_if)
8723 + /* Disable all interrupts */
8724 + if( _core_if->core_global_regs != NULL)
8726 + ifxusb_mreg( &_core_if->core_global_regs->gahbcfg, 1, 0);
8727 + ifxusb_wreg( &_core_if->core_global_regs->gintmsk, 0);
8730 + if( _core_if->core_global_regs != NULL) iounmap(_core_if->core_global_regs );
8731 + if( _core_if->data_fifo[0] != NULL) iounmap(_core_if->data_fifo[0] );
8732 + if( _core_if->data_fifo_dbg != NULL) iounmap(_core_if->data_fifo_dbg );
8735 + if (_core_if->wq_usb)
8736 + destroy_workqueue(_core_if->wq_usb);
8738 + memset(_core_if, 0, sizeof(ifxusb_core_if_t));
8745 + \brief This function enbles the controller's Global Interrupt in the AHB Config register.
8746 + \param _core_if Pointer of core_if structure
8748 +void ifxusb_enable_global_interrupts( ifxusb_core_if_t *_core_if )
8750 + gahbcfg_data_t ahbcfg ={ .d32 = 0};
8751 + ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
8752 + ifxusb_mreg(&_core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
8756 + \brief This function disables the controller's Global Interrupt in the AHB Config register.
8757 + \param _core_if Pointer of core_if structure
8759 +void ifxusb_disable_global_interrupts( ifxusb_core_if_t *_core_if )
8761 + gahbcfg_data_t ahbcfg ={ .d32 = 0};
8762 + ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
8763 + ifxusb_mreg(&_core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
8770 + \brief Flush Tx and Rx FIFO.
8771 + \param _core_if Pointer of core_if structure
8773 +void ifxusb_flush_both_fifo( ifxusb_core_if_t *_core_if )
8775 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
8776 + volatile grstctl_t greset ={ .d32 = 0};
8779 + IFX_DEBUGPL((DBG_CIL|DBG_PCDV), "%s\n", __func__);
8780 + greset.b.rxfflsh = 1;
8781 + greset.b.txfflsh = 1;
8782 + greset.b.txfnum = 0x10;
8783 + greset.b.intknqflsh=1;
8784 + greset.b.hstfrm=1;
8785 + ifxusb_wreg( &global_regs->grstctl, greset.d32 );
8789 + greset.d32 = ifxusb_rreg( &global_regs->grstctl);
8790 + if (++count > 10000)
8792 + IFX_WARN("%s() HANG! GRSTCTL=%0x\n", __func__, greset.d32);
8795 + } while (greset.b.rxfflsh == 1 || greset.b.txfflsh == 1);
8796 + /* Wait for 3 PHY Clocks*/
8801 + \brief Flush a Tx FIFO.
8802 + \param _core_if Pointer of core_if structure
8803 + \param _num Tx FIFO to flush. ( 0x10 for ALL TX FIFO )
8805 +void ifxusb_flush_tx_fifo( ifxusb_core_if_t *_core_if, const int _num )
8807 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
8808 + volatile grstctl_t greset ={ .d32 = 0};
8811 + IFX_DEBUGPL((DBG_CIL|DBG_PCDV), "Flush Tx FIFO %d\n", _num);
8813 + greset.b.intknqflsh=1;
8814 + greset.b.txfflsh = 1;
8815 + greset.b.txfnum = _num;
8816 + ifxusb_wreg( &global_regs->grstctl, greset.d32 );
8820 + greset.d32 = ifxusb_rreg( &global_regs->grstctl);
8821 + if (++count > 10000&&(_num==0 ||_num==0x10))
8823 + IFX_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
8824 + __func__, greset.d32,
8825 + ifxusb_rreg( &global_regs->gnptxsts));
8828 + } while (greset.b.txfflsh == 1);
8829 + /* Wait for 3 PHY Clocks*/
8835 + \brief Flush Rx FIFO.
8836 + \param _core_if Pointer of core_if structure
8838 +void ifxusb_flush_rx_fifo( ifxusb_core_if_t *_core_if )
8840 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
8841 + volatile grstctl_t greset ={ .d32 = 0};
8844 + IFX_DEBUGPL((DBG_CIL|DBG_PCDV), "%s\n", __func__);
8845 + greset.b.rxfflsh = 1;
8846 + ifxusb_wreg( &global_regs->grstctl, greset.d32 );
8850 + greset.d32 = ifxusb_rreg( &global_regs->grstctl);
8851 + if (++count > 10000)
8853 + IFX_WARN("%s() HANG! GRSTCTL=%0x\n", __func__, greset.d32);
8856 + } while (greset.b.rxfflsh == 1);
8857 + /* Wait for 3 PHY Clocks*/
8862 +#define SOFT_RESET_DELAY 100
8865 + \brief Do a soft reset of the core. Be careful with this because it
8866 + resets all the internal state machines of the core.
8867 + \param _core_if Pointer of core_if structure
8869 +int ifxusb_core_soft_reset(ifxusb_core_if_t *_core_if)
8871 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
8872 + volatile grstctl_t greset ={ .d32 = 0};
8875 + IFX_DEBUGPL(DBG_CILV, "%s\n", __func__);
8876 + /* Wait for AHB master IDLE state. */
8880 + greset.d32 = ifxusb_rreg( &global_regs->grstctl);
8881 + if (++count > 100000)
8883 + IFX_WARN("%s() HANG! AHB Idle GRSTCTL=%0x %x\n", __func__,
8884 + greset.d32, greset.b.ahbidle);
8887 + } while (greset.b.ahbidle == 0);
8891 + /* Core Soft Reset */
8893 + greset.b.csftrst = 1;
8894 + ifxusb_wreg( &global_regs->grstctl, greset.d32 );
8896 + #ifdef SOFT_RESET_DELAY
8897 + MDELAY(SOFT_RESET_DELAY);
8903 + greset.d32 = ifxusb_rreg( &global_regs->grstctl);
8904 + if (++count > 100000)
8906 + IFX_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n", __func__, greset.d32);
8909 + } while (greset.b.csftrst == 1);
8911 + #ifdef SOFT_RESET_DELAY
8912 + MDELAY(SOFT_RESET_DELAY);
8916 + #if defined(__IS_VR9__)
8917 + if(_core_if->core_no==0)
8919 + set_bit (4, VR9_RCU_USBRESET2);
8921 + clear_bit (4, VR9_RCU_USBRESET2);
8925 + set_bit (5, VR9_RCU_USBRESET2);
8927 + clear_bit (5, VR9_RCU_USBRESET2);
8930 + #endif //defined(__IS_VR9__)
8932 + IFX_PRINT("USB core #%d soft-reset\n",_core_if->core_no);
8938 + \brief Turn on the USB Core Power
8939 + \param _core_if Pointer of core_if structure
8941 +void ifxusb_power_on (ifxusb_core_if_t *_core_if)
8943 + struct clk *clk0 = clk_get_sys("usb0", NULL);
8944 + struct clk *clk1 = clk_get_sys("usb1", NULL);
8945 + // set clock gating
8946 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
8947 + #if defined(__UEIP__)
8949 + #if defined(__IS_TWINPASS) || defined(__IS_DANUBE__)
8950 + set_bit (4, (volatile unsigned long *)DANUBE_CGU_IFCCR);
8951 + set_bit (5, (volatile unsigned long *)DANUBE_CGU_IFCCR);
8952 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
8953 + #if defined(__IS_AMAZON_SE__)
8954 + // clear_bit (4, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR);
8955 + clear_bit (5, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR);
8956 + #endif //defined(__IS_AMAZON_SE__)
8957 + #if defined(__IS_AR9__)
8958 + set_bit (0, (volatile unsigned long *)AR9_CGU_IFCCR);
8959 + set_bit (1, (volatile unsigned long *)AR9_CGU_IFCCR);
8960 + #endif //defined(__IS_AR9__)
8961 + #if defined(__IS_VR9__)
8962 +// set_bit (0, (volatile unsigned long *)VR9_CGU_IFCCR);
8963 +// set_bit (1, (volatile unsigned long *)VR9_CGU_IFCCR);
8964 + #endif //defined(__IS_VR9__)
8969 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
8970 + USB_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
8971 + //#if defined(__IS_TWINPASS__)
8972 + // ifxusb_enable_afe_oc();
8974 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
8975 + #if defined(__IS_AR9__) || defined(__IS_VR9__)
8976 + if(_core_if->core_no==0)
8978 +// USB0_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
8981 +// USB1_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
8982 + #endif //defined(__IS_AR9__) || defined(__IS_VR9__)
8984 + if(_core_if->core_global_regs)
8986 + // PHY configurations.
8987 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
8988 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
8989 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
8990 + #if defined(__IS_AMAZON_SE__)
8991 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
8992 + #endif //defined(__IS_AMAZON_SE__)
8993 + #if defined(__IS_AR9__)
8994 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
8995 + #endif //defined(__IS_AR9__)
8996 + #if defined(__IS_VR9__)
8997 + //ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
8998 + #endif //defined(__IS_VR9__)
9000 + #else //defined(__UEIP__)
9001 + #if defined(__IS_TWINPASS) || defined(__IS_DANUBE__)
9002 + set_bit (4, (volatile unsigned long *)DANUBE_CGU_IFCCR);
9003 + set_bit (5, (volatile unsigned long *)DANUBE_CGU_IFCCR);
9004 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9005 + #if defined(__IS_AMAZON_SE__)
9006 + // clear_bit (4, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR);
9007 + clear_bit (5, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR);
9008 + #endif //defined(__IS_AMAZON_SE__)
9009 + #if defined(__IS_AR9__)
9010 + set_bit (0, (volatile unsigned long *)AMAZON_S_CGU_IFCCR);
9011 + set_bit (1, (volatile unsigned long *)AMAZON_S_CGU_IFCCR);
9012 + #endif //defined(__IS_AR9__)
9017 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9018 + clear_bit (6, (volatile unsigned long *)DANUBE_PMU_PWDCR);//USB
9019 + clear_bit (9, (volatile unsigned long *)DANUBE_PMU_PWDCR);//DSL
9020 + clear_bit (15, (volatile unsigned long *)DANUBE_PMU_PWDCR);//AHB
9021 + #if defined(__IS_TWINPASS__)
9022 + ifxusb_enable_afe_oc();
9024 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9025 + #if defined(__IS_AMAZON_SE__)
9026 + clear_bit (6, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);
9027 + clear_bit (9, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);
9028 + clear_bit (15, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);
9029 + #endif //defined(__IS_AMAZON_SE__)
9030 + #if defined(__IS_AR9__)
9031 + if(_core_if->core_no==0)
9032 + clear_bit (6, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB
9034 + clear_bit (27, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB
9035 + clear_bit (9, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//DSL
9036 + clear_bit (15, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//AHB
9037 + #endif //defined(__IS_AR9__)
9039 + if(_core_if->core_global_regs)
9041 + // PHY configurations.
9042 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9043 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9044 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9045 + #if defined(__IS_AMAZON_SE__)
9046 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9047 + #endif //defined(__IS_AMAZON_SE__)
9048 + #if defined(__IS_AR9__)
9049 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9050 + #endif //defined(__IS_AR9__)
9053 + #endif //defined(__UEIP__)
9057 + \brief Turn off the USB Core Power
9058 + \param _core_if Pointer of core_if structure
9060 +void ifxusb_power_off (ifxusb_core_if_t *_core_if)
9062 + struct clk *clk0 = clk_get_sys("usb0", NULL);
9063 + struct clk *clk1 = clk_get_sys("usb1", NULL);
9064 + ifxusb_phy_power_off (_core_if);
9067 + #if defined(__UEIP__)
9068 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
9069 + USB_CTRL_PMU_SETUP(IFX_PMU_DISABLE);
9070 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
9071 + #if defined(__IS_AR9__) || defined(__IS_VR9__)
9072 + if(_core_if->core_no==0)
9073 + clk_disable(clk0);
9074 + //USB0_CTRL_PMU_SETUP(IFX_PMU_DISABLE);
9076 + clk_disable(clk1);
9077 + //USB1_CTRL_PMU_SETUP(IFX_PMU_DISABLE);
9078 + #endif //defined(__IS_AR9__) || defined(__IS_VR9__)
9079 + #else //defined(__UEIP__)
9080 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9081 + set_bit (6, (volatile unsigned long *)DANUBE_PMU_PWDCR);//USB
9082 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9083 + #if defined(__IS_AMAZON_SE__)
9084 + set_bit (6, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);//USB
9085 + #endif //defined(__IS_AMAZON_SE__)
9086 + #if defined(__IS_AR9__)
9087 + if(_core_if->core_no==0)
9088 + set_bit (6, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB
9090 + set_bit (27, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB
9091 + #endif //defined(__IS_AR9__)
9092 + #endif //defined(__UEIP__)
9096 + \brief Turn on the USB PHY Power
9097 + \param _core_if Pointer of core_if structure
9099 +void ifxusb_phy_power_on (ifxusb_core_if_t *_core_if)
9101 + struct clk *clk0 = clk_get_sys("usb0", NULL);
9102 + struct clk *clk1 = clk_get_sys("usb1", NULL);
9103 + #if defined(__UEIP__)
9104 + if(_core_if->core_global_regs)
9106 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9107 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9108 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9109 + #if defined(__IS_AMAZON_SE__)
9110 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9111 + #endif //defined(__IS_AMAZON_SE__)
9112 + #if defined(__IS_AR9__)
9113 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9114 + #endif //defined(__IS_AR9__)
9115 + #if defined(__IS_VR9_S__)
9116 + if(_core_if->core_no==0)
9117 + set_bit (0, VR9_RCU_USB_ANA_CFG1A);
9119 + set_bit (0, VR9_RCU_USB_ANA_CFG1B);
9120 + #endif //defined(__IS_VR9__)
9123 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
9124 + USB_PHY_PMU_SETUP(IFX_PMU_ENABLE);
9125 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
9126 + #if defined(__IS_AR9__) || defined(__IS_VR9__)
9127 + if(_core_if->core_no==0)
9129 + //USB0_PHY_PMU_SETUP(IFX_PMU_ENABLE);
9132 + //USB1_PHY_PMU_SETUP(IFX_PMU_ENABLE);
9133 + #endif //defined(__IS_AR9__) || defined(__IS_VR9__)
9135 + // PHY configurations.
9136 + if(_core_if->core_global_regs)
9138 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9139 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9140 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9141 + #if defined(__IS_AMAZON_SE__)
9142 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9143 + #endif //defined(__IS_AMAZON_SE__)
9144 + #if defined(__IS_AR9__)
9145 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9146 + #endif //defined(__IS_AR9__)
9147 + #if defined(__IS_VR9_S__)
9148 + if(_core_if->core_no==0)
9149 + set_bit (0, VR9_RCU_USB_ANA_CFG1A);
9151 + set_bit (0, VR9_RCU_USB_ANA_CFG1B);
9152 + #endif //defined(__IS_VR9__)
9154 + #else //defined(__UEIP__)
9155 + // PHY configurations.
9156 + if(_core_if->core_global_regs)
9158 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9159 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9160 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9161 + #if defined(__IS_AMAZON_SE__)
9162 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9163 + #endif //defined(__IS_AMAZON_SE__)
9164 + #if defined(__IS_AR9__)
9165 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9166 + #endif //defined(__IS_AR9__)
9169 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9170 + clear_bit (0, (volatile unsigned long *)DANUBE_PMU_PWDCR);//PHY
9171 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9172 + #if defined(__IS_AMAZON_SE__)
9173 + clear_bit (0, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);
9174 + #endif //defined(__IS_AMAZON_SE__)
9175 + #if defined(__IS_AR9__)
9176 + if(_core_if->core_no==0)
9177 + clear_bit (0, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY
9179 + clear_bit (26, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY
9180 + #endif //defined(__IS_AR9__)
9182 + // PHY configurations.
9183 + if(_core_if->core_global_regs)
9185 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9186 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9187 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9188 + #if defined(__IS_AMAZON_SE__)
9189 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9190 + #endif //defined(__IS_AMAZON_SE__)
9191 + #if defined(__IS_AR9__)
9192 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9193 + #endif //defined(__IS_AR9__)
9195 + #endif //defined(__UEIP__)
9200 + \brief Turn off the USB PHY Power
9201 + \param _core_if Pointer of core_if structure
9203 +void ifxusb_phy_power_off (ifxusb_core_if_t *_core_if)
9205 + struct clk *clk0 = clk_get_sys("usb0", NULL);
9206 + struct clk *clk1 = clk_get_sys("usb1", NULL);
9207 + #if defined(__UEIP__)
9208 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
9209 + USB_PHY_PMU_SETUP(IFX_PMU_DISABLE);
9210 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
9211 + #if defined(__IS_AR9__) || defined(__IS_VR9__)
9212 + if(_core_if->core_no==0)
9213 + clk_disable(clk0);
9214 + //USB0_PHY_PMU_SETUP(IFX_PMU_DISABLE);
9216 + clk_disable(clk1);
9217 + //USB1_PHY_PMU_SETUP(IFX_PMU_DISABLE);
9218 + #endif // defined(__IS_AR9__) || defined(__IS_VR9__)
9219 + #else //defined(__UEIP__)
9220 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9221 + set_bit (0, (volatile unsigned long *)DANUBE_PMU_PWDCR);//PHY
9222 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9223 + #if defined(__IS_AMAZON_SE__)
9224 + set_bit (0, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);//PHY
9225 + #endif //defined(__IS_AMAZON_SE__)
9226 + #if defined(__IS_AR9__)
9227 + if(_core_if->core_no==0)
9228 + set_bit (0, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY
9230 + set_bit (26, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY
9231 + #endif //defined(__IS_AR9__)
9232 + #endif //defined(__UEIP__)
9237 + \brief Reset on the USB Core RCU
9238 + \param _core_if Pointer of core_if structure
9240 +#if defined(__IS_VR9__)
9241 + int already_hard_reset=0;
9243 +void ifxusb_hard_reset(ifxusb_core_if_t *_core_if)
9245 + #if defined(__UEIP__)
9246 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9247 + #if defined (__IS_HOST__)
9248 + clear_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
9249 + #elif defined (__IS_DEVICE__)
9250 + set_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
9252 + #endif //defined(__IS_AMAZON_SE__)
9254 + #if defined(__IS_AMAZON_SE__)
9255 + #if defined (__IS_HOST__)
9256 + clear_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
9257 + #elif defined (__IS_DEVICE__)
9258 + set_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
9260 + #endif //defined(__IS_AMAZON_SE__)
9262 + #if defined(__IS_AR9__)
9263 + if(_core_if->core_no==0)
9265 + #if defined (__IS_HOST__)
9266 + clear_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG);
9267 + #elif defined (__IS_DEVICE__)
9268 + set_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG);
9273 + #if defined (__IS_HOST__)
9274 + clear_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG);
9275 + #elif defined (__IS_DEVICE__)
9276 + set_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG);
9279 + #endif //defined(__IS_AR9__)
9281 + #if defined(__IS_VR9__)
9282 + if(_core_if->core_no==0)
9284 + #if defined (__IS_HOST__)
9285 + clear_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
9286 + #elif defined (__IS_DEVICE__)
9287 + set_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
9292 + #if defined (__IS_HOST__)
9293 + clear_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
9294 + #elif defined (__IS_DEVICE__)
9295 + set_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
9298 + #endif //defined(__IS_VR9__)
9301 + // set the HC's byte-order to big-endian
9302 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9303 + set_bit (DANUBE_USBCFG_HOST_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
9304 + clear_bit (DANUBE_USBCFG_SLV_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
9305 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9306 + #if defined(__IS_AMAZON_SE__)
9307 + set_bit (AMAZON_SE_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
9308 + clear_bit (AMAZON_SE_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
9309 + #endif //defined(__IS_AMAZON_SE__)
9310 + #if defined(__IS_AR9__)
9311 + if(_core_if->core_no==0)
9313 + set_bit (AR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG);
9314 + clear_bit (AR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG);
9318 + set_bit (AR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG);
9319 + clear_bit (AR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG);
9321 + #endif //defined(__IS_AR9__)
9322 + #if defined(__IS_VR9__)
9323 + if(_core_if->core_no==0)
9325 + set_bit (VR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
9326 + clear_bit (VR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
9330 + set_bit (VR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
9331 + clear_bit (VR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
9333 + #endif //defined(__IS_VR9__)
9335 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9336 + set_bit (4, DANUBE_RCU_RESET);
9338 + clear_bit (4, DANUBE_RCU_RESET);
9339 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9341 + #if defined(__IS_AMAZON_SE__)
9342 + set_bit (4, AMAZON_SE_RCU_RESET);
9344 + clear_bit (4, AMAZON_SE_RCU_RESET);
9346 + #endif //defined(__IS_AMAZON_SE__)
9348 + #if defined(__IS_AR9__)
9349 + if(_core_if->core_no==0)
9351 + set_bit (4, AR9_RCU_USBRESET);
9353 + clear_bit (4, AR9_RCU_USBRESET);
9357 + set_bit (28, AR9_RCU_USBRESET);
9359 + clear_bit (28, AR9_RCU_USBRESET);
9362 + #endif //defined(__IS_AR9__)
9363 + #if defined(__IS_VR9__)
9364 + if(!already_hard_reset)
9366 + set_bit (4, VR9_RCU_USBRESET);
9368 + clear_bit (4, VR9_RCU_USBRESET);
9370 + already_hard_reset=1;
9372 + #endif //defined(__IS_VR9__)
9374 + #if defined(__IS_TWINPASS__)
9375 + ifxusb_enable_afe_oc();
9378 + if(_core_if->core_global_regs)
9380 + // PHY configurations.
9381 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9382 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9383 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9384 + #if defined(__IS_AMAZON_SE__)
9385 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9386 + #endif //defined(__IS_AMAZON_SE__)
9387 + #if defined(__IS_AR9__)
9388 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9389 + #endif //defined(__IS_AR9__)
9390 + #if defined(__IS_VR9__)
9391 + // ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9392 + #endif //defined(__IS_VR9__)
9394 + #else //defined(__UEIP__)
9395 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9396 + #if defined (__IS_HOST__)
9397 + clear_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
9398 + #elif defined (__IS_DEVICE__)
9399 + set_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
9401 + #endif //defined(__IS_AMAZON_SE__)
9403 + #if defined(__IS_AMAZON_SE__)
9404 + #if defined (__IS_HOST__)
9405 + clear_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
9406 + #elif defined (__IS_DEVICE__)
9407 + set_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
9409 + #endif //defined(__IS_AMAZON_SE__)
9411 + #if defined(__IS_AR9__)
9412 + if(_core_if->core_no==0)
9414 + #if defined (__IS_HOST__)
9415 + clear_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG);
9416 + #elif defined (__IS_DEVICE__)
9417 + set_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG);
9422 + #if defined (__IS_HOST__)
9423 + clear_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG);
9424 + #elif defined (__IS_DEVICE__)
9425 + set_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG);
9428 + #endif //defined(__IS_AR9__)
9430 + // set the HC's byte-order to big-endian
9431 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9432 + set_bit (DANUBE_USBCFG_HOST_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
9433 + clear_bit (DANUBE_USBCFG_SLV_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
9434 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9435 + #if defined(__IS_AMAZON_SE__)
9436 + set_bit (AMAZON_SE_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
9437 + clear_bit (AMAZON_SE_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
9438 + #endif //defined(__IS_AMAZON_SE__)
9439 + #if defined(__IS_AR9__)
9440 + if(_core_if->core_no==0)
9442 + set_bit (AMAZON_S_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG);
9443 + clear_bit (AMAZON_S_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG);
9447 + set_bit (AMAZON_S_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG);
9448 + clear_bit (AMAZON_S_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG);
9450 + #endif //defined(__IS_AR9__)
9452 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9453 + set_bit (4, DANUBE_RCU_RESET);
9454 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9455 + #if defined(__IS_AMAZON_SE__)
9456 + set_bit (4, AMAZON_SE_RCU_RESET);
9457 + #endif //defined(__IS_AMAZON_SE__)
9458 + #if defined(__IS_AR9__)
9459 + if(_core_if->core_no==0)
9461 + set_bit (4, AMAZON_S_RCU_USBRESET);
9465 + set_bit (28, AMAZON_S_RCU_USBRESET);
9467 + #endif //defined(__IS_AR9__)
9471 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9472 + clear_bit (4, DANUBE_RCU_RESET);
9473 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9474 + #if defined(__IS_AMAZON_SE__)
9475 + clear_bit (4, AMAZON_SE_RCU_RESET);
9476 + #endif //defined(__IS_AMAZON_SE__)
9477 + #if defined(__IS_AR9__)
9478 + if(_core_if->core_no==0)
9480 + clear_bit (4, AMAZON_S_RCU_USBRESET);
9484 + clear_bit (28, AMAZON_S_RCU_USBRESET);
9486 + #endif //defined(__IS_AR9__)
9490 + #if defined(__IS_TWINPASS__)
9491 + ifxusb_enable_afe_oc();
9494 + if(_core_if->core_global_regs)
9496 + // PHY configurations.
9497 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9498 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9499 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
9500 + #if defined(__IS_AMAZON_SE__)
9501 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9502 + #endif //defined(__IS_AMAZON_SE__)
9503 + #if defined(__IS_AR9__)
9504 + ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
9505 + #endif //defined(__IS_AR9__)
9507 + #endif //defined(__UEIP__)
9510 +#if defined(__GADGET_LED__) || defined(__HOST_LED__)
9511 + #if defined(__UEIP__)
9512 + static void *g_usb_led_trigger = NULL;
9515 + void ifxusb_led_init(ifxusb_core_if_t *_core_if)
9517 + #if defined(__UEIP__)
9518 + if ( !g_usb_led_trigger )
9520 + ifx_led_trigger_register("usb_link", &g_usb_led_trigger);
9521 + if ( g_usb_led_trigger != NULL )
9523 + struct ifx_led_trigger_attrib attrib = {0};
9524 + attrib.delay_on = 250;
9525 + attrib.delay_off = 250;
9526 + attrib.timeout = 2000;
9527 + attrib.def_value = 1;
9528 + attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE;
9529 + IFX_DEBUGP("Reg USB LED!!\n");
9530 + ifx_led_trigger_set_attrib(g_usb_led_trigger, &attrib);
9533 + #endif //defined(__UEIP__)
9536 + void ifxusb_led_free(ifxusb_core_if_t *_core_if)
9538 + #if defined(__UEIP__)
9539 + if ( g_usb_led_trigger )
9541 + ifx_led_trigger_deregister(g_usb_led_trigger);
9542 + g_usb_led_trigger = NULL;
9544 + #endif //defined(__UEIP__)
9548 + \brief Turn off the USB 5V VBus Power
9549 + \param _core_if Pointer of core_if structure
9551 + void ifxusb_led(ifxusb_core_if_t *_core_if)
9553 + #if defined(__UEIP__)
9554 + if(g_usb_led_trigger)
9555 + ifx_led_trigger_activate(g_usb_led_trigger);
9557 + #endif //defined(__UEIP__)
9559 +#endif // defined(__GADGET_LED__) || defined(__HOST_LED__)
9563 +#if defined(__IS_HOST__) && defined(__DO_OC_INT__) && defined(__DO_OC_INT_ENABLE__)
9565 + \brief Turn on the OC Int
9567 + void ifxusb_oc_int_on()
9569 + #if defined(__UEIP__)
9571 + #if defined(__IS_TWINPASS__)
9572 + irq_enable(DANUBE_USB_OC_INT);
9574 + #endif //defined(__UEIP__)
9577 + \brief Turn off the OC Int
9579 + void ifxusb_oc_int_off()
9581 + #if defined(__UEIP__)
9583 + #if defined(__IS_TWINPASS__)
9584 + irq_disable(DANUBE_USB_OC_INT);
9586 + #endif //defined(__UEIP__)
9588 +#endif //defined(__IS_HOST__) && defined(__DO_OC_INT__) && defined(__DO_OC_INT_ENABLE__)
9590 +/* internal routines for debugging */
9591 +void ifxusb_dump_msg(const u8 *buf, unsigned int length)
9594 + unsigned int start, num, i;
9595 + char line[52], *p;
9597 + if (length >= 512)
9600 + while (length > 0)
9602 + num = min(length, 16u);
9604 + for (i = 0; i < num; ++i)
9608 + sprintf(p, " %02x", buf[i]);
9612 + IFX_PRINT( "%6x: %s\n", start, line);
9620 +/* This functions reads the SPRAM and prints its content */
9621 +void ifxusb_dump_spram(ifxusb_core_if_t *_core_if)
9623 +#ifdef __ENABLE_DUMP__
9624 + volatile uint8_t *addr, *start_addr, *end_addr;
9626 + IFX_PRINT("SPRAM Data:\n");
9627 + start_addr = (void*)_core_if->core_global_regs;
9628 + IFX_PRINT("Base Address: 0x%8X\n", (uint32_t)start_addr);
9630 + start_addr = (void*)_core_if->data_fifo_dbg;
9631 + IFX_PRINT("Starting Address: 0x%8X\n", (uint32_t)start_addr);
9633 + size=_core_if->hwcfg3.b.dfifo_depth;
9638 + end_addr = (void*)_core_if->data_fifo_dbg;
9641 + for(addr = start_addr; addr < end_addr; addr+=16)
9643 + IFX_PRINT("0x%8X:\t%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", (uint32_t)addr,
9644 + addr[ 0], addr[ 1], addr[ 2], addr[ 3],
9645 + addr[ 4], addr[ 5], addr[ 6], addr[ 7],
9646 + addr[ 8], addr[ 9], addr[10], addr[11],
9647 + addr[12], addr[13], addr[14], addr[15]
9651 +#endif //__ENABLE_DUMP__
9657 +/* This function reads the core global registers and prints them */
9658 +void ifxusb_dump_registers(ifxusb_core_if_t *_core_if)
9660 +#ifdef __ENABLE_DUMP__
9662 + volatile uint32_t *addr;
9663 + #ifdef __IS_DEVICE__
9664 + volatile uint32_t *addri,*addro;
9667 + IFX_PRINT("Core Global Registers\n");
9668 + addr=&_core_if->core_global_regs->gotgctl;
9669 + IFX_PRINT("GOTGCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9670 + addr=&_core_if->core_global_regs->gotgint;
9671 + IFX_PRINT("GOTGINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9672 + addr=&_core_if->core_global_regs->gahbcfg;
9673 + IFX_PRINT("GAHBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9674 + addr=&_core_if->core_global_regs->gusbcfg;
9675 + IFX_PRINT("GUSBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9676 + addr=&_core_if->core_global_regs->grstctl;
9677 + IFX_PRINT("GRSTCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9678 + addr=&_core_if->core_global_regs->gintsts;
9679 + IFX_PRINT("GINTSTS @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9680 + addr=&_core_if->core_global_regs->gintmsk;
9681 + IFX_PRINT("GINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9682 + addr=&_core_if->core_global_regs->gi2cctl;
9683 + IFX_PRINT("GI2CCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9684 + addr=&_core_if->core_global_regs->gpvndctl;
9685 + IFX_PRINT("GPVNDCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9686 + addr=&_core_if->core_global_regs->ggpio;
9687 + IFX_PRINT("GGPIO @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9688 + addr=&_core_if->core_global_regs->guid;
9689 + IFX_PRINT("GUID @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9690 + addr=&_core_if->core_global_regs->gsnpsid;
9691 + IFX_PRINT("GSNPSID @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9692 + addr=&_core_if->core_global_regs->ghwcfg1;
9693 + IFX_PRINT("GHWCFG1 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9694 + addr=&_core_if->core_global_regs->ghwcfg2;
9695 + IFX_PRINT("GHWCFG2 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9696 + addr=&_core_if->core_global_regs->ghwcfg3;
9697 + IFX_PRINT("GHWCFG3 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9698 + addr=&_core_if->core_global_regs->ghwcfg4;
9699 + IFX_PRINT("GHWCFG4 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9701 + addr=_core_if->pcgcctl;
9702 + IFX_PRINT("PCGCCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9704 + addr=&_core_if->core_global_regs->grxfsiz;
9705 + IFX_PRINT("GRXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9707 + #ifdef __IS_HOST__
9708 + addr=&_core_if->core_global_regs->gnptxfsiz;
9709 + IFX_PRINT("GNPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9710 + addr=&_core_if->core_global_regs->hptxfsiz;
9711 + IFX_PRINT("HPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9712 + #endif //__IS_HOST__
9714 + #ifdef __IS_DEVICE__
9715 + #ifdef __DED_FIFO__
9716 + addr=&_core_if->core_global_regs->gnptxfsiz;
9717 + IFX_PRINT("GNPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9718 + for (i=0; i<= _core_if->hwcfg4.b.num_in_eps; i++)
9720 + addr=&_core_if->core_global_regs->dptxfsiz_dieptxf[i];
9721 + IFX_PRINT("DPTXFSIZ[%d] @0x%08X : 0x%08X\n",i,(uint32_t)addr,ifxusb_rreg(addr));
9724 + addr=&_core_if->core_global_regs->gnptxfsiz;
9725 + IFX_PRINT("TXFSIZ[00] @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9726 + for (i=0; i< _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
9728 + addr=&_core_if->core_global_regs->dptxfsiz_dieptxf[i];
9729 + IFX_PRINT("TXFSIZ[%02d] @0x%08X : 0x%08X\n",i+1,(uint32_t)addr,ifxusb_rreg(addr));
9732 + #endif //__IS_DEVICE__
9734 + #ifdef __IS_HOST__
9735 + IFX_PRINT("Host Global Registers\n");
9736 + addr=&_core_if->host_global_regs->hcfg;
9737 + IFX_PRINT("HCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9738 + addr=&_core_if->host_global_regs->hfir;
9739 + IFX_PRINT("HFIR @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9740 + addr=&_core_if->host_global_regs->hfnum;
9741 + IFX_PRINT("HFNUM @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9742 + addr=&_core_if->host_global_regs->hptxsts;
9743 + IFX_PRINT("HPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9744 + addr=&_core_if->host_global_regs->haint;
9745 + IFX_PRINT("HAINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9746 + addr=&_core_if->host_global_regs->haintmsk;
9747 + IFX_PRINT("HAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9748 + addr= _core_if->hprt0;
9749 + IFX_PRINT("HPRT0 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9751 + for (i=0; i<MAX_EPS_CHANNELS; i++)
9753 + IFX_PRINT("Host Channel %d Specific Registers\n", i);
9754 + addr=&_core_if->hc_regs[i]->hcchar;
9755 + IFX_PRINT("HCCHAR @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9756 + addr=&_core_if->hc_regs[i]->hcsplt;
9757 + IFX_PRINT("HCSPLT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9758 + addr=&_core_if->hc_regs[i]->hcint;
9759 + IFX_PRINT("HCINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9760 + addr=&_core_if->hc_regs[i]->hcintmsk;
9761 + IFX_PRINT("HCINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9762 + addr=&_core_if->hc_regs[i]->hctsiz;
9763 + IFX_PRINT("HCTSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9764 + addr=&_core_if->hc_regs[i]->hcdma;
9765 + IFX_PRINT("HCDMA @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9767 + #endif //__IS_HOST__
9769 + #ifdef __IS_DEVICE__
9770 + IFX_PRINT("Device Global Registers\n");
9771 + addr=&_core_if->dev_global_regs->dcfg;
9772 + IFX_PRINT("DCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9773 + addr=&_core_if->dev_global_regs->dctl;
9774 + IFX_PRINT("DCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9775 + addr=&_core_if->dev_global_regs->dsts;
9776 + IFX_PRINT("DSTS @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9777 + addr=&_core_if->dev_global_regs->diepmsk;
9778 + IFX_PRINT("DIEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9779 + addr=&_core_if->dev_global_regs->doepmsk;
9780 + IFX_PRINT("DOEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9781 + addr=&_core_if->dev_global_regs->daintmsk;
9782 + IFX_PRINT("DAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9783 + addr=&_core_if->dev_global_regs->daint;
9784 + IFX_PRINT("DAINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9785 + addr=&_core_if->dev_global_regs->dvbusdis;
9786 + IFX_PRINT("DVBUSID @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9787 + addr=&_core_if->dev_global_regs->dvbuspulse;
9788 + IFX_PRINT("DVBUSPULSE @0x%08X : 0x%08X\n", (uint32_t)addr,ifxusb_rreg(addr));
9790 + addr=&_core_if->dev_global_regs->dtknqr1;
9791 + IFX_PRINT("DTKNQR1 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
9792 + if (_core_if->hwcfg2.b.dev_token_q_depth > 6) {
9793 + addr=&_core_if->dev_global_regs->dtknqr2;
9794 + IFX_PRINT("DTKNQR2 @0x%08X : 0x%08X\n", (uint32_t)addr,ifxusb_rreg(addr));
9797 + if (_core_if->hwcfg2.b.dev_token_q_depth > 14)
9799 + addr=&_core_if->dev_global_regs->dtknqr3_dthrctl;
9800 + IFX_PRINT("DTKNQR3_DTHRCTL @0x%08X : 0x%08X\n", (uint32_t)addr, ifxusb_rreg(addr));
9803 + if (_core_if->hwcfg2.b.dev_token_q_depth > 22)
9805 + addr=&_core_if->dev_global_regs->dtknqr4_fifoemptymsk;
9806 + IFX_PRINT("DTKNQR4 @0x%08X : 0x%08X\n", (uint32_t)addr, ifxusb_rreg(addr));
9809 + //for (i=0; i<= MAX_EPS_CHANNELS; i++)
9810 + //for (i=0; i<= 10; i++)
9811 + for (i=0; i<= 3; i++)
9813 + IFX_PRINT("Device EP %d Registers\n", i);
9814 + addri=&_core_if->in_ep_regs[i]->diepctl;addro=&_core_if->out_ep_regs[i]->doepctl;
9815 + IFX_PRINT("DEPCTL I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro));
9816 + addro=&_core_if->out_ep_regs[i]->doepfn;
9817 + IFX_PRINT("DEPFN I: O: 0x%08X\n",ifxusb_rreg(addro));
9818 + addri=&_core_if->in_ep_regs[i]->diepint;addro=&_core_if->out_ep_regs[i]->doepint;
9819 + IFX_PRINT("DEPINT I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro));
9820 + addri=&_core_if->in_ep_regs[i]->dieptsiz;addro=&_core_if->out_ep_regs[i]->doeptsiz;
9821 + IFX_PRINT("DETSIZ I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro));
9822 + addri=&_core_if->in_ep_regs[i]->diepdma;addro=&_core_if->out_ep_regs[i]->doepdma;
9823 + IFX_PRINT("DEPDMA I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro));
9824 + addri=&_core_if->in_ep_regs[i]->dtxfsts;
9825 + IFX_PRINT("DTXFSTS I: 0x%08X\n",ifxusb_rreg(addri) );
9826 + addri=&_core_if->in_ep_regs[i]->diepdmab;addro=&_core_if->out_ep_regs[i]->doepdmab;
9827 + IFX_PRINT("DEPDMAB I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro));
9829 + #endif //__IS_DEVICE__
9830 +#endif //__ENABLE_DUMP__
9833 +void ifxusb_clean_spram(ifxusb_core_if_t *_core_if,uint32_t dwords)
9835 + volatile uint32_t *addr1,*addr2, *start_addr, *end_addr;
9840 + start_addr = (uint32_t *)_core_if->data_fifo_dbg;
9842 + end_addr = (uint32_t *)_core_if->data_fifo_dbg;
9843 + end_addr += dwords;
9845 + IFX_PRINT("Clearning SPRAM: 0x%8X-0x%8X\n", (uint32_t)start_addr,(uint32_t)end_addr);
9846 + for(addr1 = start_addr; addr1 < end_addr; addr1+=4)
9848 + for(addr2 = addr1; addr2 < addr1+4; addr2++)
9849 + *addr2=0x00000000;
9851 + IFX_PRINT("Clearning SPRAM: 0x%8X-0x%8X Done\n", (uint32_t)start_addr,(uint32_t)end_addr);
9855 diff --git a/drivers/usb/ifxhcd/ifxusb_cif.h b/drivers/usb/ifxhcd/ifxusb_cif.h
9856 new file mode 100644
9857 index 0000000..191781f
9859 +++ b/drivers/usb/ifxhcd/ifxusb_cif.h
9861 +/*****************************************************************************
9862 + ** FILE NAME : ifxusb_cif.h
9863 + ** PROJECT : IFX USB sub-system V3
9864 + ** MODULES : IFX USB sub-system Host and Device driver
9865 + ** SRC VERSION : 1.0
9866 + ** DATE : 1/Jan/2009
9867 + ** AUTHOR : Chen, Howard
9868 + ** DESCRIPTION : The Core Interface provides basic services for accessing and
9869 + ** managing the IFX USB hardware. These services are used by both the
9870 + ** Host Controller Driver and the Peripheral Controller Driver.
9873 + ** REFERENCE : IFX hardware ref handbook for each plateforms
9875 + ** Version Control Section **
9879 + ** $Log$ Revision history
9880 +*****************************************************************************/
9883 + \defgroup IFXUSB_DRIVER_V3 IFX USB SS Project
9884 + \brief IFX USB subsystem V3.x
9888 + \defgroup IFXUSB_CIF Core Interface APIs
9889 + \ingroup IFXUSB_DRIVER_V3
9890 + \brief The Core Interface provides basic services for accessing and
9891 + managing the IFXUSB hardware. These services are used by both the
9892 + Host Controller Driver and the Peripheral Controller Driver.
9897 + \file ifxusb_cif.h
9898 + \ingroup IFXUSB_DRIVER_V3
9899 + \brief This file contains the interface to the IFX USB Core.
9902 +#if !defined(__IFXUSB_CIF_H__)
9903 +#define __IFXUSB_CIF_H__
9905 +#include <linux/workqueue.h>
9907 +#include <linux/version.h>
9908 +#include <asm/param.h>
9910 +#include "ifxusb_plat.h"
9911 +#include "ifxusb_regs.h"
9914 + #include "linux/timer.h"
9917 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9919 +#define IFXUSB_PARAM_SPEED_HIGH 0
9920 +#define IFXUSB_PARAM_SPEED_FULL 1
9922 +#define IFXUSB_EP_SPEED_LOW 0
9923 +#define IFXUSB_EP_SPEED_FULL 1
9924 +#define IFXUSB_EP_SPEED_HIGH 2
9926 +#define IFXUSB_EP_TYPE_CTRL 0
9927 +#define IFXUSB_EP_TYPE_ISOC 1
9928 +#define IFXUSB_EP_TYPE_BULK 2
9929 +#define IFXUSB_EP_TYPE_INTR 3
9931 +#define IFXUSB_HC_PID_DATA0 0
9932 +#define IFXUSB_HC_PID_DATA2 1
9933 +#define IFXUSB_HC_PID_DATA1 2
9934 +#define IFXUSB_HC_PID_MDATA 3
9935 +#define IFXUSB_HC_PID_SETUP 3
9939 + \addtogroup IFXUSB_CIF
9944 + \struct ifxusb_params
9945 + \brief IFXUSB Parameters structure.
9946 + This structure is used for both importing from insmod stage and run-time storage.
9947 + These parameters define how the IFXUSB controller should be configured.
9949 +typedef struct ifxusb_params
9951 + int32_t dma_burst_size; /*!< The DMA Burst size (applicable only for Internal DMA
9952 + Mode). 0(for single), 1(incr), 4(incr4), 8(incr8) 16(incr16)
9954 + /* Translate this to GAHBCFG values */
9955 + int32_t speed; /*!< Specifies the maximum speed of operation in host and device mode.
9956 + The actual speed depends on the speed of the attached device and
9957 + the value of phy_type. The actual speed depends on the speed of the
9959 + 0 - High Speed (default)
9963 + int32_t data_fifo_size; /*!< Total number of dwords in the data FIFO memory. This
9964 + memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic
9968 + #ifdef __IS_DEVICE__
9969 + int32_t rx_fifo_size; /*!< Number of dwords in the Rx FIFO in device mode.
9974 + int32_t tx_fifo_size[MAX_EPS_CHANNELS]; /*!< Number of dwords in each of the Tx FIFOs in device mode.
9977 + #ifdef __DED_FIFO__
9978 + int32_t thr_ctl; /*!< Threshold control on/off */
9979 + int32_t tx_thr_length; /*!< Threshold length for Tx */
9980 + int32_t rx_thr_length; /*!< Threshold length for Rx*/
9982 + #else //__IS_HOST__
9983 + int32_t host_channels; /*!< The number of host channel registers to use.
9987 + int32_t rx_fifo_size; /*!< Number of dwords in the Rx FIFO in host mode.
9991 + int32_t nperio_tx_fifo_size;/*!< Number of dwords in the non-periodic Tx FIFO in host mode.
9995 + int32_t perio_tx_fifo_size; /*!< Number of dwords in the host periodic Tx FIFO.
9998 + #endif //__IS_HOST__
10000 + int32_t max_transfer_size; /*!< The maximum transfer size supported in bytes.
10004 + int32_t max_packet_count; /*!< The maximum number of packets in a transfer.
10005 + 15 to 511 (default 511)
10007 + int32_t phy_utmi_width; /*!< Specifies the UTMI+ Data Width.
10008 + 8 or 16 bits (default 16)
10011 + int32_t turn_around_time_hs; /*!< Specifies the Turn-Around time at HS*/
10012 + int32_t turn_around_time_fs; /*!< Specifies the Turn-Around time at FS*/
10014 + int32_t timeout_cal_hs; /*!< Specifies the Timeout_Calibration at HS*/
10015 + int32_t timeout_cal_fs; /*!< Specifies the Timeout_Calibration at FS*/
10016 +} ifxusb_params_t;
10018 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10019 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10022 + \struct ifxusb_core_if
10023 + \brief The ifx_core_if structure contains information needed to manage
10024 + the IFX USB controller acting in either host or device mode. It
10025 + represents the programming view of the controller as a whole.
10027 +typedef struct ifxusb_core_if
10029 + ifxusb_params_t params; /*!< Run-time Parameters */
10031 + uint8_t core_no; /*!< core number (used as id when multi-core case */
10032 + char *core_name; /*!< core name used for registration and informative purpose*/
10033 + int irq; /*!< irq number this core is hooked */
10035 + /*****************************************************************
10036 + * Structures and pointers to physical register interface.
10037 + *****************************************************************/
10038 + /** Core Global registers starting at offset 000h. */
10039 + ifxusb_core_global_regs_t *core_global_regs; /*!< pointer to Core Global Registers, offset at 000h */
10041 + /** Host-specific registers */
10042 + #ifdef __IS_HOST__
10043 + /** Host Global Registers starting at offset 400h.*/
10044 + ifxusb_host_global_regs_t *host_global_regs; /*!< pointer to Host Global Registers, offset at 400h */
10045 + #define IFXUSB_HOST_GLOBAL_REG_OFFSET 0x400
10046 + /** Host Port 0 Control and Status Register */
10047 + volatile uint32_t *hprt0; /*!< pointer to HPRT0 Registers, offset at 440h */
10048 + #define IFXUSB_HOST_PORT_REGS_OFFSET 0x440
10049 + /** Host Channel Specific Registers at offsets 500h-5FCh. */
10050 + ifxusb_hc_regs_t *hc_regs[MAX_EPS_CHANNELS]; /*!< pointer to Host-Channel n Registers, offset at 500h */
10051 + #define IFXUSB_HOST_CHAN_REGS_OFFSET 0x500
10052 + #define IFXUSB_CHAN_REGS_OFFSET 0x20
10055 + /** Device-specific registers */
10056 + #ifdef __IS_DEVICE__
10057 + /** Device Global Registers starting at offset 800h */
10058 + ifxusb_device_global_regs_t *dev_global_regs; /*!< pointer to Device Global Registers, offset at 800h */
10059 + #define IFXUSB_DEV_GLOBAL_REG_OFFSET 0x800
10061 + /** Device Logical IN Endpoint-Specific Registers 900h-AFCh */
10062 + ifxusb_dev_in_ep_regs_t *in_ep_regs[MAX_EPS_CHANNELS]; /*!< pointer to Device IN-EP Registers, offset at 900h */
10063 + #define IFXUSB_DEV_IN_EP_REG_OFFSET 0x900
10064 + #define IFXUSB_EP_REG_OFFSET 0x20
10065 + /** Device Logical OUT Endpoint-Specific Registers B00h-CFCh */
10066 + ifxusb_dev_out_ep_regs_t *out_ep_regs[MAX_EPS_CHANNELS];/*!< pointer to Device OUT-EP Registers, offset at 900h */
10067 + #define IFXUSB_DEV_OUT_EP_REG_OFFSET 0xB00
10070 + /** Power and Clock Gating Control Register */
10071 + volatile uint32_t *pcgcctl; /*!< pointer to Power and Clock Gating Control Registers, offset at E00h */
10072 + #define IFXUSB_PCGCCTL_OFFSET 0xE00
10074 + /** Push/pop addresses for endpoints or host channels.*/
10075 + uint32_t *data_fifo[MAX_EPS_CHANNELS]; /*!< pointer to FIFO access windows, offset at 1000h */
10076 + #define IFXUSB_DATA_FIFO_OFFSET 0x1000
10077 + #define IFXUSB_DATA_FIFO_SIZE 0x1000
10079 + uint32_t *data_fifo_dbg; /*!< pointer to FIFO debug windows, offset at 1000h */
10081 + /** Hardware Configuration -- stored here for convenience.*/
10082 + hwcfg1_data_t hwcfg1; /*!< preserved Hardware Configuration 1 */
10083 + hwcfg2_data_t hwcfg2; /*!< preserved Hardware Configuration 2 */
10084 + hwcfg3_data_t hwcfg3; /*!< preserved Hardware Configuration 3 */
10085 + hwcfg4_data_t hwcfg4; /*!< preserved Hardware Configuration 3 */
10086 + uint32_t snpsid; /*!< preserved SNPSID */
10088 + /*****************************************************************
10089 + * Run-time informations.
10090 + *****************************************************************/
10091 + /* Set to 1 if the core PHY interface bits in USBCFG have been initialized. */
10092 + uint8_t phy_init_done; /*!< indicated PHY is initialized. */
10094 + #ifdef __IS_HOST__
10095 + uint8_t queuing_high_bandwidth; /*!< Host mode, Queueing High Bandwidth. */
10097 +} ifxusb_core_if_t;
10099 +/*@}*//*IFXUSB_CIF*/
10103 + \fn void *ifxusb_alloc_buf(size_t size, int clear)
10104 + \brief This function is called to allocate buffer of specified size.
10105 + The allocated buffer is mapped into DMA accessable address.
10106 + \param size Size in BYTE to be allocated
10107 + \param clear 0: don't do clear after buffer allocated, other: do clear to zero
10108 + \return 0/NULL: Fail; uncached pointer of allocated buffer
10109 + \ingroup IFXUSB_CIF
10111 +extern void *ifxusb_alloc_buf(size_t size, int clear);
10114 + \fn void ifxusb_free_buf(void *vaddr)
10115 + \brief This function is called to free allocated buffer.
10116 + \param vaddr the uncached pointer of the buffer
10117 + \ingroup IFXUSB_CIF
10119 +extern void ifxusb_free_buf(void *vaddr);
10122 + \fn int ifxusb_core_if_init(ifxusb_core_if_t *_core_if,
10124 + uint32_t _reg_base_addr,
10125 + uint32_t _fifo_base_addr,
10126 + uint32_t _fifo_dbg_addr)
10127 + \brief This function is called to initialize the IFXUSB CSR data
10128 + structures. The register addresses in the device and host
10129 + structures are initialized from the base address supplied by the
10130 + caller. The calling function must make the OS calls to get the
10131 + base address of the IFXUSB controller registers.
10132 + \param _core_if Pointer of core_if structure
10133 + \param _irq irq number
10134 + \param _reg_base_addr Base address of IFXUSB core registers
10135 + \param _fifo_base_addr Fifo base address
10136 + \param _fifo_dbg_addr Fifo debug address
10137 + \return 0: success;
10138 + \ingroup IFXUSB_CIF
10140 +extern int ifxusb_core_if_init(ifxusb_core_if_t *_core_if,
10142 + uint32_t _reg_base_addr,
10143 + uint32_t _fifo_base_addr,
10144 + uint32_t _fifo_dbg_addr);
10148 + \fn void ifxusb_core_if_remove(ifxusb_core_if_t *_core_if)
10149 + \brief This function free the mapped address in the IFXUSB CSR data structures.
10150 + \param _core_if Pointer of core_if structure
10151 + \ingroup IFXUSB_CIF
10153 +extern void ifxusb_core_if_remove(ifxusb_core_if_t *_core_if);
10156 + \fn void ifxusb_enable_global_interrupts( ifxusb_core_if_t *_core_if )
10157 + \brief This function enbles the controller's Global Interrupt in the AHB Config register.
10158 + \param _core_if Pointer of core_if structure
10160 +extern void ifxusb_enable_global_interrupts( ifxusb_core_if_t *_core_if );
10163 + \fn void ifxusb_disable_global_interrupts( ifxusb_core_if_t *_core_if )
10164 + \brief This function disables the controller's Global Interrupt in the AHB Config register.
10165 + \param _core_if Pointer of core_if structure
10166 + \ingroup IFXUSB_CIF
10168 +extern void ifxusb_disable_global_interrupts( ifxusb_core_if_t *_core_if );
10171 + \fn void ifxusb_flush_tx_fifo( ifxusb_core_if_t *_core_if, const int _num )
10172 + \brief Flush a Tx FIFO.
10173 + \param _core_if Pointer of core_if structure
10174 + \param _num Tx FIFO to flush. ( 0x10 for ALL TX FIFO )
10175 + \ingroup IFXUSB_CIF
10177 +extern void ifxusb_flush_tx_fifo( ifxusb_core_if_t *_core_if, const int _num );
10180 + \fn void ifxusb_flush_rx_fifo( ifxusb_core_if_t *_core_if )
10181 + \brief Flush Rx FIFO.
10182 + \param _core_if Pointer of core_if structure
10183 + \ingroup IFXUSB_CIF
10185 +extern void ifxusb_flush_rx_fifo( ifxusb_core_if_t *_core_if );
10188 + \fn void ifxusb_flush_both_fifo( ifxusb_core_if_t *_core_if )
10189 + \brief Flush ALL Rx and Tx FIFO.
10190 + \param _core_if Pointer of core_if structure
10191 + \ingroup IFXUSB_CIF
10193 +extern void ifxusb_flush_both_fifo( ifxusb_core_if_t *_core_if );
10197 + \fn int ifxusb_core_soft_reset(ifxusb_core_if_t *_core_if)
10198 + \brief Do core a soft reset of the core. Be careful with this because it
10199 + resets all the internal state machines of the core.
10200 + \param _core_if Pointer of core_if structure
10201 + \ingroup IFXUSB_CIF
10203 +extern int ifxusb_core_soft_reset(ifxusb_core_if_t *_core_if);
10207 + \brief Turn on the USB Core Power
10208 + \param _core_if Pointer of core_if structure
10209 + \ingroup IFXUSB_CIF
10211 +extern void ifxusb_power_on (ifxusb_core_if_t *_core_if);
10214 + \fn void ifxusb_power_off (ifxusb_core_if_t *_core_if)
10215 + \brief Turn off the USB Core Power
10216 + \param _core_if Pointer of core_if structure
10217 + \ingroup IFXUSB_CIF
10219 +extern void ifxusb_power_off (ifxusb_core_if_t *_core_if);
10222 + \fn void ifxusb_phy_power_on (ifxusb_core_if_t *_core_if)
10223 + \brief Turn on the USB PHY Power
10224 + \param _core_if Pointer of core_if structure
10225 + \ingroup IFXUSB_CIF
10227 +extern void ifxusb_phy_power_on (ifxusb_core_if_t *_core_if);
10230 + \fn void ifxusb_phy_power_off (ifxusb_core_if_t *_core_if)
10231 + \brief Turn off the USB PHY Power
10232 + \param _core_if Pointer of core_if structure
10233 + \ingroup IFXUSB_CIF
10235 +extern void ifxusb_phy_power_off (ifxusb_core_if_t *_core_if);
10238 + \fn void ifxusb_hard_reset(ifxusb_core_if_t *_core_if)
10239 + \brief Reset on the USB Core RCU
10240 + \param _core_if Pointer of core_if structure
10241 + \ingroup IFXUSB_CIF
10243 +extern void ifxusb_hard_reset(ifxusb_core_if_t *_core_if);
10245 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10248 +#ifdef __IS_HOST__
10250 + \fn void ifxusb_host_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params)
10251 + \brief This function initializes the IFXUSB controller registers for Host mode.
10252 + This function flushes the Tx and Rx FIFOs and it flushes any entries in the
10254 + \param _core_if Pointer of core_if structure
10255 + \param _params parameters to be set
10256 + \ingroup IFXUSB_CIF
10258 + extern void ifxusb_host_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params);
10261 + \fn void ifxusb_host_enable_interrupts(ifxusb_core_if_t *_core_if)
10262 + \brief This function enables the Host mode interrupts.
10263 + \param _core_if Pointer of core_if structure
10264 + \ingroup IFXUSB_CIF
10266 + extern void ifxusb_host_enable_interrupts(ifxusb_core_if_t *_core_if);
10269 + \fn void ifxusb_host_disable_interrupts(ifxusb_core_if_t *_core_if)
10270 + \brief This function disables the Host mode interrupts.
10271 + \param _core_if Pointer of core_if structure
10272 + \ingroup IFXUSB_CIF
10274 + extern void ifxusb_host_disable_interrupts(ifxusb_core_if_t *_core_if);
10276 + #if defined(__IS_TWINPASS__)
10277 + extern void ifxusb_enable_afe_oc(void);
10281 + \fn void ifxusb_vbus_init(ifxusb_core_if_t *_core_if)
10282 + \brief This function init the VBUS control.
10283 + \param _core_if Pointer of core_if structure
10284 + \ingroup IFXUSB_CIF
10286 + extern void ifxusb_vbus_init(ifxusb_core_if_t *_core_if);
10289 + \fn void ifxusb_vbus_free(ifxusb_core_if_t *_core_if)
10290 + \brief This function free the VBUS control.
10291 + \param _core_if Pointer of core_if structure
10292 + \ingroup IFXUSB_CIF
10294 + extern void ifxusb_vbus_free(ifxusb_core_if_t *_core_if);
10297 + \fn void ifxusb_vbus_on(ifxusb_core_if_t *_core_if)
10298 + \brief Turn on the USB 5V VBus Power
10299 + \param _core_if Pointer of core_if structure
10300 + \ingroup IFXUSB_CIF
10302 + extern void ifxusb_vbus_on(ifxusb_core_if_t *_core_if);
10305 + \fn void ifxusb_vbus_off(ifxusb_core_if_t *_core_if)
10306 + \brief Turn off the USB 5V VBus Power
10307 + \param _core_if Pointer of core_if structure
10308 + \ingroup IFXUSB_CIF
10310 + extern void ifxusb_vbus_off(ifxusb_core_if_t *_core_if);
10313 + \fn int ifxusb_vbus(ifxusb_core_if_t *_core_if)
10314 + \brief Read Current VBus status
10315 + \param _core_if Pointer of core_if structure
10316 + \ingroup IFXUSB_CIF
10318 + extern int ifxusb_vbus(ifxusb_core_if_t *_core_if);
10320 + #if defined(__DO_OC_INT__) && defined(__DO_OC_INT_ENABLE__)
10322 + \fn void ifxusb_oc_int_on(void)
10323 + \brief Turn on the OC interrupt
10324 + \ingroup IFXUSB_CIF
10326 + extern void ifxusb_oc_int_on(void);
10329 + \fn void ifxusb_oc_int_off(void)
10330 + \brief Turn off the OC interrupt
10331 + \ingroup IFXUSB_CIF
10333 + extern void ifxusb_oc_int_off(void);
10334 + #endif //defined(__DO_OC_INT__) && defined(__DO_OC_INT_ENABLE__)
10337 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10340 +#ifdef __IS_DEVICE__
10342 + \fn void ifxusb_dev_enable_interrupts(ifxusb_core_if_t *_core_if)
10343 + \brief This function enables the Device mode interrupts.
10344 + \param _core_if Pointer of core_if structure
10345 + \ingroup IFXUSB_CIF
10347 + extern void ifxusb_dev_enable_interrupts(ifxusb_core_if_t *_core_if);
10350 + \fn uint32_t ifxusb_dev_get_frame_number(ifxusb_core_if_t *_core_if)
10351 + \brief Gets the current USB frame number. This is the frame number from the last SOF packet.
10352 + \param _core_if Pointer of core_if structure
10353 + \ingroup IFXUSB_CIF
10355 + extern uint32_t ifxusb_dev_get_frame_number(ifxusb_core_if_t *_core_if);
10358 + \fn void ifxusb_dev_ep_set_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _is_in)
10359 + \brief Set the EP STALL.
10360 + \param _core_if Pointer of core_if structure
10361 + \param _epno EP number
10362 + \param _is_in 1: is IN transfer
10363 + \ingroup IFXUSB_CIF
10365 + extern void ifxusb_dev_ep_set_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _is_in);
10368 + \fn void ifxusb_dev_ep_clear_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _ep_type, uint8_t _is_in)
10369 + \brief Set the EP STALL.
10370 + \param _core_if Pointer of core_if structure
10371 + \param _epno EP number
10372 + \param _ep_type EP Type
10373 + \ingroup IFXUSB_CIF
10375 + extern void ifxusb_dev_ep_clear_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _ep_type, uint8_t _is_in);
10378 + \fn void ifxusb_dev_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params)
10379 + \brief This function initializes the IFXUSB controller registers for Device mode.
10380 + This function flushes the Tx and Rx FIFOs and it flushes any entries in the
10382 + This function validate the imported parameters and store the result in the CIF structure.
10384 + \param _core_if Pointer of core_if structure
10385 + \param _params structure of inported parameters
10386 + \ingroup IFXUSB_CIF
10388 + extern void ifxusb_dev_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params);
10391 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10393 +#if defined(__GADGET_LED__) || defined(__HOST_LED__)
10395 + \fn void ifxusb_led_init(ifxusb_core_if_t *_core_if)
10396 + \brief This function init the LED control.
10397 + \param _core_if Pointer of core_if structure
10398 + \ingroup IFXUSB_CIF
10400 + extern void ifxusb_led_init(ifxusb_core_if_t *_core_if);
10403 + \fn void ifxusb_led_free(ifxusb_core_if_t *_core_if)
10404 + \brief This function free the LED control.
10405 + \param _core_if Pointer of core_if structure
10406 + \ingroup IFXUSB_CIF
10408 + extern void ifxusb_led_free(ifxusb_core_if_t *_core_if);
10411 + \fn void ifxusb_led(ifxusb_core_if_t *_core_if)
10412 + \brief This function trigger the LED access.
10413 + \param _core_if Pointer of core_if structure
10414 + \ingroup IFXUSB_CIF
10416 + extern void ifxusb_led(ifxusb_core_if_t *_core_if);
10419 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10421 +/* internal routines for debugging */
10422 +extern void ifxusb_dump_msg(const u8 *buf, unsigned int length);
10423 +extern void ifxusb_dump_spram(ifxusb_core_if_t *_core_if);
10424 +extern void ifxusb_dump_registers(ifxusb_core_if_t *_core_if);
10425 +extern void ifxusb_clean_spram(ifxusb_core_if_t *_core_if,uint32_t dwords);
10427 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10429 +static inline uint32_t ifxusb_read_core_intr(ifxusb_core_if_t *_core_if)
10431 + return (ifxusb_rreg(&_core_if->core_global_regs->gintsts) &
10432 + (ifxusb_rreg(&_core_if->core_global_regs->gintmsk)
10433 +#ifdef __USE_TIMER_4_SOF__
10434 + | IFXUSB_SOF_INTR_MASK
10439 +static inline uint32_t ifxusb_read_otg_intr (ifxusb_core_if_t *_core_if)
10441 + return (ifxusb_rreg (&_core_if->core_global_regs->gotgint));
10444 +static inline uint32_t ifxusb_mode(ifxusb_core_if_t *_core_if)
10446 + return (ifxusb_rreg( &_core_if->core_global_regs->gintsts ) & 0x1);
10448 +static inline uint8_t ifxusb_is_device_mode(ifxusb_core_if_t *_core_if)
10450 + return (ifxusb_mode(_core_if) != 1);
10452 +static inline uint8_t ifxusb_is_host_mode(ifxusb_core_if_t *_core_if)
10454 + return (ifxusb_mode(_core_if) == 1);
10457 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10459 +#ifdef __IS_HOST__
10460 + static inline uint32_t ifxusb_read_hprt0(ifxusb_core_if_t *_core_if)
10462 + hprt0_data_t hprt0;
10463 + hprt0.d32 = ifxusb_rreg(_core_if->hprt0);
10464 + hprt0.b.prtena = 0;
10465 + hprt0.b.prtconndet = 0;
10466 + hprt0.b.prtenchng = 0;
10467 + hprt0.b.prtovrcurrchng = 0;
10468 + return hprt0.d32;
10471 + static inline uint32_t ifxusb_read_host_all_channels_intr (ifxusb_core_if_t *_core_if)
10473 + return (ifxusb_rreg (&_core_if->host_global_regs->haint));
10476 + static inline uint32_t ifxusb_read_host_channel_intr (ifxusb_core_if_t *_core_if, int hc_num)
10478 + return (ifxusb_rreg (&_core_if->hc_regs[hc_num]->hcint));
10482 +#ifdef __IS_DEVICE__
10483 + static inline uint32_t ifxusb_read_dev_all_in_ep_intr(ifxusb_core_if_t *_core_if)
10486 + v = ifxusb_rreg(&_core_if->dev_global_regs->daint) &
10487 + ifxusb_rreg(&_core_if->dev_global_regs->daintmsk);
10488 + return (v & 0xffff);
10491 + static inline uint32_t ifxusb_read_dev_all_out_ep_intr(ifxusb_core_if_t *_core_if)
10494 + v = ifxusb_rreg(&_core_if->dev_global_regs->daint) &
10495 + ifxusb_rreg(&_core_if->dev_global_regs->daintmsk);
10496 + return ((v & 0xffff0000) >> 16);
10499 + static inline uint32_t ifxusb_read_dev_in_ep_intr(ifxusb_core_if_t *_core_if, int _ep_num)
10502 + v = ifxusb_rreg(&_core_if->in_ep_regs[_ep_num]->diepint) &
10503 + ifxusb_rreg(&_core_if->dev_global_regs->diepmsk);
10507 + static inline uint32_t ifxusb_read_dev_out_ep_intr(ifxusb_core_if_t *_core_if, int _ep_num)
10510 + v = ifxusb_rreg(&_core_if->out_ep_regs[_ep_num]->doepint) &
10511 + ifxusb_rreg(&_core_if->dev_global_regs->doepmsk);
10517 +extern void ifxusb_attr_create (void *_dev);
10519 +extern void ifxusb_attr_remove (void *_dev);
10521 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10523 +#endif // !defined(__IFXUSB_CIF_H__)
10526 diff --git a/drivers/usb/ifxhcd/ifxusb_cif_d.c b/drivers/usb/ifxhcd/ifxusb_cif_d.c
10527 new file mode 100644
10528 index 0000000..36ab0e7
10530 +++ b/drivers/usb/ifxhcd/ifxusb_cif_d.c
10532 +/*****************************************************************************
10533 + ** FILE NAME : ifxusb_cif_d.c
10534 + ** PROJECT : IFX USB sub-system V3
10535 + ** MODULES : IFX USB sub-system Host and Device driver
10536 + ** SRC VERSION : 1.0
10537 + ** DATE : 1/Jan/2009
10538 + ** AUTHOR : Chen, Howard
10539 + ** DESCRIPTION : The Core Interface provides basic services for accessing and
10540 + ** managing the IFX USB hardware. These services are used by the
10541 + ** Peripheral Controller Driver only.
10542 + *****************************************************************************/
10545 + \file ifxusb_cif_d.c
10546 + \ingroup IFXUSB_DRIVER_V3
10547 + \brief This file contains the interface to the IFX USB Core.
10550 +#include <linux/version.h>
10551 +#include "ifxusb_version.h"
10554 +#include <asm/byteorder.h>
10555 +#include <asm/unaligned.h>
10558 + #include <linux/jiffies.h>
10561 +#include "ifxusb_plat.h"
10562 +#include "ifxusb_regs.h"
10563 +#include "ifxusb_cif.h"
10565 +#include "ifxpcd.h"
10570 + \brief Initializes the DevSpd field of the DCFG register depending on the PHY type
10571 + and the enumeration speed of the device.
10572 + \param _core_if Pointer of core_if structure
10574 +void ifxusb_dev_init_spd(ifxusb_core_if_t *_core_if)
10577 + dcfg_data_t dcfg;
10579 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
10580 + if (_core_if->params.speed == IFXUSB_PARAM_SPEED_FULL)
10581 + /* High speed PHY running at full speed */
10584 + /* High speed PHY running at high speed and full speed*/
10587 + IFX_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
10588 + dcfg.d32 = ifxusb_rreg(&_core_if->dev_global_regs->dcfg);
10589 + dcfg.b.devspd = val;
10590 + ifxusb_wreg(&_core_if->dev_global_regs->dcfg, dcfg.d32);
10595 + \brief This function enables the Device mode interrupts.
10596 + \param _core_if Pointer of core_if structure
10598 +void ifxusb_dev_enable_interrupts(ifxusb_core_if_t *_core_if)
10600 + gint_data_t intr_mask ={ .d32 = 0};
10601 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
10603 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
10604 + IFX_DEBUGPL(DBG_CIL, "%s()\n", __func__);
10606 + /* Clear any pending OTG Interrupts */
10607 + ifxusb_wreg( &global_regs->gotgint, 0xFFFFFFFF);
10609 + /* Clear any pending interrupts */
10610 + ifxusb_wreg( &global_regs->gintsts, 0xFFFFFFFF);
10612 + /* Enable the interrupts in the GINTMSK.*/
10613 + intr_mask.b.modemismatch = 1;
10614 + intr_mask.b.conidstschng = 1;
10615 + intr_mask.b.wkupintr = 1;
10616 + intr_mask.b.disconnect = 1;
10617 + intr_mask.b.usbsuspend = 1;
10619 + intr_mask.b.usbreset = 1;
10620 + intr_mask.b.enumdone = 1;
10621 + intr_mask.b.inepintr = 1;
10622 + intr_mask.b.outepintr = 1;
10623 + intr_mask.b.erlysuspend = 1;
10624 + #ifndef __DED_FIFO__
10625 +// intr_mask.b.epmismatch = 1;
10628 + ifxusb_mreg( &global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
10629 + IFX_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__, ifxusb_rreg( &global_regs->gintmsk));
10633 + \brief Gets the current USB frame number. This is the frame number from the last SOF packet.
10634 + \param _core_if Pointer of core_if structure
10636 +uint32_t ifxusb_dev_get_frame_number(ifxusb_core_if_t *_core_if)
10638 + dsts_data_t dsts;
10639 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
10640 + dsts.d32 = ifxusb_rreg(&_core_if->dev_global_regs->dsts);
10641 + /* read current frame/microfreme number from DSTS register */
10642 + return dsts.b.soffn;
10647 + \brief Set the EP STALL.
10649 +void ifxusb_dev_ep_set_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _is_in)
10651 + depctl_data_t depctl;
10652 + volatile uint32_t *depctl_addr;
10654 + IFX_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _epno, (_is_in?"IN":"OUT"));
10656 + depctl_addr = (_is_in)? (&(_core_if->in_ep_regs [_epno]->diepctl)):
10657 + (&(_core_if->out_ep_regs[_epno]->doepctl));
10658 + depctl.d32 = ifxusb_rreg(depctl_addr);
10659 + depctl.b.stall = 1;
10661 + if (_is_in && depctl.b.epena)
10662 + depctl.b.epdis = 1;
10664 + ifxusb_wreg(depctl_addr, depctl.d32);
10665 + IFX_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",ifxusb_rreg(depctl_addr));
10670 +\brief Clear the EP STALL.
10672 +void ifxusb_dev_ep_clear_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _ep_type, uint8_t _is_in)
10674 + depctl_data_t depctl;
10675 + volatile uint32_t *depctl_addr;
10677 + IFX_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _epno, (_is_in?"IN":"OUT"));
10679 + depctl_addr = (_is_in)? (&(_core_if->in_ep_regs [_epno]->diepctl)):
10680 + (&(_core_if->out_ep_regs[_epno]->doepctl));
10682 + depctl.d32 = ifxusb_rreg(depctl_addr);
10683 + /* clear the stall bits */
10684 + depctl.b.stall = 0;
10687 + * USB Spec 9.4.5: For endpoints using data toggle, regardless
10688 + * of whether an endpoint has the Halt feature set, a
10689 + * ClearFeature(ENDPOINT_HALT) request always results in the
10690 + * data toggle being reinitialized to DATA0.
10692 + if (_ep_type == IFXUSB_EP_TYPE_INTR || _ep_type == IFXUSB_EP_TYPE_BULK)
10693 + depctl.b.setd0pid = 1; /* DATA0 */
10695 + ifxusb_wreg(depctl_addr, depctl.d32);
10696 + IFX_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",ifxusb_rreg(depctl_addr));
10701 + \brief This function initializes the IFXUSB controller registers for Device mode.
10702 + This function flushes the Tx and Rx FIFOs and it flushes any entries in the
10704 + \param _core_if Pointer of core_if structure
10705 + \param _params parameters to be set
10707 +void ifxusb_dev_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params)
10709 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
10711 + gusbcfg_data_t usbcfg ={.d32 = 0};
10712 + gahbcfg_data_t ahbcfg ={.d32 = 0};
10713 + dcfg_data_t dcfg ={.d32 = 0};
10714 + grstctl_t resetctl ={.d32 = 0};
10715 + gotgctl_data_t gotgctl ={.d32 = 0};
10720 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
10721 + IFX_DEBUGPL(DBG_CILV, "%s(%p)\n",__func__,_core_if);
10723 + /* Copy Params */
10724 + _core_if->params.dma_burst_size = _params->dma_burst_size;
10725 + _core_if->params.speed = _params->speed;
10726 + if(_params->max_transfer_size < 2048 || _params->max_transfer_size > ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1) )
10727 + _core_if->params.max_transfer_size = ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1);
10729 + _core_if->params.max_transfer_size = _params->max_transfer_size;
10731 + if(_params->max_packet_count < 16 || _params->max_packet_count > ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1) )
10732 + _core_if->params.max_packet_count= ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
10734 + _core_if->params.max_packet_count= _params->max_packet_count;
10735 + _core_if->params.phy_utmi_width = _params->phy_utmi_width;
10736 + _core_if->params.turn_around_time_hs = _params->turn_around_time_hs;
10737 + _core_if->params.turn_around_time_fs = _params->turn_around_time_fs;
10738 + _core_if->params.timeout_cal_hs = _params->timeout_cal_hs;
10739 + _core_if->params.timeout_cal_fs = _params->timeout_cal_fs;
10741 + #ifdef __DED_FIFO__
10742 + _core_if->params.thr_ctl = _params->thr_ctl;
10743 + _core_if->params.tx_thr_length = _params->tx_thr_length;
10744 + _core_if->params.rx_thr_length = _params->rx_thr_length;
10747 + /* Reset the Controller */
10750 + while(ifxusb_core_soft_reset( _core_if ))
10751 + ifxusb_hard_reset(_core_if);
10752 + } while (ifxusb_is_host_mode(_core_if));
10754 + usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg);
10756 + #if defined(__DED_FIFO__)
10757 + usbcfg.b.ForceDevMode = 1;
10758 + usbcfg.b.ForceHstMode = 0;
10761 + usbcfg.b.term_sel_dl_pulse = 0;
10762 + ifxusb_wreg (&global_regs->gusbcfg, usbcfg.d32);
10764 + /* This programming sequence needs to happen in FS mode before any other
10765 + * programming occurs */
10766 + /* High speed PHY. */
10767 + if (!_core_if->phy_init_done)
10769 + _core_if->phy_init_done = 1;
10770 + /* HS PHY parameters. These parameters are preserved
10771 + * during soft reset so only program the first time. Do
10772 + * a soft reset immediately after setting phyif. */
10773 + usbcfg.b.ulpi_utmi_sel = 0; //UTMI+
10774 + usbcfg.b.phyif = ( _core_if->params.phy_utmi_width == 16)?1:0;
10775 + ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32);
10776 + /* Reset after setting the PHY parameters */
10777 + ifxusb_core_soft_reset( _core_if );
10780 + /* Program the GAHBCFG Register.*/
10781 + switch (_core_if->params.dma_burst_size)
10784 + ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE;
10787 + ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR;
10790 + ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4;
10793 + ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8;
10796 + ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16;
10799 + ahbcfg.b.dmaenable = 1;
10800 + ifxusb_wreg(&global_regs->gahbcfg, ahbcfg.d32);
10802 + /* Program the GUSBCFG register. */
10803 + usbcfg.d32 = ifxusb_rreg( &global_regs->gusbcfg );
10804 + usbcfg.b.hnpcap = 0;
10805 + usbcfg.b.srpcap = 0;
10806 + ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32);
10808 + /* Restart the Phy Clock */
10809 + ifxusb_wreg(_core_if->pcgcctl, 0);
10811 + /* Device configuration register */
10812 + ifxusb_dev_init_spd(_core_if);
10813 + dcfg.d32 = ifxusb_rreg( &_core_if->dev_global_regs->dcfg);
10814 + dcfg.b.perfrint = IFXUSB_DCFG_FRAME_INTERVAL_80;
10815 + #if defined(__DED_FIFO__)
10816 + #if defined(__DESC_DMA__)
10817 + dcfg.b.descdma = 1;
10819 + dcfg.b.descdma = 0;
10823 + ifxusb_wreg( &_core_if->dev_global_regs->dcfg, dcfg.d32 );
10825 + /* Configure data FIFO sizes */
10826 + _core_if->params.data_fifo_size = _core_if->hwcfg3.b.dfifo_depth;
10827 + _core_if->params.rx_fifo_size = ifxusb_rreg(&global_regs->grxfsiz);
10828 + IFX_DEBUGPL(DBG_CIL, "Initial: FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size);
10829 + IFX_DEBUGPL(DBG_CIL, " Rx FIFO Size=0x%06X\n", _core_if->params.rx_fifo_size);
10831 + _core_if->params.tx_fifo_size[0]= ifxusb_rreg(&global_regs->gnptxfsiz) >> 16;
10833 + #ifdef __DED_FIFO__
10834 + for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++)
10835 + _core_if->params.tx_fifo_size[i] =
10836 + ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i-1]) >> 16;
10838 + for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
10839 + _core_if->params.tx_fifo_size[i+1] =
10840 + ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
10844 + #ifdef __DED_FIFO__
10845 + for (i=0; i <= _core_if->hwcfg4.b.num_in_eps; i++)
10846 + IFX_DEBUGPL(DBG_CIL, " Tx[%02d] FIFO Size=0x%06X\n",i, _core_if->params.tx_fifo_size[i]);
10848 + IFX_DEBUGPL(DBG_CIL, " NPTx FIFO Size=0x%06X\n", _core_if->params.tx_fifo_size[0]);
10849 + for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
10850 + IFX_DEBUGPL(DBG_CIL, " PTx[%02d] FIFO Size=0x%06X\n",i, _core_if->params.tx_fifo_size[i+1]);
10855 + fifosize_data_t txfifosize;
10856 + if(_params->data_fifo_size >=0 && _params->data_fifo_size < _core_if->params.data_fifo_size)
10857 + _core_if->params.data_fifo_size = _params->data_fifo_size;
10860 + if(_params->rx_fifo_size >=0 && _params->rx_fifo_size < _core_if->params.rx_fifo_size)
10861 + _core_if->params.rx_fifo_size = _params->rx_fifo_size;
10862 + if(_core_if->params.data_fifo_size < _core_if->params.rx_fifo_size)
10863 + _core_if->params.rx_fifo_size = _core_if->params.data_fifo_size;
10864 + ifxusb_wreg( &global_regs->grxfsiz, _core_if->params.rx_fifo_size);
10866 + for (i=0; i < MAX_EPS_CHANNELS; i++)
10867 + if(_params->tx_fifo_size[i] >=0 && _params->tx_fifo_size[i] < _core_if->params.tx_fifo_size[i])
10868 + _core_if->params.tx_fifo_size[i] = _params->tx_fifo_size[i];
10870 + txfifosize.b.startaddr = _core_if->params.rx_fifo_size;
10871 + #ifdef __DED_FIFO__
10872 + if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[0] > _core_if->params.data_fifo_size)
10873 + _core_if->params.tx_fifo_size[0]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
10874 + txfifosize.b.depth=_core_if->params.tx_fifo_size[0];
10875 + ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32);
10876 + txfifosize.b.startaddr += _core_if->params.tx_fifo_size[0];
10877 + for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++)
10879 + if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[i] > _core_if->params.data_fifo_size)
10880 + _core_if->params.tx_fifo_size[i]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
10881 + txfifosize.b.depth=_core_if->params.tx_fifo_size[i];
10882 + ifxusb_wreg( &global_regs->dptxfsiz_dieptxf[i-1], txfifosize.d32);
10883 + txfifosize.b.startaddr += _core_if->params.tx_fifo_size[i];
10886 + if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[0] > _core_if->params.data_fifo_size)
10887 + _core_if->params.tx_fifo_size[0]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
10888 + txfifosize.b.depth=_core_if->params.tx_fifo_size[0];
10889 + ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32);
10890 + txfifosize.b.startaddr += _core_if->params.tx_fifo_size[0];
10891 + for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
10893 + if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[i+1] > _core_if->params.data_fifo_size)
10894 + _core_if->params.tx_fifo_size[i+1]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
10895 + //txfifosize.b.depth=_core_if->params.tx_fifo_size[i+1];
10896 + ifxusb_wreg( &global_regs->dptxfsiz_dieptxf[i], txfifosize.d32);
10897 + txfifosize.b.startaddr += _core_if->params.tx_fifo_size[i+1];
10904 + fifosize_data_t fifosize;
10905 + IFX_DEBUGPL(DBG_CIL, "Result : FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size);
10907 + IFX_DEBUGPL(DBG_CIL, " Rx FIFO =0x%06X Sz=0x%06X\n", 0,ifxusb_rreg(&global_regs->grxfsiz));
10908 + #ifdef __DED_FIFO__
10909 + fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz);
10910 + IFX_DEBUGPL(DBG_CIL, " Tx[00] FIFO =0x%06X Sz=0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
10911 + for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++)
10913 + fifosize.d32=ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i-1]);
10914 + IFX_DEBUGPL(DBG_CIL, " Tx[%02d] FIFO 0x%06X Sz=0x%06X\n",i, fifosize.b.startaddr,fifosize.b.depth);
10917 + fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz);
10918 + IFX_DEBUGPL(DBG_CIL, " NPTx FIFO =0x%06X Sz=0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
10919 + for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
10921 + fifosize.d32=ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i]);
10922 + IFX_DEBUGPL(DBG_CIL, " PTx[%02d] FIFO 0x%06X Sz=0x%06X\n",i, fifosize.b.startaddr,fifosize.b.depth);
10928 + /* Clear Host Set HNP Enable in the OTG Control Register */
10929 + gotgctl.b.hstsethnpen = 1;
10930 + ifxusb_mreg( &global_regs->gotgctl, gotgctl.d32, 0);
10932 + /* Flush the FIFOs */
10933 + ifxusb_flush_tx_fifo(_core_if, 0x10); /* all Tx FIFOs */
10934 + ifxusb_flush_rx_fifo(_core_if);
10936 + /* Flush the Learning Queue. */
10937 + resetctl.b.intknqflsh = 1;
10938 + ifxusb_wreg( &global_regs->grstctl, resetctl.d32);
10940 + /* Clear all pending Device Interrupts */
10941 + ifxusb_wreg( &_core_if->dev_global_regs->diepmsk , 0 );
10942 + ifxusb_wreg( &_core_if->dev_global_regs->doepmsk , 0 );
10943 + ifxusb_wreg( &_core_if->dev_global_regs->daint , 0xFFFFFFFF );
10944 + ifxusb_wreg( &_core_if->dev_global_regs->daintmsk, 0 );
10946 + dir=_core_if->hwcfg1.d32;
10947 + for (i=0; i <= _core_if->hwcfg2.b.num_dev_ep ; i++,dir>>=2)
10949 + depctl_data_t depctl;
10950 + if((dir&0x03)==0 || (dir&0x03) ==1)
10952 + depctl.d32 = ifxusb_rreg(&_core_if->in_ep_regs[i]->diepctl);
10953 + if (depctl.b.epena)
10956 + depctl.b.epdis = 1;
10957 + depctl.b.snak = 1;
10961 + ifxusb_wreg( &_core_if->in_ep_regs[i]->diepctl, depctl.d32);
10962 + #ifndef __DESC_DMA__
10963 + ifxusb_wreg( &_core_if->in_ep_regs[i]->dieptsiz, 0);
10965 + ifxusb_wreg( &_core_if->in_ep_regs[i]->diepdma, 0);
10966 + ifxusb_wreg( &_core_if->in_ep_regs[i]->diepint, 0xFF);
10969 + if((dir&0x03)==0 || (dir&0x03) ==2)
10971 + depctl.d32 = ifxusb_rreg(&_core_if->out_ep_regs[i]->doepctl);
10972 + if (depctl.b.epena)
10975 + depctl.b.epdis = 1;
10976 + depctl.b.snak = 1;
10980 + ifxusb_wreg( &_core_if->out_ep_regs[i]->doepctl, depctl.d32);
10981 + #ifndef __DESC_DMA__
10982 + ifxusb_wreg( &_core_if->out_ep_regs[i]->doeptsiz, 0);
10984 + ifxusb_wreg( &_core_if->out_ep_regs[i]->doepdma, 0);
10985 + ifxusb_wreg( &_core_if->out_ep_regs[i]->doepint, 0xFF);
10990 diff --git a/drivers/usb/ifxhcd/ifxusb_cif_h.c b/drivers/usb/ifxhcd/ifxusb_cif_h.c
10991 new file mode 100644
10992 index 0000000..0f47ecd
10994 +++ b/drivers/usb/ifxhcd/ifxusb_cif_h.c
10996 +/*****************************************************************************
10997 + ** FILE NAME : ifxusb_cif_h.c
10998 + ** PROJECT : IFX USB sub-system V3
10999 + ** MODULES : IFX USB sub-system Host and Device driver
11000 + ** SRC VERSION : 1.0
11001 + ** DATE : 1/Jan/2009
11002 + ** AUTHOR : Chen, Howard
11003 + ** DESCRIPTION : The Core Interface provides basic services for accessing and
11004 + ** managing the IFX USB hardware. These services are used by the
11005 + ** Host Controller Driver only.
11006 + *****************************************************************************/
11009 + \file ifxusb_cif_h.c
11010 + \ingroup IFXUSB_DRIVER_V3
11011 + \brief This file contains the interface to the IFX USB Core.
11013 +#include <linux/version.h>
11014 +#include "ifxusb_version.h"
11016 +#include <asm/byteorder.h>
11017 +#include <asm/unaligned.h>
11020 + #include <linux/jiffies.h>
11022 +#include <linux/platform_device.h>
11023 +#include <linux/kernel.h>
11024 +#include <linux/ioport.h>
11025 +#if defined(__UEIP__)
11026 +// #include <asm/ifx/ifx_board.h>
11029 +//#include <asm/ifx/ifx_gpio.h>
11030 +#if defined(__UEIP__)
11031 +// #include <asm/ifx/ifx_led.h>
11034 +#include "ifxusb_plat.h"
11035 +#include "ifxusb_regs.h"
11036 +#include "ifxusb_cif.h"
11038 +#include "ifxhcd.h"
11040 +#if !defined(__UEIP__)
11041 + #undef __USING_LED_AS_GPIO__
11046 + \brief This function enables the Host mode interrupts.
11047 + \param _core_if Pointer of core_if structure
11049 +void ifxusb_host_enable_interrupts(ifxusb_core_if_t *_core_if)
11051 + gint_data_t intr_mask ={ .d32 = 0};
11052 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
11054 + IFX_DEBUGPL(DBG_CIL, "%s()\n", __func__);
11056 + /* Clear any pending OTG Interrupts */
11057 + ifxusb_wreg( &global_regs->gotgint, 0xFFFFFFFF);
11059 + /* Clear any pending interrupts */
11060 + ifxusb_wreg( &global_regs->gintsts, 0xFFFFFFFF);
11062 + /* Enable the interrupts in the GINTMSK.*/
11064 + /* Common interrupts */
11065 + intr_mask.b.modemismatch = 1;
11066 + intr_mask.b.conidstschng = 1;
11067 + intr_mask.b.wkupintr = 1;
11068 + intr_mask.b.disconnect = 1;
11069 + intr_mask.b.usbsuspend = 1;
11071 + /* Host interrupts */
11072 + intr_mask.b.sofintr = 1;
11073 + intr_mask.b.portintr = 1;
11074 + intr_mask.b.hcintr = 1;
11076 + ifxusb_mreg( &global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
11077 + IFX_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__, ifxusb_rreg( &global_regs->gintmsk));
11081 + \brief This function disables the Host mode interrupts.
11082 + \param _core_if Pointer of core_if structure
11084 +void ifxusb_host_disable_interrupts(ifxusb_core_if_t *_core_if)
11086 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
11088 + IFX_DEBUGPL(DBG_CILV, "%s()\n", __func__);
11091 + ifxusb_wreg( &global_regs->gintmsk, 0);
11093 + /* Common interrupts */
11095 + gint_data_t intr_mask ={.d32 = 0};
11096 + intr_mask.b.modemismatch = 1;
11097 + intr_mask.b.rxstsqlvl = 1;
11098 + intr_mask.b.conidstschng = 1;
11099 + intr_mask.b.wkupintr = 1;
11100 + intr_mask.b.disconnect = 1;
11101 + intr_mask.b.usbsuspend = 1;
11103 + /* Host interrupts */
11104 + intr_mask.b.sofintr = 1;
11105 + intr_mask.b.portintr = 1;
11106 + intr_mask.b.hcintr = 1;
11107 + intr_mask.b.ptxfempty = 1;
11108 + intr_mask.b.nptxfempty = 1;
11109 + ifxusb_mreg(&global_regs->gintmsk, intr_mask.d32, 0);
11115 + \brief This function initializes the IFXUSB controller registers for Host mode.
11116 + This function flushes the Tx and Rx FIFOs and it flushes any entries in the
11118 + \param _core_if Pointer of core_if structure
11119 + \param _params parameters to be set
11121 +void ifxusb_host_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params)
11123 + ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
11125 + gusbcfg_data_t usbcfg ={.d32 = 0};
11126 + gahbcfg_data_t ahbcfg ={.d32 = 0};
11127 + gotgctl_data_t gotgctl ={.d32 = 0};
11131 + IFX_DEBUGPL(DBG_CILV, "%s(%p)\n",__func__,_core_if);
11133 + /* Copy Params */
11135 + _core_if->params.dma_burst_size = _params->dma_burst_size;
11136 + _core_if->params.speed = _params->speed;
11137 + _core_if->params.max_transfer_size = _params->max_transfer_size;
11138 + _core_if->params.max_packet_count = _params->max_packet_count;
11139 + _core_if->params.phy_utmi_width = _params->phy_utmi_width;
11140 + _core_if->params.turn_around_time_hs = _params->turn_around_time_hs;
11141 + _core_if->params.turn_around_time_fs = _params->turn_around_time_fs;
11142 + _core_if->params.timeout_cal_hs = _params->timeout_cal_hs;
11143 + _core_if->params.timeout_cal_fs = _params->timeout_cal_fs;
11145 + /* Reset the Controller */
11148 + while(ifxusb_core_soft_reset( _core_if ))
11149 + ifxusb_hard_reset(_core_if);
11150 + } while (ifxusb_is_device_mode(_core_if));
11152 + usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg);
11153 +// usbcfg.b.ulpi_ext_vbus_drv = 1;
11154 + usbcfg.b.term_sel_dl_pulse = 0;
11155 + ifxusb_wreg (&global_regs->gusbcfg, usbcfg.d32);
11157 + /* This programming sequence needs to happen in FS mode before any other
11158 + * programming occurs */
11159 + /* High speed PHY. */
11160 + if (!_core_if->phy_init_done)
11162 + _core_if->phy_init_done = 1;
11163 + /* HS PHY parameters. These parameters are preserved
11164 + * during soft reset so only program the first time. Do
11165 + * a soft reset immediately after setting phyif. */
11166 + usbcfg.b.ulpi_utmi_sel = 0; //UTMI+
11167 + usbcfg.b.phyif = ( _core_if->params.phy_utmi_width == 16)?1:0;
11168 + ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32);
11169 + /* Reset after setting the PHY parameters */
11170 + ifxusb_core_soft_reset( _core_if );
11173 + usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg);
11174 +// usbcfg.b.ulpi_fsls = 0;
11175 +// usbcfg.b.ulpi_clk_sus_m = 0;
11176 + ifxusb_wreg(&global_regs->gusbcfg, usbcfg.d32);
11178 + /* Program the GAHBCFG Register.*/
11179 + switch (_core_if->params.dma_burst_size)
11182 + ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE;
11185 + ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR;
11188 + ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4;
11191 + ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8;
11194 + ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16;
11197 + ahbcfg.b.dmaenable = 1;
11198 + ifxusb_wreg(&global_regs->gahbcfg, ahbcfg.d32);
11200 + /* Program the GUSBCFG register. */
11201 + usbcfg.d32 = ifxusb_rreg( &global_regs->gusbcfg );
11202 + usbcfg.b.hnpcap = 0;
11203 + usbcfg.b.srpcap = 0;
11204 + ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32);
11206 + /* Restart the Phy Clock */
11207 + ifxusb_wreg(_core_if->pcgcctl, 0);
11209 + /* Initialize Host Configuration Register */
11211 + hcfg_data_t hcfg;
11212 + hcfg.d32 = ifxusb_rreg(&_core_if->host_global_regs->hcfg);
11213 + hcfg.b.fslspclksel = IFXUSB_HCFG_30_60_MHZ;
11214 + if (_params->speed == IFXUSB_PARAM_SPEED_FULL)
11215 + hcfg.b.fslssupp = 1;
11216 + ifxusb_wreg(&_core_if->host_global_regs->hcfg, hcfg.d32);
11219 + _core_if->params.host_channels=(_core_if->hwcfg2.b.num_host_chan + 1);
11221 + if(_params->host_channels>0 && _params->host_channels < _core_if->params.host_channels)
11222 + _core_if->params.host_channels = _params->host_channels;
11224 + /* Configure data FIFO sizes */
11225 + _core_if->params.data_fifo_size = _core_if->hwcfg3.b.dfifo_depth;
11226 + _core_if->params.rx_fifo_size = ifxusb_rreg(&global_regs->grxfsiz);
11227 + _core_if->params.nperio_tx_fifo_size= ifxusb_rreg(&global_regs->gnptxfsiz) >> 16;
11228 + _core_if->params.perio_tx_fifo_size = ifxusb_rreg(&global_regs->hptxfsiz) >> 16;
11229 + IFX_DEBUGPL(DBG_CIL, "Initial: FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size);
11230 + IFX_DEBUGPL(DBG_CIL, " Rx FIFO Size=0x%06X\n", _core_if->params.rx_fifo_size);
11231 + IFX_DEBUGPL(DBG_CIL, " NPTx FIFO Size=0x%06X\n", _core_if->params.nperio_tx_fifo_size);
11232 + IFX_DEBUGPL(DBG_CIL, " PTx FIFO Size=0x%06X\n", _core_if->params.perio_tx_fifo_size);
11235 + fifosize_data_t txfifosize;
11236 + if(_params->data_fifo_size >=0 && _params->data_fifo_size < _core_if->params.data_fifo_size)
11237 + _core_if->params.data_fifo_size = _params->data_fifo_size;
11239 + if( _params->rx_fifo_size >= 0 && _params->rx_fifo_size < _core_if->params.rx_fifo_size)
11240 + _core_if->params.rx_fifo_size = _params->rx_fifo_size;
11241 + if( _params->nperio_tx_fifo_size >=0 && _params->nperio_tx_fifo_size < _core_if->params.nperio_tx_fifo_size)
11242 + _core_if->params.nperio_tx_fifo_size = _params->nperio_tx_fifo_size;
11243 + if( _params->perio_tx_fifo_size >=0 && _params->perio_tx_fifo_size < _core_if->params.perio_tx_fifo_size)
11244 + _core_if->params.perio_tx_fifo_size = _params->perio_tx_fifo_size;
11246 + if(_core_if->params.data_fifo_size < _core_if->params.rx_fifo_size)
11247 + _core_if->params.rx_fifo_size = _core_if->params.data_fifo_size;
11248 + ifxusb_wreg( &global_regs->grxfsiz, _core_if->params.rx_fifo_size);
11249 + txfifosize.b.startaddr = _core_if->params.rx_fifo_size;
11251 + if(txfifosize.b.startaddr + _core_if->params.nperio_tx_fifo_size > _core_if->params.data_fifo_size)
11252 + _core_if->params.nperio_tx_fifo_size = _core_if->params.data_fifo_size - txfifosize.b.startaddr;
11253 + txfifosize.b.depth=_core_if->params.nperio_tx_fifo_size;
11254 + ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32);
11255 + txfifosize.b.startaddr += _core_if->params.nperio_tx_fifo_size;
11257 + if(txfifosize.b.startaddr + _core_if->params.perio_tx_fifo_size > _core_if->params.data_fifo_size)
11258 + _core_if->params.perio_tx_fifo_size = _core_if->params.data_fifo_size - txfifosize.b.startaddr;
11259 + txfifosize.b.depth=_core_if->params.perio_tx_fifo_size;
11260 + ifxusb_wreg( &global_regs->hptxfsiz, txfifosize.d32);
11261 + txfifosize.b.startaddr += _core_if->params.perio_tx_fifo_size;
11266 + fifosize_data_t fifosize;
11267 + IFX_DEBUGPL(DBG_CIL, "Result : FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size);
11269 + fifosize.d32=ifxusb_rreg(&global_regs->grxfsiz);
11270 + IFX_DEBUGPL(DBG_CIL, " Rx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
11271 + fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz);
11272 + IFX_DEBUGPL(DBG_CIL, " NPTx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
11273 + fifosize.d32=ifxusb_rreg(&global_regs->hptxfsiz);
11274 + IFX_DEBUGPL(DBG_CIL, " PTx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
11278 + /* Clear Host Set HNP Enable in the OTG Control Register */
11279 + gotgctl.b.hstsethnpen = 1;
11280 + ifxusb_mreg( &global_regs->gotgctl, gotgctl.d32, 0);
11282 + /* Flush the FIFOs */
11283 + ifxusb_flush_tx_fifo(_core_if, 0x10); /* all Tx FIFOs */
11284 + ifxusb_flush_rx_fifo(_core_if);
11286 + for (i = 0; i < _core_if->hwcfg2.b.num_host_chan + 1; i++)
11288 + hcchar_data_t hcchar;
11289 + hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar);
11290 + hcchar.b.chen = 0;
11291 + hcchar.b.chdis = 1;
11292 + hcchar.b.epdir = 0;
11293 + ifxusb_wreg(&_core_if->hc_regs[i]->hcchar, hcchar.d32);
11295 + /* Halt all channels to put them into a known state. */
11296 + for (i = 0; i < _core_if->hwcfg2.b.num_host_chan + 1; i++)
11298 + hcchar_data_t hcchar;
11301 + hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar);
11302 + hcchar.b.chen = 1;
11303 + hcchar.b.chdis = 1;
11304 + hcchar.b.epdir = 0;
11305 + ifxusb_wreg(&_core_if->hc_regs[i]->hcchar, hcchar.d32);
11307 + IFX_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
11309 + hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar);
11310 + if (++count > 1000)
11312 + IFX_ERROR("%s: Unable to clear halt on channel %d\n", __func__, i);
11315 + } while (hcchar.b.chen);
11319 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11321 +#if defined(__UEIP__)
11322 + #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
11323 + int ifxusb_vbus_status =-1;
11326 + #if defined(IFX_GPIO_USB_VBUS1) || defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
11327 + int ifxusb_vbus1_status =-1;
11330 + #if defined(IFX_GPIO_USB_VBUS2) || defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
11331 + int ifxusb_vbus2_status =-1;
11334 + #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
11335 + static void *g_usb_vbus_trigger = NULL;
11337 + #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
11338 + static void *g_usb_vbus1_trigger = NULL;
11340 + #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
11341 + static void *g_usb_vbus2_trigger = NULL;
11344 + #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
11345 + int ifxusb_vbus_gpio_inited=0;
11348 +#else //defined(__UEIP__)
11349 + int ifxusb_vbus_gpio_inited=0;
11352 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11354 +void ifxusb_vbus_init(ifxusb_core_if_t *_core_if)
11356 + #if defined(__UEIP__)
11357 + #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
11358 + if ( !g_usb_vbus_trigger )
11360 + ifx_led_trigger_register("USB_VBUS", &g_usb_vbus_trigger);
11361 + if ( g_usb_vbus_trigger != NULL )
11363 + struct ifx_led_trigger_attrib attrib = {0};
11364 + attrib.delay_on = 0;
11365 + attrib.delay_off = 0;
11366 + attrib.timeout = 0;
11367 + attrib.def_value = 0;
11368 + attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE;
11369 + IFX_DEBUGP("Reg USB power!!\n");
11370 + ifx_led_trigger_set_attrib(g_usb_vbus_trigger, &attrib);
11371 + ifxusb_vbus_status =0;
11375 + #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
11376 + if(_core_if->core_no==0 && !g_usb_vbus1_trigger )
11378 + ifx_led_trigger_register("USB_VBUS1", &g_usb_vbus1_trigger);
11379 + if ( g_usb_vbus1_trigger != NULL )
11381 + struct ifx_led_trigger_attrib attrib = {0};
11382 + attrib.delay_on = 0;
11383 + attrib.delay_off = 0;
11384 + attrib.timeout = 0;
11385 + attrib.def_value = 0;
11386 + attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE;
11387 + IFX_DEBUGP("Reg USB1 power!!\n");
11388 + ifx_led_trigger_set_attrib(g_usb_vbus1_trigger, &attrib);
11389 + ifxusb_vbus1_status =0;
11393 + #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
11394 + if(_core_if->core_no==1 && !g_usb_vbus2_trigger )
11396 + ifx_led_trigger_register("USB_VBUS2", &g_usb_vbus2_trigger);
11397 + if ( g_usb_vbus2_trigger != NULL )
11399 + struct ifx_led_trigger_attrib attrib = {0};
11400 + attrib.delay_on = 0;
11401 + attrib.delay_off = 0;
11402 + attrib.timeout = 0;
11403 + attrib.def_value = 0;
11404 + attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE;
11405 + IFX_DEBUGP("Reg USB2 power!!\n");
11406 + ifx_led_trigger_set_attrib(g_usb_vbus2_trigger, &attrib);
11407 + ifxusb_vbus2_status =0;
11412 + #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
11413 + /* == 20100712 AVM/WK use gpio_inited as bitmask == */
11414 + if(ifxusb_vbus_gpio_inited == 0)
11416 + if(!ifx_gpio_register(IFX_GPIO_MODULE_USB))
11418 + IFX_DEBUGP("Register USB VBus through GPIO OK!!\n");
11419 + #ifdef IFX_GPIO_USB_VBUS
11420 + ifxusb_vbus_status =0;
11421 + #endif //IFX_GPIO_USB_VBUS
11422 + #ifdef IFX_GPIO_USB_VBUS1
11423 + ifxusb_vbus1_status=0;
11424 + #endif //IFX_GPIO_USB_VBUS1
11425 + #ifdef IFX_GPIO_USB_VBUS2
11426 + ifxusb_vbus2_status=0;
11427 + #endif //IFX_GPIO_USB_VBUS2
11428 + ifxusb_vbus_gpio_inited|= (1<<_core_if->core_no);
11431 + IFX_PRINT("Register USB VBus Failed!!\n");
11433 + ifxusb_vbus_gpio_inited|= (1<<_core_if->core_no);
11435 + #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
11436 + #endif //defined(__UEIP__)
11439 +void ifxusb_vbus_free(ifxusb_core_if_t *_core_if)
11441 + #if defined(__UEIP__)
11442 + #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
11443 + if ( g_usb_vbus_trigger )
11445 + ifx_led_trigger_deregister(g_usb_vbus_trigger);
11446 + g_usb_vbus_trigger = NULL;
11447 + ifxusb_vbus_status =-1;
11450 + #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
11451 + if(_core_if->core_no==0 && g_usb_vbus1_trigger )
11453 + ifx_led_trigger_deregister(g_usb_vbus1_trigger);
11454 + g_usb_vbus1_trigger = NULL;
11455 + ifxusb_vbus1_status =-1;
11458 + #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
11459 + if(_core_if->core_no==1 && g_usb_vbus2_trigger )
11461 + ifx_led_trigger_deregister(g_usb_vbus2_trigger);
11462 + g_usb_vbus2_trigger = NULL;
11463 + ifxusb_vbus2_status =-1;
11467 + #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
11468 + /* == 20100712 AVM/WK use gpio_inited as bitmask == */
11469 + if((ifxusb_vbus_gpio_inited & (1<<_core_if->core_no)) == ifxusb_vbus_gpio_inited)
11471 + ifx_gpio_deregister(IFX_GPIO_MODULE_USB);
11472 + #ifdef IFX_GPIO_USB_VBUS
11473 + ifxusb_vbus_status =-1;
11474 + #endif //IFX_GPIO_USB_VBUS
11475 + #ifdef IFX_GPIO_USB_VBUS1
11476 + ifxusb_vbus1_status=-1;
11477 + #endif //IFX_GPIO_USB_VBUS1
11478 + #ifdef IFX_GPIO_USB_VBUS2
11479 + ifxusb_vbus2_status=-1;
11480 + #endif //IFX_GPIO_USB_VBUS2
11482 + ifxusb_vbus_gpio_inited &= ~(1<<_core_if->core_no);
11483 + #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
11484 + #endif //defined(__UEIP__)
11489 + \brief Turn on the USB 5V VBus Power
11490 + \param _core_if Pointer of core_if structure
11492 +void ifxusb_vbus_on(ifxusb_core_if_t *_core_if)
11494 + IFX_DEBUGP("SENDING VBus POWER UP\n");
11495 + #if defined(__UEIP__)
11496 + #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
11497 + if ( g_usb_vbus_trigger && ifxusb_vbus_status==0)
11499 + ifx_led_trigger_activate(g_usb_vbus_trigger);
11500 + IFX_DEBUGP("Enable USB power!!\n");
11501 + ifxusb_vbus_status=1;
11504 + #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
11505 + if(_core_if->core_no==0 && g_usb_vbus1_trigger && ifxusb_vbus1_status==0)
11507 + ifx_led_trigger_activate(g_usb_vbus1_trigger);
11508 + IFX_DEBUGP("Enable USB1 power!!\n");
11509 + ifxusb_vbus1_status=1;
11512 + #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
11513 + if(_core_if->core_no==1 && g_usb_vbus2_trigger && ifxusb_vbus2_status==0)
11515 + ifx_led_trigger_activate(g_usb_vbus2_trigger);
11516 + IFX_DEBUGP("Enable USB2 power!!\n");
11517 + ifxusb_vbus2_status=1;
11521 + #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
11522 + if(ifxusb_vbus_gpio_inited)
11524 + #if defined(IFX_GPIO_USB_VBUS)
11525 + if(ifxusb_vbus_status==0)
11527 + ifx_gpio_output_set(IFX_GPIO_USB_VBUS,IFX_GPIO_MODULE_USB);
11528 + ifxusb_vbus_status=1;
11531 + #if defined(IFX_GPIO_USB_VBUS1)
11532 + if(_core_if->core_no==0 && ifxusb_vbus1_status==0)
11534 + ifx_gpio_output_set(IFX_GPIO_USB_VBUS1,IFX_GPIO_MODULE_USB);
11535 + ifxusb_vbus1_status=1;
11538 + #if defined(IFX_GPIO_USB_VBUS2)
11539 + if(_core_if->core_no==1 && ifxusb_vbus2_status==0)
11541 + ifx_gpio_output_set(IFX_GPIO_USB_VBUS2,IFX_GPIO_MODULE_USB);
11542 + ifxusb_vbus2_status=1;
11546 + #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
11548 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
11549 + ifxusb_vbus_status=1;
11550 + //usb_set_vbus_on();
11551 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
11552 + #if defined(__IS_AMAZON_SE__)
11553 + set_bit (4, (volatile unsigned long *)AMAZON_SE_GPIO_P0_OUT);
11554 + ifxusb_vbus_status=1;
11555 + #endif //defined(__IS_AMAZON_SE__)
11556 + #if defined(__IS_AR9__)
11557 + if(_core_if->core_no==0)
11559 + if (bsp_port_reserve_pin(1, 13, PORT_MODULE_USB) != 0)
11561 + IFX_PRINT("Can't enable USB1 5.5V power!!\n");
11564 + bsp_port_clear_altsel0(1, 13, PORT_MODULE_USB);
11565 + bsp_port_clear_altsel1(1, 13, PORT_MODULE_USB);
11566 + bsp_port_set_dir_out(1, 13, PORT_MODULE_USB);
11567 + bsp_port_set_pudsel(1, 13, PORT_MODULE_USB);
11568 + bsp_port_set_puden(1, 13, PORT_MODULE_USB);
11569 + bsp_port_set_output(1, 13, PORT_MODULE_USB);
11570 + IFX_DEBUGP("Enable USB1 power!!\n");
11571 + ifxusb_vbus1_status=1;
11575 + if (bsp_port_reserve_pin(3, 4, PORT_MODULE_USB) != 0)
11577 + IFX_PRINT("Can't enable USB2 5.5V power!!\n");
11580 + bsp_port_clear_altsel0(3, 4, PORT_MODULE_USB);
11581 + bsp_port_clear_altsel1(3, 4, PORT_MODULE_USB);
11582 + bsp_port_set_dir_out(3, 4, PORT_MODULE_USB);
11583 + bsp_port_set_pudsel(3, 4, PORT_MODULE_USB);
11584 + bsp_port_set_puden(3, 4, PORT_MODULE_USB);
11585 + bsp_port_set_output(3, 4, PORT_MODULE_USB);
11586 + IFX_DEBUGP("Enable USB2 power!!\n");
11587 + ifxusb_vbus2_status=1;
11589 + #endif //defined(__IS_AR9__)
11590 + #if defined(__IS_VR9__)
11591 + if(_core_if->core_no==0)
11593 + ifxusb_vbus1_status=1;
11597 + ifxusb_vbus2_status=1;
11599 + #endif //defined(__IS_VR9__)
11600 + #endif //defined(__UEIP__)
11605 + \brief Turn off the USB 5V VBus Power
11606 + \param _core_if Pointer of core_if structure
11608 +void ifxusb_vbus_off(ifxusb_core_if_t *_core_if)
11610 + IFX_DEBUGP("SENDING VBus POWER OFF\n");
11612 + #if defined(__UEIP__)
11613 + #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
11614 + if ( g_usb_vbus_trigger && ifxusb_vbus_status==1)
11616 + ifx_led_trigger_deactivate(g_usb_vbus_trigger);
11617 + IFX_DEBUGP("Disable USB power!!\n");
11618 + ifxusb_vbus_status=0;
11621 + #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
11622 + if(_core_if->core_no==0 && g_usb_vbus1_trigger && ifxusb_vbus1_status==1)
11624 + ifx_led_trigger_deactivate(g_usb_vbus1_trigger);
11625 + IFX_DEBUGP("Disable USB1 power!!\n");
11626 + ifxusb_vbus1_status=0;
11629 + #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
11630 + if(_core_if->core_no==1 && g_usb_vbus2_trigger && ifxusb_vbus2_status==1)
11632 + ifx_led_trigger_deactivate(g_usb_vbus2_trigger);
11633 + IFX_DEBUGP("Disable USB2 power!!\n");
11634 + ifxusb_vbus2_status=0;
11638 + #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
11639 + if(ifxusb_vbus_gpio_inited)
11641 + #if defined(IFX_GPIO_USB_VBUS)
11642 + if(ifxusb_vbus_status==1)
11644 + ifx_gpio_output_clear(IFX_GPIO_USB_VBUS,IFX_GPIO_MODULE_USB);
11645 + ifxusb_vbus_status=0;
11648 + #if defined(IFX_GPIO_USB_VBUS1)
11649 + if(_core_if->core_no==0 && ifxusb_vbus1_status==1)
11651 + ifx_gpio_output_clear(IFX_GPIO_USB_VBUS1,IFX_GPIO_MODULE_USB);
11652 + ifxusb_vbus1_status=0;
11655 + #if defined(IFX_GPIO_USB_VBUS2)
11656 + if(_core_if->core_no==1 && ifxusb_vbus2_status==1)
11658 + ifx_gpio_output_clear(IFX_GPIO_USB_VBUS2,IFX_GPIO_MODULE_USB);
11659 + ifxusb_vbus2_status=0;
11663 + #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
11665 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
11666 + ifxusb_vbus_status=0;
11667 + //usb_set_vbus_on();
11668 + #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
11669 + #if defined(__IS_AMAZON_SE__)
11670 + clear_bit (4, (volatile unsigned long *)AMAZON_SE_GPIO_P0_OUT);
11671 + ifxusb_vbus_status=0;
11672 + #endif //defined(__IS_AMAZON_SE__)
11673 + #if defined(__IS_AR9__)
11674 + if(_core_if->core_no==0)
11676 + if (bsp_port_reserve_pin(1, 13, PORT_MODULE_USB) != 0) {
11677 + IFX_PRINT("Can't Disable USB1 5.5V power!!\n");
11680 + bsp_port_clear_altsel0(1, 13, PORT_MODULE_USB);
11681 + bsp_port_clear_altsel1(1, 13, PORT_MODULE_USB);
11682 + bsp_port_set_dir_out(1, 13, PORT_MODULE_USB);
11683 + bsp_port_set_pudsel(1, 13, PORT_MODULE_USB);
11684 + bsp_port_set_puden(1, 13, PORT_MODULE_USB);
11685 + bsp_port_clear_output(1, 13, PORT_MODULE_USB);
11686 + IFX_DEBUGP("Disable USB1 power!!\n");
11687 + ifxusb_vbus1_status=0;
11691 + if (bsp_port_reserve_pin(3, 4, PORT_MODULE_USB) != 0) {
11692 + IFX_PRINT("Can't Disable USB2 5.5V power!!\n");
11695 + bsp_port_clear_altsel0(3, 4, PORT_MODULE_USB);
11696 + bsp_port_clear_altsel1(3, 4, PORT_MODULE_USB);
11697 + bsp_port_set_dir_out(3, 4, PORT_MODULE_USB);
11698 + bsp_port_set_pudsel(3, 4, PORT_MODULE_USB);
11699 + bsp_port_set_puden(3, 4, PORT_MODULE_USB);
11700 + bsp_port_clear_output(3, 4, PORT_MODULE_USB);
11701 + IFX_DEBUGP("Disable USB2 power!!\n");
11703 + ifxusb_vbus2_status=0;
11705 + #endif //defined(__IS_AR9__)
11706 + #if defined(__IS_VR9__)
11707 + if(_core_if->core_no==0)
11709 + ifxusb_vbus1_status=0;
11713 + ifxusb_vbus2_status=0;
11715 + #endif //defined(__IS_VR9__)
11716 + #endif //defined(__UEIP__)
11722 + \brief Read Current VBus status
11723 + \param _core_if Pointer of core_if structure
11725 +int ifxusb_vbus(ifxusb_core_if_t *_core_if)
11727 +#if defined(__UEIP__)
11728 + #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
11729 + return (ifxusb_vbus_status);
11732 + #if defined(IFX_GPIO_USB_VBUS1) || defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
11733 + if(_core_if->core_no==0)
11734 + return (ifxusb_vbus1_status);
11737 + #if defined(IFX_GPIO_USB_VBUS2) || defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
11738 + if(_core_if->core_no==1)
11739 + return (ifxusb_vbus2_status);
11741 +#else //defined(__UEIP__)
11746 +#if defined(__UEIP__)
11748 + #if defined(__IS_TWINPASS__)
11749 + #define ADSL_BASE 0x20000
11750 + #define CRI_BASE 0x31F00
11751 + #define CRI_CCR0 CRI_BASE + 0x00
11752 + #define CRI_CCR1 CRI_BASE + 0x01*4
11753 + #define CRI_CDC0 CRI_BASE + 0x02*4
11754 + #define CRI_CDC1 CRI_BASE + 0x03*4
11755 + #define CRI_RST CRI_BASE + 0x04*4
11756 + #define CRI_MASK0 CRI_BASE + 0x05*4
11757 + #define CRI_MASK1 CRI_BASE + 0x06*4
11758 + #define CRI_MASK2 CRI_BASE + 0x07*4
11759 + #define CRI_STATUS0 CRI_BASE + 0x08*4
11760 + #define CRI_STATUS1 CRI_BASE + 0x09*4
11761 + #define CRI_STATUS2 CRI_BASE + 0x0A*4
11762 + #define CRI_AMASK0 CRI_BASE + 0x0B*4
11763 + #define CRI_AMASK1 CRI_BASE + 0x0C*4
11764 + #define CRI_UPDCTL CRI_BASE + 0x0D*4
11765 + #define CRI_MADST CRI_BASE + 0x0E*4
11766 + // 0x0f is missing
11767 + #define CRI_EVENT0 CRI_BASE + 0x10*4
11768 + #define CRI_EVENT1 CRI_BASE + 0x11*4
11769 + #define CRI_EVENT2 CRI_BASE + 0x12*4
11771 + #define IRI_I_ENABLE 0x32000
11772 + #define STY_SMODE 0x3c004
11773 + #define AFE_TCR_0 0x3c0dc
11774 + #define AFE_ADDR_ADDR 0x3c0e8
11775 + #define AFE_RDATA_ADDR 0x3c0ec
11776 + #define AFE_WDATA_ADDR 0x3c0f0
11777 + #define AFE_CONFIG 0x3c0f4
11778 + #define AFE_SERIAL_CFG 0x3c0fc
11780 + #define DFE_BASE_ADDR 0xBE116000
11781 + //#define DFE_BASE_ADDR 0x9E116000
11783 + #define MEI_FR_ARCINT_C (DFE_BASE_ADDR + 0x0000001C)
11784 + #define MEI_DBG_WADDR_C (DFE_BASE_ADDR + 0x00000024)
11785 + #define MEI_DBG_RADDR_C (DFE_BASE_ADDR + 0x00000028)
11786 + #define MEI_DBG_DATA_C (DFE_BASE_ADDR + 0x0000002C)
11787 + #define MEI_DBG_DECO_C (DFE_BASE_ADDR + 0x00000030)
11788 + #define MEI_DBG_MASTER_C (DFE_BASE_ADDR + 0x0000003C)
11790 + static void WriteARCmem(uint32_t addr, uint32_t data)
11792 + writel(1 ,(volatile uint32_t *)MEI_DBG_MASTER_C);
11793 + writel(1 ,(volatile uint32_t *)MEI_DBG_DECO_C );
11794 + writel(addr ,(volatile uint32_t *)MEI_DBG_WADDR_C );
11795 + writel(data ,(volatile uint32_t *)MEI_DBG_DATA_C );
11796 + while( (ifxusb_rreg((volatile uint32_t *)MEI_FR_ARCINT_C) & 0x20) != 0x20 ){};
11797 + writel(0 ,(volatile uint32_t *)MEI_DBG_MASTER_C);
11798 + IFX_DEBUGP("WriteARCmem %08x %08x\n",addr,data);
11801 + static uint32_t ReadARCmem(uint32_t addr)
11804 + writel(1 ,(volatile uint32_t *)MEI_DBG_MASTER_C);
11805 + writel(1 ,(volatile uint32_t *)MEI_DBG_DECO_C );
11806 + writel(addr ,(volatile uint32_t *)MEI_DBG_RADDR_C );
11807 + while( (ifxusb_rreg((volatile uint32_t *)MEI_FR_ARCINT_C) & 0x20) != 0x20 ){};
11808 + data = ifxusb_rreg((volatile uint32_t *)MEI_DBG_DATA_C );
11809 + writel(0 ,(volatile uint32_t *)MEI_DBG_MASTER_C);
11810 + IFX_DEBUGP("ReadARCmem %08x %08x\n",addr,data);
11814 + void ifxusb_enable_afe_oc(void)
11816 + /* Start the clock */
11817 + WriteARCmem(CRI_UPDCTL ,0x00000008);
11818 + WriteARCmem(CRI_CCR0 ,0x00000014);
11819 + WriteARCmem(CRI_CCR1 ,0x00000500);
11820 + WriteARCmem(AFE_CONFIG ,0x000001c8);
11821 + WriteARCmem(AFE_SERIAL_CFG,0x00000016); // (DANUBE_PCI_CFG_BASE+(1<<addrline))AFE serial interface clock & data latch edge
11822 + WriteARCmem(AFE_TCR_0 ,0x00000002);
11823 + //Take afe out of reset
11824 + WriteARCmem(AFE_CONFIG ,0x000000c0);
11825 + WriteARCmem(IRI_I_ENABLE ,0x00000101);
11826 + WriteARCmem(STY_SMODE ,0x00001980);
11828 + ReadARCmem(CRI_UPDCTL );
11829 + ReadARCmem(CRI_CCR0 );
11830 + ReadARCmem(CRI_CCR1 );
11831 + ReadARCmem(AFE_CONFIG );
11832 + ReadARCmem(AFE_SERIAL_CFG); // (DANUBE_PCI_CFG_BASE+(1<<addrline))AFE serial interface clock & data latch edge
11833 + ReadARCmem(AFE_TCR_0 );
11834 + ReadARCmem(AFE_CONFIG );
11835 + ReadARCmem(IRI_I_ENABLE );
11836 + ReadARCmem(STY_SMODE );
11838 + #endif //defined(__IS_TWINPASS__)
11839 +#endif //defined(__UEIP__)
11842 diff --git a/drivers/usb/ifxhcd/ifxusb_ctl.c b/drivers/usb/ifxhcd/ifxusb_ctl.c
11843 new file mode 100644
11844 index 0000000..ade8e13
11846 +++ b/drivers/usb/ifxhcd/ifxusb_ctl.c
11848 +/*****************************************************************************
11849 + ** FILE NAME : ifxusb_ctl.c
11850 + ** PROJECT : IFX USB sub-system V3
11851 + ** MODULES : IFX USB sub-system Host and Device driver
11852 + ** SRC VERSION : 1.0
11853 + ** DATE : 1/Jan/2009
11854 + ** AUTHOR : Chen, Howard
11855 + ** DESCRIPTION : Implementing the procfs and sysfs for IFX USB driver
11856 + *****************************************************************************/
11858 +/*! \file ifxusb_ctl.c
11859 + \ingroup IFXUSB_DRIVER_V3
11860 + \brief Implementing the procfs and sysfs for IFX USB driver
11863 +#include <linux/version.h>
11864 +#include "ifxusb_version.h"
11867 +#include <linux/proc_fs.h>
11868 +#include <asm/byteorder.h>
11869 +#include <asm/unaligned.h>
11870 +#include <asm/uaccess.h>
11872 +#include "ifxusb_plat.h"
11873 +#include "ifxusb_regs.h"
11874 +#include "ifxusb_cif.h"
11876 +#ifdef __IS_DEVICE__
11877 + #include "ifxpcd.h"
11880 +#ifdef __IS_HOST__
11881 + #include "ifxhcd.h"
11884 +#include <linux/device.h>
11885 +#include <linux/platform_device.h>
11886 +#include <linux/gfp.h>
11889 +#ifdef __IS_HOST__
11890 + extern char ifxusb_driver_name[];
11892 + #ifdef __IS_DUAL__
11893 + extern ifxhcd_hcd_t ifxusb_hcd_1;
11894 + extern ifxhcd_hcd_t ifxusb_hcd_2;
11895 + extern char ifxusb_hcd_name_1[];
11896 + extern char ifxusb_hcd_name_2[];
11898 + extern ifxhcd_hcd_t ifxusb_hcd;
11899 + extern char ifxusb_hcd_name[];
11904 +#ifdef __IS_DEVICE__
11905 + extern char ifxusb_driver_name[];
11907 + extern ifxpcd_pcd_t ifxusb_pcd;
11908 + extern char ifxusb_pcd_name[];
11912 +//Attributes for sysfs (for 2.6 only)
11914 +extern struct device_attribute dev_attr_dbglevel;
11916 +#ifdef __IS_DUAL__
11917 + extern struct device_attribute dev_attr_dump_params_1;
11918 + extern struct device_attribute dev_attr_dump_params_2;
11920 + extern struct device_attribute dev_attr_dump_params;
11923 +#ifdef __IS_DUAL__
11924 + extern struct device_attribute dev_attr_mode_1;
11925 + extern struct device_attribute dev_attr_mode_2;
11927 + extern struct device_attribute dev_attr_mode;
11930 +#ifdef __IS_HOST__
11931 + #ifdef __IS_DUAL__
11932 + extern struct device_attribute dev_attr_buspower_1;
11933 + extern struct device_attribute dev_attr_buspower_2;
11934 + extern struct device_attribute dev_attr_bussuspend_1;
11935 + extern struct device_attribute dev_attr_bussuspend_2;
11936 + extern struct device_attribute dev_attr_busconnected_1;
11937 + extern struct device_attribute dev_attr_busconnected_2;
11938 + extern struct device_attribute dev_attr_connectspeed_1;
11939 + extern struct device_attribute dev_attr_connectspeed_1;
11941 + extern struct device_attribute dev_attr_buspower;
11942 + extern struct device_attribute dev_attr_bussuspend;
11943 + extern struct device_attribute dev_attr_busconnected;
11944 + extern struct device_attribute dev_attr_connectspeed;
11946 +#endif //__IS_HOST__
11948 +#ifdef __IS_DEVICE__
11949 + extern struct device_attribute dev_attr_devspeed;
11950 + extern struct device_attribute dev_attr_enumspeed;
11951 +#endif //__IS_DEVICE__
11953 +#ifdef __ENABLE_DUMP__
11954 + #ifdef __IS_DUAL__
11955 + extern struct device_attribute dev_attr_dump_reg_1;
11956 + extern struct device_attribute dev_attr_dump_reg_2;
11957 + extern struct device_attribute dev_attr_dump_spram_1;
11958 + extern struct device_attribute dev_attr_dump_spram_2;
11959 + #ifdef __IS_HOST__
11960 + extern struct device_attribute dev_attr_dump_host_state_1;
11961 + extern struct device_attribute dev_attr_dump_host_state_2;
11965 + extern struct device_attribute dev_attr_dump_reg;
11966 + extern struct device_attribute dev_attr_dump_spram;
11967 + #ifdef __IS_HOST__
11968 + extern struct device_attribute dev_attr_dump_host_state;
11972 +#endif //__ENABLE_DUMP__
11975 +/////////////////////////////////////////////////////////////////////////////////////////////////////
11976 +/////////////////////////////////////////////////////////////////////////////////////////////////////
11977 +/////////////////////////////////////////////////////////////////////////////////////////////////////
11979 +static ssize_t procfs_dbglevel_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
11981 + #ifdef __IS_HOST__
11982 + return sprintf( buf, "%08X\n",h_dbg_lvl );
11984 + return sprintf( buf, "%08X\n",d_dbg_lvl );
11988 +static ssize_t procfs_dbglevel_store(struct file *file, const char *buffer, unsigned long count, void *data)
11993 + if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
11995 + value = simple_strtoul(buf, NULL, 16);
11996 + #ifdef __IS_HOST__
11997 + h_dbg_lvl =value;
11999 + d_dbg_lvl =value;
12001 + //turn on and off power
12005 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12006 + static ssize_t sysfs_dbglevel_show( struct device *_dev, struct device_attribute *attr,char *buf)
12008 + static ssize_t sysfs_dbglevel_show( struct device *_dev, char *buf)
12011 + #ifdef __IS_HOST__
12012 + return sprintf( buf, "%08X\n",h_dbg_lvl );
12014 + return sprintf( buf, "%08X\n",d_dbg_lvl );
12018 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12019 + static ssize_t sysfs_dbglevel_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
12021 + static ssize_t sysfs_dbglevel_store( struct device *_dev, const char *buffer, size_t count )
12027 + if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
12029 + value = simple_strtoul(buf, NULL, 16);
12030 + #ifdef __IS_HOST__
12031 + h_dbg_lvl =value;
12033 + d_dbg_lvl =value;
12035 + //turn on and off power
12039 +DEVICE_ATTR(dbglevel, S_IRUGO|S_IWUSR, sysfs_dbglevel_show, sysfs_dbglevel_store);
12042 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12043 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12044 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12046 +static void ifxusb_dump_params(ifxusb_core_if_t *_core_if);
12048 +#ifdef __IS_DUAL__
12049 + static void dump_params_1(void)
12051 + ifxusb_dump_params(&ifxusb_hcd_1.core_if);
12053 + static void dump_params_2(void)
12055 + ifxusb_dump_params(&ifxusb_hcd_2.core_if);
12058 + static ssize_t procfs_dump_params_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12063 + static ssize_t procfs_dump_params_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12069 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12070 + static ssize_t sysfs_dump_params_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
12072 + static ssize_t sysfs_dump_params_show_1( struct device *_dev,char *buf)
12078 + DEVICE_ATTR(dump_params_1, S_IRUGO|S_IWUSR, sysfs_dump_params_show_1, NULL);
12080 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12081 + static ssize_t sysfs_dump_params_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
12083 + static ssize_t sysfs_dump_params_show_2( struct device *_dev,char *buf)
12090 + DEVICE_ATTR(dump_params_2, S_IRUGO|S_IWUSR, sysfs_dump_params_show_2, NULL);
12092 + static void dump_params(void)
12094 + #ifdef __IS_HOST__
12095 + ifxusb_dump_params(&ifxusb_hcd.core_if);
12097 + ifxusb_dump_params(&ifxusb_pcd.core_if);
12101 + static ssize_t procfs_dump_params_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12107 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12108 + static ssize_t sysfs_dump_params_show( struct device *_dev, struct device_attribute *attr,char *buf)
12110 + static ssize_t sysfs_dump_params_show( struct device *_dev,char *buf)
12116 + DEVICE_ATTR(dump_params, S_IRUGO|S_IWUSR, sysfs_dump_params_show, NULL);
12119 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12120 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12121 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12123 +#ifdef __IS_DUAL__
12124 + static ssize_t mode_show_1(char *buf)
12126 + if((ifxusb_rreg(&ifxusb_hcd_1.core_if.core_global_regs->gintsts ) & 0x1) == 1)
12127 + return sprintf( buf, "HOST\n" );
12129 + return sprintf( buf, "DEVICE(INCORRECT!)\n" );
12132 + static ssize_t mode_show_2(char *buf)
12134 + if((ifxusb_rreg(&ifxusb_hcd_2.core_if.core_global_regs->gintsts ) & 0x1) == 1)
12135 + return sprintf( buf, "HOST\n" );
12137 + return sprintf( buf, "DEVICE(INCORRECT!)\n" );
12140 + static ssize_t procfs_mode_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12142 + return mode_show_1(buf);
12144 + static ssize_t procfs_mode_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12146 + return mode_show_2(buf);
12149 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12150 + static ssize_t sysfs_mode_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
12152 + static ssize_t sysfs_mode_show_1( struct device *_dev,char *buf)
12155 + return mode_show_1(buf);
12158 + DEVICE_ATTR(mode_1, S_IRUGO|S_IWUSR, sysfs_mode_show_1, 0);
12160 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12161 + static ssize_t sysfs_mode_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
12163 + static ssize_t sysfs_mode_show_2( struct device *_dev,char *buf)
12166 + return mode_show_2(buf);
12168 + DEVICE_ATTR(mode_2, S_IRUGO|S_IWUSR, sysfs_mode_show_2, NULL);
12170 + static ssize_t mode_show(char *buf)
12172 + #ifdef __IS_HOST__
12173 + if((ifxusb_rreg(&ifxusb_hcd.core_if.core_global_regs->gintsts ) & 0x1) == 1)
12174 + return sprintf( buf, "HOST\n" );
12176 + return sprintf( buf, "DEVICE(INCORRECT!)\n" );
12178 + if((ifxusb_rreg(&ifxusb_pcd.core_if.core_global_regs->gintsts ) & 0x1) != 1)
12179 + return sprintf( buf, "DEVICE\n" );
12181 + return sprintf( buf, "HOST(INCORRECT!)\n" );
12184 + static ssize_t procfs_mode_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12186 + return mode_show(buf);
12188 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12189 + static ssize_t sysfs_mode_show( struct device *_dev, struct device_attribute *attr,char *buf)
12191 + static ssize_t sysfs_mode_show( struct device *_dev, char *buf)
12194 + return mode_show(buf);
12196 + DEVICE_ATTR(mode, S_IRUGO|S_IWUSR, sysfs_mode_show, NULL);
12199 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12200 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12201 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12203 +#ifdef __IS_HOST__
12204 + #ifdef __IS_DUAL__
12205 + static ssize_t buspower_show_1(char *buf)
12207 + if(ifxusb_vbus (&ifxusb_hcd_1.core_if)==1) return sprintf( buf, "1\n" );
12208 + if(ifxusb_vbus (&ifxusb_hcd_1.core_if)==0) return sprintf( buf, "0\n" );
12209 + return sprintf( buf, "UNKNOWN\n" );
12211 + static void buspower_store_1(uint32_t value)
12213 + if (value==1) ifxusb_vbus_on (&ifxusb_hcd_1.core_if);
12214 + else if(value==0) ifxusb_vbus_off(&ifxusb_hcd_1.core_if);
12216 + static ssize_t buspower_show_2(char *buf)
12218 + if(ifxusb_vbus (&ifxusb_hcd_2.core_if)==1) return sprintf( buf, "1\n" );
12219 + if(ifxusb_vbus (&ifxusb_hcd_2.core_if)==0) return sprintf( buf, "0\n" );
12220 + return sprintf( buf, "UNKNOWN\n" );
12222 + static void buspower_store_2(uint32_t value)
12224 + if (value==1) ifxusb_vbus_on (&ifxusb_hcd_2.core_if);
12225 + else if(value==0) ifxusb_vbus_off(&ifxusb_hcd_2.core_if);
12227 + static ssize_t procfs_buspower_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12229 + return buspower_show_1(buf);
12231 + static ssize_t procfs_buspower_store_1(struct file *file, const char *buffer, unsigned long count, void *data)
12236 + if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
12238 + value = simple_strtoul(buf, NULL, 16);
12239 + buspower_store_1(value);
12242 + static ssize_t procfs_buspower_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12244 + return buspower_show_2(buf);
12246 + static ssize_t procfs_buspower_store_2(struct file *file, const char *buffer, unsigned long count, void *data)
12251 + if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
12253 + value = simple_strtoul(buf, NULL, 16);
12254 + buspower_store_2(value);
12258 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12259 + static ssize_t sysfs_buspower_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
12261 + static ssize_t sysfs_buspower_show_1( struct device *_dev,char *buf)
12264 + return buspower_show_1(buf);
12266 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12267 + static ssize_t sysfs_buspower_store_1( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
12269 + static ssize_t sysfs_buspower_store_1( struct device *_dev, const char *buffer, size_t count )
12275 + if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
12277 + value = simple_strtoul(buf, NULL, 16);
12278 + buspower_store_1(value);
12281 + DEVICE_ATTR(buspower_1, S_IRUGO|S_IWUSR, sysfs_buspower_show_1, sysfs_buspower_store_1);
12283 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12284 + static ssize_t sysfs_buspower_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
12286 + static ssize_t sysfs_buspower_show_2( struct device *_dev,char *buf)
12289 + return buspower_show_2(buf);
12291 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12292 + static ssize_t sysfs_buspower_store_2( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
12294 + static ssize_t sysfs_buspower_store_2( struct device *_dev, const char *buffer, size_t count )
12300 + if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
12302 + value = simple_strtoul(buf, NULL, 16);
12303 + buspower_store_2(value);
12306 + DEVICE_ATTR(buspower_2, S_IRUGO|S_IWUSR, sysfs_buspower_show_2, sysfs_buspower_store_2);
12308 + static ssize_t buspower_show(char *buf)
12310 + if(ifxusb_vbus (&ifxusb_hcd.core_if)==1) return sprintf( buf, "1\n" );
12311 + if(ifxusb_vbus (&ifxusb_hcd.core_if)==0) return sprintf( buf, "0\n" );
12312 + return sprintf( buf, "UNKNOWN\n" );
12314 + static void buspower_store(uint32_t value)
12316 + if (value==1) ifxusb_vbus_on (&ifxusb_hcd.core_if);
12317 + else if(value==0) ifxusb_vbus_off(&ifxusb_hcd.core_if);
12319 + static ssize_t procfs_buspower_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12321 + return buspower_show(buf);
12323 + static ssize_t procfs_buspower_store(struct file *file, const char *buffer, unsigned long count, void *data)
12328 + if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
12330 + value = simple_strtoul(buf, NULL, 16);
12331 + buspower_store(value);
12334 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12335 + static ssize_t sysfs_buspower_show( struct device *_dev, struct device_attribute *attr,char *buf)
12337 + static ssize_t sysfs_buspower_show( struct device *_dev, char *buf)
12340 + return buspower_show(buf);
12342 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12343 + static ssize_t sysfs_buspower_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
12345 + static ssize_t sysfs_buspower_store( struct device *_dev, const char *buffer, size_t count )
12351 + if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
12353 + value = simple_strtoul(buf, NULL, 16);
12354 + buspower_store(value);
12357 + DEVICE_ATTR(buspower, S_IRUGO|S_IWUSR, sysfs_buspower_show, sysfs_buspower_store);
12360 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12361 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12362 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12365 + #ifdef __IS_DUAL__
12366 + static ssize_t bussuspend_show_1(char *buf)
12368 + hprt0_data_t val;
12369 + val.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0);
12370 + return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
12372 + static ssize_t bussuspend_show_2(char *buf)
12374 + hprt0_data_t val;
12375 + val.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0);
12376 + return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
12379 + static ssize_t procfs_bussuspend_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12381 + return bussuspend_show_1(buf);
12383 + static ssize_t procfs_bussuspend_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12385 + return bussuspend_show_2(buf);
12387 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12388 + static ssize_t sysfs_bussuspend_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
12390 + static ssize_t sysfs_bussuspend_show_1( struct device *_dev,char *buf)
12393 + return bussuspend_show_1(buf);
12395 + DEVICE_ATTR(bussuspend_1, S_IRUGO|S_IWUSR, sysfs_bussuspend_show_1, 0);
12396 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12397 + static ssize_t sysfs_bussuspend_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
12399 + static ssize_t sysfs_bussuspend_show_2( struct device *_dev,char *buf)
12402 + return bussuspend_show_2(buf);
12404 + DEVICE_ATTR(bussuspend_2, S_IRUGO|S_IWUSR, sysfs_bussuspend_show_2, 0);
12406 + static ssize_t bussuspend_show(char *buf)
12408 + hprt0_data_t val;
12409 + val.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0);
12410 + return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
12412 + static ssize_t procfs_bussuspend_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12414 + return bussuspend_show(buf);
12417 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12418 + static ssize_t sysfs_bussuspend_show( struct device *_dev, struct device_attribute *attr,char *buf)
12420 + static ssize_t sysfs_bussuspend_show( struct device *_dev, char *buf)
12423 + return bussuspend_show(buf);
12425 + DEVICE_ATTR(bussuspend, S_IRUGO|S_IWUSR, sysfs_bussuspend_show, 0);
12428 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12429 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12430 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12432 + #ifdef __IS_DUAL__
12433 + static ssize_t busconnected_show_1(char *buf)
12435 + hprt0_data_t val;
12436 + val.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0);
12437 + return sprintf (buf, "Bus Connected = 0x%x\n", val.b.prtconnsts);
12439 + static ssize_t busconnected_show_2(char *buf)
12441 + hprt0_data_t val;
12442 + val.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0);
12443 + return sprintf (buf, "Bus Connected = 0x%x\n", val.b.prtconnsts);
12446 + static ssize_t procfs_busconnected_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12448 + return busconnected_show_1(buf);
12450 + static ssize_t procfs_busconnected_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12452 + return busconnected_show_2(buf);
12454 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12455 + static ssize_t sysfs_busconnected_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
12457 + static ssize_t sysfs_busconnected_show_1( struct device *_dev,char *buf)
12460 + return busconnected_show_1(buf);
12462 + DEVICE_ATTR(busconnected_1, S_IRUGO|S_IWUSR, sysfs_busconnected_show_1, 0);
12463 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12464 + static ssize_t sysfs_busconnected_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
12466 + static ssize_t sysfs_busconnected_show_2( struct device *_dev,char *buf)
12469 + return busconnected_show_2(buf);
12471 + DEVICE_ATTR(busconnected_2, S_IRUGO|S_IWUSR, sysfs_busconnected_show_2, 0);
12473 + static ssize_t busconnected_show(char *buf)
12475 + hprt0_data_t val;
12476 + val.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0);
12477 + return sprintf (buf, "Bus Connected = 0x%x\n", val.b.prtconnsts);
12479 + static ssize_t procfs_busconnected_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12481 + return busconnected_show(buf);
12484 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12485 + static ssize_t sysfs_busconnected_show( struct device *_dev, struct device_attribute *attr,char *buf)
12487 + static ssize_t sysfs_busconnected_show( struct device *_dev, char *buf)
12490 + return busconnected_show(buf);
12492 + DEVICE_ATTR(busconnected, S_IRUGO|S_IWUSR, sysfs_busconnected_show, 0);
12495 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12496 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12497 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12499 + #ifdef __IS_DUAL__
12500 + static ssize_t connectspeed_show_1(char *buf)
12502 + hprt0_data_t val;
12503 + val.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0);
12504 + if( val.b.prtspd ==0) return sprintf (buf, "Bus Speed = High (%d)\n", val.b.prtspd);
12505 + if( val.b.prtspd ==1) return sprintf (buf, "Bus Speed = Full (%d)\n", val.b.prtspd);
12506 + if( val.b.prtspd ==2) return sprintf (buf, "Bus Speed = Low (%d)\n", val.b.prtspd);
12507 + return sprintf (buf, "Bus Speed = Unknown (%d)\n", val.b.prtspd);
12509 + static ssize_t connectspeed_show_2(char *buf)
12511 + hprt0_data_t val;
12512 + val.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0);
12513 + if( val.b.prtspd ==0) return sprintf (buf, "Bus Speed = High (%d)\n", val.b.prtspd);
12514 + if( val.b.prtspd ==1) return sprintf (buf, "Bus Speed = Full (%d)\n", val.b.prtspd);
12515 + if( val.b.prtspd ==2) return sprintf (buf, "Bus Speed = Low (%d)\n", val.b.prtspd);
12516 + return sprintf (buf, "Bus Speed = Unknown (%d)\n", val.b.prtspd);
12519 + static ssize_t procfs_connectspeed_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12521 + return connectspeed_show_1(buf);
12523 + static ssize_t procfs_connectspeed_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12525 + return connectspeed_show_2(buf);
12527 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12528 + static ssize_t sysfs_connectspeed_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
12530 + static ssize_t sysfs_connectspeed_show_1( struct device *_dev,char *buf)
12533 + return connectspeed_show_1(buf);
12535 + DEVICE_ATTR(connectspeed_1, S_IRUGO|S_IWUSR, sysfs_connectspeed_show_1, 0);
12536 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12537 + static ssize_t sysfs_connectspeed_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
12539 + static ssize_t sysfs_connectspeed_show_2( struct device *_dev,char *buf)
12542 + return connectspeed_show_2(buf);
12544 + DEVICE_ATTR(connectspeed_2, S_IRUGO|S_IWUSR, sysfs_connectspeed_show_2, 0);
12546 + static ssize_t connectspeed_show(char *buf)
12548 + hprt0_data_t val;
12549 + val.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0);
12550 + if( val.b.prtspd ==0) return sprintf (buf, "Bus Speed = High (%d)\n", val.b.prtspd);
12551 + if( val.b.prtspd ==1) return sprintf (buf, "Bus Speed = Full (%d)\n", val.b.prtspd);
12552 + if( val.b.prtspd ==2) return sprintf (buf, "Bus Speed = Low (%d)\n", val.b.prtspd);
12553 + return sprintf (buf, "Bus Speed = Unknown (%d)\n", val.b.prtspd);
12556 + static ssize_t procfs_connectspeed_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12558 + return connectspeed_show(buf);
12561 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12562 + static ssize_t sysfs_connectspeed_show( struct device *_dev, struct device_attribute *attr,char *buf)
12564 + static ssize_t sysfs_connectspeed_show( struct device *_dev, char *buf)
12567 + return connectspeed_show(buf);
12569 + DEVICE_ATTR(connectspeed, S_IRUGO|S_IWUSR, sysfs_connectspeed_show, 0);
12571 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12572 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12573 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12577 +#ifdef __IS_DEVICE__
12578 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12579 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12580 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12581 + static ssize_t devspeed_show(char *buf)
12584 + val.d32 = ifxusb_rreg(&ifxusb_pcd.core_if.dev_global_regs->dcfg);
12585 + if( val.b.devspd ==0) return sprintf (buf, "Dev Speed = High (%d)\n", val.b.devspd);
12586 + if( val.b.devspd ==1) return sprintf (buf, "Dev Speed = Full (%d)\n", val.b.devspd);
12587 + if( val.b.devspd ==3) return sprintf (buf, "Dev Speed = Full (%d)\n", val.b.devspd);
12588 + return sprintf (buf, "Dev Speed = Unknown (%d)\n", val.b.devspd);
12591 + static ssize_t procfs_devspeed_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12593 + return devspeed_show(buf);
12596 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12597 + static ssize_t sysfs_devspeed_show( struct device *_dev, struct device_attribute *attr,char *buf)
12599 + static ssize_t sysfs_devspeed_show( struct device *_dev, char *buf)
12602 + return devspeed_show(buf);
12604 + DEVICE_ATTR(devspeed, S_IRUGO|S_IWUSR, sysfs_devspeed_show, 0);
12606 + static ssize_t enumspeed_show(char *buf)
12609 + val.d32 = ifxusb_rreg(&ifxusb_pcd.core_if.dev_global_regs->dsts);
12610 + if( val.b.enumspd ==0) return sprintf (buf, "Enum Speed = High (%d)\n", val.b.enumspd);
12611 + if( val.b.enumspd ==1) return sprintf (buf, "Enum Speed = Full (%d)\n", val.b.enumspd);
12612 + if( val.b.enumspd ==2) return sprintf (buf, "Enum Speed = Low (%d)\n", val.b.enumspd);
12613 + return sprintf (buf, "Enum Speed = invalid(%d)\n", val.b.enumspd);
12616 + static ssize_t procfs_enumspeed_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12618 + return enumspeed_show(buf);
12621 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12622 + static ssize_t sysfs_enumspeed_show( struct device *_dev, struct device_attribute *attr,char *buf)
12624 + static ssize_t sysfs_enumspeed_show( struct device *_dev, char *buf)
12627 + return enumspeed_show(buf);
12629 + DEVICE_ATTR(enumspeed, S_IRUGO|S_IWUSR, sysfs_enumspeed_show, 0);
12630 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12631 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12632 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12636 +//////////////////////////////////////////////////////////////////////////////////
12637 +#ifdef __ENABLE_DUMP__
12639 + #ifdef __IS_DUAL__
12640 + static void dump_reg_1(void)
12642 + ifxusb_dump_registers(&ifxusb_hcd_1.core_if);
12644 + static void dump_reg_2(void)
12646 + ifxusb_dump_registers(&ifxusb_hcd_2.core_if);
12649 + static ssize_t procfs_dump_reg_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12654 + static ssize_t procfs_dump_reg_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12659 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12660 + static ssize_t sysfs_dump_reg_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
12662 + static ssize_t sysfs_dump_reg_show_1( struct device *_dev,char *buf)
12668 + DEVICE_ATTR(dump_reg_1, S_IRUGO|S_IWUSR, sysfs_dump_reg_show_1, 0);
12669 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12670 + static ssize_t sysfs_dump_reg_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
12672 + static ssize_t sysfs_dump_reg_show_2( struct device *_dev,char *buf)
12678 + DEVICE_ATTR(dump_reg_2, S_IRUGO|S_IWUSR, sysfs_dump_reg_show_2, 0);
12680 + static void dump_reg(void)
12682 + #ifdef __IS_HOST__
12683 + ifxusb_dump_registers(&ifxusb_hcd.core_if);
12685 + #ifdef __IS_DEVICE__
12686 + ifxusb_dump_registers(&ifxusb_pcd.core_if);
12689 + static ssize_t procfs_dump_reg_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12694 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12695 + static ssize_t sysfs_dump_reg_show( struct device *_dev, struct device_attribute *attr,char *buf)
12697 + static ssize_t sysfs_dump_reg_show( struct device *_dev,char *buf)
12703 + DEVICE_ATTR(dump_reg, S_IRUGO|S_IWUSR, sysfs_dump_reg_show, 0);
12707 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12708 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12709 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12711 + #ifdef __IS_DUAL__
12712 + static void dump_spram_1(void)
12714 + ifxusb_dump_spram(&ifxusb_hcd_1.core_if);
12716 + static void dump_spram_2(void)
12718 + ifxusb_dump_spram(&ifxusb_hcd_2.core_if);
12721 + static ssize_t procfs_dump_spram_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12726 + static ssize_t procfs_dump_spram_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12731 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12732 + static ssize_t sysfs_dump_spram_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
12734 + static ssize_t sysfs_dump_spram_show_1( struct device *_dev,char *buf)
12740 + DEVICE_ATTR(dump_spram_1, S_IRUGO|S_IWUSR, sysfs_dump_spram_show_1, 0);
12742 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12743 + static ssize_t sysfs_dump_spram_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
12745 + static ssize_t sysfs_dump_spram_show_2( struct device *_dev,char *buf)
12751 + DEVICE_ATTR(dump_spram_2, S_IRUGO|S_IWUSR, sysfs_dump_spram_show_2, 0);
12753 + static void dump_spram(void)
12755 + #ifdef __IS_HOST__
12756 + ifxusb_dump_spram(&ifxusb_hcd.core_if);
12758 + #ifdef __IS_DEVICE__
12759 + ifxusb_dump_spram(&ifxusb_pcd.core_if);
12762 + static ssize_t procfs_dump_spram_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12767 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12768 + static ssize_t sysfs_dump_spram_show( struct device *_dev, struct device_attribute *attr,char *buf)
12770 + static ssize_t sysfs_dump_spram_show( struct device *_dev,char *buf)
12776 + DEVICE_ATTR(dump_spram, S_IRUGO|S_IWUSR, sysfs_dump_spram_show, 0);
12778 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12779 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12780 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12782 + #ifdef __IS_HOST__
12783 + #ifdef __IS_DUAL__
12784 + static ssize_t procfs_dump_host_state_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12786 + ifxhcd_dump_state(&ifxusb_hcd_1);
12789 + static ssize_t procfs_dump_host_state_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12791 + ifxhcd_dump_state(&ifxusb_hcd_2);
12794 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12795 + static ssize_t sysfs_dump_host_state_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
12797 + static ssize_t sysfs_dump_host_state_show_1( struct device *_dev,char *buf)
12800 + ifxhcd_dump_state(&ifxusb_hcd_1);
12803 + DEVICE_ATTR(dump_host_state_1, S_IRUGO|S_IWUSR, sysfs_dump_host_state_show_1, 0);
12804 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12805 + static ssize_t sysfs_dump_host_state_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
12807 + static ssize_t sysfs_dump_host_state_show_2( struct device *_dev,char *buf)
12810 + ifxhcd_dump_state(&ifxusb_hcd_2);
12813 + DEVICE_ATTR(dump_host_state_2, S_IRUGO|S_IWUSR, sysfs_dump_host_state_show_2, 0);
12815 + static ssize_t procfs_dump_host_state_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
12817 + ifxhcd_dump_state(&ifxusb_hcd);
12820 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
12821 + static ssize_t sysfs_dump_host_state_show( struct device *_dev, struct device_attribute *attr,char *buf)
12823 + static ssize_t sysfs_dump_host_state_show( struct device *_dev,char *buf)
12826 + ifxhcd_dump_state(&ifxusb_hcd);
12829 + DEVICE_ATTR(dump_host_state, S_IRUGO|S_IWUSR, sysfs_dump_host_state_show, 0);
12832 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12833 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12834 +/////////////////////////////////////////////////////////////////////////////////////////////////////
12836 + #endif //IS_HOST_
12838 +#endif //__ENABLE_DUMP__
12840 +//////////////////////////////////////////////////////////////////////////////////
12842 +static int ifx_proc_addproc(char *funcname, read_proc_t *hookfuncr, write_proc_t *hookfuncw);
12843 +static void ifx_proc_delproc(char *funcname);
12845 +//////////////////////////////////////////////////////////////////////////////////
12848 + \brief This function create the sysfs and procfs entries
12849 + \param[in] _dev Pointer of device structure, if applied
12851 +void ifxusb_attr_create (void *_dev)
12855 + struct device *dev = (struct device *) _dev;
12857 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
12858 + error = ifx_proc_addproc("dbglevel", procfs_dbglevel_show, procfs_dbglevel_store);
12859 + error = device_create_file(dev, &dev_attr_dbglevel);
12861 + #ifdef __IS_DUAL__
12862 + error = ifx_proc_addproc("dump_params_1", procfs_dump_params_show_1, NULL);
12863 + error = ifx_proc_addproc("dump_params_2", procfs_dump_params_show_2, NULL);
12864 + error = device_create_file(dev, &dev_attr_dump_params_1);
12865 + error = device_create_file(dev, &dev_attr_dump_params_2);
12867 + error = ifx_proc_addproc("dump_params", procfs_dump_params_show, NULL);
12868 + error = device_create_file(dev, &dev_attr_dump_params);
12871 + #ifdef __IS_DUAL__
12872 + error = ifx_proc_addproc("mode_1", procfs_mode_show_1, NULL);
12873 + error = ifx_proc_addproc("mode_2", procfs_mode_show_2, NULL);
12874 + error = device_create_file(dev, &dev_attr_mode_1);
12875 + error = device_create_file(dev, &dev_attr_mode_2);
12877 + error = ifx_proc_addproc("mode", procfs_mode_show, NULL);
12878 + error = device_create_file(dev, &dev_attr_mode);
12881 + #ifdef __IS_HOST__
12882 + #ifdef __IS_DUAL__
12883 + error = ifx_proc_addproc("buspower_1", procfs_buspower_show_1, procfs_buspower_store_1);
12884 + error = ifx_proc_addproc("buspower_2", procfs_buspower_show_2, procfs_buspower_store_2);
12885 + error = device_create_file(dev, &dev_attr_buspower_1);
12886 + error = device_create_file(dev, &dev_attr_buspower_2);
12888 + error = ifx_proc_addproc("buspower", procfs_buspower_show, procfs_buspower_store);
12889 + error = device_create_file(dev, &dev_attr_buspower);
12892 + #ifdef __IS_DUAL__
12893 + error = ifx_proc_addproc("bussuspend_1", procfs_bussuspend_show_1, NULL);
12894 + error = ifx_proc_addproc("bussuspend_2", procfs_bussuspend_show_2, NULL);
12895 + error = device_create_file(dev, &dev_attr_bussuspend_1);
12896 + error = device_create_file(dev, &dev_attr_bussuspend_2);
12898 + error = ifx_proc_addproc("bussuspend", procfs_bussuspend_show, NULL);
12899 + error = device_create_file(dev, &dev_attr_bussuspend);
12902 + #ifdef __IS_DUAL__
12903 + error = ifx_proc_addproc("busconnected_1", procfs_busconnected_show_1, NULL);
12904 + error = ifx_proc_addproc("busconnected_2", procfs_busconnected_show_2, NULL);
12905 + error = device_create_file(dev, &dev_attr_busconnected_1);
12906 + error = device_create_file(dev, &dev_attr_busconnected_2);
12908 + error = ifx_proc_addproc("busconnected", procfs_busconnected_show, NULL);
12909 + error = device_create_file(dev, &dev_attr_busconnected);
12912 + #ifdef __IS_DUAL__
12913 + error = ifx_proc_addproc("connectspeed_1", procfs_connectspeed_show_1, NULL);
12914 + error = ifx_proc_addproc("connectspeed_2", procfs_connectspeed_show_2, NULL);
12915 + error = device_create_file(dev, &dev_attr_connectspeed_1);
12916 + error = device_create_file(dev, &dev_attr_connectspeed_2);
12918 + error = ifx_proc_addproc("connectspeed", procfs_connectspeed_show, NULL);
12919 + error = device_create_file(dev, &dev_attr_connectspeed);
12923 + #ifdef __IS_DEVICE__
12924 + error = ifx_proc_addproc("devspeed", procfs_devspeed_show, NULL);
12925 + error = device_create_file(dev, &dev_attr_devspeed);
12926 + error = ifx_proc_addproc("enumspeed", procfs_enumspeed_show, NULL);
12927 + error = device_create_file(dev, &dev_attr_enumspeed);
12930 + //////////////////////////////////////////////////////
12931 + #ifdef __ENABLE_DUMP__
12932 + #ifdef __IS_DUAL__
12933 + error = ifx_proc_addproc("dump_reg_1", procfs_dump_reg_show_1, NULL);
12934 + error = ifx_proc_addproc("dump_reg_2", procfs_dump_reg_show_2, NULL);
12935 + error = device_create_file(dev, &dev_attr_dump_reg_1);
12936 + error = device_create_file(dev, &dev_attr_dump_reg_2);
12938 + error = ifx_proc_addproc("dump_reg", procfs_dump_reg_show, NULL);
12939 + error = device_create_file(dev, &dev_attr_dump_reg);
12942 + #ifdef __IS_DUAL__
12943 + error = ifx_proc_addproc("dump_spram_1", procfs_dump_spram_show_1, NULL);
12944 + error = ifx_proc_addproc("dump_spram_2", procfs_dump_spram_show_2, NULL);
12945 + error = device_create_file(dev, &dev_attr_dump_spram_1);
12946 + error = device_create_file(dev, &dev_attr_dump_spram_2);
12948 + error = ifx_proc_addproc("dump_spram", procfs_dump_spram_show, NULL);
12949 + error = device_create_file(dev, &dev_attr_dump_spram);
12952 + #ifdef __IS_HOST__
12953 + #ifdef __IS_DUAL__
12954 + error = ifx_proc_addproc("dump_host_state_1", procfs_dump_host_state_show_1, NULL);
12955 + error = ifx_proc_addproc("dump_host_state_2", procfs_dump_host_state_show_2, NULL);
12956 + error = device_create_file(dev, &dev_attr_dump_host_state_1);
12957 + error = device_create_file(dev, &dev_attr_dump_host_state_2);
12959 + error = ifx_proc_addproc("dump_host_state", procfs_dump_host_state_show, NULL);
12960 + error = device_create_file(dev, &dev_attr_dump_host_state);
12963 + #endif //__ENABLE_DUMP__
12964 + //////////////////////////////////////////////////////
12969 + \brief This function remove the sysfs and procfs entries
12970 + \param[in] _dev Pointer of device structure, if applied
12972 +void ifxusb_attr_remove (void *_dev)
12974 + struct device *dev = (struct device *) _dev;
12976 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
12977 + ifx_proc_delproc("dbglevel");
12978 + device_remove_file(dev, &dev_attr_dbglevel);
12980 + #ifdef __IS_DUAL__
12981 + ifx_proc_delproc("dump_params_1");
12982 + ifx_proc_delproc("dump_params_2");
12983 + device_remove_file(dev, &dev_attr_dump_params_1);
12984 + device_remove_file(dev, &dev_attr_dump_params_2);
12986 + ifx_proc_delproc("dump_params");
12987 + device_remove_file(dev, &dev_attr_dump_params);
12990 + #ifdef __IS_DUAL__
12991 + ifx_proc_delproc("mode_1");
12992 + ifx_proc_delproc("mode_2");
12993 + device_remove_file(dev, &dev_attr_mode_1);
12994 + device_remove_file(dev, &dev_attr_mode_2);
12996 + ifx_proc_delproc("mode");
12997 + device_remove_file(dev, &dev_attr_mode);
13000 + #ifdef __IS_HOST__
13001 + #ifdef __IS_DUAL__
13002 + ifx_proc_delproc("buspower_1");
13003 + ifx_proc_delproc("buspower_2");
13004 + device_remove_file(dev, &dev_attr_buspower_1);
13005 + device_remove_file(dev, &dev_attr_buspower_2);
13007 + ifx_proc_delproc("buspower");
13008 + device_remove_file(dev, &dev_attr_buspower);
13011 + #ifdef __IS_DUAL__
13012 + ifx_proc_delproc("bussuspend_1");
13013 + ifx_proc_delproc("bussuspend_2");
13014 + device_remove_file(dev, &dev_attr_bussuspend_1);
13015 + device_remove_file(dev, &dev_attr_bussuspend_2);
13017 + ifx_proc_delproc("bussuspend");
13018 + device_remove_file(dev, &dev_attr_bussuspend);
13021 + #ifdef __IS_DUAL__
13022 + ifx_proc_delproc("busconnected_1");
13023 + ifx_proc_delproc("busconnected_2");
13024 + device_remove_file(dev, &dev_attr_busconnected_1);
13025 + device_remove_file(dev, &dev_attr_busconnected_2);
13027 + ifx_proc_delproc("busconnected");
13028 + device_remove_file(dev, &dev_attr_busconnected);
13031 + #ifdef __IS_DUAL__
13032 + ifx_proc_delproc("connectspeed_1");
13033 + ifx_proc_delproc("connectspeed_2");
13034 + device_remove_file(dev, &dev_attr_connectspeed_1);
13035 + device_remove_file(dev, &dev_attr_connectspeed_2);
13037 + ifx_proc_delproc("connectspeed");
13038 + device_remove_file(dev, &dev_attr_connectspeed);
13042 + #ifdef __IS_DEVICE__
13043 + ifx_proc_delproc("devspeed");
13044 + device_remove_file(dev, &dev_attr_devspeed);
13045 + ifx_proc_delproc("enumspeed");
13046 + device_remove_file(dev, &dev_attr_enumspeed);
13049 + #ifdef __ENABLE_DUMP__
13050 + #ifdef __IS_DUAL__
13051 + ifx_proc_delproc("dump_reg_1");
13052 + ifx_proc_delproc("dump_reg_2");
13053 + device_remove_file(dev, &dev_attr_dump_reg_1);
13054 + device_remove_file(dev, &dev_attr_dump_reg_2);
13056 + ifx_proc_delproc("dump_reg");
13057 + device_remove_file(dev, &dev_attr_dump_reg);
13060 + #ifdef __IS_DUAL__
13061 + ifx_proc_delproc("dump_spram_1");
13062 + ifx_proc_delproc("dump_spram_2");
13063 + device_remove_file(dev, &dev_attr_dump_spram_1);
13064 + device_remove_file(dev, &dev_attr_dump_spram_2);
13066 + ifx_proc_delproc("dump_spram");
13067 + device_remove_file(dev, &dev_attr_dump_spram);
13070 + #ifdef __IS_HOST__
13071 + #ifdef __IS_DUAL__
13072 + ifx_proc_delproc("dump_host_state_1");
13073 + ifx_proc_delproc("dump_host_state_2");
13074 + device_remove_file(dev, &dev_attr_dump_host_state_1);
13075 + device_remove_file(dev, &dev_attr_dump_host_state_2);
13077 + ifx_proc_delproc("dump_host_state");
13078 + device_remove_file(dev, &dev_attr_dump_host_state);
13081 + #endif //__ENABLE_DUMP__
13082 + /* AVM/WK fix: del IFXUSB root dir*/
13083 + ifx_proc_delproc(NULL);
13086 +static struct proc_dir_entry * proc_ifx_root = NULL;
13088 +/* initialize the proc file system and make a dir named /proc/[name] */
13089 +static void ifx_proc_init(void)
13091 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13092 + proc_ifx_root = proc_mkdir(ifxusb_driver_name, (void *)0);
13093 + if (!proc_ifx_root){
13094 + IFX_PRINT("%s proc initialization failed! \n", ifxusb_driver_name);
13099 +/* proc file system add function for debugging. */
13100 +static int ifx_proc_addproc(char *funcname, read_proc_t *hookfuncr, write_proc_t *hookfuncw)
13102 + struct proc_dir_entry *pe;
13103 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13104 + if (!proc_ifx_root)
13107 + if (hookfuncw == NULL)
13109 + pe = create_proc_read_entry(funcname, S_IRUGO, proc_ifx_root, hookfuncr, NULL);
13112 + IFX_PRINT("ERROR in creating read proc entry (%s)! \n", funcname);
13118 + pe = create_proc_entry(funcname, S_IRUGO | S_IWUGO, proc_ifx_root);
13121 + pe->read_proc = hookfuncr;
13122 + pe->write_proc = hookfuncw;
13126 + IFX_PRINT("ERROR in creating proc entry (%s)! \n", funcname);
13134 +/* proc file system del function for removing module. */
13135 +static void ifx_proc_delproc(char *funcname)
13138 + if (funcname != NULL) {
13139 + remove_proc_entry(funcname, proc_ifx_root);
13141 + remove_proc_entry(ifxusb_driver_name, NULL);
13142 + proc_ifx_root = NULL;
13146 +static void ifxusb_dump_params(ifxusb_core_if_t *_core_if)
13148 + ifxusb_params_t *params=&_core_if->params;
13150 + #ifdef __IS_HOST__
13151 + IFX_PRINT("IFXUSB Dump Parameters ( Host Mode) \n");
13152 + #endif //__IS_HOST__
13153 + #ifdef __IS_DEVICE__
13154 + IFX_PRINT("IFXUSB Dump Parameters ( Device Mode) \n");
13155 + #endif //__IS_DEVICE__
13157 + #ifdef __DESC_DMA__
13158 + IFX_PRINT("DMA: Hermes DMA\n");
13160 + IFX_PRINT("DMA: Non-Desc DMA\n");
13162 + IFX_PRINT(" Burst size: %d\n",params->dma_burst_size);
13164 + if (params->speed==1)
13165 + IFX_PRINT("Full Speed only\n");
13166 + else if(params->speed==0)
13167 + IFX_PRINT("Full/Hign Speed\n");
13169 + IFX_PRINT("Unkonwn setting (%d) for Speed\n",params->speed);
13171 + IFX_PRINT("Total Data FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",
13172 + params->data_fifo_size,params->data_fifo_size,
13173 + params->data_fifo_size*4, params->data_fifo_size*4
13176 + #ifdef __IS_DEVICE__
13177 + IFX_PRINT("Rx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",
13178 + params->rx_fifo_size,params->rx_fifo_size,
13179 + params->rx_fifo_size*4, params->rx_fifo_size*4
13183 + for(i=0;i<MAX_EPS_CHANNELS;i++)
13185 + IFX_PRINT("Tx FIFO #%d size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",i,
13186 + params->tx_fifo_size[i],params->tx_fifo_size[i],
13187 + params->tx_fifo_size[i]*4, params->tx_fifo_size[i]*4
13191 + #ifdef __DED_FIFO__
13192 + IFX_PRINT("Treshold : %s Rx:%d Tx:%d \n",
13193 + (params->thr_ctl)?"On":"Off",params->tx_thr_length,params->rx_thr_length);
13195 + #else //__IS_HOST__
13196 + IFX_PRINT("Host Channels: %d\n",params->host_channels);
13198 + IFX_PRINT("Rx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",
13199 + params->data_fifo_size,params->data_fifo_size,
13200 + params->data_fifo_size*4, params->data_fifo_size*4
13203 + IFX_PRINT("NP Tx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",
13204 + params->nperio_tx_fifo_size,params->nperio_tx_fifo_size,
13205 + params->nperio_tx_fifo_size*4, params->nperio_tx_fifo_size*4
13208 + IFX_PRINT(" P Tx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",
13209 + params->perio_tx_fifo_size,params->perio_tx_fifo_size,
13210 + params->perio_tx_fifo_size*4, params->perio_tx_fifo_size*4
13212 + #endif //__IS_HOST__
13214 + IFX_PRINT("Max Transfer size: %d(0x%06X) Bytes\n",
13215 + params->max_transfer_size,params->max_transfer_size
13217 + IFX_PRINT("Max Packet Count: %d(0x%06X)\n",
13218 + params->max_packet_count,params->max_packet_count
13221 + IFX_PRINT("PHY UTMI Width: %d\n",params->phy_utmi_width);
13223 + IFX_PRINT("Turn Around Time: HS:%d FS:%d\n",params->turn_around_time_hs,params->turn_around_time_fs);
13224 + IFX_PRINT("Timeout Calibration: HS:%d FS:%d\n",params->timeout_cal_hs,params->timeout_cal_fs);
13227 + IFX_PRINT("==================================================\n");
13228 + IFX_PRINT("End of Parameters Dump\n");
13229 + IFX_PRINT("==================================================\n");
13233 diff --git a/drivers/usb/ifxhcd/ifxusb_driver.c b/drivers/usb/ifxhcd/ifxusb_driver.c
13234 new file mode 100644
13235 index 0000000..2334905
13237 +++ b/drivers/usb/ifxhcd/ifxusb_driver.c
13239 +/*****************************************************************************
13240 + ** FILE NAME : ifxusb_driver.c
13241 + ** PROJECT : IFX USB sub-system V3
13242 + ** MODULES : IFX USB sub-system Host and Device driver
13243 + ** SRC VERSION : 1.0
13244 + ** DATE : 1/Jan/2009
13245 + ** AUTHOR : Chen, Howard
13246 + ** DESCRIPTION : The provides the initialization and cleanup entry
13247 + ** points for the IFX USB driver. This module can be
13248 + ** dynamically loaded with insmod command or built-in
13249 + ** with kernel. When loaded or executed the ifxusb_driver_init
13250 + ** function is called. When the module is removed (using rmmod),
13251 + ** the ifxusb_driver_cleanup function is called.
13252 + *****************************************************************************/
13255 + \file ifxusb_driver.c
13256 + \brief This file contains the loading/unloading interface to the Linux driver.
13259 +#include <linux/version.h>
13260 +#include "ifxusb_version.h"
13262 +#include <linux/kernel.h>
13263 +#include <linux/module.h>
13264 +#include <linux/moduleparam.h>
13265 +#include <linux/init.h>
13267 +#include <linux/device.h>
13268 +#include <linux/platform_device.h>
13270 +#include <linux/errno.h>
13271 +#include <linux/types.h>
13272 +#include <linux/stat.h> /* permission constants */
13273 +#include <linux/gpio.h>
13274 +#include <lantiq_soc.h>
13276 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
13277 + #include <linux/irq.h>
13280 +#include <asm/io.h>
13282 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
13283 + #include <asm/irq.h>
13286 +#include "ifxusb_plat.h"
13288 +#include "ifxusb_cif.h"
13290 +#ifdef __IS_HOST__
13291 + #include "ifxhcd.h"
13293 + #define USB_DRIVER_DESC "IFX USB HCD driver"
13294 + const char ifxusb_driver_name[] = "ifxusb_hcd";
13296 + #ifdef __IS_DUAL__
13297 + ifxhcd_hcd_t ifxusb_hcd_1;
13298 + ifxhcd_hcd_t ifxusb_hcd_2;
13299 + const char ifxusb_hcd_name_1[] = "ifxusb_hcd_1";
13300 + const char ifxusb_hcd_name_2[] = "ifxusb_hcd_2";
13302 + ifxhcd_hcd_t ifxusb_hcd;
13303 + const char ifxusb_hcd_name[] = "ifxusb_hcd";
13306 + #if defined(__DO_OC_INT__)
13307 + static unsigned int oc_int_installed=0;
13308 + static ifxhcd_hcd_t *oc_int_id=NULL;
13312 +#ifdef __IS_DEVICE__
13313 + #include "ifxpcd.h"
13315 + #define USB_DRIVER_DESC "IFX USB PCD driver"
13316 + const char ifxusb_driver_name[] = "ifxusb_pcd";
13318 + ifxpcd_pcd_t ifxusb_pcd;
13319 + const char ifxusb_pcd_name[] = "ifxusb_pcd";
13322 +/* Global Debug Level Mask. */
13323 +#ifdef __IS_HOST__
13324 + uint32_t h_dbg_lvl = 0x00;
13327 +#ifdef __IS_DEVICE__
13328 + uint32_t d_dbg_lvl = 0x00;
13331 +ifxusb_params_t ifxusb_module_params;
13333 +static void parse_parms(void);
13336 +#include <lantiq_irq.h>
13337 +#define IFX_USB0_IR (INT_NUM_IM1_IRL0 + 22)
13338 +#define IFX_USB1_IR (INT_NUM_IM2_IRL0 + 19)
13341 + \brief This function is called when a driver is unregistered. This happens when
13342 + the rmmod command is executed. The device may or may not be electrically
13343 + present. If it is present, the driver stops device processing. Any resources
13344 + used on behalf of this device are freed.
13346 +static int ifxusb_driver_remove(struct platform_device *_dev)
13348 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13349 + #ifdef __IS_HOST__
13350 + #if defined(__DO_OC_INT__)
13351 + #if defined(__DO_OC_INT_ENABLE__)
13352 + ifxusb_oc_int_off();
13355 + if(oc_int_installed && oc_int_id)
13356 + free_irq((unsigned int)IFXUSB_OC_IRQ, oc_int_id );
13357 + oc_int_installed=0;
13361 + #if defined(__IS_DUAL__)
13362 + ifxhcd_remove(&ifxusb_hcd_1);
13363 + ifxusb_core_if_remove(&ifxusb_hcd_1.core_if );
13364 + ifxhcd_remove(&ifxusb_hcd_2);
13365 + ifxusb_core_if_remove(&ifxusb_hcd_2.core_if );
13367 + ifxhcd_remove(&ifxusb_hcd);
13368 + ifxusb_core_if_remove(&ifxusb_hcd.core_if );
13372 + #ifdef __IS_DEVICE__
13374 + ifxusb_core_if_remove(&ifxusb_pcd.core_if );
13377 + /* Remove the device attributes */
13379 + ifxusb_attr_remove(&_dev->dev);
13385 +/* Function to setup the structures to control one usb core running as host*/
13386 +#ifdef __IS_HOST__
13388 + \brief inlined by ifxusb_driver_probe(), handling host mode probing. Run at each host core.
13390 + static inline int ifxusb_driver_probe_h(ifxhcd_hcd_t *_hcd,
13392 + uint32_t _iobase,
13393 + uint32_t _fifomem,
13394 + uint32_t _fifodbg
13399 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13401 +#ifdef __DEV_NEW__
13402 + ifxusb_power_off (&_hcd->core_if);
13403 + ifxusb_phy_power_off (&_hcd->core_if); // Test
13405 +#endif //__DEV_NEW__
13406 + ifxusb_power_on (&_hcd->core_if);
13408 + ifxusb_phy_power_on (&_hcd->core_if); // Test
13410 + ifxusb_hard_reset(&_hcd->core_if);
13411 + retval =ifxusb_core_if_init(&_hcd->core_if,
13419 + ifxusb_host_core_init(&_hcd->core_if,&ifxusb_module_params);
13421 + ifxusb_disable_global_interrupts( &_hcd->core_if);
13423 + /* The driver is now initialized and need to be registered into Linux USB sub-system */
13425 + retval = ifxhcd_init(_hcd); // hook the hcd into usb ss
13429 + IFX_ERROR("_hcd_init failed\n");
13433 + //ifxusb_enable_global_interrupts( _hcd->core_if ); // this should be done at hcd_start , including hcd_interrupt
13436 +#endif //__IS_HOST__
13438 +#ifdef __IS_DEVICE__
13440 + \brief inlined by ifxusb_driver_probe(), handling device mode probing.
13442 + static inline int ifxusb_driver_probe_d(ifxpcd_pcd_t *_pcd,
13444 + uint32_t _iobase,
13445 + uint32_t _fifomem,
13446 + uint32_t _fifodbg
13451 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13452 +#ifdef __DEV_NEW__
13453 + ifxusb_power_off (&_pcd->core_if);
13454 + ifxusb_phy_power_off (&_pcd->core_if); // Test
13456 +#endif // __DEV_NEW__
13457 + ifxusb_power_on (&_pcd->core_if);
13459 + ifxusb_phy_power_on (&_pcd->core_if); // Test
13461 + ifxusb_hard_reset(&_pcd->core_if);
13462 + retval =ifxusb_core_if_init(&_pcd->core_if,
13470 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13471 + ifxusb_dev_core_init(&_pcd->core_if,&ifxusb_module_params);
13473 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13474 + ifxusb_disable_global_interrupts( &_pcd->core_if);
13476 + /* The driver is now initialized and need to be registered into
13477 + Linux USB Gadget sub-system
13479 + retval = ifxpcd_init();
13480 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13484 + IFX_ERROR("_pcd_init failed\n");
13487 + //ifxusb_enable_global_interrupts( _pcd->core_if ); // this should be done at gadget bind or start
13490 +#endif //__IS_DEVICE__
13495 + \brief This function is called by module management in 2.6 kernel or by ifxusb_driver_init with 2.4 kernel
13496 + It is to probe and setup IFXUSB core(s).
13498 +static int ifxusb_driver_probe(struct platform_device *_dev)
13501 + int *pins = _dev->dev.platform_data;
13502 + if (ltq_is_vr9()) {
13503 + gpio_request(6, "id1");
13504 + gpio_request(9, "id2");
13505 + gpio_direction_input(6);
13506 + gpio_direction_input(9);
13510 + gpio_request(pins[0], "vbus1");
13511 + gpio_direction_output(pins[0], 1);
13513 + if (pins[1] && ltq_is_vr9()) {
13514 + gpio_request(pins[1], "vbus2");
13515 + gpio_direction_output(pins[1], 1);
13518 + // Parsing and store the parameters
13519 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13522 + #ifdef __IS_HOST__
13523 + #if defined(__IS_DUAL__)
13524 + memset(&ifxusb_hcd_1, 0, sizeof(ifxhcd_hcd_t));
13525 + memset(&ifxusb_hcd_2, 0, sizeof(ifxhcd_hcd_t));
13527 + ifxusb_hcd_1.core_if.core_no=0;
13528 + ifxusb_hcd_2.core_if.core_no=1;
13529 + ifxusb_hcd_1.core_if.core_name=(char *)ifxusb_hcd_name_1;
13530 + ifxusb_hcd_2.core_if.core_name=(char *)ifxusb_hcd_name_2;
13532 + ifxusb_hcd_1.dev=&_dev->dev;
13533 + ifxusb_hcd_2.dev=&_dev->dev;
13535 + retval = ifxusb_driver_probe_h(&ifxusb_hcd_1,
13537 + IFXUSB1_IOMEM_BASE,
13538 + IFXUSB1_FIFOMEM_BASE,
13539 + IFXUSB1_FIFODBG_BASE
13542 + goto ifxusb_driver_probe_fail;
13544 + retval = ifxusb_driver_probe_h(&ifxusb_hcd_2,
13546 + IFXUSB2_IOMEM_BASE,
13547 + IFXUSB2_FIFOMEM_BASE,
13548 + IFXUSB2_FIFODBG_BASE
13551 + goto ifxusb_driver_probe_fail;
13553 + #elif defined(__IS_FIRST__)
13554 + memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t));
13556 + ifxusb_hcd.core_if.core_no=0;
13557 + ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name;
13559 + ifxusb_hcd.dev=&_dev->dev;
13561 + retval = ifxusb_driver_probe_h(&ifxusb_hcd,
13563 + IFXUSB1_IOMEM_BASE,
13564 + IFXUSB1_FIFOMEM_BASE,
13565 + IFXUSB1_FIFODBG_BASE
13568 + goto ifxusb_driver_probe_fail;
13570 + #elif defined(__IS_SECOND__)
13571 + memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t));
13573 + ifxusb_hcd.core_if.core_no=1;
13574 + ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name;
13576 + ifxusb_hcd.dev=&_dev->dev;
13578 + retval = ifxusb_driver_probe_h(&ifxusb_hcd,
13580 + IFXUSB2_IOMEM_BASE,
13581 + IFXUSB2_FIFOMEM_BASE,
13582 + IFXUSB2_FIFODBG_BASE
13585 + goto ifxusb_driver_probe_fail;
13588 + memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t));
13590 + ifxusb_hcd.core_if.core_no=0;
13591 + ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name;
13593 + ifxusb_hcd.dev=&_dev->dev;
13595 + retval = ifxusb_driver_probe_h(&ifxusb_hcd,
13597 + IFXUSB_IOMEM_BASE,
13598 + IFXUSB_FIFOMEM_BASE,
13599 + IFXUSB_FIFODBG_BASE
13602 + goto ifxusb_driver_probe_fail;
13605 + #if defined(__DO_OC_INT__)
13606 + IFXUSB_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for irq%d\n", IFXUSB_OC_IRQ);
13607 + #if defined(__IS_DUAL__)
13608 + request_irq((unsigned int)IFXUSB_OC_IRQ, &ifx_hcd_oc_irq,
13609 +// SA_INTERRUPT|SA_SHIRQ, "ifxusb_oc", (void *)&ifxusb_hcd_1);
13610 + IRQF_DISABLED | IRQF_SHARED, "ifxusb_oc", (void *)&ifxusb_hcd_1);
13611 + oc_int_id=&ifxusb_hcd_1;
13613 + request_irq((unsigned int)IFXUSB_OC_IRQ, &ifx_hcd_oc_irq,
13614 +// SA_INTERRUPT|SA_SHIRQ, "ifxusb_oc", (void *)&ifxusb_hcd);
13615 + IRQF_DISABLED | IRQF_SHARED, "ifxusb_oc", (void *)&ifxusb_hcd);
13616 + oc_int_id=&ifxusb_hcd;
13618 + oc_int_installed=1;
13620 + #if defined(__DO_OC_INT_ENABLE__)
13621 + ifxusb_oc_int_on();
13627 + #ifdef __IS_DEVICE__
13628 + memset(&ifxusb_pcd, 0, sizeof(ifxpcd_pcd_t));
13629 + ifxusb_pcd.core_if.core_name=(char *)&ifxusb_pcd_name[0];
13631 + ifxusb_pcd.dev=&_dev->dev;
13633 + #if defined(__IS_FIRST__)
13634 + ifxusb_pcd.core_if.core_no=0;
13635 + retval = ifxusb_driver_probe_d(&ifxusb_pcd,
13637 + IFXUSB1_IOMEM_BASE,
13638 + IFXUSB1_FIFOMEM_BASE,
13639 + IFXUSB1_FIFODBG_BASE
13641 + #elif defined(__IS_SECOND__)
13642 + ifxusb_pcd.core_if.core_no=1;
13643 + retval = ifxusb_driver_probe_d(&ifxusb_pcd,
13645 + IFXUSB2_IOMEM_BASE,
13646 + IFXUSB2_FIFOMEM_BASE,
13647 + IFXUSB2_FIFODBG_BASE
13650 + ifxusb_pcd.core_if.core_no=0;
13651 + retval = ifxusb_driver_probe_d(&ifxusb_pcd,
13653 + IFXUSB_IOMEM_BASE,
13654 + IFXUSB_FIFOMEM_BASE,
13655 + IFXUSB_FIFODBG_BASE
13659 + goto ifxusb_driver_probe_fail;
13662 + ifxusb_attr_create(&_dev->dev);
13666 +ifxusb_driver_probe_fail:
13667 + ifxusb_driver_remove(_dev);
13674 + \brief This function is called when the ifxusb_driver is installed with the insmod command.
13678 +static struct platform_driver ifxusb_driver = {
13680 + .name = ifxusb_driver_name,
13681 + .owner = THIS_MODULE,
13683 + .probe = ifxusb_driver_probe,
13684 + .remove = ifxusb_driver_remove,
13687 +int __init ifxusb_driver_init(void)
13691 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13692 + IFX_PRINT("%s: version %s\n", ifxusb_driver_name, IFXUSB_VERSION);
13694 + retval = platform_driver_register(&ifxusb_driver);
13696 + if (retval < 0) {
13697 + IFX_ERROR("%s retval=%d\n", __func__, retval);
13704 + int __init ifxusb_driver_init(void)
13707 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13708 + IFX_PRINT("%s: version %s\n", ifxusb_driver_name, IFXUSB_VERSION);
13709 + retval = ifxusb_driver_probe();
13711 + if (retval < 0) {
13712 + IFX_ERROR("%s retval=%d\n", __func__, retval);
13720 +module_init(ifxusb_driver_init);
13724 + \brief This function is called when the driver is removed from the kernel
13725 + with the rmmod command. The driver unregisters itself with its bus
13729 +void __exit ifxusb_driver_cleanup(void)
13731 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13733 + platform_driver_unregister(&ifxusb_driver);
13735 + IFX_PRINT("%s module removed\n", ifxusb_driver_name);
13738 + void __exit ifxusb_driver_cleanup(void)
13740 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13741 + ifxusb_driver_remove();
13742 + IFX_PRINT("%s module removed\n", ifxusb_driver_name);
13745 +module_exit(ifxusb_driver_cleanup);
13749 +MODULE_DESCRIPTION(USB_DRIVER_DESC);
13750 +MODULE_AUTHOR("Infineon");
13751 +MODULE_LICENSE("GPL");
13755 +// Parameters set when loaded
13756 +//static long dbg_lvl =0xFFFFFFFF;
13757 +static long dbg_lvl =0;
13758 +static short dma_burst_size =-1;
13759 +static short speed =-1;
13760 +static long data_fifo_size =-1;
13761 +#ifdef __IS_DEVICE__
13762 + static long rx_fifo_size =-1;
13763 + #ifdef __DED_FIFO__
13764 + static long tx_fifo_size_00 =-1;
13765 + static long tx_fifo_size_01 =-1;
13766 + static long tx_fifo_size_02 =-1;
13767 + static long tx_fifo_size_03 =-1;
13768 + static long tx_fifo_size_04 =-1;
13769 + static long tx_fifo_size_05 =-1;
13770 + static long tx_fifo_size_06 =-1;
13771 + static long tx_fifo_size_07 =-1;
13772 + static long tx_fifo_size_08 =-1;
13773 + static long tx_fifo_size_09 =-1;
13774 + static long tx_fifo_size_10 =-1;
13775 + static long tx_fifo_size_11 =-1;
13776 + static long tx_fifo_size_12 =-1;
13777 + static long tx_fifo_size_13 =-1;
13778 + static long tx_fifo_size_14 =-1;
13779 + static long tx_fifo_size_15 =-1;
13780 + static short thr_ctl=-1;
13781 + static long tx_thr_length =-1;
13782 + static long rx_thr_length =-1;
13784 + static long nperio_tx_fifo_size =-1;
13785 + static long perio_tx_fifo_size_01 =-1;
13786 + static long perio_tx_fifo_size_02 =-1;
13787 + static long perio_tx_fifo_size_03 =-1;
13788 + static long perio_tx_fifo_size_04 =-1;
13789 + static long perio_tx_fifo_size_05 =-1;
13790 + static long perio_tx_fifo_size_06 =-1;
13791 + static long perio_tx_fifo_size_07 =-1;
13792 + static long perio_tx_fifo_size_08 =-1;
13793 + static long perio_tx_fifo_size_09 =-1;
13794 + static long perio_tx_fifo_size_10 =-1;
13795 + static long perio_tx_fifo_size_11 =-1;
13796 + static long perio_tx_fifo_size_12 =-1;
13797 + static long perio_tx_fifo_size_13 =-1;
13798 + static long perio_tx_fifo_size_14 =-1;
13799 + static long perio_tx_fifo_size_15 =-1;
13801 + static short dev_endpoints =-1;
13804 +#ifdef __IS_HOST__
13805 + static long rx_fifo_size =-1;
13806 + static long nperio_tx_fifo_size =-1;
13807 + static long perio_tx_fifo_size =-1;
13808 + static short host_channels =-1;
13811 +static long max_transfer_size =-1;
13812 +static long max_packet_count =-1;
13813 +static long phy_utmi_width =-1;
13814 +static long turn_around_time_hs =-1;
13815 +static long turn_around_time_fs =-1;
13816 +static long timeout_cal_hs =-1;
13817 +static long timeout_cal_fs =-1;
13820 + \brief Parsing the parameters taken when module load
13822 +static void parse_parms(void)
13825 + IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
13826 + #ifdef __IS_HOST__
13827 + h_dbg_lvl=dbg_lvl;
13829 + #ifdef __IS_DEVICE__
13830 + d_dbg_lvl=dbg_lvl;
13833 + switch(dma_burst_size)
13840 + ifxusb_module_params.dma_burst_size=dma_burst_size;
13843 + ifxusb_module_params.dma_burst_size=default_param_dma_burst_size;
13846 + if(speed==0 || speed==1)
13847 + ifxusb_module_params.speed=speed;
13849 + ifxusb_module_params.speed=default_param_speed;
13851 + if(max_transfer_size>=2048 && max_transfer_size<=65535)
13852 + ifxusb_module_params.max_transfer_size=max_transfer_size;
13854 + ifxusb_module_params.max_transfer_size=default_param_max_transfer_size;
13856 + if(max_packet_count>=15 && max_packet_count<=511)
13857 + ifxusb_module_params.max_packet_count=max_packet_count;
13859 + ifxusb_module_params.max_packet_count=default_param_max_packet_count;
13861 + switch(phy_utmi_width)
13865 + ifxusb_module_params.phy_utmi_width=phy_utmi_width;
13868 + ifxusb_module_params.phy_utmi_width=default_param_phy_utmi_width;
13871 + if(turn_around_time_hs>=0 && turn_around_time_hs<=7)
13872 + ifxusb_module_params.turn_around_time_hs=turn_around_time_hs;
13874 + ifxusb_module_params.turn_around_time_hs=default_param_turn_around_time_hs;
13876 + if(turn_around_time_fs>=0 && turn_around_time_fs<=7)
13877 + ifxusb_module_params.turn_around_time_fs=turn_around_time_fs;
13879 + ifxusb_module_params.turn_around_time_fs=default_param_turn_around_time_fs;
13881 + if(timeout_cal_hs>=0 && timeout_cal_hs<=7)
13882 + ifxusb_module_params.timeout_cal_hs=timeout_cal_hs;
13884 + ifxusb_module_params.timeout_cal_hs=default_param_timeout_cal_hs;
13886 + if(timeout_cal_fs>=0 && timeout_cal_fs<=7)
13887 + ifxusb_module_params.timeout_cal_fs=timeout_cal_fs;
13889 + ifxusb_module_params.timeout_cal_fs=default_param_timeout_cal_fs;
13891 + if(data_fifo_size>=32 && data_fifo_size<=32768)
13892 + ifxusb_module_params.data_fifo_size=data_fifo_size;
13894 + ifxusb_module_params.data_fifo_size=default_param_data_fifo_size;
13896 + #ifdef __IS_HOST__
13897 + if(host_channels>=1 && host_channels<=16)
13898 + ifxusb_module_params.host_channels=host_channels;
13900 + ifxusb_module_params.host_channels=default_param_host_channels;
13902 + if(rx_fifo_size>=16 && rx_fifo_size<=32768)
13903 + ifxusb_module_params.rx_fifo_size=rx_fifo_size;
13905 + ifxusb_module_params.rx_fifo_size=default_param_rx_fifo_size;
13907 + if(nperio_tx_fifo_size>=16 && nperio_tx_fifo_size<=32768)
13908 + ifxusb_module_params.nperio_tx_fifo_size=nperio_tx_fifo_size;
13910 + ifxusb_module_params.nperio_tx_fifo_size=default_param_nperio_tx_fifo_size;
13912 + if(perio_tx_fifo_size>=16 && perio_tx_fifo_size<=32768)
13913 + ifxusb_module_params.perio_tx_fifo_size=perio_tx_fifo_size;
13915 + ifxusb_module_params.perio_tx_fifo_size=default_param_perio_tx_fifo_size;
13916 + #endif //__IS_HOST__
13918 + #ifdef __IS_DEVICE__
13919 + if(rx_fifo_size>=16 && rx_fifo_size<=32768)
13920 + ifxusb_module_params.rx_fifo_size=rx_fifo_size;
13922 + ifxusb_module_params.rx_fifo_size=default_param_rx_fifo_size;
13923 + #ifdef __DED_FIFO__
13924 + if(tx_fifo_size_00>=16 && tx_fifo_size_00<=32768)
13925 + ifxusb_module_params.tx_fifo_size[ 0]=tx_fifo_size_00;
13927 + ifxusb_module_params.tx_fifo_size[ 0]=default_param_tx_fifo_size_00;
13928 + if(tx_fifo_size_01>=0 && tx_fifo_size_01<=32768)
13929 + ifxusb_module_params.tx_fifo_size[ 1]=tx_fifo_size_01;
13931 + ifxusb_module_params.tx_fifo_size[ 1]=default_param_tx_fifo_size_01;
13932 + if(tx_fifo_size_02>=0 && tx_fifo_size_02<=32768)
13933 + ifxusb_module_params.tx_fifo_size[ 2]=tx_fifo_size_02;
13935 + ifxusb_module_params.tx_fifo_size[ 2]=default_param_tx_fifo_size_02;
13936 + if(tx_fifo_size_03>=0 && tx_fifo_size_03<=32768)
13937 + ifxusb_module_params.tx_fifo_size[ 3]=tx_fifo_size_03;
13939 + ifxusb_module_params.tx_fifo_size[ 3]=default_param_tx_fifo_size_03;
13940 + if(tx_fifo_size_04>=0 && tx_fifo_size_04<=32768)
13941 + ifxusb_module_params.tx_fifo_size[ 4]=tx_fifo_size_04;
13943 + ifxusb_module_params.tx_fifo_size[ 4]=default_param_tx_fifo_size_04;
13944 + if(tx_fifo_size_05>=0 && tx_fifo_size_05<=32768)
13945 + ifxusb_module_params.tx_fifo_size[ 5]=tx_fifo_size_05;
13947 + ifxusb_module_params.tx_fifo_size[ 5]=default_param_tx_fifo_size_05;
13948 + if(tx_fifo_size_06>=0 && tx_fifo_size_06<=32768)
13949 + ifxusb_module_params.tx_fifo_size[ 6]=tx_fifo_size_06;
13951 + ifxusb_module_params.tx_fifo_size[ 6]=default_param_tx_fifo_size_06;
13952 + if(tx_fifo_size_07>=0 && tx_fifo_size_07<=32768)
13953 + ifxusb_module_params.tx_fifo_size[ 7]=tx_fifo_size_07;
13955 + ifxusb_module_params.tx_fifo_size[ 7]=default_param_tx_fifo_size_07;
13956 + if(tx_fifo_size_08>=0 && tx_fifo_size_08<=32768)
13957 + ifxusb_module_params.tx_fifo_size[ 8]=tx_fifo_size_08;
13959 + ifxusb_module_params.tx_fifo_size[ 8]=default_param_tx_fifo_size_08;
13960 + if(tx_fifo_size_09>=0 && tx_fifo_size_09<=32768)
13961 + ifxusb_module_params.tx_fifo_size[ 9]=tx_fifo_size_09;
13963 + ifxusb_module_params.tx_fifo_size[ 9]=default_param_tx_fifo_size_09;
13964 + if(tx_fifo_size_10>=0 && tx_fifo_size_10<=32768)
13965 + ifxusb_module_params.tx_fifo_size[10]=tx_fifo_size_10;
13967 + ifxusb_module_params.tx_fifo_size[10]=default_param_tx_fifo_size_10;
13968 + if(tx_fifo_size_11>=0 && tx_fifo_size_11<=32768)
13969 + ifxusb_module_params.tx_fifo_size[11]=tx_fifo_size_11;
13971 + ifxusb_module_params.tx_fifo_size[11]=default_param_tx_fifo_size_11;
13972 + if(tx_fifo_size_12>=0 && tx_fifo_size_12<=32768)
13973 + ifxusb_module_params.tx_fifo_size[12]=tx_fifo_size_12;
13975 + ifxusb_module_params.tx_fifo_size[12]=default_param_tx_fifo_size_12;
13976 + if(tx_fifo_size_13>=0 && tx_fifo_size_13<=32768)
13977 + ifxusb_module_params.tx_fifo_size[13]=tx_fifo_size_13;
13979 + ifxusb_module_params.tx_fifo_size[13]=default_param_tx_fifo_size_13;
13980 + if(tx_fifo_size_14>=0 && tx_fifo_size_14<=32768)
13981 + ifxusb_module_params.tx_fifo_size[14]=tx_fifo_size_14;
13983 + ifxusb_module_params.tx_fifo_size[14]=default_param_tx_fifo_size_14;
13984 + if(tx_fifo_size_15>=0 && tx_fifo_size_15<=32768)
13985 + ifxusb_module_params.tx_fifo_size[15]=tx_fifo_size_15;
13987 + ifxusb_module_params.tx_fifo_size[15]=default_param_tx_fifo_size_15;
13988 + if(thr_ctl==0 || thr_ctl==1)
13989 + ifxusb_module_params.thr_ctl=thr_ctl;
13991 + ifxusb_module_params.thr_ctl=default_param_thr_ctl;
13992 + if(tx_thr_length>=16 && tx_thr_length<=511)
13993 + ifxusb_module_params.tx_thr_length=tx_thr_length;
13995 + ifxusb_module_params.tx_thr_length=default_param_tx_thr_length;
13996 + if(rx_thr_length>=16 && rx_thr_length<=511)
13997 + ifxusb_module_params.rx_thr_length=rx_thr_length;
13999 + ifxusb_module_params.rx_thr_length=default_param_rx_thr_length;
14000 + #else //__DED_FIFO__
14001 + if(nperio_tx_fifo_size>=16 && nperio_tx_fifo_size<=32768)
14002 + ifxusb_module_params.tx_fifo_size[ 0]=nperio_tx_fifo_size;
14004 + ifxusb_module_params.tx_fifo_size[ 0]=default_param_nperio_tx_fifo_size;
14005 + if(perio_tx_fifo_size_01>=0 && perio_tx_fifo_size_01<=32768)
14006 + ifxusb_module_params.tx_fifo_size[ 1]=perio_tx_fifo_size_01;
14008 + ifxusb_module_params.tx_fifo_size[ 1]=default_param_perio_tx_fifo_size_01;
14009 + if(perio_tx_fifo_size_02>=0 && perio_tx_fifo_size_02<=32768)
14010 + ifxusb_module_params.tx_fifo_size[ 2]=perio_tx_fifo_size_02;
14012 + ifxusb_module_params.tx_fifo_size[ 2]=default_param_perio_tx_fifo_size_02;
14013 + if(perio_tx_fifo_size_03>=0 && perio_tx_fifo_size_03<=32768)
14014 + ifxusb_module_params.tx_fifo_size[ 3]=perio_tx_fifo_size_03;
14016 + ifxusb_module_params.tx_fifo_size[ 3]=default_param_perio_tx_fifo_size_03;
14017 + if(perio_tx_fifo_size_04>=0 && perio_tx_fifo_size_04<=32768)
14018 + ifxusb_module_params.tx_fifo_size[ 4]=perio_tx_fifo_size_04;
14020 + ifxusb_module_params.tx_fifo_size[ 4]=default_param_perio_tx_fifo_size_04;
14021 + if(perio_tx_fifo_size_05>=0 && perio_tx_fifo_size_05<=32768)
14022 + ifxusb_module_params.tx_fifo_size[ 5]=perio_tx_fifo_size_05;
14024 + ifxusb_module_params.tx_fifo_size[ 5]=default_param_perio_tx_fifo_size_05;
14025 + if(perio_tx_fifo_size_06>=0 && perio_tx_fifo_size_06<=32768)
14026 + ifxusb_module_params.tx_fifo_size[ 6]=perio_tx_fifo_size_06;
14028 + ifxusb_module_params.tx_fifo_size[ 6]=default_param_perio_tx_fifo_size_06;
14029 + if(perio_tx_fifo_size_07>=0 && perio_tx_fifo_size_07<=32768)
14030 + ifxusb_module_params.tx_fifo_size[ 7]=perio_tx_fifo_size_07;
14032 + ifxusb_module_params.tx_fifo_size[ 7]=default_param_perio_tx_fifo_size_07;
14033 + if(perio_tx_fifo_size_08>=0 && perio_tx_fifo_size_08<=32768)
14034 + ifxusb_module_params.tx_fifo_size[ 8]=perio_tx_fifo_size_08;
14036 + ifxusb_module_params.tx_fifo_size[ 8]=default_param_perio_tx_fifo_size_08;
14037 + if(perio_tx_fifo_size_09>=0 && perio_tx_fifo_size_09<=32768)
14038 + ifxusb_module_params.tx_fifo_size[ 9]=perio_tx_fifo_size_09;
14040 + ifxusb_module_params.tx_fifo_size[ 9]=default_param_perio_tx_fifo_size_09;
14041 + if(perio_tx_fifo_size_10>=0 && perio_tx_fifo_size_10<=32768)
14042 + ifxusb_module_params.tx_fifo_size[10]=perio_tx_fifo_size_10;
14044 + ifxusb_module_params.tx_fifo_size[10]=default_param_perio_tx_fifo_size_10;
14045 + if(perio_tx_fifo_size_11>=0 && perio_tx_fifo_size_11<=32768)
14046 + ifxusb_module_params.tx_fifo_size[11]=perio_tx_fifo_size_11;
14048 + ifxusb_module_params.tx_fifo_size[11]=default_param_perio_tx_fifo_size_11;
14049 + if(perio_tx_fifo_size_12>=0 && perio_tx_fifo_size_12<=32768)
14050 + ifxusb_module_params.tx_fifo_size[12]=perio_tx_fifo_size_12;
14052 + ifxusb_module_params.tx_fifo_size[12]=default_param_perio_tx_fifo_size_12;
14053 + if(perio_tx_fifo_size_13>=0 && perio_tx_fifo_size_13<=32768)
14054 + ifxusb_module_params.tx_fifo_size[13]=perio_tx_fifo_size_13;
14056 + ifxusb_module_params.tx_fifo_size[13]=default_param_perio_tx_fifo_size_13;
14057 + if(perio_tx_fifo_size_14>=0 && perio_tx_fifo_size_14<=32768)
14058 + ifxusb_module_params.tx_fifo_size[14]=perio_tx_fifo_size_14;
14060 + ifxusb_module_params.tx_fifo_size[14]=default_param_perio_tx_fifo_size_14;
14061 + if(perio_tx_fifo_size_15>=0 && perio_tx_fifo_size_15<=32768)
14062 + ifxusb_module_params.tx_fifo_size[15]=perio_tx_fifo_size_15;
14064 + ifxusb_module_params.tx_fifo_size[15]=default_param_perio_tx_fifo_size_15;
14065 + #endif //__DED_FIFO__
14066 + #endif //__IS_DEVICE__
14075 +module_param(dbg_lvl, long, 0444);
14076 +MODULE_PARM_DESC(dbg_lvl, "Debug level.");
14078 +module_param(dma_burst_size, short, 0444);
14079 +MODULE_PARM_DESC(dma_burst_size, "DMA Burst Size 0, 1, 4, 8, 16");
14081 +module_param(speed, short, 0444);
14082 +MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed");
14084 +module_param(data_fifo_size, long, 0444);
14085 +MODULE_PARM_DESC(data_fifo_size, "Total number of words in the data FIFO memory 32-32768");
14087 +#ifdef __IS_DEVICE__
14088 + module_param(rx_fifo_size, long, 0444);
14089 + MODULE_PARM_DESC(rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
14091 + #ifdef __DED_FIFO__
14092 + module_param(tx_fifo_size_00, long, 0444);
14093 + MODULE_PARM_DESC(tx_fifo_size_00, "Number of words in the Tx FIFO #00 16-32768");
14094 + module_param(tx_fifo_size_01, long, 0444);
14095 + MODULE_PARM_DESC(tx_fifo_size_01, "Number of words in the Tx FIFO #01 0-32768");
14096 + module_param(tx_fifo_size_02, long, 0444);
14097 + MODULE_PARM_DESC(tx_fifo_size_02, "Number of words in the Tx FIFO #02 0-32768");
14098 + module_param(tx_fifo_size_03, long, 0444);
14099 + MODULE_PARM_DESC(tx_fifo_size_03, "Number of words in the Tx FIFO #03 0-32768");
14100 + module_param(tx_fifo_size_04, long, 0444);
14101 + MODULE_PARM_DESC(tx_fifo_size_04, "Number of words in the Tx FIFO #04 0-32768");
14102 + module_param(tx_fifo_size_05, long, 0444);
14103 + MODULE_PARM_DESC(tx_fifo_size_05, "Number of words in the Tx FIFO #05 0-32768");
14104 + module_param(tx_fifo_size_06, long, 0444);
14105 + MODULE_PARM_DESC(tx_fifo_size_06, "Number of words in the Tx FIFO #06 0-32768");
14106 + module_param(tx_fifo_size_07, long, 0444);
14107 + MODULE_PARM_DESC(tx_fifo_size_07, "Number of words in the Tx FIFO #07 0-32768");
14108 + module_param(tx_fifo_size_08, long, 0444);
14109 + MODULE_PARM_DESC(tx_fifo_size_08, "Number of words in the Tx FIFO #08 0-32768");
14110 + module_param(tx_fifo_size_09, long, 0444);
14111 + MODULE_PARM_DESC(tx_fifo_size_09, "Number of words in the Tx FIFO #09 0-32768");
14112 + module_param(tx_fifo_size_10, long, 0444);
14113 + MODULE_PARM_DESC(tx_fifo_size_10, "Number of words in the Tx FIFO #10 0-32768");
14114 + module_param(tx_fifo_size_11, long, 0444);
14115 + MODULE_PARM_DESC(tx_fifo_size_11, "Number of words in the Tx FIFO #11 0-32768");
14116 + module_param(tx_fifo_size_12, long, 0444);
14117 + MODULE_PARM_DESC(tx_fifo_size_12, "Number of words in the Tx FIFO #12 0-32768");
14118 + module_param(tx_fifo_size_13, long, 0444);
14119 + MODULE_PARM_DESC(tx_fifo_size_13, "Number of words in the Tx FIFO #13 0-32768");
14120 + module_param(tx_fifo_size_14, long, 0444);
14121 + MODULE_PARM_DESC(tx_fifo_size_14, "Number of words in the Tx FIFO #14 0-32768");
14122 + module_param(tx_fifo_size_15, long, 0444);
14123 + MODULE_PARM_DESC(tx_fifo_size_15, "Number of words in the Tx FIFO #15 0-32768");
14125 + module_param(thr_ctl, short, 0444);
14126 + MODULE_PARM_DESC(thr_ctl, "0=Without 1=With Theshold Ctrl");
14128 + module_param(tx_thr_length, long, 0444);
14129 + MODULE_PARM_DESC(tx_thr_length, "TX Threshold length");
14131 + module_param(rx_thr_length, long, 0444);
14132 + MODULE_PARM_DESC(rx_thr_length, "RX Threshold length");
14135 + module_param(nperio_tx_fifo_size, long, 0444);
14136 + MODULE_PARM_DESC(nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
14138 + module_param(perio_tx_fifo_size_01, long, 0444);
14139 + MODULE_PARM_DESC(perio_tx_fifo_size_01, "Number of words in the periodic Tx FIFO #01 0-32768");
14140 + module_param(perio_tx_fifo_size_02, long, 0444);
14141 + MODULE_PARM_DESC(perio_tx_fifo_size_02, "Number of words in the periodic Tx FIFO #02 0-32768");
14142 + module_param(perio_tx_fifo_size_03, long, 0444);
14143 + MODULE_PARM_DESC(perio_tx_fifo_size_03, "Number of words in the periodic Tx FIFO #03 0-32768");
14144 + module_param(perio_tx_fifo_size_04, long, 0444);
14145 + MODULE_PARM_DESC(perio_tx_fifo_size_04, "Number of words in the periodic Tx FIFO #04 0-32768");
14146 + module_param(perio_tx_fifo_size_05, long, 0444);
14147 + MODULE_PARM_DESC(perio_tx_fifo_size_05, "Number of words in the periodic Tx FIFO #05 0-32768");
14148 + module_param(perio_tx_fifo_size_06, long, 0444);
14149 + MODULE_PARM_DESC(perio_tx_fifo_size_06, "Number of words in the periodic Tx FIFO #06 0-32768");
14150 + module_param(perio_tx_fifo_size_07, long, 0444);
14151 + MODULE_PARM_DESC(perio_tx_fifo_size_07, "Number of words in the periodic Tx FIFO #07 0-32768");
14152 + module_param(perio_tx_fifo_size_08, long, 0444);
14153 + MODULE_PARM_DESC(perio_tx_fifo_size_08, "Number of words in the periodic Tx FIFO #08 0-32768");
14154 + module_param(perio_tx_fifo_size_09, long, 0444);
14155 + MODULE_PARM_DESC(perio_tx_fifo_size_09, "Number of words in the periodic Tx FIFO #09 0-32768");
14156 + module_param(perio_tx_fifo_size_10, long, 0444);
14157 + MODULE_PARM_DESC(perio_tx_fifo_size_10, "Number of words in the periodic Tx FIFO #10 0-32768");
14158 + module_param(perio_tx_fifo_size_11, long, 0444);
14159 + MODULE_PARM_DESC(perio_tx_fifo_size_11, "Number of words in the periodic Tx FIFO #11 0-32768");
14160 + module_param(perio_tx_fifo_size_12, long, 0444);
14161 + MODULE_PARM_DESC(perio_tx_fifo_size_12, "Number of words in the periodic Tx FIFO #12 0-32768");
14162 + module_param(perio_tx_fifo_size_13, long, 0444);
14163 + MODULE_PARM_DESC(perio_tx_fifo_size_13, "Number of words in the periodic Tx FIFO #13 0-32768");
14164 + module_param(perio_tx_fifo_size_14, long, 0444);
14165 + MODULE_PARM_DESC(perio_tx_fifo_size_14, "Number of words in the periodic Tx FIFO #14 0-32768");
14166 + module_param(perio_tx_fifo_size_15, long, 0444);
14167 + MODULE_PARM_DESC(perio_tx_fifo_size_15, "Number of words in the periodic Tx FIFO #15 0-32768");
14168 + #endif//__DED_FIFO__
14169 + module_param(dev_endpoints, short, 0444);
14170 + MODULE_PARM_DESC(dev_endpoints, "The number of endpoints in addition to EP0 available for device mode 1-15");
14173 +#ifdef __IS_HOST__
14174 + module_param(rx_fifo_size, long, 0444);
14175 + MODULE_PARM_DESC(rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
14177 + module_param(nperio_tx_fifo_size, long, 0444);
14178 + MODULE_PARM_DESC(nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
14180 + module_param(perio_tx_fifo_size, long, 0444);
14181 + MODULE_PARM_DESC(perio_tx_fifo_size, "Number of words in the host periodic Tx FIFO 16-32768");
14183 + module_param(host_channels, short, 0444);
14184 + MODULE_PARM_DESC(host_channels, "The number of host channel registers to use 1-16");
14187 +module_param(max_transfer_size, long, 0444);
14188 +MODULE_PARM_DESC(max_transfer_size, "The maximum transfer size supported in bytes 2047-65535");
14190 +module_param(max_packet_count, long, 0444);
14191 +MODULE_PARM_DESC(max_packet_count, "The maximum number of packets in a transfer 15-511");
14193 +module_param(phy_utmi_width, long, 0444);
14194 +MODULE_PARM_DESC(phy_utmi_width, "Specifies the UTMI+ Data Width 8 or 16 bits");
14196 +module_param(turn_around_time_hs, long, 0444);
14197 +MODULE_PARM_DESC(turn_around_time_hs, "Turn-Around time for HS");
14199 +module_param(turn_around_time_fs, long, 0444);
14200 +MODULE_PARM_DESC(turn_around_time_fs, "Turn-Around time for FS");
14202 +module_param(timeout_cal_hs, long, 0444);
14203 +MODULE_PARM_DESC(timeout_cal_hs, "Timeout Cal for HS");
14205 +module_param(timeout_cal_fs, long, 0444);
14206 +MODULE_PARM_DESC(timeout_cal_fs, "Timeout Cal for FS");
14209 diff --git a/drivers/usb/ifxhcd/ifxusb_plat.h b/drivers/usb/ifxhcd/ifxusb_plat.h
14210 new file mode 100644
14211 index 0000000..a50294f
14213 +++ b/drivers/usb/ifxhcd/ifxusb_plat.h
14215 +/*****************************************************************************
14216 + ** FILE NAME : ifxusb_plat.h
14217 + ** PROJECT : IFX USB sub-system V3
14218 + ** MODULES : IFX USB sub-system Host and Device driver
14219 + ** SRC VERSION : 1.0
14220 + ** DATE : 1/Jan/2009
14221 + ** AUTHOR : Chen, Howard
14222 + ** DESCRIPTION : This file contains the Platform Specific constants, interfaces
14223 + ** (functions and macros).
14225 + ** COMPILER : gcc
14226 + ** REFERENCE : IFX hardware ref handbook for each plateforms
14228 + ** Version Control Section **
14232 + ** $Log$ Revision history
14233 + *****************************************************************************/
14237 + \defgroup IFXUSB_PLATEFORM_DEFINITION Platform Specific constants, interfaces (functions and macros).
14238 + \ingroup IFXUSB_DRIVER_V3
14239 + \brief Maintain plateform specific definitions and macros in this file.
14240 + Each plateform has its own definition zone.
14244 + \defgroup IFXUSB_PLATEFORM_MEM_ADDR Definition of memory address and size and default parameters
14245 + \ingroup IFXUSB_PLATEFORM_DEFINITION
14249 + \defgroup IFXUSB_DBG_ROUTINE Routines for debug message
14250 + \ingroup IFXUSB_PLATEFORM_DEFINITION
14254 +/*! \file ifxusb_plat.h
14255 + \ingroup IFXUSB_DRIVER_V3
14256 + \brief This file contains the Platform Specific constants, interfaces (functions and macros).
14259 +#if !defined(__IFXUSB_PLAT_H__)
14260 +#define __IFXUSB_PLAT_H__
14263 +#include <linux/types.h>
14264 +#include <linux/slab.h>
14265 +#include <linux/list.h>
14266 +#include <linux/delay.h>
14267 +#include <asm/io.h>
14270 +#define IFXUSB_IOMEM_SIZE 0x00001000
14271 +#define IFXUSB_FIFOMEM_SIZE 0x00010000
14272 +#define IFXUSB_FIFODBG_SIZE 0x00020000
14277 + \addtogroup IFXUSB_PLATEFORM_MEM_ADDR
14280 +#if defined(__UEIP__)
14281 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
14282 +// #define IFXUSB_IRQ 54
14283 + #define IFXUSB_IOMEM_BASE 0x1e101000
14284 + #define IFXUSB_FIFOMEM_BASE 0x1e120000
14285 + #define IFXUSB_FIFODBG_BASE 0x1e140000
14286 +// #define IFXUSB_OC_IRQ 151
14288 + #ifndef DANUBE_RCU_BASE_ADDR
14289 + #define DANUBE_RCU_BASE_ADDR (0xBF203000)
14292 + #ifndef DANUBE_CGU
14293 + #define DANUBE_CGU (0xBF103000)
14295 + #ifndef DANUBE_CGU_IFCCR
14296 + #define DANUBE_CGU_IFCCR ((volatile unsigned long *)(DANUBE_CGU+ 0x0018))
14298 + #ifndef DANUBE_PMU
14299 + #define DANUBE_PMU (KSEG1+0x1F102000)
14301 + #ifndef DANUBE_PMU_PWDCR
14302 + #define DANUBE_PMU_PWDCR ((volatile unsigned long *)(DANUBE_PMU+0x001C))
14305 + #ifndef DANUBE_GPIO_P0_OUT
14306 + #define DANUBE_GPIO_P0_OUT (0xBF103000+0x10)
14307 + #define DANUBE_GPIO_P0_DIR (0xBF103000+0x18)
14308 + #define DANUBE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
14309 + #define DANUBE_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
14310 + #define DANUBE_GPIO_P0_OD (0xBF103000+0x24)
14311 + #define DANUBE_GPIO_P0_PUDSEL (0xBF103000+0x2C)
14312 + #define DANUBE_GPIO_P0_PUDEN (0xBF103000+0x30)
14313 + #define DANUBE_GPIO_P1_OUT (0xBF103000+0x40)
14314 + #define DANUBE_GPIO_P1_DIR (0xBF103000+0x48)
14315 + #define DANUBE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
14316 + #define DANUBE_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
14317 + #define DANUBE_GPIO_P1_OD (0xBF103000+0x54)
14318 + #define DANUBE_GPIO_P1_PUDSEL (0xBF103000+0x5C)
14319 + #define DANUBE_GPIO_P1_PUDEN (0xBF103000+0x60)
14322 + #define DANUBE_RCU_USBCFG ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x18))
14323 + #define DANUBE_RCU_RESET ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x10))
14324 + #define DANUBE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
14325 + #define DANUBE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
14326 + #define DANUBE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
14328 + #define default_param_dma_burst_size 4
14330 + #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
14332 + #define default_param_max_transfer_size -1 //(Max, hwcfg)
14333 + #define default_param_max_packet_count -1 //(Max, hwcfg)
14334 + #define default_param_phy_utmi_width 16
14336 + #define default_param_turn_around_time_hs 4
14337 + #define default_param_turn_around_time_fs 4
14338 + #define default_param_timeout_cal_hs -1 //(NoChange)
14339 + #define default_param_timeout_cal_fs -1 //(NoChange)
14341 + #define default_param_data_fifo_size -1 //(Max, hwcfg)
14343 + #ifdef __IS_HOST__
14344 + #define default_param_host_channels -1 //(Max, hwcfg)
14345 + #define default_param_rx_fifo_size 640
14346 + #define default_param_nperio_tx_fifo_size 640
14347 + #define default_param_perio_tx_fifo_size 768
14348 + #endif //__IS_HOST__
14350 + #ifdef __IS_DEVICE__
14351 + #ifdef __DED_INTR__
14352 + #define default_param_rx_fifo_size 1024
14353 + #define default_param_nperio_tx_fifo_size 1016
14354 + #define default_param_perio_tx_fifo_size_01 8
14356 + #define default_param_rx_fifo_size 1024
14357 + #define default_param_nperio_tx_fifo_size 1024
14358 + #define default_param_perio_tx_fifo_size_01 0
14360 + #define default_param_perio_tx_fifo_size_02 0
14361 + #define default_param_perio_tx_fifo_size_03 0
14362 + #define default_param_perio_tx_fifo_size_04 0
14363 + #define default_param_perio_tx_fifo_size_05 0
14364 + #define default_param_perio_tx_fifo_size_06 0
14365 + #define default_param_perio_tx_fifo_size_07 0
14366 + #define default_param_perio_tx_fifo_size_08 0
14367 + #define default_param_perio_tx_fifo_size_09 0
14368 + #define default_param_perio_tx_fifo_size_10 0
14369 + #define default_param_perio_tx_fifo_size_11 0
14370 + #define default_param_perio_tx_fifo_size_12 0
14371 + #define default_param_perio_tx_fifo_size_13 0
14372 + #define default_param_perio_tx_fifo_size_14 0
14373 + #define default_param_perio_tx_fifo_size_15 0
14374 + #endif //__IS_DEVICE__
14376 + #elif defined(__IS_AMAZON_SE__)
14377 + //#include <asm/amazon_se/amazon_se.h>
14378 + //#include <asm/amazon_se/irq.h>
14380 +// #define IFXUSB_IRQ 31
14381 + #define IFXUSB_IOMEM_BASE 0x1e101000
14382 + #define IFXUSB_FIFOMEM_BASE 0x1e120000
14383 + #define IFXUSB_FIFODBG_BASE 0x1e140000
14384 +// #define IFXUSB_OC_IRQ 20
14386 + #ifndef AMAZON_SE_RCU_BASE_ADDR
14387 + #define AMAZON_SE_RCU_BASE_ADDR (0xBF203000)
14389 + #define AMAZON_SE_RCU_USBCFG ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x18))
14390 + #define AMAZON_SE_RCU_RESET ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x10))
14391 + #define AMAZON_SE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
14392 + #define AMAZON_SE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
14393 + #define AMAZON_SE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
14395 + #ifndef AMAZON_SE_GPIO_P0_OUT
14396 + #define AMAZON_SE_GPIO_P0_OUT (0xBF103000+0x10)
14397 + #define AMAZON_SE_GPIO_P0_DIR (0xBF103000+0x18)
14398 + #define AMAZON_SE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
14399 + #define AMAZON_SE_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
14400 + #define AMAZON_SE_GPIO_P0_OD (0xBF103000+0x24)
14401 + #define AMAZON_SE_GPIO_P0_PUDSEL (0xBF103000+0x2C)
14402 + #define AMAZON_SE_GPIO_P0_PUDEN (0xBF103000+0x30)
14403 + #define AMAZON_SE_GPIO_P1_OUT (0xBF103000+0x40)
14404 + #define AMAZON_SE_GPIO_P1_DIR (0xBF103000+0x48)
14405 + #define AMAZON_SE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
14406 + #define AMAZON_SE_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
14407 + #define AMAZON_SE_GPIO_P1_OD (0xBF103000+0x54)
14408 + #define AMAZON_SE_GPIO_P1_PUDSEL (0xBF103000+0x5C)
14409 + #define AMAZON_SE_GPIO_P1_PUDEN (0xBF103000+0x60)
14412 + #ifndef AMAZON_SE_CGU
14413 + #define AMAZON_SE_CGU (0xBF103000)
14415 + #ifndef AMAZON_SE_CGU_IFCCR
14416 + #define AMAZON_SE_CGU_IFCCR ((volatile unsigned long *)(AMAZON_SE_CGU+ 0x0018))
14418 + #ifndef AMAZON_SE_PMU
14419 + #define AMAZON_SE_PMU (KSEG1+0x1F102000)
14421 + #ifndef AMAZON_SE_PMU_PWDCR
14422 + #define AMAZON_SE_PMU_PWDCR ((volatile unsigned long *)(AMAZON_SE_PMU+0x001C))
14425 + #define default_param_dma_burst_size 4
14427 + #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
14429 + #define default_param_max_transfer_size -1 //(Max, hwcfg)
14430 + #define default_param_max_packet_count -1 //(Max, hwcfg)
14431 + #define default_param_phy_utmi_width 16
14433 + #define default_param_turn_around_time_hs 4 //(NoChange)
14434 + #define default_param_turn_around_time_fs 4 //(NoChange)
14435 + #define default_param_timeout_cal_hs -1 //(NoChange)
14436 + #define default_param_timeout_cal_fs -1 //(NoChange)
14438 + #define default_param_data_fifo_size -1 //(Max, hwcfg)
14440 + #ifdef __IS_HOST__
14441 + #define default_param_host_channels -1 //(Max, hwcfg)
14442 + #define default_param_rx_fifo_size 240
14443 + #define default_param_nperio_tx_fifo_size 240
14444 + #define default_param_perio_tx_fifo_size 32
14445 + #endif //__IS_HOST__
14446 + #ifdef __IS_DEVICE__
14447 + #ifdef __DED_INTR__
14448 + #define default_param_rx_fifo_size 256
14449 + #define default_param_nperio_tx_fifo_size 248
14450 + #define default_param_perio_tx_fifo_size_01 8
14452 + #define default_param_rx_fifo_size 256
14453 + #define default_param_nperio_tx_fifo_size 256
14454 + #define default_param_perio_tx_fifo_size_01 0
14456 + #define default_param_perio_tx_fifo_size_02 0
14457 + #define default_param_perio_tx_fifo_size_03 0
14458 + #define default_param_perio_tx_fifo_size_04 0
14459 + #define default_param_perio_tx_fifo_size_05 0
14460 + #define default_param_perio_tx_fifo_size_06 0
14461 + #define default_param_perio_tx_fifo_size_07 0
14462 + #define default_param_perio_tx_fifo_size_08 0
14463 + #define default_param_perio_tx_fifo_size_09 0
14464 + #define default_param_perio_tx_fifo_size_10 0
14465 + #define default_param_perio_tx_fifo_size_11 0
14466 + #define default_param_perio_tx_fifo_size_12 0
14467 + #define default_param_perio_tx_fifo_size_13 0
14468 + #define default_param_perio_tx_fifo_size_14 0
14469 + #define default_param_perio_tx_fifo_size_15 0
14470 + #endif //__IS_DEVICE__
14472 + #elif defined(__IS_AR9__)
14473 +// #define IFXUSB1_IRQ 54
14474 + #define IFXUSB1_IOMEM_BASE 0x1E101000
14475 + #define IFXUSB1_FIFOMEM_BASE 0x1E120000
14476 + #define IFXUSB1_FIFODBG_BASE 0x1E140000
14478 +// #define IFXUSB2_IRQ 83
14479 + #define IFXUSB2_IOMEM_BASE 0x1E106000
14480 + #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000
14481 + #define IFXUSB2_FIFODBG_BASE 0x1E1C0000
14483 +// #define IFXUSB_OC_IRQ 60
14485 + #ifndef AR9_RCU_BASE_ADDR
14486 + #define AR9_RCU_BASE_ADDR (0xBF203000)
14490 + #define AR9_CGU (0xBF103000)
14492 + #ifndef AR9_CGU_IFCCR
14493 + #define AR9_CGU_IFCCR ((volatile unsigned long *)(AR9_CGU+ 0x0018))
14497 + #define AR9_PMU (KSEG1+0x1F102000)
14499 + #ifndef AR9_PMU_PWDCR
14500 + #define AR9_PMU_PWDCR ((volatile unsigned long *)(AR9_PMU+0x001C))
14503 + #ifndef AR9_GPIO_P0_OUT
14504 + #define AR9_GPIO_P0_OUT (0xBF103000+0x10)
14505 + #define AR9_GPIO_P0_DIR (0xBF103000+0x18)
14506 + #define AR9_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
14507 + #define AR9_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
14508 + #define AR9_GPIO_P0_OD (0xBF103000+0x24)
14509 + #define AR9_GPIO_P0_PUDSEL (0xBF103000+0x2C)
14510 + #define AR9_GPIO_P0_PUDEN (0xBF103000+0x30)
14511 + #define AR9_GPIO_P1_OUT (0xBF103000+0x40)
14512 + #define AR9_GPIO_P1_DIR (0xBF103000+0x48)
14513 + #define AR9_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
14514 + #define AR9_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
14515 + #define AR9_GPIO_P1_OD (0xBF103000+0x54)
14516 + #define AR9_GPIO_P1_PUDSEL (0xBF103000+0x5C)
14517 + #define AR9_GPIO_P1_PUDEN (0xBF103000+0x60)
14520 + #define AR9_RCU_USB1CFG ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x18))
14521 + #define AR9_RCU_USB2CFG ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x34))
14522 + #define AR9_RCU_USBRESET ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x10))
14523 + #define AR9_USBCFG_ARB 7 //
14524 + #define AR9_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
14525 + #define AR9_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
14526 + #define AR9_USBCFG_SLV_END_BIT 17 // 0:little_end, 1:big_end
14528 + #define default_param_dma_burst_size 4
14530 + #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
14532 + #define default_param_max_transfer_size -1 //(Max, hwcfg)
14533 + #define default_param_max_packet_count -1 //(Max, hwcfg)
14534 + #define default_param_phy_utmi_width 16
14536 + #define default_param_turn_around_time_hs 4 //(NoChange)
14537 + #define default_param_turn_around_time_fs 4 //(NoChange)
14538 + #define default_param_timeout_cal_hs -1 //(NoChange)
14539 + #define default_param_timeout_cal_fs -1 //(NoChange)
14541 + #define default_param_data_fifo_size -1 //(Max, hwcfg)
14543 + #ifdef __IS_HOST__
14544 + #define default_param_host_channels -1 //(Max, hwcfg)
14545 + #define default_param_rx_fifo_size 240
14546 + #define default_param_nperio_tx_fifo_size 240
14547 + #define default_param_perio_tx_fifo_size 32
14548 + #endif //__IS_HOST__
14549 + #ifdef __IS_DEVICE__
14550 + #ifdef __DED_INTR__
14551 + #define default_param_rx_fifo_size 256
14552 +// #define default_param_nperio_tx_fifo_size 248
14553 +// #define default_param_perio_tx_fifo_size_01 8
14554 + #define default_param_nperio_tx_fifo_size 252
14555 + #define default_param_perio_tx_fifo_size_01 4
14557 + #define default_param_rx_fifo_size 256
14558 + #define default_param_nperio_tx_fifo_size 256
14559 + #define default_param_perio_tx_fifo_size_01 0
14561 + #define default_param_perio_tx_fifo_size_02 0
14562 + #define default_param_perio_tx_fifo_size_03 0
14563 + #define default_param_perio_tx_fifo_size_04 0
14564 + #define default_param_perio_tx_fifo_size_05 0
14565 + #define default_param_perio_tx_fifo_size_06 0
14566 + #define default_param_perio_tx_fifo_size_07 0
14567 + #define default_param_perio_tx_fifo_size_08 0
14568 + #define default_param_perio_tx_fifo_size_09 0
14569 + #define default_param_perio_tx_fifo_size_10 0
14570 + #define default_param_perio_tx_fifo_size_11 0
14571 + #define default_param_perio_tx_fifo_size_12 0
14572 + #define default_param_perio_tx_fifo_size_13 0
14573 + #define default_param_perio_tx_fifo_size_14 0
14574 + #define default_param_perio_tx_fifo_size_15 0
14575 + #endif //__IS_DEVICE__
14577 + #elif defined(__IS_VR9__)
14578 +// #define IFXUSB1_IRQ 54
14579 + #define IFXUSB1_IOMEM_BASE 0x1E101000
14580 + #define IFXUSB1_FIFOMEM_BASE 0x1E120000
14581 + #define IFXUSB1_FIFODBG_BASE 0x1E140000
14583 +// #define IFXUSB2_IRQ 83
14584 + #define IFXUSB2_IOMEM_BASE 0x1E106000
14585 + #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000
14586 + #define IFXUSB2_FIFODBG_BASE 0x1E1C0000
14587 +// #define IFXUSB_OC_IRQ 60
14589 + #ifndef VR9_RCU_BASE_ADDR
14590 + #define VR9_RCU_BASE_ADDR (0xBF203000)
14594 + #define VR9_CGU (0xBF103000)
14596 + #ifndef VR9_CGU_IFCCR
14597 + #define VR9_CGU_IFCCR ((volatile unsigned long *)(VR9_CGU+ 0x0018))
14601 + #define VR9_PMU (KSEG1+0x1F102000)
14603 + #ifndef VR9_PMU_PWDCR
14604 + #define VR9_PMU_PWDCR ((volatile unsigned long *)(VR9_PMU+0x001C))
14607 + #ifndef VR9_GPIO_P0_OUT
14608 + #define VR9_GPIO_P0_OUT (0xBF103000+0x10)
14609 + #define VR9_GPIO_P0_DIR (0xBF103000+0x18)
14610 + #define VR9_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
14611 + #define VR9_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
14612 + #define VR9_GPIO_P0_OD (0xBF103000+0x24)
14613 + #define VR9_GPIO_P0_PUDSEL (0xBF103000+0x2C)
14614 + #define VR9_GPIO_P0_PUDEN (0xBF103000+0x30)
14615 + #define VR9_GPIO_P1_OUT (0xBF103000+0x40)
14616 + #define VR9_GPIO_P1_DIR (0xBF103000+0x48)
14617 + #define VR9_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
14618 + #define VR9_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
14619 + #define VR9_GPIO_P1_OD (0xBF103000+0x54)
14620 + #define VR9_GPIO_P1_PUDSEL (0xBF103000+0x5C)
14621 + #define VR9_GPIO_P1_PUDEN (0xBF103000+0x60)
14624 + #define VR9_RCU_USB1CFG ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x18))
14625 + #define VR9_RCU_USB2CFG ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x34))
14626 + #define VR9_RCU_USB_ANA_CFG1A ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x38))
14627 + #define VR9_RCU_USB_ANA_CFG1B ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x3C))
14628 + #define VR9_RCU_USBRESET ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x10))
14629 + #define VR9_RCU_USBRESET2 ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x48))
14630 + #define VR9_USBCFG_ARB 7 //
14631 + #define VR9_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
14632 + #define VR9_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
14633 + #define VR9_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
14635 + /*== AVM/BC 20101220 Workaround VR9 DMA burst size ==
14636 + * Using 2 Devices in diferent ports cause a general USB Host Error.
14637 + * Workaround found in UGW4.3
14639 +// #define default_param_dma_burst_size 4 //(ALL)
14641 + #define default_param_dma_burst_size 0 //(ALL)
14643 + #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
14645 + #define default_param_max_transfer_size -1 //(Max, hwcfg)
14646 + #define default_param_max_packet_count -1 //(Max, hwcfg)
14647 + #define default_param_phy_utmi_width 16
14649 + #define default_param_turn_around_time_hs 6 //(NoChange) snpsid >= 0x4f54260a
14650 + #define default_param_turn_around_time_fs 6 //(NoChange) snpsid >= 0x4f54260a
14651 + #define default_param_timeout_cal_hs -1 //(NoChange)
14652 + #define default_param_timeout_cal_fs -1 //(NoChange)
14654 + #define default_param_data_fifo_size -1 //(Max, hwcfg)
14656 + #ifdef __IS_HOST__
14657 + #define default_param_host_channels -1 //(Max, hwcfg)
14658 + #define default_param_rx_fifo_size 240
14659 + #define default_param_nperio_tx_fifo_size 240
14660 + #define default_param_perio_tx_fifo_size 32
14661 + #endif //__IS_HOST__
14662 + #ifdef __IS_DEVICE__
14664 + #define default_param_rx_fifo_size 256
14665 + #define default_param_tx_fifo_size_00 -1
14666 + #define default_param_tx_fifo_size_01 -1
14667 + #define default_param_tx_fifo_size_02 -1
14669 + #define default_param_rx_fifo_size 256
14670 + #define default_param_tx_fifo_size_00 32
14671 + #define default_param_tx_fifo_size_01 200
14672 + #define default_param_tx_fifo_size_02 8
14674 + #define default_param_tx_fifo_size_03 -1
14675 + #define default_param_tx_fifo_size_04 -1
14676 + #define default_param_tx_fifo_size_05 -1
14677 + #define default_param_tx_fifo_size_06 -1
14678 + #define default_param_tx_fifo_size_07 -1
14679 + #define default_param_tx_fifo_size_08 -1
14680 + #define default_param_tx_fifo_size_09 -1
14681 + #define default_param_tx_fifo_size_10 -1
14682 + #define default_param_tx_fifo_size_11 -1
14683 + #define default_param_tx_fifo_size_12 -1
14684 + #define default_param_tx_fifo_size_13 -1
14685 + #define default_param_tx_fifo_size_14 -1
14686 + #define default_param_tx_fifo_size_15 -1
14687 + #define default_param_dma_unalgned_tx -1
14688 + #define default_param_dma_unalgned_rx -1
14689 + #define default_param_thr_ctl -1
14690 + #define default_param_tx_thr_length -1
14691 + #define default_param_rx_thr_length -1
14692 + #endif //__IS_DEVICE__
14693 + #else // __IS_VR9__
14694 + #error "Please choose one platform!!"
14695 + #endif // __IS_VR9__
14698 + #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
14699 +// #define IFXUSB_IRQ 54
14700 + #define IFXUSB_IOMEM_BASE 0x1e101000
14701 + #define IFXUSB_FIFOMEM_BASE 0x1e120000
14702 + #define IFXUSB_FIFODBG_BASE 0x1e140000
14703 +// #define IFXUSB_OC_IRQ 151
14706 + #ifndef DANUBE_RCU_BASE_ADDR
14707 + #define DANUBE_RCU_BASE_ADDR (0xBF203000)
14710 + #ifndef DANUBE_CGU
14711 + #define DANUBE_CGU (0xBF103000)
14713 + #ifndef DANUBE_CGU_IFCCR
14714 + #define DANUBE_CGU_IFCCR ((volatile unsigned long *)(DANUBE_CGU+ 0x0018))
14716 + #ifndef DANUBE_PMU
14717 + #define DANUBE_PMU (KSEG1+0x1F102000)
14719 + #ifndef DANUBE_PMU_PWDCR
14720 + #define DANUBE_PMU_PWDCR ((volatile unsigned long *)(DANUBE_PMU+0x001C))
14723 + #ifndef DANUBE_GPIO_P0_OUT
14724 + #define DANUBE_GPIO_P0_OUT (0xBF103000+0x10)
14725 + #define DANUBE_GPIO_P0_DIR (0xBF103000+0x18)
14726 + #define DANUBE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
14727 + #define DANUBE_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
14728 + #define DANUBE_GPIO_P0_OD (0xBF103000+0x24)
14729 + #define DANUBE_GPIO_P0_PUDSEL (0xBF103000+0x2C)
14730 + #define DANUBE_GPIO_P0_PUDEN (0xBF103000+0x30)
14731 + #define DANUBE_GPIO_P1_OUT (0xBF103000+0x40)
14732 + #define DANUBE_GPIO_P1_DIR (0xBF103000+0x48)
14733 + #define DANUBE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
14734 + #define DANUBE_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
14735 + #define DANUBE_GPIO_P1_OD (0xBF103000+0x54)
14736 + #define DANUBE_GPIO_P1_PUDSEL (0xBF103000+0x5C)
14737 + #define DANUBE_GPIO_P1_PUDEN (0xBF103000+0x60)
14741 + #define DANUBE_RCU_USBCFG ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x18))
14742 + #define DANUBE_RCU_RESET ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x10))
14743 + #define DANUBE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
14744 + #define DANUBE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
14745 + #define DANUBE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
14747 + #define default_param_dma_burst_size 4
14749 + #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
14751 + #define default_param_max_transfer_size -1 //(Max, hwcfg)
14752 + #define default_param_max_packet_count -1 //(Max, hwcfg)
14753 + #define default_param_phy_utmi_width 16
14755 + #define default_param_turn_around_time_hs 4 //(NoChange)
14756 + #define default_param_turn_around_time_fs 4 //(NoChange)
14757 + #define default_param_timeout_cal_hs -1 //(NoChange)
14758 + #define default_param_timeout_cal_fs -1 //(NoChange)
14760 + #define default_param_data_fifo_size -1 //(Max, hwcfg)
14761 + #ifdef __IS_HOST__
14762 + #define default_param_host_channels -1 //(Max, hwcfg)
14763 + #define default_param_rx_fifo_size 640
14764 + #define default_param_nperio_tx_fifo_size 640
14765 + #define default_param_perio_tx_fifo_size 768
14766 + #endif //__IS_HOST__
14768 + #ifdef __IS_DEVICE__
14769 + #ifdef __DED_INTR__
14770 + #define default_param_rx_fifo_size 1024
14771 + #define default_param_nperio_tx_fifo_size 1016
14772 + #define default_param_perio_tx_fifo_size_01 8
14774 + #define default_param_rx_fifo_size 1024
14775 + #define default_param_nperio_tx_fifo_size 1024
14776 + #define default_param_perio_tx_fifo_size_01 0
14778 + #define default_param_perio_tx_fifo_size_02 0
14779 + #define default_param_perio_tx_fifo_size_03 0
14780 + #define default_param_perio_tx_fifo_size_04 0
14781 + #define default_param_perio_tx_fifo_size_05 0
14782 + #define default_param_perio_tx_fifo_size_06 0
14783 + #define default_param_perio_tx_fifo_size_07 0
14784 + #define default_param_perio_tx_fifo_size_08 0
14785 + #define default_param_perio_tx_fifo_size_09 0
14786 + #define default_param_perio_tx_fifo_size_10 0
14787 + #define default_param_perio_tx_fifo_size_11 0
14788 + #define default_param_perio_tx_fifo_size_12 0
14789 + #define default_param_perio_tx_fifo_size_13 0
14790 + #define default_param_perio_tx_fifo_size_14 0
14791 + #define default_param_perio_tx_fifo_size_15 0
14792 + #endif //__IS_DEVICE__
14794 + #elif defined(__IS_AMAZON_SE__)
14795 + #include <asm/amazon_se/amazon_se.h>
14796 + //#include <asm/amazon_se/irq.h>
14798 +// #define IFXUSB_IRQ 31
14799 + #define IFXUSB_IOMEM_BASE 0x1e101000
14800 + #define IFXUSB_FIFOMEM_BASE 0x1e120000
14801 + #define IFXUSB_FIFODBG_BASE 0x1e140000
14802 +// #define IFXUSB_OC_IRQ 20
14804 + #define AMAZON_SE_RCU_USBCFG ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x18))
14805 + #define AMAZON_SE_RCU_RESET ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x10))
14806 + #define AMAZON_SE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
14807 + #define AMAZON_SE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
14808 + #define AMAZON_SE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
14810 + #ifndef AMAZON_SE_GPIO_P0_OUT
14811 + #define AMAZON_SE_GPIO_P0_OUT (0xBF103000+0x10)
14812 + #define AMAZON_SE_GPIO_P0_DIR (0xBF103000+0x18)
14813 + #define AMAZON_SE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
14814 + #define AMAZON_SE_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
14815 + #define AMAZON_SE_GPIO_P0_OD (0xBF103000+0x24)
14816 + #define AMAZON_SE_GPIO_P0_PUDSEL (0xBF103000+0x2C)
14817 + #define AMAZON_SE_GPIO_P0_PUDEN (0xBF103000+0x30)
14818 + #define AMAZON_SE_GPIO_P1_OUT (0xBF103000+0x40)
14819 + #define AMAZON_SE_GPIO_P1_DIR (0xBF103000+0x48)
14820 + #define AMAZON_SE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
14821 + #define AMAZON_SE_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
14822 + #define AMAZON_SE_GPIO_P1_OD (0xBF103000+0x54)
14823 + #define AMAZON_SE_GPIO_P1_PUDSEL (0xBF103000+0x5C)
14824 + #define AMAZON_SE_GPIO_P1_PUDEN (0xBF103000+0x60)
14828 + #ifndef AMAZON_SE_CGU
14829 + #define AMAZON_SE_CGU (0xBF103000)
14831 + #ifndef AMAZON_SE_CGU_IFCCR
14832 + #define AMAZON_SE_CGU_IFCCR ((volatile unsigned long *)(AMAZON_SE_CGU+ 0x0018))
14834 + #ifndef AMAZON_SE_PMU
14835 + #define AMAZON_SE_PMU (KSEG1+0x1F102000)
14837 + #ifndef AMAZON_SE_PMU_PWDCR
14838 + #define AMAZON_SE_PMU_PWDCR ((volatile unsigned long *)(AMAZON_SE_PMU+0x001C))
14841 + #define default_param_dma_burst_size 4
14843 + #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
14845 + #define default_param_max_transfer_size -1 //(Max, hwcfg)
14846 + #define default_param_max_packet_count -1 //(Max, hwcfg)
14847 + #define default_param_phy_utmi_width 16
14849 + #define default_param_turn_around_time_hs 4 //(NoChange)
14850 + #define default_param_turn_around_time_fs 4 //(NoChange)
14851 + #define default_param_timeout_cal_hs -1 //(NoChange)
14852 + #define default_param_timeout_cal_fs -1 //(NoChange)
14854 + #define default_param_data_fifo_size -1 //(Max, hwcfg)
14856 + #ifdef __IS_HOST__
14857 + #define default_param_host_channels -1 //(Max, hwcfg)
14858 + #define default_param_rx_fifo_size 240
14859 + #define default_param_nperio_tx_fifo_size 240
14860 + #define default_param_perio_tx_fifo_size 32
14861 + #endif //__IS_HOST__
14862 + #ifdef __IS_DEVICE__
14863 + #ifdef __DED_INTR__
14864 + #define default_param_rx_fifo_size 256
14865 + #define default_param_nperio_tx_fifo_size 248
14866 + #define default_param_perio_tx_fifo_size_01 8
14868 + #define default_param_rx_fifo_size 256
14869 + #define default_param_nperio_tx_fifo_size 256
14870 + #define default_param_perio_tx_fifo_size_01 0
14872 + #define default_param_perio_tx_fifo_size_02 0
14873 + #define default_param_perio_tx_fifo_size_03 0
14874 + #define default_param_perio_tx_fifo_size_04 0
14875 + #define default_param_perio_tx_fifo_size_05 0
14876 + #define default_param_perio_tx_fifo_size_06 0
14877 + #define default_param_perio_tx_fifo_size_07 0
14878 + #define default_param_perio_tx_fifo_size_08 0
14879 + #define default_param_perio_tx_fifo_size_09 0
14880 + #define default_param_perio_tx_fifo_size_10 0
14881 + #define default_param_perio_tx_fifo_size_11 0
14882 + #define default_param_perio_tx_fifo_size_12 0
14883 + #define default_param_perio_tx_fifo_size_13 0
14884 + #define default_param_perio_tx_fifo_size_14 0
14885 + #define default_param_perio_tx_fifo_size_15 0
14886 + #endif //__IS_DEVICE__
14888 + #elif defined(__IS_AR9__)
14889 +// #define IFXUSB1_IRQ 54
14890 + #define IFXUSB1_IOMEM_BASE 0x1E101000
14891 + #define IFXUSB1_FIFOMEM_BASE 0x1E120000
14892 + #define IFXUSB1_FIFODBG_BASE 0x1E140000
14894 +// #define IFXUSB2_IRQ 83
14895 + #define IFXUSB2_IOMEM_BASE 0x1E106000
14896 + #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000
14897 + #define IFXUSB2_FIFODBG_BASE 0x1E1C0000
14899 +// #define IFXUSB_OC_IRQ 60
14901 + #ifndef AMAZON_S_RCU_BASE_ADDR
14902 + #define AMAZON_S_RCU_BASE_ADDR (0xBF203000)
14905 + #ifndef AMAZON_S_CGU
14906 + #define AMAZON_S_CGU (0xBF103000)
14908 + #ifndef AMAZON_S_CGU_IFCCR
14909 + #define AMAZON_S_CGU_IFCCR ((volatile unsigned long *)(AMAZON_S_CGU+ 0x0018))
14912 + #ifndef AMAZON_S_PMU
14913 + #define AMAZON_S_PMU (KSEG1+0x1F102000)
14915 + #ifndef AMAZON_S_PMU_PWDCR
14916 + #define AMAZON_S_PMU_PWDCR ((volatile unsigned long *)(AMAZON_S_PMU+0x001C))
14919 + #ifndef AMAZON_S_GPIO_P0_OUT
14920 + #define AMAZON_S_GPIO_P0_OUT (0xBF103000+0x10)
14921 + #define AMAZON_S_GPIO_P0_DIR (0xBF103000+0x18)
14922 + #define AMAZON_S_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
14923 + #define AMAZON_S_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
14924 + #define AMAZON_S_GPIO_P0_OD (0xBF103000+0x24)
14925 + #define AMAZON_S_GPIO_P0_PUDSEL (0xBF103000+0x2C)
14926 + #define AMAZON_S_GPIO_P0_PUDEN (0xBF103000+0x30)
14927 + #define AMAZON_S_GPIO_P1_OUT (0xBF103000+0x40)
14928 + #define AMAZON_S_GPIO_P1_DIR (0xBF103000+0x48)
14929 + #define AMAZON_S_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
14930 + #define AMAZON_S_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
14931 + #define AMAZON_S_GPIO_P1_OD (0xBF103000+0x54)
14932 + #define AMAZON_S_GPIO_P1_PUDSEL (0xBF103000+0x5C)
14933 + #define AMAZON_S_GPIO_P1_PUDEN (0xBF103000+0x60)
14936 + #define AMAZON_S_RCU_USB1CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x18))
14937 + #define AMAZON_S_RCU_USB2CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x34))
14938 + #define AMAZON_S_RCU_USBRESET ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x10))
14939 + #define AMAZON_S_USBCFG_ARB 7 //
14940 + #define AMAZON_S_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
14941 + #define AMAZON_S_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
14942 + #define AMAZON_S_USBCFG_SLV_END_BIT 17 // 0:little_end, 1:big_end
14944 + #define default_param_dma_burst_size 4
14946 + #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
14948 + #define default_param_max_transfer_size -1 //(Max, hwcfg)
14949 + #define default_param_max_packet_count -1 //(Max, hwcfg)
14950 + #define default_param_phy_utmi_width 16
14952 + #define default_param_turn_around_time_hs 4 //(NoChange)
14953 + #define default_param_turn_around_time_fs 4 //(NoChange)
14954 + #define default_param_timeout_cal_hs -1 //(NoChange)
14955 + #define default_param_timeout_cal_fs -1 //(NoChange)
14957 + #define default_param_data_fifo_size -1 //(Max, hwcfg)
14959 + #ifdef __IS_HOST__
14960 + #define default_param_host_channels -1 //(Max, hwcfg)
14961 + #define default_param_rx_fifo_size 240
14962 + #define default_param_nperio_tx_fifo_size 240
14963 + #define default_param_perio_tx_fifo_size 32
14964 + #endif //__IS_HOST__
14965 + #ifdef __IS_DEVICE__
14966 + #ifdef __DED_INTR__
14967 + #define default_param_rx_fifo_size 256
14968 + #define default_param_nperio_tx_fifo_size 248
14969 + #define default_param_perio_tx_fifo_size_01 8
14971 + #define default_param_rx_fifo_size 256
14972 + #define default_param_nperio_tx_fifo_size 256
14973 + #define default_param_perio_tx_fifo_size_01 0
14975 + #define default_param_perio_tx_fifo_size_02 0
14976 + #define default_param_perio_tx_fifo_size_03 0
14977 + #define default_param_perio_tx_fifo_size_04 0
14978 + #define default_param_perio_tx_fifo_size_05 0
14979 + #define default_param_perio_tx_fifo_size_06 0
14980 + #define default_param_perio_tx_fifo_size_07 0
14981 + #define default_param_perio_tx_fifo_size_08 0
14982 + #define default_param_perio_tx_fifo_size_09 0
14983 + #define default_param_perio_tx_fifo_size_10 0
14984 + #define default_param_perio_tx_fifo_size_11 0
14985 + #define default_param_perio_tx_fifo_size_12 0
14986 + #define default_param_perio_tx_fifo_size_13 0
14987 + #define default_param_perio_tx_fifo_size_14 0
14988 + #define default_param_perio_tx_fifo_size_15 0
14989 + #endif //__IS_DEVICE__
14991 + #elif defined(__IS_VR9__)
14992 +// #define IFXUSB1_IRQ 54
14993 + #define IFXUSB1_IOMEM_BASE 0x1E101000
14994 + #define IFXUSB1_FIFOMEM_BASE 0x1E120000
14995 + #define IFXUSB1_FIFODBG_BASE 0x1E140000
14997 +// #define IFXUSB2_IRQ 83
14998 + #define IFXUSB2_IOMEM_BASE 0x1E106000
14999 + #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000
15000 + #define IFXUSB2_FIFODBG_BASE 0x1E1C0000
15001 +// #define IFXUSB_OC_IRQ 60
15003 + #ifndef AMAZON_S_RCU_BASE_ADDR
15004 + #define AMAZON_S_RCU_BASE_ADDR (0xBF203000)
15007 + #ifndef AMAZON_S_CGU
15008 + #define AMAZON_S_CGU (0xBF103000)
15010 + #ifndef AMAZON_S_CGU_IFCCR
15011 + #define AMAZON_S_CGU_IFCCR ((volatile unsigned long *)(AMAZON_S_CGU+ 0x0018))
15014 + #ifndef AMAZON_S_PMU
15015 + #define AMAZON_S_PMU (KSEG1+0x1F102000)
15017 + #ifndef AMAZON_S_PMU_PWDCR
15018 + #define AMAZON_S_PMU_PWDCR ((volatile unsigned long *)(AMAZON_S_PMU+0x001C))
15021 + #ifndef AMAZON_S_GPIO_P0_OUT
15022 + #define AMAZON_S_GPIO_P0_OUT (0xBF103000+0x10)
15023 + #define AMAZON_S_GPIO_P0_DIR (0xBF103000+0x18)
15024 + #define AMAZON_S_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
15025 + #define AMAZON_S_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
15026 + #define AMAZON_S_GPIO_P0_OD (0xBF103000+0x24)
15027 + #define AMAZON_S_GPIO_P0_PUDSEL (0xBF103000+0x2C)
15028 + #define AMAZON_S_GPIO_P0_PUDEN (0xBF103000+0x30)
15029 + #define AMAZON_S_GPIO_P1_OUT (0xBF103000+0x40)
15030 + #define AMAZON_S_GPIO_P1_DIR (0xBF103000+0x48)
15031 + #define AMAZON_S_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
15032 + #define AMAZON_S_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
15033 + #define AMAZON_S_GPIO_P1_OD (0xBF103000+0x54)
15034 + #define AMAZON_S_GPIO_P1_PUDSEL (0xBF103000+0x5C)
15035 + #define AMAZON_S_GPIO_P1_PUDEN (0xBF103000+0x60)
15038 + #define AMAZON_S_RCU_USB1CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x18))
15039 + #define AMAZON_S_RCU_USB2CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x34))
15040 + #define AMAZON_S_RCU_USBRESET ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x10))
15041 + #define AMAZON_S_USBCFG_ARB 7 //
15042 + #define AMAZON_S_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
15043 + #define AMAZON_S_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
15044 + #define AMAZON_S_USBCFG_SLV_END_BIT 17 // 0:little_end, 1:big_end
15046 + #define default_param_dma_burst_size 4 //(ALL)
15048 + #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
15050 + #define default_param_max_transfer_size -1 //(Max, hwcfg)
15051 + #define default_param_max_packet_count -1 //(Max, hwcfg)
15052 + #define default_param_phy_utmi_width 16
15054 + #define default_param_turn_around_time_hs 6 //(NoChange) snpsid >= 0x4f54260a
15055 + #define default_param_turn_around_time_fs 6 //(NoChange) snpsid >= 0x4f54260a
15056 + #define default_param_timeout_cal_hs -1 //(NoChange)
15057 + #define default_param_timeout_cal_fs -1 //(NoChange)
15059 + #define default_param_data_fifo_size -1 //(Max, hwcfg)
15061 + #ifdef __IS_HOST__
15062 + #define default_param_host_channels -1 //(Max, hwcfg)
15063 + #define default_param_rx_fifo_size 240
15064 + #define default_param_nperio_tx_fifo_size 240
15065 + #define default_param_perio_tx_fifo_size 32
15066 + #endif //__IS_HOST__
15067 + #ifdef __IS_DEVICE__
15068 + #define default_param_rx_fifo_size 256
15069 + #define default_param_tx_fifo_size_00 -1
15070 + #define default_param_tx_fifo_size_01 -1
15071 + #define default_param_tx_fifo_size_02 -1
15072 + #define default_param_tx_fifo_size_03 -1
15073 + #define default_param_tx_fifo_size_04 -1
15074 + #define default_param_tx_fifo_size_05 -1
15075 + #define default_param_tx_fifo_size_06 -1
15076 + #define default_param_tx_fifo_size_07 -1
15077 + #define default_param_tx_fifo_size_08 -1
15078 + #define default_param_tx_fifo_size_09 -1
15079 + #define default_param_tx_fifo_size_10 -1
15080 + #define default_param_tx_fifo_size_11 -1
15081 + #define default_param_tx_fifo_size_12 -1
15082 + #define default_param_tx_fifo_size_13 -1
15083 + #define default_param_tx_fifo_size_14 -1
15084 + #define default_param_tx_fifo_size_15 -1
15085 + #define default_param_dma_unalgned_tx -1
15086 + #define default_param_dma_unalgned_rx -1
15087 + #define default_param_thr_ctl -1
15088 + #define default_param_tx_thr_length -1
15089 + #define default_param_rx_thr_length -1
15090 + #endif //__IS_DEVICE__
15091 + #else // __IS_VR9__
15092 + #error "Please choose one platform!!"
15093 + #endif // __IS_VR9__
15096 +/*@}*//*IFXUSB_PLATEFORM_MEM_ADDR*/
15098 +/////////////////////////////////////////////////////////////////////////
15100 +#ifdef __IS_HOST__
15101 + #ifdef CONFIG_USB_HOST_IFX_FORCE_USB11
15102 + #undef default_param_speed
15103 + #define default_param_speed IFXUSB_PARAM_SPEED_FULL
15106 +#ifdef __IS_DEVICE__
15107 + #ifndef CONFIG_USB_GADGET_DUALSPEED
15108 + #undef default_param_speed
15109 + #define default_param_speed IFXUSB_PARAM_SPEED_FULL
15113 +/////////////////////////////////////////////////////////////////////////
15115 +static __inline__ void UDELAY( const uint32_t _usecs )
15117 + udelay( _usecs );
15120 +static __inline__ void MDELAY( const uint32_t _msecs )
15122 + mdelay( _msecs );
15125 +static __inline__ void SPIN_LOCK( spinlock_t *_lock )
15127 + spin_lock(_lock);
15130 +static __inline__ void SPIN_UNLOCK( spinlock_t *_lock )
15132 + spin_unlock(_lock);
15135 +#define SPIN_LOCK_IRQSAVE( _l, _f ) \
15137 + spin_lock_irqsave(_l,_f); \
15140 +#define SPIN_UNLOCK_IRQRESTORE( _l,_f ) \
15142 + spin_unlock_irqrestore(_l,_f); \
15145 +/////////////////////////////////////////////////////////////////////////
15147 + \addtogroup IFXUSB_DBG_ROUTINE
15150 +#ifdef __IS_HOST__
15151 + extern uint32_t h_dbg_lvl;
15154 +#ifdef __IS_DEVICE__
15155 + extern uint32_t d_dbg_lvl;
15158 +/*! \brief When debug level has the DBG_CIL bit set, display CIL Debug messages. */
15159 +#define DBG_CIL (0x2)
15160 +/*! \brief When debug level has the DBG_CILV bit set, display CIL Verbose debug messages */
15161 +#define DBG_CILV (0x20)
15162 +/*! \brief When debug level has the DBG_PCD bit set, display PCD (Device) debug messages */
15163 +#define DBG_PCD (0x4)
15164 +/*! \brief When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug messages */
15165 +#define DBG_PCDV (0x40)
15166 +/*! \brief When debug level has the DBG_HCD bit set, display Host debug messages */
15167 +#define DBG_HCD (0x8)
15168 +/*! \brief When debug level has the DBG_HCDV bit set, display Verbose Host debug messages */
15169 +#define DBG_HCDV (0x80)
15170 +/*! \brief When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host mode. */
15171 +#define DBG_HCD_URB (0x800)
15172 +/*! \brief When debug level has any bit set, display debug messages */
15173 +#define DBG_ANY (0xFF)
15174 +/*! \brief All debug messages off */
15177 +#define DBG_ENTRY (0x8000)
15179 +#define IFXUSB "IFXUSB: "
15182 + \fn inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new )
15183 + \brief Set the Debug Level variable.
15184 + \param _new 32-bit mask of debug level.
15185 + \return previous debug level
15187 +static inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new )
15189 + #ifdef __IS_HOST__
15190 + uint32_t old = h_dbg_lvl;
15191 + h_dbg_lvl = _new;
15194 + #ifdef __IS_DEVICE__
15195 + uint32_t old = d_dbg_lvl;
15196 + d_dbg_lvl = _new;
15202 + #ifdef __IS_HOST__
15203 + # define IFX_DEBUGPL(lvl, x...) do{ if ((lvl)&h_dbg_lvl)printk( KERN_DEBUG IFXUSB x ); }while(0)
15204 + # define CHK_DEBUG_LEVEL(level) ((level) & h_dbg_lvl)
15207 + #ifdef __IS_DEVICE__
15208 + # define IFX_DEBUGPL(lvl, x...) do{ if ((lvl)&d_dbg_lvl)printk( KERN_DEBUG IFXUSB x ); }while(0)
15209 + # define CHK_DEBUG_LEVEL(level) ((level) & d_dbg_lvl)
15212 + # define IFX_DEBUGP(x...) IFX_DEBUGPL(DBG_ANY, x )
15214 + # define IFX_DEBUGPL(lvl, x...) do{}while(0)
15215 + # define IFX_DEBUGP(x...)
15216 + # define CHK_DEBUG_LEVEL(level) (0)
15217 +#endif //__DEBUG__
15219 +/* Print an Error message. */
15220 +#define IFX_ERROR(x...) printk( KERN_ERR IFXUSB x )
15221 +/* Print a Warning message. */
15222 +#define IFX_WARN(x...) printk( KERN_WARNING IFXUSB x )
15223 +/* Print a notice (normal but significant message). */
15224 +#define IFX_NOTICE(x...) printk( KERN_NOTICE IFXUSB x )
15225 +/* Basic message printing. */
15226 +#define IFX_PRINT(x...) printk( KERN_INFO IFXUSB x )
15228 +/*@}*//*IFXUSB_DBG_ROUTINE*/
15231 +#endif //__IFXUSB_PLAT_H__
15233 diff --git a/drivers/usb/ifxhcd/ifxusb_regs.h b/drivers/usb/ifxhcd/ifxusb_regs.h
15234 new file mode 100644
15235 index 0000000..014c6db
15237 +++ b/drivers/usb/ifxhcd/ifxusb_regs.h
15239 +/*****************************************************************************
15240 + ** FILE NAME : ifxusb_regs.h
15241 + ** PROJECT : IFX USB sub-system V3
15242 + ** MODULES : IFX USB sub-system Host and Device driver
15243 + ** SRC VERSION : 1.0
15244 + ** DATE : 1/Jan/2009
15245 + ** AUTHOR : Chen, Howard
15246 + ** DESCRIPTION : This file contains the data structures for accessing the IFXUSB core
15248 + ** The application interfaces with the USB core by reading from and
15249 + ** writing to the Control and Status Register (CSR) space through the
15250 + ** AHB Slave interface. These registers are 32 bits wide, and the
15251 + ** addresses are 32-bit-block aligned.
15252 + ** CSRs are classified as follows:
15253 + ** - Core Global Registers
15254 + ** - Device Mode Registers
15255 + ** - Device Global Registers
15256 + ** - Device Endpoint Specific Registers
15257 + ** - Host Mode Registers
15258 + ** - Host Global Registers
15259 + ** - Host Port CSRs
15260 + ** - Host Channel Specific Registers
15262 + ** Only the Core Global registers can be accessed in both Device and
15263 + ** Host modes. When the USB core is operating in one mode, either
15264 + ** Device or Host, the application must not access registers from the
15265 + ** other mode. When the core switches from one mode to another, the
15266 + ** registers in the new mode of operation must be reprogrammed as they
15267 + ** would be after a power-on reset.
15269 + ** COMPILER : gcc
15270 + ** REFERENCE : Synopsys DWC-OTG Driver 2.7
15272 + ** Version Control Section **
15276 + ** $Log$ Revision history
15277 +*****************************************************************************/
15282 + \defgroup IFXUSB_CSR_DEFINITION Control and Status Register bit-map definition
15283 + \ingroup IFXUSB_DRIVER_V3
15284 + \brief Data structures for accessing the IFXUSB core registers.
15285 + The application interfaces with the USB core by reading from and
15286 + writing to the Control and Status Register (CSR) space through the
15287 + AHB Slave interface. These registers are 32 bits wide, and the
15288 + addresses are 32-bit-block aligned.
15289 + CSRs are classified as follows:
15290 + - Core Global Registers
15291 + - Device Mode Registers
15292 + - Device Global Registers
15293 + - Device Endpoint Specific Registers
15294 + - Host Mode Registers
15295 + - Host Global Registers
15297 + - Host Channel Specific Registers
15299 + Only the Core Global registers can be accessed in both Device andHost modes.
15300 + When the USB core is operating in one mode, either Device or Host, the
15301 + application must not access registers from the other mode. When the core
15302 + switches from one mode to another, the registers in the new mode of operation
15303 + must be reprogrammed as they would be after a power-on reset.
15307 + \defgroup IFXUSB_CSR_DEVICE_GLOBAL_REG Device Mode Registers
15308 + \ingroup IFXUSB_CSR_DEFINITION
15309 + \brief Bit-mapped structure to access Device Mode Global Registers
15313 + \defgroup IFXUSB_CSR_DEVICE_EP_REG Device Mode EP Registers
15314 + \ingroup IFXUSB_CSR_DEFINITION
15315 + \brief Bit-mapped structure to access Device Mode EP Registers
15316 + There will be one set of endpoint registers per logical endpoint
15318 + These registers are visible only in Device mode and must not be
15319 + accessed in Host mode, as the results are unknown.
15323 + \defgroup IFXUSB_CSR_DEVICE_DMA_DESC Device mode scatter dma descriptor strusture
15324 + \ingroup IFXUSB_CSR_DEFINITION
15325 + \brief Bit-mapped structure to DMA descriptor
15330 + \defgroup IFXUSB_CSR_HOST_GLOBAL_REG Host Mode Registers
15331 + \ingroup IFXUSB_CSR_DEFINITION
15332 + \brief Bit-mapped structure to access Host Mode Global Registers
15336 + \defgroup IFXUSB_CSR_HOST_HC_REG Host Mode HC Registers
15337 + \ingroup IFXUSB_CSR_DEFINITION
15338 + \brief Bit-mapped structure to access Host Mode Host Channel Registers
15339 + There will be one set of endpoint registers per host channel
15341 + These registers are visible only in Host mode and must not be
15342 + accessed in Device mode, as the results are unknown.
15346 + \defgroup IFXUSB_CSR_PWR_CLK_GATING_REG Power and Clock Gating Control Register
15347 + \ingroup IFXUSB_CSR_DEFINITION
15348 + \brief Bit-mapped structure to Power and Clock Gating Control Register
15359 + \defgroup IFXUSB_CSR_CORE_GLOBAL_REG Core Global Registers
15360 + \ingroup IFXUSB_CSR_DEFINITION
15361 + \brief Bit-mapped structure to access Core Global Registers
15364 + \defgroup IFXUSB_CSR_CORE_GLOBAL_REG Core Global Registers
15365 + \ingroup IFXUSB_CSR_DEFINITION
15366 + \brief Bit-mapped structure to access Core Global Registers
15378 + \file ifxusb_regs.h
15379 + \ingroup IFXUSB_DRIVER_V3
15380 + \brief This file contains the data structures for accessing the IFXUSB core registers.
15384 +#ifndef __IFXUSB_REGS_H__
15385 +#define __IFXUSB_REGS_H__
15387 +/****************************************************************************/
15389 +#define MAX_PERIO_FIFOS 15 /** Maximum number of Periodic FIFOs */
15390 +#define MAX_TX_FIFOS 15 /** Maximum number of Periodic FIFOs */
15391 +#define MAX_EPS_CHANNELS 16 /** Maximum number of Endpoints/HostChannels */
15393 +/****************************************************************************/
15396 + \addtogroup IFXUSB_CSR_ACCESS_MACROS
15400 +//#define RecordRegRW
15403 + \fn static __inline__ uint32_t ifxusb_rreg( volatile uint32_t *_reg)
15404 + \brief Reads the content of a register.
15405 + \param _reg address of register to read.
15406 + \return contents of the register.
15408 +static __inline__ uint32_t ifxusb_rreg( volatile uint32_t *_reg)
15410 + #ifdef RecordRegRW
15415 + return (*(_reg));
15421 + \fn static __inline__ void ifxusb_wreg( volatile uint32_t *_reg, const uint32_t _value)
15422 + \brief Writes a register with a 32 bit value.
15423 + \param _reg address of register to write.
15424 + \param _value value to write to _reg.
15426 +static __inline__ void ifxusb_wreg( volatile uint32_t *_reg, const uint32_t _value)
15428 + #ifdef RecordRegRW
15429 + printk(KERN_INFO "[W %p<-%08X]\n",_reg,_value);
15436 + \fn static __inline__ void ifxusb_mreg( volatile uint32_t *_reg, const uint32_t _clear_mask, const uint32_t _set_mask)
15437 + \brief Modifies bit values in a register. Using the
15438 + algorithm: (reg_contents & ~clear_mask) | set_mask.
15439 + \param _reg address of register to modify.
15440 + \param _clear_mask bit mask to be cleared.
15441 + \param _set_mask bit mask to be set.
15443 +static __inline__ void ifxusb_mreg( volatile uint32_t *_reg, const uint32_t _clear_mask, const uint32_t _set_mask)
15446 + #ifdef RecordRegRW
15450 + r&=(~_clear_mask);
15453 + printk(KERN_INFO "[M %p->%08X+%08X/%08X<-%08X]\n",_reg,r,_clear_mask,_set_mask,r);
15456 + v&=(~_clear_mask);
15462 +/*@}*//*IFXUSB_CSR_ACCESS_MACROS*/
15463 +/****************************************************************************/
15466 + \addtogroup IFXUSB_CSR_CORE_GLOBAL_REG
15471 + \struct ifxusb_core_global_regs
15472 + \brief IFXUSB Core registers .
15473 + The ifxusb_core_global_regs structure defines the size
15474 + and relative field offsets for the Core Global registers.
15476 +typedef struct ifxusb_core_global_regs
15478 + volatile uint32_t gotgctl; /*!< 000h OTG Control and Status Register. */
15479 + volatile uint32_t gotgint; /*!< 004h OTG Interrupt Register. */
15480 + volatile uint32_t gahbcfg; /*!< 008h Core AHB Configuration Register. */
15481 + volatile uint32_t gusbcfg; /*!< 00Ch Core USB Configuration Register. */
15482 + volatile uint32_t grstctl; /*!< 010h Core Reset Register. */
15483 + volatile uint32_t gintsts; /*!< 014h Core Interrupt Register. */
15484 + volatile uint32_t gintmsk; /*!< 018h Core Interrupt Mask Register. */
15485 + volatile uint32_t grxstsr; /*!< 01Ch Receive Status Queue Read Register (Read Only). */
15486 + volatile uint32_t grxstsp; /*!< 020h Receive Status Queue Read & POP Register (Read Only). */
15487 + volatile uint32_t grxfsiz; /*!< 024h Receive FIFO Size Register. */
15488 + volatile uint32_t gnptxfsiz; /*!< 028h Non Periodic Transmit FIFO Size Register. */
15489 + volatile uint32_t gnptxsts; /*!< 02Ch Non Periodic Transmit FIFO/Queue Status Register (Read Only). */
15490 + volatile uint32_t gi2cctl; /*!< 030h I2C Access Register. */
15491 + volatile uint32_t gpvndctl; /*!< 034h PHY Vendor Control Register. */
15492 + volatile uint32_t ggpio; /*!< 038h General Purpose Input/Output Register. */
15493 + volatile uint32_t guid; /*!< 03Ch User ID Register. */
15494 + volatile uint32_t gsnpsid; /*!< 040h Synopsys ID Register (Read Only). */
15495 + volatile uint32_t ghwcfg1; /*!< 044h User HW Config1 Register (Read Only). */
15496 + volatile uint32_t ghwcfg2; /*!< 048h User HW Config2 Register (Read Only). */
15497 + volatile uint32_t ghwcfg3; /*!< 04Ch User HW Config3 Register (Read Only). */
15498 + volatile uint32_t ghwcfg4; /*!< 050h User HW Config4 Register (Read Only). */
15499 + volatile uint32_t reserved[43]; /*!< 054h Reserved 054h-0FFh */
15500 + volatile uint32_t hptxfsiz; /*!< 100h Host Periodic Transmit FIFO Size Register. */
15501 + volatile uint32_t dptxfsiz_dieptxf[15];/*!< 104h + (FIFO_Number-1)*04h, 1 <= FIFO Number <= 15.
15502 + Device Periodic Transmit FIFO#n Register if dedicated
15503 + fifos are disabled, otherwise Device Transmit FIFO#n
15506 +} ifxusb_core_global_regs_t;
15509 + \brief Bits of the Core OTG Control and Status Register (GOTGCTL).
15511 +typedef union gotgctl_data
15515 + unsigned reserved21_31 : 11;
15516 + unsigned currmod : 1 ; /*!< 20 */
15517 + unsigned bsesvld : 1 ; /*!< 19 */
15518 + unsigned asesvld : 1 ; /*!< 18 */
15519 + unsigned reserved17 : 1 ;
15520 + unsigned conidsts : 1 ; /*!< 16 */
15521 + unsigned reserved12_15 : 4 ;
15522 + unsigned devhnpen : 1 ; /*!< 11 */
15523 + unsigned hstsethnpen : 1 ; /*!< 10 */
15524 + unsigned hnpreq : 1 ; /*!< 09 */
15525 + unsigned hstnegscs : 1 ; /*!< 08 */
15526 + unsigned reserved2_7 : 6 ;
15527 + unsigned sesreq : 1 ; /*!< 01 */
15528 + unsigned sesreqscs : 1 ; /*!< 00 */
15533 + \brief Bit fields of the Core OTG Interrupt Register (GOTGINT).
15535 +typedef union gotgint_data
15540 + unsigned reserved31_20 : 12;
15541 + unsigned debdone : 1 ; /*!< 19 Debounce Done */
15542 + unsigned adevtoutchng : 1 ; /*!< 18 A-Device Timeout Change */
15543 + unsigned hstnegdet : 1 ; /*!< 17 Host Negotiation Detected */
15544 + unsigned reserver10_16 : 7 ;
15545 + unsigned hstnegsucstschng : 1 ; /*!< 09 Host Negotiation Success Status Change */
15546 + unsigned sesreqsucstschng : 1 ; /*!< 08 Session Request Success Status Change */
15547 + unsigned reserved3_7 : 5 ;
15548 + unsigned sesenddet : 1 ; /*!< 02 Session End Detected */
15549 + unsigned reserved0_1 : 2 ;
15554 + \brief Bit fields of the Core AHB Configuration Register (GAHBCFG).
15556 +typedef union gahbcfg_data
15561 + unsigned reserved9_31 : 23;
15562 + unsigned ptxfemplvl : 1 ; /*!< 08 Periodic FIFO empty level trigger condition*/
15563 + unsigned nptxfemplvl : 1 ; /*!< 07 Non-Periodic FIFO empty level trigger condition*/
15564 + #define IFXUSB_GAHBCFG_TXFEMPTYLVL_EMPTY 1
15565 + #define IFXUSB_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
15566 + unsigned reserved : 1 ;
15567 + unsigned dmaenable : 1 ; /*!< 05 DMA enable*/
15568 + #define IFXUSB_GAHBCFG_DMAENABLE 1
15569 + unsigned hburstlen : 4 ; /*!< 01-04 DMA Burst-length*/
15570 + #define IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE 0
15571 + #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR 1
15572 + #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4 3
15573 + #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8 5
15574 + #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16 7
15575 + unsigned glblintrmsk : 1 ; /*!< 00 USB Global Interrupt Enable */
15576 + #define IFXUSB_GAHBCFG_GLBINT_ENABLE 1
15581 + \brief Bit fields of the Core USB Configuration Register (GUSBCFG).
15583 +typedef union gusbcfg_data
15588 + unsigned reserved31 : 1;
15589 + unsigned ForceDevMode : 1; /*!< 30 Force Device Mode */
15590 + unsigned ForceHstMode : 1; /*!< 29 Force Host Mode */
15591 + unsigned TxEndDelay : 1; /*!< 28 Tx End Delay */
15592 + unsigned reserved2723 : 5;
15593 + unsigned term_sel_dl_pulse : 1; /*!< 22 TermSel DLine Pulsing Selection */
15594 + unsigned reserved2117 : 5;
15595 + unsigned otgutmifssel : 1; /*!< 16 UTMIFS Select */
15596 + unsigned phylpwrclksel : 1; /*!< 15 PHY Low-Power Clock Select */
15597 + unsigned reserved14 : 1;
15598 + unsigned usbtrdtim : 4; /*!< 13-10 USB Turnaround Time */
15599 + unsigned hnpcap : 1; /*!< 09 HNP-Capable */
15600 + unsigned srpcap : 1; /*!< 08 SRP-Capable */
15601 + unsigned reserved07 : 1;
15602 + unsigned physel : 1; /*!< 06 USB 2.0 High-Speed PHY or
15603 + USB 1.1 Full-Speed Serial
15604 + Transceiver Select */
15605 + unsigned fsintf : 1; /*!< 05 Full-Speed Serial Interface Select */
15606 + unsigned ulpi_utmi_sel : 1; /*!< 04 ULPI or UTMI+ Select */
15607 + unsigned phyif : 1; /*!< 03 PHY Interface */
15608 + unsigned toutcal : 3; /*!< 00-02 HS/FS Timeout Calibration */
15613 + \brief Bit fields of the Core Reset Register (GRSTCTL).
15615 +typedef union grstctl_data
15620 + unsigned ahbidle : 1; /*!< 31 AHB Master Idle. Indicates the AHB Master State
15621 + Machine is in IDLE condition. */
15622 + unsigned dmareq : 1; /*!< 30 DMA Request Signal. Indicated DMA request is in
15623 + probress. Used for debug purpose. */
15624 + unsigned reserved11_29 :19;
15625 + unsigned txfnum : 5; /*!< 10-06 TxFIFO Number (TxFNum) to be flushed.
15626 + 0x00: Non Periodic TxFIFO Flush or TxFIFO 0
15627 + 0x01-0x0F: Periodic TxFIFO Flush or TxFIFO n
15628 + 0x10: Flush all TxFIFO
15630 + unsigned txfflsh : 1; /*!< 05 TxFIFO Flush */
15631 + unsigned rxfflsh : 1; /*!< 04 RxFIFO Flush */
15632 + unsigned intknqflsh : 1; /*!< 03 In Token Sequence Learning Queue Flush (Device Only) */
15633 + unsigned hstfrm : 1; /*!< 02 Host Frame Counter Reset (Host Only) */
15634 + unsigned hsftrst : 1; /*!< 01 Hclk Soft Reset */
15636 + unsigned csftrst : 1; /*!< 00 Core Soft Reset
15637 + The application can flush the control logic in the
15638 + entire core using this bit. This bit resets the
15639 + pipelines in the AHB Clock domain as well as the
15640 + PHY Clock domain.
15641 + The state machines are reset to an IDLE state, the
15642 + control bits in the CSRs are cleared, all the
15643 + transmit FIFOs and the receive FIFO are flushed.
15644 + The status mask bits that control the generation of
15645 + the interrupt, are cleared, to clear the
15646 + interrupt. The interrupt status bits are not
15647 + cleared, so the application can get the status of
15648 + any events that occurred in the core after it has
15650 + Any transactions on the AHB are terminated as soon
15651 + as possible following the protocol. Any
15652 + transactions on the USB are terminated immediately.
15653 + The configuration settings in the CSRs are
15654 + unchanged, so the software doesn't have to
15655 + reprogram these registers (Device
15656 + Configuration/Host Configuration/Core System
15657 + Configuration/Core PHY Configuration).
15658 + The application can write to this bit, any time it
15659 + wants to reset the core. This is a self clearing
15660 + bit and the core clears this bit after all the
15661 + necessary logic is reset in the core, which may
15662 + take several clocks, depending on the current state
15669 + \brief Bit fields of the Core Interrupt Mask Register (GINTMSK) and
15670 + Core Interrupt Register (GINTSTS).
15672 +typedef union gint_data
15675 + #define IFXUSB_SOF_INTR_MASK 0x0008
15678 + unsigned wkupintr : 1; /*!< 31 Resume/Remote Wakeup Detected Interrupt */
15679 + unsigned sessreqintr : 1; /*!< 30 Session Request/New Session Detected Interrupt */
15680 + unsigned disconnect : 1; /*!< 29 Disconnect Detected Interrupt */
15681 + unsigned conidstschng : 1; /*!< 28 Connector ID Status Change */
15682 + unsigned reserved27 : 1;
15683 + unsigned ptxfempty : 1; /*!< 26 Periodic TxFIFO Empty */
15684 + unsigned hcintr : 1; /*!< 25 Host Channels Interrupt */
15685 + unsigned portintr : 1; /*!< 24 Host Port Interrupt */
15686 + unsigned reserved23 : 1;
15687 + unsigned fetsuspmsk : 1; /*!< 22 Data Fetch Suspended */
15688 + unsigned incomplisoout : 1; /*!< 21 Incomplete IsochronousOUT/Period Transfer */
15689 + unsigned incomplisoin : 1; /*!< 20 Incomplete Isochronous IN Transfer */
15690 + unsigned outepintr : 1; /*!< 19 OUT Endpoints Interrupt */
15691 + unsigned inepintr : 1; /*!< 18 IN Endpoints Interrupt */
15692 + unsigned epmismatch : 1; /*!< 17 Endpoint Mismatch Interrupt */
15693 + unsigned reserved16 : 1;
15694 + unsigned eopframe : 1; /*!< 15 End of Periodic Frame Interrupt */
15695 + unsigned isooutdrop : 1; /*!< 14 Isochronous OUT Packet Dropped Interrupt */
15696 + unsigned enumdone : 1; /*!< 13 Enumeration Done */
15697 + unsigned usbreset : 1; /*!< 12 USB Reset */
15698 + unsigned usbsuspend : 1; /*!< 11 USB Suspend */
15699 + unsigned erlysuspend : 1; /*!< 10 Early Suspend */
15700 + unsigned i2cintr : 1; /*!< 09 I2C Interrupt */
15701 + unsigned reserved8 : 1;
15702 + unsigned goutnakeff : 1; /*!< 07 Global OUT NAK Effective */
15703 + unsigned ginnakeff : 1; /*!< 06 Global Non-periodic IN NAK Effective */
15704 + unsigned nptxfempty : 1; /*!< 05 Non-periodic TxFIFO Empty */
15705 + unsigned rxstsqlvl : 1; /*!< 04 Receive FIFO Non-Empty */
15706 + unsigned sofintr : 1; /*!< 03 Start of (u)Frame */
15707 + unsigned otgintr : 1; /*!< 02 OTG Interrupt */
15708 + unsigned modemismatch : 1; /*!< 01 Mode Mismatch Interrupt */
15709 + unsigned reserved0 : 1;
15714 + \brief Bit fields in the Receive Status Read and Pop Registers (GRXSTSR, GRXSTSP)
15716 +typedef union grxsts_data
15721 + unsigned reserved : 7;
15722 + unsigned fn : 4; /*!< 24-21 Frame Number */
15723 + unsigned pktsts : 4; /*!< 20-17 Packet Status */
15724 + #define IFXUSB_DSTS_DATA_UPDT 0x2 // OUT Data Packet
15725 + #define IFXUSB_DSTS_XFER_COMP 0x3 // OUT Data Transfer Complete
15726 + #define IFXUSB_DSTS_GOUT_NAK 0x1 // Global OUT NAK
15727 + #define IFXUSB_DSTS_SETUP_COMP 0x4 // Setup Phase Complete
15728 + #define IFXUSB_DSTS_SETUP_UPDT 0x6 // SETUP Packet
15729 + unsigned dpid : 2; /*!< 16-15 Data PID */
15730 + unsigned bcnt :11; /*!< 14-04 Byte Count */
15731 + unsigned epnum : 4; /*!< 03-00 Endpoint Number */
15735 + unsigned reserved :11;
15736 + unsigned pktsts : 4; /*!< 20-17 Packet Status */
15737 + #define IFXUSB_HSTS_DATA_UPDT 0x2 // OUT Data Packet
15738 + #define IFXUSB_HSTS_XFER_COMP 0x3 // OUT Data Transfer Complete
15739 + #define IFXUSB_HSTS_DATA_TOGGLE_ERR 0x5 // DATA TOGGLE Error
15740 + #define IFXUSB_HSTS_CH_HALTED 0x7 // Channel Halted
15741 + unsigned dpid : 2; /*!< 16-15 Data PID */
15742 + unsigned bcnt :11; /*!< 14-04 Byte Count */
15743 + unsigned chnum : 4; /*!< 03-00 Channel Number */
15748 + \brief Bit fields in the FIFO Size Registers (HPTXFSIZ, GNPTXFSIZ, DPTXFSIZn).
15750 +typedef union fifosize_data
15755 + unsigned depth : 16; /*!< 31-16 TxFIFO Depth (in DWord)*/
15756 + unsigned startaddr : 16; /*!< 15-00 RAM Starting address */
15758 +} fifosize_data_t;
15761 + \brief Bit fields in the Non-Periodic Transmit FIFO/Queue Status Register (GNPTXSTS).
15764 +typedef union gnptxsts_data
15769 + unsigned reserved : 1;
15770 + unsigned nptxqtop_chnep : 4; /*!< 30-27 Channel/EP Number of top of the Non-Periodic
15771 + Transmit Request Queue
15773 + unsigned nptxqtop_token : 2; /*!< 26-25 Token Type top of the Non-Periodic
15774 + Transmit Request Queue
15776 + 1 - Zero Length OUT
15777 + 2 - PING/Complete Split
15780 + unsigned nptxqtop_terminate : 1; /*!< 24 Terminate (Last entry for the selected
15782 + unsigned nptxqspcavail : 8; /*!< 23-16 Transmit Request Queue Space Available */
15783 + unsigned nptxfspcavail :16; /*!< 15-00 TxFIFO Space Avail (in DWord)*/
15785 +} gnptxsts_data_t;
15789 + \brief Bit fields in the Transmit FIFO Status Register (DTXFSTS).
15791 +typedef union dtxfsts_data
15796 + unsigned reserved : 16;
15797 + unsigned txfspcavail : 16; /*!< 15-00 TxFIFO Space Avail (in DWord)*/
15803 + \brief Bit fields in the I2C Control Register (I2CCTL).
15805 +typedef union gi2cctl_data
15810 + unsigned bsydne : 1; /*!< 31 I2C Busy/Done*/
15811 + unsigned rw : 1; /*!< 30 Read/Write Indicator */
15812 + unsigned reserved : 2;
15813 + unsigned i2cdevaddr : 2; /*!< 27-26 I2C Device Address */
15814 + unsigned i2csuspctl : 1; /*!< 25 I2C Suspend Control */
15815 + unsigned ack : 1; /*!< 24 I2C ACK */
15816 + unsigned i2cen : 1; /*!< 23 I2C Enable */
15817 + unsigned addr : 7; /*!< 22-16 I2C Address */
15818 + unsigned regaddr : 8; /*!< 15-08 I2C Register Addr */
15819 + unsigned rwdata : 8; /*!< I2C Read/Write Data */
15825 + \brief Bit fields in the User HW Config1 Register.
15827 +typedef union hwcfg1_data
15832 + unsigned ep_dir15 : 2; /*!< Direction of each EP
15833 + 0: BIDIR (IN and OUT) endpoint
15838 + unsigned ep_dir14 : 2;
15839 + unsigned ep_dir13 : 2;
15840 + unsigned ep_dir12 : 2;
15841 + unsigned ep_dir11 : 2;
15842 + unsigned ep_dir10 : 2;
15843 + unsigned ep_dir09 : 2;
15844 + unsigned ep_dir08 : 2;
15845 + unsigned ep_dir07 : 2;
15846 + unsigned ep_dir06 : 2;
15847 + unsigned ep_dir05 : 2;
15848 + unsigned ep_dir04 : 2;
15849 + unsigned ep_dir03 : 2;
15850 + unsigned ep_dir02 : 2;
15851 + unsigned ep_dir01 : 2;
15852 + unsigned ep_dir00 : 2;
15857 + \brief Bit fields in the User HW Config2 Register.
15859 +typedef union hwcfg2_data
15864 + unsigned reserved31 : 1;
15865 + unsigned dev_token_q_depth : 5; /*!< 30-26 Device Mode IN Token Sequence Learning Queue Depth */
15866 + unsigned host_perio_tx_q_depth : 2; /*!< 25-24 Host Mode Periodic Request Queue Depth */
15867 + unsigned nonperio_tx_q_depth : 2; /*!< 23-22 Non-periodic Request Queue Depth */
15868 + unsigned rx_status_q_depth : 2; /*!< 21-20 Multi Processor Interrupt Enabled */
15869 + unsigned dynamic_fifo : 1; /*!< 19 Dynamic FIFO Sizing Enabled */
15870 + unsigned perio_ep_supported : 1; /*!< 18 Periodic OUT Channels Supported in Host Mode */
15871 + unsigned num_host_chan : 4; /*!< 17-14 Number of Host Channels */
15872 + unsigned num_dev_ep : 4; /*!< 13-10 Number of Device Endpoints */
15873 + unsigned fs_phy_type : 2; /*!< 09-08 Full-Speed PHY Interface Type */
15874 + #define IFXUSB_HWCFG2_FS_PHY_TYPE_NOT_SUPPORTED 0
15875 + #define IFXUSB_HWCFG2_FS_PHY_TYPE_DEDICATE 1
15876 + #define IFXUSB_HWCFG2_FS_PHY_TYPE_UTMI 2
15877 + #define IFXUSB_HWCFG2_FS_PHY_TYPE_ULPI 3
15878 + unsigned hs_phy_type : 2; /*!< 07-06 High-Speed PHY Interface Type */
15879 + #define IFXUSB_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
15880 + #define IFXUSB_HWCFG2_HS_PHY_TYPE_UTMI 1
15881 + #define IFXUSB_HWCFG2_HS_PHY_TYPE_ULPI 2
15882 + #define IFXUSB_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
15883 + unsigned point2point : 1; /*!< 05 Point-to-Point */
15884 + unsigned architecture : 2; /*!< 04-03 Architecture */
15885 + #define IFXUSB_HWCFG2_ARCH_SLAVE_ONLY 0
15886 + #define IFXUSB_HWCFG2_ARCH_EXT_DMA 1
15887 + #define IFXUSB_HWCFG2_ARCH_INT_DMA 2
15888 + unsigned op_mode : 3; /*!< 02-00 Mode of Operation */
15889 + #define IFXUSB_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0
15890 + #define IFXUSB_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1
15891 + #define IFXUSB_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2
15892 + #define IFXUSB_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
15893 + #define IFXUSB_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
15894 + #define IFXUSB_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
15895 + #define IFXUSB_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
15900 + \brief Bit fields in the User HW Config3 Register.
15902 +typedef union hwcfg3_data
15907 + unsigned dfifo_depth :16; /*!< 31-16 DFIFO Depth */
15908 + unsigned reserved15_12 : 4;
15909 + unsigned synch_reset_type : 1; /*!< 11 Reset Style for Clocked always Blocks in RTL */
15910 + unsigned optional_features : 1; /*!< 10 Optional Features Removed */
15911 + unsigned vendor_ctrl_if : 1; /*!< 09 Vendor Control Interface Support */
15912 + unsigned i2c : 1; /*!< 08 I2C Selection */
15913 + unsigned otg_func : 1; /*!< 07 OTG Function Enabled */
15914 + unsigned packet_size_cntr_width : 3; /*!< 06-04 Width of Packet Size Counters */
15915 + unsigned xfer_size_cntr_width : 4; /*!< 03-00 Width of Transfer Size Counters */
15920 + \brief Bit fields in the User HW Config4
15921 + * Register. Read the register into the <i>d32</i> element then read
15922 + * out the bits using the <i>b</i>it elements.
15924 +typedef union hwcfg4_data
15929 + unsigned desc_dma_dyn : 1; /*!< 31 Scatter/Gather DMA */
15930 + unsigned desc_dma : 1; /*!< 30 Scatter/Gather DMA configuration */
15931 + unsigned num_in_eps : 4; /*!< 29-26 Number of Device Mode IN Endpoints Including Control Endpoints */
15932 + unsigned ded_fifo_en : 1; /*!< 25 Enable Dedicated Transmit FIFO for device IN Endpoints */
15933 + unsigned session_end_filt_en : 1; /*!< 24 session_end Filter Enabled */
15934 + unsigned b_valid_filt_en : 1; /*!< 23 b_valid Filter Enabled */
15935 + unsigned a_valid_filt_en : 1; /*!< 22 a_valid Filter Enabled */
15936 + unsigned vbus_valid_filt_en : 1; /*!< 21 vbus_valid Filter Enabled */
15937 + unsigned iddig_filt_en : 1; /*!< 20 iddig Filter Enable */
15938 + unsigned num_dev_mode_ctrl_ep : 4; /*!< 19-16 Number of Device Mode Control Endpoints in Addition to Endpoint 0 */
15939 + unsigned utmi_phy_data_width : 2; /*!< 15-14 UTMI+ PHY/ULPI-to-Internal UTMI+ Wrapper Data Width */
15940 + unsigned reserved13_06 : 8;
15941 + unsigned min_ahb_freq : 1; /*!< 05 Minimum AHB Frequency Less Than 60 MHz */
15942 + unsigned power_optimiz : 1; /*!< 04 Enable Power Optimization? */
15943 + unsigned num_dev_perio_in_ep : 4; /*!< 03-00 Number of Device Mode Periodic IN Endpoints */
15947 +/*@}*//*IFXUSB_CSR_CORE_GLOBAL_REG*/
15949 +/****************************************************************************/
15951 + \addtogroup IFXUSB_CSR_DEVICE_GLOBAL_REG
15956 + \struct ifxusb_dev_global_regs
15957 + \brief IFXUSB Device Mode Global registers. Offsets 800h-BFFh
15958 + The ifxusb_dev_global_regs structure defines the size
15959 + and relative field offsets for the Device Global registers.
15960 + These registers are visible only in Device mode and must not be
15961 + accessed in Host mode, as the results are unknown.
15963 +typedef struct ifxusb_dev_global_regs
15965 + volatile uint32_t dcfg; /*!< 800h Device Configuration Register. */
15966 + volatile uint32_t dctl; /*!< 804h Device Control Register. */
15967 + volatile uint32_t dsts; /*!< 808h Device Status Register (Read Only). */
15969 + volatile uint32_t diepmsk; /*!< 810h Device IN Endpoint Common Interrupt Mask Register. */
15970 + volatile uint32_t doepmsk; /*!< 814h Device OUT Endpoint Common Interrupt Mask Register. */
15971 + volatile uint32_t daint; /*!< 818h Device All Endpoints Interrupt Register. */
15972 + volatile uint32_t daintmsk; /*!< 81Ch Device All Endpoints Interrupt Mask Register. */
15973 + volatile uint32_t dtknqr1; /*!< 820h Device IN Token Queue Read Register-1 (Read Only). */
15974 + volatile uint32_t dtknqr2; /*!< 824h Device IN Token Queue Read Register-2 (Read Only). */
15975 + volatile uint32_t dvbusdis; /*!< 828h Device VBUS discharge Register.*/
15976 + volatile uint32_t dvbuspulse; /*!< 82Ch Device VBUS Pulse Register. */
15977 + volatile uint32_t dtknqr3_dthrctl; /*!< 830h Device IN Token Queue Read Register-3 (Read Only).
15978 + Device Thresholding control register (Read/Write)
15980 + volatile uint32_t dtknqr4_fifoemptymsk; /*!< 834h Device IN Token Queue Read Register-4 (Read Only).
15981 + Device IN EPs empty Inr. Mask Register (Read/Write)
15983 +} ifxusb_device_global_regs_t;
15986 + \brief Bit fields in the Device Configuration Register.
15989 +typedef union dcfg_data
15994 + unsigned reserved31_26 : 6;
15995 + unsigned perschintvl : 2; /*!< 25-24 Periodic Scheduling Interval */
15996 + unsigned descdma : 1; /*!< 23 Enable Descriptor DMA in Device mode */
15997 + unsigned epmscnt : 5; /*!< 22-18 In Endpoint Mis-match count */
15998 + unsigned reserved13_17 : 5;
15999 + unsigned perfrint : 2; /*!< 12-11 Periodic Frame Interval */
16000 + #define IFXUSB_DCFG_FRAME_INTERVAL_80 0
16001 + #define IFXUSB_DCFG_FRAME_INTERVAL_85 1
16002 + #define IFXUSB_DCFG_FRAME_INTERVAL_90 2
16003 + #define IFXUSB_DCFG_FRAME_INTERVAL_95 3
16004 + unsigned devaddr : 7; /*!< 10-04 Device Addresses */
16005 + unsigned reserved3 : 1;
16006 + unsigned nzstsouthshk : 1; /*!< 02 Non Zero Length Status OUT Handshake */
16007 + #define IFXUSB_DCFG_SEND_STALL 1
16008 + unsigned devspd : 2; /*!< 01-00 Device Speed */
16013 + \brief Bit fields in the Device Control Register.
16015 +typedef union dctl_data
16020 + unsigned reserved16_31 :16;
16021 + unsigned ifrmnum : 1; /*!< 15 Ignore Frame Number for ISOC EPs */
16022 + unsigned gmc : 2; /*!< 14-13 Global Multi Count */
16023 + unsigned gcontbna : 1; /*!< 12 Global Continue on BNA */
16024 + unsigned pwronprgdone : 1; /*!< 11 Power-On Programming Done */
16025 + unsigned cgoutnak : 1; /*!< 10 Clear Global OUT NAK */
16026 + unsigned sgoutnak : 1; /*!< 09 Set Global OUT NAK */
16027 + unsigned cgnpinnak : 1; /*!< 08 Clear Global Non-Periodic IN NAK */
16028 + unsigned sgnpinnak : 1; /*!< 07 Set Global Non-Periodic IN NAK */
16029 + unsigned tstctl : 3; /*!< 06-04 Test Control */
16030 + unsigned goutnaksts : 1; /*!< 03 Global OUT NAK Status */
16031 + unsigned gnpinnaksts : 1; /*!< 02 Global Non-Periodic IN NAK Status */
16032 + unsigned sftdiscon : 1; /*!< 01 Soft Disconnect */
16033 + unsigned rmtwkupsig : 1; /*!< 00 Remote Wakeup */
16039 + \brief Bit fields in the Device Status Register.
16041 +typedef union dsts_data
16046 + unsigned reserved22_31 :10;
16047 + unsigned soffn :14; /*!< 21-08 Frame or Microframe Number of the received SOF */
16048 + unsigned reserved4_7 : 4;
16049 + unsigned errticerr : 1; /*!< 03 Erratic Error */
16050 + unsigned enumspd : 2; /*!< 02-01 Enumerated Speed */
16051 + #define IFXUSB_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
16052 + #define IFXUSB_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
16053 + #define IFXUSB_DSTS_ENUMSPD_LS_PHY_6MHZ 2
16054 + #define IFXUSB_DSTS_ENUMSPD_FS_PHY_48MHZ 3
16055 + unsigned suspsts : 1; /*!< 00 Suspend Status */
16060 + \brief Bit fields in the Device IN EP Interrupt Register
16061 + and the Device IN EP Common Mask Register.
16063 +typedef union diepint_data
16068 + unsigned reserved14_31 :18;
16069 + unsigned nakmsk : 1; /*!< 13 NAK interrupt Mask */
16070 + unsigned reserved10_12 : 3;
16071 + unsigned bna : 1; /*!< 09 BNA Interrupt mask */
16072 + unsigned txfifoundrn : 1; /*!< 08 Fifo Underrun Mask */
16073 + unsigned emptyintr : 1; /*!< 07 IN Endpoint HAK Effective mask */
16074 + unsigned inepnakeff : 1; /*!< 06 IN Endpoint HAK Effective mask */
16075 + unsigned intknepmis : 1; /*!< 05 IN Token Received with EP mismatch mask */
16076 + unsigned intktxfemp : 1; /*!< 04 IN Token received with TxF Empty mask */
16077 + unsigned timeout : 1; /*!< 03 TimeOUT Handshake mask (non-ISOC EPs) */
16078 + unsigned ahberr : 1; /*!< 02 AHB Error mask */
16079 + unsigned epdisabled : 1; /*!< 01 Endpoint disable mask */
16080 + unsigned xfercompl : 1; /*!< 00 Transfer complete mask */
16086 + \brief Bit fields in the Device OUT EP Interrupt Register and
16087 + Device OUT EP Common Interrupt Mask Register.
16089 +typedef union doepint_data
16094 + unsigned reserved15_31 :17;
16095 + unsigned nyetmsk : 1; /*!< 14 NYET Interrupt */
16096 + unsigned nakmsk : 1; /*!< 13 NAK Interrupt */
16097 + unsigned bbleerrmsk : 1; /*!< 12 Babble Interrupt */
16098 + unsigned reserved10_11 : 2;
16099 + unsigned bna : 1; /*!< 09 BNA Interrupt */
16100 + unsigned outpkterr : 1; /*!< 08 OUT packet Error */
16101 + unsigned reserved07 : 1;
16102 + unsigned back2backsetup : 1; /*!< 06 Back-to-Back SETUP Packets Received */
16103 + unsigned stsphsercvd : 1; /*!< 05 */
16104 + unsigned outtknepdis : 1; /*!< 04 OUT Token Received when Endpoint Disabled */
16105 + unsigned setup : 1; /*!< 03 Setup Phase Done (contorl EPs) */
16106 + unsigned ahberr : 1; /*!< 02 AHB Error */
16107 + unsigned epdisabled : 1; /*!< 01 Endpoint disable */
16108 + unsigned xfercompl : 1; /*!< 00 Transfer complete */
16114 + \brief Bit fields in the Device All EP Interrupt Registers.
16116 +typedef union daint_data
16121 + unsigned out : 16; /*!< 31-16 OUT Endpoint bits */
16122 + unsigned in : 16; /*!< 15-00 IN Endpoint bits */
16126 + /** OUT Endpoint bits */
16127 + unsigned outep15 : 1;
16128 + unsigned outep14 : 1;
16129 + unsigned outep13 : 1;
16130 + unsigned outep12 : 1;
16131 + unsigned outep11 : 1;
16132 + unsigned outep10 : 1;
16133 + unsigned outep09 : 1;
16134 + unsigned outep08 : 1;
16135 + unsigned outep07 : 1;
16136 + unsigned outep06 : 1;
16137 + unsigned outep05 : 1;
16138 + unsigned outep04 : 1;
16139 + unsigned outep03 : 1;
16140 + unsigned outep02 : 1;
16141 + unsigned outep01 : 1;
16142 + unsigned outep00 : 1;
16143 + /** IN Endpoint bits */
16144 + unsigned inep15 : 1;
16145 + unsigned inep14 : 1;
16146 + unsigned inep13 : 1;
16147 + unsigned inep12 : 1;
16148 + unsigned inep11 : 1;
16149 + unsigned inep10 : 1;
16150 + unsigned inep09 : 1;
16151 + unsigned inep08 : 1;
16152 + unsigned inep07 : 1;
16153 + unsigned inep06 : 1;
16154 + unsigned inep05 : 1;
16155 + unsigned inep04 : 1;
16156 + unsigned inep03 : 1;
16157 + unsigned inep02 : 1;
16158 + unsigned inep01 : 1;
16159 + unsigned inep00 : 1;
16165 + \brief Bit fields in the Device IN Token Queue Read Registers.
16167 +typedef union dtknq1_data
16172 + unsigned epnums0_5 :24; /*!< 31-08 EP Numbers of IN Tokens 0 ... 4 */
16173 + unsigned wrap_bit : 1; /*!< 07 write pointer has wrapped */
16174 + unsigned reserved05_06 : 2;
16175 + unsigned intknwptr : 5; /*!< 04-00 In Token Queue Write Pointer */
16181 + \brief Bit fields in Threshold control Register
16183 +typedef union dthrctl_data
16188 + unsigned reserved26_31 : 6;
16189 + unsigned rx_thr_len : 9; /*!< 25-17 Rx Thr. Length */
16190 + unsigned rx_thr_en : 1; /*!< 16 Rx Thr. Enable */
16191 + unsigned reserved11_15 : 5;
16192 + unsigned tx_thr_len : 9; /*!< 10-02 Tx Thr. Length */
16193 + unsigned iso_thr_en : 1; /*!< 01 ISO Tx Thr. Enable */
16194 + unsigned non_iso_thr_en : 1; /*!< 00 non ISO Tx Thr. Enable */
16198 +/*@}*//*IFXUSB_CSR_DEVICE_GLOBAL_REG*/
16200 +/****************************************************************************/
16203 + \addtogroup IFXUSB_CSR_DEVICE_EP_REG
16208 + \struct ifxusb_dev_in_ep_regs
16209 + \brief Device Logical IN Endpoint-Specific Registers.
16210 + There will be one set of endpoint registers per logical endpoint
16212 + each EP's IN EP Register are offset at :
16213 + 900h + * (ep_num * 20h)
16216 +typedef struct ifxusb_dev_in_ep_regs
16218 + volatile uint32_t diepctl; /*!< 00h: Endpoint Control Register */
16219 + uint32_t reserved04; /*!< 04h: */
16220 + volatile uint32_t diepint; /*!< 08h: Endpoint Interrupt Register */
16221 + uint32_t reserved0C; /*!< 0Ch: */
16222 + volatile uint32_t dieptsiz; /*!< 10h: Endpoint Transfer Size Register.*/
16223 + volatile uint32_t diepdma; /*!< 14h: Endpoint DMA Address Register. */
16224 + volatile uint32_t dtxfsts; /*!< 18h: Endpoint Transmit FIFO Status Register. */
16225 + volatile uint32_t diepdmab; /*!< 1Ch: Endpoint DMA Buffer Register. */
16226 +} ifxusb_dev_in_ep_regs_t;
16229 + \brief Device Logical OUT Endpoint-Specific Registers.
16230 + There will be one set of endpoint registers per logical endpoint
16232 + each EP's OUT EP Register are offset at :
16233 + B00h + * (ep_num * 20h) + 00h
16235 +typedef struct ifxusb_dev_out_ep_regs
16237 + volatile uint32_t doepctl; /*!< 00h: Endpoint Control Register */
16238 + volatile uint32_t doepfn; /*!< 04h: Endpoint Frame number Register */
16239 + volatile uint32_t doepint; /*!< 08h: Endpoint Interrupt Register */
16240 + uint32_t reserved0C; /*!< 0Ch: */
16241 + volatile uint32_t doeptsiz; /*!< 10h: Endpoint Transfer Size Register.*/
16242 + volatile uint32_t doepdma; /*!< 14h: Endpoint DMA Address Register. */
16243 + uint32_t reserved18; /*!< 18h: */
16244 + volatile uint32_t doepdmab; /*!< 1Ch: Endpoint DMA Buffer Register. */
16245 +} ifxusb_dev_out_ep_regs_t;
16249 + \brief Bit fields in the Device EP Control
16252 +typedef union depctl_data
16257 + unsigned epena : 1; /*!< 31 Endpoint Enable */
16258 + unsigned epdis : 1; /*!< 30 Endpoint Disable */
16259 + unsigned setd1pid : 1; /*!< 29 Set DATA1 PID (INTR/Bulk IN and OUT endpoints) */
16260 + unsigned setd0pid : 1; /*!< 28 Set DATA0 PID (INTR/Bulk IN and OUT endpoints) */
16261 + unsigned snak : 1; /*!< 27 Set NAK */
16262 + unsigned cnak : 1; /*!< 26 Clear NAK */
16263 + unsigned txfnum : 4; /*!< 25-22 Tx Fifo Number */
16264 + unsigned stall : 1; /*!< 21 Stall Handshake */
16265 + unsigned snp : 1; /*!< 20 Snoop Mode */
16266 + unsigned eptype : 2; /*!< 19-18 Endpoint Type
16272 + unsigned naksts : 1; /*!< 17 NAK Status */
16273 + unsigned dpid : 1; /*!< 16 Endpoint DPID (INTR/Bulk IN and OUT endpoints) */
16274 + unsigned usbactep : 1; /*!< 15 USB Active Endpoint */
16275 + unsigned nextep : 4; /*!< 14-11 Next Endpoint */
16276 + unsigned mps :11; /*!< 10-00 Maximum Packet Size */
16277 + #define IFXUSB_DEP0CTL_MPS_64 0
16278 + #define IFXUSB_DEP0CTL_MPS_32 1
16279 + #define IFXUSB_DEP0CTL_MPS_16 2
16280 + #define IFXUSB_DEP0CTL_MPS_8 3
16286 + \brief Bit fields in the Device EP Transfer Size Register. (EP0 and EPn)
16288 +typedef union deptsiz_data
16293 + unsigned reserved31 : 1;
16294 + unsigned supcnt : 2; /*!< 30-29 Setup Packet Count */
16295 + unsigned reserved20_28 : 9;
16296 + unsigned pktcnt : 1; /*!< 19 Packet Count */
16297 + unsigned reserved7_18 :12;
16298 + unsigned xfersize : 7; /*!< 06-00 Transfer size */
16302 + unsigned reserved : 1;
16303 + unsigned mc : 2; /*!< 30-29 Multi Count */
16304 + unsigned pktcnt :10; /*!< 28-19 Packet Count */
16305 + unsigned xfersize :19; /*!< 18-00 Transfer size */
16309 +/*@}*//*IFXUSB_CSR_DEVICE_EP_REG*/
16310 +/****************************************************************************/
16313 + \addtogroup IFXUSB_CSR_DEVICE_DMA_DESC
16317 + \struct desc_sts_data
16318 + \brief Bit fields in the DMA Descriptor status quadlet.
16320 +typedef union desc_sts_data
16324 + unsigned bs : 2; /*!< 31-30 Buffer Status */
16325 + #define BS_HOST_READY 0x0
16326 + #define BS_DMA_BUSY 0x1
16327 + #define BS_DMA_DONE 0x2
16328 + #define BS_HOST_BUSY 0x3
16329 + unsigned sts : 2; /*!< 29-28 Receive/Trasmit Status */
16330 + #define RTS_SUCCESS 0x0
16331 + #define RTS_BUFFLUSH 0x1
16332 + #define RTS_RESERVED 0x2
16333 + #define RTS_BUFERR 0x3
16334 + unsigned l : 1; /*!< 27 Last */
16335 + unsigned sp : 1; /*!< 26 Short Packet */
16336 + unsigned ioc : 1; /*!< 25 Interrupt On Complete */
16337 + unsigned sr : 1; /*!< 24 Setup Packet received */
16338 + unsigned mtrf : 1; /*!< 23 Multiple Transfer */
16339 + unsigned reserved16_22 : 7;
16340 + unsigned bytes :16; /*!< 15-00 Transfer size in bytes */
16342 + uint32_t d32; /*!< DMA Descriptor data buffer pointer */
16343 +} desc_sts_data_t;
16345 +/*@}*//*IFXUSB_CSR_DEVICE_DMA_DESC*/
16346 +/****************************************************************************/
16349 + \addtogroup IFXUSB_CSR_HOST_GLOBAL_REG
16353 + \struct ifxusb_host_global_regs
16354 + \brief IFXUSB Host Mode Global registers. Offsets 400h-7FFh
16355 + The ifxusb_host_global_regs structure defines the size
16356 + and relative field offsets for the Host Global registers.
16357 + These registers are visible only in Host mode and must not be
16358 + accessed in Device mode, as the results are unknown.
16360 +typedef struct ifxusb_host_global_regs
16362 + volatile uint32_t hcfg; /*!< 400h Host Configuration Register. */
16363 + volatile uint32_t hfir; /*!< 404h Host Frame Interval Register. */
16364 + volatile uint32_t hfnum; /*!< 408h Host Frame Number / Frame Remaining Register. */
16365 + uint32_t reserved40C;
16366 + volatile uint32_t hptxsts; /*!< 410h Host Periodic Transmit FIFO/ Queue Status Register. */
16367 + volatile uint32_t haint; /*!< 414h Host All Channels Interrupt Register. */
16368 + volatile uint32_t haintmsk; /*!< 418h Host All Channels Interrupt Mask Register. */
16369 +} ifxusb_host_global_regs_t;
16372 + \brief Bit fields in the Host Configuration Register.
16374 +typedef union hcfg_data
16379 + unsigned reserved31_03 :29;
16380 + unsigned fslssupp : 1; /*!< 02 FS/LS Only Support */
16381 + unsigned fslspclksel : 2; /*!< 01-00 FS/LS Phy Clock Select */
16382 + #define IFXUSB_HCFG_30_60_MHZ 0
16383 + #define IFXUSB_HCFG_48_MHZ 1
16384 + #define IFXUSB_HCFG_6_MHZ 2
16389 + \brief Bit fields in the Host Frame Interval Register.
16391 +typedef union hfir_data
16396 + unsigned reserved : 16;
16397 + unsigned frint : 16; /*!< 15-00 Frame Interval */
16402 + \brief Bit fields in the Host Frame Time Remaing/Number Register.
16404 +typedef union hfnum_data
16409 + unsigned frrem : 16; /*!< 31-16 Frame Time Remaining */
16410 + unsigned frnum : 16; /*!< 15-00 Frame Number*/
16411 + #define IFXUSB_HFNUM_MAX_FRNUM 0x3FFF
16416 + \brief Bit fields in the Host Periodic Transmit FIFO/Queue Status Register
16418 +typedef union hptxsts_data
16420 + /** raw register data */
16424 + /** Top of the Periodic Transmit Request Queue
16425 + * - bit 24 - Terminate (last entry for the selected channel)
16427 + unsigned ptxqtop_odd : 1; /*!< 31 Top of the Periodic Transmit Request
16428 + Queue Odd/even microframe*/
16429 + unsigned ptxqtop_chnum : 4; /*!< 30-27 Top of the Periodic Transmit Request
16430 + Channel Number */
16431 + unsigned ptxqtop_token : 2; /*!< 26-25 Top of the Periodic Transmit Request
16437 + unsigned ptxqtop_terminate : 1; /*!< 24 Top of the Periodic Transmit Request
16438 + Terminate (last entry for the selected channel)*/
16439 + unsigned ptxqspcavail : 8; /*!< 23-16 Periodic Transmit Request Queue Space Available */
16440 + unsigned ptxfspcavail :16; /*!< 15-00 Periodic Transmit Data FIFO Space Available */
16445 + \brief Bit fields in the Host Port Control and Status Register.
16447 +typedef union hprt0_data
16452 + unsigned reserved19_31 :13;
16453 + unsigned prtspd : 2; /*!< 18-17 Port Speed */
16454 + #define IFXUSB_HPRT0_PRTSPD_HIGH_SPEED 0
16455 + #define IFXUSB_HPRT0_PRTSPD_FULL_SPEED 1
16456 + #define IFXUSB_HPRT0_PRTSPD_LOW_SPEED 2
16457 + unsigned prttstctl : 4; /*!< 16-13 Port Test Control */
16458 + unsigned prtpwr : 1; /*!< 12 Port Power */
16459 + unsigned prtlnsts : 2; /*!< 11-10 Port Line Status */
16460 + unsigned reserved9 : 1;
16461 + unsigned prtrst : 1; /*!< 08 Port Reset */
16462 + unsigned prtsusp : 1; /*!< 07 Port Suspend */
16463 + unsigned prtres : 1; /*!< 06 Port Resume */
16464 + unsigned prtovrcurrchng : 1; /*!< 05 Port Overcurrent Change */
16465 + unsigned prtovrcurract : 1; /*!< 04 Port Overcurrent Active */
16466 + unsigned prtenchng : 1; /*!< 03 Port Enable/Disable Change */
16467 + unsigned prtena : 1; /*!< 02 Port Enable */
16468 + unsigned prtconndet : 1; /*!< 01 Port Connect Detected */
16469 + unsigned prtconnsts : 1; /*!< 00 Port Connect Status */
16474 + \brief Bit fields in the Host All Interrupt Register.
16476 +typedef union haint_data
16481 + unsigned reserved : 16;
16482 + unsigned ch15 : 1;
16483 + unsigned ch14 : 1;
16484 + unsigned ch13 : 1;
16485 + unsigned ch12 : 1;
16486 + unsigned ch11 : 1;
16487 + unsigned ch10 : 1;
16488 + unsigned ch09 : 1;
16489 + unsigned ch08 : 1;
16490 + unsigned ch07 : 1;
16491 + unsigned ch06 : 1;
16492 + unsigned ch05 : 1;
16493 + unsigned ch04 : 1;
16494 + unsigned ch03 : 1;
16495 + unsigned ch02 : 1;
16496 + unsigned ch01 : 1;
16497 + unsigned ch00 : 1;
16501 + unsigned reserved : 16;
16502 + unsigned chint : 16;
16505 +/*@}*//*IFXUSB_CSR_HOST_GLOBAL_REG*/
16506 +/****************************************************************************/
16508 + \addtogroup IFXUSB_CSR_HOST_HC_REG
16512 + \brief Host Channel Specific Registers
16513 + There will be one set of hc registers per host channelimplemented.
16514 + each HC's Register are offset at :
16515 + 500h + * (hc_num * 20h)
16517 +typedef struct ifxusb_hc_regs
16519 + volatile uint32_t hcchar; /*!< 00h Host Channel Characteristic Register.*/
16520 + volatile uint32_t hcsplt; /*!< 04h Host Channel Split Control Register.*/
16521 + volatile uint32_t hcint; /*!< 08h Host Channel Interrupt Register. */
16522 + volatile uint32_t hcintmsk; /*!< 0Ch Host Channel Interrupt Mask Register. */
16523 + volatile uint32_t hctsiz; /*!< 10h Host Channel Transfer Size Register. */
16524 + volatile uint32_t hcdma; /*!< 14h Host Channel DMA Address Register. */
16525 + uint32_t reserved[2]; /*!< 18h Reserved. */
16526 +} ifxusb_hc_regs_t;
16530 + \brief Bit fields in the Host Channel Characteristics Register.
16532 +typedef union hcchar_data
16537 + unsigned chen : 1; /*!< 31 Channel enable */
16538 + unsigned chdis : 1; /*!< 30 Channel disable */
16539 + unsigned oddfrm : 1; /*!< 29 Frame to transmit periodic transaction */
16540 + unsigned devaddr : 7; /*!< 28-22 Device address */
16541 + unsigned multicnt : 2; /*!< 21-20 Packets per frame for periodic transfers */
16542 + unsigned eptype : 2; /*!< 19-18 0: Control, 1: Isoc, 2: Bulk, 3: Intr */
16543 + unsigned lspddev : 1; /*!< 17 0: Full/high speed device, 1: Low speed device */
16544 + unsigned reserved : 1;
16545 + unsigned epdir : 1; /*!< 15 0: OUT, 1: IN */
16546 + unsigned epnum : 4; /*!< 14-11 Endpoint number */
16547 + unsigned mps :11; /*!< 10-00 Maximum packet size in bytes */
16552 + \brief Bit fields in the Host Channel Split Control Register
16554 +typedef union hcsplt_data
16559 + unsigned spltena : 1; /*!< 31 Split Enble */
16560 + unsigned reserved :14;
16561 + unsigned compsplt : 1; /*!< 16 Do Complete Split */
16562 + unsigned xactpos : 2; /*!< 15-14 Transaction Position */
16563 + #define IFXUSB_HCSPLIT_XACTPOS_MID 0
16564 + #define IFXUSB_HCSPLIT_XACTPOS_END 1
16565 + #define IFXUSB_HCSPLIT_XACTPOS_BEGIN 2
16566 + #define IFXUSB_HCSPLIT_XACTPOS_ALL 3
16567 + unsigned hubaddr : 7; /*!< 13-07 Hub Address */
16568 + unsigned prtaddr : 7; /*!< 06-00 Port Address */
16573 + \brief Bit fields in the Host Interrupt Register.
16575 +typedef union hcint_data
16580 + unsigned reserved :21;
16581 + unsigned datatglerr : 1; /*!< 10 Data Toggle Error */
16582 + unsigned frmovrun : 1; /*!< 09 Frame Overrun */
16583 + unsigned bblerr : 1; /*!< 08 Babble Error */
16584 + unsigned xacterr : 1; /*!< 07 Transaction Err */
16585 + unsigned nyet : 1; /*!< 06 NYET Response Received */
16586 + unsigned ack : 1; /*!< 05 ACK Response Received */
16587 + unsigned nak : 1; /*!< 04 NAK Response Received */
16588 + unsigned stall : 1; /*!< 03 STALL Response Received */
16589 + unsigned ahberr : 1; /*!< 02 AHB Error */
16590 + unsigned chhltd : 1; /*!< 01 Channel Halted */
16591 + unsigned xfercomp : 1; /*!< 00 Channel Halted */
16597 + \brief Bit fields in the Host Channel Transfer Size
16600 +typedef union hctsiz_data
16606 + unsigned dopng : 1; /*!< 31 Do PING protocol when 1 */
16608 + * Packet ID for next data packet
16612 + * 3: MDATA (non-Control), SETUP (Control)
16614 + unsigned pid : 2; /*!< 30-29 Packet ID for next data packet
16618 + 3: MDATA (non-Control), SETUP (Control)
16620 + #define IFXUSB_HCTSIZ_DATA0 0
16621 + #define IFXUSB_HCTSIZ_DATA1 2
16622 + #define IFXUSB_HCTSIZ_DATA2 1
16623 + #define IFXUSB_HCTSIZ_MDATA 3
16624 + #define IFXUSB_HCTSIZ_SETUP 3
16625 + unsigned pktcnt :10; /*!< 28-19 Data packets to transfer */
16626 + unsigned xfersize :19; /*!< 18-00 Total transfer size in bytes */
16630 +/*@}*//*IFXUSB_CSR_HOST_HC_REG*/
16632 +/****************************************************************************/
16635 + \addtogroup IFXUSB_CSR_PWR_CLK_GATING_REG
16639 + \brief Bit fields in the Power and Clock Gating Control Register
16641 +typedef union pcgcctl_data
16646 + unsigned reserved : 27;
16647 + unsigned physuspended : 1; /*!< 04 PHY Suspended */
16648 + unsigned rstpdwnmodule : 1; /*!< 03 Reset Power Down Modules */
16649 + unsigned pwrclmp : 1; /*!< 02 Power Clamp */
16650 + unsigned gatehclk : 1; /*!< 01 Gate Hclk */
16651 + unsigned stoppclk : 1; /*!< 00 Stop Pclk */
16654 +/*@}*//*IFXUSB_CSR_PWR_CLK_GATING_REG*/
16656 +/****************************************************************************/
16658 +#endif //__IFXUSB_REGS_H__
16659 diff --git a/drivers/usb/ifxhcd/ifxusb_version.h b/drivers/usb/ifxhcd/ifxusb_version.h
16660 new file mode 100644
16661 index 0000000..2dff735
16663 +++ b/drivers/usb/ifxhcd/ifxusb_version.h
16666 +#ifndef IFXUSB_VERSION
16667 +#define IFXUSB_VERSION "3.0alpha B100312"