All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 0/8] USB Audio Gadget part 2: Feedback endpoint, Volume/Mute support
@ 2021-03-01 16:49 Johannes Freyberger
  2021-03-01 21:34 ` Ruslan Bilovol
  0 siblings, 1 reply; 5+ messages in thread
From: Johannes Freyberger @ 2021-03-01 16:49 UTC (permalink / raw)
  To: ruslan.bilovol
  Cc: balbi, corbet, gregkh, gschmottlach, linux-doc, linux-kernel, linux-usb

Hi Ruslan,

thanks for all your efforts to make the USB Audio Gadget work in Win10 using
UAC2. Meanwhile I managed to apply and compile your previous modifications
and now my Raspberry PI shows up in the Windows Device Manager as a valid
UAC2 audio device. Unfortunately it still doesn't work to transfer any audio
as it seems the audio endpoints or the topology is not working. I checked it
with some tools and found one providing some information on the USB part
(it's called UVCview.exe and is part of the Windows Driver Kit). Here's the
output which I hope can give some hints on the problems still existing in
this driver:

          ---===>Device Information<===---
English product name: "Linux USB Audio Gadget"

ConnectionStatus:                  
Current Config Value:              0x01  -> Device Bus Speed: High
Device Address:                    0x0F
Open Pipes:                           0
*!*ERROR:  No open pipes!

          ===>Device Descriptor<===
bLength:                           0x12
bDescriptorType:                   0x01
bcdUSB:                          0x0200
bDeviceClass:                      0xEF  -> This is a Multi-interface
Function Code Device
bDeviceSubClass:                   0x02  -> This is the Common Class Sub
Class
bDeviceProtocol:                   0x01  -> This is the Interface
Association Descriptor protocol
bMaxPacketSize0:                   0x40 = (64) Bytes
idVendor:                        0x1D6B = The Linux Foundation
idProduct:                       0x0101
bcdDevice:                       0x0510
iManufacturer:                     0x01
     English (United States)  "Linux 5.10.17-v7l-R3LAY_TEST+ with
fe980000.usb"
iProduct:                          0x02
     English (United States)  "Linux USB Audio Gadget"
iSerialNumber:                     0x00
bNumConfigurations:                0x01

          ===>Configuration Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x02
wTotalLength:                    0x00E2  -> Validated
bNumInterfaces:                    0x03
bConfigurationValue:               0x01
iConfiguration:                    0x00
bmAttributes:                      0xC0  -> Bus Powered
MaxPower:                          0x01 =   2 mA

          ===>IAD Descriptor<===
bLength:                           0x08
bDescriptorType:                   0x0B
bFirstInterface:                   0x00
bInterfaceCount:                   0x03
bFunctionClass:                    0x01  -> Audio Interface Class
bFunctionSubClass:                 0x00
*!*CAUTION:    This appears to be an invalid bFunctionSubClass
bFunctionProtocol:                 0x20
iFunction:                         0x04
     English (United States)  "R3lay PI"

          ===>Interface Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x04
bInterfaceNumber:                  0x00
bAlternateSetting:                 0x00
bNumEndpoints:                     0x00
bInterfaceClass:                   0x01  -> Audio Interface Class
bInterfaceSubClass:                0x01  -> Audio Control Interface SubClass
bInterfaceProtocol:                0x20
CAUTION:  This may be an invalid bInterfaceProtocol
iInterface:                        0x05
     English (United States)  "Topology Control"

          ===>Audio Control Interface Header Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x24
bDescriptorSubtype:                0x01
bcdADC:                          0x0200
wTotalLength:                    0x5308
bInCollection:                     0x00

          ===>Descriptor Hex Dump<===
bLength:                           0x08
bDescriptorType:                   0x24
08 24 0A 06 01 01 00 06 

          ===>Descriptor Hex Dump<===
bLength:                           0x08
bDescriptorType:                   0x24
08 24 0A 05 01 01 00 07 

          ===>Descriptor Hex Dump<===
bLength:                           0x11
bDescriptorType:                   0x24
11 24 02 01 01 01 00 05 02 03 00 00 00 00 03 00 
08 

          ===>Descriptor Hex Dump<===
bLength:                           0x11
bDescriptorType:                   0x24
11 24 02 02 00 02 00 06 02 03 00 00 00 00 03 00 
09 

          ===>Descriptor Hex Dump<===
bLength:                           0x0C
bDescriptorType:                   0x24
0C 24 03 04 01 01 00 02 06 03 00 0A 

          ===>Descriptor Hex Dump<===
bLength:                           0x0C
bDescriptorType:                   0x24
0C 24 03 03 00 03 00 01 05 03 00 0B 

          ===>Interface Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x04
bInterfaceNumber:                  0x01
bAlternateSetting:                 0x00
bNumEndpoints:                     0x00
bInterfaceClass:                   0x01  -> Audio Interface Class
bInterfaceSubClass:                0x02  -> Audio Streaming Interface
SubClass
bInterfaceProtocol:                0x20
CAUTION:  This may be an invalid bInterfaceProtocol
iInterface:                        0x0C
     English (United States)  "Playback Inactive"

          ===>Interface Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x04
bInterfaceNumber:                  0x01
bAlternateSetting:                 0x01
bNumEndpoints:                     0x02
bInterfaceClass:                   0x01  -> Audio Interface Class
bInterfaceSubClass:                0x02  -> Audio Streaming Interface
SubClass
bInterfaceProtocol:                0x20
CAUTION:  This may be an invalid bInterfaceProtocol
iInterface:                        0x0D
     English (United States)  "Playback Active"

          ===>Descriptor Hex Dump<===
bLength:                           0x10
bDescriptorType:                   0x24
10 24 01 01 00 01 01 00 00 00 02 03 00 00 00 00 

          ===>Audio Streaming Format Type Descriptor<===
bLength:                           0x06
bDescriptorType:                   0x24
bDescriptorSubtype:                0x02
bFormatType:                       0x01
bNrChannels:                       0x02
bSubframeSize:                     0x10
bBitResolution:                    0x07
bSamFreqType:                      0x05
tSamFreq[1]:                   0x380501 (3671297 Hz)
tSamFreq[2]:                   0x080401 (525313 Hz)
tSamFreq[3]:                   0x000125 (293 Hz)
tSamFreq[4]:                   0x000000 (0 Hz)
tSamFreq[5]:                   0x050700 (329472 Hz)

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x01  -> Direction: OUT - EndpointID: 1
bmAttributes:                      0x05  -> Isochronous Transfer Type
                   Synchronization Type = Asynchronous
Bulk Transfer Type
wMaxPacketSize:                  0x0138 = 1 transactions per microframe,
0x138 max bytes
bInterval:                         0x04

          ===>Descriptor Hex Dump<===
bLength:                           0x08
bDescriptorType:                   0x25
08 25 01 00 00 00 00 00 

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x81  -> Direction: IN - EndpointID: 1
bmAttributes:                      0x11  -> Isochronous Transfer Type
                   Synchronization Type = No Synchronization
Bulk Transfer Type
wMaxPacketSize:                  0x0004 = 1 transactions per microframe,
0x04 max bytes
bInterval:                         0x04

          ===>Interface Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x04
bInterfaceNumber:                  0x02
bAlternateSetting:                 0x00
bNumEndpoints:                     0x00
bInterfaceClass:                   0x01  -> Audio Interface Class
bInterfaceSubClass:                0x02  -> Audio Streaming Interface
SubClass
bInterfaceProtocol:                0x20
CAUTION:  This may be an invalid bInterfaceProtocol
iInterface:                        0x0E
     English (United States)  "Capture Inactive"

          ===>Interface Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x04
bInterfaceNumber:                  0x02
bAlternateSetting:                 0x01
bNumEndpoints:                     0x01
bInterfaceClass:                   0x01  -> Audio Interface Class
bInterfaceSubClass:                0x02  -> Audio Streaming Interface
SubClass
bInterfaceProtocol:                0x20
CAUTION:  This may be an invalid bInterfaceProtocol
iInterface:                        0x0F
     English (United States)  "Capture Active"

          ===>Descriptor Hex Dump<===
bLength:                           0x10
bDescriptorType:                   0x24
10 24 01 04 00 01 01 00 00 00 02 03 00 00 00 00 

          ===>Audio Streaming Format Type Descriptor<===
bLength:                           0x06
bDescriptorType:                   0x24
bDescriptorSubtype:                0x02
bFormatType:                       0x01
bNrChannels:                       0x02
bSubframeSize:                     0x10
bBitResolution:                    0x07
bSamFreqType:                      0x05
tSamFreq[1]:                   0xC40582 (12846466 Hz)
tSamFreq[2]:                   0x080400 (525312 Hz)
tSamFreq[3]:                   0x000125 (293 Hz)
tSamFreq[4]:                   0x000000 (0 Hz)
tSamFreq[5]:                   0x000000 (0 Hz)

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x82  -> Direction: IN - EndpointID: 2
bmAttributes:                      0x05  -> Isochronous Transfer Type
                   Synchronization Type = Asynchronous
Bulk Transfer Type
wMaxPacketSize:                  0x00C4 = 1 transactions per microframe,
0xC4 max bytes
bInterval:                         0x04

          ===>Descriptor Hex Dump<===
bLength:                           0x08
bDescriptorType:                   0x25
08 25 01 00 00 00 00 00


^ permalink raw reply	[flat|nested] 5+ messages in thread
* [PATCH 0/8] USB Audio Gadget part 2: Feedback endpoint, Volume/Mute support
@ 2021-03-01 13:05 Ruslan Bilovol
  2021-03-23 11:56 ` Greg Kroah-Hartman
  0 siblings, 1 reply; 5+ messages in thread
From: Ruslan Bilovol @ 2021-03-01 13:05 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Jonathan Corbet
  Cc: gschmottlach, linux-usb, linux-doc, linux-kernel

This is extendend version of "UAC2 Feedback endpoint" patch set
I've sent back in 2020 [1]. It is extended with
bi-directional Volume/Mute controls support for both UAC1
and UAC2 gadgets.

It fixes issues with enumeration in various operation systems
because of Feedback endpoint implementation, yet also adds
new Volume/Mute support which allows developers to control
UAC1/2 Gadget's Volume/Mute from the Host and in the same way
UAC1/2 Gadget can control Volume/Mute of the Host making it
closer to a real USB Audio card.

This patch set should be applied on top of USB Audio Gadget
part 1 fixes/improvements that I've sent previously to the
mailing list [2]

============ UAC2 Feedback Endpoint support ============

Current UAC2 gadget implements capture/sync paths
as two USB ISO ASYNC endpoints (IN and OUT).

This violates USB spec which says that ISO ASYNC OUT endpoint
should have feedback companion endpoint.
See USB2.0 spec  "5.12.4.1 Synchronization Type": asynchronous
sink provides explicit feedback (isochronous pipe).
Interesting that for ISO ASYNC *IN* endpoint respective
feedback isn't required since source provides implicit
feedforward (data stream).

While it's not an issue if UAC2 Gadget is connected to
Linux host (Linux ignores missing feedback endpoint),
with other hosts like Windows or MacOS the UAC2 Gadget
isn't enumerated due to missing feedback endpoint.

This patch series adds feedback endpoint support to
UAC2 function, new control to UAC2 mixer which can
be used by userspace tools (like alsaloop from alsa-utils)
for updating feedback frequency reported to the host.
This is useful for usecases when UAC2 Gadget's audio
samples are played to another codec or audio card
with its own internal freerunning clock so host can
be notified that more/less samples are required.

The alsaloop tool requires some (relatively small)
modifications in order to start support driving
feedback frequency through UAC2 mixer control.
That change have been sent as a separate patch
to ALSA community [3].

Also added ability to switch ISO ASYNC OUT endpoint into
adaptive endpoint which doesn't require feedback endpoint
(as per USB spec).

======== UAC1/2 Volume/Mute controls support ==========

Volume and Mute controls are traditionally presented in
USB Audio cards that are available on the market,
and Hosts usually expect they exist in the attached devices.

However, Linux UAC gadget previosly didn't have such
functinality which (depending on Host's operation system)
was causing different behaviour: Linux hosts (usually) in
this case can adjust volume by changing audio sample's
amplitude that are sent to the gadget. Other hosts may
stuck with maximum volume and can't adjust it for the
Linux UAC gadget device.

Volume/Mute controls support is quite useful feature.
If implemented according to UAC1/2 spec, it allows to
control volume in both directions: from the Host to Gadget
and from Gadget to the Host. To do it, it's required to add
new Feature Unit descriptor to existing UAC1/2 Gadget
topology and add new interrupt endpoint so Volume/Mute
changes can be reported to the Host.

This has been tested with Linux/MacOS/Windows(7,10) hosts,
by attaching alsamixer to the UAC1/2 ALSA card on Gadget
side, and using available Volume/Mute control applications
on the Hosts.

An user can adjust Volume/Mute on the Host and see respective
changes on the Gadget side. In the same way, an user can adjust
Volume/Mute on the Gadget side and observe respective changes
on the Host

There is a known issue with Win7 which for some reason doesn't
poll UAC1 interrupt endpoint causing Volume/Mute control not
working in Gadget->Host direction

========================================================

Both features have been tested on BeagleBone Black and
Raspberry PI 4 boards with Linux/MacOS/Windows(7,10) hosts.

While on BeagleBone Black it works fine, Raspberry PI 4 DWC2
controller is affected by the DMA issue for control trasfers
which I reported a while back in [4]. It is causing incorrect
data provided by DWC2 UDC to UAC1/2 gadgets screwing up
volume and mute control messages in the Host->Gadget direction.
The hack is available (see [4]) but it leads to traces/issues
with audio streaming.

Patches reviews and testing on your HW is welcome as usual!

[1] https://lore.kernel.org/linux-usb/1604794711-8661-1-git-send-email-ruslan.bilovol@gmail.com/
[2] https://lore.kernel.org/linux-usb/1614599375-8803-1-git-send-email-ruslan.bilovol@gmail.com/
[3] https://lore.kernel.org/linux-usb/1605220482-28487-1-git-send-email-ruslan.bilovol@gmail.com/
[4] https://lore.kernel.org/linux-usb/CAB=otbTVxa=nGWF4K1AYcYyPceYYRkC_1HYSb_Nhu6C9RMZEHA@mail.gmail.com/

Ruslan Bilovol (8):
  usb: gadget: u_audio: convert to strscpy
  usb: gadget: f_uac2/u_audio: add feedback endpoint support
  usb: gadget: f_uac2: add adaptive sync support for capture
  usb: gadget: u_audio: add real feedback implementation
  usb: audio-v2: add ability to define feature unit descriptor
  usb: gadget: u_audio: add bi-directional volume and mute support
  usb: gadget: f_uac2: add volume and mute support
  usb: gadget: f_uac1: add volume and mute support

 Documentation/ABI/testing/configfs-usb-gadget-uac1 |  10 +
 Documentation/ABI/testing/configfs-usb-gadget-uac2 |  11 +
 Documentation/usb/gadget-testing.rst               |  37 +-
 drivers/usb/gadget/function/f_uac1.c               | 674 +++++++++++++++++-
 drivers/usb/gadget/function/f_uac2.c               | 764 +++++++++++++++++++--
 drivers/usb/gadget/function/u_audio.c              | 582 +++++++++++++++-
 drivers/usb/gadget/function/u_audio.h              |  32 +
 drivers/usb/gadget/function/u_uac1.h               |  20 +
 drivers/usb/gadget/function/u_uac2.h               |  23 +
 include/linux/usb/audio-v2.h                       |  14 +
 10 files changed, 2069 insertions(+), 98 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-03-23 11:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-01 16:49 [PATCH 0/8] USB Audio Gadget part 2: Feedback endpoint, Volume/Mute support Johannes Freyberger
2021-03-01 21:34 ` Ruslan Bilovol
2021-03-01 22:11   ` AW: " Johannes Freyberger
  -- strict thread matches above, loose matches on Subject: below --
2021-03-01 13:05 Ruslan Bilovol
2021-03-23 11:56 ` Greg Kroah-Hartman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.