usb: dwc_otg: fix problems of commit 058d627
[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_status = 2;
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                                struct usb_gadget_driver *driver)
780 {
781         return 0;
782 }
783
784 static const struct usb_gadget_ops dwc_otg_pcd_ops = {
785         .get_frame = get_frame_number,
786         .wakeup = wakeup,
787         .pullup = dwc_otg_pcd_pullup,
788 #ifdef CONFIG_USB_DWC_OTG_LPM
789         .lpm_support = test_lpm_enabled,
790 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
791         .besl_support = test_besl_enabled,
792         .get_baseline_besl = get_param_baseline_besl,
793         .get_deep_besl = get_param_deep_besl,
794 #endif
795 #endif
796         .udc_start = dwc_otg_gadget_start,
797         .udc_stop = dwc_otg_gadget_stop,
798
799         /* current versions must always be self-powered */
800 };
801
802 static int _setup(dwc_otg_pcd_t *pcd, uint8_t *bytes)
803 {
804         int retval = -DWC_E_NOT_SUPPORTED;
805         if (gadget_wrapper->driver && gadget_wrapper->driver->setup) {
806                 retval = gadget_wrapper->driver->setup(&gadget_wrapper->gadget,
807                                                        (struct usb_ctrlrequest
808                                                         *)bytes);
809         }
810
811         if (retval == -ENOTSUPP) {
812                 retval = -DWC_E_NOT_SUPPORTED;
813         } else if (retval < 0) {
814                 retval = -DWC_E_INVALID;
815         }
816
817         return retval;
818 }
819
820 #ifdef DWC_EN_ISOC
821 static int _isoc_complete(dwc_otg_pcd_t *pcd, void *ep_handle,
822                           void *req_handle, int proc_buf_num)
823 {
824         int i, packet_count;
825         struct usb_gadget_iso_packet_descriptor *iso_packet = 0;
826         struct usb_iso_request *iso_req = req_handle;
827
828         if (proc_buf_num) {
829                 iso_packet = iso_req->iso_packet_desc1;
830         } else {
831                 iso_packet = iso_req->iso_packet_desc0;
832         }
833         packet_count =
834             dwc_otg_pcd_get_iso_packet_count(pcd, ep_handle, req_handle);
835         for (i = 0; i < packet_count; ++i) {
836                 int status;
837                 int actual;
838                 int offset;
839                 dwc_otg_pcd_get_iso_packet_params(pcd, ep_handle, req_handle,
840                                                   i, &status, &actual, &offset);
841                 switch (status) {
842                 case -DWC_E_NO_DATA:
843                         status = -ENODATA;
844                         break;
845                 default:
846                         if (status) {
847                                 DWC_PRINTF("unknown status in isoc packet\n");
848                         }
849
850                 }
851                 iso_packet[i].status = status;
852                 iso_packet[i].offset = offset;
853                 iso_packet[i].actual_length = actual;
854         }
855
856         iso_req->status = 0;
857         iso_req->process_buffer(ep_handle, iso_req);
858
859         return 0;
860 }
861 #endif /* DWC_EN_ISOC */
862
863 #ifdef DWC_UTE_PER_IO
864 /**
865  * Copy the contents of the extended request to the Linux usb_request's
866  * extended part and call the gadget's completion.
867  *
868  * @param pcd                   Pointer to the pcd structure
869  * @param ep_handle             Void pointer to the usb_ep structure
870  * @param req_handle    Void pointer to the usb_request structure
871  * @param status                Request status returned from the portable logic
872  * @param ereq_port             Void pointer to the extended request structure
873  *                                              created in the the portable part that contains the
874  *                                              results of the processed iso packets.
875  */
876 static int _xisoc_complete(dwc_otg_pcd_t *pcd, void *ep_handle,
877                            void *req_handle, int32_t status, void *ereq_port)
878 {
879         struct dwc_ute_iso_req_ext *ereqorg = NULL;
880         struct dwc_iso_xreq_port *ereqport = NULL;
881         struct dwc_ute_iso_packet_descriptor *desc_org = NULL;
882         int i;
883         struct usb_request *req;
884         /* struct dwc_ute_iso_packet_descriptor * */
885         /* int status = 0; */
886
887         req = (struct usb_request *)req_handle;
888         ereqorg = &req->ext_req;
889         ereqport = (struct dwc_iso_xreq_port *)ereq_port;
890         desc_org = ereqorg->per_io_frame_descs;
891
892         if (req && req->complete) {
893                 /* Copy the request data from the portable logic to our request */
894                 for (i = 0; i < ereqport->pio_pkt_count; i++) {
895                         desc_org[i].actual_length =
896                             ereqport->per_io_frame_descs[i].actual_length;
897                         desc_org[i].status =
898                             ereqport->per_io_frame_descs[i].status;
899                 }
900
901                 switch (status) {
902                 case -DWC_E_SHUTDOWN:
903                         req->status = -ESHUTDOWN;
904                         break;
905                 case -DWC_E_RESTART:
906                         req->status = -ECONNRESET;
907                         break;
908                 case -DWC_E_INVALID:
909                         req->status = -EINVAL;
910                         break;
911                 case -DWC_E_TIMEOUT:
912                         req->status = -ETIMEDOUT;
913                         break;
914                 default:
915                         req->status = status;
916                 }
917
918                 /* And call the gadget's completion */
919                 req->complete(ep_handle, req);
920         }
921
922         return 0;
923 }
924 #endif /* DWC_UTE_PER_IO */
925
926 static int _complete(dwc_otg_pcd_t *pcd, void *ep_handle,
927                      void *req_handle, int32_t status, uint32_t actual)
928 {
929         struct usb_request *req = (struct usb_request *)req_handle;
930         struct dwc_otg_pcd_ep *ep = NULL;
931
932         ep = ep_from_handle(pcd, ep_handle);
933
934         if (GET_CORE_IF(pcd)->dma_enable) {
935                 /* if (req->length != 0) */
936                 if (req->dma != DWC_DMA_ADDR_INVALID) {
937                         dma_unmap_single(gadget_wrapper->gadget.dev.parent,
938                                          req->dma,
939                                          req->length !=
940                                          0 ? req->length : 4,
941                                          ep->dwc_ep.is_in
942                                          ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
943                         req->dma = DWC_DMA_ADDR_INVALID;
944                 }
945         }
946
947         if (req && req->complete) {
948                 switch (status) {
949                 case -DWC_E_SHUTDOWN:
950                         req->status = -ESHUTDOWN;
951                         break;
952                 case -DWC_E_RESTART:
953                         req->status = -ECONNRESET;
954                         break;
955                 case -DWC_E_INVALID:
956                         req->status = -EINVAL;
957                         break;
958                 case -DWC_E_TIMEOUT:
959                         req->status = -ETIMEDOUT;
960                         break;
961                 default:
962                         req->status = status;
963
964                 }
965
966                 req->actual = actual;
967                 DWC_SPINUNLOCK(pcd->lock);
968                 req->complete(ep_handle, req);
969                 DWC_SPINLOCK(pcd->lock);
970         }
971
972
973         return 0;
974 }
975
976 static int _connect(dwc_otg_pcd_t *pcd, int speed)
977 {
978         gadget_wrapper->gadget.speed = speed;
979         return 0;
980 }
981
982 static int _disconnect(dwc_otg_pcd_t *pcd)
983 {
984         if (gadget_wrapper->driver && gadget_wrapper->driver->disconnect) {
985                 gadget_wrapper->driver->disconnect(&gadget_wrapper->gadget);
986         }
987         return 0;
988 }
989
990 static int _resume(dwc_otg_pcd_t *pcd)
991 {
992         if (gadget_wrapper->driver && gadget_wrapper->driver->resume) {
993                 gadget_wrapper->driver->resume(&gadget_wrapper->gadget);
994         }
995
996         return 0;
997 }
998
999 static int _suspend(dwc_otg_pcd_t *pcd)
1000 {
1001         if (gadget_wrapper->driver && gadget_wrapper->driver->suspend) {
1002                 gadget_wrapper->driver->suspend(&gadget_wrapper->gadget);
1003         }
1004         return 0;
1005 }
1006
1007 /**
1008  * This function updates the otg values in the gadget structure.
1009  */
1010 static int _hnp_changed(dwc_otg_pcd_t *pcd)
1011 {
1012
1013         if (!gadget_wrapper->gadget.is_otg)
1014                 return 0;
1015
1016         gadget_wrapper->gadget.b_hnp_enable = get_b_hnp_enable(pcd);
1017         gadget_wrapper->gadget.a_hnp_support = get_a_hnp_support(pcd);
1018         gadget_wrapper->gadget.a_alt_hnp_support = get_a_alt_hnp_support(pcd);
1019         return 0;
1020 }
1021
1022 static int _reset(dwc_otg_pcd_t *pcd)
1023 {
1024         return 0;
1025 }
1026
1027 #ifdef DWC_UTE_CFI
1028 static int _cfi_setup(dwc_otg_pcd_t *pcd, void *cfi_req)
1029 {
1030         int retval = -DWC_E_INVALID;
1031         if (gadget_wrapper->driver->cfi_feature_setup) {
1032                 retval =
1033                     gadget_wrapper->driver->cfi_feature_setup(&gadget_wrapper->
1034                                                               gadget,
1035                                                               (struct
1036                                                                cfi_usb_ctrlrequest
1037                                                                *)cfi_req);
1038         }
1039
1040         return retval;
1041 }
1042 #endif
1043
1044 static const struct dwc_otg_pcd_function_ops fops = {
1045         .complete = _complete,
1046 #ifdef DWC_EN_ISOC
1047         .isoc_complete = _isoc_complete,
1048 #endif
1049         .setup = _setup,
1050         .disconnect = _disconnect,
1051         .connect = _connect,
1052         .resume = _resume,
1053         .suspend = _suspend,
1054         .hnp_changed = _hnp_changed,
1055         .reset = _reset,
1056 #ifdef DWC_UTE_CFI
1057         .cfi_setup = _cfi_setup,
1058 #endif
1059 #ifdef DWC_UTE_PER_IO
1060         .xisoc_complete = _xisoc_complete,
1061 #endif
1062 };
1063
1064 /**
1065  * This function is the top level PCD interrupt handler.
1066  */
1067 static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev)
1068 {
1069         dwc_otg_pcd_t *pcd = dev;
1070         int32_t retval = IRQ_NONE;
1071
1072         retval = dwc_otg_pcd_handle_intr(pcd);
1073         if (retval != 0) {
1074                 /* S3C2410X_CLEAR_EINTPEND();*/
1075         }
1076         return IRQ_RETVAL(retval);
1077 }
1078
1079 /**
1080  * This function initialized the usb_ep structures to there default
1081  * state.
1082  *
1083  * @param d Pointer on gadget_wrapper.
1084  */
1085 void gadget_add_eps(struct gadget_wrapper *d)
1086 {
1087         static const char *names[] = {
1088
1089                 "ep0",
1090                 "ep1in",
1091                 "ep2in",
1092                 "ep3in",
1093                 "ep4in",
1094                 "ep5in",
1095                 "ep6in",
1096                 "ep7in",
1097                 "ep8in",
1098                 "ep9in",
1099                 "ep10in",
1100                 "ep11in",
1101                 "ep12in",
1102                 "ep13in",
1103                 "ep14in",
1104                 "ep15in",
1105                 "ep1out",
1106                 "ep2out",
1107                 "ep3out",
1108                 "ep4out",
1109                 "ep5out",
1110                 "ep6out",
1111                 "ep7out",
1112                 "ep8out",
1113                 "ep9out",
1114                 "ep10out",
1115                 "ep11out",
1116                 "ep12out",
1117                 "ep13out",
1118                 "ep14out",
1119                 "ep15out"
1120         };
1121
1122         int i;
1123         struct usb_ep *ep;
1124         int8_t dev_endpoints;
1125
1126         DWC_DEBUGPL(DBG_PCDV, "%s\n", __func__);
1127
1128         INIT_LIST_HEAD(&d->gadget.ep_list);
1129         d->gadget.ep0 = &d->ep0;
1130         d->gadget.speed = USB_SPEED_UNKNOWN;
1131 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
1132         d->gadget.max_speed = USB_SPEED_HIGH;
1133 #endif
1134
1135         INIT_LIST_HEAD(&d->gadget.ep0->ep_list);
1136
1137         /**
1138          * Initialize the EP0 structure.
1139          */
1140         ep = &d->ep0;
1141
1142         /* Init the usb_ep structure. */
1143         ep->name = names[0];
1144         ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1145
1146         /**
1147          * @todo NGS: What should the max packet size be set to
1148          * here?  Before EP type is set?
1149          */
1150         ep->maxpacket = MAX_PACKET_SIZE;
1151         dwc_otg_pcd_ep_enable(d->pcd, NULL, ep);
1152
1153         list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1154
1155         /**
1156          * Initialize the EP structures.
1157          */
1158         dev_endpoints = d->pcd->core_if->dev_if->num_in_eps;
1159
1160         for (i = 0; i < dev_endpoints; i++) {
1161                 ep = &d->in_ep[i];
1162
1163                 /* Init the usb_ep structure. */
1164                 ep->name = names[d->pcd->in_ep[i].dwc_ep.num];
1165                 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1166
1167                 /**
1168                  * @todo NGS: What should the max packet size be set to
1169                  * here?  Before EP type is set?
1170                  */
1171                 ep->maxpacket = MAX_PACKET_SIZE;
1172                 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1173         }
1174
1175         dev_endpoints = d->pcd->core_if->dev_if->num_out_eps;
1176
1177         for (i = 0; i < dev_endpoints; i++) {
1178                 ep = &d->out_ep[i];
1179
1180                 /* Init the usb_ep structure. */
1181                 ep->name = names[15 + d->pcd->out_ep[i].dwc_ep.num];
1182                 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1183
1184                 /**
1185                  * @todo NGS: What should the max packet size be set to
1186                  * here?  Before EP type is set?
1187                  */
1188                 ep->maxpacket = MAX_PACKET_SIZE;
1189
1190                 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1191         }
1192
1193         /* remove ep0 from the list.  There is a ep0 pointer. */
1194         list_del_init(&d->ep0.ep_list);
1195
1196         d->ep0.maxpacket = MAX_EP0_SIZE;
1197 }
1198
1199 /**
1200  * This function releases the Gadget device.
1201  * required by device_unregister().
1202  *
1203  * @todo Should this do something?      Should it free the PCD?
1204  */
1205 static void dwc_otg_pcd_gadget_release(struct device *dev)
1206 {
1207         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
1208 }
1209
1210 static struct gadget_wrapper *alloc_wrapper(struct platform_device *_dev)
1211 {
1212         static char pcd_name[] = "dwc_otg_pcd";
1213
1214         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1215         struct gadget_wrapper *d;
1216         int retval;
1217
1218         d = DWC_ALLOC(sizeof(*d));
1219         if (d == NULL) {
1220                 return NULL;
1221         }
1222
1223         memset(d, 0, sizeof(*d));
1224
1225         d->gadget.name = pcd_name;
1226         d->pcd = otg_dev->pcd;
1227
1228 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
1229         strcpy(d->gadget.dev.bus_id, "gadget");
1230 #else
1231         dev_set_name(&d->gadget.dev, "%s", "gadget");
1232 #endif
1233
1234         d->gadget.dev.parent = &_dev->dev;
1235         d->gadget.dev.release = dwc_otg_pcd_gadget_release;
1236         d->gadget.ops = &dwc_otg_pcd_ops;
1237 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
1238         d->gadget.is_dualspeed = dwc_otg_pcd_is_dualspeed(otg_dev->pcd);
1239 #endif
1240         d->gadget.is_otg = dwc_otg_pcd_is_otg(otg_dev->pcd);
1241
1242         d->gadget.max_speed = USB_SPEED_HIGH;
1243         d->driver = 0;
1244         d->pcd->conn_en = 0;
1245         /* Register the gadget device */
1246         retval = usb_add_gadget_udc(&_dev->dev, &d->gadget);
1247         if (retval != 0) {
1248                 DWC_ERROR("device_register failed\n");
1249                 DWC_FREE(d);
1250                 return NULL;
1251         }
1252
1253         return d;
1254 }
1255
1256 static void free_wrapper(struct gadget_wrapper *d)
1257 {
1258         if (d->driver) {
1259                 /* should have been done already by driver model core */
1260                 DWC_WARN("driver '%s' is still registered\n",
1261                          d->driver->driver.name);
1262                 usb_gadget_unregister_driver(d->driver);
1263         }
1264
1265         usb_del_gadget_udc(&d->gadget);
1266         DWC_FREE(d);
1267 }
1268
1269 static void dwc_otg_pcd_work_init(dwc_otg_pcd_t *pcd,
1270                                   struct platform_device *dev);
1271
1272 /**
1273  * This function initialized the PCD portion of the driver.
1274  *
1275  */
1276 int pcd_init(struct platform_device *_dev)
1277 {
1278
1279         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1280
1281         int retval = 0;
1282         int irq;
1283         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1284
1285         otg_dev->pcd = dwc_otg_pcd_init(otg_dev->core_if);
1286         printk("pcd_init otg_dev = %p\n", otg_dev);
1287
1288         if (!otg_dev->pcd) {
1289                 DWC_ERROR("dwc_otg_pcd_init failed\n");
1290                 return -ENOMEM;
1291         }
1292
1293         otg_dev->pcd->otg_dev = otg_dev;
1294         gadget_wrapper = alloc_wrapper(_dev);
1295
1296         /*
1297          * Initialize EP structures
1298          */
1299         gadget_add_eps(gadget_wrapper);
1300         /*
1301          * Setup interupt handler
1302          */
1303         irq = platform_get_irq(_dev, 0);
1304         DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", irq);
1305         retval = request_irq(irq, dwc_otg_pcd_irq,
1306                              IRQF_SHARED,
1307                              gadget_wrapper->gadget.name, otg_dev->pcd);
1308         if (retval != 0) {
1309                 DWC_ERROR("request of irq%d failed\n", irq);
1310                 free_wrapper(gadget_wrapper);
1311                 return -EBUSY;
1312         }
1313
1314         dwc_otg_pcd_start(gadget_wrapper->pcd, &fops);
1315
1316         dwc_otg_pcd_work_init(otg_dev->pcd, _dev);
1317
1318         return retval;
1319 }
1320
1321 /**
1322  * Cleanup the PCD.
1323  */
1324 void pcd_remove(struct platform_device *_dev)
1325 {
1326
1327         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1328         dwc_otg_pcd_t *pcd = otg_dev->pcd;
1329         int irq;
1330
1331         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1332
1333         /*
1334          * Free the IRQ
1335          */
1336         irq = platform_get_irq(_dev, 0);
1337         free_irq(irq, pcd);
1338         free_wrapper(gadget_wrapper);
1339         dwc_otg_pcd_remove(otg_dev->pcd);
1340         otg_dev->pcd = 0;
1341 }
1342
1343 /**
1344  * This function registers a gadget driver with the PCD.
1345  *
1346  * When a driver is successfully registered, it will receive control
1347  * requests including set_configuration(), which enables non-control
1348  * requests.  then usb traffic follows until a disconnect is reported.
1349  * then a host may connect again, or the driver might get unbound.
1350  *
1351  * @param driver The driver being registered
1352  * @param bind The bind function of gadget driver
1353  */
1354 #if 0
1355 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
1356 int usb_gadget_register_driver(struct usb_gadget_driver *driver)
1357 #else
1358 int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
1359                             int (*bind) (struct usb_gadget *))
1360 #endif
1361 {
1362         int retval;
1363
1364         DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n",
1365                     driver->driver.name);
1366
1367         if (!driver ||
1368 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
1369             driver->speed == USB_SPEED_UNKNOWN ||
1370 #else
1371             driver->max_speed == USB_SPEED_UNKNOWN ||
1372 #endif
1373 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
1374             !driver->bind ||
1375 #else
1376             !bind ||
1377 #endif
1378             !driver->unbind || !driver->disconnect || !driver->setup) {
1379                 DWC_DEBUGPL(DBG_PCDV, "EINVAL\n");
1380                 return -EINVAL;
1381         }
1382         if (gadget_wrapper == 0) {
1383                 DWC_DEBUGPL(DBG_PCDV, "ENODEV\n");
1384                 return -ENODEV;
1385         }
1386         if (gadget_wrapper->driver != 0) {
1387                 DWC_DEBUGPL(DBG_PCDV, "EBUSY (%p)\n", gadget_wrapper->driver);
1388                 return -EBUSY;
1389         }
1390
1391         /* hook up the driver */
1392         gadget_wrapper->driver = driver;
1393         gadget_wrapper->gadget.dev.driver = &driver->driver;
1394
1395         DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
1396 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
1397         retval = driver->bind(&gadget_wrapper->gadget);
1398 #else
1399         retval = bind(&gadget_wrapper->gadget);
1400 #endif
1401         if (retval) {
1402                 DWC_ERROR("bind to driver %s --> error %d\n",
1403                           driver->driver.name, retval);
1404                 gadget_wrapper->driver = 0;
1405                 gadget_wrapper->gadget.dev.driver = 0;
1406                 return retval;
1407         }
1408         DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
1409                     driver->driver.name);
1410         return 0;
1411 }
1412
1413 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
1414 EXPORT_SYMBOL(usb_gadget_register_driver);
1415 #else
1416 EXPORT_SYMBOL(usb_gadget_probe_driver);
1417 #endif
1418
1419 /**
1420  * This function unregisters a gadget driver
1421  *
1422  * @param driver The driver being unregistered
1423  */
1424 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1425 {
1426         /* DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver); */
1427
1428         if (gadget_wrapper == 0) {
1429                 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
1430                             -ENODEV);
1431                 return -ENODEV;
1432         }
1433         if (driver == 0 || driver != gadget_wrapper->driver) {
1434                 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
1435                             -EINVAL);
1436                 return -EINVAL;
1437         }
1438
1439         driver->unbind(&gadget_wrapper->gadget);
1440         gadget_wrapper->driver = 0;
1441
1442         DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n", driver->driver.name);
1443         return 0;
1444 }
1445
1446 EXPORT_SYMBOL(usb_gadget_unregister_driver);
1447
1448 #endif
1449
1450 /************************ for RK platform ************************/
1451
1452 void dwc_otg_msc_lock(dwc_otg_pcd_t *pcd)
1453 {
1454         unsigned long flags;
1455         local_irq_save(flags);
1456         wake_lock(&pcd->wake_lock);
1457         local_irq_restore(flags);
1458 }
1459
1460 void dwc_otg_msc_unlock(dwc_otg_pcd_t *pcd)
1461 {
1462         unsigned long flags;
1463         local_irq_save(flags);
1464         wake_unlock(&pcd->wake_lock);
1465         local_irq_restore(flags);
1466 }
1467
1468 unsigned int dwc_otg_battery_detect(bool det_type)
1469 {
1470         printk("%s\n", __func__);
1471         return 0;
1472 }
1473
1474 static void dwc_phy_reconnect(struct work_struct *work)
1475 {
1476         dwc_otg_pcd_t *pcd;
1477         dwc_otg_core_if_t *core_if;
1478         gotgctl_data_t gctrl;
1479         dctl_data_t dctl = {.d32 = 0 };
1480         struct dwc_otg_platform_data *pldata;
1481
1482         pcd = container_of(work, dwc_otg_pcd_t, reconnect.work);
1483         pldata = pcd->otg_dev->pldata;
1484         core_if = GET_CORE_IF(pcd);
1485         gctrl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
1486
1487         if (gctrl.b.bsesvld) {
1488                 pcd->conn_status++;
1489                 pldata->soft_reset(pldata, RST_RECNT);
1490                 dwc_pcd_reset(pcd);
1491                 /*
1492                  * Enable the global interrupt after all the interrupt
1493                  * handlers are installed.
1494                  */
1495                 dctl.d32 =
1496                     DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
1497                 dctl.b.sftdiscon = 0;
1498                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
1499                                 dctl.d32);
1500                 printk
1501                     ("*******************soft connect!!!*******************\n");
1502         }
1503 }
1504
1505 static void id_status_change(dwc_otg_core_if_t *p, bool current_id)
1506 {
1507         dwc_otg_core_if_t *core_if = p;
1508         uint32_t count = 0;
1509         gotgctl_data_t gotgctl = {.d32 = 0 };
1510         dwc_otg_pcd_t *pcd = core_if->otg_dev->pcd;
1511
1512         gotgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
1513         DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32);
1514         DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts);
1515
1516         if (core_if->usb_mode != USB_MODE_NORMAL)
1517                 return;
1518
1519         /* B-Device connector (Device Mode) */
1520         if (current_id) {
1521                 gotgctl_data_t gotgctl_local;
1522                 /* Wait for switch to device mode. */
1523                 while (!dwc_otg_is_device_mode(core_if)) {
1524                         gotgctl_local.d32 =
1525                             DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
1526                         DWC_DEBUGPL(DBG_ANY,
1527                                     "Waiting for Peripheral Mode, Mode=%s count = %d gotgctl=%08x\n",
1528                                     (dwc_otg_is_host_mode(core_if) ? "Host" :
1529                                      "Peripheral"), count, gotgctl_local.d32);
1530                         dwc_mdelay(1);
1531                         if (++count > 200)
1532                                 break;
1533                 }
1534                 if (count >= 200) {
1535                         DWC_PRINTF("Connection id status change timed out");
1536                         return;
1537                 }
1538                 dwc_otg_set_force_mode(core_if, USB_MODE_FORCE_DEVICE);
1539                 core_if->op_state = B_PERIPHERAL;
1540                 cil_hcd_stop(core_if);
1541                 /* pcd->phy_suspend = 1; */
1542                 pcd->vbus_status = 0;
1543                 dwc_otg_core_init(core_if);
1544                 cil_pcd_start(core_if);
1545                 dwc_otg_pcd_start_check_vbus_work(pcd);
1546         } else {
1547                 /* A-Device connector (Host Mode) */
1548                 while (!dwc_otg_is_host_mode(core_if)) {
1549                         DWC_DEBUGPL(DBG_ANY, "Waiting for Host Mode, Mode=%s\n",
1550                                     (dwc_otg_is_host_mode(core_if) ? "Host" :
1551                                      "Peripheral"));
1552                         dwc_mdelay(1);  /* vahrama previously was 100 */
1553                         if (++count > 200)
1554                                 break;
1555                 }
1556                 if (count >= 200) {
1557                         DWC_PRINTF("Connection id status change timed out");
1558                         return;
1559                 }
1560
1561                 core_if->op_state = A_HOST;
1562                 dwc_otg_set_force_mode(core_if, USB_MODE_FORCE_HOST);
1563
1564                 cancel_delayed_work(&pcd->check_vbus_work);
1565
1566                 /*
1567                  * Initialize the Core for Host mode.
1568                  */
1569                 dwc_otg_core_init(core_if);
1570                 cil_hcd_start(core_if);
1571                 dwc_otg_enable_global_interrupts(core_if);
1572         }
1573 }
1574
1575
1576 static void check_id(struct work_struct *work)
1577 {
1578         dwc_otg_pcd_t *_pcd =
1579             container_of(work, dwc_otg_pcd_t, check_id_work.work);
1580         struct dwc_otg_device *otg_dev = _pcd->otg_dev;
1581         struct dwc_otg_platform_data *pldata = otg_dev->pldata;
1582         static int last_id = -1;
1583         int id = pldata->get_status(USB_STATUS_ID);
1584
1585         if (last_id != id) {
1586                 pr_info("[otg id chg] last id %d current id %d\n", last_id, id);
1587                 if (!id) { /* Force Host */
1588                         if (pldata->phy_status == USB_PHY_SUSPEND) {
1589                                 pldata->clock_enable(pldata, 1);
1590                                 pldata->phy_suspend(pldata, USB_PHY_ENABLED);
1591         }
1592                         id_status_change(otg_dev->core_if, id);
1593                 } else { /* Force Device */
1594                         id_status_change(otg_dev->core_if, id);
1595                 }
1596         }
1597         last_id = id;
1598         schedule_delayed_work(&_pcd->check_id_work, (HZ));
1599 }
1600
1601 static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
1602 {
1603         dwc_otg_pcd_t *_pcd =
1604             container_of(work, dwc_otg_pcd_t, check_vbus_work.work);
1605         struct dwc_otg_device *otg_dev = _pcd->otg_dev;
1606         struct dwc_otg_platform_data *pldata = otg_dev->pldata;
1607
1608         if (pldata->get_status(USB_STATUS_BVABLID)) {
1609                 /* if usb not connect before ,then start connect */
1610                 if (_pcd->vbus_status == USB_BC_TYPE_DISCNT) {
1611                         printk("***************vbus detect*****************\n");
1612                         if( pldata->bc_detect_cb != NULL )
1613                                 pldata->bc_detect_cb(_pcd->vbus_status =
1614                                         usb_battery_charger_detect(1));
1615                         else
1616                                 _pcd->vbus_status = USB_BC_TYPE_SDP;
1617                         if (_pcd->conn_en) {
1618                                 goto connect;
1619                         } else if (pldata->phy_status == USB_PHY_ENABLED) {
1620                                 /* do not allow to connect, suspend phy */
1621                                 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1622                                 udelay(3);
1623                                 pldata->clock_enable(pldata, 0);
1624                         }
1625                 } else if ((_pcd->conn_en) && (_pcd->conn_status >= 0)
1626                            && (_pcd->conn_status < 2)) {
1627                         printk("**************soft reconnect**************\n");
1628                         goto connect;
1629                 } else if (_pcd->conn_status == 2) {
1630                         /* release pcd->wake_lock if fail to connect,
1631                          * allow system to enter second sleep.
1632                          */
1633                         dwc_otg_msc_unlock(_pcd);
1634                         _pcd->conn_status++;
1635                         if (pldata->bc_detect_cb != NULL) {
1636                                 pldata->bc_detect_cb(_pcd->vbus_status =
1637                                                      USB_BC_TYPE_DCP);
1638                         } else {
1639                                 _pcd->vbus_status = USB_BC_TYPE_DCP;
1640                         }
1641                         /* fail to connect, suspend usb phy and disable clk */
1642                         if (pldata->phy_status == USB_PHY_ENABLED) {
1643                                 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1644                                 udelay(3);
1645                                 pldata->clock_enable(pldata, 0);
1646                         }
1647                 }
1648         } else {
1649                 if (pldata->bc_detect_cb != NULL)
1650                         pldata->bc_detect_cb(_pcd->vbus_status =
1651                                              usb_battery_charger_detect(0));
1652                 else
1653                         _pcd->vbus_status = USB_BC_TYPE_DISCNT;
1654
1655                 if (_pcd->conn_status) {
1656                         _pcd->conn_status = 0;
1657                 }
1658
1659                 if (pldata->phy_status == USB_PHY_ENABLED) {
1660                         /* release wake lock */
1661                         dwc_otg_msc_unlock(_pcd);
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                 /* usb phy bypass to uart mode  */
1669                 if (pldata->dwc_otg_uart_mode != NULL)
1670                         pldata->dwc_otg_uart_mode(pldata, PHY_UART_MODE);
1671         }
1672
1673         schedule_delayed_work(&_pcd->check_vbus_work, HZ);
1674         return;
1675
1676 connect:
1677         if (pldata->phy_status) {
1678                 pldata->clock_enable(pldata, 1);
1679                 pldata->phy_suspend(pldata, USB_PHY_ENABLED);
1680         }
1681
1682         if (_pcd->conn_status == 0)
1683                 dwc_otg_msc_lock(_pcd);
1684
1685         schedule_delayed_work(&_pcd->reconnect, 8);     /* delay 8 jiffies */
1686         schedule_delayed_work(&_pcd->check_vbus_work, (HZ));
1687         return;
1688 }
1689
1690 void dwc_otg_pcd_start_check_vbus_work(dwc_otg_pcd_t *pcd)
1691 {
1692         /*
1693          * when receive reset int,the vbus state may not be update,so
1694          * always start vbus work here.
1695          */
1696         schedule_delayed_work(&pcd->check_vbus_work, HZ/2);
1697
1698 }
1699
1700 /*
1701 * 20091228,HSL@RK,to get the current vbus status.
1702 */
1703 int dwc_vbus_status(void)
1704 {
1705 #ifdef CONFIG_USB20_OTG
1706         dwc_otg_pcd_t *pcd = 0;
1707         if (gadget_wrapper) {
1708                 pcd = gadget_wrapper->pcd;
1709         }
1710
1711         if (!pcd)
1712                 return 0;
1713         else
1714                 return pcd->vbus_status;
1715 #else
1716         return 0;
1717 #endif
1718 }
1719
1720 EXPORT_SYMBOL(dwc_vbus_status);
1721
1722 static void dwc_otg_pcd_work_init(dwc_otg_pcd_t *pcd,
1723                                   struct platform_device *dev)
1724 {
1725
1726         struct dwc_otg_device *otg_dev = pcd->otg_dev;
1727         struct dwc_otg_platform_data *pldata = otg_dev->pldata;
1728
1729         pcd->vbus_status = USB_BC_TYPE_DISCNT;
1730         pcd->phy_suspend = USB_PHY_ENABLED;
1731
1732         INIT_DELAYED_WORK(&pcd->reconnect, dwc_phy_reconnect);
1733         INIT_DELAYED_WORK(&pcd->check_vbus_work, dwc_otg_pcd_check_vbus_work);
1734         INIT_DELAYED_WORK(&pcd->check_id_work, check_id);
1735
1736         wake_lock_init(&pcd->wake_lock, WAKE_LOCK_SUSPEND, "usb_pcd");
1737
1738         if (dwc_otg_is_device_mode(pcd->core_if) &&
1739             (otg_dev->core_if->usb_mode != USB_MODE_FORCE_HOST)) {
1740                 if (pldata->get_status(USB_STATUS_BVABLID)) {
1741                         /* enter usb phy mode */
1742                         pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
1743                 } else {
1744                         /* usb phy bypass to uart mode */
1745                         pldata->dwc_otg_uart_mode(pldata, PHY_UART_MODE);
1746                 }
1747         } else if (pldata->dwc_otg_uart_mode != NULL) {
1748                 /* host mode,enter usb phy mode */
1749                 pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
1750         }
1751         schedule_delayed_work(&pcd->check_id_work, HZ);
1752 }
1753
1754 #endif /* DWC_HOST_ONLY */