chiark / gitweb /
7b821d4723661df701667389a660a6dd95936087
[elogind.git] / rules / rules.d / 78-sound-card.rules
1 # do not edit this file, it will be overwritten on update
2
3 SUBSYSTEM!="sound", GOTO="sound_end"
4
5 ACTION=="add|change", KERNEL=="controlC*", ATTR{../uevent}="change"
6 ACTION!="change", GOTO="sound_end"
7
8 # Ok, we probably need a little explanation here for what the two lines above
9 # are good for.
10 #
11 # The story goes like this: when ALSA registers a new sound card it emits a
12 # series of 'add' events to userspace, for the main card device and for all the
13 # child device nodes that belong to it. udev relays those to applications,
14 # however only maintains the order between father and child, but not between
15 # the siblings. The control device node creation can be used as synchronization
16 # point. All other devices that belong to a card are created in the kernel
17 # before it. However unfortunately due to the fact that siblings are forwarded
18 # out of order by udev this fact is lost to applications.
19 #
20 # OTOH before an application can open a device it needs to make sure that all
21 # its device nodes are completely created and set up.
22 #
23 # As a workaround for this issue we have added the udev rule above which will
24 # generate a 'change' event on the main card device from the 'add' event of the
25 # card's control device. Due to the ordering semantics of udev this event will
26 # only be relayed after all child devices have finished processing properly.
27 # When an application needs to listen for appearing devices it can hence look
28 # for 'change' events only, and ignore the actual 'add' events.
29 #
30 # When the application is initialized at the same time as a device is plugged
31 # in it may need to figure out if the 'change' event has already been triggered
32 # or not for a card. To find that out we store the flag environment variable
33 # SOUND_INITIALIZED on the device which simply tells us if the card 'change'
34 # event has already been processed.
35
36 KERNEL!="card*", GOTO="sound_end"
37
38 ENV{SOUND_INITIALIZED}="1"
39
40 SUBSYSTEMS=="usb", ENV{ID_MODEL}=="", IMPORT{program}="usb_id --export %p"
41 SUBSYSTEMS=="usb", ENV{ID_VENDOR_FROM_DATABASE}=="", IMPORT{program}="usb-db %p"
42 SUBSYSTEMS=="usb", ATTRS{idVendor}!="", ATTRS{idProduct}!="", ENV{ID_VENDOR_ID}="$attr{idVendor}", ENV{ID_MODEL_ID}="$attr{idProduct}"
43 SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}!="", ENV{ID_IFACE}="$attr{bInterfaceNumber}"
44 SUBSYSTEMS=="usb", GOTO="skip_pci"
45
46 SUBSYSTEMS=="pci", ENV{ID_VENDOR_FROM_DATABASE}=="", IMPORT{program}="pci-db %p"
47 SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
48
49 LABEL="skip_pci"
50
51 ENV{ID_SERIAL}=="?*", ENV{ID_IFACE}=="?*", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_IFACE}-$attr{id}"
52 ENV{ID_SERIAL}=="?*", ENV{ID_IFACE}=="", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$attr{id}"
53
54 ENV{ID_PATH}=="", IMPORT{program}="path_id %p/controlC%n"
55
56 # The values used here for $SOUND_FORM_FACTOR and $SOUND_CLASS should be kept
57 # in sync with those defined for PulseAudio's src/pulse/proplist.h
58 # PA_PROP_DEVICE_FORM_FACTOR, PA_PROP_DEVICE_CLASS properties.
59
60 # If the first PCM device of this card has the pcm class 'modem', then the card is a modem
61 ATTR{pcmC%nD0p/pcm_class}=="modem", ENV{SOUND_CLASS}="modem", GOTO="sound_end"
62
63 # Identify cards on the internal PCI bus as internal
64 SUBSYSTEMS=="pci", DEVPATH=="*/0000:00:??.?/sound/*", ENV{SOUND_FORM_FACTOR}="internal", GOTO="sound_end"
65
66 # Devices that also support Image/Video interfaces are most likely webcams
67 SUBSYSTEMS=="usb", ENV{ID_USB_INTERFACES}=="*:0e????:*", ENV{SOUND_FORM_FACTOR}="webcam", GOTO="sound_end"
68
69 # Matching on the model strings is a bit ugly, I admit
70 ENV{ID_MODEL}=="*[Ss]peaker*", ENV{SOUND_FORM_FACTOR}="speaker", GOTO="sound_end"
71 ENV{ID_MODEL_FROM_DATABASE}=="*[Ss]peaker*", ENV{SOUND_FORM_FACTOR}="speaker", GOTO="sound_end"
72
73 ENV{ID_MODEL}=="*[Hh]eadphone*", ENV{SOUND_FORM_FACTOR}="headphone", GOTO="sound_end"
74 ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]eadphone*", ENV{SOUND_FORM_FACTOR}="headphone", GOTO="sound_end"
75
76 ENV{ID_MODEL}=="*[Hh]eadset*", ENV{SOUND_FORM_FACTOR}="headset", GOTO="sound_end"
77 ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]eadset*", ENV{SOUND_FORM_FACTOR}="headset", GOTO="sound_end"
78
79 ENV{ID_MODEL}=="*[Hh]andset*", ENV{SOUND_FORM_FACTOR}="handset", GOTO="sound_end"
80 ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]andset*", ENV{SOUND_FORM_FACTOR}="handset", GOTO="sound_end"
81
82 ENV{ID_MODEL}=="*[Mm]icrophone*", ENV{SOUND_FORM_FACTOR}="microphone", GOTO="sound_end"
83 ENV{ID_MODEL_FROM_DATABASE}=="*[Mm]icrophone*", ENV{SOUND_FORM_FACTOR}="microphone", GOTO="sound_end"
84
85 LABEL="sound_end"