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 <asm/errno.h>
57 #include <linux/list.h>
58 #include <linux/string.h>
63 #include <asm/arch/ldo.h>
64 #include <linux/usb/ch9.h>
65 #include <linux/usb/gadget.h>
67 #include "dwc_otg_driver.h"
68 #include "dwc_otg_pcd_if.h"
69 #include "dwc_otg_dbg.h"
71 static struct gadget_wrapper {
74 struct usb_gadget gadget;
75 struct usb_gadget_driver *driver;
78 struct usb_ep in_ep[16];
79 struct usb_ep out_ep[16];
83 /* Display the contents of the buffer */
84 extern void dump_msg(const u8 * buf, unsigned int length);
86 /* USB Endpoint Operations */
88 * The following sections briefly describe the behavior of the Gadget
89 * API endpoint operations implemented in the DWC_otg driver
90 * software. Detailed descriptions of the generic behavior of each of
91 * these functions can be found in the Linux header file
92 * include/linux/usb_gadget.h.
94 * The Gadget API provides wrapper functions for each of the function
95 * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper
96 * function, which then calls the underlying PCD function. The
97 * following sections are named according to the wrapper
98 * functions. Within each section, the corresponding DWC_otg PCD
99 * function name is specified.
104 * This function is called by the Gadget Driver for each EP to be
105 * configured for the current configuration (SET_CONFIGURATION).
107 * This function initializes the dwc_otg_ep_t data structure, and then
108 * calls dwc_otg_ep_activate.
110 static int ep_enable(struct usb_ep *usb_ep,
111 const struct usb_endpoint_descriptor *ep_desc)
115 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, ep_desc);
117 if (!usb_ep || !ep_desc || ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
118 DWC_WARN("%s, bad ep or descriptor\n", __func__);
121 if (usb_ep == &gadget_wrapper->ep0) {
122 DWC_WARN("%s, bad ep(0)\n", __func__);
126 /* Check FIFO size? */
127 if (!ep_desc->wMaxPacketSize) {
128 DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name);
132 if (!gadget_wrapper->driver ||
133 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
134 DWC_WARN("%s, bogus device state\n", __func__);
138 retval = dwc_otg_pcd_ep_enable(gadget_wrapper->pcd,
139 (const uint8_t *)ep_desc,
142 DWC_WARN("dwc_otg_pcd_ep_enable failed\n");
146 usb_ep->maxpacket = le16_to_cpu(ep_desc->wMaxPacketSize);
152 * This function is called when an EP is disabled due to disconnect or
153 * change in configuration. Any pending requests will terminate with a
154 * status of -ESHUTDOWN.
156 * This function modifies the dwc_otg_ep_t data structure for this EP,
157 * and then calls dwc_otg_ep_deactivate.
159 static int ep_disable(struct usb_ep *usb_ep)
163 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, usb_ep);
165 DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
166 usb_ep ? usb_ep->name : NULL);
170 retval = dwc_otg_pcd_ep_disable(gadget_wrapper->pcd, usb_ep);
179 * This function allocates a request object to use with the specified
182 * @param ep The endpoint to be used with with the request
183 * @param gfp_flags the GFP_* flags to use.
185 static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
188 struct usb_request *usb_req;
190 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d)\n", __func__, ep, gfp_flags);
192 DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
195 usb_req = dwc_alloc(sizeof(*usb_req));
197 DWC_WARN("%s() %s\n", __func__, "request allocation failed!\n");
200 memset(usb_req, 0, sizeof(*usb_req));
201 usb_req->dma = DWC_INVALID_DMA_ADDR;
207 * This function frees a request object.
209 * @param ep The endpoint associated with the request
210 * @param req The request being freed
212 static void dwc_otg_pcd_free_request(struct usb_ep *ep, struct usb_request *req)
214 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, ep, req);
216 if (0 == ep || 0 == req) {
217 DWC_WARN("%s() %s\n", __func__,
218 "Invalid ep or req argument!\n");
226 * This function is used to submit an I/O Request to an EP.
228 * - When the request completes the request's completion callback
229 * is called to return the request to the driver.
230 * - An EP, except control EPs, may have multiple requests
232 * - Once submitted the request cannot be examined or modified.
233 * - Each request is turned into one or more packets.
234 * - A BULK EP can queue any amount of data; the transfer is
236 * - Zero length Packets are specified with the request 'zero'
239 static int ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req,
245 //dwc_debug("(%p,%p,%d)\n",
246 // usb_ep, usb_req, gfp_flags);
248 if (!usb_req || !usb_req->complete || !usb_req->buf) {
249 DWC_WARN("bad params\n");
254 DWC_WARN("bad ep\n");
258 pcd = gadget_wrapper->pcd;
259 if (!gadget_wrapper->driver ||
260 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
261 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
262 gadget_wrapper->gadget.speed);
263 DWC_WARN("bogus device state\n");
267 DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
268 usb_ep->name, usb_req, usb_req->length, usb_req->buf);
269 usb_req->status = -EINPROGRESS;
272 retval = dwc_otg_pcd_ep_queue(pcd, usb_ep, usb_req->buf, usb_req->dma,
273 usb_req->length, usb_req->zero, usb_req,
275 //gfp_flags == GFP_ATOMIC ? 1 : 0);
284 * This function cancels an I/O request from an EP.
286 static int ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req)
289 if (!usb_ep || !usb_req) {
290 DWC_WARN("bad argument\n");
293 if (!gadget_wrapper->driver ||
294 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
295 DWC_WARN("bogus device state\n");
298 if (dwc_otg_pcd_ep_dequeue(gadget_wrapper->pcd, usb_ep, usb_req)) {
306 * usb_ep_set_halt stalls an endpoint.
308 * usb_ep_clear_halt clears an endpoint halt and resets its data
311 * Both of these functions are implemented with the same underlying
312 * function. The behavior depends on the value argument.
314 * @param[in] usb_ep the Endpoint to halt or clear halt.
316 * - 0 means clear_halt.
317 * - 1 means set_halt,
318 * - 2 means clear stall lock flag.
319 * - 3 means set stall lock flag.
321 static int ep_halt(struct usb_ep *usb_ep, int value)
325 DWC_DEBUGPL(DBG_PCD, "HALT %s %d\n", usb_ep->name, value);
328 DWC_WARN("bad ep\n");
332 retval = dwc_otg_pcd_ep_halt(gadget_wrapper->pcd, usb_ep, value);
333 if (retval == -DWC_E_AGAIN) {
344 * This function is used to submit an ISOC Transfer Request to an EP.
346 * - Every time a sync period completes the request's completion callback
347 * is called to provide data to the gadget driver.
348 * - Once submitted the request cannot be modified.
349 * - Each request is turned into periodic data packets untill ISO
350 * Transfer is stopped..
352 static int iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
357 if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
358 DWC_WARN("bad params\n");
363 DWC_DEBUGPL(DBG_CIL,"bad params\n");
367 req->status = -EINPROGRESS;
370 dwc_otg_pcd_iso_ep_start(gadget_wrapper->pcd, usb_ep, req->buf0,
371 req->buf1, req->dma0, req->dma1,
372 req->sync_frame, req->data_pattern_frame,
374 req->flags & USB_REQ_ISO_ASAP ? -1 : req->
375 start_frame, req->buf_proc_intrvl, req,
376 gfp_flags == GFP_ATOMIC ? 1 : 0);
386 * This function stops ISO EP Periodic Data Transfer.
388 static int iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
392 DWC_WARN("bad ep\n");
395 if (!gadget_wrapper->driver ||
396 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
397 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
398 gadget_wrapper->gadget.speed);
399 DWC_WARN("bogus device state\n");
402 dwc_otg_pcd_iso_ep_stop(gadget_wrapper->pcd, usb_ep, req);
410 static struct usb_iso_request *alloc_iso_request(struct usb_ep *ep,
411 int packets, gfp_t gfp_flags)
413 struct usb_iso_request *pReq = NULL;
416 req_size = sizeof(struct usb_iso_request);
418 (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
420 pReq = dwc_alloc(req_size);
422 DWC_WARN("Can't allocate Iso Request\n");
425 pReq->iso_packet_desc0 = (void *)(pReq + 1);
427 pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
432 static void free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
437 static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops = {
440 .disable = ep_disable,
442 .alloc_request = dwc_otg_pcd_alloc_request,
443 .free_request = dwc_otg_pcd_free_request,
445 .alloc_buffer = dwc_otg_pcd_alloc_buffer,
446 .free_buffer = dwc_otg_pcd_free_buffer,
449 .dequeue = ep_dequeue,
455 .iso_ep_start = iso_ep_start,
456 .iso_ep_stop = iso_ep_stop,
457 .alloc_iso_request = alloc_iso_request,
458 .free_iso_request = free_iso_request,
463 static struct usb_ep_ops dwc_otg_pcd_ep_ops = {
465 .disable = ep_disable,
467 .alloc_request = dwc_otg_pcd_alloc_request,
468 .free_request = dwc_otg_pcd_free_request,
471 .dequeue = ep_dequeue,
479 #endif /* _EN_ISOC_ */
480 /* Gadget Operations */
482 * The following gadget operations will be implemented in the DWC_otg
483 * PCD. Functions in the API that are not described below are not
486 * The Gadget API provides wrapper functions for each of the function
487 * pointers defined in usb_gadget_ops. The Gadget Driver calls the
488 * wrapper function, which then calls the underlying PCD function. The
489 * following sections are named according to the wrapper functions
490 * (except for ioctl, which doesn't have a wrapper function). Within
491 * each section, the corresponding DWC_otg PCD function name is
497 *Gets the USB Frame number of the last SOF.
499 static int get_frame_number(struct usb_gadget *gadget)
501 struct gadget_wrapper *d;
503 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
509 d = container_of(gadget, struct gadget_wrapper, gadget);
510 return dwc_otg_pcd_get_frame_number(d->pcd);
513 #ifdef CONFIG_USB_DWC_OTG_LPM
514 static int test_lpm_enabled(struct usb_gadget *gadget)
516 struct gadget_wrapper *d;
518 d = container_of(gadget, struct gadget_wrapper, gadget);
520 return dwc_otg_pcd_is_lpm_enabled(d->pcd);
525 #include <asm/arch/regs_ahb.h>
526 #include <asm/arch/ldo.h>
527 #include <asm/arch/regs_global.h>
530 static void __raw_bits_and(unsigned int v, unsigned int a)
532 __raw_writel((__raw_readl(a) & v), a);
536 static void __raw_bits_or(unsigned int v, unsigned int a)
538 __raw_writel((__raw_readl(a) | v), a);
541 extern void __udelay (unsigned long usec);
543 void usb_ldo_switch(int flag)
546 LDO_TurnOnLDO(LDO_LDO_USB);
549 LDO_TurnOffLDO(LDO_LDO_USB);
553 static void usb_enable_module(int en)
556 #if defined( CONFIG_SC8830) || defined(CONFIG_SC9630)
557 __raw_bits_or(BIT_4, AHB_CTL0);
559 __raw_bits_or(BIT_6, AHB_CTL3);
560 __raw_bits_and(~BIT_9, GR_CLK_GEN5);
562 //__raw_bits_or(BIT_5, AHB_CTL0);
564 #if defined( CONFIG_SC8830) || defined(CONFIG_SC9630)
565 __raw_bits_and(~BIT_4, AHB_CTL0);
567 __raw_bits_and(~BIT_6, AHB_CTL3);
568 __raw_bits_or(BIT_9, GR_CLK_GEN5);
569 __raw_bits_and(~BIT_5, AHB_CTL0);
573 static void usb_startup(void)
575 usb_enable_module(1);
578 #if defined( CONFIG_SC8830) || defined(CONFIG_SC9630)
580 __raw_bits_and(~BIT_1, AHB_CTL3);
581 __raw_bits_and(~BIT_2, AHB_CTL3);
584 #if defined(CONFIG_SPX20)
588 #if defined( CONFIG_SC8830) || defined(CONFIG_SC9630)
589 #if defined(CONFIG_SPX20)
590 __raw_bits_or(BIT_4, AHB_CTL0);
591 __raw_bits_or(BIT_5|BIT_6, AHB_SOFT_RST);
593 __raw_bits_and(~(BIT_5|BIT_6), AHB_SOFT_RST);
595 __raw_bits_or(BIT_3, USB_GUSBCFG);//SPRD USB PHY width: 16 bit
597 __raw_bits_and(~BIT_0, AP_TOP_USB_PHY_RST_PIN_CTL);//utmi_porn
598 __raw_bits_or(BIT_7, AHB_SOFT_RST);//utmi_rst
600 __raw_bits_or(BIT_0, AP_TOP_USB_PHY_RST_PIN_CTL);
601 __raw_bits_and(~BIT_7, AHB_SOFT_RST);
603 __raw_bits_or(BIT_4, AHB_CTL0);
604 __raw_bits_or(BIT_5|BIT_6|BIT_7, AHB_SOFT_RST);
606 __raw_bits_and(~(BIT_5|BIT_6|BIT_7), AHB_SOFT_RST);
610 __raw_bits_or(BIT_6, AHB_CTL3);
611 __raw_bits_or(BIT_6|BIT_7, AHB_SOFT_RST);
613 __raw_bits_and(~(BIT_6|BIT_7), AHB_SOFT_RST);
615 __raw_bits_or(BIT_5, AHB_CTL0);
620 static void udc_disable(void)
622 usb_enable_module(0);
626 void udc_power_on(void)
628 if(readl(CHIP_ID) == 0x88100001){
629 /*SMIC chip id == 0x88100001*/
630 __raw_bits_or(BIT_9, USB_PHY_CTRL);
631 __raw_bits_and(~(BIT_15 | BIT_14), USB_PHY_CTRL);
632 __raw_bits_or(BIT_13 | BIT_12, USB_PHY_CTRL);
633 writel(0x28,USB_SPR_REG);
636 * config usb phy controller
638 /*SMIC chip id == 0x88100001*/
639 #ifdef CONFIG_SC7710G2
640 __raw_bits_or(BIT_9, USB_PHY_CTRL);
641 __raw_bits_and(~(BIT_15 | BIT_14), USB_PHY_CTRL);
642 __raw_bits_or(BIT_13 | BIT_12, USB_PHY_CTRL);
643 writel(0x28,USB_SPR_REG);
645 __raw_bits_or(BIT_8, USB_PHY_CTRL);
646 __raw_bits_or(BIT_17, USB_PHY_CTRL);
647 __raw_bits_and(~BIT_16, USB_PHY_CTRL);
648 __raw_bits_and(~(BIT_13 | BIT_12), USB_PHY_CTRL);
649 __raw_bits_or(BIT_15 | BIT_14, USB_PHY_CTRL);
656 void udc_power_off(void)
661 * Initiates Session Request Protocol (SRP) to wakeup the host if no
662 * session is in progress. If a session is already in progress, but
663 * the device is suspended, remote wakeup signaling is started.
666 static int wakeup(struct usb_gadget *gadget)
668 struct gadget_wrapper *d;
670 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
675 d = container_of(gadget, struct gadget_wrapper, gadget);
677 dwc_otg_pcd_wakeup(d->pcd);
681 static const struct usb_gadget_ops dwc_otg_pcd_ops = {
682 .get_frame = get_frame_number,
684 // current versions must always be self-powered
687 static int _setup(dwc_otg_pcd_t * pcd, uint8_t * bytes)
689 int retval = -DWC_E_NOT_SUPPORTED;
690 if (gadget_wrapper->driver && gadget_wrapper->driver->setup) {
691 retval = gadget_wrapper->driver->setup(&gadget_wrapper->gadget,
692 (struct usb_ctrlrequest
697 //if (retval == -ENOTSUPP) {
698 if (retval == -EOPNOTSUPP) {
699 retval = -DWC_E_NOT_SUPPORTED;
700 } else if (retval < 0) {
701 retval = -DWC_E_INVALID;
708 static int _isoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle,
709 void *req_handle, int proc_buf_num)
712 struct usb_gadget_iso_packet_descriptor *iso_packet = 0;
713 struct usb_iso_request *iso_req = req_handle;
716 iso_packet = iso_req->iso_packet_desc1;
718 iso_packet = iso_req->iso_packet_desc0;
721 dwc_otg_pcd_get_iso_packet_count(pcd, ep_handle, req_handle);
722 for (i = 0; i < packet_count; ++i) {
726 dwc_otg_pcd_get_iso_packet_params(pcd, ep_handle, req_handle,
727 i, &status, &actual, &offset);
734 DWC_DEBUGPL(DBG_CIL,"unknown status in isoc packet\n");
738 iso_packet[i].status = status;
739 iso_packet[i].offset = offset;
740 iso_packet[i].actual_length = actual;
744 iso_req->process_buffer(ep_handle, iso_req);
748 #endif /* DWC_EN_ISOC */
750 static int _complete(dwc_otg_pcd_t * pcd, void *ep_handle,
751 void *req_handle, int32_t status, uint32_t actual)
753 struct usb_request *req = (struct usb_request *)req_handle;
755 if (req && req->complete) {
757 case -DWC_E_SHUTDOWN:
758 req->status = -ESHUTDOWN;
761 req->status = -ECONNRESET;
764 req->status = -EINVAL;
767 req->status = -ETIMEDOUT;
770 req->status = status;
773 req->actual = actual;
774 req->complete(ep_handle, req);
780 static int _connect(dwc_otg_pcd_t * pcd, int speed)
782 gadget_wrapper->gadget.speed = speed;
786 static int _disconnect(dwc_otg_pcd_t * pcd)
788 if (gadget_wrapper->driver && gadget_wrapper->driver->disconnect) {
789 gadget_wrapper->driver->disconnect(&gadget_wrapper->gadget);
794 static int _resume(dwc_otg_pcd_t * pcd)
796 if (gadget_wrapper->driver && gadget_wrapper->driver->resume) {
797 gadget_wrapper->driver->resume(&gadget_wrapper->gadget);
803 static int _suspend(dwc_otg_pcd_t * pcd)
805 if (gadget_wrapper->driver && gadget_wrapper->driver->suspend) {
806 gadget_wrapper->driver->suspend(&gadget_wrapper->gadget);
812 * This function updates the otg values in the gadget structure.
814 static int _hnp_changed(dwc_otg_pcd_t * pcd)
817 if (!gadget_wrapper->gadget.is_otg)
820 gadget_wrapper->gadget.b_hnp_enable = get_b_hnp_enable(pcd);
821 gadget_wrapper->gadget.a_hnp_support = get_a_hnp_support(pcd);
822 gadget_wrapper->gadget.a_alt_hnp_support = get_a_alt_hnp_support(pcd);
826 static int _reset(dwc_otg_pcd_t * pcd)
832 static int _cfi_setup(dwc_otg_pcd_t * pcd, void *cfi_req)
834 int retval = -DWC_E_INVALID;
835 if (gadget_wrapper->driver->cfi_feature_setup) {
837 gadget_wrapper->driver->cfi_feature_setup(&gadget_wrapper->
848 static const struct dwc_otg_pcd_function_ops fops = {
849 .complete = _complete,
851 .isoc_complete = _isoc_complete,
854 .disconnect = _disconnect,
858 .hnp_changed = _hnp_changed,
861 .cfi_setup = _cfi_setup,
865 static dwc_otg_pcd_t *sprd_pcd;
867 * This function is the top level PCD interrupt handler.
869 static int dwc_otg_pcd_irq(int irq, void *dev)
871 dwc_otg_pcd_t *pcd = dev;
874 retval = dwc_otg_pcd_handle_intr(pcd);
876 S3C2410X_CLEAR_EINTPEND();
880 //return IRQ_RETVAL(retval);
884 * This function initialized the usb_ep structures to there default
887 * @param d Pointer on gadget_wrapper.
889 void gadget_add_eps(struct gadget_wrapper *d)
891 static const char *names[] = {
929 DWC_DEBUGPL(DBG_PCDV, "%s\n", __func__);
931 INIT_LIST_HEAD(&d->gadget.ep_list);
932 d->gadget.ep0 = &d->ep0;
933 d->gadget.speed = USB_SPEED_UNKNOWN;
935 INIT_LIST_HEAD(&d->gadget.ep0->ep_list);
938 * Initialize the EP0 structure.
942 /* Init the usb_ep structure. */
944 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
947 * @todo NGS: What should the max packet size be set to
948 * here? Before EP type is set?
950 ep->maxpacket = MAX_PACKET_SIZE;
951 dwc_otg_pcd_ep_enable(d->pcd, NULL, ep);
953 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
956 * Initialize the EP structures.
959 for (i = 0; i < 15; i++) {
962 /* Init the usb_ep structure. */
963 ep->name = names[i + 1];
964 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
967 * @todo NGS: What should the max packet size be set to
968 * here? Before EP type is set?
970 ep->maxpacket = MAX_PACKET_SIZE;
971 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
974 for (i = 0; i < 15; i++) {
977 /* Init the usb_ep structure. */
978 ep->name = names[15 + i + 1];
979 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
982 * @todo NGS: What should the max packet size be set to
983 * here? Before EP type is set?
985 ep->maxpacket = MAX_PACKET_SIZE;
987 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
990 /* remove ep0 from the list. There is a ep0 pointer. */
991 list_del_init(&d->ep0.ep_list);
993 d->ep0.maxpacket = MAX_EP0_SIZE;
997 * This function releases the Gadget device.
998 * required by device_unregister().
1000 * @todo Should this do something? Should it free the PCD?
1002 static void dwc_otg_pcd_gadget_release(struct device *dev)
1004 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
1007 static struct gadget_wrapper *alloc_wrapper(
1008 struct dwc_otg_device *_dev
1011 static char pcd_name[] = "dwc_otg";
1012 //dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev);
1013 dwc_otg_device_t *otg_dev = _dev;
1014 struct gadget_wrapper *d;
1017 d = dwc_alloc(sizeof(*d));
1022 memset(d, 0, sizeof(*d));
1024 d->gadget.name = pcd_name;
1025 d->pcd = otg_dev->pcd;
1028 strcpy(d->gadget.dev.bus_id, "gadget");
1031 dev_set_name(&d->gadget.dev, "gadget");
1032 d->gadget.dev.parent = &_dev->dev;
1033 d->gadget.dev.release = dwc_otg_pcd_gadget_release;
1035 d->gadget.ops = &dwc_otg_pcd_ops;
1036 d->gadget.is_dualspeed = dwc_otg_pcd_is_dualspeed(otg_dev->pcd);
1037 d->gadget.is_otg = dwc_otg_pcd_is_otg(otg_dev->pcd);
1040 /* Register the gadget device */
1042 retval = device_register(&d->gadget.dev);
1044 DWC_ERROR("device_register failed\n");
1053 static void free_wrapper(struct gadget_wrapper *d)
1056 /* should have been done already by driver model core */
1057 DWC_WARN("driver is still registered\n");
1058 usb_gadget_unregister_driver(d->driver);
1061 //device_unregister(&d->gadget.dev);
1066 * This function initialized the PCD portion of the driver.
1070 struct dwc_otg_device *_dev
1073 //dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev);
1074 dwc_otg_device_t *otg_dev = _dev;
1078 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1080 otg_dev->pcd = dwc_otg_pcd_init(otg_dev->core_if);
1082 if (!otg_dev->pcd) {
1083 DWC_ERROR("dwc_otg_pcd_init failed\n");
1087 gadget_wrapper = alloc_wrapper(_dev);
1090 * Initialize EP structures
1092 gadget_add_eps(gadget_wrapper);
1095 * Setup interupt handler
1099 irq = platform_get_irq(_dev, 0);
1100 DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", irq);
1101 retval = request_irq(irq, dwc_otg_pcd_irq,
1102 0, gadget_wrapper->gadget.name,
1104 //SA_SHIRQ, gadget_wrapper->gadget.name,
1106 DWC_ERROR("request of irq%d failed\n", irq);
1107 free_wrapper(gadget_wrapper);
1111 sprd_pcd = otg_dev->pcd;
1113 dwc_otg_pcd_start(gadget_wrapper->pcd, &fops);
1123 struct dwc_otg_device *_dev
1127 dwc_otg_device_t *otg_dev = _dev;
1128 dwc_otg_pcd_t *pcd = otg_dev->pcd;
1130 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1135 //free_irq(_dev->irq, pcd);
1136 dwc_otg_pcd_remove(otg_dev->pcd);
1137 free_wrapper(gadget_wrapper);
1142 * This function registers a gadget driver with the PCD.
1144 * When a driver is successfully registered, it will receive control
1145 * requests including set_configuration(), which enables non-control
1146 * requests. then usb traffic follows until a disconnect is reported.
1147 * then a host may connect again, or the driver might get unbound.
1149 * @param driver The driver being registered
1151 int usb_gadget_register_driver(struct usb_gadget_driver *driver)
1155 DWC_DEBUGPL(DBG_PCD, "registering gadget driver \n");
1157 if (!driver || driver->speed == USB_SPEED_UNKNOWN ||
1159 !driver->disconnect || !driver->setup) {
1160 //!driver->unbind || !driver->disconnect || !driver->setup) {
1161 DWC_DEBUGPL(DBG_PCDV, "EINVAL\n");
1164 if (gadget_wrapper == 0) {
1165 DWC_DEBUGPL(DBG_PCDV, "ENODEV\n");
1168 if (gadget_wrapper->driver != 0) {
1169 DWC_DEBUGPL(DBG_PCDV, "EBUSY (%p)\n", gadget_wrapper->driver);
1173 /* hook up the driver */
1174 gadget_wrapper->driver = driver;
1175 //gadget_wrapper->gadget.dev.driver = &driver->driver;
1177 DWC_DEBUGPL(DBG_PCD, "bind to driver \n");
1178 retval = driver->bind(&gadget_wrapper->gadget);
1180 DWC_ERROR("bind to driver --> error %d\n",
1182 gadget_wrapper->driver = 0;
1183 //gadget_wrapper->gadget.dev.driver = 0;
1187 DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
1188 driver->driver.name);
1195 * This function unregisters a gadget driver
1197 * @param driver The driver being unregistered
1199 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1201 //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver);
1203 if (gadget_wrapper == 0) {
1204 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
1208 if (driver == 0 || driver != gadget_wrapper->driver) {
1209 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
1214 driver->unbind(&gadget_wrapper->gadget);
1215 gadget_wrapper->driver = 0;
1217 DWC_DEBUGPL(DBG_ANY, "unregistered driver \n");
1221 int usb_gadget_handle_interrupts(void)
1223 dwc_otg_pcd_irq(0, sprd_pcd);
1227 #endif /* DWC_HOST_ONLY */