The implementation is derived from the fsl_udc_core code in fsl_ep_enable and makes basic iso handling possible.
Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> Signed-off-by: Marc Kleine-Budde <m...@pengutronix.de> --- Changes since v4: - rebased on the new alignment patch - changed indention to tabs - removed spare brakets - added special handling for iso in ep_queue and ep_halt - changed TODO list entry in core.c Changes since v3: - added QH_ISO_TRANS macro - removed unused operations mentioned by Peter Changes since v2: - fixed usage of variable max - reworked on writel/readl patches Changes since v1: - fixed coding style issues mentioned by Sergei drivers/usb/chipidea/core.c | 2 +- drivers/usb/chipidea/udc.c | 15 ++++++++++++--- drivers/usb/chipidea/udc.h | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 47b8da2..82de38b 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -43,7 +43,7 @@ * * TODO List * - OTG - * - Isochronous & Interrupt Traffic + * - Interrupt Traffic * - Handle requests which spawns into several TDs * - GET_STATUS(device) - always reports 0 * - Gadget API (majority of optional features) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 567ce89..cab349b 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1010,6 +1010,8 @@ static int ep_enable(struct usb_ep *ep, unsigned long flags; u32 val = 0; + unsigned short max; + if (ep == NULL || desc == NULL) return -EINVAL; @@ -1026,19 +1028,19 @@ static int ep_enable(struct usb_ep *ep, mEp->num = usb_endpoint_num(desc); mEp->type = usb_endpoint_type(desc); - mEp->ep.maxpacket = usb_endpoint_maxp(desc); + max = mEp->ep.maxpacket = usb_endpoint_maxp(desc); trace_ci_ep_enable(mEp, 0); if (mEp->type == USB_ENDPOINT_XFER_CONTROL) val |= QH_IOS; else if (mEp->type == USB_ENDPOINT_XFER_ISOC) - val &= ~QH_MULT; + val |= QH_ISO_TRANS(max) << __ffs(QH_MULT); if (mEp->num) val |= QH_ZLT; - val |= (mEp->ep.maxpacket << __ffs(QH_MAX_PKT)) & QH_MAX_PKT; + val |= (max << __ffs(QH_MAX_PKT)) & QH_MAX_PKT; mEp->qh.ptr->cap = val; mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */ @@ -1182,6 +1184,10 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, } } + if (usb_endpoint_xfer_isoc(mEp->ep.desc) + && mReq->req.length > mEp->ep.maxpacket) + return -EMSGSIZE; + /* first nuke then test link, e.g. previous status has not sent */ if (!list_empty(&mReq->queue)) { retval = -EBUSY; @@ -1268,6 +1274,9 @@ static int ep_set_halt(struct usb_ep *ep, int value) if (ep == NULL || mEp->ep.desc == NULL) return -EINVAL; + if (usb_endpoint_xfer_isoc(mEp->ep.desc)) + return -EOPNOTSUPP; + spin_lock_irqsave(mEp->lock, flags); #ifndef STALL_IN diff --git a/drivers/usb/chipidea/udc.h b/drivers/usb/chipidea/udc.h index 4b1315a..65ed812 100644 --- a/drivers/usb/chipidea/udc.h +++ b/drivers/usb/chipidea/udc.h @@ -48,6 +48,7 @@ struct ci13xxx_qh { #define QH_MAX_PKT (0x07FFUL << 16) #define QH_ZLT BIT(29) #define QH_MULT (0x0003UL << 30) +#define QH_ISO_TRANS(x) (1 + ((x >> 11) & 0x03)) /* 1 */ u32 curr; /* 2 - 8 */ -- 1.8.2.rc2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html