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