|
@@ -238,8 +238,27 @@ static void cppi41_dma_callback(void *private_data,
|
|
transferred < cppi41_channel->packet_sz)
|
|
transferred < cppi41_channel->packet_sz)
|
|
cppi41_channel->prog_len = 0;
|
|
cppi41_channel->prog_len = 0;
|
|
|
|
|
|
- if (cppi41_channel->is_tx)
|
|
|
|
- empty = musb_is_tx_fifo_empty(hw_ep);
|
|
|
|
|
|
+ if (cppi41_channel->is_tx) {
|
|
|
|
+ u8 type;
|
|
|
|
+
|
|
|
|
+ if (is_host_active(musb))
|
|
|
|
+ type = hw_ep->out_qh->type;
|
|
|
|
+ else
|
|
|
|
+ type = hw_ep->ep_in.type;
|
|
|
|
+
|
|
|
|
+ if (type == USB_ENDPOINT_XFER_ISOC)
|
|
|
|
+ /*
|
|
|
|
+ * Don't use the early-TX-interrupt workaround below
|
|
|
|
+ * for Isoch transfter. Since Isoch are periodic
|
|
|
|
+ * transfer, by the time the next transfer is
|
|
|
|
+ * scheduled, the current one should be done already.
|
|
|
|
+ *
|
|
|
|
+ * This avoids audio playback underrun issue.
|
|
|
|
+ */
|
|
|
|
+ empty = true;
|
|
|
|
+ else
|
|
|
|
+ empty = musb_is_tx_fifo_empty(hw_ep);
|
|
|
|
+ }
|
|
|
|
|
|
if (!cppi41_channel->is_tx || empty) {
|
|
if (!cppi41_channel->is_tx || empty) {
|
|
cppi41_trans_done(cppi41_channel);
|
|
cppi41_trans_done(cppi41_channel);
|