aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRamneek Mehresh <ramneek.mehresh@freescale.com>2011-05-04 10:11:55 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-06 21:19:39 -0400
commitea437f39234f7f991428886f16aae5c264cffe62 (patch)
treece34d093ed810893aa03f61edaf2a24c3aaaf0d7
parent69248d4281fda03dd4da982e1d51f6b22cf1a109 (diff)
fsl/usb: Unused endpoint failure for USB gadget
Though USB controller works without this most of the time, an issue was faced where USB was configured as printer device and it was dropping first packet(64 bytes) in full speed mode due to DATA PID mismatch. The problem gets resolved once unused endpoints are configured as bulk. As per P1020 RM (Table17-31, bits 19-18, bits 3-2) "When only one endpoint (RX or TX, but not both) of an endpoint pair is used, the unused endpoint should be configured as a bulk type endpoint." So according to the RM, this patch is initializing TX and RX endpoints as bulk type Signed-off-by: Suchit Lepcha <Suchit.Lepcha@freescale.com> Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 999eafe89653..2cd9a60c7f3a 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (C) 2004-2007 Freescale Semicondutor, Inc. All rights reserved. 2 * Copyright (C) 2004-2007,2011 Freescale Semiconductor, Inc.
3 * All rights reserved.
3 * 4 *
4 * Author: Li Yang <leoli@freescale.com> 5 * Author: Li Yang <leoli@freescale.com>
5 * Jiang Bo <tanya.jiang@freescale.com> 6 * Jiang Bo <tanya.jiang@freescale.com>
@@ -230,7 +231,8 @@ static void nuke(struct fsl_ep *ep, int status)
230 231
231static int dr_controller_setup(struct fsl_udc *udc) 232static int dr_controller_setup(struct fsl_udc *udc)
232{ 233{
233 unsigned int tmp, portctrl; 234 unsigned int tmp, portctrl, ep_num;
235 unsigned int max_no_of_ep;
234#ifndef CONFIG_ARCH_MXC 236#ifndef CONFIG_ARCH_MXC
235 unsigned int ctrl; 237 unsigned int ctrl;
236#endif 238#endif
@@ -298,6 +300,14 @@ static int dr_controller_setup(struct fsl_udc *udc)
298 udc->ep_qh, (int)tmp, 300 udc->ep_qh, (int)tmp,
299 fsl_readl(&dr_regs->endpointlistaddr)); 301 fsl_readl(&dr_regs->endpointlistaddr));
300 302
303 max_no_of_ep = (0x0000001F & fsl_readl(&dr_regs->dccparams));
304 for (ep_num = 1; ep_num < max_no_of_ep; ep_num++) {
305 tmp = fsl_readl(&dr_regs->endptctrl[ep_num]);
306 tmp &= ~(EPCTRL_TX_TYPE | EPCTRL_RX_TYPE);
307 tmp |= (EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT)
308 | (EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT);
309 fsl_writel(tmp, &dr_regs->endptctrl[ep_num]);
310 }
301 /* Config control enable i/o output, cpu endian register */ 311 /* Config control enable i/o output, cpu endian register */
302#ifndef CONFIG_ARCH_MXC 312#ifndef CONFIG_ARCH_MXC
303 if (udc->pdata->have_sysif_regs) { 313 if (udc->pdata->have_sysif_regs) {
@@ -391,12 +401,14 @@ static void dr_ep_setup(unsigned char ep_num, unsigned char dir,
391 if (ep_num) 401 if (ep_num)
392 tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST; 402 tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST;
393 tmp_epctrl |= EPCTRL_TX_ENABLE; 403 tmp_epctrl |= EPCTRL_TX_ENABLE;
404 tmp_epctrl &= ~EPCTRL_TX_TYPE;
394 tmp_epctrl |= ((unsigned int)(ep_type) 405 tmp_epctrl |= ((unsigned int)(ep_type)
395 << EPCTRL_TX_EP_TYPE_SHIFT); 406 << EPCTRL_TX_EP_TYPE_SHIFT);
396 } else { 407 } else {
397 if (ep_num) 408 if (ep_num)
398 tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST; 409 tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST;
399 tmp_epctrl |= EPCTRL_RX_ENABLE; 410 tmp_epctrl |= EPCTRL_RX_ENABLE;
411 tmp_epctrl &= ~EPCTRL_RX_TYPE;
400 tmp_epctrl |= ((unsigned int)(ep_type) 412 tmp_epctrl |= ((unsigned int)(ep_type)
401 << EPCTRL_RX_EP_TYPE_SHIFT); 413 << EPCTRL_RX_EP_TYPE_SHIFT);
402 } 414 }
@@ -619,10 +631,13 @@ static int fsl_ep_disable(struct usb_ep *_ep)
619 /* disable ep on controller */ 631 /* disable ep on controller */
620 ep_num = ep_index(ep); 632 ep_num = ep_index(ep);
621 epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); 633 epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]);
622 if (ep_is_in(ep)) 634 if (ep_is_in(ep)) {
623 epctrl &= ~EPCTRL_TX_ENABLE; 635 epctrl &= ~(EPCTRL_TX_ENABLE | EPCTRL_TX_TYPE);
624 else 636 epctrl |= EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT;
625 epctrl &= ~EPCTRL_RX_ENABLE; 637 } else {
638 epctrl &= ~(EPCTRL_RX_ENABLE | EPCTRL_TX_TYPE);
639 epctrl |= EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT;
640 }
626 fsl_writel(epctrl, &dr_regs->endptctrl[ep_num]); 641 fsl_writel(epctrl, &dr_regs->endptctrl[ep_num]);
627 642
628 udc = (struct fsl_udc *)ep->udc; 643 udc = (struct fsl_udc *)ep->udc;