1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_linux.c $
7 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9 * otherwise expressly agreed to in writing between Synopsys and you.
11 * The Software IS NOT an item of Licensed Software or Licensed Product under
12 * any End User Software License Agreement or Agreement for Licensed Product
13 * with Synopsys or any supplement thereto. You are permitted to use and
14 * redistribute this Software in source and binary forms, with or without
15 * modification, provided that redistributions of source code must retain this
16 * notice. You may not view, use, disclose, copy or distribute this file or
17 * any information contained herein except pursuant to this license grant from
18 * Synopsys. If you do not agree with this notice, including the disclaimer
19 * below, then you are not authorized to use the Software.
21 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32 * ========================================================================== */
33 #ifndef DWC_DEVICE_ONLY
38 * This file contains the implementation of the HCD. In Linux, the HCD
39 * implements the hc_driver API.
41 #include <linux/kernel.h>
42 #include <linux/module.h>
43 #include <linux/moduleparam.h>
44 #include <linux/init.h>
45 #include <linux/device.h>
46 #include <linux/errno.h>
47 #include <linux/list.h>
48 #include <linux/interrupt.h>
49 #include <linux/string.h>
50 #include <linux/dma-mapping.h>
51 #include <linux/version.h>
53 #ifdef CONFIG_MACH_IPMATE
54 #include <asm/arch/regs-irq.h>
55 #include <asm/arch/lm.h>
56 #include <asm/arch/irqs.h>
58 #include <linux/platform_device.h>
59 #include <linux/irq.h>
60 #include <linux/wakelock.h>
62 #include <linux/usb.h>
63 #include <linux/usb/hcd.h>
64 #include <linux/usb/gadget.h>
66 #include <soc/sprd/adi.h>
67 #include <soc/sprd/sci_glb_regs.h>
69 #ifdef CONFIG_USB_EXTERNAL_DETECT
70 #include <linux/usb_notifier.h>
73 #include "dwc_otg_hcd_if.h"
74 #include "dwc_otg_dbg.h"
75 #include "dwc_otg_driver.h"
76 #include "dwc_otg_hcd.h"
79 static dwc_otg_device_t *_otg_dev = NULL;
82 * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
83 * qualified with its direction (possible 32 endpoints per device).
85 #define dwc_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
86 ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
88 static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
89 static struct wake_lock usb_host_wake_lock;
92 /** @name Linux HC Driver API Functions */
94 static int urb_enqueue(struct usb_hcd *hcd,
95 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
96 struct usb_host_endpoint *ep,
98 struct urb *urb, gfp_t mem_flags);
99 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
100 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb);
102 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
105 static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
106 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
107 static void endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
109 static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd);
110 extern int hcd_start(struct usb_hcd *hcd);
111 extern void hcd_stop(struct usb_hcd *hcd);
112 static int get_frame_number(struct usb_hcd *hcd);
113 extern int hub_status_data(struct usb_hcd *hcd, char *buf);
114 extern int hub_control(struct usb_hcd *hcd,
116 u16 wValue, u16 wIndex, char *buf, u16 wLength);
118 static int dwc_otg_bus_suspend(struct usb_hcd *hcd);
119 static int dwc_otg_bus_resume(struct usb_hcd *hcd);
121 #ifdef CONFIG_SPRD_EXT_IC_POWER
122 extern void sprd_extic_otg_power(int enable);
125 struct wrapper_priv_data {
126 dwc_otg_hcd_t *dwc_otg_hcd;
129 #define OTG_CABLE_TIMEOUT (HZ*3)
132 static struct hc_driver dwc_otg_hc_driver = {
134 .description = dwc_otg_hcd_name,
135 .product_desc = "DWC OTG Controller",
136 .hcd_priv_size = sizeof(struct wrapper_priv_data),
138 .irq = dwc_otg_hcd_irq,
140 .flags = HCD_MEMORY | HCD_USB2,
148 .urb_enqueue = urb_enqueue,
149 .urb_dequeue = urb_dequeue,
150 .endpoint_disable = endpoint_disable,
151 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
152 .endpoint_reset = endpoint_reset,
154 .get_frame_number = get_frame_number,
156 .hub_status_data = hub_status_data,
157 .hub_control = hub_control,
158 .bus_suspend = dwc_otg_bus_suspend,
159 .bus_resume = dwc_otg_bus_resume,
162 /** fake function: for bus suspend fail err -2 */
163 /** when work in host mode,doesn't allow the system to enter suspend */
164 static int dwc_otg_bus_suspend(struct usb_hcd *hcd)
166 //struct dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
168 //printk("%s\n", __func__);
169 if(usb_get_id_state())
175 static int dwc_otg_bus_resume(struct usb_hcd *hcd)
177 //struct dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
179 //printk("%s\n", __func__);
183 /** Gets the dwc_otg_hcd from a struct usb_hcd */
184 static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
186 struct wrapper_priv_data *p;
187 p = (struct wrapper_priv_data *)(hcd->hcd_priv);
188 return p->dwc_otg_hcd;
191 /** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */
192 static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t * dwc_otg_hcd)
194 return dwc_otg_hcd_get_priv_data(dwc_otg_hcd);
197 /** Gets the usb_host_endpoint associated with an URB. */
198 inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
200 struct usb_device *dev = urb->dev;
201 int ep_num = usb_pipeendpoint(urb->pipe);
203 if (usb_pipein(urb->pipe))
204 return dev->ep_in[ep_num];
206 return dev->ep_out[ep_num];
209 static int _disconnect(dwc_otg_hcd_t * hcd)
211 struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
213 usb_hcd->self.is_b_host = 0;
217 static int _start(dwc_otg_hcd_t * hcd)
219 struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
221 usb_hcd->self.is_b_host = dwc_otg_hcd_is_b_host(hcd);
227 static int _hub_info(dwc_otg_hcd_t * hcd, void *urb_handle, uint32_t * hub_addr,
228 uint32_t * port_addr)
230 struct urb *urb = (struct urb *)urb_handle;
232 *hub_addr = urb->dev->tt->hub->devnum;
236 *port_addr = urb->dev->ttport;
240 static int _speed(dwc_otg_hcd_t * hcd, void *urb_handle)
242 struct urb *urb = (struct urb *)urb_handle;
243 return urb->dev->speed;
246 static int _get_b_hnp_enable(dwc_otg_hcd_t * hcd)
248 struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
249 return usb_hcd->self.b_hnp_enable;
252 static void allocate_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
255 hcd_to_bus(hcd)->bandwidth_allocated += bw / urb->interval;
256 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
257 hcd_to_bus(hcd)->bandwidth_isoc_reqs++;
259 hcd_to_bus(hcd)->bandwidth_int_reqs++;
263 static void free_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
266 hcd_to_bus(hcd)->bandwidth_allocated -= bw / urb->interval;
267 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
268 hcd_to_bus(hcd)->bandwidth_isoc_reqs--;
270 hcd_to_bus(hcd)->bandwidth_int_reqs--;
275 * Sets the final status of an URB and returns it to the device driver. Any
276 * required cleanup of the URB is performed.
278 static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
279 dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
281 struct urb *urb = (struct urb *)urb_handle;
283 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
284 DWC_PRINTF("%s: urb %p, device %d, ep %d %s, status=%d\n",
285 __func__, urb, usb_pipedevice(urb->pipe),
286 usb_pipeendpoint(urb->pipe),
287 usb_pipein(urb->pipe) ? "IN" : "OUT", status);
288 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
290 for (i = 0; i < urb->number_of_packets; i++) {
291 DWC_PRINTF(" ISO Desc %d status: %d\n",
292 i, urb->iso_frame_desc[i].status);
298 urb->actual_length = dwc_otg_hcd_urb_get_actual_length(dwc_otg_urb);
299 /* Convert status value. */
301 case -DWC_E_PROTOCOL:
304 case -DWC_E_IN_PROGRESS:
305 status = -EINPROGRESS;
316 case -DWC_E_OVERFLOW:
321 DWC_PRINTF("Uknown urb status %d\n", status);
326 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
329 urb->error_count = dwc_otg_hcd_urb_get_error_count(dwc_otg_urb);
330 for (i = 0; i < urb->number_of_packets; ++i) {
331 urb->iso_frame_desc[i].actual_length =
332 dwc_otg_hcd_urb_get_iso_desc_actual_length
334 urb->iso_frame_desc[i].status =
335 dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_urb, i);
339 urb->status = status;
342 if ((urb->transfer_flags & URB_SHORT_NOT_OK) &&
343 (urb->actual_length < urb->transfer_buffer_length)) {
344 urb->status = -EREMOTEIO;
348 if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) ||
349 (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
350 struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
352 free_bus_bandwidth(dwc_otg_hcd_to_hcd(hcd),
353 dwc_otg_hcd_get_ep_bandwidth(hcd,
359 DWC_FREE(dwc_otg_urb);
361 DWC_SPINUNLOCK(hcd->lock);
362 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
363 usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb);
365 usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
367 DWC_SPINLOCK(hcd->lock);
372 static struct dwc_otg_hcd_function_ops hcd_fops = {
374 .disconnect = _disconnect,
375 .hub_info = _hub_info,
377 .complete = _complete,
378 .get_b_hnp_enable = _get_b_hnp_enable,
382 static struct timer_list otg_cable_connect_timer;
383 static int32_t otg_cable_connect_fun(void *dev)
386 dwc_otg_device_t *otg_dev = dev;
387 printk("USB otg cable is not connected timeout");
390 otg_cable_disconnect(otg_dev->core_if);
391 if(timer_pending(&otg_cable_connect_timer))
392 del_timer(&otg_cable_connect_timer);
398 static int start_otg_flag = 0;
400 void usb_otg_cable_detect_work(void *p)
402 dwc_otg_device_t *otg_dev = p;
403 struct sprd_usb_platform_data *platform_data =&otg_dev->platform_data;
407 vbus_irq = usb_get_vbus_irq();
408 value = usb_get_id_state();
410 if(start_otg_flag ==1){
411 pr_info("usb otg cable detect work plug out\n");
412 wake_unlock(&usb_host_wake_lock);
413 //otg_cable_disconnect(otg_dev->core_if);
414 //charge_pump_set(platform_data->gpio_boost,0);This charge method is implemented by internal chip on ADIE,and that will not be used;
416 mdelay(10);//charge pump need time to turn off
417 sci_adi_write((ANA_EIC_BASE+0x24),1,0);//clear vbus irq flag before enable it
418 enable_irq(vbus_irq);
422 if(start_otg_flag ==0){
423 pr_info("usb otg cable detect work plug in\n");
425 //charge_pump_set(platform_data->gpio_boost,1);This charge method is implemented by internal chip on ADIE,and that will not be used;
426 dwc_otg_set_param_dma_desc_enable(otg_dev->core_if,0);
428 dwc_otg_core_fore_host(otg_dev->core_if);
429 dwc_otg_core_init(otg_dev->core_if);
430 _start(otg_dev->hcd);
431 dwc_otg_enable_global_interrupts(otg_dev->core_if);
437 void usb_otg_cable_detect_event(bool is_otg_cable_in)
439 if (!is_otg_cable_in) {
442 if (_otg_dev != NULL) {
443 dwc_otg_set_param_dma_desc_enable(_otg_dev->core_if,0);
445 dwc_otg_core_fore_host(_otg_dev->core_if);
446 dwc_otg_core_init(_otg_dev->core_if);
447 _start(_otg_dev->hcd);
448 dwc_otg_enable_global_interrupts(_otg_dev->core_if);
450 pr_err("[%s] _otg_dev is null!\n", __func__);
456 static irqreturn_t usb_otg_cable_detect_handler(int irq, void *dev)
458 dwc_otg_device_t *otg_dev = dev;
462 vbus_irq = usb_get_vbus_irq();
463 value = usb_get_id_state();
465 pr_info("usb otg cable detect plug out\n");
467 usb_set_id_irq_type(irq, OTG_CABLE_PLUG_IN);
468 #ifdef CONFIG_SPRD_EXT_IC_POWER
469 sprd_extic_otg_power(0); //Turn off ext ic otg func
472 pr_info("usb otg cable detect plug in\n");
473 disable_irq(vbus_irq);
474 usb_set_id_irq_type(irq, OTG_CABLE_PLUG_OUT);
475 #ifdef CONFIG_SPRD_EXT_IC_POWER
476 sprd_extic_otg_power(1); //Turn on ext ic otg func
479 /*use DWC workqueue*/
480 DWC_WORKQ_SCHEDULE_DELAYED(otg_dev->core_if->wq_otg, usb_otg_cable_detect_work,
481 otg_dev, 50, "OTG cable connect state change");
486 #ifdef CONFIG_USB_EXTERNAL_DETECT
487 int dwc_otg_start(void *data, bool enable)
489 struct usb_hcd *hcd = NULL;
490 dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)data;
491 struct sprd_usb_platform_data *platform_data
492 = &otg_dev->platform_data;
494 pr_info("%s enable=%d+\n", __func__, enable);
496 hcd = dwc_otg_hcd_get_priv_data(otg_dev->hcd);
498 dwc_otg_set_param_dma_desc_enable(otg_dev->core_if,0);
501 dwc_otg_core_fore_host(otg_dev->core_if);
502 dwc_otg_core_init(otg_dev->core_if);
503 _start(otg_dev->hcd);
504 usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
506 dwc_otg_enable_global_interrupts(otg_dev->core_if);
508 dwc_otg_disable_global_interrupts(otg_dev->core_if);
509 otg_cable_disconnect(otg_dev->core_if);
513 pr_info("%s-\n", __func__);
517 static struct device *device_hcd_dwc_otg;
518 static u64 dwc_otg_dmamask = DMA_BIT_MASK(32);
520 * Initializes the HCD. This function allocates memory for and initializes the
521 * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
522 * USB bus with the core and calls the hc_driver->start() function. It returns
523 * a negative error on failure.
526 struct platform_device *_dev
529 struct usb_hcd *hcd = NULL;
530 dwc_otg_hcd_t *dwc_otg_hcd = NULL;
531 dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev);
532 struct sprd_usb_platform_data *pdata= _dev->dev.platform_data;
535 int otg_cable_connected;
538 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
540 device_hcd_dwc_otg = &(_dev->dev);
543 /* Set device flags indicating whether the HCD supports DMA. */
544 /* HCD.c will judge this flag. */
545 /* and also scsi_lib.c will check this dma_mask. daniel.li */
546 if (dwc_otg_is_dma_enable(otg_dev->core_if)) {
547 _dev->dev.dma_mask = &dwc_otg_dmamask;
548 _dev->dev.coherent_dma_mask = dwc_otg_dmamask;
550 _dev->dev.dma_mask = (void *)0;
551 _dev->dev.coherent_dma_mask = 0;
555 * Allocate memory for the base HCD plus the DWC OTG HCD.
556 * Initialize the base HCD.
558 hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, dev_name(&_dev->dev));
559 /** need hcd->has_tt = 1, because if the device is work on FS, we should support it**/
566 #ifdef CONFIG_USB_EXTERNAL_DETECT
570 // hcd->uses_new_polling = 1;
573 hcd->regs = otg_dev->os_dep.base;
575 /* Initialize the DWC OTG HCD. */
576 dwc_otg_hcd = dwc_otg_hcd_alloc_hcd();
580 ((struct wrapper_priv_data *)(hcd->hcd_priv))->dwc_otg_hcd =
582 otg_dev->hcd = dwc_otg_hcd;
584 if (dwc_otg_hcd_init(dwc_otg_hcd, otg_dev->core_if)) {
588 otg_dev->hcd->otg_dev = otg_dev;
589 hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd);
591 irq = platform_get_irq(_dev, 0);
592 #if 0//need to confirm LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) //don't support for LM(with 2.6.20.1 kernel)
593 hcd->self.otg_version = dwc_otg_get_otg_version(otg_dev->core_if);
594 /* Don't support SG list at this point */
595 hcd->self.sg_tablesize = 0;
597 #ifdef CONFIG_USB_EXTERNAL_DETECT
599 register_otg_func(dwc_otg_start, NULL, otg_dev);
602 * Finish generic HCD initialization and start the HCD. This function
603 * allocates the DMA buffer pool, registers the USB bus, requests the
604 * IRQ line, and calls hcd_start method.
606 retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
612 /*doesn't need timer, just judge the GPIO ID state, if no otg cable connect ,host_init wouldn't done*/
613 setup_timer(&otg_cable_connect_timer,otg_cable_connect_fun,otg_dev);
614 mod_timer(&otg_cable_connect_timer, jiffies + OTG_CABLE_TIMEOUT);
616 #ifndef CONFIG_USB_EXTERNAL_DETECT
617 #ifndef CONFIG_MFD_SM5504
619 * setup usb OTG cable detect interrupt, using id pin. added by sprd
622 otg_cable_irq = usb_alloc_id_irq(pdata->gpio_otgdet);
623 if (otg_cable_irq < 0) {
624 pr_warning("cannot alloc otg cable irq\n");
627 usb_set_id_irq_type(otg_cable_irq, OTG_CABLE_PLUG_IN);
628 otg_cable_connected = usb_get_id_state();
629 pr_info("now usb id state is :%d\n", otg_cable_connected);
630 retval = request_irq(otg_cable_irq, usb_otg_cable_detect_handler, IRQF_NO_SUSPEND,
631 "usb otg cable detect", otg_dev);
637 wake_lock_init(&usb_host_wake_lock, WAKE_LOCK_SUSPEND, "usb_host_work");
638 dwc_otg_hcd_set_priv_data(dwc_otg_hcd, hcd);
649 * Frees memory and resources associated with the HCD and deregisters the bus.
652 struct platform_device *_dev
656 dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev);
659 dwc_otg_hcd_t *dwc_otg_hcd;
662 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
665 DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
669 dwc_otg_hcd = otg_dev->hcd;
672 DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
676 hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
680 "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n",
684 #ifndef CONFIG_USB_EXTERNAL_DETECT
687 dwc_otg_hcd_set_priv_data(dwc_otg_hcd, NULL);
688 dwc_otg_hcd_remove(dwc_otg_hcd);
692 /* =========================================================================
693 * Linux HC Driver Functions
694 * ========================================================================= */
696 /** Initializes the DWC_otg controller and its root hub and prepares it for host
697 * mode operation. Activates the root port. Returns 0 on success and a negative
698 * error code on failure. */
699 int hcd_start(struct usb_hcd *hcd)
701 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
704 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
705 bus = hcd_to_bus(hcd);
707 hcd->state = HC_STATE_RUNNING;
708 if (dwc_otg_hcd_start(dwc_otg_hcd, &hcd_fops)) {
712 /* Initialize and connect root hub if one is not already attached */
714 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n");
715 /* Inform the HUB driver to resume. */
716 usb_hcd_resume_root_hub(hcd);
723 * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
726 void hcd_stop(struct usb_hcd *hcd)
728 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
730 dwc_otg_hcd_stop(dwc_otg_hcd);
733 /** Returns the current frame number. */
734 static int get_frame_number(struct usb_hcd *hcd)
736 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
738 return dwc_otg_hcd_get_frame_number(dwc_otg_hcd);
742 static void dump_urb_info(struct urb *urb, char *fn_name)
744 DWC_PRINTF("%s, urb %p\n", fn_name, urb);
745 DWC_PRINTF(" Device address: %d\n", usb_pipedevice(urb->pipe));
746 DWC_PRINTF(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
747 (usb_pipein(urb->pipe) ? "IN" : "OUT"));
748 DWC_PRINTF(" Endpoint type: %s\n", ( {
750 switch (usb_pipetype(urb->pipe)) {
752 pipetype = "CONTROL"; break; case PIPE_BULK:
753 pipetype = "BULK"; break; case PIPE_INTERRUPT:
754 pipetype = "INTERRUPT"; break; case PIPE_ISOCHRONOUS:
755 pipetype = "ISOCHRONOUS"; break; default:
756 pipetype = "UNKNOWN"; break;};
759 DWC_PRINTF(" Speed: %s\n", ( {
760 char *speed; switch (urb->dev->speed) {
762 speed = "HIGH"; break; case USB_SPEED_FULL:
763 speed = "FULL"; break; case USB_SPEED_LOW:
764 speed = "LOW"; break; default:
765 speed = "UNKNOWN"; break;};
768 DWC_PRINTF(" Max packet size: %d\n",
769 usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
770 DWC_PRINTF(" Data buffer length: %d\n", urb->transfer_buffer_length);
771 DWC_PRINTF(" Transfer buffer: %p, Transfer DMA: %p\n",
772 urb->transfer_buffer, (void *)urb->transfer_dma);
773 DWC_PRINTF(" Setup buffer: %p, Setup DMA: %p\n",
774 urb->setup_packet, (void *)urb->setup_dma);
775 DWC_PRINTF(" Interval: %d\n", urb->interval);
776 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
778 for (i = 0; i < urb->number_of_packets; i++) {
779 DWC_PRINTF(" ISO Desc %d:\n", i);
780 DWC_PRINTF(" offset: %d, length %d\n",
781 urb->iso_frame_desc[i].offset,
782 urb->iso_frame_desc[i].length);
789 /** Starts processing a USB transfer request specified by a USB Request Block
790 * (URB). mem_flags indicates the type of memory allocation to use while
791 * processing this URB. */
792 static int urb_enqueue(struct usb_hcd *hcd,
793 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
794 struct usb_host_endpoint *ep,
796 struct urb *urb, gfp_t mem_flags)
799 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
800 struct usb_host_endpoint *ep = urb->ep;
802 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
803 dwc_otg_hcd_urb_t *dwc_otg_urb;
805 int alloc_bandwidth = 0;
811 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
812 dump_urb_info(urb, "urb_enqueue");
816 if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
817 || (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
818 if (!dwc_otg_hcd_is_bandwidth_allocated
819 (dwc_otg_hcd, &ep->hcpriv)) {
824 switch (usb_pipetype(urb->pipe)) {
826 ep_type = USB_ENDPOINT_XFER_CONTROL;
828 case PIPE_ISOCHRONOUS:
829 ep_type = USB_ENDPOINT_XFER_ISOC;
832 ep_type = USB_ENDPOINT_XFER_BULK;
835 ep_type = USB_ENDPOINT_XFER_INT;
838 DWC_WARN("Wrong ep type\n");
841 dwc_otg_urb = dwc_otg_hcd_urb_alloc(dwc_otg_hcd,
842 urb->number_of_packets,
843 mem_flags == GFP_ATOMIC ? 1 : 0);
845 dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_urb, usb_pipedevice(urb->pipe),
846 usb_pipeendpoint(urb->pipe), ep_type,
847 usb_pipein(urb->pipe),
848 usb_maxpacket(urb->dev, urb->pipe,
849 !(usb_pipein(urb->pipe))));
851 buf = urb->transfer_buffer;
852 if (hcd->self.uses_dma) {
854 * Calculate virtual address from physical address,
855 * because some class driver may not fill transfer_buffer.
856 * In Buffer DMA mode virual address is used,
857 * when handling non DWORD aligned buffers.
859 buf = phys_to_virt(urb->transfer_dma);
862 if (!(urb->transfer_flags & URB_NO_INTERRUPT))
863 flags |= URB_GIVEBACK_ASAP;
864 if (urb->transfer_flags & URB_ZERO_PACKET)
865 flags |= URB_SEND_ZERO_PACKET;
867 dwc_otg_hcd_urb_set_params(dwc_otg_urb, urb, buf,
869 urb->transfer_buffer_length,
871 urb->setup_dma, flags, urb->interval);
873 for (i = 0; i < urb->number_of_packets; ++i) {
874 dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_urb, i,
876 iso_frame_desc[i].offset,
878 iso_frame_desc[i].length);
881 urb->hcpriv = dwc_otg_urb;
882 retval = dwc_otg_hcd_urb_enqueue(dwc_otg_hcd, dwc_otg_urb, &ep->hcpriv,
883 mem_flags == GFP_ATOMIC ? 1 : 0);
885 if (alloc_bandwidth) {
886 allocate_bus_bandwidth(hcd,
887 dwc_otg_hcd_get_ep_bandwidth
888 (dwc_otg_hcd, ep->hcpriv), urb);
891 if (retval == -DWC_E_NO_DEVICE) {
899 /** Aborts/cancels a USB transfer request. Always returns 0 to indicate
901 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
902 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
904 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
907 dwc_irqflags_t flags;
908 dwc_otg_hcd_t *dwc_otg_hcd;
909 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
911 dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
914 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
915 dump_urb_info(urb, "urb_dequeue");
919 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
920 if(urb->hcpriv != NULL) {
921 dwc_otg_hcd_urb_dequeue(dwc_otg_hcd, urb->hcpriv);
923 DWC_FREE(urb->hcpriv);
926 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
928 /* Higher layer software sets URB status. */
929 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
930 usb_hcd_giveback_urb(hcd, urb);
932 usb_hcd_giveback_urb(hcd, urb, status);
934 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
935 DWC_PRINTF("Called usb_hcd_giveback_urb()\n");
936 DWC_PRINTF(" urb->status = %d\n", urb->status);
942 /* Frees resources in the DWC_otg controller related to a given endpoint. Also
943 * clears state in the HCD related to the endpoint. Any URBs for the endpoint
944 * must already be dequeued. */
945 static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
947 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
950 "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
951 "endpoint=%d\n", ep->desc.bEndpointAddress,
952 dwc_ep_addr_to_endpoint(ep->desc.bEndpointAddress));
953 dwc_otg_hcd_endpoint_disable(dwc_otg_hcd, ep->hcpriv, 250);
957 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
958 /* Resets endpoint specific parameter values, in current version used to reset
959 * the data toggle(as a WA). This function can be called from usb_clear_halt routine */
960 static void endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
962 dwc_irqflags_t flags;
963 struct usb_device *udev = NULL;
964 int epnum = usb_endpoint_num(&ep->desc);
965 int is_out = usb_endpoint_dir_out(&ep->desc);
966 int is_control = usb_endpoint_xfer_control(&ep->desc);
967 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
968 struct device *dev = DWC_OTG_OS_GETDEV(dwc_otg_hcd->otg_dev->os_dep);
971 udev = to_usb_device(dev);
975 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP RESET: Endpoint Num=0x%02d\n", epnum);
977 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
978 usb_settoggle(udev, epnum, is_out, 0);
980 usb_settoggle(udev, epnum, !is_out, 0);
983 dwc_otg_hcd_endpoint_reset(dwc_otg_hcd, ep->hcpriv);
985 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
989 /** Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
990 * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
993 * This function is called by the USB core when an interrupt occurs */
994 static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd)
996 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
997 int32_t retval = dwc_otg_hcd_handle_intr(dwc_otg_hcd);
999 S3C2410X_CLEAR_EINTPEND();
1001 return IRQ_RETVAL(retval);
1004 /** Creates Status Change bitmap for the root hub and root port. The bitmap is
1005 * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
1006 * is the status change indicator for the single root port. Returns 1 if either
1007 * change indicator is 1, otherwise returns 0. */
1008 int hub_status_data(struct usb_hcd *hcd, char *buf)
1010 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1013 buf[0] |= (dwc_otg_hcd_is_status_changed(dwc_otg_hcd, 1)) << 1;
1015 return (buf[0] != 0);
1018 /** Handles hub class-specific requests. */
1019 int hub_control(struct usb_hcd *hcd,
1020 u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
1024 retval = dwc_otg_hcd_hub_control(hcd_to_dwc_otg_hcd(hcd),
1025 typeReq, wValue, wIndex, buf, wLength);
1028 case -DWC_E_INVALID:
1036 struct device *get_hcd_device()
1039 if(NULL != device_hcd_dwc_otg)
1041 return device_hcd_dwc_otg;
1045 gadget_wrapper->gadget.dev.dma_mask = &dwc_otg_dmamask;
1046 gadget_wrapper->gadget.dev.coherent_dma_mask = dwc_otg_dmamask;
1047 return &(gadget_wrapper->gadget.dev);
1054 #endif /* DWC_DEVICE_ONLY */