diff options
-rw-r--r-- | drivers/usb/chipidea/core.c | 2 | ||||
-rw-r--r-- | drivers/usb/chipidea/udc.c | 20 | ||||
-rw-r--r-- | drivers/usb/chipidea/udc.h | 1 |
3 files changed, 21 insertions, 2 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 475c9c114689..ade1b91b5ae7 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c | |||
@@ -43,7 +43,7 @@ | |||
43 | * | 43 | * |
44 | * TODO List | 44 | * TODO List |
45 | * - OTG | 45 | * - OTG |
46 | * - Isochronous & Interrupt Traffic | 46 | * - Interrupt Traffic |
47 | * - Handle requests which spawns into several TDs | 47 | * - Handle requests which spawns into several TDs |
48 | * - GET_STATUS(device) - always reports 0 | 48 | * - GET_STATUS(device) - always reports 0 |
49 | * - Gadget API (majority of optional features) | 49 | * - Gadget API (majority of optional features) |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index b501346484ae..8aed28855c04 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -466,6 +466,14 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | |||
466 | mEp->qh.ptr->td.token &= | 466 | mEp->qh.ptr->td.token &= |
467 | cpu_to_le32(~(TD_STATUS_HALTED|TD_STATUS_ACTIVE)); | 467 | cpu_to_le32(~(TD_STATUS_HALTED|TD_STATUS_ACTIVE)); |
468 | 468 | ||
469 | if (mEp->type == USB_ENDPOINT_XFER_ISOC) { | ||
470 | u32 mul = mReq->req.length / mEp->ep.maxpacket; | ||
471 | |||
472 | if (mReq->req.length % mEp->ep.maxpacket) | ||
473 | mul++; | ||
474 | mEp->qh.ptr->cap |= mul << __ffs(QH_MULT); | ||
475 | } | ||
476 | |||
469 | wmb(); /* synchronize before ep prime */ | 477 | wmb(); /* synchronize before ep prime */ |
470 | 478 | ||
471 | ret = hw_ep_prime(ci, mEp->num, mEp->dir, | 479 | ret = hw_ep_prime(ci, mEp->num, mEp->dir, |
@@ -678,6 +686,12 @@ static int _ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
678 | } | 686 | } |
679 | } | 687 | } |
680 | 688 | ||
689 | if (usb_endpoint_xfer_isoc(mEp->ep.desc) && | ||
690 | mReq->req.length > (1 + mEp->ep.mult) * mEp->ep.maxpacket) { | ||
691 | dev_err(mEp->ci->dev, "request length too big for isochronous\n"); | ||
692 | return -EMSGSIZE; | ||
693 | } | ||
694 | |||
681 | /* first nuke then test link, e.g. previous status has not sent */ | 695 | /* first nuke then test link, e.g. previous status has not sent */ |
682 | if (!list_empty(&mReq->queue)) { | 696 | if (!list_empty(&mReq->queue)) { |
683 | dev_err(mEp->ci->dev, "request already in queue\n"); | 697 | dev_err(mEp->ci->dev, "request already in queue\n"); |
@@ -1060,7 +1074,8 @@ static int ep_enable(struct usb_ep *ep, | |||
1060 | mEp->num = usb_endpoint_num(desc); | 1074 | mEp->num = usb_endpoint_num(desc); |
1061 | mEp->type = usb_endpoint_type(desc); | 1075 | mEp->type = usb_endpoint_type(desc); |
1062 | 1076 | ||
1063 | mEp->ep.maxpacket = usb_endpoint_maxp(desc); | 1077 | mEp->ep.maxpacket = usb_endpoint_maxp(desc) & 0x07ff; |
1078 | mEp->ep.mult = QH_ISO_MULT(usb_endpoint_maxp(desc)); | ||
1064 | 1079 | ||
1065 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) | 1080 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) |
1066 | cap |= QH_IOS; | 1081 | cap |= QH_IOS; |
@@ -1246,6 +1261,9 @@ static int ep_set_halt(struct usb_ep *ep, int value) | |||
1246 | if (ep == NULL || mEp->ep.desc == NULL) | 1261 | if (ep == NULL || mEp->ep.desc == NULL) |
1247 | return -EINVAL; | 1262 | return -EINVAL; |
1248 | 1263 | ||
1264 | if (usb_endpoint_xfer_isoc(mEp->ep.desc)) | ||
1265 | return -EOPNOTSUPP; | ||
1266 | |||
1249 | spin_lock_irqsave(mEp->lock, flags); | 1267 | spin_lock_irqsave(mEp->lock, flags); |
1250 | 1268 | ||
1251 | #ifndef STALL_IN | 1269 | #ifndef STALL_IN |
diff --git a/drivers/usb/chipidea/udc.h b/drivers/usb/chipidea/udc.h index d12e8b59b110..a75724a19e1a 100644 --- a/drivers/usb/chipidea/udc.h +++ b/drivers/usb/chipidea/udc.h | |||
@@ -50,6 +50,7 @@ struct ci13xxx_qh { | |||
50 | #define QH_MAX_PKT (0x07FFUL << 16) | 50 | #define QH_MAX_PKT (0x07FFUL << 16) |
51 | #define QH_ZLT BIT(29) | 51 | #define QH_ZLT BIT(29) |
52 | #define QH_MULT (0x0003UL << 30) | 52 | #define QH_MULT (0x0003UL << 30) |
53 | #define QH_ISO_MULT(x) ((x >> 11) & 0x03) | ||
53 | /* 1 */ | 54 | /* 1 */ |
54 | u32 curr; | 55 | u32 curr; |
55 | /* 2 - 8 */ | 56 | /* 2 - 8 */ |