USB: support DWC_OTG Driver Version3.10 and used by default
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / dwc_otg_pcd_linux.c
1  /* ==========================================================================
2   * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_linux.c $
3   * $Revision: #26 $
4   * $Date: 2012/12/13 $
5   * $Change: 2125485 $
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_HOST_ONLY
34
35 /** @file
36  * This file implements the Peripheral Controller Driver.
37  *
38  * The Peripheral Controller Driver (PCD) is responsible for
39  * translating requests from the Function Driver into the appropriate
40  * actions on the DWC_otg controller. It isolates the Function Driver
41  * from the specifics of the controller by providing an API to the
42  * Function Driver.
43  *
44  * The Peripheral Controller Driver for Linux will implement the
45  * Gadget API, so that the existing Gadget drivers can be used.
46  * (Gadget Driver is the Linux terminology for a Function Driver.)
47  *
48  * The Linux Gadget API is defined in the header file
49  * <code><linux/usb_gadget.h></code>.  The USB EP operations API is
50  * defined in the structure <code>usb_ep_ops</code> and the USB
51  * Controller API is defined in the structure
52  * <code>usb_gadget_ops</code>.
53  *
54  */
55
56 #include "dwc_otg_os_dep.h"
57 #include "dwc_otg_pcd_if.h"
58 #include "dwc_otg_pcd.h"
59 #include "dwc_otg_driver.h"
60 #include "dwc_otg_dbg.h"
61 #include "dwc_otg_attr.h"
62
63 #include "usbdev_rk.h"
64
65 static struct gadget_wrapper {
66         dwc_otg_pcd_t *pcd;
67
68         struct usb_gadget gadget;
69         struct usb_gadget_driver *driver;
70
71         struct usb_ep ep0;
72         struct usb_ep in_ep[16];
73         struct usb_ep out_ep[16];
74
75 } *gadget_wrapper;
76
77 /* Display the contents of the buffer */
78 extern void dump_msg(const u8 * buf, unsigned int length);
79
80 /**
81  * Get the dwc_otg_pcd_ep_t* from usb_ep* pointer - NULL in case
82  * if the endpoint is not found
83  */
84 static struct dwc_otg_pcd_ep *ep_from_handle(dwc_otg_pcd_t * pcd, void *handle)
85 {
86         int i;
87         if (pcd->ep0.priv == handle) {
88                 return &pcd->ep0;
89         }
90
91         for (i = 0; i < MAX_EPS_CHANNELS - 1; i++) {
92                 if (pcd->in_ep[i].priv == handle)
93                         return &pcd->in_ep[i];
94                 if (pcd->out_ep[i].priv == handle)
95                         return &pcd->out_ep[i];
96         }
97
98         return NULL;
99 }
100
101 /* USB Endpoint Operations */
102 /*
103  * The following sections briefly describe the behavior of the Gadget
104  * API endpoint operations implemented in the DWC_otg driver
105  * software. Detailed descriptions of the generic behavior of each of
106  * these functions can be found in the Linux header file
107  * include/linux/usb_gadget.h.
108  *
109  * The Gadget API provides wrapper functions for each of the function
110  * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper
111  * function, which then calls the underlying PCD function. The
112  * following sections are named according to the wrapper
113  * functions. Within each section, the corresponding DWC_otg PCD
114  * function name is specified.
115  *
116  */
117
118 /**
119  * This function is called by the Gadget Driver for each EP to be
120  * configured for the current configuration (SET_CONFIGURATION).
121  *
122  * This function initializes the dwc_otg_ep_t data structure, and then
123  * calls dwc_otg_ep_activate.
124  */
125 static int ep_enable(struct usb_ep *usb_ep,
126                      const struct usb_endpoint_descriptor *ep_desc)
127 {
128         int retval;
129
130         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, ep_desc);
131
132         if (!usb_ep || !ep_desc || ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
133                 DWC_WARN("%s, bad ep or descriptor\n", __func__);
134                 return -EINVAL;
135         }
136         if (usb_ep == &gadget_wrapper->ep0) {
137                 DWC_WARN("%s, bad ep(0)\n", __func__);
138                 return -EINVAL;
139         }
140
141         /* Check FIFO size? */
142         if (!ep_desc->wMaxPacketSize) {
143                 DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name);
144                 return -ERANGE;
145         }
146
147         if (!gadget_wrapper->driver ||
148             gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
149                 DWC_WARN("%s, bogus device state\n", __func__);
150                 return -ESHUTDOWN;
151         }
152
153         /* Delete after check - MAS */
154 #if 0
155         nat = (uint32_t) ep_desc->wMaxPacketSize;
156         printk(KERN_ALERT "%s: nat (before) =%d\n", __func__, nat);
157         nat = (nat >> 11) & 0x03;
158         printk(KERN_ALERT "%s: nat (after) =%d\n", __func__, nat);
159 #endif
160         retval = dwc_otg_pcd_ep_enable(gadget_wrapper->pcd,
161                                        (const uint8_t *)ep_desc,
162                                        (void *)usb_ep);
163         if (retval) {
164                 DWC_WARN("dwc_otg_pcd_ep_enable failed\n");
165                 return -EINVAL;
166         }
167
168         usb_ep->maxpacket = le16_to_cpu(ep_desc->wMaxPacketSize);
169
170         return 0;
171 }
172
173 /**
174  * This function is called when an EP is disabled due to disconnect or
175  * change in configuration. Any pending requests will terminate with a
176  * status of -ESHUTDOWN.
177  *
178  * This function modifies the dwc_otg_ep_t data structure for this EP,
179  * and then calls dwc_otg_ep_deactivate.
180  */
181 static int ep_disable(struct usb_ep *usb_ep)
182 {
183         int retval;
184
185         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, usb_ep);
186         if (!usb_ep) {
187                 DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
188                             usb_ep ? usb_ep->name : NULL);
189                 return -EINVAL;
190         }
191
192         retval = dwc_otg_pcd_ep_disable(gadget_wrapper->pcd, usb_ep);
193         if (retval) {
194                 retval = -EINVAL;
195         }
196
197         return retval;
198 }
199
200 /**
201  * This function allocates a request object to use with the specified
202  * endpoint.
203  *
204  * @param ep The endpoint to be used with with the request
205  * @param gfp_flags the GFP_* flags to use.
206  */
207 static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
208                                                      gfp_t gfp_flags)
209 {
210         struct usb_request *usb_req;
211
212         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d)\n", __func__, ep, gfp_flags);
213         if (0 == ep) {
214                 DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
215                 return 0;
216         }
217         usb_req = kmalloc(sizeof(*usb_req), gfp_flags);
218         if (0 == usb_req) {
219                 DWC_WARN("%s() %s\n", __func__, "request allocation failed!\n");
220                 return 0;
221         }
222         memset(usb_req, 0, sizeof(*usb_req));
223         usb_req->dma = DWC_DMA_ADDR_INVALID;
224
225         return usb_req;
226 }
227
228 /**
229  * This function frees a request object.
230  *
231  * @param ep The endpoint associated with the request
232  * @param req The request being freed
233  */
234 static void dwc_otg_pcd_free_request(struct usb_ep *ep, struct usb_request *req)
235 {
236         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, ep, req);
237
238         if (0 == ep || 0 == req) {
239                 DWC_WARN("%s() %s\n", __func__,
240                          "Invalid ep or req argument!\n");
241                 return;
242         }
243
244         kfree(req);
245 }
246
247 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
248 /**
249  * This function allocates an I/O buffer to be used for a transfer
250  * to/from the specified endpoint.
251  *
252  * @param usb_ep The endpoint to be used with with the request
253  * @param bytes The desired number of bytes for the buffer
254  * @param dma Pointer to the buffer's DMA address; must be valid
255  * @param gfp_flags the GFP_* flags to use.
256  * @return address of a new buffer or null is buffer could not be allocated.
257  */
258 static void *dwc_otg_pcd_alloc_buffer(struct usb_ep *usb_ep, unsigned bytes,
259                                       dma_addr_t * dma, gfp_t gfp_flags)
260 {
261         void *buf;
262         dwc_otg_pcd_t *pcd = 0;
263
264         pcd = gadget_wrapper->pcd;
265
266         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d,%p,%0x)\n", __func__, usb_ep, bytes,
267                     dma, gfp_flags);
268
269         /* Check dword alignment */
270         if ((bytes & 0x3UL) != 0) {
271                 DWC_WARN("%s() Buffer size is not a multiple of"
272                          "DWORD size (%d)", __func__, bytes);
273         }
274
275         buf = dma_alloc_coherent(NULL, bytes, dma, gfp_flags);
276
277         /* Check dword alignment */
278         if (((int)buf & 0x3UL) != 0) {
279                 DWC_WARN("%s() Buffer is not DWORD aligned (%p)",
280                          __func__, buf);
281         }
282
283         return buf;
284 }
285
286 /**
287  * This function frees an I/O buffer that was allocated by alloc_buffer.
288  *
289  * @param usb_ep the endpoint associated with the buffer
290  * @param buf address of the buffer
291  * @param dma The buffer's DMA address
292  * @param bytes The number of bytes of the buffer
293  */
294 static void dwc_otg_pcd_free_buffer(struct usb_ep *usb_ep, void *buf,
295                                     dma_addr_t dma, unsigned bytes)
296 {
297         dwc_otg_pcd_t *pcd = 0;
298
299         pcd = gadget_wrapper->pcd;
300
301         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%0x,%d)\n", __func__, buf, dma, bytes);
302
303         dma_free_coherent(NULL, bytes, buf, dma);
304 }
305 #endif
306
307 /**
308  * This function is used to submit an I/O Request to an EP.
309  *
310  *      - When the request completes the request's completion callback
311  *        is called to return the request to the driver.
312  *      - An EP, except control EPs, may have multiple requests
313  *        pending.
314  *      - Once submitted the request cannot be examined or modified.
315  *      - Each request is turned into one or more packets.
316  *      - A BULK EP can queue any amount of data; the transfer is
317  *        packetized.
318  *      - Zero length Packets are specified with the request 'zero'
319  *        flag.
320  */
321 static int ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req,
322                     gfp_t gfp_flags)
323 {
324         dwc_otg_pcd_t *pcd;
325         struct dwc_otg_pcd_ep *ep = NULL;
326         int retval = 0, is_isoc_ep = 0;
327         dma_addr_t dma_addr = DWC_DMA_ADDR_INVALID;
328
329         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p,%d)\n",
330                     __func__, usb_ep, usb_req, gfp_flags);
331
332         if (!usb_req || !usb_req->complete || !usb_req->buf) {
333                 DWC_WARN("bad params\n");
334                 return -EINVAL;
335         }
336
337         if (!usb_ep) {
338                 DWC_WARN("bad ep\n");
339                 return -EINVAL;
340         }
341
342         pcd = gadget_wrapper->pcd;
343         if (!gadget_wrapper->driver ||
344             gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
345                 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
346                             gadget_wrapper->gadget.speed);
347                 DWC_WARN("bogus device state\n");
348                 return -ESHUTDOWN;
349         }
350
351         DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
352                     usb_ep->name, usb_req, usb_req->length, usb_req->buf);
353
354         usb_req->status = -EINPROGRESS;
355         usb_req->actual = 0;
356
357         ep = ep_from_handle(pcd, usb_ep);
358         if (ep == NULL)
359                 is_isoc_ep = 0;
360         else
361                 is_isoc_ep = (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) ? 1 : 0;
362 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
363         dma_addr = usb_req->dma;
364 #else
365         if (GET_CORE_IF(pcd)->dma_enable) {
366 //              if (usb_req->length != 0/* && usb_req->dma == DWC_DMA_ADDR_INVALID*/) {
367                 if(usb_req->dma == DWC_DMA_ADDR_INVALID){
368                         dma_addr = dma_map_single(gadget_wrapper->gadget.dev.parent,
369                                                   usb_req->buf, usb_req->length,
370                                                   ep->dwc_ep.is_in 
371                                                   ? DMA_TO_DEVICE 
372                                                   : DMA_FROM_DEVICE);
373                         usb_req->dma = dma_addr;
374                 }
375
376         }
377 #endif
378
379 #ifdef DWC_UTE_PER_IO
380         if (is_isoc_ep == 1) {
381                 retval =
382                     dwc_otg_pcd_xiso_ep_queue(pcd, usb_ep, usb_req->buf,
383                                               dma_addr, usb_req->length,
384                                               usb_req->zero, usb_req,
385                                               gfp_flags == GFP_ATOMIC ? 1 : 0,
386                                               &usb_req->ext_req);
387                 if (retval)
388                         return -EINVAL;
389
390                 return 0;
391         }
392 #endif
393         retval = dwc_otg_pcd_ep_queue(pcd, usb_ep, usb_req->buf, dma_addr,
394                                       usb_req->length, usb_req->zero, usb_req,
395                                       gfp_flags == GFP_ATOMIC ? 1 : 0);
396         if (retval) {
397                 return -EINVAL;
398         }
399
400         return 0;
401 }
402
403 /**
404  * This function cancels an I/O request from an EP.
405  */
406 static int ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req)
407 {
408         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, usb_req);
409
410         if (!usb_ep || !usb_req) {
411                 DWC_WARN("bad argument\n");
412                 return -EINVAL;
413         }
414         if (!gadget_wrapper->driver ||
415             gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
416                 DWC_WARN("bogus device state\n");
417                 return -ESHUTDOWN;
418         }
419         if (dwc_otg_pcd_ep_dequeue(gadget_wrapper->pcd, usb_ep, usb_req)) {
420                 return -EINVAL;
421         }
422
423         return 0;
424 }
425
426 /**
427  * usb_ep_set_halt stalls an endpoint.
428  *
429  * usb_ep_clear_halt clears an endpoint halt and resets its data
430  * toggle.
431  *
432  * Both of these functions are implemented with the same underlying
433  * function. The behavior depends on the value argument.
434  *
435  * @param[in] usb_ep the Endpoint to halt or clear halt.
436  * @param[in] value
437  *      - 0 means clear_halt.
438  *      - 1 means set_halt,
439  *      - 2 means clear stall lock flag.
440  *      - 3 means set  stall lock flag.
441  */
442 static int ep_halt(struct usb_ep *usb_ep, int value)
443 {
444         int retval = 0;
445
446         DWC_DEBUGPL(DBG_PCD, "HALT %s %d\n", usb_ep->name, value);
447
448         if (!usb_ep) {
449                 DWC_WARN("bad ep\n");
450                 return -EINVAL;
451         }
452
453         retval = dwc_otg_pcd_ep_halt(gadget_wrapper->pcd, usb_ep, value);
454         if (retval == -DWC_E_AGAIN) {
455                 return -EAGAIN;
456         } else if (retval) {
457                 retval = -EINVAL;
458         }
459
460         return retval;
461 }
462
463 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
464 static int ep_wedge(struct usb_ep *usb_ep)
465 {
466         DWC_DEBUGPL(DBG_PCD, "WEDGE %s\n", usb_ep->name);
467
468         return ep_halt(usb_ep, 3);
469 }
470 #endif
471
472 #ifdef DWC_EN_ISOC
473 /**
474  * This function is used to submit an ISOC Transfer Request to an EP.
475  *
476  *      - Every time a sync period completes the request's completion callback
477  *        is called to provide data to the gadget driver.
478  *      - Once submitted the request cannot be modified.
479  *      - Each request is turned into periodic data packets untill ISO
480  *        Transfer is stopped..
481  */
482 static int iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
483                         gfp_t gfp_flags)
484 {
485         int retval = 0;
486
487         if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
488                 DWC_WARN("bad params\n");
489                 return -EINVAL;
490         }
491
492         if (!usb_ep) {
493                 DWC_PRINTF("bad params\n");
494                 return -EINVAL;
495         }
496
497         req->status = -EINPROGRESS;
498
499         retval =
500             dwc_otg_pcd_iso_ep_start(gadget_wrapper->pcd, usb_ep, req->buf0,
501                                      req->buf1, req->dma0, req->dma1,
502                                      req->sync_frame, req->data_pattern_frame,
503                                      req->data_per_frame,
504                                      req->
505                                      flags & USB_REQ_ISO_ASAP ? -1 :
506                                      req->start_frame, req->buf_proc_intrvl,
507                                      req, gfp_flags == GFP_ATOMIC ? 1 : 0);
508
509         if (retval) {
510                 return -EINVAL;
511         }
512
513         return retval;
514 }
515
516 /**
517  * This function stops ISO EP Periodic Data Transfer.
518  */
519 static int iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
520 {
521         int retval = 0;
522         if (!usb_ep) {
523                 DWC_WARN("bad ep\n");
524         }
525
526         if (!gadget_wrapper->driver ||
527             gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
528                 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
529                             gadget_wrapper->gadget.speed);
530                 DWC_WARN("bogus device state\n");
531         }
532
533         dwc_otg_pcd_iso_ep_stop(gadget_wrapper->pcd, usb_ep, req);
534         if (retval) {
535                 retval = -EINVAL;
536         }
537
538         return retval;
539 }
540
541 static struct usb_iso_request *alloc_iso_request(struct usb_ep *ep,
542                                                  int packets, gfp_t gfp_flags)
543 {
544         struct usb_iso_request *pReq = NULL;
545         uint32_t req_size;
546
547         req_size = sizeof(struct usb_iso_request);
548         req_size +=
549             (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
550
551         pReq = kmalloc(req_size, gfp_flags);
552         if (!pReq) {
553                 DWC_WARN("Can't allocate Iso Request\n");
554                 return 0;
555         }
556         pReq->iso_packet_desc0 = (void *)(pReq + 1);
557
558         pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
559
560         return pReq;
561 }
562
563 static void free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
564 {
565         kfree(req);
566 }
567
568 static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops = {
569         .ep_ops = {
570                 .enable = ep_enable,
571                 .disable = ep_disable,
572
573                 .alloc_request = dwc_otg_pcd_alloc_request,
574                 .free_request = dwc_otg_pcd_free_request,
575
576 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
577                 .alloc_buffer = dwc_otg_pcd_alloc_buffer,
578                 .free_buffer = dwc_otg_pcd_free_buffer,
579 #endif
580
581                 .queue = ep_queue,
582                 .dequeue = ep_dequeue,
583
584                 .set_halt = ep_halt,
585                  
586 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
587                 .set_wedge = ep_wedge,
588 #endif
589                 .fifo_status = 0,
590                 .fifo_flush = 0,
591         },
592
593         .iso_ep_start = iso_ep_start,
594         .iso_ep_stop = iso_ep_stop,
595         .alloc_iso_request = alloc_iso_request,
596         .free_iso_request = free_iso_request,
597 };
598
599 #else
600
601 static struct usb_ep_ops dwc_otg_pcd_ep_ops = {
602         .enable = ep_enable,
603         .disable = ep_disable,
604
605         .alloc_request = dwc_otg_pcd_alloc_request,
606         .free_request = dwc_otg_pcd_free_request,
607
608 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
609         .alloc_buffer = dwc_otg_pcd_alloc_buffer,
610         .free_buffer = dwc_otg_pcd_free_buffer,
611 #endif
612
613         .queue = ep_queue,
614         .dequeue = ep_dequeue,
615
616         .set_halt = ep_halt,
617         
618         #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
619                 .set_wedge = ep_wedge,
620     #endif
621
622         .fifo_status = 0,
623         .fifo_flush = 0,
624
625 };
626
627 #endif /* _EN_ISOC_ */
628 /*      Gadget Operations */
629 /**
630  * The following gadget operations will be implemented in the DWC_otg
631  * PCD. Functions in the API that are not described below are not
632  * implemented.
633  *
634  * The Gadget API provides wrapper functions for each of the function
635  * pointers defined in usb_gadget_ops. The Gadget Driver calls the
636  * wrapper function, which then calls the underlying PCD function. The
637  * following sections are named according to the wrapper functions
638  * (except for ioctl, which doesn't have a wrapper function). Within
639  * each section, the corresponding DWC_otg PCD function name is
640  * specified.
641  *
642  */
643
644 /**
645  *Gets the USB Frame number of the last SOF.
646  */
647 static int get_frame_number(struct usb_gadget *gadget)
648 {
649         struct gadget_wrapper *d;
650
651         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
652
653         if (gadget == 0) {
654                 return -ENODEV;
655         }
656
657         d = container_of(gadget, struct gadget_wrapper, gadget);
658         return dwc_otg_pcd_get_frame_number(d->pcd);
659 }
660
661 #ifdef CONFIG_USB_DWC_OTG_LPM
662 static int test_lpm_enabled(struct usb_gadget *gadget)
663 {
664         struct gadget_wrapper *d;
665
666         d = container_of(gadget, struct gadget_wrapper, gadget);
667
668         return dwc_otg_pcd_is_lpm_enabled(d->pcd);
669 }
670 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
671 static int test_besl_enabled(struct usb_gadget *gadget)
672 {
673         struct gadget_wrapper *d;
674
675         d = container_of(gadget, struct gadget_wrapper, gadget);
676
677         return dwc_otg_pcd_is_besl_enabled(d->pcd);
678 }
679 static int get_param_baseline_besl(struct usb_gadget *gadget)
680 {
681         struct gadget_wrapper *d;
682
683         d = container_of(gadget, struct gadget_wrapper, gadget);
684
685         return dwc_otg_pcd_get_param_baseline_besl(d->pcd);
686 }
687 static int get_param_deep_besl(struct usb_gadget *gadget)
688 {
689         struct gadget_wrapper *d;
690
691         d = container_of(gadget, struct gadget_wrapper, gadget);
692
693         return dwc_otg_pcd_get_param_deep_besl(d->pcd);
694 }
695 #endif
696 #endif
697
698 /**
699  * Initiates Session Request Protocol (SRP) to wakeup the host if no
700  * session is in progress. If a session is already in progress, but
701  * the device is suspended, remote wakeup signaling is started.
702  *
703  */
704 static int wakeup(struct usb_gadget *gadget)
705 {
706         struct gadget_wrapper *d;
707
708         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
709
710         if (gadget == 0) {
711                 return -ENODEV;
712         } else {
713                 d = container_of(gadget, struct gadget_wrapper, gadget);
714         }
715         dwc_otg_pcd_wakeup(d->pcd);
716         return 0;
717 }
718 static int dwc_otg_pcd_pullup(struct usb_gadget *_gadget, int is_on)
719 {
720         struct gadget_wrapper *d;
721         dwc_otg_pcd_t *pcd;
722         dwc_otg_core_if_t *core_if;
723         
724         printk( "pcd_pullup, is_on %d\n",is_on);
725         if (_gadget == NULL)
726                 return -ENODEV;
727         else{
728                 d = container_of(_gadget, struct gadget_wrapper, gadget);
729                 pcd = d->pcd;
730                 core_if = GET_CORE_IF(d->pcd);
731         }
732
733         if(is_on){
734                 //dwc_otg_pcd_pullup_enable(pcd);
735                 pcd->conn_en = 1;
736                 pcd->conn_status = 0;
737         }else{
738                 dwc_otg_pcd_pullup_disable(pcd);
739                 pcd->conn_status = 2;
740         }
741
742         return 0;
743
744 }
745
746 static int dwc_otg_gadget_start(struct usb_gadget *g,
747                                 struct usb_gadget_driver *driver)
748 {
749         DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", driver->driver.name);
750         if (gadget_wrapper == 0){
751                 DWC_ERROR("ENODEV\n");
752                 return -ENODEV;
753         }
754         if (gadget_wrapper->driver != 0){
755                 DWC_ERROR("EBUSY (%p)\n", gadget_wrapper->driver);
756                 return -EBUSY;
757         }
758         /* hook up the driver */
759         gadget_wrapper->driver = driver;
760         gadget_wrapper->gadget.dev.driver = &driver->driver;
761
762         DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
763
764         return 0;
765 }
766
767 static int dwc_otg_gadget_stop(struct usb_gadget *g,
768                                struct usb_gadget_driver *driver)
769 {
770         return 0;
771 }
772
773 static const struct usb_gadget_ops dwc_otg_pcd_ops = {
774         .get_frame = get_frame_number,
775         .wakeup = wakeup,
776         .pullup = dwc_otg_pcd_pullup,
777 #ifdef CONFIG_USB_DWC_OTG_LPM
778         .lpm_support = test_lpm_enabled,
779 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) 
780         .besl_support = test_besl_enabled,
781         .get_baseline_besl = get_param_baseline_besl,
782         .get_deep_besl = get_param_deep_besl,
783 #endif  
784 #endif
785         .udc_start = dwc_otg_gadget_start,
786         .udc_stop = dwc_otg_gadget_stop,
787
788         // current versions must always be self-powered
789 };
790
791
792
793 static int _setup(dwc_otg_pcd_t * pcd, uint8_t * bytes)
794 {
795         int retval = -DWC_E_NOT_SUPPORTED;
796         if (gadget_wrapper->driver && gadget_wrapper->driver->setup) {
797                 retval = gadget_wrapper->driver->setup(&gadget_wrapper->gadget,
798                                                        (struct usb_ctrlrequest
799                                                         *)bytes);
800         }
801
802         if (retval == -ENOTSUPP) {
803                 retval = -DWC_E_NOT_SUPPORTED;
804         } else if (retval < 0) {
805                 retval = -DWC_E_INVALID;
806         }
807
808         return retval;
809 }
810
811 #ifdef DWC_EN_ISOC
812 static int _isoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle,
813                           void *req_handle, int proc_buf_num)
814 {
815         int i, packet_count;
816         struct usb_gadget_iso_packet_descriptor *iso_packet = 0;
817         struct usb_iso_request *iso_req = req_handle;
818
819         if (proc_buf_num) {
820                 iso_packet = iso_req->iso_packet_desc1;
821         } else {
822                 iso_packet = iso_req->iso_packet_desc0;
823         }
824         packet_count =
825             dwc_otg_pcd_get_iso_packet_count(pcd, ep_handle, req_handle);
826         for (i = 0; i < packet_count; ++i) {
827                 int status;
828                 int actual;
829                 int offset;
830                 dwc_otg_pcd_get_iso_packet_params(pcd, ep_handle, req_handle,
831                                                   i, &status, &actual, &offset);
832                 switch (status) {
833                 case -DWC_E_NO_DATA:
834                         status = -ENODATA;
835                         break;
836                 default:
837                         if (status) {
838                                 DWC_PRINTF("unknown status in isoc packet\n");
839                         }
840
841                 }
842                 iso_packet[i].status = status;
843                 iso_packet[i].offset = offset;
844                 iso_packet[i].actual_length = actual;
845         }
846
847         iso_req->status = 0;
848         iso_req->process_buffer(ep_handle, iso_req);
849
850         return 0;
851 }
852 #endif /* DWC_EN_ISOC */
853
854 #ifdef DWC_UTE_PER_IO
855 /**
856  * Copy the contents of the extended request to the Linux usb_request's
857  * extended part and call the gadget's completion.
858  *
859  * @param pcd                   Pointer to the pcd structure
860  * @param ep_handle             Void pointer to the usb_ep structure
861  * @param req_handle    Void pointer to the usb_request structure
862  * @param status                Request status returned from the portable logic
863  * @param ereq_port             Void pointer to the extended request structure
864  *                                              created in the the portable part that contains the
865  *                                              results of the processed iso packets.
866  */
867 static int _xisoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle,
868                            void *req_handle, int32_t status, void *ereq_port)
869 {
870         struct dwc_ute_iso_req_ext *ereqorg = NULL;
871         struct dwc_iso_xreq_port *ereqport = NULL;
872         struct dwc_ute_iso_packet_descriptor *desc_org = NULL;
873         int i;
874         struct usb_request *req;
875         //struct dwc_ute_iso_packet_descriptor *
876         //int status = 0;
877
878         req = (struct usb_request *)req_handle;
879         ereqorg = &req->ext_req;
880         ereqport = (struct dwc_iso_xreq_port *)ereq_port;
881         desc_org = ereqorg->per_io_frame_descs;
882
883         if (req && req->complete) {
884                 /* Copy the request data from the portable logic to our request */
885                 for (i = 0; i < ereqport->pio_pkt_count; i++) {
886                         desc_org[i].actual_length =
887                             ereqport->per_io_frame_descs[i].actual_length;
888                         desc_org[i].status =
889                             ereqport->per_io_frame_descs[i].status;
890                 }
891
892                 switch (status) {
893                 case -DWC_E_SHUTDOWN:
894                         req->status = -ESHUTDOWN;
895                         break;
896                 case -DWC_E_RESTART:
897                         req->status = -ECONNRESET;
898                         break;
899                 case -DWC_E_INVALID:
900                         req->status = -EINVAL;
901                         break;
902                 case -DWC_E_TIMEOUT:
903                         req->status = -ETIMEDOUT;
904                         break;
905                 default:
906                         req->status = status;
907                 }
908
909                 /* And call the gadget's completion */
910                 req->complete(ep_handle, req);
911         }
912
913         return 0;
914 }
915 #endif /* DWC_UTE_PER_IO */
916
917 static int _complete(dwc_otg_pcd_t * pcd, void *ep_handle,
918                      void *req_handle, int32_t status, uint32_t actual)
919 {
920         struct usb_request *req = (struct usb_request *)req_handle;
921         struct device * dev = NULL;
922 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27)
923         struct dwc_otg_pcd_ep *ep = NULL;
924 #endif
925
926         if (req && req->complete) {
927                 switch (status) {
928                 case -DWC_E_SHUTDOWN:
929                         req->status = -ESHUTDOWN;
930                         break;
931                 case -DWC_E_RESTART:
932                         req->status = -ECONNRESET;
933                         break;
934                 case -DWC_E_INVALID:
935                         req->status = -EINVAL;
936                         break;
937                 case -DWC_E_TIMEOUT:
938                         req->status = -ETIMEDOUT;
939                         break;
940                 default:
941                         req->status = status;
942
943                 }
944
945                 req->actual = actual;
946                 DWC_SPINUNLOCK(pcd->lock);
947                 req->complete(ep_handle, req);
948                 DWC_SPINLOCK(pcd->lock);
949         }
950         
951         dev = &gadget_wrapper->pcd->otg_dev->os_dep.pdev->dev;
952         ep = ep_from_handle(pcd, ep_handle);
953
954         if (GET_CORE_IF(pcd)->dma_enable) {
955 //              if (req->length != 0)
956                 if(req->dma != DWC_DMA_ADDR_INVALID){
957                         dma_unmap_single(gadget_wrapper->gadget.dev.parent,
958                                          req->dma, req->length,
959                                          ep->dwc_ep.is_in
960                                          ? DMA_TO_DEVICE
961                                          : DMA_FROM_DEVICE);
962                         req->dma = DWC_DMA_ADDR_INVALID;
963                 }
964         }
965         return 0;
966 }
967
968 static int _connect(dwc_otg_pcd_t * pcd, int speed)
969 {
970         gadget_wrapper->gadget.speed = speed;
971         return 0;
972 }
973
974 static int _disconnect(dwc_otg_pcd_t * pcd)
975 {
976         if (gadget_wrapper->driver && gadget_wrapper->driver->disconnect) {
977                 gadget_wrapper->driver->disconnect(&gadget_wrapper->gadget);
978         }
979         return 0;
980 }
981
982 static int _resume(dwc_otg_pcd_t * pcd)
983 {
984         if (gadget_wrapper->driver && gadget_wrapper->driver->resume) {
985                 gadget_wrapper->driver->resume(&gadget_wrapper->gadget);
986         }
987
988         return 0;
989 }
990
991 static int _suspend(dwc_otg_pcd_t * pcd)
992 {
993         if (gadget_wrapper->driver && gadget_wrapper->driver->suspend) {
994                 gadget_wrapper->driver->suspend(&gadget_wrapper->gadget);
995         }
996         return 0;
997 }
998
999 /**
1000  * This function updates the otg values in the gadget structure.
1001  */
1002 static int _hnp_changed(dwc_otg_pcd_t * pcd)
1003 {
1004
1005         if (!gadget_wrapper->gadget.is_otg)
1006                 return 0;
1007
1008         gadget_wrapper->gadget.b_hnp_enable = get_b_hnp_enable(pcd);
1009         gadget_wrapper->gadget.a_hnp_support = get_a_hnp_support(pcd);
1010         gadget_wrapper->gadget.a_alt_hnp_support = get_a_alt_hnp_support(pcd);
1011         return 0;
1012 }
1013
1014 static int _reset(dwc_otg_pcd_t * pcd)
1015 {
1016         return 0;
1017 }
1018
1019 #ifdef DWC_UTE_CFI
1020 static int _cfi_setup(dwc_otg_pcd_t * pcd, void *cfi_req)
1021 {
1022         int retval = -DWC_E_INVALID;
1023         if (gadget_wrapper->driver->cfi_feature_setup) {
1024                 retval =
1025                     gadget_wrapper->driver->
1026                     cfi_feature_setup(&gadget_wrapper->gadget,
1027                                       (struct cfi_usb_ctrlrequest *)cfi_req);
1028         }
1029
1030         return retval;
1031 }
1032 #endif
1033
1034 static const struct dwc_otg_pcd_function_ops fops = {
1035         .complete = _complete,
1036 #ifdef DWC_EN_ISOC
1037         .isoc_complete = _isoc_complete,
1038 #endif
1039         .setup = _setup,
1040         .disconnect = _disconnect,
1041         .connect = _connect,
1042         .resume = _resume,
1043         .suspend = _suspend,
1044         .hnp_changed = _hnp_changed,
1045         .reset = _reset,
1046 #ifdef DWC_UTE_CFI
1047         .cfi_setup = _cfi_setup,
1048 #endif
1049 #ifdef DWC_UTE_PER_IO
1050         .xisoc_complete = _xisoc_complete,
1051 #endif
1052 };
1053
1054 /**
1055  * This function is the top level PCD interrupt handler.
1056  */
1057 static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev)
1058 {
1059         dwc_otg_pcd_t *pcd = dev;
1060         int32_t retval = IRQ_NONE;
1061
1062         retval = dwc_otg_pcd_handle_intr(pcd);
1063         if (retval != 0) {
1064                 //S3C2410X_CLEAR_EINTPEND();
1065         }
1066         return IRQ_RETVAL(retval);
1067 }
1068
1069 /**
1070  * This function initialized the usb_ep structures to there default
1071  * state.
1072  *
1073  * @param d Pointer on gadget_wrapper.
1074  */
1075 void gadget_add_eps(struct gadget_wrapper *d)
1076 {
1077         static const char *names[] = {
1078
1079                 "ep0",
1080                 "ep1in",
1081                 "ep2in",
1082                 "ep3in",
1083                 "ep4in",
1084                 "ep5in",
1085                 "ep6in",
1086                 "ep7in",
1087                 "ep8in",
1088                 "ep9in",
1089                 "ep10in",
1090                 "ep11in",
1091                 "ep12in",
1092                 "ep13in",
1093                 "ep14in",
1094                 "ep15in",
1095                 "ep1out",
1096                 "ep2out",
1097                 "ep3out",
1098                 "ep4out",
1099                 "ep5out",
1100                 "ep6out",
1101                 "ep7out",
1102                 "ep8out",
1103                 "ep9out",
1104                 "ep10out",
1105                 "ep11out",
1106                 "ep12out",
1107                 "ep13out",
1108                 "ep14out",
1109                 "ep15out"
1110         };
1111
1112         int i;
1113         struct usb_ep *ep;
1114         int8_t dev_endpoints;
1115
1116         DWC_DEBUGPL(DBG_PCDV, "%s\n", __func__);
1117
1118         INIT_LIST_HEAD(&d->gadget.ep_list);
1119         d->gadget.ep0 = &d->ep0;
1120         d->gadget.speed = USB_SPEED_UNKNOWN;
1121 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
1122         d->gadget.max_speed = USB_SPEED_HIGH;
1123 #endif
1124
1125         INIT_LIST_HEAD(&d->gadget.ep0->ep_list);
1126
1127         /**
1128          * Initialize the EP0 structure.
1129          */
1130         ep = &d->ep0;
1131
1132         /* Init the usb_ep structure. */
1133         ep->name = names[0];
1134         ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1135
1136         /**
1137          * @todo NGS: What should the max packet size be set to
1138          * here?  Before EP type is set?
1139          */
1140         ep->maxpacket = MAX_PACKET_SIZE;
1141         dwc_otg_pcd_ep_enable(d->pcd, NULL, ep);
1142
1143         list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1144
1145         /**
1146          * Initialize the EP structures.
1147          */
1148         dev_endpoints = d->pcd->core_if->dev_if->num_in_eps;
1149
1150         for (i = 0; i < dev_endpoints; i++) {
1151                 ep = &d->in_ep[i];
1152
1153                 /* Init the usb_ep structure. */
1154                 ep->name = names[d->pcd->in_ep[i].dwc_ep.num];
1155                 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1156
1157                 /**
1158                  * @todo NGS: What should the max packet size be set to
1159                  * here?  Before EP type is set?
1160                  */
1161                 ep->maxpacket = MAX_PACKET_SIZE;
1162                 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1163         }
1164
1165         dev_endpoints = d->pcd->core_if->dev_if->num_out_eps;
1166
1167         for (i = 0; i < dev_endpoints; i++) {
1168                 ep = &d->out_ep[i];
1169
1170                 /* Init the usb_ep structure. */
1171                 ep->name = names[15 + d->pcd->out_ep[i].dwc_ep.num];
1172                 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1173
1174                 /**
1175                  * @todo NGS: What should the max packet size be set to
1176                  * here?  Before EP type is set?
1177                  */
1178                 ep->maxpacket = MAX_PACKET_SIZE;
1179
1180                 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1181         }
1182
1183         /* remove ep0 from the list.  There is a ep0 pointer. */
1184         list_del_init(&d->ep0.ep_list);
1185
1186         d->ep0.maxpacket = MAX_EP0_SIZE;
1187 }
1188
1189 /**
1190  * This function releases the Gadget device.
1191  * required by device_unregister().
1192  *
1193  * @todo Should this do something?      Should it free the PCD?
1194  */
1195 static void dwc_otg_pcd_gadget_release(struct device *dev)
1196 {
1197         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
1198 }
1199
1200 static struct gadget_wrapper *alloc_wrapper(
1201
1202         struct platform_device *_dev
1203     )
1204 {
1205         static char pcd_name[] = "dwc_otg_pcd";
1206
1207         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1208         struct gadget_wrapper *d;
1209         int retval;
1210
1211         d = DWC_ALLOC(sizeof(*d));
1212         if (d == NULL) {
1213                 return NULL;
1214         }
1215
1216         memset(d, 0, sizeof(*d));
1217
1218         d->gadget.name = pcd_name;
1219         d->pcd = otg_dev->pcd;
1220
1221 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
1222         strcpy(d->gadget.dev.bus_id, "gadget");
1223 #else
1224         dev_set_name(&d->gadget.dev, "%s", "gadget");
1225 #endif
1226
1227         d->gadget.dev.parent = &_dev->dev;
1228         d->gadget.dev.release = dwc_otg_pcd_gadget_release;
1229         d->gadget.ops = &dwc_otg_pcd_ops;
1230 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
1231         d->gadget.is_dualspeed = dwc_otg_pcd_is_dualspeed(otg_dev->pcd);
1232 #endif
1233         d->gadget.is_otg = dwc_otg_pcd_is_otg(otg_dev->pcd);
1234
1235         d->gadget.max_speed = USB_SPEED_HIGH;
1236         d->driver = 0;
1237         d->pcd->conn_en = 0;
1238         /* Register the gadget device */
1239         retval = usb_add_gadget_udc(&_dev->dev, &d->gadget);
1240         if (retval != 0) {
1241                 DWC_ERROR("device_register failed\n");
1242                 DWC_FREE(d);
1243                 return NULL;
1244         }
1245
1246         return d;
1247 }
1248
1249 static void free_wrapper(struct gadget_wrapper *d)
1250 {
1251         if (d->driver) {
1252                 /* should have been done already by driver model core */
1253                 DWC_WARN("driver '%s' is still registered\n",
1254                          d->driver->driver.name);
1255                 usb_gadget_unregister_driver(d->driver);
1256         }
1257
1258         usb_del_gadget_udc(&d->gadget);
1259         DWC_FREE(d);
1260 }
1261
1262 static void dwc_otg_pcd_work_init(dwc_otg_pcd_t *pcd, struct platform_device *dev);
1263
1264 /**
1265  * This function initialized the PCD portion of the driver.
1266  *
1267  */
1268 int pcd_init(struct platform_device *_dev)
1269 {
1270
1271         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1272
1273         int retval = 0;
1274         int irq;
1275         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1276
1277         otg_dev->pcd = dwc_otg_pcd_init(otg_dev->core_if);
1278         printk("pcd_init otg_dev = %p\n",otg_dev);
1279
1280         if (!otg_dev->pcd) {
1281                 DWC_ERROR("dwc_otg_pcd_init failed\n");
1282                 return -ENOMEM;
1283         }
1284
1285         otg_dev->pcd->otg_dev = otg_dev;
1286         gadget_wrapper = alloc_wrapper(_dev);
1287
1288         /*
1289          * Initialize EP structures
1290          */
1291         gadget_add_eps(gadget_wrapper);
1292         /*
1293          * Setup interupt handler
1294          */
1295         irq = platform_get_irq(_dev,0);
1296         DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", irq);
1297         retval = request_irq(irq, dwc_otg_pcd_irq,
1298                              IRQF_SHARED ,
1299                              gadget_wrapper->gadget.name, otg_dev->pcd);
1300         if (retval != 0) {
1301                 DWC_ERROR("request of irq%d failed\n", irq);
1302                 free_wrapper(gadget_wrapper);
1303                 return -EBUSY;
1304         }
1305
1306         dwc_otg_pcd_start(gadget_wrapper->pcd, &fops);
1307
1308         dwc_otg_pcd_work_init(otg_dev->pcd, _dev);
1309
1310         return retval;
1311 }
1312
1313 /**
1314  * Cleanup the PCD.
1315  */
1316 void pcd_remove(
1317
1318         struct platform_device *_dev
1319     )
1320 {
1321
1322         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1323         dwc_otg_pcd_t *pcd = otg_dev->pcd;
1324         int irq;
1325
1326         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1327
1328         /*
1329          * Free the IRQ
1330          */
1331         irq = platform_get_irq(_dev,0);
1332         free_irq(irq, pcd);
1333         free_wrapper(gadget_wrapper);
1334         dwc_otg_pcd_remove(otg_dev->pcd);       
1335         otg_dev->pcd = 0;
1336 }
1337
1338 /**
1339  * This function registers a gadget driver with the PCD.
1340  *
1341  * When a driver is successfully registered, it will receive control
1342  * requests including set_configuration(), which enables non-control
1343  * requests.  then usb traffic follows until a disconnect is reported.
1344  * then a host may connect again, or the driver might get unbound.
1345  *
1346  * @param driver The driver being registered
1347  * @param bind The bind function of gadget driver
1348  */
1349 #if 0
1350 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
1351 int usb_gadget_register_driver(struct usb_gadget_driver *driver)
1352 #else
1353 int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
1354                 int (*bind)(struct usb_gadget *))
1355 #endif
1356 {
1357         int retval;
1358
1359         DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n",
1360                     driver->driver.name);
1361
1362         if (!driver || 
1363 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
1364                 driver->speed == USB_SPEED_UNKNOWN ||
1365 #else
1366                 driver->max_speed == USB_SPEED_UNKNOWN ||
1367 #endif
1368 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
1369             !driver->bind ||
1370 #else
1371                 !bind ||
1372 #endif
1373             !driver->unbind || !driver->disconnect || !driver->setup) {
1374                 DWC_DEBUGPL(DBG_PCDV, "EINVAL\n");
1375                 return -EINVAL;
1376         }
1377         if (gadget_wrapper == 0) {
1378                 DWC_DEBUGPL(DBG_PCDV, "ENODEV\n");
1379                 return -ENODEV;
1380         }
1381         if (gadget_wrapper->driver != 0) {
1382                 DWC_DEBUGPL(DBG_PCDV, "EBUSY (%p)\n", gadget_wrapper->driver);
1383                 return -EBUSY;
1384         }
1385
1386         /* hook up the driver */
1387         gadget_wrapper->driver = driver;
1388         gadget_wrapper->gadget.dev.driver = &driver->driver;
1389
1390         DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
1391 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
1392         retval = driver->bind(&gadget_wrapper->gadget);
1393 #else
1394         retval = bind(&gadget_wrapper->gadget);
1395 #endif
1396         if (retval) {
1397                 DWC_ERROR("bind to driver %s --> error %d\n",
1398                           driver->driver.name, retval);
1399                 gadget_wrapper->driver = 0;
1400                 gadget_wrapper->gadget.dev.driver = 0;
1401                 return retval;
1402         }
1403         DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
1404                     driver->driver.name);
1405         return 0;
1406 }
1407 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
1408 EXPORT_SYMBOL(usb_gadget_register_driver);
1409 #else
1410 EXPORT_SYMBOL(usb_gadget_probe_driver);
1411 #endif
1412
1413 /**
1414  * This function unregisters a gadget driver
1415  *
1416  * @param driver The driver being unregistered
1417  */
1418 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1419 {
1420         //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver);
1421
1422         if (gadget_wrapper == 0) {
1423                 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
1424                             -ENODEV);
1425                 return -ENODEV;
1426         }
1427         if (driver == 0 || driver != gadget_wrapper->driver) {
1428                 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
1429                             -EINVAL);
1430                 return -EINVAL;
1431         }
1432
1433         driver->unbind(&gadget_wrapper->gadget);
1434         gadget_wrapper->driver = 0;
1435
1436         DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n", driver->driver.name);
1437         return 0;
1438 }
1439
1440 EXPORT_SYMBOL(usb_gadget_unregister_driver);
1441
1442 #endif
1443
1444 /************************ for RK platform ************************/
1445
1446 void dwc_otg_msc_lock(dwc_otg_pcd_t *pcd)
1447 {
1448         unsigned long flags;
1449         local_irq_save(flags);
1450         wake_lock(&pcd->wake_lock);
1451         local_irq_restore(flags);
1452 }
1453
1454 void dwc_otg_msc_unlock(dwc_otg_pcd_t *pcd)
1455 {
1456         unsigned long flags;
1457         local_irq_save(flags);
1458         wake_unlock(&pcd->wake_lock);
1459         local_irq_restore(flags);
1460 }
1461
1462 unsigned int dwc_otg_battery_detect(bool det_type)
1463 {
1464     printk("%s\n",__func__);
1465     return 0;
1466 }
1467
1468 static void dwc_phy_reconnect(struct work_struct *work)
1469 {
1470         dwc_otg_pcd_t *pcd;
1471         dwc_otg_core_if_t *core_if;
1472         gotgctl_data_t    gctrl;
1473         dctl_data_t dctl = {.d32=0};
1474
1475         pcd = container_of(work, dwc_otg_pcd_t, reconnect.work);
1476         core_if = GET_CORE_IF(pcd);
1477         gctrl.d32 = DWC_READ_REG32( &core_if->core_global_regs->gotgctl );
1478
1479         if(gctrl.b.bsesvld){
1480                 pcd->conn_status++;
1481                 dwc_pcd_reset(pcd);
1482                 /*
1483                  * Enable the global interrupt after all the interrupt
1484                  * handlers are installed.
1485                  */
1486                 dctl.d32 = DWC_READ_REG32( &core_if->dev_if->dev_global_regs->dctl );
1487                 dctl.b.sftdiscon = 0;
1488                 DWC_WRITE_REG32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
1489                 printk("*******************soft connect!!!*******************\n");
1490         }
1491 }
1492
1493 static void dwc_otg_pcd_check_vbus_work( struct work_struct *work )
1494 {
1495         dwc_otg_pcd_t * _pcd = container_of(work, dwc_otg_pcd_t, check_vbus_work.work);
1496         struct dwc_otg_device* otg_dev = _pcd->otg_dev;
1497         struct dwc_otg_platform_data *pldata = otg_dev->pldata;
1498         unsigned long flags;
1499
1500         local_irq_save(flags);
1501
1502         if(!pldata->get_status(USB_STATUS_ID)){
1503                 // id low, host mode
1504                 if( pldata->dwc_otg_uart_mode != NULL ){
1505                         //exit phy bypass to uart & enable usb phy
1506                         pldata->dwc_otg_uart_mode( pldata, PHY_USB_MODE);
1507                 }
1508                 if( pldata->phy_status){
1509                         pldata->clock_enable( pldata, 1);
1510                         pldata->phy_suspend(pldata, USB_PHY_ENABLED);
1511                 }
1512                dwc_otg_enable_global_interrupts(otg_dev->core_if);
1513
1514         }else if(pldata->get_status(USB_STATUS_BVABLID)){
1515                 /* if usb not connect before ,then start connect */
1516                 if( _pcd->vbus_status == 0 ) {
1517                         printk("*******************vbus detect*********************\n");
1518                         _pcd->vbus_status = 1;
1519                         if(_pcd->conn_en){
1520                                 goto connect;
1521                         }
1522                         else if( pldata->phy_status == USB_PHY_ENABLED ){
1523                                 // do not allow to connect, suspend phy
1524                                 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1525                                 udelay(3);
1526                                 pldata->clock_enable( pldata, 0);
1527                         }
1528                 }else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <2)){
1529                         printk("******************soft reconnect********************\n");
1530                         goto connect;
1531                 }else if(_pcd->conn_status == 2){
1532                         /* release pcd->wake_lock if fail to connect,
1533                          * allow system to enter second sleep.
1534                          */
1535                         dwc_otg_msc_unlock(_pcd);
1536                         _pcd->conn_status++;
1537                         if((DWC_READ_REG32((uint32_t*)((uint8_t *)_pcd->otg_dev->os_dep.base
1538                             + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
1539                         _pcd->vbus_status = 2;
1540                 
1541                         /* fail to connect, suspend usb phy and disable clk */
1542                         if( pldata->phy_status == USB_PHY_ENABLED ){
1543                                 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1544                                 udelay(3);
1545                                 pldata->clock_enable( pldata, 0);
1546                         }
1547                 }
1548         }else {
1549                 _pcd->vbus_status = 0;
1550
1551                 if(_pcd->conn_status){
1552                         _pcd->conn_status = 0;
1553                 }
1554
1555                 if( pldata->phy_status == USB_PHY_ENABLED ){
1556                         /* no vbus detect here , close usb phy  */
1557                         pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1558                         udelay(3);
1559                         pldata->clock_enable( pldata, 0);
1560                         /* usb phy bypass to uart mode  */
1561                         if( pldata->dwc_otg_uart_mode != NULL )
1562                                 pldata->dwc_otg_uart_mode( pldata, PHY_UART_MODE);
1563                         /* release wake lock */
1564                         dwc_otg_msc_unlock(_pcd);
1565                 }
1566         }
1567
1568         schedule_delayed_work(&_pcd->check_vbus_work, HZ);
1569         local_irq_restore(flags);
1570
1571         return;
1572     
1573 connect:
1574         if(_pcd->conn_status==0)
1575                 dwc_otg_msc_lock(_pcd);
1576
1577         if( pldata->phy_status)
1578         {
1579                 pldata->clock_enable(pldata, 1);
1580                 pldata->phy_suspend(pldata, USB_PHY_ENABLED);
1581         }
1582
1583         schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 8 jiffies */
1584         schedule_delayed_work(&_pcd->check_vbus_work, (HZ<<2));
1585         local_irq_restore(flags);
1586
1587         return;
1588 }
1589
1590 void dwc_otg_pcd_start_check_vbus_work(dwc_otg_pcd_t * pcd)
1591 {
1592         /* 
1593          * when receive reset int,the vbus state may not be update,so 
1594          * always start vbus work here.
1595          */
1596         schedule_delayed_work(&pcd->check_vbus_work, (HZ*2));
1597 }
1598
1599 /*
1600 * 20091228,HSL@RK,to get the current vbus status.
1601 */
1602 int dwc_vbus_status( void )
1603 {
1604         dwc_otg_pcd_t *pcd = 0;
1605         pcd = gadget_wrapper->pcd;
1606
1607         if(!pcd)
1608                 return 0;
1609         else
1610                 return pcd->vbus_status ;
1611
1612 }
1613 EXPORT_SYMBOL(dwc_vbus_status);
1614
1615 static void dwc_otg_pcd_work_init(dwc_otg_pcd_t *pcd, struct platform_device *dev)
1616 {
1617         pcd->vbus_status  = 0;
1618         pcd->phy_suspend  = 0;
1619
1620         INIT_DELAYED_WORK(&pcd->reconnect , dwc_phy_reconnect);
1621         INIT_DELAYED_WORK(&pcd->check_vbus_work , dwc_otg_pcd_check_vbus_work);
1622
1623         wake_lock_init(&pcd->wake_lock, WAKE_LOCK_SUSPEND,"usb_pcd");
1624     
1625         if(dwc_otg_is_device_mode(pcd->core_if)){
1626 #ifdef CONFIG_RK_USB_UART        
1627                 if(pldata->get_status(USB_STATUS_BVABLID)){
1628                         //enter usb phy mode
1629                         pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
1630                 }else{
1631                         //usb phy bypass to uart mode
1632                         pldata->phy_suspend(pldata,USB_PHY_SUSPEND);
1633                         pldata->dwc_otg_uart_mode(pldata, PHY_UART_MODE);
1634                 }
1635 #endif
1636                 schedule_delayed_work(&pcd->check_vbus_work, (HZ<<4));
1637         }
1638 #ifdef CONFIG_RK_USB_UART
1639         else if(pldata->dwc_otg_uart_mode != NULL)
1640                 //host mode,enter usb phy mode
1641                 pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
1642 #endif
1643
1644 }
1645
1646 #endif /* DWC_HOST_ONLY */