tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / usb / gadget / dwc_otg / dwc_otg_hcd_linux.c
1 /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_linux.c $
3  * $Revision: #20 $
4  * $Date: 2011/10/26 $
5  * $Change: 1872981 $
6  *
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.
10  *
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.
20  *
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
31  * DAMAGE.
32  * ========================================================================== */
33 #ifndef DWC_DEVICE_ONLY
34
35 /**
36  * @file
37  *
38  * This file contains the implementation of the HCD. In Linux, the HCD
39  * implements the hc_driver API.
40  */
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>
52 #include <asm/io.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>
57 #endif
58 #include <linux/platform_device.h>
59 #include <linux/irq.h>
60 #include <linux/wakelock.h>
61
62 #include <linux/usb.h>
63 #include <linux/usb/hcd.h>
64 #include <linux/usb/gadget.h>
65
66 #include <soc/sprd/adi.h>
67 #include <soc/sprd/sci_glb_regs.h>
68
69 #ifdef CONFIG_USB_EXTERNAL_DETECT
70 #include <linux/usb_notifier.h>
71 #endif
72
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"
77 #include "usb_hw.h"
78
79 static dwc_otg_device_t *_otg_dev = NULL;
80
81 /**
82  * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
83  * qualified with its direction (possible 32 endpoints per device).
84  */
85 #define dwc_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
86                                                      ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
87
88 static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
89 static struct wake_lock usb_host_wake_lock;
90
91
92 /** @name Linux HC Driver API Functions */
93 /** @{ */
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,
97 #endif
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);
101 #else
102 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
103 #endif
104
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);
108 #endif
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,
115                        u16 typeReq,
116                        u16 wValue, u16 wIndex, char *buf, u16 wLength);
117
118 static int dwc_otg_bus_suspend(struct usb_hcd *hcd);
119 static int dwc_otg_bus_resume(struct usb_hcd *hcd);
120
121 #ifdef CONFIG_SPRD_EXT_IC_POWER
122 extern void sprd_extic_otg_power(int enable);
123 #endif
124
125 struct wrapper_priv_data {
126         dwc_otg_hcd_t *dwc_otg_hcd;
127 };
128
129 #define OTG_CABLE_TIMEOUT               (HZ*3)
130 /** @} */
131
132 static struct hc_driver dwc_otg_hc_driver = {
133
134         .description = dwc_otg_hcd_name,
135         .product_desc = "DWC OTG Controller",
136         .hcd_priv_size = sizeof(struct wrapper_priv_data),
137
138         .irq = dwc_otg_hcd_irq,
139
140         .flags = HCD_MEMORY | HCD_USB2,
141
142         //.reset =              
143         .start = hcd_start,
144         //.suspend =            
145         //.resume =             
146         .stop = hcd_stop,
147
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,
153 #endif
154         .get_frame_number = get_frame_number,
155
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,     
160 };
161
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)
165 {
166         //struct dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
167
168         //printk("%s\n", __func__);
169         if(usb_get_id_state())
170                 return 0;
171         else
172                 return -EBUSY;
173 }
174
175 static int dwc_otg_bus_resume(struct usb_hcd *hcd)
176 {
177         //struct dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
178
179         //printk("%s\n", __func__);
180         return 0;
181 }
182
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)
185 {
186         struct wrapper_priv_data *p;
187         p = (struct wrapper_priv_data *)(hcd->hcd_priv);
188         return p->dwc_otg_hcd;
189 }
190
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)
193 {
194         return dwc_otg_hcd_get_priv_data(dwc_otg_hcd);
195 }
196
197 /** Gets the usb_host_endpoint associated with an URB. */
198 inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
199 {
200         struct usb_device *dev = urb->dev;
201         int ep_num = usb_pipeendpoint(urb->pipe);
202
203         if (usb_pipein(urb->pipe))
204                 return dev->ep_in[ep_num];
205         else
206                 return dev->ep_out[ep_num];
207 }
208
209 static int _disconnect(dwc_otg_hcd_t * hcd)
210 {
211         struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
212
213         usb_hcd->self.is_b_host = 0;
214         return 0;
215 }
216
217 static int _start(dwc_otg_hcd_t * hcd)
218 {
219         struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
220
221         usb_hcd->self.is_b_host = dwc_otg_hcd_is_b_host(hcd);
222         hcd_start(usb_hcd);
223
224         return 0;
225 }
226
227 static int _hub_info(dwc_otg_hcd_t * hcd, void *urb_handle, uint32_t * hub_addr,
228                      uint32_t * port_addr)
229 {
230         struct urb *urb = (struct urb *)urb_handle;
231         if (urb->dev->tt) {
232                 *hub_addr = urb->dev->tt->hub->devnum;
233         } else {
234                 *hub_addr = 0;
235         }
236         *port_addr = urb->dev->ttport;
237         return 0;
238 }
239
240 static int _speed(dwc_otg_hcd_t * hcd, void *urb_handle)
241 {
242         struct urb *urb = (struct urb *)urb_handle;
243         return urb->dev->speed;
244 }
245
246 static int _get_b_hnp_enable(dwc_otg_hcd_t * hcd)
247 {
248         struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
249         return usb_hcd->self.b_hnp_enable;
250 }
251
252 static void allocate_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
253                                    struct urb *urb)
254 {
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++;
258         } else {
259                 hcd_to_bus(hcd)->bandwidth_int_reqs++;
260         }
261 }
262
263 static void free_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
264                                struct urb *urb)
265 {
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--;
269         } else {
270                 hcd_to_bus(hcd)->bandwidth_int_reqs--;
271         }
272 }
273
274 /**
275  * Sets the final status of an URB and returns it to the device driver. Any
276  * required cleanup of the URB is performed.
277  */
278 static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
279                      dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
280 {
281         struct urb *urb = (struct urb *)urb_handle;
282 #ifdef DEBUG
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) {
289                         int i;
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);
293                         }
294                 }
295         }
296 #endif
297
298         urb->actual_length = dwc_otg_hcd_urb_get_actual_length(dwc_otg_urb);
299         /* Convert status value. */
300         switch (status) {
301         case -DWC_E_PROTOCOL:
302                 status = -EPROTO;
303                 break;
304         case -DWC_E_IN_PROGRESS:
305                 status = -EINPROGRESS;
306                 break;
307         case -DWC_E_PIPE:
308                 status = -EPIPE;
309                 break;
310         case -DWC_E_IO:
311                 status = -EIO;
312                 break;
313         case -DWC_E_TIMEOUT:
314                 status = -ETIMEDOUT;
315                 break;
316         case -DWC_E_OVERFLOW:
317                 status = -EOVERFLOW;
318                 break;
319         default:
320                 if (status) {
321                         DWC_PRINTF("Uknown urb status %d\n", status);
322
323                 }
324         }
325
326         if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
327                 int i;
328
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
333                             (dwc_otg_urb, i);
334                         urb->iso_frame_desc[i].status =
335                             dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_urb, i);
336                 }
337         }
338
339         urb->status = status;
340         urb->hcpriv = NULL;
341         if (!status) {
342                 if ((urb->transfer_flags & URB_SHORT_NOT_OK) &&
343                     (urb->actual_length < urb->transfer_buffer_length)) {
344                         urb->status = -EREMOTEIO;
345                 }
346         }
347
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);
351                 if (ep) {
352                         free_bus_bandwidth(dwc_otg_hcd_to_hcd(hcd),
353                                            dwc_otg_hcd_get_ep_bandwidth(hcd,
354                                                                         ep->hcpriv),
355                                            urb);
356                 }
357         }
358
359         DWC_FREE(dwc_otg_urb);
360
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);
364 #else
365         usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
366 #endif
367         DWC_SPINLOCK(hcd->lock);
368
369         return 0;
370 }
371
372 static struct dwc_otg_hcd_function_ops hcd_fops = {
373         .start = _start,
374         .disconnect = _disconnect,
375         .hub_info = _hub_info,
376         .speed = _speed,
377         .complete = _complete,
378         .get_b_hnp_enable = _get_b_hnp_enable,
379 };
380
381 #if 0
382 static struct timer_list otg_cable_connect_timer;
383 static int32_t otg_cable_connect_fun(void *dev)
384 {
385
386         dwc_otg_device_t *otg_dev = dev;        
387         printk("USB otg cable is not connected timeout");
388         return 0;
389         /*
390         otg_cable_disconnect(otg_dev->core_if);
391         if(timer_pending(&otg_cable_connect_timer))
392                 del_timer(&otg_cable_connect_timer);
393         */
394
395 }
396 #endif
397
398 static int start_otg_flag = 0;
399
400 void usb_otg_cable_detect_work(void *p)
401 {
402         dwc_otg_device_t *otg_dev = p;
403          struct sprd_usb_platform_data *platform_data =&otg_dev->platform_data;
404         int value = 0;
405         int vbus_irq;
406         
407         vbus_irq = usb_get_vbus_irq();
408         value = usb_get_id_state();
409         if (value){
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;
415                         udc_disable();
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);
419                         start_otg_flag = 0;
420                 }
421         } else {
422                 if(start_otg_flag ==0){
423                         pr_info("usb otg cable detect work plug in\n");
424
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);
427                         udc_enable();
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);
432                         start_otg_flag = 1;
433                 }
434         }
435
436 }
437 void usb_otg_cable_detect_event(bool is_otg_cable_in)
438 {
439         if (!is_otg_cable_in) {
440                 udc_disable();
441         } else {
442                 if (_otg_dev != NULL) {
443                         dwc_otg_set_param_dma_desc_enable(_otg_dev->core_if,0);
444                         udc_enable();
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);
449                 } else {
450                         pr_err("[%s] _otg_dev is null!\n", __func__);
451                 }
452         }
453
454 }
455
456 static irqreturn_t usb_otg_cable_detect_handler(int irq, void *dev)
457 {
458         dwc_otg_device_t *otg_dev = dev;
459         int value = 0;
460         int vbus_irq;
461         
462         vbus_irq = usb_get_vbus_irq();
463         value = usb_get_id_state();
464         if (value){
465                 pr_info("usb otg cable detect plug out\n");
466
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
470 #endif
471         } else {
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
477 #endif
478         }
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");
482
483         return IRQ_HANDLED;
484 }
485
486 #ifdef CONFIG_USB_EXTERNAL_DETECT
487 int dwc_otg_start(void *data, bool enable)
488 {
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;
493
494         pr_info("%s enable=%d+\n", __func__, enable);
495
496         hcd = dwc_otg_hcd_get_priv_data(otg_dev->hcd);
497         if (enable) {
498                 dwc_otg_set_param_dma_desc_enable(otg_dev->core_if,0);
499                 udc_enable();
500                 usb_phy_tune_host();
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);
505                 mdelay(10);
506                 dwc_otg_enable_global_interrupts(otg_dev->core_if);
507         } else {
508                 dwc_otg_disable_global_interrupts(otg_dev->core_if);
509                 otg_cable_disconnect(otg_dev->core_if);
510                 usb_remove_hcd(hcd);
511                 udc_disable();
512         }
513         pr_info("%s-\n", __func__);
514         return 0;
515 }
516 #endif
517 static struct device *device_hcd_dwc_otg;
518 static u64 dwc_otg_dmamask = DMA_BIT_MASK(32);
519 /**
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.
524  */
525 int hcd_init(
526         struct platform_device *_dev
527         )
528 {
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;
533         int irq;
534         int otg_cable_irq;
535         int otg_cable_connected;
536         int retval = 0;
537
538         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
539 #ifdef CONFIG_ARM64
540         device_hcd_dwc_otg = &(_dev->dev);
541 #endif
542
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;
549         } else {
550                 _dev->dev.dma_mask = (void *)0;
551                 _dev->dev.coherent_dma_mask = 0;
552         }
553
554         /*
555          * Allocate memory for the base HCD plus the DWC OTG HCD.
556          * Initialize the base HCD.
557          */
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**/
560         if (!hcd) {
561                 retval = -ENOMEM;
562                 goto error1;
563         }
564
565         hcd->has_tt = 1;
566 #ifdef CONFIG_USB_EXTERNAL_DETECT
567         hcd->no_suspend = 1;
568 #endif
569
570 //      hcd->uses_new_polling = 1;
571 //      hcd->poll_rh = 0;
572
573         hcd->regs = otg_dev->os_dep.base;
574
575         /* Initialize the DWC OTG HCD. */
576         dwc_otg_hcd = dwc_otg_hcd_alloc_hcd();
577         if (!dwc_otg_hcd) {
578                 goto error2;
579         }
580         ((struct wrapper_priv_data *)(hcd->hcd_priv))->dwc_otg_hcd =
581             dwc_otg_hcd;
582         otg_dev->hcd = dwc_otg_hcd;
583
584         if (dwc_otg_hcd_init(dwc_otg_hcd, otg_dev->core_if)) {
585                 goto error2;
586         }
587
588         otg_dev->hcd->otg_dev = otg_dev;
589         hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd);
590         
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;
596 #endif
597 #ifdef CONFIG_USB_EXTERNAL_DETECT
598         hcd->irq = irq;
599         register_otg_func(dwc_otg_start, NULL, otg_dev);
600 #else
601         /*
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.
605          */
606         retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
607         if (retval < 0) {
608                 goto error2;
609         }
610 #endif
611 #if 0   
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);
615 #endif
616 #ifndef CONFIG_USB_EXTERNAL_DETECT
617 #ifndef CONFIG_MFD_SM5504
618         /*
619          * setup usb OTG cable detect interrupt, using id pin. added by sprd
620          */
621         {
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");
625                         return -EBUSY;
626                 }
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);
632         }
633 #endif
634 #endif
635         //save to global
636         _otg_dev = 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);
639         return 0;
640
641       error2:
642         usb_put_hcd(hcd);
643       error1:
644         return retval;
645 }
646
647 /**
648  * Removes the HCD.
649  * Frees memory and resources associated with the HCD and deregisters the bus.
650  */
651 void hcd_remove(
652         struct platform_device *_dev
653
654         )
655 {
656         dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev);
657
658
659         dwc_otg_hcd_t *dwc_otg_hcd;
660         struct usb_hcd *hcd;
661
662         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
663
664         if (!otg_dev) {
665                 DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
666                 return;
667         }
668
669         dwc_otg_hcd = otg_dev->hcd;
670
671         if (!dwc_otg_hcd) {
672                 DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
673                 return;
674         }
675
676         hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
677
678         if (!hcd) {
679                 DWC_DEBUGPL(DBG_ANY,
680                             "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n",
681                             __func__);
682                 return;
683         }
684 #ifndef CONFIG_USB_EXTERNAL_DETECT
685         usb_remove_hcd(hcd);
686 #endif
687         dwc_otg_hcd_set_priv_data(dwc_otg_hcd, NULL);
688         dwc_otg_hcd_remove(dwc_otg_hcd);
689         usb_put_hcd(hcd);
690 }
691
692 /* =========================================================================
693  *  Linux HC Driver Functions
694  * ========================================================================= */
695
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)
700 {
701         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
702         struct usb_bus *bus;
703
704         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
705         bus = hcd_to_bus(hcd);
706
707         hcd->state = HC_STATE_RUNNING;
708         if (dwc_otg_hcd_start(dwc_otg_hcd, &hcd_fops)) {
709                 return 0;
710         }
711
712         /* Initialize and connect root hub if one is not already attached */
713         if (bus->root_hub) {
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);
717         }
718
719         return 0;
720 }
721
722 /**
723  * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
724  * stopped.
725  */
726 void hcd_stop(struct usb_hcd *hcd)
727 {
728         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
729
730         dwc_otg_hcd_stop(dwc_otg_hcd);
731 }
732
733 /** Returns the current frame number. */
734 static int get_frame_number(struct usb_hcd *hcd)
735 {
736         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
737
738         return dwc_otg_hcd_get_frame_number(dwc_otg_hcd);
739 }
740
741 #ifdef DEBUG
742 static void dump_urb_info(struct urb *urb, char *fn_name)
743 {
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", ( {
749                                              char *pipetype;
750                                              switch (usb_pipetype(urb->pipe)) {
751 case PIPE_CONTROL:
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;};
757                                              pipetype;}
758                    )) ;
759         DWC_PRINTF("  Speed: %s\n", ( {
760                                      char *speed; switch (urb->dev->speed) {
761 case USB_SPEED_HIGH:
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;};
766                                      speed;}
767                    )) ;
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) {
777                 int i;
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);
783                 }
784         }
785 }
786
787 #endif
788
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,
795 #endif
796                        struct urb *urb, gfp_t mem_flags)
797 {
798         int retval = 0;
799 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
800         struct usb_host_endpoint *ep = urb->ep;
801 #endif
802         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
803         dwc_otg_hcd_urb_t *dwc_otg_urb;
804         int i;
805         int alloc_bandwidth = 0;
806         uint8_t ep_type = 0;
807         uint32_t flags = 0;
808         void *buf;
809
810 #ifdef DEBUG
811         if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
812                 dump_urb_info(urb, "urb_enqueue");
813         }
814 #endif
815
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)) {
820                         alloc_bandwidth = 1;
821                 }
822         }
823
824         switch (usb_pipetype(urb->pipe)) {
825         case PIPE_CONTROL:
826                 ep_type = USB_ENDPOINT_XFER_CONTROL;
827                 break;
828         case PIPE_ISOCHRONOUS:
829                 ep_type = USB_ENDPOINT_XFER_ISOC;
830                 break;
831         case PIPE_BULK:
832                 ep_type = USB_ENDPOINT_XFER_BULK;
833                 break;
834         case PIPE_INTERRUPT:
835                 ep_type = USB_ENDPOINT_XFER_INT;
836                 break;
837         default:
838                 DWC_WARN("Wrong ep type\n");
839         }
840
841         dwc_otg_urb = dwc_otg_hcd_urb_alloc(dwc_otg_hcd,
842                                             urb->number_of_packets,
843                                             mem_flags == GFP_ATOMIC ? 1 : 0);
844
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))));
850
851         buf = urb->transfer_buffer;
852         if (hcd->self.uses_dma) {
853                 /*
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.
858                  */
859                 buf = phys_to_virt(urb->transfer_dma);
860         }
861         
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;
866
867         dwc_otg_hcd_urb_set_params(dwc_otg_urb, urb, buf,
868                                    urb->transfer_dma,
869                                    urb->transfer_buffer_length,
870                                    urb->setup_packet,
871                                    urb->setup_dma, flags, urb->interval);
872
873         for (i = 0; i < urb->number_of_packets; ++i) {
874                 dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_urb, i,
875                                                     urb->
876                                                     iso_frame_desc[i].offset,
877                                                     urb->
878                                                     iso_frame_desc[i].length);
879         }
880
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);
884         if (!retval) {
885                 if (alloc_bandwidth) {
886                         allocate_bus_bandwidth(hcd,
887                                                dwc_otg_hcd_get_ep_bandwidth
888                                                (dwc_otg_hcd, ep->hcpriv), urb);
889                 }
890         } else {
891                 if (retval == -DWC_E_NO_DEVICE) {
892                         retval = -ENODEV;
893                 }
894         }
895
896         return retval;
897 }
898
899 /** Aborts/cancels a USB transfer request. Always returns 0 to indicate
900  * success.  */
901 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
902 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
903 #else
904 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
905 #endif
906 {
907         dwc_irqflags_t flags;
908         dwc_otg_hcd_t *dwc_otg_hcd;
909         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
910
911         dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
912
913 #ifdef DEBUG
914         if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
915                 dump_urb_info(urb, "urb_dequeue");
916         }
917 #endif
918
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);
922
923                 DWC_FREE(urb->hcpriv);
924                 urb->hcpriv = NULL;
925         }
926         DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
927
928         /* Higher layer software sets URB status. */
929 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
930         usb_hcd_giveback_urb(hcd, urb);
931 #else
932         usb_hcd_giveback_urb(hcd, urb, status);
933 #endif
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);
937         }
938
939         return 0;
940 }
941
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)
946 {
947         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
948
949         DWC_DEBUGPL(DBG_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);
954         ep->hcpriv = NULL;
955 }
956
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)
961 {
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);
969
970         if (dev)
971                 udev = to_usb_device(dev);
972         else
973                 return;
974
975         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP RESET: Endpoint Num=0x%02d\n", epnum);
976
977         DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
978         usb_settoggle(udev, epnum, is_out, 0);
979         if (is_control)
980                 usb_settoggle(udev, epnum, !is_out, 0);
981
982         if (ep->hcpriv) {
983                 dwc_otg_hcd_endpoint_reset(dwc_otg_hcd, ep->hcpriv);
984         }
985         DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
986 }
987 #endif
988
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
991  * interrupt.
992  *
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)
995 {
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);
998         if (retval != 0) {
999                 S3C2410X_CLEAR_EINTPEND();
1000         }
1001         return IRQ_RETVAL(retval);
1002 }
1003
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)
1009 {
1010         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1011 //dump_stack();
1012         buf[0] = 0;
1013         buf[0] |= (dwc_otg_hcd_is_status_changed(dwc_otg_hcd, 1)) << 1;
1014
1015         return (buf[0] != 0);
1016 }
1017
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)
1021 {
1022         int retval;
1023
1024         retval = dwc_otg_hcd_hub_control(hcd_to_dwc_otg_hcd(hcd),
1025                                          typeReq, wValue, wIndex, buf, wLength);
1026
1027         switch (retval) {
1028         case -DWC_E_INVALID:
1029                 retval = -EINVAL;
1030                 break;
1031         }
1032
1033         return retval;
1034 }
1035
1036 struct device *get_hcd_device()
1037 {
1038 #ifdef CONFIG_ARM64
1039 if(NULL != device_hcd_dwc_otg)
1040         {
1041         return device_hcd_dwc_otg;
1042         }
1043 else
1044         {
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);
1048         }
1049 #else
1050     return NULL;
1051 #endif
1052 }
1053
1054 #endif                          /* DWC_DEVICE_ONLY */