Udev
From the ALSA wiki
udev is the standard way of managing /dev directories, designed to clear up some issues with previous /dev implementations, and provide a robust path forward.
Contents |
[edit] Writing Udev rules for Alsa
udev rules are flexible and very powerful. Writing udev rules should solve common Alsa problems, reported by several people:
- Assign several audio devices the same hwplug:x,y numbers, whenever you plug-in or plug-out a device.
- Identify two identical audio devices using the product ID or the USB bus ID of the device.
- Upload firmware to a special device.
[edit] A working example
This script has to be called by udev, and allows for arbitrary naming (actually, numbering) of multiple (identical or not) usb soundcards.
The number each card will get is hardcoded into the script, and is selected by the physical usb port, hub, bus to which the soundcard is connected to.
(Eg. the soundcard that you connect to the third port of the second hub will always get the same number, also if you plug and unplug it, reboot, etc. But if you connect it to a different port, or hub, it will get a different name).
You have to edit the script to suit your hub-usb ports and the corresponding soundcard numbering. The script is commented (to help you customize it).
Then you have to edit the right rules file udev is using for ALSA naming (Ubuntu: /etc/udev/rules.d/20-names.rules CentOS: /etc/udev/rules.d/50-udev.rules Other Linuxes: ...?) and insert the 4 rules you find at the beginning of the script BEFORE the regular ALSA rules.
If you have ideas, suggestions, or improvements, please edit this page or email me.
/usb/bin/alsa_name.pl
#!/usr/bin/perl
# fixed and persistent naming for multiple (identical or not) usb soundcards,
# based on which port-hub-usbbus they connect to
#
# gmaruzz (at) celliax.org
#
# This is to be executed by udev with the following rules:
#KERNEL=="controlC[0-9]*", DRIVERS=="usb", PROGRAM="/usr/bin/alsa_name.pl %k", NAME="snd/%c{1}"
#KERNEL=="hwC[D0-9]*", DRIVERS=="usb", PROGRAM="/usr/bin/alsa_name.pl %k", NAME="snd/%c{1}"
#KERNEL=="midiC[D0-9]*", DRIVERS=="usb", PROGRAM="/usr/bin/alsa_name.pl %k", NAME="snd/%c{1}"
#KERNEL=="pcmC[D0-9cp]*", DRIVERS=="usb", PROGRAM="/usr/bin/alsa_name.pl %k", NAME="snd/%c{1}"
#
use strict;
use warnings;
#
my $alsaname = $ARGV[0]; #udev called us with this argument (%k)
my $physdevpath = $ENV{PHYSDEVPATH}; #udev put this in our environment
my $alsanum = "cucu";
#you can find the physdevpath of a device with "udevinfo -a -p $(udevinfo -q path -n /dev/snd/pcmC0D0c)"
#
#
$physdevpath =~ s/.*\/([^\/]*)/$1/; #eliminate until last slash (/)
$physdevpath =~ s/([^:]*):.*/$1/; #eliminate from colon (:) to end_of_line
#
if($physdevpath eq "1-5.2") # you can find this value with "dmesg"
{
$alsanum="11"; #start from "10" (easier for debugging), "0" is for motherboard soundcard, max is "31"
}
if($physdevpath eq "1-5.3") # you can find this value with "dmesg"
{
$alsanum="12"; #start from "10" (easier for debugging), "0" is for motherboard soundcard, max is "31"
}
if($physdevpath eq "1-5.4") # you can find this value with "dmesg"
{
$alsanum="13"; #start from "10" (easier for debugging), "0" is for motherboard soundcard, max is "31"
}
if($physdevpath eq "3-2") # you can find this value with "dmesg"
{
$alsanum="14"; #start from "10" (easier for debugging), "0" is for motherboard soundcard, max is "31"
}
# other bus positions....
#
if($alsanum ne "cucu")
{
$alsaname=~ s/(.*)C([0-9]+)(.*)/$1C$alsanum$3/;
}
#
print $alsaname;
exit 0;
[edit] Query information about your audio devices
[edit] Writing udev rules
[edit] Assign several audio devices the same hwplug:x,y numbers
[edit] Identify two identical audio devices
[edit] Upload firmware
[edit] See also
- While this article is being completed you may want to look at the mailing list, where the usage of udev with ALSA has been discussed.
- Hotplugging USB audio devices (Howto)
- MultipleCards
- MultipleUSBAudioDevices

