E.g. https://github.com/torvalds/linux/blob/master/Documentation/usb/gadget-testing.rst or configfs--usb-gadget-xxx files in https://github.com/torvalds/linux/tree/master/Documentation/ABI/testingWhere ist the best place to get the most concise and most up-to-date informations about all these changes?
That file is a gadget coding hint, I do not think anyone cares much about that file and nobody bothered to update it (apart of a few formatting changes https://github.com/torvalds/linux/commits/master/Documentation/driver-api/usb/gadget.rst ). New composite functions are created with code/inspiration from the existing ones.The 3rd line of this link is somewhat irritating however, and maybe misleading also. Because the link refers to 6.2, but the text reads ...
... "Date: 20. August 2004" ... ???
I'm playing a bit with gadget mode on a Pine Quartz64 A board (link: https://www.pine64.org/quartz64a/)
This uses the dwc3 usb controller (instead of dwc2 on the pi4). I'm running Manjaro with kernel 6.2.5.
First it was a bit of a pain to get the gadget to work at all. I needed to modify the device tree, specifically these two commands:
IIUC this should enable th gadget on two separate usb ports, but only one of them works. I have tried countless other combinations like setting only one of them to "device", setting one or both to "peripheral" (what's the difference?) or "otg", but nothing else works.
Right now it works, but with a bunch of problems.
It only works at 16 bits. Trying 32 bits (S32_LE) gives stuttering garbage. I haven't tried 24 bits but I'm not really optimistic about that.
I can only get it to work on Windows. A linux box finds it but playback fails. A mac doesn't find it at all.
Another problem is that I'm missing the capture pitch adjust:
So I kindof have it working a little bit, but it's not good enough to use for anything. Anyone have any ideas for things to try?
This uses the dwc3 usb controller (instead of dwc2 on the pi4). I'm running Manjaro with kernel 6.2.5.
First it was a bit of a pain to get the gadget to work at all. I needed to modify the device tree, specifically these two commands:
where /boot/dtbs/rockchip/rk3566-quartz64-a-otg.dtb is a copy of the standard /boot/dtbs/rockchip/rk3566-quartz64-a.dtbsudo fdtput -t s -v /boot/dtbs/rockchip/rk3566-quartz64-a-otg.dtb /usb@fcc00000 dr_mode device
sudo fdtput -t s -v /boot/dtbs/rockchip/rk3566-quartz64-a-otg.dtb /usb@fd000000 dr_mode device
IIUC this should enable th gadget on two separate usb ports, but only one of them works. I have tried countless other combinations like setting only one of them to "device", setting one or both to "peripheral" (what's the difference?) or "otg", but nothing else works.
Right now it works, but with a bunch of problems.
It only works at 16 bits. Trying 32 bits (S32_LE) gives stuttering garbage. I haven't tried 24 bits but I'm not really optimistic about that.
I can only get it to work on Windows. A linux box finds it but playback fails. A mac doesn't find it at all.
Another problem is that I'm missing the capture pitch adjust:
Where is my "Capture Pitch 1000000"?$ amixer controls
numid=2,iface=MIXER,name='PCM Playback Switch'
numid=3,iface=MIXER,name='PCM Playback Volume'
numid=5,iface=MIXER,name='PCM Capture Switch'
numid=6,iface=MIXER,name='PCM Capture Volume'
numid=7,iface=PCM,name='Capture Rate'
numid=1,iface=PCM,name='Playback Pitch 1000000'
numid=4,iface=PCM,name='Playback Rate'
So I kindof have it working a little bit, but it's not good enough to use for anything. Anyone have any ideas for things to try?
Update on that, it seems I was somehow using the uac1 gadget, not uac2.
New try via configfs, using this script (adapted from here: https://forums.raspberrypi.com/viewtopic.php?t=333504):
This works much better. 16&32 bit both work, and the capture pitch is back. Works on windows and linux, only the mac doesn't like it.
New try via configfs, using this script (adapted from here: https://forums.raspberrypi.com/viewtopic.php?t=333504):
#!/bin/sh
# USB Audio configuration:
AUDIO_CHANNEL_MASK=3
AUDIO_SAMPLE_RATES=44100
AUDIO_SAMPLE_SIZE=4
# Load libcomposite
modprobe libcomposite
# Create a gadget called usb-gadgets
cd /sys/kernel/config/usb_gadget/
mkdir -p usb-gadgets
cd usb-gadgets
# Configure our gadget details
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
echo "0123456789abcdef" > strings/0x409/serialnumber
echo "Z Engineering" > strings/0x409/manufacturer
echo "Z Audio" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
# UAC2 (audio) gadget
# attributes from: https://www.kernel.org/doc/Documentation/ABI/testing/configfs-usb-gadget-uac2
mkdir -p functions/uac2.usb0
echo $AUDIO_CHANNEL_MASK > functions/uac2.usb0/c_chmask
echo $AUDIO_SAMPLE_RATES > functions/uac2.usb0/c_srate
echo $AUDIO_SAMPLE_SIZE > functions/uac2.usb0/c_ssize
echo $AUDIO_CHANNEL_MASK > functions/uac2.usb0/p_chmask
echo $AUDIO_SAMPLE_RATES > functions/uac2.usb0/p_srate
echo $AUDIO_SAMPLE_SIZE > functions/uac2.usb0/p_ssize
ln -s functions/uac2.usb0 configs/c.1/
# End functions
ls /sys/class/udc > UDC
This works much better. 16&32 bit both work, and the capture pitch is back. Works on windows and linux, only the mac doesn't like it.
It does work on Mac, just not when plugged directly to a Thunderbolt port. Via a hub it's fine. So now it's working perfectly.
The gaudio module is basically a hard-coded composite configuration, which picks the audio function based on kernel configsUpdate on that, it seems I was somehow using the uac1 gadget, not uac2.
https://github.com/torvalds/linux/b...5/drivers/usb/gadget/legacy/audio.c#L268-L277 . The module offers only some of the composite config options via its module params. The gaudio module is deprecated (configfs is the preferred way) and kernel admins do not welcome new features to that module (typically adding new parameters).
Most likely your kernel config has the option CONFIG_GADGET_UAC1 enabled. Typically distributions include the kernel configs in /boot/config-CURRENT_KERNEL_VERSION, that's often handy to check.
This writeup seems very instructive https://www.collabora.com/news-and-...-and-how-to-integrate-it-with-systemd-part-1/ Basically udev detects a new UDC device (the OTG port switched from host to device) and triggers some activation which builds the configfs chain. Upon the UDC device removal (the OTG port switched from device to host) udev triggers some deactivation command.
I probably did something wrong before, there is no need to touch usb@fd000000. This is enough:
This quartz board is somehow configured so that it can't auto-switch between host and device (read something about some pin that should have been connected for that to work). Selecting "otg" makes the port device only.
Now let's see if I can get this to start on boot..
And the mode should be "otg" and nothing else, "device" is not a valid option and makes it revert to the default which happens to be "otg".sudo fdtput -t s -v /boot/dtbs/rockchip/rk3566-quartz64-a-otg.dtb /usb@fcc00000 dr_mode otg
This quartz board is somehow configured so that it can't auto-switch between host and device (read something about some pin that should have been connected for that to work). Selecting "otg" makes the port device only.
Now let's see if I can get this to start on boot..
All set up! I'm listening to spotify on windows -> usb to quartz64 (with camilladsp capturing from the gadget) ->usb to Motu M4. It has been nice and stable for an hour or so.
The gadget configfs is set up by a systemd service at boot. Camilladsp also runs as a systemd service that is started by a udev rule when the dac connects.
The gadget configfs is set up by a systemd service at boot. Camilladsp also runs as a systemd service that is started by a udev rule when the dac connects.
Excellent, congrats. Please can you compare DSP/float64 performance of that RK3566 board with RPi4B?
I did some quick tests some time ago. It's slower than the pi4 but don't remember by how much. It only has four A55 cores. Not like it's cool big brother RK3588 with 4xA76 + 4xA55 🙂
I'll do some comparison next time I hook up the pi4.
I'll do some comparison next time I hook up the pi4.
Does this solution support automatic sample rate switching?
Or you need to manually switch sample rates?
Or you need to manually switch sample rates?
My setup doesn't have it, but it could be done.Does this solution support automatic sample rate switching?
You can use the Pavel's gadget controller to handle the changes. I think there is some post about that somewhere but I don't remember where.
https://github.com/pavhofman/gaudio_ctl
...
# Configure our gadget details
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
...
...
This writeup seems very instructive https://www.collabora.com/news-and-...-and-how-to-integrate-it-with-systemd-part-1/
...
And collabora.com says ...
...
0x1d6b is for Linux Foundation and 0x0104 is for Ethernet Gagdet. If your USB host sees such ids it assumes it needs the cdc_ether host-side driver.
...
So declaring ...
echo 0x0104 > idProduct # Multifunction Composite Gadget
... as advocated in the raspberry forum and applyed by Henrik then would make the host providing the cdc_ether driver. But we have an audio gadget here. Is this really the perfect match ??? I think there might be another, specific idProduct code for an audio gadget? Or not?
IMO the product ID in this case does not mark any driver, if the device complies with standard USB functions and does not require a custom driver (which could be tied to the specific PID).
Yes, it's true Linux Foundation has put a few PIDs into the USB database https://the-sz.com/products/usbid/index.php?v=0x1D6B but IMO these are not critical. Linux Foundation has no custom drivers for windows, OSX etc.
Yes, it's true Linux Foundation has put a few PIDs into the USB database https://the-sz.com/products/usbid/index.php?v=0x1D6B but IMO these are not critical. Linux Foundation has no custom drivers for windows, OSX etc.
Thank you for the link and your comments. So, peeping into your link
0x0104 stands for a Multifunction Composite Gadget (which might include ethernet as well as audio)
and instead
0x0101 would stand for the specific Audio Gadget
Well then, let's go along with the RaspiPibians and with Henrik for ID 0x0104 which seems perfect for our maybe multifunctional audio needs.
0x0104 stands for a Multifunction Composite Gadget (which might include ethernet as well as audio)
and instead
0x0101 would stand for the specific Audio Gadget
Well then, let's go along with the RaspiPibians and with Henrik for ID 0x0104 which seems perfect for our maybe multifunctional audio needs.
I already made a small attempt to add a network interface. I used a windows host, and could make it recognize the audio gadget or the network adapter, not both at the same time.
After giving up I found this: https://github.com/RoganDawes/P4wnP1/blob/master/boot/init_usb.sh
Looks promising and worth another try.
After giving up I found this: https://github.com/RoganDawes/P4wnP1/blob/master/boot/init_usb.sh
Looks promising and worth another try.
IMO the PID really does not matter, if the USB descriptor contains valid standard USB functions for which built-in drivers of the OS exist.0x0104 stands for a Multifunction Composite Gadget (which might include ethernet as well as audio)
and instead
0x0101 would stand for the specific Audio Gadget
Well then, let's go along with the RaspiPibians and with Henrik for ID 0x0104 which seems perfect for our maybe multifunctional audio needs.
IIUC the issue is with windows which caches the combination VID+PID+firmware_version (bcdDevice) for a particular USB driver. If the functionality changes, some of it needs to be changed to restart driver installation.
See the notes in https://github.com/RoganDawes/P4wnP1/search?q=pid https://github.com/RoganDawes/P4wnP...c07caab8b7/payloads/stickykey/trigger.txt#L30
- Home
- Source & Line
- PC Based
- Linux USB-Audio Gadget (RPi4 OTG)