USB Audio Gadget Driver: How to rename/define displayed UAC1 device name at host device - audio

I created an USB audio gadget using USB Audio Class 1 (UAC1) to send/receive audio over USB from a Linux device (Raspberry Pi) to/from a Windows host. The gadget is already working and Windows detects the Raspberry Pi as an audio in and output.
The problem I have is, that the audio output device is called "AC Interface" and the input audio device is called "capture input terminal (AC Interface) in Windows". However, I would like to define an own name, that will be display at the host. Can somebody help me how to do this?
I tried to change the name using uac1_legacy (https://www.kernel.org/doc/Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy), but I couldn't manged to add this to the script.
Or do I have to configure the USB audio gadget using gadget schemes?
# Load libcomposite
modprobe libcomposite
# Create USB Gadget
mkdir -p /sys/kernel/config/usb_gadget/g1
# Device Descriptors
echo 0x1d6b > /sys/kernel/config/usb_gadget/g1/idVendor # Linux Foundation
echo 0x0104 > /sys/kernel/config/usb_gadget/g1/idProduct # Multifunction Composite Gadget
echo 0x0100 > /sys/kernel/config/usb_gadget/g1/bcdDevice # v1.0.0
echo 0x0200 > /sys/kernel/config/usb_gadget/g1/bcdUSB # USB 2.0
echo 0xef > /sys/kernel/config/usb_gadget/g1/bDeviceClass # USB 2.0
echo 0x02 > /sys/kernel/config/usb_gadget/g1/bDeviceSubClass # USB 2.0
echo 0x01 > /sys/kernel/config/usb_gadget/g1/bDeviceProtocol # USB 2.0
mkdir -p /sys/kernel/config/usb_gadget/g1/strings/0x409
echo "000001" > /sys/kernel/config/usb_gadget/g1/strings/0x409/serialnumber
echo "xy" > /sys/kernel/config/usb_gadget/g1/strings/0x409/manufacturer
echo "xy" > /sys/kernel/config/usb_gadget/g1/strings/0x409/product
# Configure UAC1 (audio)
mkdir -p /sys/kernel/config/usb_gadget/g1/functions/uac1.usb0
echo 0x1 > /sys/kernel/config/usb_gadget/g1/functions/uac1.usb0/c_chmask
echo 48000 > /sys/kernel/config/usb_gadget/g1/functions/uac1.usb0/c_srate
echo 0xf > /sys/kernel/config/usb_gadget/g1/functions/uac1.usb0/p_chmask
echo 48000 > /sys/kernel/config/usb_gadget/g1/functions/uac1.usb0/p_srate
mkdir -p /sys/kernel/config/usb_gadget/g1/configs/c.1
echo 250 > /sys/kernel/config/usb_gadget/g1/configs/c.1/MaxPower
ln -s /sys/kernel/config/usb_gadget/g1/functions/uac1.usb0 /sys/kernel/config/usb_gadget/g1/configs/c.1/
udevadm settle -t 5 || :
# End
ls /sys/class/udc/ > /sys/kernel/config/usb_gadget/sonoDSP_audio/UDC

You can check f_uac1.c. For me it seems you can not change the gstrings on the fly for the predefined funcation f_uac.
static struct usb_string strings_uac1[] = {
[STR_AC_IF].s = "AC Interface",
...,
[STR_IO_IN_IT].s = "Capture Input terminal",
...,
{ }
};
What you can do is, creating a simple functionfs user space program with your custom configurations. See the following for further details on ffs.
How to load ffs?
See: https://github.com/linkjumper/configfs/blob/master/setup_usb_gadget.sh
Documentation on how to write a userspace functionfs:
See: linux/tools/usb/ffs-test.c. (Spoiler, those testfile did not work for all endpoints to me. But it is a good source as an example.)
It is a little work, but worth it.

Related

Setting GPIO using sysfs fails in i.MX6

I have a custom i.MX6 board, and I want to turn on a particular GPIO.
From the schematic, the GPIO pin is connected to KEY_COL2 pad, and the KEY_COL2 has the following options.
So, I have to export the following GPIO as per the calculation:
linux gpio number = (gpio_bank - 1) * 32 + gpio_bit
gpio number = ( 4 - 1 ) *32 +10 = 106
When I run the following command, i get the error:
# echo 106 > /sys/class/gpio/export
sh: write error: Device or resource busy
What can be the issue, am i missing anything...
After looking at the device tree, this particular GPIO was used by some other device, hence the error.
You can find the GPIO's in use with the following commands:
mount -t debugfs none /sys/kernel/debug
cat /sys/kernel/debug/gpio

How can i send a binary file via serial in linux?

I want to control a hdmi matrix switch via serial connection.
In Windows i already tried it successful by the following steps:
Decode the necessary HEX from a simple textfile to a binary:
certutil -decodehex on.txt on.bin
Then configure the mode for my comport:
MODE COM1:19,n,8,1
copy on.bin \\.\com1 /b
Now i try to do the same in linux (debian). Since the files are binary i figured i can reuse them, so i transferred them to the linux system and tried the following to configure the comport:
stty -F /dev/ttyUSB0 19200 cs8 -cstopb -parenb
And sending the binary:
cat on.bin > /dev/ttyUSB0
But that won't do anything.´
EDIT:
It's a different PC, but the USB2Serial Converter ist the same.
lsusb gives me:
Bus 001 Device 003: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
dmesg shows
[ 5.070075] usbserial: USB Serial support registered for generic
[ 5.072824] usbserial: USB Serial support registered for ch341-uart
[ 5.073476] usb 1-9: ch341-uart converter now attached to ttyUSB0

alsa on embedded system CORE9G25

I have a CORE9G25-CON (256MBRAM) (http://armdevs.com/core9g25.html) device with embedded linux installed on it.
The version of linux is:
# uname -or
3.6.9 GNU/Linux
# cat /etc/os-release
NAME=Buildroot
VERSION=2012.11.1-dirty
ID=buildroot
VERSION_ID=2012.11.1
PRETTY_NAME="Buildroot 2012.11.1
The device is equipped with USB host connector in which I connected an USB-AUDIO interface
The USB interface is recognize by the system
# cat /proc/asound/cards
0 [Device ]: USB-Audio - USB PnP Sound Device
C-Media Electronics Inc. USB PnP Sound Device at usb-at91-1, full speed
# cat /proc/asound/devices
0: [ 0] : control
16: [ 0- 0]: digital audio playback
24: [ 0- 0]: digital audio capture
33: : timer
# ls /dev/snd
controlC0 pcmC0D0c pcmC0D0p timer
I would like to handle the AUDIO interface by using ALSA but this is the error shown on the console by using the simple command aplay -l
# aplay -l
**** List of PLAYBACK Hardware Devices ****
ALSA lib control.c:739:(snd_ctl_open_noupdate) Invalid CTL hw:0
aplay: device_list:226: control open (0): No such file or directory
aplay: conf.c:3095: snd_config_update_free: Assertion `update->count > 0 && update->finfo' failed.
Aborted
I googled for about a week trying to fix the problem but, up to now, i didn't find any solution.
Could you help me to fix the problem ?
Had you other similar experience about it ?
Thank you very much for your help and cooperation
best regards
What does your alsa.conf look like ? do this
locate alsa.conf
typically found at
/usr/share/alsa/alsa.conf
do a google on
audio sound alsa Invalid CTL hw:0
this might get you on the right path
#alsa.conf minimal configuration
ctl.hw {
#args [ CARD ]
#args.CARD {
type string
}
type hw
card $CARD #with 0 alsamixer work, with $CARD alsamixer lend to invalid argument
}

RS232 console communication - set baudrate to 1 MBaud

Within a bash script, I use the following:
$ stty -F /dev/ttyUSB0 921600 raw
$ echo -n "some test data" >/dev/ttyUSB0
and it works as expected.
Using a PL2303 USB to RS232 adapter:
$ lsusb
...
Bus 006 Device 010: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Bus 006 Device 011: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Now I tried to do the same with 1 MBd, but got an error:
$ stty -F /dev/ttyUSB0 1000000 raw
stty: /dev/ttyUSB0: unable to perform all requested operations
Also the same message when I try with 500 kBd. Trying 250 kBd the error message is different:
$ stty -F /dev/ttyUSB0 250000 raw
stty: invalid argument `250000'
Try `stty --help' for more information.
As seen here, it's a problem in the PL2303 linux driver.
I'm working on Kubuntu 12.04, 32 Bit. Unfortunally, I don't know how to fix that driver on my system (getting driver source, patch em, compile, install … hmm, maybe I learn a bit and give it a try - advice is welcome).
But maybe there is an updated driver avaliable which is easy to install?
Or does someone know an alternate USB to RS232 adapter which works at 1 MBd (hardware flowcontrol via rts/cts is needed, which works pretty well with the PL2303)?
After the realization that »Prolific and FTDI are competitors«, I bought Ftdi US232R-10 which is a FT232R based device and specified for 1 MBd transfer rate.
With this adapter I'd successfully tested communication at 1 MBd by transfering some GiB data without any error (including usage of Rts/Cts hardware flow control).
Configuring this device using stty like:
$ stty -F /dev/ttyUSB0 1000000 raw
works successfully.

Disconnect and reconnect ttyUSB0 programmatically in Linux

Trying to solve this problem (ttyUSB0 that works properly than stop working after about 1hr)I'm thinking on if disconnecting and reconnecting the usb device could be a good fix.
So, it is possibile to cut down power to the USB device and repower it programmatically (bash)?
# lsusb -t
1-1:1.0: No such file or directory
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=musb-hdrc/1p, 480M
|__ Port 1: Dev 2, If 0, Class=vend., Driver=, 12M
|__ Port 1: Dev 2, If 1, Class=vend., Driver=cp210x, 12M
On am335x, kernel 3.2.0, ubuntu core armhf.
[ 1.784332] usb 1-1: cp210x converter now attached to ttyUSB0
At the moment I need a complete power cycle to have ttyUSB0 back.
This is the solution:
Find the identity of your usb device.
# tree /sys/bus/usb/drivers/cp210x/
/sys/bus/usb/drivers/cp210x/
|-- 1-1:1.1 -> ../../../../devices/platform/omap/musb-ti81xx/musb-hdrc.1/usb1/1-1/1-1:1.1
|-- bind
|-- module -> ../../../../module/cp210x
|-- remove_id
|-- uevent
-- unbind
So 1-1:1.1 is the identifier of my ttyUSB0(it can be discovered also via dmesg).
Then, disconnect the device (as root):
# echo -n "1-1:1.1" > /sys/bus/usb/drivers/cp210x/unbind
reconnect it
# echo -n "1-1:1.1" > /sys/bus/usb/drivers/cp210x/bind
At this point I had the same device but with a different name, it was now ttyUSB1 instead of ttyUSB0.
- To avoid this I added a new rule in /etc/udev/rules.d/ by creating a new file named 99-usb-serial.rules with this line:
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea70", ATTRS{serial}=="002DCFAF", SYMLINK+="sameName", MODE:="0666"
where idVendor, idProduct and serial must be the values of your device. This rule will create a new device called sameName linked to the ttyUSB* device normally generated from the OS.
As #Robert Harvey Said,
You first need to find our driver that will help you 'unplug and plug' the usb. Type: ls /sys/bus/usb/drivers which should print something like this: btusb ftdi_sio hub usb usbfs usbhid usbserial_generic uvcvideo. These, are all the drivers for each usb device. Now, lets say mine is ftdi_sio, which is a device i use to program my arduino (atmega328p chip). I am not sure how Your/other usb devices name themselves there. Like, i dont know which of these is my mouse.
Now, you can see the driver's commands using:
ls /sys/bus/usb/drivers/ftdi_sio/, which will print something like: 1-4:1.0 bind module uevent unbind, Where 1-4:1.0 is the device's characteristic code, and the bind and unbind command, which are the 'plug' and 'unplug' command respectively.
Now, if i want to unplug programatically the ftdi usb port, i will type:
echo -n "1-4:1.0" > /sys/bus/usb/drivers/ftdi_sio/unbind
and, to plug it again:
echo -n "1-4:1.0" > /sys/bus/usb/drivers/ftdi_sio/bind
Now, we can combine all the commands together, with a ';':
echo -n "1-4:1.0" > /sys/bus/usb/drivers/ftdi_sio/unbind ; echo -n "1-4:1.0" > /sys/bus/usb/drivers/ftdi_sio/bind

Resources