← Documents Documentation/sound/designs/jack-injection.rst GitHub 원문 ↗

Linux 6.18.37 · Sound

ALSA Jack Software Injection

SND_JACK_INJECTION_DEBUG의 debugfs 계층과 sw_inject_enable·jackin_inject를 이용해 plug event를 시험하는 방법을 설명합니다.

Source pathDocumentation/sound/designs/jack-injection.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

jack-injection.rst:1-166

SND_JACK_INJECTION_DEBUG의 debugfs 계층과 sw_inject_enable·jackin_inject를 이용해 plug event를 시험하는 방법을 설명합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ============================
2 ALSA Jack Software Injection
3 ============================
4
5 Simple Introduction On Jack Injection
6 =====================================
7
8 Here jack injection means users could inject plugin or plugout events
9 to the audio jacks through debugfs interface, it is helpful to
10 validate ALSA userspace changes. For example, we change the audio
11 profile switching code in the pulseaudio, and we want to verify if the
12 change works as expected and if the change introduce the regression,
13 in this case, we could inject plugin or plugout events to an audio
14 jack or to some audio jacks, we don't need to physically access the
15 machine and plug/unplug physical devices to the audio jack.
16
17 In this design, an audio jack doesn't equal to a physical audio jack.
18 Sometimes a physical audio jack contains multi functions, and the
19 ALSA driver creates multi ``jack_kctl`` for a ``snd_jack``, here the
20 ``snd_jack`` represents a physical audio jack and the ``jack_kctl``
21 represents a function, for example a physical jack has two functions:
22 headphone and mic_in, the ALSA ASoC driver will build 2 ``jack_kctl``
23 for this jack. The jack injection is implemented based on the
24 ``jack_kctl`` instead of ``snd_jack``.
25
26 To inject events to audio jacks, we need to enable the jack injection
27 via ``sw_inject_enable`` first, once it is enabled, this jack will not
28 change the state by hardware events anymore, we could inject plugin or
29 plugout events via ``jackin_inject`` and check the jack state via
30 ``status``, after we finish our test, we need to disable the jack
31 injection via ``sw_inject_enable`` too, once it is disabled, the jack
32 state will be restored according to the last reported hardware events
33 and will change by future hardware events.
34
35 The Layout of Jack Injection Interface
36 ======================================
37
38 If users enable the SND_JACK_INJECTION_DEBUG in the kernel, the audio
39 jack injection interface will be created as below:
40 ::
41
42 $debugfs_mount_dir/sound
43 |-- card0
44 |-- |-- HDMI_DP_pcm_10_Jack
45 |-- |-- |-- jackin_inject
46 |-- |-- |-- kctl_id
47 |-- |-- |-- mask_bits
48 |-- |-- |-- status
49 |-- |-- |-- sw_inject_enable
50 |-- |-- |-- type
51 ...
52 |-- |-- HDMI_DP_pcm_9_Jack
53 |-- |-- jackin_inject
54 |-- |-- kctl_id
55 |-- |-- mask_bits
56 |-- |-- status
57 |-- |-- sw_inject_enable
58 |-- |-- type
59 |-- card1
60 |-- HDMI_DP_pcm_5_Jack
61 |-- |-- jackin_inject
62 |-- |-- kctl_id
63 |-- |-- mask_bits
64 |-- |-- status
65 |-- |-- sw_inject_enable
66 |-- |-- type
67 ...
68 |-- Headphone_Jack
69 |-- |-- jackin_inject
70 |-- |-- kctl_id
71 |-- |-- mask_bits
72 |-- |-- status
73 |-- |-- sw_inject_enable
74 |-- |-- type
75 |-- Headset_Mic_Jack
76 |-- jackin_inject
77 |-- kctl_id
78 |-- mask_bits
79 |-- status
80 |-- sw_inject_enable
81 |-- type
82
83 The Explanation Of The Nodes
84 ======================================
85
86 kctl_id
87 read-only, get jack_kctl->kctl's id
88 ::
89
90 sound/card1/Headphone_Jack# cat kctl_id
91 Headphone Jack
92
93 mask_bits
94 read-only, get jack_kctl's supported events mask_bits
95 ::
96
97 sound/card1/Headphone_Jack# cat mask_bits
98 0x0001 HEADPHONE(0x0001)
99
100 status
101 read-only, get jack_kctl's current status
102
103 - headphone unplugged:
104
105 ::
106
107 sound/card1/Headphone_Jack# cat status
108 Unplugged
109
110 - headphone plugged:
111
112 ::
113
114 sound/card1/Headphone_Jack# cat status
115 Plugged
116
117 type
118 read-only, get snd_jack's supported events from type (all supported events on the physical audio jack)
119 ::
120
121 sound/card1/Headphone_Jack# cat type
122 0x7803 HEADPHONE(0x0001) MICROPHONE(0x0002) BTN_3(0x0800) BTN_2(0x1000) BTN_1(0x2000) BTN_0(0x4000)
123
124 sw_inject_enable
125 read-write, enable or disable injection
126
127 - injection disabled:
128
129 ::
130
131 sound/card1/Headphone_Jack# cat sw_inject_enable
132 Jack: Headphone Jack Inject Enabled: 0
133
134 - injection enabled:
135
136 ::
137
138 sound/card1/Headphone_Jack# cat sw_inject_enable
139 Jack: Headphone Jack Inject Enabled: 1
140
141 - to enable jack injection:
142
143 ::
144
145 sound/card1/Headphone_Jack# echo 1 > sw_inject_enable
146
147 - to disable jack injection:
148
149 ::
150
151 sound/card1/Headphone_Jack# echo 0 > sw_inject_enable
152
153 jackin_inject
154 write-only, inject plugin or plugout
155
156 - to inject plugin:
157
158 ::
159
160 sound/card1/Headphone_Jack# echo 1 > jackin_inject
161
162 - to inject plugout:
163
164 ::
165
166 sound/card1/Headphone_Jack# echo 0 > jackin_inject
167

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Software jack event 주입

1-34

Jack injection은 사용자가 debugfs interface를 통해 audio jack에 plug-in 또는 plug-out event를 주입하는 기능이다. PulseAudio의 audio profile 전환 code 변경을 검증하거나 regression을 확인할 때 장치에 물리적으로 접근해 실제 plug를 꽂고 뺄 필요가 없다. 하나 또는 여러 audio jack에 event를 주입할 수 있다.

여기서 audio jack은 반드시 물리 jack 하나와 같지 않다. 하나의 물리 jack이 headphone과 `mic_in`처럼 여러 기능을 가지면 ALSA ASoC driver는 하나의 `snd_jack`에 여러 `jack_kctl`을 만든다. `snd_jack`은 물리 jack, 각 `jack_kctl`은 개별 기능을 나타내며 injection은 `snd_jack`이 아니라 `jack_kctl`을 기준으로 구현한다.

Event를 주입하려면 먼저 `sw_inject_enable`로 injection을 켠다. 켜진 동안 해당 jack 상태는 hardware event로 바뀌지 않고 `jackin_inject`로 plug-in/plug-out을 주입하며 `status`로 확인한다. 시험 후 `sw_inject_enable`을 끄면 마지막 hardware event에 따라 상태를 복원하고 이후 hardware event를 다시 따른다.

Jack injection 시험 흐름
sw_inject_enable=1hardware event 반영 중지jackin_inject로 plug-in/outstatus 확인sw_inject_enable=0마지막 hardware 상태 복원

Software override를 켠 동안 hardware event 대신 debugfs 값을 사용한다.

============================
ALSA Jack Software Injection
============================

Simple Introduction On Jack Injection
=====================================

Here jack injection means users could inject plugin or plugout events
to the audio jacks through debugfs interface, it is helpful to
validate ALSA userspace changes. For example, we change the audio
profile switching code in the pulseaudio, and we want to verify if the
change works as expected and if the change introduce the regression,
in this case, we could inject plugin or plugout events to an audio
jack or to some audio jacks, we don't need to physically access the
machine and plug/unplug physical devices to the audio jack.

In this design, an audio jack doesn't equal to a physical audio jack.
Sometimes a physical audio jack contains multi functions, and the
ALSA driver creates multi ``jack_kctl`` for a ``snd_jack``, here the
``snd_jack`` represents a physical audio jack and the ``jack_kctl``
represents a function, for example a physical jack has two functions:
headphone and mic_in, the ALSA ASoC driver will build 2 ``jack_kctl``
for this jack. The jack injection is implemented based on the
``jack_kctl`` instead of ``snd_jack``.

To inject events to audio jacks, we need to enable the jack injection
via ``sw_inject_enable`` first, once it is enabled, this jack will not
change the state by hardware events anymore, we could inject plugin or
plugout events via ``jackin_inject`` and check the jack state via
``status``, after we finish our test, we need to disable the jack
injection via ``sw_inject_enable`` too, once it is disabled, the jack
state will be restored according to the last reported hardware events
and will change by future hardware events.

Debugfs interface 계층

35-82

Kernel에서 `SND_JACK_INJECTION_DEBUG`를 켜면 `$debugfs_mount_dir/sound` 아래 card별·jack별 directory가 생긴다. 각 jack directory에는 `jackin_inject`, `kctl_id`, `mask_bits`, `status`, `sw_inject_enable`, `type` 여섯 node가 있다.

Jack injection debugfs 구조
$debugfs_mount_dir/soundcard0HDMI_DP_pcm_10_Jackjackin_inject | kctl_id | mask_bits | status | sw_inject_enable | type
$debugfs_mount_dir/soundcard0HDMI_DP_pcm_9_Jack같은 6개 node
$debugfs_mount_dir/soundcard1HDMI_DP_pcm_5_Jack같은 6개 node
$debugfs_mount_dir/soundcard1Headphone_Jack같은 6개 node
$debugfs_mount_dir/soundcard1Headset_Mic_Jack같은 6개 node

원문의 ASCII directory tree를 card→jack→node 계층으로 재구성했다.

The Layout of Jack Injection Interface
======================================

If users enable the SND_JACK_INJECTION_DEBUG in the kernel, the audio
jack injection interface will be created as below:
::

   $debugfs_mount_dir/sound
   |-- card0
   |-- |-- HDMI_DP_pcm_10_Jack
   |-- |-- |-- jackin_inject
   |-- |-- |-- kctl_id
   |-- |-- |-- mask_bits
   |-- |-- |-- status
   |-- |-- |-- sw_inject_enable
   |-- |-- |-- type
   ...
   |-- |-- HDMI_DP_pcm_9_Jack
   |--     |-- jackin_inject
   |--     |-- kctl_id
   |--     |-- mask_bits
   |--     |-- status
   |--     |-- sw_inject_enable
   |--     |-- type
   |-- card1
       |-- HDMI_DP_pcm_5_Jack
       |-- |-- jackin_inject
       |-- |-- kctl_id
       |-- |-- mask_bits
       |-- |-- status
       |-- |-- sw_inject_enable
       |-- |-- type
       ...
       |-- Headphone_Jack
       |-- |-- jackin_inject
       |-- |-- kctl_id
       |-- |-- mask_bits
       |-- |-- status
       |-- |-- sw_inject_enable
       |-- |-- type
       |-- Headset_Mic_Jack
           |-- jackin_inject
           |-- kctl_id
           |-- mask_bits
           |-- status
           |-- sw_inject_enable
           |-- type

kctl_id·mask_bits·status·type

83-123

`kctl_id`는 read-only이며 `jack_kctl->kctl`의 ID를 반환한다. `mask_bits`도 read-only이며 `jack_kctl`이 지원하는 event mask를 반환한다. 예에서는 headphone event bit `0x0001`을 보여준다.

sound/card1/Headphone_Jack# cat kctl_id
Headphone Jack

sound/card1/Headphone_Jack# cat mask_bits
0x0001 HEADPHONE(0x0001)

`status`는 read-only current state로 unplugged면 `Unplugged`, plugged면 `Plugged`를 반환한다.

sound/card1/Headphone_Jack# cat status
Unplugged

sound/card1/Headphone_Jack# cat status
Plugged

`type`은 물리 audio jack 전체에서 `snd_jack`이 지원하는 모든 event를 read-only로 반환한다. 예에는 HEADPHONE, MICROPHONE과 BTN_0~BTN_3 bit가 포함된다.

sound/card1/Headphone_Jack# cat type
0x7803 HEADPHONE(0x0001) MICROPHONE(0x0002) BTN_3(0x0800) BTN_2(0x1000) BTN_1(0x2000) BTN_0(0x4000)
Jack injection read-only node
Node반환
kctl_idjack_kctl->kctl ID
mask_bits해당 jack_kctl의 지원 event mask
statusPlugged 또는 Unplugged
typesnd_jack 물리 jack 전체의 지원 event

기능별 kcontrol과 물리 jack 전체 정보를 구분한다.

The Explanation Of The Nodes
======================================

kctl_id
  read-only, get jack_kctl->kctl's id
  ::

     sound/card1/Headphone_Jack# cat kctl_id
     Headphone Jack

mask_bits
  read-only, get jack_kctl's supported events mask_bits
  ::

     sound/card1/Headphone_Jack# cat mask_bits
     0x0001 HEADPHONE(0x0001)

status
  read-only, get jack_kctl's current status

- headphone unplugged:

  ::

     sound/card1/Headphone_Jack# cat status
     Unplugged

- headphone plugged:

  ::

     sound/card1/Headphone_Jack# cat status
     Plugged

type
  read-only, get snd_jack's supported events from type (all supported events on the physical audio jack)
  ::

     sound/card1/Headphone_Jack# cat type
     0x7803 HEADPHONE(0x0001) MICROPHONE(0x0002) BTN_3(0x0800) BTN_2(0x1000) BTN_1(0x2000) BTN_0(0x4000)

sw_inject_enable

124-152

`sw_inject_enable`은 injection을 enable/disable하는 read-write node다. 읽으면 jack 이름과 `Inject Enabled: 0` 또는 `1`을 반환한다. `1`을 쓰면 software injection을 켜고 `0`을 쓰면 끈다.

sound/card1/Headphone_Jack# cat sw_inject_enable
Jack: Headphone Jack        Inject Enabled: 0

sound/card1/Headphone_Jack# cat sw_inject_enable
Jack: Headphone Jack        Inject Enabled: 1

sound/card1/Headphone_Jack# echo 1 > sw_inject_enable
sound/card1/Headphone_Jack# echo 0 > sw_inject_enable
Software injection 전환
echo 1 > sw_inject_enableinjection enabledjackin_inject가 상태 제어
echo 0 > sw_inject_enableinjection disabledhardware event 상태 복원

쓰기 값과 jack 상태 source의 관계다.

sw_inject_enable
  read-write, enable or disable injection

- injection disabled:

  ::

     sound/card1/Headphone_Jack# cat sw_inject_enable
     Jack: Headphone Jack                Inject Enabled: 0

- injection enabled:

  ::

     sound/card1/Headphone_Jack# cat sw_inject_enable
     Jack: Headphone Jack                Inject Enabled: 1

- to enable jack injection:

  ::

     sound/card1/Headphone_Jack# echo 1 > sw_inject_enable

- to disable jack injection:

  ::

     sound/card1/Headphone_Jack# echo 0 > sw_inject_enable

jackin_inject

153-166

`jackin_inject`는 plug-in 또는 plug-out을 주입하는 write-only node다. 값 `1`은 plug-in, `0`은 plug-out event를 뜻한다. 먼저 `sw_inject_enable`을 켠 상태에서 사용해야 한다.

sound/card1/Headphone_Jack# echo 1 > jackin_inject
sound/card1/Headphone_Jack# echo 0 > jackin_inject
jackin_inject 값
1plug-in
0plug-out

Write-only 값이 생성하는 jack event다.

jackin_inject
  write-only, inject plugin or plugout

- to inject plugin:

  ::

     sound/card1/Headphone_Jack# echo 1 > jackin_inject

- to inject plugout:

  ::

     sound/card1/Headphone_Jack# echo 0 > jackin_inject