USB: fix compile warnings.
[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                 if (usb_req->dma == DWC_DMA_ADDR_INVALID) {
367                         dma_addr =
368                             dma_map_single(gadget_wrapper->gadget.dev.parent,
369                                            usb_req->buf, usb_req->length,
370                                            ep->dwc_ep.
371                                            is_in ? DMA_TO_DEVICE :
372                                            DMA_FROM_DEVICE);
373                         usb_req->dma = dma_addr;
374                 }
375
376         }
377 #endif
378
379 #ifdef DWC_UTE_PER_IO
380         if (is_isoc_ep == 1) {
381                 retval =
382                     dwc_otg_pcd_xiso_ep_queue(pcd, usb_ep, usb_req->buf,
383                                               dma_addr, usb_req->length,
384                                               usb_req->zero, usb_req,
385                                               gfp_flags == GFP_ATOMIC ? 1 : 0,
386                                               &usb_req->ext_req);
387                 if (retval)
388                         return -EINVAL;
389
390                 return 0;
391         }
392 #endif
393         retval = dwc_otg_pcd_ep_queue(pcd, usb_ep, usb_req->buf, dma_addr,
394                                       usb_req->length, usb_req->zero, usb_req,
395                                       gfp_flags == GFP_ATOMIC ? 1 : 0);
396         if (retval) {
397                 return -EINVAL;
398         }
399
400         return 0;
401 }
402
403 /**
404  * This function cancels an I/O request from an EP.
405  */
406 static int ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req)
407 {
408         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, usb_req);
409
410         if (!usb_ep || !usb_req) {
411                 DWC_WARN("bad argument\n");
412                 return -EINVAL;
413         }
414         if (!gadget_wrapper->driver ||
415             gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
416                 DWC_WARN("bogus device state\n");
417                 return -ESHUTDOWN;
418         }
419         if (dwc_otg_pcd_ep_dequeue(gadget_wrapper->pcd, usb_ep, usb_req)) {
420                 return -EINVAL;
421         }
422
423         return 0;
424 }
425
426 /**
427  * usb_ep_set_halt stalls an endpoint.
428  *
429  * usb_ep_clear_halt clears an endpoint halt and resets its data
430  * toggle.
431  *
432  * Both of these functions are implemented with the same underlying
433  * function. The behavior depends on the value argument.
434  *
435  * @param[in] usb_ep the Endpoint to halt or clear halt.
436  * @param[in] value
437  *      - 0 means clear_halt.
438  *      - 1 means set_halt,
439  *      - 2 means clear stall lock flag.
440  *      - 3 means set  stall lock flag.
441  */
442 static int ep_halt(struct usb_ep *usb_ep, int value)
443 {
444         int retval = 0;
445
446         DWC_DEBUGPL(DBG_PCD, "HALT %s %d\n", usb_ep->name, value);
447
448         if (!usb_ep) {
449                 DWC_WARN("bad ep\n");
450                 return -EINVAL;
451         }
452
453         retval = dwc_otg_pcd_ep_halt(gadget_wrapper->pcd, usb_ep, value);
454         if (retval == -DWC_E_AGAIN) {
455                 return -EAGAIN;
456         } else if (retval) {
457                 retval = -EINVAL;
458         }
459
460         return retval;
461 }
462
463 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
464 static int ep_wedge(struct usb_ep *usb_ep)
465 {
466         DWC_DEBUGPL(DBG_PCD, "WEDGE %s\n", usb_ep->name);
467
468         return ep_halt(usb_ep, 3);
469 }
470 #endif
471
472 #ifdef DWC_EN_ISOC
473 /**
474  * This function is used to submit an ISOC Transfer Request to an EP.
475  *
476  *      - Every time a sync period completes the request's completion callback
477  *        is called to provide data to the gadget driver.
478  *      - Once submitted the request cannot be modified.
479  *      - Each request is turned into periodic data packets untill ISO
480  *        Transfer is stopped..
481  */
482 static int iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
483                         gfp_t gfp_flags)
484 {
485         int retval = 0;
486
487         if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
488                 DWC_WARN("bad params\n");
489                 return -EINVAL;
490         }
491
492         if (!usb_ep) {
493                 DWC_PRINTF("bad params\n");
494                 return -EINVAL;
495         }
496
497         req->status = -EINPROGRESS;
498
499         retval =
500             dwc_otg_pcd_iso_ep_start(gadget_wrapper->pcd, usb_ep, req->buf0,
501                                      req->buf1, req->dma0, req->dma1,
502                                      req->sync_frame, req->data_pattern_frame,
503                                      req->data_per_frame,
504                                      req->flags & USB_REQ_ISO_ASAP ? -1 :
505                                      req->start_frame, req->buf_proc_intrvl,
506                                      req, gfp_flags == GFP_ATOMIC ? 1 : 0);
507
508         if (retval) {
509                 return -EINVAL;
510         }
511
512         return retval;
513 }
514
515 /**
516  * This function stops ISO EP Periodic Data Transfer.
517  */
518 static int iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
519 {
520         int retval = 0;
521         if (!usb_ep) {
522                 DWC_WARN("bad ep\n");
523         }
524
525         if (!gadget_wrapper->driver ||
526             gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
527                 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
528                             gadget_wrapper->gadget.speed);
529                 DWC_WARN("bogus device state\n");
530         }
531
532         dwc_otg_pcd_iso_ep_stop(gadget_wrapper->pcd, usb_ep, req);
533         if (retval) {
534                 retval = -EINVAL;
535         }
536
537         return retval;
538 }
539
540 static struct usb_iso_request *alloc_iso_request(struct usb_ep *ep,
541                                                  int packets, gfp_t gfp_flags)
542 {
543         struct usb_iso_request *pReq = NULL;
544         uint32_t req_size;
545
546         req_size = sizeof(struct usb_iso_request);
547         req_size +=
548             (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
549
550         pReq = kmalloc(req_size, gfp_flags);
551         if (!pReq) {
552                 DWC_WARN("Can't allocate Iso Request\n");
553                 return 0;
554         }
555         pReq->iso_packet_desc0 = (void *)(pReq + 1);
556
557         pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
558
559         return pReq;
560 }
561
562 static void free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
563 {
564         kfree(req);
565 }
566
567 static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops = {
568         .ep_ops = {
569                    .enable = ep_enable,
570                    .disable = ep_disable,
571
572                    .alloc_request = dwc_otg_pcd_alloc_request,
573                    .free_request = dwc_otg_pcd_free_request,
574
575 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
576                    .alloc_buffer = dwc_otg_pcd_alloc_buffer,
577                    .free_buffer = dwc_otg_pcd_free_buffer,
578 #endif
579
580                    .queue = ep_queue,
581                    .dequeue = ep_dequeue,
582
583                    .set_halt = ep_halt,
584
585 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
586                    .set_wedge = ep_wedge,
587 #endif
588                    .fifo_status = 0,
589                    .fifo_flush = 0,
590                    },
591
592         .iso_ep_start = iso_ep_start,
593         .iso_ep_stop = iso_ep_stop,
594         .alloc_iso_request = alloc_iso_request,
595         .free_iso_request = free_iso_request,
596 };
597
598 #else
599
600 static struct usb_ep_ops dwc_otg_pcd_ep_ops = {
601         .enable = ep_enable,
602         .disable = ep_disable,
603
604         .alloc_request = dwc_otg_pcd_alloc_request,
605         .free_request = dwc_otg_pcd_free_request,
606
607 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
608         .alloc_buffer = dwc_otg_pcd_alloc_buffer,
609         .free_buffer = dwc_otg_pcd_free_buffer,
610 #endif
611
612         .queue = ep_queue,
613         .dequeue = ep_dequeue,
614
615         .set_halt = ep_halt,
616
617 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
618         .set_wedge = ep_wedge,
619 #endif
620
621         .fifo_status = 0,
622         .fifo_flush = 0,
623
624 };
625
626 #endif /* _EN_ISOC_ */
627 /*      Gadget Operations */
628 /**
629  * The following gadget operations will be implemented in the DWC_otg
630  * PCD. Functions in the API that are not described below are not
631  * implemented.
632  *
633  * The Gadget API provides wrapper functions for each of the function
634  * pointers defined in usb_gadget_ops. The Gadget Driver calls the
635  * wrapper function, which then calls the underlying PCD function. The
636  * following sections are named according to the wrapper functions
637  * (except for ioctl, which doesn't have a wrapper function). Within
638  * each section, the corresponding DWC_otg PCD function name is
639  * specified.
640  *
641  */
642
643 /**
644  *Gets the USB Frame number of the last SOF.
645  */
646 static int get_frame_number(struct usb_gadget *gadget)
647 {
648         struct gadget_wrapper *d;
649
650         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
651
652         if (gadget == 0) {
653                 return -ENODEV;
654         }
655
656         d = container_of(gadget, struct gadget_wrapper, gadget);
657         return dwc_otg_pcd_get_frame_number(d->pcd);
658 }
659
660 #ifdef CONFIG_USB_DWC_OTG_LPM
661 static int test_lpm_enabled(struct usb_gadget *gadget)
662 {
663         struct gadget_wrapper *d;
664
665         d = container_of(gadget, struct gadget_wrapper, gadget);
666
667         return dwc_otg_pcd_is_lpm_enabled(d->pcd);
668 }
669
670 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
671 static int test_besl_enabled(struct usb_gadget *gadget)
672 {
673         struct gadget_wrapper *d;
674
675         d = container_of(gadget, struct gadget_wrapper, gadget);
676
677         return dwc_otg_pcd_is_besl_enabled(d->pcd);
678 }
679
680 static int get_param_baseline_besl(struct usb_gadget *gadget)
681 {
682         struct gadget_wrapper *d;
683
684         d = container_of(gadget, struct gadget_wrapper, gadget);
685
686         return dwc_otg_pcd_get_param_baseline_besl(d->pcd);
687 }
688
689 static int get_param_deep_besl(struct usb_gadget *gadget)
690 {
691         struct gadget_wrapper *d;
692
693         d = container_of(gadget, struct gadget_wrapper, gadget);
694
695         return dwc_otg_pcd_get_param_deep_besl(d->pcd);
696 }
697 #endif
698 #endif
699
700 /**
701  * Initiates Session Request Protocol (SRP) to wakeup the host if no
702  * session is in progress. If a session is already in progress, but
703  * the device is suspended, remote wakeup signaling is started.
704  *
705  */
706 static int wakeup(struct usb_gadget *gadget)
707 {
708         struct gadget_wrapper *d;
709
710         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
711
712         if (gadget == 0) {
713                 return -ENODEV;
714         } else {
715                 d = container_of(gadget, struct gadget_wrapper, gadget);
716         }
717         dwc_otg_pcd_wakeup(d->pcd);
718         return 0;
719 }
720
721 static int dwc_otg_pcd_pullup(struct usb_gadget *_gadget, int is_on)
722 {
723         struct gadget_wrapper *d;
724         dwc_otg_pcd_t *pcd;
725         dwc_otg_core_if_t *core_if;
726
727         printk("pcd_pullup, is_on %d\n", is_on);
728         if (_gadget == NULL)
729                 return -ENODEV;
730         else {
731                 d = container_of(_gadget, struct gadget_wrapper, gadget);
732                 pcd = d->pcd;
733                 core_if = GET_CORE_IF(d->pcd);
734         }
735
736         if (is_on) {
737                 /* dwc_otg_pcd_pullup_enable(pcd); */
738                 pcd->conn_en = 1;
739                 pcd->conn_status = 0;
740         } else {
741                 dwc_otg_pcd_pullup_disable(pcd);
742                 pcd->conn_status = 2;
743         }
744
745         return 0;
746
747 }
748
749 static int dwc_otg_gadget_start(struct usb_gadget *g,
750                                 struct usb_gadget_driver *driver)
751 {
752         DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n",
753                     driver->driver.name);
754         if (gadget_wrapper == 0) {
755                 DWC_ERROR("ENODEV\n");
756                 return -ENODEV;
757         }
758         if (gadget_wrapper->driver != 0) {
759                 DWC_ERROR("EBUSY (%p)\n", gadget_wrapper->driver);
760                 return -EBUSY;
761         }
762         /* hook up the driver */
763         gadget_wrapper->driver = driver;
764         gadget_wrapper->gadget.dev.driver = &driver->driver;
765
766         DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
767
768         return 0;
769 }
770
771 static int dwc_otg_gadget_stop(struct usb_gadget *g,
772                                struct usb_gadget_driver *driver)
773 {
774         return 0;
775 }
776
777 static const struct usb_gadget_ops dwc_otg_pcd_ops = {
778         .get_frame = get_frame_number,
779         .wakeup = wakeup,
780         .pullup = dwc_otg_pcd_pullup,
781 #ifdef CONFIG_USB_DWC_OTG_LPM
782         .lpm_support = test_lpm_enabled,
783 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
784         .besl_support = test_besl_enabled,
785         .get_baseline_besl = get_param_baseline_besl,
786         .get_deep_besl = get_param_deep_besl,
787 #endif
788 #endif
789         .udc_start = dwc_otg_gadget_start,
790         .udc_stop = dwc_otg_gadget_stop,
791
792         /* current versions must always be self-powered */
793 };
794
795 static int _setup(dwc_otg_pcd_t *pcd, uint8_t *bytes)
796 {
797         int retval = -DWC_E_NOT_SUPPORTED;
798         if (gadget_wrapper->driver && gadget_wrapper->driver->setup) {
799                 retval = gadget_wrapper->driver->setup(&gadget_wrapper->gadget,
800                                                        (struct usb_ctrlrequest
801                                                         *)bytes);
802         }
803
804         if (retval == -ENOTSUPP) {
805                 retval = -DWC_E_NOT_SUPPORTED;
806         } else if (retval < 0) {
807                 retval = -DWC_E_INVALID;
808         }
809
810         return retval;
811 }
812
813 #ifdef DWC_EN_ISOC
814 static int _isoc_complete(dwc_otg_pcd_t *pcd, void *ep_handle,
815                           void *req_handle, int proc_buf_num)
816 {
817         int i, packet_count;
818         struct usb_gadget_iso_packet_descriptor *iso_packet = 0;
819         struct usb_iso_request *iso_req = req_handle;
820
821         if (proc_buf_num) {
822                 iso_packet = iso_req->iso_packet_desc1;
823         } else {
824                 iso_packet = iso_req->iso_packet_desc0;
825         }
826         packet_count =
827             dwc_otg_pcd_get_iso_packet_count(pcd, ep_handle, req_handle);
828         for (i = 0; i < packet_count; ++i) {
829                 int status;
830                 int actual;
831                 int offset;
832                 dwc_otg_pcd_get_iso_packet_params(pcd, ep_handle, req_handle,
833                                                   i, &status, &actual, &offset);
834                 switch (status) {
835                 case -DWC_E_NO_DATA:
836                         status = -ENODATA;
837                         break;
838                 default:
839                         if (status) {
840                                 DWC_PRINTF("unknown status in isoc packet\n");
841                         }
842
843                 }
844                 iso_packet[i].status = status;
845                 iso_packet[i].offset = offset;
846                 iso_packet[i].actual_length = actual;
847         }
848
849         iso_req->status = 0;
850         iso_req->process_buffer(ep_handle, iso_req);
851
852         return 0;
853 }
854 #endif /* DWC_EN_ISOC */
855
856 #ifdef DWC_UTE_PER_IO
857 /**
858  * Copy the contents of the extended request to the Linux usb_request's
859  * extended part and call the gadget's completion.
860  *
861  * @param pcd                   Pointer to the pcd structure
862  * @param ep_handle             Void pointer to the usb_ep structure
863  * @param req_handle    Void pointer to the usb_request structure
864  * @param status                Request status returned from the portable logic
865  * @param ereq_port             Void pointer to the extended request structure
866  *                                              created in the the portable part that contains the
867  *                                              results of the processed iso packets.
868  */
869 static int _xisoc_complete(dwc_otg_pcd_t *pcd, void *ep_handle,
870                            void *req_handle, int32_t status, void *ereq_port)
871 {
872         struct dwc_ute_iso_req_ext *ereqorg = NULL;
873         struct dwc_iso_xreq_port *ereqport = NULL;
874         struct dwc_ute_iso_packet_descriptor *desc_org = NULL;
875         int i;
876         struct usb_request *req;
877         /* struct dwc_ute_iso_packet_descriptor * */
878         /* int status = 0; */
879
880         req = (struct usb_request *)req_handle;
881         ereqorg = &req->ext_req;
882         ereqport = (struct dwc_iso_xreq_port *)ereq_port;
883         desc_org = ereqorg->per_io_frame_descs;
884
885         if (req && req->complete) {
886                 /* Copy the request data from the portable logic to our request */
887                 for (i = 0; i < ereqport->pio_pkt_count; i++) {
888                         desc_org[i].actual_length =
889                             ereqport->per_io_frame_descs[i].actual_length;
890                         desc_org[i].status =
891                             ereqport->per_io_frame_descs[i].status;
892                 }
893
894                 switch (status) {
895                 case -DWC_E_SHUTDOWN:
896                         req->status = -ESHUTDOWN;
897                         break;
898                 case -DWC_E_RESTART:
899                         req->status = -ECONNRESET;
900                         break;
901                 case -DWC_E_INVALID:
902                         req->status = -EINVAL;
903                         break;
904                 case -DWC_E_TIMEOUT:
905                         req->status = -ETIMEDOUT;
906                         break;
907                 default:
908                         req->status = status;
909                 }
910
911                 /* And call the gadget's completion */
912                 req->complete(ep_handle, req);
913         }
914
915         return 0;
916 }
917 #endif /* DWC_UTE_PER_IO */
918
919 static int _complete(dwc_otg_pcd_t *pcd, void *ep_handle,
920                      void *req_handle, int32_t status, uint32_t actual)
921 {
922         struct usb_request *req = (struct usb_request *)req_handle;
923         struct device *dev = NULL;
924 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27)
925         struct dwc_otg_pcd_ep *ep = NULL;
926 #endif
927
928         if (req && req->complete) {
929                 switch (status) {
930                 case -DWC_E_SHUTDOWN:
931                         req->status = -ESHUTDOWN;
932                         break;
933                 case -DWC_E_RESTART:
934                         req->status = -ECONNRESET;
935                         break;
936                 case -DWC_E_INVALID:
937                         req->status = -EINVAL;
938                         break;
939                 case -DWC_E_TIMEOUT:
940                         req->status = -ETIMEDOUT;
941                         break;
942                 default:
943                         req->status = status;
944
945                 }
946
947                 req->actual = actual;
948                 DWC_SPINUNLOCK(pcd->lock);
949                 req->complete(ep_handle, req);
950                 DWC_SPINLOCK(pcd->lock);
951         }
952
953         dev = &gadget_wrapper->pcd->otg_dev->os_dep.pdev->dev;
954         ep = ep_from_handle(pcd, ep_handle);
955
956         if (GET_CORE_IF(pcd)->dma_enable) {
957                 /* if (req->length != 0) */
958                 if (req->dma != DWC_DMA_ADDR_INVALID) {
959                         dma_unmap_single(gadget_wrapper->gadget.dev.parent,
960                                          req->dma, req->length,
961                                          ep->dwc_ep.is_in
962                                          ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
963                         req->dma = DWC_DMA_ADDR_INVALID;
964                 }
965         }
966         return 0;
967 }
968
969 static int _connect(dwc_otg_pcd_t *pcd, int speed)
970 {
971         gadget_wrapper->gadget.speed = speed;
972         return 0;
973 }
974
975 static int _disconnect(dwc_otg_pcd_t *pcd)
976 {
977         if (gadget_wrapper->driver && gadget_wrapper->driver->disconnect) {
978                 gadget_wrapper->driver->disconnect(&gadget_wrapper->gadget);
979         }
980         return 0;
981 }
982
983 static int _resume(dwc_otg_pcd_t *pcd)
984 {
985         if (gadget_wrapper->driver && gadget_wrapper->driver->resume) {
986                 gadget_wrapper->driver->resume(&gadget_wrapper->gadget);
987         }
988
989         return 0;
990 }
991
992 static int _suspend(dwc_otg_pcd_t *pcd)
993 {
994         if (gadget_wrapper->driver && gadget_wrapper->driver->suspend) {
995                 gadget_wrapper->driver->suspend(&gadget_wrapper->gadget);
996         }
997         return 0;
998 }
999
1000 /**
1001  * This function updates the otg values in the gadget structure.
1002  */
1003 static int _hnp_changed(dwc_otg_pcd_t *pcd)
1004 {
1005
1006         if (!gadget_wrapper->gadget.is_otg)
1007                 return 0;
1008
1009         gadget_wrapper->gadget.b_hnp_enable = get_b_hnp_enable(pcd);
1010         gadget_wrapper->gadget.a_hnp_support = get_a_hnp_support(pcd);
1011         gadget_wrapper->gadget.a_alt_hnp_support = get_a_alt_hnp_support(pcd);
1012         return 0;
1013 }
1014
1015 static int _reset(dwc_otg_pcd_t *pcd)
1016 {
1017         return 0;
1018 }
1019
1020 #ifdef DWC_UTE_CFI
1021 static int _cfi_setup(dwc_otg_pcd_t *pcd, void *cfi_req)
1022 {
1023         int retval = -DWC_E_INVALID;
1024         if (gadget_wrapper->driver->cfi_feature_setup) {
1025                 retval =
1026                     gadget_wrapper->driver->cfi_feature_setup(&gadget_wrapper->
1027                                                               gadget,
1028                                                               (struct
1029                                                                cfi_usb_ctrlrequest
1030                                                                *)cfi_req);
1031         }
1032
1033         return retval;
1034 }
1035 #endif
1036
1037 static const struct dwc_otg_pcd_function_ops fops = {
1038         .complete = _complete,
1039 #ifdef DWC_EN_ISOC
1040         .isoc_complete = _isoc_complete,
1041 #endif
1042         .setup = _setup,
1043         .disconnect = _disconnect,
1044         .connect = _connect,
1045         .resume = _resume,
1046         .suspend = _suspend,
1047         .hnp_changed = _hnp_changed,
1048         .reset = _reset,
1049 #ifdef DWC_UTE_CFI
1050         .cfi_setup = _cfi_setup,
1051 #endif
1052 #ifdef DWC_UTE_PER_IO
1053         .xisoc_complete = _xisoc_complete,
1054 #endif
1055 };
1056
1057 /**
1058  * This function is the top level PCD interrupt handler.
1059  */
1060 static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev)
1061 {
1062         dwc_otg_pcd_t *pcd = dev;
1063         int32_t retval = IRQ_NONE;
1064
1065         retval = dwc_otg_pcd_handle_intr(pcd);
1066         if (retval != 0) {
1067                 /* S3C2410X_CLEAR_EINTPEND();*/
1068         }
1069         return IRQ_RETVAL(retval);
1070 }
1071
1072 /**
1073  * This function initialized the usb_ep structures to there default
1074  * state.
1075  *
1076  * @param d Pointer on gadget_wrapper.
1077  */
1078 void gadget_add_eps(struct gadget_wrapper *d)
1079 {
1080         static const char *names[] = {
1081
1082                 "ep0",
1083                 "ep1in",
1084                 "ep2in",
1085                 "ep3in",
1086                 "ep4in",
1087                 "ep5in",
1088                 "ep6in",
1089                 "ep7in",
1090                 "ep8in",
1091                 "ep9in",
1092                 "ep10in",
1093                 "ep11in",
1094                 "ep12in",
1095                 "ep13in",
1096                 "ep14in",
1097                 "ep15in",
1098                 "ep1out",
1099                 "ep2out",
1100                 "ep3out",
1101                 "ep4out",
1102                 "ep5out",
1103                 "ep6out",
1104                 "ep7out",
1105                 "ep8out",
1106                 "ep9out",
1107                 "ep10out",
1108                 "ep11out",
1109                 "ep12out",
1110                 "ep13out",
1111                 "ep14out",
1112                 "ep15out"
1113         };
1114
1115         int i;
1116         struct usb_ep *ep;
1117         int8_t dev_endpoints;
1118
1119         DWC_DEBUGPL(DBG_PCDV, "%s\n", __func__);
1120
1121         INIT_LIST_HEAD(&d->gadget.ep_list);
1122         d->gadget.ep0 = &d->ep0;
1123         d->gadget.speed = USB_SPEED_UNKNOWN;
1124 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
1125         d->gadget.max_speed = USB_SPEED_HIGH;
1126 #endif
1127
1128         INIT_LIST_HEAD(&d->gadget.ep0->ep_list);
1129
1130         /**
1131          * Initialize the EP0 structure.
1132          */
1133         ep = &d->ep0;
1134
1135         /* Init the usb_ep structure. */
1136         ep->name = names[0];
1137         ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1138
1139         /**
1140          * @todo NGS: What should the max packet size be set to
1141          * here?  Before EP type is set?
1142          */
1143         ep->maxpacket = MAX_PACKET_SIZE;
1144         dwc_otg_pcd_ep_enable(d->pcd, NULL, ep);
1145
1146         list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1147
1148         /**
1149          * Initialize the EP structures.
1150          */
1151         dev_endpoints = d->pcd->core_if->dev_if->num_in_eps;
1152
1153         for (i = 0; i < dev_endpoints; i++) {
1154                 ep = &d->in_ep[i];
1155
1156                 /* Init the usb_ep structure. */
1157                 ep->name = names[d->pcd->in_ep[i].dwc_ep.num];
1158                 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1159
1160                 /**
1161                  * @todo NGS: What should the max packet size be set to
1162                  * here?  Before EP type is set?
1163                  */
1164                 ep->maxpacket = MAX_PACKET_SIZE;
1165                 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1166         }
1167
1168         dev_endpoints = d->pcd->core_if->dev_if->num_out_eps;
1169
1170         for (i = 0; i < dev_endpoints; i++) {
1171                 ep = &d->out_ep[i];
1172
1173                 /* Init the usb_ep structure. */
1174                 ep->name = names[15 + d->pcd->out_ep[i].dwc_ep.num];
1175                 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1176
1177                 /**
1178                  * @todo NGS: What should the max packet size be set to
1179                  * here?  Before EP type is set?
1180                  */
1181                 ep->maxpacket = MAX_PACKET_SIZE;
1182
1183                 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1184         }
1185
1186         /* remove ep0 from the list.  There is a ep0 pointer. */
1187         list_del_init(&d->ep0.ep_list);
1188
1189         d->ep0.maxpacket = MAX_EP0_SIZE;
1190 }
1191
1192 /**
1193  * This function releases the Gadget device.
1194  * required by device_unregister().
1195  *
1196  * @todo Should this do something?      Should it free the PCD?
1197  */
1198 static void dwc_otg_pcd_gadget_release(struct device *dev)
1199 {
1200         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
1201 }
1202
1203 static struct gadget_wrapper *alloc_wrapper(struct platform_device *_dev)
1204 {
1205         static char pcd_name[] = "dwc_otg_pcd";
1206
1207         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1208         struct gadget_wrapper *d;
1209         int retval;
1210
1211         d = DWC_ALLOC(sizeof(*d));
1212         if (d == NULL) {
1213                 return NULL;
1214         }
1215
1216         memset(d, 0, sizeof(*d));
1217
1218         d->gadget.name = pcd_name;
1219         d->pcd = otg_dev->pcd;
1220
1221 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
1222         strcpy(d->gadget.dev.bus_id, "gadget");
1223 #else
1224         dev_set_name(&d->gadget.dev, "%s", "gadget");
1225 #endif
1226
1227         d->gadget.dev.parent = &_dev->dev;
1228         d->gadget.dev.release = dwc_otg_pcd_gadget_release;
1229         d->gadget.ops = &dwc_otg_pcd_ops;
1230 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
1231         d->gadget.is_dualspeed = dwc_otg_pcd_is_dualspeed(otg_dev->pcd);
1232 #endif
1233         d->gadget.is_otg = dwc_otg_pcd_is_otg(otg_dev->pcd);
1234
1235         d->gadget.max_speed = USB_SPEED_HIGH;
1236         d->driver = 0;
1237         d->pcd->conn_en = 0;
1238         /* Register the gadget device */
1239         retval = usb_add_gadget_udc(&_dev->dev, &d->gadget);
1240         if (retval != 0) {
1241                 DWC_ERROR("device_register failed\n");
1242                 DWC_FREE(d);
1243                 return NULL;
1244         }
1245
1246         return d;
1247 }
1248
1249 static void free_wrapper(struct gadget_wrapper *d)
1250 {
1251         if (d->driver) {
1252                 /* should have been done already by driver model core */
1253                 DWC_WARN("driver '%s' is still registered\n",
1254                          d->driver->driver.name);
1255                 usb_gadget_unregister_driver(d->driver);
1256         }
1257
1258         usb_del_gadget_udc(&d->gadget);
1259         DWC_FREE(d);
1260 }
1261
1262 static void dwc_otg_pcd_work_init(dwc_otg_pcd_t *pcd,
1263                                   struct platform_device *dev);
1264
1265 /**
1266  * This function initialized the PCD portion of the driver.
1267  *
1268  */
1269 int pcd_init(struct platform_device *_dev)
1270 {
1271
1272         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1273
1274         int retval = 0;
1275         int irq;
1276         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1277
1278         otg_dev->pcd = dwc_otg_pcd_init(otg_dev->core_if);
1279         printk("pcd_init otg_dev = %p\n", otg_dev);
1280
1281         if (!otg_dev->pcd) {
1282                 DWC_ERROR("dwc_otg_pcd_init failed\n");
1283                 return -ENOMEM;
1284         }
1285
1286         otg_dev->pcd->otg_dev = otg_dev;
1287         gadget_wrapper = alloc_wrapper(_dev);
1288
1289         /*
1290          * Initialize EP structures
1291          */
1292         gadget_add_eps(gadget_wrapper);
1293         /*
1294          * Setup interupt handler
1295          */
1296         irq = platform_get_irq(_dev, 0);
1297         DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", irq);
1298         retval = request_irq(irq, dwc_otg_pcd_irq,
1299                              IRQF_SHARED,
1300                              gadget_wrapper->gadget.name, otg_dev->pcd);
1301         if (retval != 0) {
1302                 DWC_ERROR("request of irq%d failed\n", irq);
1303                 free_wrapper(gadget_wrapper);
1304                 return -EBUSY;
1305         }
1306
1307         dwc_otg_pcd_start(gadget_wrapper->pcd, &fops);
1308
1309         dwc_otg_pcd_work_init(otg_dev->pcd, _dev);
1310
1311         return retval;
1312 }
1313
1314 /**
1315  * Cleanup the PCD.
1316  */
1317 void pcd_remove(struct platform_device *_dev)
1318 {
1319
1320         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1321         dwc_otg_pcd_t *pcd = otg_dev->pcd;
1322         int irq;
1323
1324         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1325
1326         /*
1327          * Free the IRQ
1328          */
1329         irq = platform_get_irq(_dev, 0);
1330         free_irq(irq, pcd);
1331         free_wrapper(gadget_wrapper);
1332         dwc_otg_pcd_remove(otg_dev->pcd);
1333         otg_dev->pcd = 0;
1334 }
1335
1336 /**
1337  * This function registers a gadget driver with the PCD.
1338  *
1339  * When a driver is successfully registered, it will receive control
1340  * requests including set_configuration(), which enables non-control
1341  * requests.  then usb traffic follows until a disconnect is reported.
1342  * then a host may connect again, or the driver might get unbound.
1343  *
1344  * @param driver The driver being registered
1345  * @param bind The bind function of gadget driver
1346  */
1347 #if 0
1348 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
1349 int usb_gadget_register_driver(struct usb_gadget_driver *driver)
1350 #else
1351 int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
1352                             int (*bind) (struct usb_gadget *))
1353 #endif
1354 {
1355         int retval;
1356
1357         DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n",
1358                     driver->driver.name);
1359
1360         if (!driver ||
1361 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
1362             driver->speed == USB_SPEED_UNKNOWN ||
1363 #else
1364             driver->max_speed == USB_SPEED_UNKNOWN ||
1365 #endif
1366 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
1367             !driver->bind ||
1368 #else
1369             !bind ||
1370 #endif
1371             !driver->unbind || !driver->disconnect || !driver->setup) {
1372                 DWC_DEBUGPL(DBG_PCDV, "EINVAL\n");
1373                 return -EINVAL;
1374         }
1375         if (gadget_wrapper == 0) {
1376                 DWC_DEBUGPL(DBG_PCDV, "ENODEV\n");
1377                 return -ENODEV;
1378         }
1379         if (gadget_wrapper->driver != 0) {
1380                 DWC_DEBUGPL(DBG_PCDV, "EBUSY (%p)\n", gadget_wrapper->driver);
1381                 return -EBUSY;
1382         }
1383
1384         /* hook up the driver */
1385         gadget_wrapper->driver = driver;
1386         gadget_wrapper->gadget.dev.driver = &driver->driver;
1387
1388         DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
1389 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
1390         retval = driver->bind(&gadget_wrapper->gadget);
1391 #else
1392         retval = bind(&gadget_wrapper->gadget);
1393 #endif
1394         if (retval) {
1395                 DWC_ERROR("bind to driver %s --> error %d\n",
1396                           driver->driver.name, retval);
1397                 gadget_wrapper->driver = 0;
1398                 gadget_wrapper->gadget.dev.driver = 0;
1399                 return retval;
1400         }
1401         DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
1402                     driver->driver.name);
1403         return 0;
1404 }
1405
1406 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
1407 EXPORT_SYMBOL(usb_gadget_register_driver);
1408 #else
1409 EXPORT_SYMBOL(usb_gadget_probe_driver);
1410 #endif
1411
1412 /**
1413  * This function unregisters a gadget driver
1414  *
1415  * @param driver The driver being unregistered
1416  */
1417 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1418 {
1419         /* DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver); */
1420
1421         if (gadget_wrapper == 0) {
1422                 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
1423                             -ENODEV);
1424                 return -ENODEV;
1425         }
1426         if (driver == 0 || driver != gadget_wrapper->driver) {
1427                 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
1428                             -EINVAL);
1429                 return -EINVAL;
1430         }
1431
1432         driver->unbind(&gadget_wrapper->gadget);
1433         gadget_wrapper->driver = 0;
1434
1435         DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n", driver->driver.name);
1436         return 0;
1437 }
1438
1439 EXPORT_SYMBOL(usb_gadget_unregister_driver);
1440
1441 #endif
1442
1443 /************************ for RK platform ************************/
1444
1445 void dwc_otg_msc_lock(dwc_otg_pcd_t *pcd)
1446 {
1447         unsigned long flags;
1448         local_irq_save(flags);
1449         wake_lock(&pcd->wake_lock);
1450         local_irq_restore(flags);
1451 }
1452
1453 void dwc_otg_msc_unlock(dwc_otg_pcd_t *pcd)
1454 {
1455         unsigned long flags;
1456         local_irq_save(flags);
1457         wake_unlock(&pcd->wake_lock);
1458         local_irq_restore(flags);
1459 }
1460
1461 unsigned int dwc_otg_battery_detect(bool det_type)
1462 {
1463         printk("%s\n", __func__);
1464         return 0;
1465 }
1466
1467 static void dwc_phy_reconnect(struct work_struct *work)
1468 {
1469         dwc_otg_pcd_t *pcd;
1470         dwc_otg_core_if_t *core_if;
1471         gotgctl_data_t gctrl;
1472         dctl_data_t dctl = {.d32 = 0 };
1473         struct dwc_otg_platform_data *pldata;
1474
1475         pcd = container_of(work, dwc_otg_pcd_t, reconnect.work);
1476         pldata = pcd->otg_dev->pldata;
1477         core_if = GET_CORE_IF(pcd);
1478         gctrl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
1479
1480         if (gctrl.b.bsesvld) {
1481                 pcd->conn_status++;
1482                 pldata->soft_reset();
1483                 dwc_pcd_reset(pcd);
1484                 /*
1485                  * Enable the global interrupt after all the interrupt
1486                  * handlers are installed.
1487                  */
1488                 dctl.d32 =
1489                     DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
1490                 dctl.b.sftdiscon = 0;
1491                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
1492                                 dctl.d32);
1493                 printk
1494                     ("*******************soft connect!!!*******************\n");
1495         }
1496 }
1497
1498 static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
1499 {
1500         dwc_otg_pcd_t *_pcd =
1501             container_of(work, dwc_otg_pcd_t, check_vbus_work.work);
1502         struct dwc_otg_device *otg_dev = _pcd->otg_dev;
1503         struct dwc_otg_platform_data *pldata = otg_dev->pldata;
1504         unsigned long flags;
1505
1506         local_irq_save(flags);
1507
1508         if (!pldata->get_status(USB_STATUS_ID)) {
1509                 /* id low, host mode */
1510                 if (pldata->dwc_otg_uart_mode != NULL) {
1511                         /* exit phy bypass to uart & enable usb phy */
1512                         pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
1513                 }
1514                 if (pldata->phy_status) {
1515                         pldata->clock_enable(pldata, 1);
1516                         pldata->phy_suspend(pldata, USB_PHY_ENABLED);
1517                 }
1518                 if (pldata->bc_detect_cb != NULL)
1519                         pldata->bc_detect_cb(_pcd->vbus_status =
1520                                              USB_BC_TYPE_DISCNT);
1521                 else
1522                         _pcd->vbus_status = USB_BC_TYPE_DISCNT;
1523                 dwc_otg_enable_global_interrupts(otg_dev->core_if);
1524
1525         } else if (pldata->get_status(USB_STATUS_BVABLID)) {
1526                 /* if usb not connect before ,then start connect */
1527                 if (_pcd->vbus_status == USB_BC_TYPE_DISCNT) {
1528                         printk("*****************vbus detect*******************\n");
1529                         /* if( pldata->bc_detect_cb != NULL ) */
1530                         /*      pldata->bc_detect_cb(_pcd->vbus_status */
1531                         /*                           = usb_battery_charger_detect(1)); */
1532                         /* else */
1533                         _pcd->vbus_status = USB_BC_TYPE_SDP;
1534                         if (_pcd->conn_en) {
1535                                 goto connect;
1536                         } else if (pldata->phy_status == USB_PHY_ENABLED) {
1537                                 /* do not allow to connect, suspend phy */
1538                                 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1539                                 udelay(3);
1540                                 pldata->clock_enable(pldata, 0);
1541                         }
1542                 } else if ((_pcd->conn_en) && (_pcd->conn_status >= 0)
1543                            && (_pcd->conn_status < 2)) {
1544                         printk("****************soft reconnect******************\n");
1545                         goto connect;
1546                 } else if (_pcd->conn_status == 2) {
1547                         /* release pcd->wake_lock if fail to connect,
1548                          * allow system to enter second sleep.
1549                          */
1550                         dwc_otg_msc_unlock(_pcd);
1551                         _pcd->conn_status++;
1552                         if (pldata->bc_detect_cb != NULL) {
1553                                 rk_usb_charger_status = USB_BC_TYPE_DCP;
1554                                 pldata->bc_detect_cb(_pcd->vbus_status =
1555                                                      USB_BC_TYPE_DCP);
1556                         } else {
1557                                 _pcd->vbus_status = USB_BC_TYPE_DCP;
1558                                 rk_usb_charger_status = USB_BC_TYPE_DCP;
1559                         }
1560                         /* fail to connect, suspend usb phy and disable clk */
1561                         if (pldata->phy_status == USB_PHY_ENABLED) {
1562                                 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1563                                 udelay(3);
1564                                 pldata->clock_enable(pldata, 0);
1565                         }
1566                 }
1567         } else {
1568                 if (pldata->bc_detect_cb != NULL)
1569                         pldata->bc_detect_cb(_pcd->vbus_status =
1570                                              USB_BC_TYPE_DISCNT);
1571                 else
1572                         _pcd->vbus_status = USB_BC_TYPE_DISCNT;
1573
1574                 if (_pcd->conn_status) {
1575                         _pcd->conn_status = 0;
1576                 }
1577
1578                 if (pldata->phy_status == USB_PHY_ENABLED) {
1579                         /* release wake lock */
1580                         dwc_otg_msc_unlock(_pcd);
1581                         /* no vbus detect here , close usb phy  */
1582                         pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1583                         udelay(3);
1584                         pldata->clock_enable(pldata, 0);
1585                 }
1586
1587                 /* usb phy bypass to uart mode  */
1588                 if (pldata->dwc_otg_uart_mode != NULL)
1589                         pldata->dwc_otg_uart_mode(pldata, PHY_UART_MODE);
1590         }
1591
1592         schedule_delayed_work(&_pcd->check_vbus_work, HZ);
1593         local_irq_restore(flags);
1594
1595         return;
1596
1597 connect:
1598         if (pldata->phy_status) {
1599                 pldata->clock_enable(pldata, 1);
1600                 pldata->phy_suspend(pldata, USB_PHY_ENABLED);
1601         }
1602
1603         if (_pcd->conn_status == 0)
1604                 dwc_otg_msc_lock(_pcd);
1605
1606         schedule_delayed_work(&_pcd->reconnect, 8);     /* delay 8 jiffies */
1607         schedule_delayed_work(&_pcd->check_vbus_work, (HZ << 2));
1608         local_irq_restore(flags);
1609
1610         return;
1611 }
1612
1613 void dwc_otg_pcd_start_check_vbus_work(dwc_otg_pcd_t *pcd)
1614 {
1615         /*
1616          * when receive reset int,the vbus state may not be update,so
1617          * always start vbus work here.
1618          */
1619         schedule_delayed_work(&pcd->check_vbus_work, (HZ * 2));
1620 }
1621
1622 /*
1623 * 20091228,HSL@RK,to get the current vbus status.
1624 */
1625 int dwc_vbus_status(void)
1626 {
1627 #ifdef CONFIG_USB20_OTG
1628         dwc_otg_pcd_t *pcd = 0;
1629         if (gadget_wrapper) {
1630                 pcd = gadget_wrapper->pcd;
1631         }
1632
1633         if (!pcd)
1634                 return 0;
1635         else
1636                 return pcd->vbus_status;
1637 #else
1638         return 0;
1639 #endif
1640 }
1641
1642 EXPORT_SYMBOL(dwc_vbus_status);
1643
1644 static void dwc_otg_pcd_work_init(dwc_otg_pcd_t *pcd,
1645                                   struct platform_device *dev)
1646 {
1647
1648         struct dwc_otg_device *otg_dev = pcd->otg_dev;
1649         pcd->vbus_status = USB_BC_TYPE_DISCNT;
1650         pcd->phy_suspend = USB_PHY_ENABLED;
1651 #ifdef CONFIG_RK_USB_UART
1652         struct dwc_otg_platform_data *pldata = otg_dev->pldata;
1653 #endif
1654
1655         INIT_DELAYED_WORK(&pcd->reconnect, dwc_phy_reconnect);
1656         INIT_DELAYED_WORK(&pcd->check_vbus_work, dwc_otg_pcd_check_vbus_work);
1657
1658         wake_lock_init(&pcd->wake_lock, WAKE_LOCK_SUSPEND, "usb_pcd");
1659
1660         if (dwc_otg_is_device_mode(pcd->core_if) &&
1661             (otg_dev->core_if->usb_mode != USB_MODE_FORCE_HOST)) {
1662 #ifdef CONFIG_RK_USB_UART
1663                 if (pldata->get_status(USB_STATUS_BVABLID)) {
1664                         /* enter usb phy mode */
1665                         pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
1666                 } else {
1667                         /* usb phy bypass to uart mode */
1668                         pldata->dwc_otg_uart_mode(pldata, PHY_UART_MODE);
1669                 }
1670 #endif
1671                 schedule_delayed_work(&pcd->check_vbus_work, (HZ << 4));
1672         }
1673 #ifdef CONFIG_RK_USB_UART
1674         else if (pldata->dwc_otg_uart_mode != NULL)
1675                 /* host mode,enter usb phy mode */
1676                 pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
1677 #endif
1678
1679 }
1680
1681 #endif /* DWC_HOST_ONLY */