1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_linux.c $
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.
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.
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
32 * ========================================================================== */
36 * This file implements the Peripheral Controller Driver.
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
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.)
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>.
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"
63 #include "usbdev_rk.h"
65 static struct gadget_wrapper {
68 struct usb_gadget gadget;
69 struct usb_gadget_driver *driver;
72 struct usb_ep in_ep[16];
73 struct usb_ep out_ep[16];
77 /* Display the contents of the buffer */
78 extern void dump_msg(const u8 * buf, unsigned int length);
81 * Get the dwc_otg_pcd_ep_t* from usb_ep* pointer - NULL in case
82 * if the endpoint is not found
84 static struct dwc_otg_pcd_ep *ep_from_handle(dwc_otg_pcd_t * pcd, void *handle)
87 if (pcd->ep0.priv == handle) {
91 for (i = 0; i < MAX_EPS_CHANNELS - 1; i++) {
92 if (pcd->in_ep[i].priv == handle)
93 return &pcd->in_ep[i];
94 if (pcd->out_ep[i].priv == handle)
95 return &pcd->out_ep[i];
101 /* USB Endpoint Operations */
103 * The following sections briefly describe the behavior of the Gadget
104 * API endpoint operations implemented in the DWC_otg driver
105 * software. Detailed descriptions of the generic behavior of each of
106 * these functions can be found in the Linux header file
107 * include/linux/usb_gadget.h.
109 * The Gadget API provides wrapper functions for each of the function
110 * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper
111 * function, which then calls the underlying PCD function. The
112 * following sections are named according to the wrapper
113 * functions. Within each section, the corresponding DWC_otg PCD
114 * function name is specified.
119 * This function is called by the Gadget Driver for each EP to be
120 * configured for the current configuration (SET_CONFIGURATION).
122 * This function initializes the dwc_otg_ep_t data structure, and then
123 * calls dwc_otg_ep_activate.
125 static int ep_enable(struct usb_ep *usb_ep,
126 const struct usb_endpoint_descriptor *ep_desc)
130 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, ep_desc);
132 if (!usb_ep || !ep_desc || ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
133 DWC_WARN("%s, bad ep or descriptor\n", __func__);
136 if (usb_ep == &gadget_wrapper->ep0) {
137 DWC_WARN("%s, bad ep(0)\n", __func__);
141 /* Check FIFO size? */
142 if (!ep_desc->wMaxPacketSize) {
143 DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name);
147 if (!gadget_wrapper->driver ||
148 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
149 DWC_WARN("%s, bogus device state\n", __func__);
153 /* Delete after check - MAS */
155 nat = (uint32_t) ep_desc->wMaxPacketSize;
156 printk(KERN_ALERT "%s: nat (before) =%d\n", __func__, nat);
157 nat = (nat >> 11) & 0x03;
158 printk(KERN_ALERT "%s: nat (after) =%d\n", __func__, nat);
160 retval = dwc_otg_pcd_ep_enable(gadget_wrapper->pcd,
161 (const uint8_t *)ep_desc,
164 DWC_WARN("dwc_otg_pcd_ep_enable failed\n");
168 usb_ep->maxpacket = le16_to_cpu(ep_desc->wMaxPacketSize);
174 * This function is called when an EP is disabled due to disconnect or
175 * change in configuration. Any pending requests will terminate with a
176 * status of -ESHUTDOWN.
178 * This function modifies the dwc_otg_ep_t data structure for this EP,
179 * and then calls dwc_otg_ep_deactivate.
181 static int ep_disable(struct usb_ep *usb_ep)
185 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, usb_ep);
187 DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
188 usb_ep ? usb_ep->name : NULL);
192 retval = dwc_otg_pcd_ep_disable(gadget_wrapper->pcd, usb_ep);
201 * This function allocates a request object to use with the specified
204 * @param ep The endpoint to be used with with the request
205 * @param gfp_flags the GFP_* flags to use.
207 static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
210 struct usb_request *usb_req;
212 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d)\n", __func__, ep, gfp_flags);
214 DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
217 usb_req = kmalloc(sizeof(*usb_req), gfp_flags);
219 DWC_WARN("%s() %s\n", __func__, "request allocation failed!\n");
222 memset(usb_req, 0, sizeof(*usb_req));
223 usb_req->dma = DWC_DMA_ADDR_INVALID;
229 * This function frees a request object.
231 * @param ep The endpoint associated with the request
232 * @param req The request being freed
234 static void dwc_otg_pcd_free_request(struct usb_ep *ep, struct usb_request *req)
236 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, ep, req);
238 if (0 == ep || 0 == req) {
239 DWC_WARN("%s() %s\n", __func__,
240 "Invalid ep or req argument!\n");
247 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
249 * This function allocates an I/O buffer to be used for a transfer
250 * to/from the specified endpoint.
252 * @param usb_ep The endpoint to be used with with the request
253 * @param bytes The desired number of bytes for the buffer
254 * @param dma Pointer to the buffer's DMA address; must be valid
255 * @param gfp_flags the GFP_* flags to use.
256 * @return address of a new buffer or null is buffer could not be allocated.
258 static void *dwc_otg_pcd_alloc_buffer(struct usb_ep *usb_ep, unsigned bytes,
259 dma_addr_t * dma, gfp_t gfp_flags)
262 dwc_otg_pcd_t *pcd = 0;
264 pcd = gadget_wrapper->pcd;
266 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d,%p,%0x)\n", __func__, usb_ep, bytes,
269 /* Check dword alignment */
270 if ((bytes & 0x3UL) != 0) {
271 DWC_WARN("%s() Buffer size is not a multiple of"
272 "DWORD size (%d)", __func__, bytes);
275 buf = dma_alloc_coherent(NULL, bytes, dma, gfp_flags);
277 /* Check dword alignment */
278 if (((int)buf & 0x3UL) != 0) {
279 DWC_WARN("%s() Buffer is not DWORD aligned (%p)",
287 * This function frees an I/O buffer that was allocated by alloc_buffer.
289 * @param usb_ep the endpoint associated with the buffer
290 * @param buf address of the buffer
291 * @param dma The buffer's DMA address
292 * @param bytes The number of bytes of the buffer
294 static void dwc_otg_pcd_free_buffer(struct usb_ep *usb_ep, void *buf,
295 dma_addr_t dma, unsigned bytes)
297 dwc_otg_pcd_t *pcd = 0;
299 pcd = gadget_wrapper->pcd;
301 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%0x,%d)\n", __func__, buf, dma, bytes);
303 dma_free_coherent(NULL, bytes, buf, dma);
308 * This function is used to submit an I/O Request to an EP.
310 * - When the request completes the request's completion callback
311 * is called to return the request to the driver.
312 * - An EP, except control EPs, may have multiple requests
314 * - Once submitted the request cannot be examined or modified.
315 * - Each request is turned into one or more packets.
316 * - A BULK EP can queue any amount of data; the transfer is
318 * - Zero length Packets are specified with the request 'zero'
321 static int ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req,
325 struct dwc_otg_pcd_ep *ep = NULL;
326 int retval = 0, is_isoc_ep = 0;
327 dma_addr_t dma_addr = DWC_DMA_ADDR_INVALID;
329 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p,%d)\n",
330 __func__, usb_ep, usb_req, gfp_flags);
332 if (!usb_req || !usb_req->complete || !usb_req->buf) {
333 DWC_WARN("bad params\n");
338 DWC_WARN("bad ep\n");
342 pcd = gadget_wrapper->pcd;
343 if (!gadget_wrapper->driver ||
344 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
345 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
346 gadget_wrapper->gadget.speed);
347 DWC_WARN("bogus device state\n");
351 DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
352 usb_ep->name, usb_req, usb_req->length, usb_req->buf);
354 usb_req->status = -EINPROGRESS;
357 ep = ep_from_handle(pcd, usb_ep);
361 is_isoc_ep = (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) ? 1 : 0;
362 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
363 dma_addr = usb_req->dma;
365 if (GET_CORE_IF(pcd)->dma_enable) {
366 // if (usb_req->length != 0/* && usb_req->dma == DWC_DMA_ADDR_INVALID*/) {
367 if(usb_req->dma == DWC_DMA_ADDR_INVALID){
368 dma_addr = dma_map_single(gadget_wrapper->gadget.dev.parent,
369 usb_req->buf, usb_req->length,
373 usb_req->dma = dma_addr;
379 #ifdef DWC_UTE_PER_IO
380 if (is_isoc_ep == 1) {
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,
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);
404 * This function cancels an I/O request from an EP.
406 static int ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req)
408 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, usb_req);
410 if (!usb_ep || !usb_req) {
411 DWC_WARN("bad argument\n");
414 if (!gadget_wrapper->driver ||
415 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
416 DWC_WARN("bogus device state\n");
419 if (dwc_otg_pcd_ep_dequeue(gadget_wrapper->pcd, usb_ep, usb_req)) {
427 * usb_ep_set_halt stalls an endpoint.
429 * usb_ep_clear_halt clears an endpoint halt and resets its data
432 * Both of these functions are implemented with the same underlying
433 * function. The behavior depends on the value argument.
435 * @param[in] usb_ep the Endpoint to halt or clear halt.
437 * - 0 means clear_halt.
438 * - 1 means set_halt,
439 * - 2 means clear stall lock flag.
440 * - 3 means set stall lock flag.
442 static int ep_halt(struct usb_ep *usb_ep, int value)
446 DWC_DEBUGPL(DBG_PCD, "HALT %s %d\n", usb_ep->name, value);
449 DWC_WARN("bad ep\n");
453 retval = dwc_otg_pcd_ep_halt(gadget_wrapper->pcd, usb_ep, value);
454 if (retval == -DWC_E_AGAIN) {
463 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
464 static int ep_wedge(struct usb_ep *usb_ep)
466 DWC_DEBUGPL(DBG_PCD, "WEDGE %s\n", usb_ep->name);
468 return ep_halt(usb_ep, 3);
474 * This function is used to submit an ISOC Transfer Request to an EP.
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..
482 static int iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
487 if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
488 DWC_WARN("bad params\n");
493 DWC_PRINTF("bad params\n");
497 req->status = -EINPROGRESS;
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,
505 flags & USB_REQ_ISO_ASAP ? -1 :
506 req->start_frame, req->buf_proc_intrvl,
507 req, gfp_flags == GFP_ATOMIC ? 1 : 0);
517 * This function stops ISO EP Periodic Data Transfer.
519 static int iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
523 DWC_WARN("bad ep\n");
526 if (!gadget_wrapper->driver ||
527 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
528 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
529 gadget_wrapper->gadget.speed);
530 DWC_WARN("bogus device state\n");
533 dwc_otg_pcd_iso_ep_stop(gadget_wrapper->pcd, usb_ep, req);
541 static struct usb_iso_request *alloc_iso_request(struct usb_ep *ep,
542 int packets, gfp_t gfp_flags)
544 struct usb_iso_request *pReq = NULL;
547 req_size = sizeof(struct usb_iso_request);
549 (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
551 pReq = kmalloc(req_size, gfp_flags);
553 DWC_WARN("Can't allocate Iso Request\n");
556 pReq->iso_packet_desc0 = (void *)(pReq + 1);
558 pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
563 static void free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
568 static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops = {
571 .disable = ep_disable,
573 .alloc_request = dwc_otg_pcd_alloc_request,
574 .free_request = dwc_otg_pcd_free_request,
576 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
577 .alloc_buffer = dwc_otg_pcd_alloc_buffer,
578 .free_buffer = dwc_otg_pcd_free_buffer,
582 .dequeue = ep_dequeue,
586 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
587 .set_wedge = ep_wedge,
593 .iso_ep_start = iso_ep_start,
594 .iso_ep_stop = iso_ep_stop,
595 .alloc_iso_request = alloc_iso_request,
596 .free_iso_request = free_iso_request,
601 static struct usb_ep_ops dwc_otg_pcd_ep_ops = {
603 .disable = ep_disable,
605 .alloc_request = dwc_otg_pcd_alloc_request,
606 .free_request = dwc_otg_pcd_free_request,
608 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
609 .alloc_buffer = dwc_otg_pcd_alloc_buffer,
610 .free_buffer = dwc_otg_pcd_free_buffer,
614 .dequeue = ep_dequeue,
618 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
619 .set_wedge = ep_wedge,
627 #endif /* _EN_ISOC_ */
628 /* Gadget Operations */
630 * The following gadget operations will be implemented in the DWC_otg
631 * PCD. Functions in the API that are not described below are not
634 * The Gadget API provides wrapper functions for each of the function
635 * pointers defined in usb_gadget_ops. The Gadget Driver calls the
636 * wrapper function, which then calls the underlying PCD function. The
637 * following sections are named according to the wrapper functions
638 * (except for ioctl, which doesn't have a wrapper function). Within
639 * each section, the corresponding DWC_otg PCD function name is
645 *Gets the USB Frame number of the last SOF.
647 static int get_frame_number(struct usb_gadget *gadget)
649 struct gadget_wrapper *d;
651 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
657 d = container_of(gadget, struct gadget_wrapper, gadget);
658 return dwc_otg_pcd_get_frame_number(d->pcd);
661 #ifdef CONFIG_USB_DWC_OTG_LPM
662 static int test_lpm_enabled(struct usb_gadget *gadget)
664 struct gadget_wrapper *d;
666 d = container_of(gadget, struct gadget_wrapper, gadget);
668 return dwc_otg_pcd_is_lpm_enabled(d->pcd);
670 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
671 static int test_besl_enabled(struct usb_gadget *gadget)
673 struct gadget_wrapper *d;
675 d = container_of(gadget, struct gadget_wrapper, gadget);
677 return dwc_otg_pcd_is_besl_enabled(d->pcd);
679 static int get_param_baseline_besl(struct usb_gadget *gadget)
681 struct gadget_wrapper *d;
683 d = container_of(gadget, struct gadget_wrapper, gadget);
685 return dwc_otg_pcd_get_param_baseline_besl(d->pcd);
687 static int get_param_deep_besl(struct usb_gadget *gadget)
689 struct gadget_wrapper *d;
691 d = container_of(gadget, struct gadget_wrapper, gadget);
693 return dwc_otg_pcd_get_param_deep_besl(d->pcd);
699 * Initiates Session Request Protocol (SRP) to wakeup the host if no
700 * session is in progress. If a session is already in progress, but
701 * the device is suspended, remote wakeup signaling is started.
704 static int wakeup(struct usb_gadget *gadget)
706 struct gadget_wrapper *d;
708 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
713 d = container_of(gadget, struct gadget_wrapper, gadget);
715 dwc_otg_pcd_wakeup(d->pcd);
718 static int dwc_otg_pcd_pullup(struct usb_gadget *_gadget, int is_on)
720 struct gadget_wrapper *d;
722 dwc_otg_core_if_t *core_if;
724 printk( "pcd_pullup, is_on %d\n",is_on);
728 d = container_of(_gadget, struct gadget_wrapper, gadget);
730 core_if = GET_CORE_IF(d->pcd);
734 //dwc_otg_pcd_pullup_enable(pcd);
736 pcd->conn_status = 0;
738 dwc_otg_pcd_pullup_disable(pcd);
739 pcd->conn_status = 2;
746 static int dwc_otg_gadget_start(struct usb_gadget *g,
747 struct usb_gadget_driver *driver)
749 DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", driver->driver.name);
750 if (gadget_wrapper == 0){
751 DWC_ERROR("ENODEV\n");
754 if (gadget_wrapper->driver != 0){
755 DWC_ERROR("EBUSY (%p)\n", gadget_wrapper->driver);
758 /* hook up the driver */
759 gadget_wrapper->driver = driver;
760 gadget_wrapper->gadget.dev.driver = &driver->driver;
762 DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
767 static int dwc_otg_gadget_stop(struct usb_gadget *g,
768 struct usb_gadget_driver *driver)
773 static const struct usb_gadget_ops dwc_otg_pcd_ops = {
774 .get_frame = get_frame_number,
776 .pullup = dwc_otg_pcd_pullup,
777 #ifdef CONFIG_USB_DWC_OTG_LPM
778 .lpm_support = test_lpm_enabled,
779 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
780 .besl_support = test_besl_enabled,
781 .get_baseline_besl = get_param_baseline_besl,
782 .get_deep_besl = get_param_deep_besl,
785 .udc_start = dwc_otg_gadget_start,
786 .udc_stop = dwc_otg_gadget_stop,
788 // current versions must always be self-powered
793 static int _setup(dwc_otg_pcd_t * pcd, uint8_t * bytes)
795 int retval = -DWC_E_NOT_SUPPORTED;
796 if (gadget_wrapper->driver && gadget_wrapper->driver->setup) {
797 retval = gadget_wrapper->driver->setup(&gadget_wrapper->gadget,
798 (struct usb_ctrlrequest
802 if (retval == -ENOTSUPP) {
803 retval = -DWC_E_NOT_SUPPORTED;
804 } else if (retval < 0) {
805 retval = -DWC_E_INVALID;
812 static int _isoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle,
813 void *req_handle, int proc_buf_num)
816 struct usb_gadget_iso_packet_descriptor *iso_packet = 0;
817 struct usb_iso_request *iso_req = req_handle;
820 iso_packet = iso_req->iso_packet_desc1;
822 iso_packet = iso_req->iso_packet_desc0;
825 dwc_otg_pcd_get_iso_packet_count(pcd, ep_handle, req_handle);
826 for (i = 0; i < packet_count; ++i) {
830 dwc_otg_pcd_get_iso_packet_params(pcd, ep_handle, req_handle,
831 i, &status, &actual, &offset);
838 DWC_PRINTF("unknown status in isoc packet\n");
842 iso_packet[i].status = status;
843 iso_packet[i].offset = offset;
844 iso_packet[i].actual_length = actual;
848 iso_req->process_buffer(ep_handle, iso_req);
852 #endif /* DWC_EN_ISOC */
854 #ifdef DWC_UTE_PER_IO
856 * Copy the contents of the extended request to the Linux usb_request's
857 * extended part and call the gadget's completion.
859 * @param pcd Pointer to the pcd structure
860 * @param ep_handle Void pointer to the usb_ep structure
861 * @param req_handle Void pointer to the usb_request structure
862 * @param status Request status returned from the portable logic
863 * @param ereq_port Void pointer to the extended request structure
864 * created in the the portable part that contains the
865 * results of the processed iso packets.
867 static int _xisoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle,
868 void *req_handle, int32_t status, void *ereq_port)
870 struct dwc_ute_iso_req_ext *ereqorg = NULL;
871 struct dwc_iso_xreq_port *ereqport = NULL;
872 struct dwc_ute_iso_packet_descriptor *desc_org = NULL;
874 struct usb_request *req;
875 //struct dwc_ute_iso_packet_descriptor *
878 req = (struct usb_request *)req_handle;
879 ereqorg = &req->ext_req;
880 ereqport = (struct dwc_iso_xreq_port *)ereq_port;
881 desc_org = ereqorg->per_io_frame_descs;
883 if (req && req->complete) {
884 /* Copy the request data from the portable logic to our request */
885 for (i = 0; i < ereqport->pio_pkt_count; i++) {
886 desc_org[i].actual_length =
887 ereqport->per_io_frame_descs[i].actual_length;
889 ereqport->per_io_frame_descs[i].status;
893 case -DWC_E_SHUTDOWN:
894 req->status = -ESHUTDOWN;
897 req->status = -ECONNRESET;
900 req->status = -EINVAL;
903 req->status = -ETIMEDOUT;
906 req->status = status;
909 /* And call the gadget's completion */
910 req->complete(ep_handle, req);
915 #endif /* DWC_UTE_PER_IO */
917 static int _complete(dwc_otg_pcd_t * pcd, void *ep_handle,
918 void *req_handle, int32_t status, uint32_t actual)
920 struct usb_request *req = (struct usb_request *)req_handle;
921 struct device * dev = NULL;
922 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27)
923 struct dwc_otg_pcd_ep *ep = NULL;
926 if (req && req->complete) {
928 case -DWC_E_SHUTDOWN:
929 req->status = -ESHUTDOWN;
932 req->status = -ECONNRESET;
935 req->status = -EINVAL;
938 req->status = -ETIMEDOUT;
941 req->status = status;
945 req->actual = actual;
946 DWC_SPINUNLOCK(pcd->lock);
947 req->complete(ep_handle, req);
948 DWC_SPINLOCK(pcd->lock);
951 dev = &gadget_wrapper->pcd->otg_dev->os_dep.pdev->dev;
952 ep = ep_from_handle(pcd, ep_handle);
954 if (GET_CORE_IF(pcd)->dma_enable) {
955 // if (req->length != 0)
956 if(req->dma != DWC_DMA_ADDR_INVALID){
957 dma_unmap_single(gadget_wrapper->gadget.dev.parent,
958 req->dma, req->length,
962 req->dma = DWC_DMA_ADDR_INVALID;
968 static int _connect(dwc_otg_pcd_t * pcd, int speed)
970 gadget_wrapper->gadget.speed = speed;
974 static int _disconnect(dwc_otg_pcd_t * pcd)
976 if (gadget_wrapper->driver && gadget_wrapper->driver->disconnect) {
977 gadget_wrapper->driver->disconnect(&gadget_wrapper->gadget);
982 static int _resume(dwc_otg_pcd_t * pcd)
984 if (gadget_wrapper->driver && gadget_wrapper->driver->resume) {
985 gadget_wrapper->driver->resume(&gadget_wrapper->gadget);
991 static int _suspend(dwc_otg_pcd_t * pcd)
993 if (gadget_wrapper->driver && gadget_wrapper->driver->suspend) {
994 gadget_wrapper->driver->suspend(&gadget_wrapper->gadget);
1000 * This function updates the otg values in the gadget structure.
1002 static int _hnp_changed(dwc_otg_pcd_t * pcd)
1005 if (!gadget_wrapper->gadget.is_otg)
1008 gadget_wrapper->gadget.b_hnp_enable = get_b_hnp_enable(pcd);
1009 gadget_wrapper->gadget.a_hnp_support = get_a_hnp_support(pcd);
1010 gadget_wrapper->gadget.a_alt_hnp_support = get_a_alt_hnp_support(pcd);
1014 static int _reset(dwc_otg_pcd_t * pcd)
1020 static int _cfi_setup(dwc_otg_pcd_t * pcd, void *cfi_req)
1022 int retval = -DWC_E_INVALID;
1023 if (gadget_wrapper->driver->cfi_feature_setup) {
1025 gadget_wrapper->driver->
1026 cfi_feature_setup(&gadget_wrapper->gadget,
1027 (struct cfi_usb_ctrlrequest *)cfi_req);
1034 static const struct dwc_otg_pcd_function_ops fops = {
1035 .complete = _complete,
1037 .isoc_complete = _isoc_complete,
1040 .disconnect = _disconnect,
1041 .connect = _connect,
1043 .suspend = _suspend,
1044 .hnp_changed = _hnp_changed,
1047 .cfi_setup = _cfi_setup,
1049 #ifdef DWC_UTE_PER_IO
1050 .xisoc_complete = _xisoc_complete,
1055 * This function is the top level PCD interrupt handler.
1057 static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev)
1059 dwc_otg_pcd_t *pcd = dev;
1060 int32_t retval = IRQ_NONE;
1062 retval = dwc_otg_pcd_handle_intr(pcd);
1064 //S3C2410X_CLEAR_EINTPEND();
1066 return IRQ_RETVAL(retval);
1070 * This function initialized the usb_ep structures to there default
1073 * @param d Pointer on gadget_wrapper.
1075 void gadget_add_eps(struct gadget_wrapper *d)
1077 static const char *names[] = {
1114 int8_t dev_endpoints;
1116 DWC_DEBUGPL(DBG_PCDV, "%s\n", __func__);
1118 INIT_LIST_HEAD(&d->gadget.ep_list);
1119 d->gadget.ep0 = &d->ep0;
1120 d->gadget.speed = USB_SPEED_UNKNOWN;
1121 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
1122 d->gadget.max_speed = USB_SPEED_HIGH;
1125 INIT_LIST_HEAD(&d->gadget.ep0->ep_list);
1128 * Initialize the EP0 structure.
1132 /* Init the usb_ep structure. */
1133 ep->name = names[0];
1134 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1137 * @todo NGS: What should the max packet size be set to
1138 * here? Before EP type is set?
1140 ep->maxpacket = MAX_PACKET_SIZE;
1141 dwc_otg_pcd_ep_enable(d->pcd, NULL, ep);
1143 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1146 * Initialize the EP structures.
1148 dev_endpoints = d->pcd->core_if->dev_if->num_in_eps;
1150 for (i = 0; i < dev_endpoints; i++) {
1153 /* Init the usb_ep structure. */
1154 ep->name = names[d->pcd->in_ep[i].dwc_ep.num];
1155 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1158 * @todo NGS: What should the max packet size be set to
1159 * here? Before EP type is set?
1161 ep->maxpacket = MAX_PACKET_SIZE;
1162 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1165 dev_endpoints = d->pcd->core_if->dev_if->num_out_eps;
1167 for (i = 0; i < dev_endpoints; i++) {
1170 /* Init the usb_ep structure. */
1171 ep->name = names[15 + d->pcd->out_ep[i].dwc_ep.num];
1172 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1175 * @todo NGS: What should the max packet size be set to
1176 * here? Before EP type is set?
1178 ep->maxpacket = MAX_PACKET_SIZE;
1180 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1183 /* remove ep0 from the list. There is a ep0 pointer. */
1184 list_del_init(&d->ep0.ep_list);
1186 d->ep0.maxpacket = MAX_EP0_SIZE;
1190 * This function releases the Gadget device.
1191 * required by device_unregister().
1193 * @todo Should this do something? Should it free the PCD?
1195 static void dwc_otg_pcd_gadget_release(struct device *dev)
1197 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
1200 static struct gadget_wrapper *alloc_wrapper(
1202 struct platform_device *_dev
1205 static char pcd_name[] = "dwc_otg_pcd";
1207 dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1208 struct gadget_wrapper *d;
1211 d = DWC_ALLOC(sizeof(*d));
1216 memset(d, 0, sizeof(*d));
1218 d->gadget.name = pcd_name;
1219 d->pcd = otg_dev->pcd;
1221 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
1222 strcpy(d->gadget.dev.bus_id, "gadget");
1224 dev_set_name(&d->gadget.dev, "%s", "gadget");
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);
1233 d->gadget.is_otg = dwc_otg_pcd_is_otg(otg_dev->pcd);
1235 d->gadget.max_speed = USB_SPEED_HIGH;
1237 d->pcd->conn_en = 0;
1238 /* Register the gadget device */
1239 retval = usb_add_gadget_udc(&_dev->dev, &d->gadget);
1241 DWC_ERROR("device_register failed\n");
1249 static void free_wrapper(struct gadget_wrapper *d)
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);
1258 usb_del_gadget_udc(&d->gadget);
1262 static void dwc_otg_pcd_work_init(dwc_otg_pcd_t *pcd, struct platform_device *dev);
1265 * This function initialized the PCD portion of the driver.
1268 int pcd_init(struct platform_device *_dev)
1271 dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1275 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1277 otg_dev->pcd = dwc_otg_pcd_init(otg_dev->core_if);
1278 printk("pcd_init otg_dev = %p\n",otg_dev);
1280 if (!otg_dev->pcd) {
1281 DWC_ERROR("dwc_otg_pcd_init failed\n");
1285 otg_dev->pcd->otg_dev = otg_dev;
1286 gadget_wrapper = alloc_wrapper(_dev);
1289 * Initialize EP structures
1291 gadget_add_eps(gadget_wrapper);
1293 * Setup interupt handler
1295 irq = platform_get_irq(_dev,0);
1296 DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", irq);
1297 retval = request_irq(irq, dwc_otg_pcd_irq,
1299 gadget_wrapper->gadget.name, otg_dev->pcd);
1301 DWC_ERROR("request of irq%d failed\n", irq);
1302 free_wrapper(gadget_wrapper);
1306 dwc_otg_pcd_start(gadget_wrapper->pcd, &fops);
1308 dwc_otg_pcd_work_init(otg_dev->pcd, _dev);
1318 struct platform_device *_dev
1322 dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
1323 dwc_otg_pcd_t *pcd = otg_dev->pcd;
1326 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1331 irq = platform_get_irq(_dev,0);
1333 free_wrapper(gadget_wrapper);
1334 dwc_otg_pcd_remove(otg_dev->pcd);
1339 * This function registers a gadget driver with the PCD.
1341 * When a driver is successfully registered, it will receive control
1342 * requests including set_configuration(), which enables non-control
1343 * requests. then usb traffic follows until a disconnect is reported.
1344 * then a host may connect again, or the driver might get unbound.
1346 * @param driver The driver being registered
1347 * @param bind The bind function of gadget driver
1350 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
1351 int usb_gadget_register_driver(struct usb_gadget_driver *driver)
1353 int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
1354 int (*bind)(struct usb_gadget *))
1359 DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n",
1360 driver->driver.name);
1363 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
1364 driver->speed == USB_SPEED_UNKNOWN ||
1366 driver->max_speed == USB_SPEED_UNKNOWN ||
1368 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
1373 !driver->unbind || !driver->disconnect || !driver->setup) {
1374 DWC_DEBUGPL(DBG_PCDV, "EINVAL\n");
1377 if (gadget_wrapper == 0) {
1378 DWC_DEBUGPL(DBG_PCDV, "ENODEV\n");
1381 if (gadget_wrapper->driver != 0) {
1382 DWC_DEBUGPL(DBG_PCDV, "EBUSY (%p)\n", gadget_wrapper->driver);
1386 /* hook up the driver */
1387 gadget_wrapper->driver = driver;
1388 gadget_wrapper->gadget.dev.driver = &driver->driver;
1390 DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
1391 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
1392 retval = driver->bind(&gadget_wrapper->gadget);
1394 retval = bind(&gadget_wrapper->gadget);
1397 DWC_ERROR("bind to driver %s --> error %d\n",
1398 driver->driver.name, retval);
1399 gadget_wrapper->driver = 0;
1400 gadget_wrapper->gadget.dev.driver = 0;
1403 DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
1404 driver->driver.name);
1407 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
1408 EXPORT_SYMBOL(usb_gadget_register_driver);
1410 EXPORT_SYMBOL(usb_gadget_probe_driver);
1414 * This function unregisters a gadget driver
1416 * @param driver The driver being unregistered
1418 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1420 //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver);
1422 if (gadget_wrapper == 0) {
1423 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
1427 if (driver == 0 || driver != gadget_wrapper->driver) {
1428 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
1433 driver->unbind(&gadget_wrapper->gadget);
1434 gadget_wrapper->driver = 0;
1436 DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n", driver->driver.name);
1440 EXPORT_SYMBOL(usb_gadget_unregister_driver);
1444 /************************ for RK platform ************************/
1446 void dwc_otg_msc_lock(dwc_otg_pcd_t *pcd)
1448 unsigned long flags;
1449 local_irq_save(flags);
1450 wake_lock(&pcd->wake_lock);
1451 local_irq_restore(flags);
1454 void dwc_otg_msc_unlock(dwc_otg_pcd_t *pcd)
1456 unsigned long flags;
1457 local_irq_save(flags);
1458 wake_unlock(&pcd->wake_lock);
1459 local_irq_restore(flags);
1462 unsigned int dwc_otg_battery_detect(bool det_type)
1464 printk("%s\n",__func__);
1468 static void dwc_phy_reconnect(struct work_struct *work)
1471 dwc_otg_core_if_t *core_if;
1472 gotgctl_data_t gctrl;
1473 dctl_data_t dctl = {.d32=0};
1475 pcd = container_of(work, dwc_otg_pcd_t, reconnect.work);
1476 core_if = GET_CORE_IF(pcd);
1477 gctrl.d32 = DWC_READ_REG32( &core_if->core_global_regs->gotgctl );
1479 if(gctrl.b.bsesvld){
1483 * Enable the global interrupt after all the interrupt
1484 * handlers are installed.
1486 dctl.d32 = DWC_READ_REG32( &core_if->dev_if->dev_global_regs->dctl );
1487 dctl.b.sftdiscon = 0;
1488 DWC_WRITE_REG32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
1489 printk("*******************soft connect!!!*******************\n");
1493 static void dwc_otg_pcd_check_vbus_work( struct work_struct *work )
1495 dwc_otg_pcd_t * _pcd = container_of(work, dwc_otg_pcd_t, check_vbus_work.work);
1496 struct dwc_otg_device* otg_dev = _pcd->otg_dev;
1497 struct dwc_otg_platform_data *pldata = otg_dev->pldata;
1498 unsigned long flags;
1500 local_irq_save(flags);
1502 if(!pldata->get_status(USB_STATUS_ID)){
1503 // id low, host mode
1504 if( pldata->dwc_otg_uart_mode != NULL ){
1505 //exit phy bypass to uart & enable usb phy
1506 pldata->dwc_otg_uart_mode( pldata, PHY_USB_MODE);
1508 if( pldata->phy_status){
1509 pldata->clock_enable( pldata, 1);
1510 pldata->phy_suspend(pldata, USB_PHY_ENABLED);
1512 dwc_otg_enable_global_interrupts(otg_dev->core_if);
1514 }else if(pldata->get_status(USB_STATUS_BVABLID)){
1515 /* if usb not connect before ,then start connect */
1516 if( _pcd->vbus_status == 0 ) {
1517 printk("*******************vbus detect*********************\n");
1518 _pcd->vbus_status = 1;
1522 else if( pldata->phy_status == USB_PHY_ENABLED ){
1523 // do not allow to connect, suspend phy
1524 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1526 pldata->clock_enable( pldata, 0);
1528 }else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <2)){
1529 printk("******************soft reconnect********************\n");
1531 }else if(_pcd->conn_status == 2){
1532 /* release pcd->wake_lock if fail to connect,
1533 * allow system to enter second sleep.
1535 dwc_otg_msc_unlock(_pcd);
1536 _pcd->conn_status++;
1537 if((DWC_READ_REG32((uint32_t*)((uint8_t *)_pcd->otg_dev->os_dep.base
1538 + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
1539 _pcd->vbus_status = 2;
1541 /* fail to connect, suspend usb phy and disable clk */
1542 if( pldata->phy_status == USB_PHY_ENABLED ){
1543 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1545 pldata->clock_enable( pldata, 0);
1549 _pcd->vbus_status = 0;
1551 if(_pcd->conn_status){
1552 _pcd->conn_status = 0;
1555 if( pldata->phy_status == USB_PHY_ENABLED ){
1556 /* no vbus detect here , close usb phy */
1557 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
1559 pldata->clock_enable( pldata, 0);
1560 /* usb phy bypass to uart mode */
1561 if( pldata->dwc_otg_uart_mode != NULL )
1562 pldata->dwc_otg_uart_mode( pldata, PHY_UART_MODE);
1563 /* release wake lock */
1564 dwc_otg_msc_unlock(_pcd);
1568 schedule_delayed_work(&_pcd->check_vbus_work, HZ);
1569 local_irq_restore(flags);
1574 if(_pcd->conn_status==0)
1575 dwc_otg_msc_lock(_pcd);
1577 if( pldata->phy_status)
1579 pldata->clock_enable(pldata, 1);
1580 pldata->phy_suspend(pldata, USB_PHY_ENABLED);
1583 schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 8 jiffies */
1584 schedule_delayed_work(&_pcd->check_vbus_work, (HZ<<2));
1585 local_irq_restore(flags);
1590 void dwc_otg_pcd_start_check_vbus_work(dwc_otg_pcd_t * pcd)
1593 * when receive reset int,the vbus state may not be update,so
1594 * always start vbus work here.
1596 schedule_delayed_work(&pcd->check_vbus_work, (HZ*2));
1600 * 20091228,HSL@RK,to get the current vbus status.
1602 int dwc_vbus_status( void )
1604 dwc_otg_pcd_t *pcd = 0;
1605 pcd = gadget_wrapper->pcd;
1610 return pcd->vbus_status ;
1613 EXPORT_SYMBOL(dwc_vbus_status);
1615 static void dwc_otg_pcd_work_init(dwc_otg_pcd_t *pcd, struct platform_device *dev)
1618 struct dwc_otg_device* otg_dev = pcd->otg_dev;
1619 struct dwc_otg_platform_data *pldata = otg_dev->pldata;
1620 pcd->vbus_status = 0;
1621 pcd->phy_suspend = 0;
1623 INIT_DELAYED_WORK(&pcd->reconnect , dwc_phy_reconnect);
1624 INIT_DELAYED_WORK(&pcd->check_vbus_work , dwc_otg_pcd_check_vbus_work);
1626 wake_lock_init(&pcd->wake_lock, WAKE_LOCK_SUSPEND,"usb_pcd");
1628 if(dwc_otg_is_device_mode(pcd->core_if)){
1629 #ifdef CONFIG_RK_USB_UART
1630 if(pldata->get_status(USB_STATUS_BVABLID)){
1631 //enter usb phy mode
1632 pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
1634 //usb phy bypass to uart mode
1635 pldata->phy_suspend(pldata,USB_PHY_SUSPEND);
1636 pldata->dwc_otg_uart_mode(pldata, PHY_UART_MODE);
1639 schedule_delayed_work(&pcd->check_vbus_work, (HZ<<4));
1641 #ifdef CONFIG_RK_USB_UART
1642 else if(pldata->dwc_otg_uart_mode != NULL)
1643 //host mode,enter usb phy mode
1644 pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
1649 #endif /* DWC_HOST_ONLY */