Skip to content

Commit 6b859f9

Browse files
committed
test-case: add test jack detection playback
Add a new test case to test jack detection durring playback or capture. 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 20a47bc commit 6b859f9

File tree

3 files changed

+202
-0
lines changed

3 files changed

+202
-0
lines changed

case-lib/lib.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,3 +1187,39 @@ perf_analyze()
11871187
fi
11881188
}
11891189

1190+
# test-mic_privacy.sh needs to control mic privacy settings (on/off)
1191+
# needs usbrelay package: https://github.com/darrylb123/usbrelay
1192+
# param1: switch name
1193+
# param2: switch state
1194+
usbrelay_switch()
1195+
{
1196+
local switch_name=$1
1197+
local state=$2
1198+
dlogi "Setting usbrelay switch $switch_name to $state."
1199+
usbrelay "$switch_name=$state" >/dev/null 2>&1 || {
1200+
# If usbrelay is not installed or no relays detected, skip the test
1201+
dloge "Failed to set usbrelay switch $switch_name to $state."
1202+
skip_test "usbrelay is not responding or no relays detected. Check hardware connection."
1203+
}
1204+
1205+
# wait for the switch to settle
1206+
sleep 0.5
1207+
1208+
# Display current state of the switch
1209+
current_state=$(usbrelay | grep "$switch_name" | awk -F= '{print $2}')
1210+
1211+
# Check if current_state is equal to the requested state
1212+
[[ "$current_state" == "$state" ]] || {
1213+
dloge "usbrelay switch $switch_name failed to set to $state (current: $current_state)"
1214+
exit 1
1215+
}
1216+
1217+
if [[ "$current_state" == "1" ]]; then
1218+
dlogi "Current state of $switch_name is: on"
1219+
elif [[ "$current_state" == "0" ]]; then
1220+
dlogi "Current state of $switch_name is: off"
1221+
else
1222+
dloge "Invalid state for $switch_name: $current_state"
1223+
exit 1
1224+
fi
1225+
}

env-check.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ func_check_pkg aplay
8787
func_check_pkg sox
8888
func_check_pkg tinycap
8989
func_check_pkg tinyplay
90+
# MIC privacy / JACK Audio detection relay switch
91+
func_check_pkg usbrelay
9092
# JACK Audio Connection Kit
9193
func_check_pkg jackd
9294
func_check_pkg jack_iodelay
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
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+
# 1. Runtime PM status is on.
9+
# 2. aplay (playback) and arecord (capture) is running.
10+
# 3. USB relay switch is available and configured.
11+
# Jack detection header should be connected to the USB relay switch
12+
# to the port HURTM_2 (NC) connector.
13+
14+
## Test Description
15+
# * Set Jack detection relay to state off (0), play/record and determine if
16+
# status is updated as expected. The status should be on.
17+
# Also alsabat command should return 0.
18+
# * Set Jack detection relay to state on (1), play/record and determine if
19+
# status is updated as expected. The status should be off.
20+
# Also alsabat command should return -1001.
21+
# * Repeat for both headphone and headset jacks.
22+
# * Repeat for both HDMI and DisplayPort if available.
23+
24+
## Case Steps
25+
# 1. Ensure the USB relay switch is configured to control the jack detection header.
26+
# 2. Set the USB relay switch to state off (0), simulate plugging in the headset.
27+
# 3. Run aplay/arecord command to play/record audio.
28+
# 4. Check the jack detection status via amixer. The status should indicate **on**.
29+
# 5. Set the USB relay switch to state on (1), simulate unplugging the headset from the jack.
30+
# 6. Check the jack detection status via amixer. The status should indicate **off**.
31+
# 7. Check dmesg for any unexpected errors.
32+
#
33+
# Repeat for both headphone and headset jacks.
34+
# Repeat for all pipelines.
35+
36+
TESTDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
37+
TESTLIB="${TESTDIR}/case-lib"
38+
39+
# shellcheck source=case-lib/lib.sh
40+
source "${TESTLIB}/lib.sh"
41+
42+
OPT_NAME['t']='tplg' OPT_DESC['t']="tplg file, default value is env TPLG: $TPLG"
43+
OPT_HAS_ARG['t']=1 OPT_VAL['t']="$TPLG"
44+
45+
OPT_NAME['r']='round' OPT_DESC['r']='round count'
46+
OPT_HAS_ARG['r']=1 OPT_VAL['r']=1
47+
48+
OPT_NAME['d']='duration' OPT_DESC['d']='arecord duration in second'
49+
OPT_HAS_ARG['d']=1 OPT_VAL['d']=2
50+
51+
OPT_NAME['l']='loop' OPT_DESC['l']='option of speaker-test'
52+
OPT_HAS_ARG['l']=1 OPT_VAL['l']=3
53+
54+
OPT_NAME['s']='sof-logger' OPT_DESC['s']="Open sof-logger trace the data will store at $LOG_ROOT"
55+
OPT_HAS_ARG['s']=0 OPT_VAL['s']=1
56+
57+
OPT_NAME['u']='relay' OPT_DESC['u']='name of usbrelay switch, default value is HURTM_2'
58+
OPT_HAS_ARG['u']=1 OPT_VAL['u']="HURTM_2"
59+
60+
func_opt_parse_option "$@"
61+
62+
tplg=${OPT_VAL['t']}
63+
duration=${OPT_VAL['d']}
64+
relay=${OPT_VAL['u']}
65+
tcnt=${OPT_VAL['l']}
66+
round_cnt=${OPT_VAL['r']}
67+
68+
check_control_switch_state()
69+
{
70+
# Check the state of the switch using amixer.
71+
# The switch name is passed as the first argument, and the expected state (on/off)
72+
# is passed as the second argument.
73+
# Returns 0 if the state matches, 1 otherwise.
74+
local switch_name="$1"
75+
local expected_switch_state="$2"
76+
local switch_state
77+
78+
switch_state=$(echo -e $(amixer -c 0 contents | grep -i "$switch_name .* *jack" -A 2) | sed -n '1s/^.*values=//p')
79+
dlogi "$switch_name switch is: $switch_state"
80+
81+
if [[ "$expected_switch_state" == "$switch_state" ]]; then
82+
return 0
83+
else
84+
return 1
85+
fi
86+
}
87+
88+
main()
89+
{
90+
func_pipeline_export "$tplg" "type:playback"
91+
92+
setup_kernel_check_point
93+
94+
start_test
95+
96+
logger_disabled || func_lib_start_log_collect
97+
98+
# check if usbrelay tool is installed
99+
command -v usbrelay || {
100+
skip_test "usbrelay command not found. Please install usbrelay to control the mic privacy switch."
101+
}
102+
103+
dlogi "Reset - plug jack audio"
104+
usbrelay_switch "$relay" 0
105+
106+
for round in $(seq 1 "$round_cnt")
107+
do
108+
for idx in $(seq 0 $((PIPELINE_COUNT - 1)))
109+
do
110+
initialize_audio_params "$idx"
111+
112+
channel=$(func_pipeline_parse_value "$idx" channel)
113+
rate=$(func_pipeline_parse_value "$idx" rate)
114+
fmt=$(func_pipeline_parse_value "$idx" fmt)
115+
dev=$(func_pipeline_parse_value "$idx" dev)
116+
snd=$(func_pipeline_parse_value "$idx" snd)
117+
118+
dlogi "===== Testing: (PCM: $pcm [$dev]<$type>) ====="
119+
120+
aplay_opts -D"$dev" -r "$rate" -c "$channel" -f "$fmt" -d "$duration" "/dev/zero" -q || {
121+
func_lib_lsof_error_dump "$snd"
122+
die "aplay on PCM $dev failed."
123+
}
124+
125+
dlogi "Unplug jack audio."
126+
usbrelay_switch "$relay" 1
127+
128+
aplay_opts -D"$dev" -r "$rate" -c "$channel" -f "$fmt" -d "$duration" "/dev/zero" -q || {
129+
func_lib_lsof_error_dump "$snd"
130+
die "aplay on PCM $dev failed."
131+
}
132+
133+
check_control_switch_state "headset" "off" || {
134+
die "unplug headset jack failed."
135+
}
136+
137+
check_control_switch_state "headphone" 'off' || {
138+
die "unplug headphone jack failed."
139+
}
140+
141+
dlogi "Plug jack audio."
142+
usbrelay_switch "$relay" 0
143+
144+
aplay_opts -D"$dev" -r "$rate" -c "$channel" -f "$fmt" -d "$duration" "/dev/zero" -q || {
145+
func_lib_lsof_error_dump "$snd"
146+
die "aplay on PCM $dev failed."
147+
}
148+
149+
check_control_switch_state "headset" "on" || {
150+
die "Plug headset jack failed."
151+
}
152+
153+
check_control_switch_state "headphone" "on" || {
154+
die "Plug headphone jack failed."
155+
}
156+
done
157+
done
158+
159+
sof-kernel-log-check.sh "$KERNEL_CHECKPOINT"
160+
}
161+
162+
{
163+
main "$@"; exit "$?"
164+
}

0 commit comments

Comments
 (0)