Skip to content

Commit 09130c9

Browse files
arikgreencgturner1
authored andcommitted
test-case: add test jack detection while playback
Add a new test case to test jack detection during playback. The test checks all playback Jack PCM devices For unplug/plug headset jack is using a USB relay. https://github.com/darrylb123/usbrelay Signed-off-by: Artur Wilczak <arturx.wilczak@intel.com>
1 parent 5e71e20 commit 09130c9

File tree

1 file changed

+208
-0
lines changed

1 file changed

+208
-0
lines changed
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
#!/bin/bash
2+
3+
# SPDX-License-Identifier: BSD-3-Clause
4+
# Copyright(c) 2025 Intel Corporation. All rights reserved.
5+
6+
##
7+
## Preconditions
8+
# USB relay switch is available and configured.
9+
# Jack detection header should be connected to the USB relay switch
10+
# to the port HURTM_2 (NC) connector.
11+
12+
## Test Description
13+
# Verify jack detection functionality by simulating plugging and unplugging
14+
# of audio jack using a USB relay switch.
15+
# The unplugging and plugging of the jack will be during playback operations
16+
# to ensure the system can handle jack detection events correctly.
17+
# The test will check if the jack detection status is updated correctly
18+
# when the jack is plugged in and unplugged.
19+
20+
## Case Steps
21+
# 1. Ensure the USB relay switch is configured to control the jack detection header.
22+
# 2. Ensure the aplay (playback) command works properly.
23+
# 3. Set the USB relay switch to state on (1), simulate unplugging the headset from the jack.
24+
# 4. Check the jack detection status via amixer. The status should indicate **off**.
25+
# 5. Check if the aplay process is still running after unplugging the jack.
26+
# If the process is not running, the test fails.
27+
# If the process is still running, continue to the next step.
28+
# 6. Set the USB relay switch to state off (0), simulate plugging the headset.
29+
# 7. Check the jack detection status via amixer. The status should indicate **on**.
30+
# 8. Check if the aplay process is still running after plugging the jack.
31+
# If the process is not running, the test fails.
32+
# If the process is still running, continue to the next step.
33+
# 9. Terminate the aplay process.
34+
# 10. Check if the aplay process is terminated successfully.
35+
# If the process is still running, the test fails.
36+
# If the process is terminated successfully, the test passes.
37+
# 11. Check dmesg for any unexpected errors.
38+
#
39+
# Repeat steps 3-11 for all pcm jack playback devices.
40+
41+
TESTDIR=$(realpath -e "$(dirname "${BASH_SOURCE[0]}")/..")
42+
TESTLIB="${TESTDIR}/case-lib"
43+
44+
# shellcheck disable=SC1091 source=case-lib/lib.sh
45+
source "${TESTLIB}/lib.sh"
46+
# shellcheck disable=SC1091 source=case-lib/relay.sh
47+
source "${TESTLIB}/relay.sh"
48+
49+
# shellcheck disable=SC2153
50+
OPT_NAME['t']='tplg' OPT_DESC['t']="tplg file, default value is env TPLG: $TPLG"
51+
OPT_HAS_ARG['t']=1 OPT_VAL['t']="$TPLG"
52+
53+
OPT_NAME['l']='loop' OPT_DESC['l']='loop count'
54+
OPT_HAS_ARG['l']=1 OPT_VAL['l']=1
55+
56+
OPT_NAME['s']='sof-logger' OPT_DESC['s']="Open sof-logger trace the data will store at $LOG_ROOT"
57+
OPT_HAS_ARG['s']=0 OPT_VAL['s']=1
58+
59+
OPT_NAME['u']='relay' OPT_DESC['u']='name of usbrelay switch, default value is HURTM_2'
60+
OPT_HAS_ARG['u']=1 OPT_VAL['u']="HURTM_2"
61+
62+
func_opt_parse_option "$@"
63+
64+
tplg=${OPT_VAL['t']}
65+
relay=${OPT_VAL['u']}
66+
loop_cnt=${OPT_VAL['l']}
67+
68+
DSP_SETTLE_TIME=2
69+
70+
check_control_switch_state()
71+
{
72+
# Check the state of the switch using amixer.
73+
# The switch name is passed as the first argument, and the expected state (on/off)
74+
# is passed as the second argument.
75+
# Returns 0 if the state matches, 1 otherwise.
76+
local control_name="$1"
77+
local expected_control_state="$2"
78+
local control_state
79+
80+
control_state=$(amixer -c "$SOFCARD" contents | awk -v name="$control_name" '
81+
BEGIN {
82+
RS = "";
83+
IGNORECASE = 1;
84+
split(name, parts, " ");
85+
};
86+
$0 ~ parts[1] && $0 ~ parts[2] {
87+
if (match($0, /values=(on|off)/, m)) print m[1];
88+
}
89+
')
90+
dlogi "$control_name switch is: $control_state"
91+
92+
if [[ "$expected_control_state" == "$control_state" ]]; then
93+
return 0
94+
else
95+
return 1
96+
fi
97+
}
98+
99+
testing_one_pcm()
100+
{
101+
dlogi "===== Testing: (PCM: $pcm [$dev]<$type>) (Loop: $i/$loop_cnt) ====="
102+
dlogi "DEVICE: $dev, TYPE: $type, PCM: $pcm, RATE: $rate, CHANNEL: $channel"
103+
104+
dlogi "Command: aplay -Dplug$dev -q /dev/zero"
105+
# Start alsabat in background with longer duration
106+
dlogi "Starting aplay in background..."
107+
aplay "-Dplug$dev" -d10 -q /dev/zero & pid_playback=$! || {
108+
func_lib_lsof_error_dump "$snd"
109+
die "Failed to start aplay on PCM: $pcm"
110+
}
111+
# Wait briefly to ensure the device is ready and avoid read errors
112+
sleep 1
113+
dlogi "aplay started with PID: $pid_playback"
114+
115+
dlogi "Unplug jack audio."
116+
usbrelay_switch "$relay" 1
117+
118+
# Wait for a short period to allow the system to detect the unplug event
119+
sleep $DSP_SETTLE_TIME
120+
121+
# check if the aplay process is still running after unplugging the jack
122+
ps -p "$pid_playback" > /dev/null || {
123+
func_lib_lsof_error_dump "$snd"
124+
die "Playback process terminated unexpectedly after unplugging the jack."
125+
}
126+
127+
check_control_switch_state "headset" "off" || {
128+
die "unplug headset jack failed."
129+
}
130+
131+
check_control_switch_state "headphone" 'off' || {
132+
die "unplug headphone jack failed."
133+
}
134+
135+
dlogi "Plug jack audio."
136+
usbrelay_switch "$relay" 0
137+
138+
# Wait for a short period to allow the system to detect the plug event
139+
sleep $DSP_SETTLE_TIME
140+
141+
# check if the aplay process is still running after unplugging the jack
142+
ps -p "$pid_playback" > /dev/null || {
143+
func_lib_lsof_error_dump "$snd"
144+
die "Playback process terminated unexpectedly after plugging the jack."
145+
}
146+
147+
check_control_switch_state "headset" "on" || {
148+
die "Plug headset jack failed."
149+
}
150+
151+
check_control_switch_state "headphone" "on" || {
152+
die "Plug headphone jack failed."
153+
}
154+
155+
kill -9 $pid_playback > /dev/null 2>&1
156+
wait $pid_playback 2>/dev/null || true
157+
ps -p "$pid_playback" > /dev/null && {
158+
dloge "Failed to kill playback process."
159+
func_lib_lsof_error_dump "$snd"
160+
die "Playback process did not terminate as expected."
161+
}
162+
dlogi "Playback process terminated."
163+
dlogi "===== Testing: PASSED ====="
164+
}
165+
166+
main()
167+
{
168+
func_pipeline_export "$tplg" "type:playback"
169+
170+
setup_kernel_check_point
171+
172+
start_test
173+
174+
logger_disabled || func_lib_start_log_collect
175+
176+
# Check if usbrelay tool is installed
177+
command -v usbrelay || {
178+
# If usbrelay package is not installed
179+
skip_test "usbrelay command not found. Please install usbrelay package."
180+
}
181+
182+
# display current status of relays
183+
usbrelay --debug
184+
185+
dlogi "Reset - plug jack audio"
186+
usbrelay_switch "$relay" 0
187+
188+
for idx in $(seq 0 $((PIPELINE_COUNT - 1)))
189+
do
190+
initialize_audio_params "$idx"
191+
192+
[[ "$pcm" == *Jack* ]] || {
193+
dlogi "PCM $pcm is not a Jack, skipping..."
194+
continue
195+
}
196+
197+
for i in $(seq 1 "$loop_cnt")
198+
do
199+
testing_one_pcm
200+
sof-kernel-log-check.sh "$KERNEL_CHECKPOINT"
201+
setup_kernel_check_point
202+
done
203+
done
204+
}
205+
206+
{
207+
main "$@"; exit "$?"
208+
}

0 commit comments

Comments
 (0)