This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/PROCESSOR-SDK-AM57X: USB audio gadget issue

Part Number: PROCESSOR-SDK-AM57X

Tool/software: Linux

Hi,

I am trying to run g_audio on AM572x with ti-processor-sdk-linux-am57xx-evm-05.00.00.15.
But it did not work with the default code, I modified the dwc3 driver and built it.

- g_audio_tmp.diff

--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -927,7 +927,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
 			 */
 			if (speed == USB_SPEED_HIGH) {
 				struct usb_ep *ep = &dep->endpoint;
-				unsigned int mult = ep->mult - 1;
+				unsigned int mult = 2;
 				unsigned int maxp = usb_endpoint_maxp(ep->desc);
 
 				if (length <= (2 * maxp))
@@ -1411,68 +1411,6 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
 		if (r == req) {
 			/* wait until it is processed */
 			dwc3_stop_active_transfer(dwc, dep->number, true);
-
-			/*
-			 * If request was already started, this means we had to
-			 * stop the transfer. With that we also need to ignore
-			 * all TRBs used by the request, however TRBs can only
-			 * be modified after completion of END_TRANSFER
-			 * command. So what we do here is that we wait for
-			 * END_TRANSFER completion and only after that, we jump
-			 * over TRBs by clearing HWO and incrementing dequeue
-			 * pointer.
-			 *
-			 * Note that we have 2 possible types of transfers here:
-			 *
-			 * i) Linear buffer request
-			 * ii) SG-list based request
-			 *
-			 * SG-list based requests will have r->num_pending_sgs
-			 * set to a valid number (> 0). Linear requests,
-			 * normally use a single TRB.
-			 *
-			 * For each of these two cases, if r->unaligned flag is
-			 * set, one extra TRB has been used to align transfer
-			 * size to wMaxPacketSize.
-			 *
-			 * All of these cases need to be taken into
-			 * consideration so we don't mess up our TRB ring
-			 * pointers.
-			 */
-			wait_event_lock_irq(dep->wait_end_transfer,
-					!(dep->flags & DWC3_EP_END_TRANSFER_PENDING),
-					dwc->lock);
-
-			if (!r->trb)
-				goto out0;
-
-			if (r->num_pending_sgs) {
-				struct dwc3_trb *trb;
-				int i = 0;
-
-				for (i = 0; i < r->num_pending_sgs; i++) {
-					trb = r->trb + i;
-					trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
-					dwc3_ep_inc_deq(dep);
-				}
-
-				if (r->unaligned || r->zero) {
-					trb = r->trb + r->num_pending_sgs + 1;
-					trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
-					dwc3_ep_inc_deq(dep);
-				}
-			} else {
-				struct dwc3_trb *trb = r->trb;
-
-				trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
-				dwc3_ep_inc_deq(dep);
-
-				if (r->unaligned || r->zero) {
-					trb = r->trb + 1;
-					trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
-					dwc3_ep_inc_deq(dep);
-				}
-			}
 			goto out1;
 		}
 		dev_err(dwc->dev, "request %pK was not queued to %s\n",

Currently, it is working on the AM572x board.
----------------
target$ modprobe -v g_audio

host$ aplay - D plughw: 1,0 test.wav
target$ arecord - f dat - t wav - D plughw: 2, 0 | aplay - D plughw: 0,0
- I can listen test.wav from audio-out on the AM572x board.

host$ arecord - f dat - t wav - D plughw: 1, 0 | aplay - D plughw: 0,0
target$ aplay - D plughw: 2, 0 test.wav
- I can listen test.wav from audio-out on the Host PC.
----------------

I have a few questions.

1. Is the modificatoin of "g_audio_tmp.diff" correct?
In particular, we deleted processing in dwc3_gadget_ep_dequeue(), but is there a problem?
Also, is there any other part to be fixed?

2. When arecord is executed on the Host PC, the Audio Data is transferred with isochronous IN,
at this time, 0-byte data is transferred from the AM572x board at the beginning.
Normal data(not 0-bytes) is transferred in the second and subsequent.

I want to send the normal data (not 0-bytes) from the beginning.
Please teach me how to fix it.
In the g_audio on AM335x(processor-sdk-linux), normal data (not 0 bytes) is transmitted from the beginning.

Best Regards,
Yasun

  • Hi Yasun-san,

    I will check the g_audio usecase and get you back on your question 1 & 2.
    Did you use the SDK v5.0.0.15 too when testing on AM335x?
  • Hi Bin-san,

    Thank you for your quick reply.

    Before v05.00.00.15 was released, I was testing on AM335x/AM57x with ti-linux-4.14.y (ti-linux-kernel.git).

    $ git clone git://git.ti.com/ti-linux-kernel/ti-linux-kernel.git
    $ git checkout origin/ti-linux-4.14.y

    The modifications are the same as described above.

    I will test on AM335x with v5.0.0.15 and get you back.

    Best Regards,
    Yasun
  • Hi Bin-san,

    I checked on AM335x with SDK v5.0.0.15.

    As mentioned earlier, normal data (not 0-bytes) is transmitted from the beginning.
    For AM335x, we have not changed any source code of the g_audio driver.

    Best Regards,
    Yasun
  • Yasun-san,

    In my test, g_audio works in SDK v4.3 but broken in v5.0.0.15. I am currently checking the kernel changes to see if I can find which kernel patch causes the regression. I will update once I have a result.
  • Yasun-san,

    Your patch exactly touches the two spots in kernel which cause g_audio broken in kernel v4.14.40.

    Your first change (related to the mult variable) is the same as the kernel commit ec5bb87e4e2a ("usb: dwc3: gadget: Fix PCM1 for ISOC EP with ep->mult less than 3"), I expect the kernel community will back port this patch to v4.14 tree.

    Similar to your second change, the kernel community is attempting to fix it recently with the patch in patchwork.kernel.org/.../. Even through the dwc3 driver maintainer suggested rework, I tested the two patches on TI v4.14.y branch and g_audio seems working fine.
  • Yasunori Saito said:
    2. When arecord is executed on the Host PC, the Audio Data is transferred with isochronous IN,
    at this time, 0-byte data is transferred from the AM572x board at the beginning.
    Normal data(not 0-bytes) is transferred in the second and subsequent.

    The non 0-byte packets are transferred only until the gadget started aplay, correct? If so, this behavior is normal. Isoch transfer is periodical transfer, the transceiver should respond the Isoch IN tokens with 0-byte packets or packets which only have Protocol header bytes (UAC header in this case), when there are not real data ready yet.

    Yasunori Saito said:
    In the g_audio on AM335x(processor-sdk-linux), normal data (not 0 bytes) is transmitted from the beginning.

    In this case, the transmitted packets have only 2 bytes, right? They are just the UAC header, no real audio data.

    So, I don't think it is a protocol problem that am57x g_audio transmitting 0-byte UAC packets.

  • Hi Bin-san,

    Thank you for your reply.

    The difference between AM335x and AM572x when the arecord is started on the HOST PC is as shown in the attached image.
    Only arecord is starting on the host PC, and no aplay is executing on the gadget side(AM335x/AM572x).

    Captured with USB Protocol Analyzer:
    For AM335x


    For AM572x


    In AM335x, the 192 bytes are transmitted at the beginning.
    In AM572x, the 0 bytes are transmitted at the beginning.
    I think that this behavior in AM572x is normal, because the transceiver should respond the Isoch IN tokens with 0-byte packets if there are not data ready yet.
    Is this correct?

    Is there a way to erase this 0-byte data packets?

    Best Regards,
    Yasun

  • Yasun-san,

    I confirm your observations - the very first Isoch packet from am335x is 192 bytes, but it is 0 byte from am57x. As you said, they are both normal from the perspective of Isoch transfers, but I am not sure if that is the case for UAC too, since the details of USB functions (such as UAC) are out of my support scope and I didn't read the UAC Spec.

    But it seems the 0-byte packet doesn't have any side effect, is there any reason why you want to remove it?

  • Bin-san,

    The reasons are:
    - Problems may be occurred depending on the host side driver and application.
    - Want to identify correctly the error conditions. (should be transferred with the expected data sizes at the normal conditions.)

    Best Regards,
    Yasun
  • Yasun-san,

    I quickly read through the UAC 2.0 Spec, but didn't find any information of specifying non-zero Isoch packet for audio streaming, so I believe the first 0-byte Isoch packet on AM57x is legal, then I have no reason to request the kernel community to eliminate the first 0-byte packet.

    Regarding your reasons, since transferring 0-byte Isoch packets is not an error condition, the host side driver should already handle it properly.
  • Bin-san,

    Thank you for your help.
    As you said, I think that the host side should handle it properly.

    Best Regards,
    Yasun