1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.c $
4 * $Date: 2008-11-27 09:21:25 $
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>.
54 * An important function of the PCD is managing interrupts generated
55 * by the DWC_otg controller. The implementation of the DWC_otg device
56 * mode interrupt service routines is in dwc_otg_pcd_intr.c.
58 * @todo Add Device Mode test modes (Test J mode, Test K mode, etc).
59 * @todo Does it work when the request size is greater than DEPTSIZ
65 #include <linux/kernel.h>
66 #include <linux/module.h>
67 #include <linux/moduleparam.h>
68 #include <linux/init.h>
69 #include <linux/device.h>
70 #include <linux/errno.h>
71 #include <linux/list.h>
72 #include <linux/interrupt.h>
73 #include <linux/string.h>
74 #include <linux/dma-mapping.h>
75 #include <linux/version.h>
77 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
78 # include <linux/usb/ch9.h>
80 # include <linux/usb_ch9.h>
83 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
84 #include <linux/usb/gadget.h>
86 #include <linux/usb_gadget.h>
89 #include "dwc_otg_driver.h"
90 #include "dwc_otg_pcd.h"
94 * Static PCD pointer for use in usb_gadget_register_driver and
95 * usb_gadget_unregister_driver. Initialized in dwc_otg_pcd_init.
97 static dwc_otg_pcd_t *s_pcd = 0;
100 /* Display the contents of the buffer */
101 extern void dump_msg(const u8 *buf, unsigned int length);
105 * This function completes a request. It call's the request call back.
107 void dwc_otg_request_done(dwc_otg_pcd_ep_t *ep, dwc_otg_pcd_request_t *req,
110 unsigned stopped = ep->stopped;
112 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, ep);
113 list_del_init(&req->queue);
115 if (req->req.status == -EINPROGRESS) {
116 req->req.status = status;
118 status = req->req.status;
121 /* don't modify queue heads during completion callback */
123 SPIN_UNLOCK(&ep->pcd->lock);
124 req->req.complete(&ep->ep, &req->req);
125 SPIN_LOCK(&ep->pcd->lock);
127 if (ep->pcd->request_pending > 0) {
128 --ep->pcd->request_pending;
131 ep->stopped = stopped;
135 * This function terminates all the requsts in the EP request queue.
137 void dwc_otg_request_nuke(dwc_otg_pcd_ep_t *ep)
139 dwc_otg_pcd_request_t *req;
143 /* called with irqs blocked?? */
144 while (!list_empty(&ep->queue)) {
145 req = list_entry(ep->queue.next, dwc_otg_pcd_request_t,
147 dwc_otg_request_done(ep, req, -ESHUTDOWN);
151 /* USB Endpoint Operations */
153 * The following sections briefly describe the behavior of the Gadget
154 * API endpoint operations implemented in the DWC_otg driver
155 * software. Detailed descriptions of the generic behavior of each of
156 * these functions can be found in the Linux header file
157 * include/linux/usb_gadget.h.
159 * The Gadget API provides wrapper functions for each of the function
160 * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper
161 * function, which then calls the underlying PCD function. The
162 * following sections are named according to the wrapper
163 * functions. Within each section, the corresponding DWC_otg PCD
164 * function name is specified.
169 * This function assigns periodic Tx FIFO to an periodic EP
170 * in shared Tx FIFO mode
172 static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t *core_if)
174 uint32_t PerTxMsk = 1;
176 for(i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; ++i)
178 if((PerTxMsk & core_if->p_tx_msk) == 0) {
179 core_if->p_tx_msk |= PerTxMsk;
187 * This function releases periodic Tx FIFO
188 * in shared Tx FIFO mode
190 static void release_perio_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
192 core_if->p_tx_msk = (core_if->p_tx_msk & (1 << (fifo_num - 1))) ^ core_if->p_tx_msk;
195 * This function assigns periodic Tx FIFO to an periodic EP
196 * in shared Tx FIFO mode
198 static uint32_t assign_tx_fifo(dwc_otg_core_if_t *core_if)
203 for(i = 0; i < core_if->hwcfg4.b.num_in_eps; ++i)
205 if((TxMsk & core_if->tx_msk) == 0) {
206 core_if->tx_msk |= TxMsk;
214 * This function releases periodic Tx FIFO
215 * in shared Tx FIFO mode
217 static void release_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
219 core_if->tx_msk = (core_if->tx_msk & (1 << (fifo_num - 1))) ^ core_if->tx_msk;
223 * This function is called by the Gadget Driver for each EP to be
224 * configured for the current configuration (SET_CONFIGURATION).
226 * This function initializes the dwc_otg_ep_t data structure, and then
227 * calls dwc_otg_ep_activate.
229 static int dwc_otg_pcd_ep_enable(struct usb_ep *usb_ep,
230 const struct usb_endpoint_descriptor *ep_desc)
232 dwc_otg_pcd_ep_t *ep = 0;
233 dwc_otg_pcd_t *pcd = 0;
236 DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, usb_ep, ep_desc);
238 ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
239 if (!usb_ep || !ep_desc || ep->desc ||
240 ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
241 DWC_WARN("%s, bad ep or descriptor\n", __func__);
244 if (ep == &ep->pcd->ep0) {
245 DWC_WARN("%s, bad ep(0)\n", __func__);
249 /* Check FIFO size? */
250 if (!ep_desc->wMaxPacketSize) {
251 DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name);
256 if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
257 DWC_WARN("%s, bogus device state\n", __func__);
261 SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
264 ep->ep.maxpacket = le16_to_cpu (ep_desc->wMaxPacketSize);
271 ep->dwc_ep.is_in = (USB_DIR_IN & ep_desc->bEndpointAddress) != 0;
272 ep->dwc_ep.maxpacket = ep->ep.maxpacket;
274 ep->dwc_ep.type = ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
276 if(ep->dwc_ep.is_in) {
277 if(!pcd->otg_dev->core_if->en_multiple_tx_fifo) {
278 ep->dwc_ep.tx_fifo_num = 0;
280 if (ep->dwc_ep.type == USB_ENDPOINT_XFER_ISOC) {
282 * if ISOC EP then assign a Periodic Tx FIFO.
284 ep->dwc_ep.tx_fifo_num = assign_perio_tx_fifo(pcd->otg_dev->core_if);
288 * if Dedicated FIFOs mode is on then assign a Tx FIFO.
290 ep->dwc_ep.tx_fifo_num = assign_tx_fifo(pcd->otg_dev->core_if);
294 /* Set initial data PID. */
295 if (ep->dwc_ep.type == USB_ENDPOINT_XFER_BULK) {
296 ep->dwc_ep.data_pid_start = 0;
299 DWC_DEBUGPL(DBG_PCD, "Activate %s-%s: type=%d, mps=%d desc=%p\n",
300 ep->ep.name, (ep->dwc_ep.is_in ?"IN":"OUT"),
301 ep->dwc_ep.type, ep->dwc_ep.maxpacket, ep->desc);
303 if(ep->dwc_ep.type != USB_ENDPOINT_XFER_ISOC) {
304 ep->dwc_ep.desc_addr = dwc_otg_ep_alloc_desc_chain(&ep->dwc_ep.dma_desc_addr, MAX_DMA_DESC_CNT);
307 dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
308 SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
314 * This function is called when an EP is disabled due to disconnect or
315 * change in configuration. Any pending requests will terminate with a
316 * status of -ESHUTDOWN.
318 * This function modifies the dwc_otg_ep_t data structure for this EP,
319 * and then calls dwc_otg_ep_deactivate.
321 static int dwc_otg_pcd_ep_disable(struct usb_ep *usb_ep)
323 dwc_otg_pcd_ep_t *ep;
324 dwc_otg_pcd_t *pcd = 0;
327 DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, usb_ep);
328 ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
329 if (!usb_ep || !ep->desc) {
330 DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
331 usb_ep ? ep->ep.name : NULL);
335 SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
337 dwc_otg_request_nuke(ep);
339 dwc_otg_ep_deactivate(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
343 if(ep->dwc_ep.is_in) {
344 dwc_otg_flush_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
345 release_perio_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
346 release_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
349 /* Free DMA Descriptors */
352 SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
354 if(ep->dwc_ep.type != USB_ENDPOINT_XFER_ISOC && ep->dwc_ep.desc_addr) {
355 dwc_otg_ep_free_desc_chain(ep->dwc_ep.desc_addr, ep->dwc_ep.dma_desc_addr, MAX_DMA_DESC_CNT);
358 DWC_DEBUGPL(DBG_PCD, "%s disabled\n", usb_ep->name);
364 * This function allocates a request object to use with the specified
367 * @param ep The endpoint to be used with with the request
368 * @param gfp_flags the GFP_* flags to use.
370 static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
371 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
378 dwc_otg_pcd_request_t *req;
380 DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d)\n", __func__, ep, gfp_flags);
382 DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
385 req = kmalloc(sizeof(dwc_otg_pcd_request_t), gfp_flags);
387 DWC_WARN("%s() %s\n", __func__,
388 "request allocation failed!\n");
391 memset(req, 0, sizeof(dwc_otg_pcd_request_t));
392 req->req.dma = DMA_ADDR_INVALID;
393 INIT_LIST_HEAD(&req->queue);
398 * This function frees a request object.
400 * @param ep The endpoint associated with the request
401 * @param req The request being freed
403 static void dwc_otg_pcd_free_request(struct usb_ep *ep,
404 struct usb_request *req)
406 dwc_otg_pcd_request_t *request;
407 DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, ep, req);
409 if (0 == ep || 0 == req) {
410 DWC_WARN("%s() %s\n", __func__,
411 "Invalid ep or req argument!\n");
415 request = container_of(req, dwc_otg_pcd_request_t, req);
419 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
421 * This function allocates an I/O buffer to be used for a transfer
422 * to/from the specified endpoint.
424 * @param usb_ep The endpoint to be used with with the request
425 * @param bytes The desired number of bytes for the buffer
426 * @param dma Pointer to the buffer's DMA address; must be valid
427 * @param gfp_flags the GFP_* flags to use.
428 * @return address of a new buffer or null is buffer could not be allocated.
430 static void *dwc_otg_pcd_alloc_buffer(struct usb_ep *usb_ep, unsigned bytes,
432 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
440 dwc_otg_pcd_ep_t *ep;
441 dwc_otg_pcd_t *pcd = 0;
443 ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
446 DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d,%p,%0x)\n", __func__, usb_ep, bytes,
449 /* Check dword alignment */
450 if ((bytes & 0x3UL) != 0) {
451 DWC_WARN("%s() Buffer size is not a multiple of"
452 "DWORD size (%d)",__func__, bytes);
455 if (GET_CORE_IF(pcd)->dma_enable) {
456 buf = dma_alloc_coherent (NULL, bytes, dma, gfp_flags);
459 buf = kmalloc(bytes, gfp_flags);
462 /* Check dword alignment */
463 if (((int)buf & 0x3UL) != 0) {
464 DWC_WARN("%s() Buffer is not DWORD aligned (%p)",
472 * This function frees an I/O buffer that was allocated by alloc_buffer.
474 * @param usb_ep the endpoint associated with the buffer
475 * @param buf address of the buffer
476 * @param dma The buffer's DMA address
477 * @param bytes The number of bytes of the buffer
479 static void dwc_otg_pcd_free_buffer(struct usb_ep *usb_ep, void *buf,
480 dma_addr_t dma, unsigned bytes)
482 dwc_otg_pcd_ep_t *ep;
483 dwc_otg_pcd_t *pcd = 0;
485 ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
488 DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p,%0x,%d)\n", __func__, ep, buf, dma, bytes);
490 if (GET_CORE_IF(pcd)->dma_enable) {
491 dma_free_coherent (NULL, bytes, buf, dma);
501 * This function is used to submit an I/O Request to an EP.
503 * - When the request completes the request's completion callback
504 * is called to return the request to the driver.
505 * - An EP, except control EPs, may have multiple requests
507 * - Once submitted the request cannot be examined or modified.
508 * - Each request is turned into one or more packets.
509 * - A BULK EP can queue any amount of data; the transfer is
511 * - Zero length Packets are specified with the request 'zero'
514 static int dwc_otg_pcd_ep_queue(struct usb_ep *usb_ep,
515 struct usb_request *usb_req,
516 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
524 dwc_otg_pcd_request_t *req;
525 dwc_otg_pcd_ep_t *ep;
527 unsigned long flags = 0;
528 dwc_otg_core_if_t *_core_if;
530 DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p,%d)\n",
531 __func__, usb_ep, usb_req, gfp_flags);
533 req = container_of(usb_req, dwc_otg_pcd_request_t, req);
534 if (!usb_req || !usb_req->complete || !usb_req->buf ||
535 !list_empty(&req->queue)) {
536 DWC_WARN("%s, bad params\n", __func__);
540 ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
541 if (!usb_ep || (!ep->desc && ep->dwc_ep.num != 0)/* || ep->stopped != 0*/) {
542 DWC_WARN("%s, bad ep\n", __func__);
547 if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
548 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
549 DWC_WARN("%s, bogus device state\n", __func__);
554 DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
555 usb_ep->name, usb_req, usb_req->length, usb_req->buf);
557 if (!GET_CORE_IF(pcd)->core_params->opt) {
558 if (ep->dwc_ep.num != 0) {
559 DWC_ERROR("%s queue req %p, len %d buf %p\n",
560 usb_ep->name, usb_req, usb_req->length, usb_req->buf);
564 SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
567 /**************************************************
568 New add by kaiker ,for DMA mode bug
569 ************************************************/
570 //by kaiker ,for RT3052 USB OTG device mode
572 _core_if = GET_CORE_IF(pcd);
574 if (_core_if->dma_enable)
576 usb_req->dma = virt_to_phys((void *)usb_req->buf);
580 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) || defined(CONFIG_MIPS)
582 dma_cache_wback_inv((unsigned long)usb_req->buf, usb_req->length + 2);
589 #if defined(DEBUG) & defined(VERBOSE)
590 dump_msg(usb_req->buf, usb_req->length);
593 usb_req->status = -EINPROGRESS;
597 * For EP0 IN without premature status, zlp is required?
599 if (ep->dwc_ep.num == 0 && ep->dwc_ep.is_in) {
600 DWC_DEBUGPL(DBG_PCDV, "%s-OUT ZLP\n", usb_ep->name);
604 /* Start the transfer */
605 if (list_empty(&ep->queue) && !ep->stopped) {
607 if (ep->dwc_ep.num == 0) {
608 switch (pcd->ep0state) {
609 case EP0_IN_DATA_PHASE:
611 "%s ep0: EP0_IN_DATA_PHASE\n",
615 case EP0_OUT_DATA_PHASE:
617 "%s ep0: EP0_OUT_DATA_PHASE\n",
619 if (pcd->request_config) {
620 /* Complete STATUS PHASE */
621 ep->dwc_ep.is_in = 1;
622 pcd->ep0state = EP0_IN_STATUS_PHASE;
626 case EP0_IN_STATUS_PHASE:
628 "%s ep0: EP0_IN_STATUS_PHASE\n",
633 DWC_DEBUGPL(DBG_ANY, "ep0: odd state %d\n",
635 SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
638 ep->dwc_ep.dma_addr = usb_req->dma;
639 ep->dwc_ep.start_xfer_buff = usb_req->buf;
640 ep->dwc_ep.xfer_buff = usb_req->buf;
641 ep->dwc_ep.xfer_len = usb_req->length;
642 ep->dwc_ep.xfer_count = 0;
643 ep->dwc_ep.sent_zlp = 0;
644 ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
647 if((ep->dwc_ep.xfer_len % ep->dwc_ep.maxpacket == 0)
648 && (ep->dwc_ep.xfer_len != 0)) {
649 ep->dwc_ep.sent_zlp = 1;
654 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep->dwc_ep);
658 uint32_t max_transfer = GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
660 /* Setup and start the Transfer */
661 ep->dwc_ep.dma_addr = usb_req->dma;
662 ep->dwc_ep.start_xfer_buff = usb_req->buf;
663 ep->dwc_ep.xfer_buff = usb_req->buf;
664 ep->dwc_ep.sent_zlp = 0;
665 ep->dwc_ep.total_len = usb_req->length;
666 ep->dwc_ep.xfer_len = 0;
667 ep->dwc_ep.xfer_count = 0;
669 if(max_transfer > MAX_TRANSFER_SIZE) {
670 ep->dwc_ep.maxxfer = max_transfer - (max_transfer % ep->dwc_ep.maxpacket);
672 ep->dwc_ep.maxxfer = max_transfer;
676 if((ep->dwc_ep.total_len % ep->dwc_ep.maxpacket == 0)
677 && (ep->dwc_ep.total_len != 0)) {
678 ep->dwc_ep.sent_zlp = 1;
682 dwc_otg_ep_start_transfer(GET_CORE_IF(pcd), &ep->dwc_ep);
686 if ((req != 0) || prevented) {
687 ++pcd->request_pending;
688 list_add_tail(&req->queue, &ep->queue);
689 if (ep->dwc_ep.is_in && ep->stopped && !(GET_CORE_IF(pcd)->dma_enable)) {
690 /** @todo NGS Create a function for this. */
691 diepmsk_data_t diepmsk = { .d32 = 0};
692 diepmsk.b.intktxfemp = 1;
693 if(&GET_CORE_IF(pcd)->multiproc_int_enable) {
694 dwc_modify_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->diepeachintmsk[ep->dwc_ep.num],
697 dwc_modify_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
702 SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
707 * This function cancels an I/O request from an EP.
709 static int dwc_otg_pcd_ep_dequeue(struct usb_ep *usb_ep,
710 struct usb_request *usb_req)
712 dwc_otg_pcd_request_t *req;
713 dwc_otg_pcd_ep_t *ep;
717 DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, usb_ep, usb_req);
719 ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
720 if (!usb_ep || !usb_req || (!ep->desc && ep->dwc_ep.num != 0)) {
721 DWC_WARN("%s, bad argument\n", __func__);
725 if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
726 DWC_WARN("%s, bogus device state\n", __func__);
730 SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
731 DWC_DEBUGPL(DBG_PCDV, "%s %s %s %p\n", __func__, usb_ep->name,
732 ep->dwc_ep.is_in ? "IN" : "OUT",
735 /* make sure it's actually queued on this endpoint */
736 list_for_each_entry(req, &ep->queue, queue)
738 if (&req->req == usb_req) {
743 if (&req->req != usb_req) {
744 SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
748 if (!list_empty(&req->queue)) {
749 dwc_otg_request_done(ep, req, -ECONNRESET);
755 SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
757 return req ? 0 : -EOPNOTSUPP;
761 * usb_ep_set_halt stalls an endpoint.
763 * usb_ep_clear_halt clears an endpoint halt and resets its data
766 * Both of these functions are implemented with the same underlying
767 * function. The behavior depends on the value argument.
769 * @param[in] usb_ep the Endpoint to halt or clear halt.
771 * - 0 means clear_halt.
772 * - 1 means set_halt,
773 * - 2 means clear stall lock flag.
774 * - 3 means set stall lock flag.
776 static int dwc_otg_pcd_ep_set_halt(struct usb_ep *usb_ep, int value)
780 dwc_otg_pcd_ep_t *ep = 0;
783 DWC_DEBUGPL(DBG_PCD,"HALT %s %d\n", usb_ep->name, value);
785 ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
787 if (!usb_ep || (!ep->desc && ep != &ep->pcd->ep0) ||
788 ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
789 DWC_WARN("%s, bad ep\n", __func__);
793 SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
794 if (!list_empty(&ep->queue)) {
795 DWC_WARN("%s() %s XFer In process\n", __func__, usb_ep->name);
798 else if (value == 0) {
799 dwc_otg_ep_clear_stall(ep->pcd->otg_dev->core_if,
802 else if(value == 1) {
803 if (ep->dwc_ep.is_in == 1 && ep->pcd->otg_dev->core_if->dma_desc_enable) {
804 dtxfsts_data_t txstatus;
805 fifosize_data_t txfifosize;
807 txfifosize.d32 = dwc_read_reg32(&ep->pcd->otg_dev->core_if->core_global_regs->dptxfsiz_dieptxf[ep->dwc_ep.tx_fifo_num]);
808 txstatus.d32 = dwc_read_reg32(&ep->pcd->otg_dev->core_if->dev_if->in_ep_regs[ep->dwc_ep.num]->dtxfsts);
810 if(txstatus.b.txfspcavail < txfifosize.b.depth) {
811 DWC_WARN("%s() %s Data In Tx Fifo\n", __func__, usb_ep->name);
815 if (ep->dwc_ep.num == 0) {
816 ep->pcd->ep0state = EP0_STALL;
820 dwc_otg_ep_set_stall(ep->pcd->otg_dev->core_if,
825 if (ep->dwc_ep.num == 0) {
826 ep->pcd->ep0state = EP0_STALL;
830 dwc_otg_ep_set_stall(ep->pcd->otg_dev->core_if,
834 else if (value == 2) {
835 ep->dwc_ep.stall_clear_flag = 0;
837 else if (value == 3) {
838 ep->dwc_ep.stall_clear_flag = 1;
841 SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
846 * This function allocates a DMA Descriptor chain for the Endpoint
847 * buffer to be used for a transfer to/from the specified endpoint.
849 dwc_otg_dma_desc_t* dwc_otg_ep_alloc_desc_chain(uint32_t * dma_desc_addr, uint32_t count)
852 return dma_alloc_coherent(NULL, count * sizeof(dwc_otg_dma_desc_t), dma_desc_addr, GFP_KERNEL);
856 * This function frees a DMA Descriptor chain that was allocated by ep_alloc_desc.
858 void dwc_otg_ep_free_desc_chain(dwc_otg_dma_desc_t* desc_addr, uint32_t dma_desc_addr, uint32_t count)
860 dma_free_coherent(NULL, count * sizeof(dwc_otg_dma_desc_t), desc_addr, dma_desc_addr);
866 * This function initializes a descriptor chain for Isochronous transfer
868 * @param core_if Programming view of DWC_otg controller.
869 * @param dwc_ep The EP to start the transfer on.
872 void dwc_otg_iso_ep_start_ddma_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
875 dsts_data_t dsts = { .d32 = 0};
876 depctl_data_t depctl = { .d32 = 0 };
877 volatile uint32_t *addr;
881 dwc_ep->desc_cnt = dwc_ep->buf_proc_intrvl / dwc_ep->bInterval;
883 dwc_ep->desc_cnt = dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
886 /** Allocate descriptors for double buffering */
887 dwc_ep->iso_desc_addr = dwc_otg_ep_alloc_desc_chain(&dwc_ep->iso_dma_desc_addr,dwc_ep->desc_cnt*2);
888 if(dwc_ep->desc_addr) {
889 DWC_WARN("%s, can't allocate DMA descriptor chain\n", __func__);
893 dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
896 if(dwc_ep->is_in == 0) {
897 desc_sts_data_t sts = { .d32 =0 };
898 dwc_otg_dma_desc_t* dma_desc = dwc_ep->iso_desc_addr;
900 uint32_t data_per_desc;
901 dwc_otg_dev_out_ep_regs_t *out_regs =
902 core_if->dev_if->out_ep_regs[dwc_ep->num];
905 addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
906 dma_ad = (dma_addr_t)dwc_read_reg32(&(out_regs->doepdma));
908 /** Buffer 0 descriptors setup */
909 dma_ad = dwc_ep->dma_addr0;
911 sts.b_iso_out.bs = BS_HOST_READY;
912 sts.b_iso_out.rxsts = 0;
914 sts.b_iso_out.sp = 0;
915 sts.b_iso_out.ioc = 0;
916 sts.b_iso_out.pid = 0;
917 sts.b_iso_out.framenum = 0;
920 for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
923 for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
925 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
926 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
928 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
929 sts.b_iso_out.rxbytes = data_per_desc;
930 writel((uint32_t)dma_ad, &dma_desc->buf);
931 writel(sts.d32, &dma_desc->status);
933 offset += data_per_desc;
935 (uint32_t)dma_ad += data_per_desc;
939 for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
941 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
942 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
943 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
944 sts.b_iso_out.rxbytes = data_per_desc;
945 writel((uint32_t)dma_ad, &dma_desc->buf);
946 writel(sts.d32, &dma_desc->status);
948 offset += data_per_desc;
950 (uint32_t)dma_ad += data_per_desc;
953 sts.b_iso_out.ioc = 1;
954 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
955 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
956 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
957 sts.b_iso_out.rxbytes = data_per_desc;
959 writel((uint32_t)dma_ad, &dma_desc->buf);
960 writel(sts.d32, &dma_desc->status);
963 /** Buffer 1 descriptors setup */
964 sts.b_iso_out.ioc = 0;
965 dma_ad = dwc_ep->dma_addr1;
968 for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
970 for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
972 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
973 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
974 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
975 sts.b_iso_out.rxbytes = data_per_desc;
976 writel((uint32_t)dma_ad, &dma_desc->buf);
977 writel(sts.d32, &dma_desc->status);
979 offset += data_per_desc;
981 (uint32_t)dma_ad += data_per_desc;
984 for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
986 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
987 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
988 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
989 sts.b_iso_out.rxbytes = data_per_desc;
990 writel((uint32_t)dma_ad, &dma_desc->buf);
991 writel(sts.d32, &dma_desc->status);
993 offset += data_per_desc;
995 (uint32_t)dma_ad += data_per_desc;
998 sts.b_iso_out.ioc = 1;
1000 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
1001 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
1002 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
1003 sts.b_iso_out.rxbytes = data_per_desc;
1005 writel((uint32_t)dma_ad, &dma_desc->buf);
1006 writel(sts.d32, &dma_desc->status);
1008 dwc_ep->next_frame = 0;
1010 /** Write dma_ad into DOEPDMA register */
1011 dwc_write_reg32(&(out_regs->doepdma),(uint32_t)dwc_ep->iso_dma_desc_addr);
1016 desc_sts_data_t sts = { .d32 =0 };
1017 dwc_otg_dma_desc_t* dma_desc = dwc_ep->iso_desc_addr;
1019 dwc_otg_dev_in_ep_regs_t *in_regs =
1020 core_if->dev_if->in_ep_regs[dwc_ep->num];
1021 unsigned int frmnumber;
1022 fifosize_data_t txfifosize,rxfifosize;
1024 txfifosize.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[dwc_ep->num]->dtxfsts);
1025 rxfifosize.d32 = dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
1028 addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
1030 dma_ad = dwc_ep->dma_addr0;
1032 dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
1034 sts.b_iso_in.bs = BS_HOST_READY;
1035 sts.b_iso_in.txsts = 0;
1036 sts.b_iso_in.sp = (dwc_ep->data_per_frame % dwc_ep->maxpacket)? 1 : 0;
1037 sts.b_iso_in.ioc = 0;
1038 sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
1041 frmnumber = dwc_ep->next_frame;
1043 sts.b_iso_in.framenum = frmnumber;
1044 sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
1047 /** Buffer 0 descriptors setup */
1048 for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
1050 writel((uint32_t)dma_ad, &dma_desc->buf);
1051 writel(sts.d32, &dma_desc->status);
1054 (uint32_t)dma_ad += dwc_ep->data_per_frame;
1055 sts.b_iso_in.framenum += dwc_ep->bInterval;
1058 sts.b_iso_in.ioc = 1;
1059 writel((uint32_t)dma_ad, &dma_desc->buf);
1060 writel(sts.d32, &dma_desc->status);
1063 /** Buffer 1 descriptors setup */
1064 sts.b_iso_in.ioc = 0;
1065 dma_ad = dwc_ep->dma_addr1;
1067 for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
1069 writel((uint32_t)dma_ad, &dma_desc->buf);
1070 writel(sts.d32, &dma_desc->status);
1073 (uint32_t)dma_ad += dwc_ep->data_per_frame;
1074 sts.b_iso_in.framenum += dwc_ep->bInterval;
1076 sts.b_iso_in.ioc = 0;
1078 sts.b_iso_in.ioc = 1;
1081 writel((uint32_t)dma_ad, &dma_desc->buf);
1082 writel(sts.d32, &dma_desc->status);
1084 dwc_ep->next_frame = sts.b_iso_in.framenum + dwc_ep->bInterval;
1086 /** Write dma_ad into diepdma register */
1087 dwc_write_reg32(&(in_regs->diepdma),(uint32_t)dwc_ep->iso_dma_desc_addr);
1089 /** Enable endpoint, clear nak */
1092 depctl.b.usbactep = 1;
1095 dwc_modify_reg32(addr, depctl.d32,depctl.d32);
1096 depctl.d32 = dwc_read_reg32(addr);
1100 * This function initializes a descriptor chain for Isochronous transfer
1102 * @param core_if Programming view of DWC_otg controller.
1103 * @param ep The EP to start the transfer on.
1107 void dwc_otg_iso_ep_start_buf_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
1109 depctl_data_t depctl = { .d32 = 0 };
1110 volatile uint32_t *addr;
1114 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
1116 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
1120 if(core_if->dma_enable == 0 || core_if->dma_desc_enable!= 0) {
1123 deptsiz_data_t deptsiz = { .d32 = 0 };
1125 ep->xfer_len = ep->data_per_frame * ep->buf_proc_intrvl / ep->bInterval;
1126 ep->pkt_cnt = (ep->xfer_len - 1 + ep->maxpacket) /
1129 ep->xfer_buff = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
1130 ep->dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
1133 /* Program the transfer size and packet count
1134 * as follows: xfersize = N * maxpacket +
1135 * short_packet pktcnt = N + (short_packet
1138 deptsiz.b.mc = ep->pkt_per_frm;
1139 deptsiz.b.xfersize = ep->xfer_len;
1141 (ep->xfer_len - 1 + ep->maxpacket) /
1143 dwc_write_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz, deptsiz.d32);
1145 /* Write the DMA register */
1146 dwc_write_reg32 (&(core_if->dev_if->in_ep_regs[ep->num]->diepdma), (uint32_t)ep->dma_addr);
1150 (ep->xfer_len + (ep->maxpacket - 1)) /
1152 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
1154 dwc_write_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
1156 /* Write the DMA register */
1157 dwc_write_reg32 (&(core_if->dev_if->out_ep_regs[ep->num]->doepdma), (uint32_t)ep->dma_addr);
1160 /** Enable endpoint, clear nak */
1162 dwc_modify_reg32(addr, depctl.d32,depctl.d32);
1167 dwc_modify_reg32(addr, depctl.d32,depctl.d32);
1173 * This function does the setup for a data transfer for an EP and
1174 * starts the transfer. For an IN transfer, the packets will be
1175 * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
1176 * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
1178 * @param core_if Programming view of DWC_otg controller.
1179 * @param ep The EP to start the transfer on.
1182 void dwc_otg_iso_ep_start_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
1184 if(core_if->dma_enable) {
1185 if(core_if->dma_desc_enable) {
1187 ep->desc_cnt = ep->pkt_cnt / ep->pkt_per_frm;
1189 ep->desc_cnt = ep->pkt_cnt;
1191 dwc_otg_iso_ep_start_ddma_transfer(core_if, ep);
1193 if(core_if->pti_enh_enable) {
1194 dwc_otg_iso_ep_start_buf_transfer(core_if, ep);
1196 ep->cur_pkt_addr = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
1197 ep->cur_pkt_dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
1198 dwc_otg_iso_ep_start_frm_transfer(core_if, ep);
1202 ep->cur_pkt_addr = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
1203 ep->cur_pkt_dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
1204 dwc_otg_iso_ep_start_frm_transfer(core_if, ep);
1209 * This function does the setup for a data transfer for an EP and
1210 * starts the transfer. For an IN transfer, the packets will be
1211 * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
1212 * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
1214 * @param core_if Programming view of DWC_otg controller.
1215 * @param ep The EP to start the transfer on.
1218 void dwc_otg_iso_ep_stop_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
1220 depctl_data_t depctl = { .d32 = 0 };
1221 volatile uint32_t *addr;
1223 if(ep->is_in == 1) {
1224 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
1227 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
1230 /* disable the ep */
1231 depctl.d32 = dwc_read_reg32(addr);
1236 dwc_write_reg32(addr, depctl.d32);
1238 if(core_if->dma_desc_enable &&
1239 ep->iso_desc_addr && ep->iso_dma_desc_addr) {
1240 dwc_otg_ep_free_desc_chain(ep->iso_desc_addr,ep->iso_dma_desc_addr,ep->desc_cnt * 2);
1243 /* reset varibales */
1248 ep->data_per_frame = 0;
1249 ep->data_pattern_frame = 0;
1251 ep->buf_proc_intrvl = 0;
1253 ep->proc_buf_num = 0;
1254 ep->pkt_per_frm = 0;
1255 ep->pkt_per_frm = 0;
1257 ep->iso_desc_addr = 0;
1258 ep->iso_dma_desc_addr = 0;
1263 * This function is used to submit an ISOC Transfer Request to an EP.
1265 * - Every time a sync period completes the request's completion callback
1266 * is called to provide data to the gadget driver.
1267 * - Once submitted the request cannot be modified.
1268 * - Each request is turned into periodic data packets untill ISO
1269 * Transfer is stopped..
1271 static int dwc_otg_pcd_iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
1272 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
1279 dwc_otg_pcd_ep_t *ep;
1282 unsigned long flags = 0;
1284 dwc_otg_core_if_t *core_if;
1289 if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
1290 DWC_WARN("%s, bad params\n", __func__);
1294 ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
1296 if (!usb_ep || !ep->desc || ep->dwc_ep.num == 0) {
1297 DWC_WARN("%s, bad ep\n", __func__);
1302 core_if = GET_CORE_IF(pcd);
1304 dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
1306 if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
1307 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
1308 DWC_WARN("%s, bogus device state\n", __func__);
1312 SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
1314 dwc_ep = &ep->dwc_ep;
1317 DWC_WARN("%s, iso request in progress\n", __func__);
1319 req->status = -EINPROGRESS;
1321 dwc_ep->dma_addr0 = req->dma0;
1322 dwc_ep->dma_addr1 = req->dma1;
1324 dwc_ep->xfer_buff0 = req->buf0;
1325 dwc_ep->xfer_buff1 = req->buf1;
1329 dwc_ep->data_per_frame = req->data_per_frame;
1331 /** @todo - pattern data support is to be implemented in the future */
1332 dwc_ep->data_pattern_frame = req->data_pattern_frame;
1333 dwc_ep->sync_frame = req->sync_frame;
1335 dwc_ep->buf_proc_intrvl = req->buf_proc_intrvl;
1337 dwc_ep->bInterval = 1 << (ep->desc->bInterval - 1);
1339 dwc_ep->proc_buf_num = 0;
1341 dwc_ep->pkt_per_frm = 0;
1342 frm_data = ep->dwc_ep.data_per_frame;
1343 while(frm_data > 0) {
1344 dwc_ep->pkt_per_frm++;
1345 frm_data -= ep->dwc_ep.maxpacket;
1348 dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
1350 if(req->flags & USB_REQ_ISO_ASAP) {
1351 dwc_ep->next_frame = dsts.b.soffn + 1;
1352 if(dwc_ep->bInterval != 1){
1353 dwc_ep->next_frame = dwc_ep->next_frame + (dwc_ep->bInterval - 1 - dwc_ep->next_frame % dwc_ep->bInterval);
1356 dwc_ep->next_frame = req->start_frame;
1360 if(!core_if->pti_enh_enable) {
1361 dwc_ep->pkt_cnt = dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
1364 (dwc_ep->data_per_frame * (dwc_ep->buf_proc_intrvl / dwc_ep->bInterval)
1365 - 1 + dwc_ep->maxpacket) / dwc_ep->maxpacket;
1368 if(core_if->dma_desc_enable) {
1370 dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
1373 dwc_ep->pkt_info = kmalloc(sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt, GFP_KERNEL);
1374 if(!dwc_ep->pkt_info) {
1377 if(core_if->pti_enh_enable) {
1378 memset(dwc_ep->pkt_info, 0, sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt);
1381 dwc_ep->cur_pkt = 0;
1383 SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
1385 dwc_otg_iso_ep_start_transfer(core_if, dwc_ep);
1391 * This function stops ISO EP Periodic Data Transfer.
1393 static int dwc_otg_pcd_iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
1395 dwc_otg_pcd_ep_t *ep;
1398 unsigned long flags;
1400 ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
1402 if (!usb_ep || !ep->desc || ep->dwc_ep.num == 0) {
1403 DWC_WARN("%s, bad ep\n", __func__);
1409 if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
1410 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
1411 DWC_WARN("%s, bogus device state\n", __func__);
1415 dwc_ep = &ep->dwc_ep;
1417 dwc_otg_iso_ep_stop_transfer(GET_CORE_IF(pcd), dwc_ep);
1419 kfree(dwc_ep->pkt_info);
1421 SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
1423 if(ep->iso_req != req) {
1427 req->status = -ECONNRESET;
1429 SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
1438 * This function is used for perodical data exchnage between PCD and gadget drivers.
1439 * for Isochronous EPs
1441 * - Every time a sync period completes this function is called to
1442 * perform data exchange between PCD and gadget
1444 void dwc_otg_iso_buffer_done(dwc_otg_pcd_ep_t *ep, dwc_otg_pcd_iso_request_t *req)
1447 struct usb_gadget_iso_packet_descriptor *iso_packet;
1450 dwc_ep = &ep->dwc_ep;
1452 if(ep->iso_req->status == -ECONNRESET) {
1453 DWC_PRINT("Device has already disconnected\n");
1454 /*Device has been disconnected*/
1458 if(dwc_ep->proc_buf_num != 0) {
1459 iso_packet = ep->iso_req->iso_packet_desc0;
1463 iso_packet = ep->iso_req->iso_packet_desc1;
1466 /* Fill in ISOC packets descriptors & pass to gadget driver*/
1468 for(i = 0; i < dwc_ep->pkt_cnt; ++i) {
1469 iso_packet[i].status = dwc_ep->pkt_info[i].status;
1470 iso_packet[i].offset = dwc_ep->pkt_info[i].offset;
1471 iso_packet[i].actual_length = dwc_ep->pkt_info[i].length;
1472 dwc_ep->pkt_info[i].status = 0;
1473 dwc_ep->pkt_info[i].offset = 0;
1474 dwc_ep->pkt_info[i].length = 0;
1477 /* Call callback function to process data buffer */
1478 ep->iso_req->status = 0;/* success */
1480 SPIN_UNLOCK(&ep->pcd->lock);
1481 ep->iso_req->process_buffer(&ep->ep, ep->iso_req);
1482 SPIN_LOCK(&ep->pcd->lock);
1486 static struct usb_iso_request *dwc_otg_pcd_alloc_iso_request(struct usb_ep *ep,int packets,
1487 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
1494 struct usb_iso_request *pReq = NULL;
1498 req_size = sizeof(struct usb_iso_request);
1499 req_size += (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
1502 pReq = kmalloc(req_size, gfp_flags);
1504 DWC_WARN("%s, can't allocate Iso Request\n", __func__);
1507 pReq->iso_packet_desc0 = (void*) (pReq + 1);
1509 pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
1514 static void dwc_otg_pcd_free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
1519 static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops =
1523 .enable = dwc_otg_pcd_ep_enable,
1524 .disable = dwc_otg_pcd_ep_disable,
1526 .alloc_request = dwc_otg_pcd_alloc_request,
1527 .free_request = dwc_otg_pcd_free_request,
1529 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
1530 .alloc_buffer = dwc_otg_pcd_alloc_buffer,
1531 .free_buffer = dwc_otg_pcd_free_buffer,
1534 .queue = dwc_otg_pcd_ep_queue,
1535 .dequeue = dwc_otg_pcd_ep_dequeue,
1537 .set_halt = dwc_otg_pcd_ep_set_halt,
1541 .iso_ep_start = dwc_otg_pcd_iso_ep_start,
1542 .iso_ep_stop = dwc_otg_pcd_iso_ep_stop,
1543 .alloc_iso_request = dwc_otg_pcd_alloc_iso_request,
1544 .free_iso_request = dwc_otg_pcd_free_iso_request,
1550 static struct usb_ep_ops dwc_otg_pcd_ep_ops =
1552 .enable = dwc_otg_pcd_ep_enable,
1553 .disable = dwc_otg_pcd_ep_disable,
1555 .alloc_request = dwc_otg_pcd_alloc_request,
1556 .free_request = dwc_otg_pcd_free_request,
1558 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
1559 .alloc_buffer = dwc_otg_pcd_alloc_buffer,
1560 .free_buffer = dwc_otg_pcd_free_buffer,
1563 .queue = dwc_otg_pcd_ep_queue,
1564 .dequeue = dwc_otg_pcd_ep_dequeue,
1566 .set_halt = dwc_otg_pcd_ep_set_halt,
1573 #endif /* DWC_EN_ISOC */
1574 /* Gadget Operations */
1576 * The following gadget operations will be implemented in the DWC_otg
1577 * PCD. Functions in the API that are not described below are not
1580 * The Gadget API provides wrapper functions for each of the function
1581 * pointers defined in usb_gadget_ops. The Gadget Driver calls the
1582 * wrapper function, which then calls the underlying PCD function. The
1583 * following sections are named according to the wrapper functions
1584 * (except for ioctl, which doesn't have a wrapper function). Within
1585 * each section, the corresponding DWC_otg PCD function name is
1591 *Gets the USB Frame number of the last SOF.
1593 static int dwc_otg_pcd_get_frame(struct usb_gadget *gadget)
1597 DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, gadget);
1603 pcd = container_of(gadget, dwc_otg_pcd_t, gadget);
1604 dwc_otg_get_frame_number(GET_CORE_IF(pcd));
1610 void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t *pcd)
1612 uint32_t *addr = (uint32_t *)&(GET_CORE_IF(pcd)->core_global_regs->gotgctl);
1616 val.d32 = dwc_read_reg32(addr);
1618 DWC_ERROR("Session Request Already active!\n");
1622 DWC_NOTICE("Session Request Initated\n");
1623 mem.d32 = dwc_read_reg32(addr);
1625 dwc_write_reg32(addr, mem.d32);
1627 /* Start the SRP timer */
1628 dwc_otg_pcd_start_srp_timer(pcd);
1632 void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t *pcd, int set)
1634 dctl_data_t dctl = {.d32=0};
1635 volatile uint32_t *addr = &(GET_CORE_IF(pcd)->dev_if->dev_global_regs->dctl);
1637 if (dwc_otg_is_device_mode(GET_CORE_IF(pcd))) {
1638 if (pcd->remote_wakeup_enable) {
1640 dctl.b.rmtwkupsig = 1;
1641 dwc_modify_reg32(addr, 0, dctl.d32);
1642 DWC_DEBUGPL(DBG_PCD, "Set Remote Wakeup\n");
1644 dwc_modify_reg32(addr, dctl.d32, 0);
1645 DWC_DEBUGPL(DBG_PCD, "Clear Remote Wakeup\n");
1651 DWC_DEBUGPL(DBG_PCD, "Remote Wakeup is disabled\n");
1658 * Initiates Session Request Protocol (SRP) to wakeup the host if no
1659 * session is in progress. If a session is already in progress, but
1660 * the device is suspended, remote wakeup signaling is started.
1663 static int dwc_otg_pcd_wakeup(struct usb_gadget *gadget)
1665 unsigned long flags;
1668 gotgctl_data_t gotgctl;
1670 DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, gadget);
1676 pcd = container_of(gadget, dwc_otg_pcd_t, gadget);
1678 SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
1681 * This function starts the Protocol if no session is in progress. If
1682 * a session is already in progress, but the device is suspended,
1683 * remote wakeup signaling is started.
1686 /* Check if valid session */
1687 gotgctl.d32 = dwc_read_reg32(&(GET_CORE_IF(pcd)->core_global_regs->gotgctl));
1688 if (gotgctl.b.bsesvld) {
1689 /* Check if suspend state */
1690 dsts.d32 = dwc_read_reg32(&(GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts));
1691 if (dsts.b.suspsts) {
1692 dwc_otg_pcd_remote_wakeup(pcd, 1);
1696 dwc_otg_pcd_initiate_srp(pcd);
1699 SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
1703 static const struct usb_gadget_ops dwc_otg_pcd_ops =
1705 .get_frame = dwc_otg_pcd_get_frame,
1706 .wakeup = dwc_otg_pcd_wakeup,
1707 // current versions must always be self-powered
1711 * This function updates the otg values in the gadget structure.
1713 void dwc_otg_pcd_update_otg(dwc_otg_pcd_t *pcd, const unsigned reset)
1716 if (!pcd->gadget.is_otg)
1720 pcd->b_hnp_enable = 0;
1721 pcd->a_hnp_support = 0;
1722 pcd->a_alt_hnp_support = 0;
1725 pcd->gadget.b_hnp_enable = pcd->b_hnp_enable;
1726 pcd->gadget.a_hnp_support = pcd->a_hnp_support;
1727 pcd->gadget.a_alt_hnp_support = pcd->a_alt_hnp_support;
1731 * This function is the top level PCD interrupt handler.
1733 static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev
1734 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
1739 dwc_otg_pcd_t *pcd = dev;
1740 int32_t retval = IRQ_NONE;
1742 retval = dwc_otg_pcd_handle_intr(pcd);
1743 return IRQ_RETVAL(retval);
1747 * PCD Callback function for initializing the PCD when switching to
1750 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
1752 static int32_t dwc_otg_pcd_start_cb(void *p)
1754 dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
1757 * Initialized the Core for Device mode.
1759 if (dwc_otg_is_device_mode(GET_CORE_IF(pcd))) {
1760 dwc_otg_core_dev_init(GET_CORE_IF(pcd));
1766 * PCD Callback function for stopping the PCD when switching to Host
1769 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
1771 static int32_t dwc_otg_pcd_stop_cb(void *p)
1773 dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
1774 extern void dwc_otg_pcd_stop(dwc_otg_pcd_t *_pcd);
1776 dwc_otg_pcd_stop(pcd);
1782 * PCD Callback function for notifying the PCD when resuming from
1785 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
1787 static int32_t dwc_otg_pcd_suspend_cb(void *p)
1789 dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
1791 if (pcd->driver && pcd->driver->resume) {
1792 SPIN_UNLOCK(&pcd->lock);
1793 pcd->driver->suspend(&pcd->gadget);
1794 SPIN_LOCK(&pcd->lock);
1802 * PCD Callback function for notifying the PCD when resuming from
1805 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
1807 static int32_t dwc_otg_pcd_resume_cb(void *p)
1809 dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
1811 if (pcd->driver && pcd->driver->resume) {
1812 SPIN_UNLOCK(&pcd->lock);
1813 pcd->driver->resume(&pcd->gadget);
1814 SPIN_LOCK(&pcd->lock);
1817 /* Stop the SRP timeout timer. */
1818 if ((GET_CORE_IF(pcd)->core_params->phy_type != DWC_PHY_TYPE_PARAM_FS) ||
1819 (!GET_CORE_IF(pcd)->core_params->i2c_enable)) {
1820 if (GET_CORE_IF(pcd)->srp_timer_started) {
1821 GET_CORE_IF(pcd)->srp_timer_started = 0;
1822 del_timer(&pcd->srp_timer);
1830 * PCD Callback structure for handling mode switching.
1832 static dwc_otg_cil_callbacks_t pcd_callbacks =
1834 .start = dwc_otg_pcd_start_cb,
1835 .stop = dwc_otg_pcd_stop_cb,
1836 .suspend = dwc_otg_pcd_suspend_cb,
1837 .resume_wakeup = dwc_otg_pcd_resume_cb,
1838 .p = 0, /* Set at registration */
1842 * This function is called when the SRP timer expires. The SRP should
1843 * complete within 6 seconds.
1845 static void srp_timeout(unsigned long ptr)
1847 gotgctl_data_t gotgctl;
1848 dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *)ptr;
1849 volatile uint32_t *addr = &core_if->core_global_regs->gotgctl;
1851 gotgctl.d32 = dwc_read_reg32(addr);
1853 core_if->srp_timer_started = 0;
1855 if ((core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) &&
1856 (core_if->core_params->i2c_enable)) {
1857 DWC_PRINT("SRP Timeout\n");
1859 if ((core_if->srp_success) &&
1860 (gotgctl.b.bsesvld)) {
1861 if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
1862 core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
1865 /* Clear Session Request */
1867 gotgctl.b.sesreq = 1;
1868 dwc_modify_reg32(&core_if->core_global_regs->gotgctl,
1871 core_if->srp_success = 0;
1874 DWC_ERROR("Device not connected/responding\n");
1875 gotgctl.b.sesreq = 0;
1876 dwc_write_reg32(addr, gotgctl.d32);
1879 else if (gotgctl.b.sesreq) {
1880 DWC_PRINT("SRP Timeout\n");
1882 DWC_ERROR("Device not connected/responding\n");
1883 gotgctl.b.sesreq = 0;
1884 dwc_write_reg32(addr, gotgctl.d32);
1887 DWC_PRINT(" SRP GOTGCTL=%0x\n", gotgctl.d32);
1892 * Start the SRP timer to detect when the SRP does not complete within
1895 * @param pcd the pcd structure.
1897 void dwc_otg_pcd_start_srp_timer(dwc_otg_pcd_t *pcd)
1899 struct timer_list *srp_timer = &pcd->srp_timer;
1900 GET_CORE_IF(pcd)->srp_timer_started = 1;
1901 init_timer(srp_timer);
1902 srp_timer->function = srp_timeout;
1903 srp_timer->data = (unsigned long)GET_CORE_IF(pcd);
1904 srp_timer->expires = jiffies + (HZ*6);
1905 add_timer(srp_timer);
1912 extern void start_next_request(dwc_otg_pcd_ep_t *ep);
1914 static void start_xfer_tasklet_func (unsigned long data)
1916 dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t*)data;
1917 dwc_otg_core_if_t *core_if = pcd->otg_dev->core_if;
1920 depctl_data_t diepctl;
1922 DWC_DEBUGPL(DBG_PCDV, "Start xfer tasklet\n");
1924 diepctl.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
1926 if (pcd->ep0.queue_sof) {
1927 pcd->ep0.queue_sof = 0;
1928 start_next_request (&pcd->ep0);
1932 for (i=0; i<core_if->dev_if->num_in_eps; i++)
1934 depctl_data_t diepctl;
1935 diepctl.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[i]->diepctl);
1937 if (pcd->in_ep[i].queue_sof) {
1938 pcd->in_ep[i].queue_sof = 0;
1939 start_next_request (&pcd->in_ep[i]);
1953 static struct tasklet_struct start_xfer_tasklet = {
1956 .count = ATOMIC_INIT(0),
1957 .func = start_xfer_tasklet_func,
1961 * This function initialized the pcd Dp structures to there default
1964 * @param pcd the pcd structure.
1966 void dwc_otg_pcd_reinit(dwc_otg_pcd_t *pcd)
1968 static const char * names[] =
2006 int in_ep_cntr, out_ep_cntr;
2008 uint32_t num_in_eps = (GET_CORE_IF(pcd))->dev_if->num_in_eps;
2009 uint32_t num_out_eps = (GET_CORE_IF(pcd))->dev_if->num_out_eps;
2010 dwc_otg_pcd_ep_t *ep;
2012 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
2014 INIT_LIST_HEAD (&pcd->gadget.ep_list);
2015 pcd->gadget.ep0 = &pcd->ep0.ep;
2016 pcd->gadget.speed = USB_SPEED_UNKNOWN;
2018 INIT_LIST_HEAD (&pcd->gadget.ep0->ep_list);
2021 * Initialize the EP0 structure.
2025 /* Init EP structure */
2030 /* Init DWC ep structure */
2032 ep->dwc_ep.active = 0;
2033 ep->dwc_ep.tx_fifo_num = 0;
2034 /* Control until ep is actvated */
2035 ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
2036 ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
2037 ep->dwc_ep.dma_addr = 0;
2038 ep->dwc_ep.start_xfer_buff = 0;
2039 ep->dwc_ep.xfer_buff = 0;
2040 ep->dwc_ep.xfer_len = 0;
2041 ep->dwc_ep.xfer_count = 0;
2042 ep->dwc_ep.sent_zlp = 0;
2043 ep->dwc_ep.total_len = 0;
2045 ep->dwc_ep.desc_addr = 0;
2046 ep->dwc_ep.dma_desc_addr = 0;
2049 /* Init the usb_ep structure. */
2050 ep->ep.name = names[0];
2051 ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
2054 * @todo NGS: What should the max packet size be set to
2055 * here? Before EP type is set?
2057 ep->ep.maxpacket = MAX_PACKET_SIZE;
2059 list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
2061 INIT_LIST_HEAD (&ep->queue);
2063 * Initialize the EP structures.
2066 hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 3;
2068 for (i = 1; in_ep_cntr < num_in_eps; i++)
2070 if((hwcfg1 & 0x1) == 0) {
2071 dwc_otg_pcd_ep_t *ep = &pcd->in_ep[in_ep_cntr];
2074 /* Init EP structure */
2079 /* Init DWC ep structure */
2080 ep->dwc_ep.is_in = 1;
2082 ep->dwc_ep.active = 0;
2083 ep->dwc_ep.tx_fifo_num = 0;
2085 /* Control until ep is actvated */
2086 ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
2087 ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
2088 ep->dwc_ep.dma_addr = 0;
2089 ep->dwc_ep.start_xfer_buff = 0;
2090 ep->dwc_ep.xfer_buff = 0;
2091 ep->dwc_ep.xfer_len = 0;
2092 ep->dwc_ep.xfer_count = 0;
2093 ep->dwc_ep.sent_zlp = 0;
2094 ep->dwc_ep.total_len = 0;
2096 ep->dwc_ep.desc_addr = 0;
2097 ep->dwc_ep.dma_desc_addr = 0;
2099 /* Init the usb_ep structure. */
2100 ep->ep.name = names[i];
2101 ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
2104 * @todo NGS: What should the max packet size be set to
2105 * here? Before EP type is set?
2107 ep->ep.maxpacket = MAX_PACKET_SIZE;
2109 list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
2111 INIT_LIST_HEAD (&ep->queue);
2117 hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 2;
2119 for (i = 1; out_ep_cntr < num_out_eps; i++)
2121 if((hwcfg1 & 0x1) == 0) {
2122 dwc_otg_pcd_ep_t *ep = &pcd->out_ep[out_ep_cntr];
2125 /* Init EP structure */
2130 /* Init DWC ep structure */
2131 ep->dwc_ep.is_in = 0;
2133 ep->dwc_ep.active = 0;
2134 ep->dwc_ep.tx_fifo_num = 0;
2135 /* Control until ep is actvated */
2136 ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
2137 ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
2138 ep->dwc_ep.dma_addr = 0;
2139 ep->dwc_ep.start_xfer_buff = 0;
2140 ep->dwc_ep.xfer_buff = 0;
2141 ep->dwc_ep.xfer_len = 0;
2142 ep->dwc_ep.xfer_count = 0;
2143 ep->dwc_ep.sent_zlp = 0;
2144 ep->dwc_ep.total_len = 0;
2147 /* Init the usb_ep structure. */
2148 ep->ep.name = names[15 + i];
2149 ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
2151 * @todo NGS: What should the max packet size be set to
2152 * here? Before EP type is set?
2154 ep->ep.maxpacket = MAX_PACKET_SIZE;
2156 list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
2158 INIT_LIST_HEAD (&ep->queue);
2163 /* remove ep0 from the list. There is a ep0 pointer.*/
2164 list_del_init (&pcd->ep0.ep.ep_list);
2166 pcd->ep0state = EP0_DISCONNECT;
2167 pcd->ep0.ep.maxpacket = MAX_EP0_SIZE;
2168 pcd->ep0.dwc_ep.maxpacket = MAX_EP0_SIZE;
2169 pcd->ep0.dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
2173 * This function releases the Gadget device.
2174 * required by device_unregister().
2176 * @todo Should this do something? Should it free the PCD?
2178 static void dwc_otg_pcd_gadget_release(struct device *dev)
2180 DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, dev);
2186 * This function initialized the PCD portion of the driver.
2190 int dwc_otg_pcd_init(struct device *dev)
2192 static char pcd_name[] = "dwc_otg_pcd";
2194 dwc_otg_core_if_t* core_if;
2195 dwc_otg_dev_if_t* dev_if;
2196 dwc_otg_device_t *otg_dev = dev_get_drvdata(dev);
2200 DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n",__func__, dev);
2202 * Allocate PCD structure
2204 pcd = kmalloc(sizeof(dwc_otg_pcd_t), GFP_KERNEL);
2210 memset(pcd, 0, sizeof(dwc_otg_pcd_t));
2211 spin_lock_init(&pcd->lock);
2215 pcd->gadget.name = pcd_name;
2216 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
2217 strcpy(pcd->gadget.dev.bus_id, "gadget");
2219 dev_set_name(&pcd->gadget.dev, "%s", "gadget");
2222 pcd->otg_dev = dev_get_drvdata(dev);
2224 pcd->gadget.dev.parent = dev;
2225 pcd->gadget.dev.release = dwc_otg_pcd_gadget_release;
2226 pcd->gadget.ops = &dwc_otg_pcd_ops;
2228 core_if = GET_CORE_IF(pcd);
2229 dev_if = core_if->dev_if;
2231 if(core_if->hwcfg4.b.ded_fifo_en) {
2232 DWC_PRINT("Dedicated Tx FIFOs mode\n");
2235 DWC_PRINT("Shared Tx FIFO mode\n");
2238 /* If the module is set to FS or if the PHY_TYPE is FS then the gadget
2239 * should not report as dual-speed capable. replace the following line
2240 * with the block of code below it once the software is debugged for
2241 * this. If is_dualspeed = 0 then the gadget driver should not report
2242 * a device qualifier descriptor when queried. */
2243 if ((GET_CORE_IF(pcd)->core_params->speed == DWC_SPEED_PARAM_FULL) ||
2244 ((GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == 2) &&
2245 (GET_CORE_IF(pcd)->hwcfg2.b.fs_phy_type == 1) &&
2246 (GET_CORE_IF(pcd)->core_params->ulpi_fs_ls))) {
2247 pcd->gadget.is_dualspeed = 0;
2250 pcd->gadget.is_dualspeed = 1;
2253 if ((otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE) ||
2254 (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST) ||
2255 (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
2256 (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
2257 pcd->gadget.is_otg = 0;
2260 pcd->gadget.is_otg = 1;
2265 /* Register the gadget device */
2266 retval = device_register(&pcd->gadget.dev);
2274 * Initialized the Core for Device mode.
2276 if (dwc_otg_is_device_mode(core_if)) {
2277 dwc_otg_core_dev_init(core_if);
2281 * Initialize EP structures
2283 dwc_otg_pcd_reinit(pcd);
2286 * Register the PCD Callbacks.
2288 dwc_otg_cil_register_pcd_callbacks(otg_dev->core_if, &pcd_callbacks,
2291 * Setup interupt handler
2293 DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", otg_dev->irq);
2294 retval = request_irq(otg_dev->irq, dwc_otg_pcd_irq,
2295 IRQF_SHARED, pcd->gadget.name, pcd);
2297 DWC_ERROR("request of irq%d failed\n", otg_dev->irq);
2298 device_unregister(&pcd->gadget.dev);
2304 * Initialize the DMA buffer for SETUP packets
2306 if (GET_CORE_IF(pcd)->dma_enable) {
2307 pcd->setup_pkt = dma_alloc_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, &pcd->setup_pkt_dma_handle, 0);
2308 if (pcd->setup_pkt == 0) {
2309 free_irq(otg_dev->irq, pcd);
2310 device_unregister(&pcd->gadget.dev);
2315 pcd->status_buf = dma_alloc_coherent (NULL, sizeof (uint16_t), &pcd->status_buf_dma_handle, 0);
2316 if (pcd->status_buf == 0) {
2317 dma_free_coherent(NULL, sizeof(*pcd->setup_pkt), pcd->setup_pkt, pcd->setup_pkt_dma_handle);
2318 free_irq(otg_dev->irq, pcd);
2319 device_unregister(&pcd->gadget.dev);
2324 if (GET_CORE_IF(pcd)->dma_desc_enable) {
2325 dev_if->setup_desc_addr[0] = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_setup_desc_addr[0], 1);
2326 dev_if->setup_desc_addr[1] = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_setup_desc_addr[1], 1);
2327 dev_if->in_desc_addr = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_in_desc_addr, 1);
2328 dev_if->out_desc_addr = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_out_desc_addr, 1);
2330 if(dev_if->setup_desc_addr[0] == 0
2331 || dev_if->setup_desc_addr[1] == 0
2332 || dev_if->in_desc_addr == 0
2333 || dev_if->out_desc_addr == 0 ) {
2335 if(dev_if->out_desc_addr)
2336 dwc_otg_ep_free_desc_chain(dev_if->out_desc_addr, dev_if->dma_out_desc_addr, 1);
2337 if(dev_if->in_desc_addr)
2338 dwc_otg_ep_free_desc_chain(dev_if->in_desc_addr, dev_if->dma_in_desc_addr, 1);
2339 if(dev_if->setup_desc_addr[1])
2340 dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[1], dev_if->dma_setup_desc_addr[1], 1);
2341 if(dev_if->setup_desc_addr[0])
2342 dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[0], dev_if->dma_setup_desc_addr[0], 1);
2345 dma_free_coherent(NULL, sizeof(*pcd->status_buf), pcd->status_buf, pcd->setup_pkt_dma_handle);
2346 dma_free_coherent(NULL, sizeof(*pcd->setup_pkt), pcd->setup_pkt, pcd->setup_pkt_dma_handle);
2348 free_irq(otg_dev->irq, pcd);
2349 device_unregister(&pcd->gadget.dev);
2357 pcd->setup_pkt = kmalloc (sizeof (*pcd->setup_pkt) * 5, GFP_KERNEL);
2358 if (pcd->setup_pkt == 0) {
2359 free_irq(otg_dev->irq, pcd);
2360 device_unregister(&pcd->gadget.dev);
2365 pcd->status_buf = kmalloc (sizeof (uint16_t), GFP_KERNEL);
2366 if (pcd->status_buf == 0) {
2367 kfree(pcd->setup_pkt);
2368 free_irq(otg_dev->irq, pcd);
2369 device_unregister(&pcd->gadget.dev);
2376 /* Initialize tasklet */
2377 start_xfer_tasklet.data = (unsigned long)pcd;
2378 pcd->start_xfer_tasklet = &start_xfer_tasklet;
2386 void dwc_otg_pcd_remove(struct device *dev)
2388 dwc_otg_device_t *otg_dev = dev_get_drvdata(dev);
2389 dwc_otg_pcd_t *pcd = otg_dev->pcd;
2390 dwc_otg_dev_if_t* dev_if = GET_CORE_IF(pcd)->dev_if;
2392 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
2397 free_irq(otg_dev->irq, pcd);
2399 /* start with the driver above us */
2401 /* should have been done already by driver model core */
2402 DWC_WARN("driver '%s' is still registered\n",
2403 pcd->driver->driver.name);
2404 usb_gadget_unregister_driver(pcd->driver);
2406 device_unregister(&pcd->gadget.dev);
2408 if (GET_CORE_IF(pcd)->dma_enable) {
2409 dma_free_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, pcd->setup_pkt, pcd->setup_pkt_dma_handle);
2410 dma_free_coherent (NULL, sizeof (uint16_t), pcd->status_buf, pcd->status_buf_dma_handle);
2411 if (GET_CORE_IF(pcd)->dma_desc_enable) {
2412 dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[0], dev_if->dma_setup_desc_addr[0], 1);
2413 dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[1], dev_if->dma_setup_desc_addr[1], 1);
2414 dwc_otg_ep_free_desc_chain(dev_if->in_desc_addr, dev_if->dma_in_desc_addr, 1);
2415 dwc_otg_ep_free_desc_chain(dev_if->out_desc_addr, dev_if->dma_out_desc_addr, 1);
2419 kfree (pcd->setup_pkt);
2420 kfree (pcd->status_buf);
2428 * This function registers a gadget driver with the PCD.
2430 * When a driver is successfully registered, it will receive control
2431 * requests including set_configuration(), which enables non-control
2432 * requests. then usb traffic follows until a disconnect is reported.
2433 * then a host may connect again, or the driver might get unbound.
2435 * @param driver The driver being registered
2437 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
2438 int usb_gadget_probe_driver(struct usb_gadget_driver *driver, int (*bind)(struct usb_gadget *))
2440 int usb_gadget_register_driver(struct usb_gadget_driver *driver)
2444 int (*d_bind)(struct usb_gadget *);
2445 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
2448 d_bind = driver->bind;
2451 DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", driver->driver.name);
2453 if (!driver || driver->speed == USB_SPEED_UNKNOWN ||
2456 !driver->disconnect ||
2458 DWC_DEBUGPL(DBG_PCDV,"EINVAL\n");
2462 DWC_DEBUGPL(DBG_PCDV,"ENODEV\n");
2465 if (s_pcd->driver != 0) {
2466 DWC_DEBUGPL(DBG_PCDV,"EBUSY (%p)\n", s_pcd->driver);
2470 /* hook up the driver */
2471 s_pcd->driver = driver;
2472 s_pcd->gadget.dev.driver = &driver->driver;
2474 DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
2475 retval = d_bind(&s_pcd->gadget);
2477 DWC_ERROR("bind to driver %s --> error %d\n",
2478 driver->driver.name, retval);
2480 s_pcd->gadget.dev.driver = 0;
2483 DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
2484 driver->driver.name);
2488 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
2489 EXPORT_SYMBOL(usb_gadget_probe_driver);
2491 EXPORT_SYMBOL(usb_gadget_register_driver);
2495 * This function unregisters a gadget driver
2497 * @param driver The driver being unregistered
2499 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
2501 //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver);
2504 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
2508 if (driver == 0 || driver != s_pcd->driver) {
2509 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
2514 driver->unbind(&s_pcd->gadget);
2517 DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n",
2518 driver->driver.name);
2521 EXPORT_SYMBOL(usb_gadget_unregister_driver);
2523 #endif /* DWC_HOST_ONLY */