Skip to content

Commit 4fcce37

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 5124961 commit 4fcce37

File tree

4 files changed

+210
-2
lines changed

4 files changed

+210
-2
lines changed

case-lib/lib.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ extract_format_number() {
791791
else
792792
die "Error: Unknown format: %s\n"
793793
fi
794-
}
794+
}
795795

796796
# Initialize the parameters using for audio testing.
797797
# shellcheck disable=SC2034
@@ -1271,4 +1271,3 @@ perf_analyze()
12711271
return 1
12721272
fi
12731273
}
1274-

case-lib/relay.sh

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/bin/bash
2+
3+
# SPDX-License-Identifier: BSD-3-Clause
4+
# Copyright(c) 2021-2025 Intel Corporation. All rights reserved.
5+
6+
# test-mic_privacy.sh needs to control mic privacy settings (on/off)
7+
# needs usbrelay package: https://github.com/darrylb123/usbrelay
8+
# param1: switch name
9+
# param2: switch state
10+
usbrelay_switch()
11+
{
12+
# Declare a constant for the relay settle time
13+
USBRELAY_SETTLE_TIME=0.5
14+
15+
local switch_name=$1
16+
local state=$2
17+
18+
dlogi "Setting usbrelay switch $switch_name to $state."
19+
usbrelay "$switch_name=$state" > /dev/null || {
20+
# if not detect relays hw module, skip the test
21+
die "Failed to set usbrelay switch $switch_name to $state.
22+
The usbrelay hw module is not responding or no relays detected.
23+
Check hardware connection."
24+
}
25+
26+
# wait for the switch to settle
27+
sleep "$USBRELAY_SETTLE_TIME"
28+
29+
# Display current state of the switch
30+
current_state=$(usbrelay | grep "$switch_name" | awk -F= '{print $2}')
31+
32+
# Check if current_state is equal to the requested state
33+
[[ "$current_state" == "$state" ]] || {
34+
die "usbrelay switch $switch_name failed to set to $state (current: $current_state)"
35+
}
36+
37+
case "$current_state" in
38+
'1') dlogi "Current state of $switch_name is: on";;
39+
'0') dlogi "Current state of $switch_name is: off";;
40+
*) die "Invalid state for $switch_name: $current_state";;
41+
esac
42+
}

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: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
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+
source "${TESTLIB}/relay.sh"
42+
43+
OPT_NAME['t']='tplg' OPT_DESC['t']="tplg file, default value is env TPLG: $TPLG"
44+
OPT_HAS_ARG['t']=1 OPT_VAL['t']="$TPLG"
45+
46+
OPT_NAME['r']='round' OPT_DESC['r']='round count'
47+
OPT_HAS_ARG['r']=1 OPT_VAL['r']=1
48+
49+
OPT_NAME['d']='duration' OPT_DESC['d']='arecord duration in second'
50+
OPT_HAS_ARG['d']=1 OPT_VAL['d']=2
51+
52+
OPT_NAME['l']='loop' OPT_DESC['l']='option of speaker-test'
53+
OPT_HAS_ARG['l']=1 OPT_VAL['l']=3
54+
55+
OPT_NAME['s']='sof-logger' OPT_DESC['s']="Open sof-logger trace the data will store at $LOG_ROOT"
56+
OPT_HAS_ARG['s']=0 OPT_VAL['s']=1
57+
58+
OPT_NAME['u']='relay' OPT_DESC['u']='name of usbrelay switch, default value is HURTM_2'
59+
OPT_HAS_ARG['u']=1 OPT_VAL['u']="HURTM_2"
60+
61+
func_opt_parse_option "$@"
62+
63+
tplg=${OPT_VAL['t']}
64+
duration=${OPT_VAL['d']}
65+
relay=${OPT_VAL['u']}
66+
tcnt=${OPT_VAL['l']}
67+
round_cnt=${OPT_VAL['r']}
68+
69+
check_control_switch_state()
70+
{
71+
# Check the state of the switch using amixer.
72+
# The switch name is passed as the first argument, and the expected state (on/off)
73+
# is passed as the second argument.
74+
# Returns 0 if the state matches, 1 otherwise.
75+
local switch_name="$1"
76+
local expected_switch_state="$2"
77+
local switch_state
78+
79+
switch_state=$(echo -e $(amixer -c 0 contents | grep -i "$switch_name .* *jack" -A 2) | sed -n '1s/^.*values=//p')
80+
dlogi "$switch_name switch is: $switch_state"
81+
82+
if [[ "$expected_switch_state" == "$switch_state" ]]; then
83+
return 0
84+
else
85+
return 1
86+
fi
87+
}
88+
89+
main()
90+
{
91+
func_pipeline_export "$tplg" "type:playback"
92+
93+
setup_kernel_check_point
94+
95+
start_test
96+
97+
logger_disabled || func_lib_start_log_collect
98+
99+
# Check if usbrelay tool is installed
100+
command -v usbrelay || {
101+
# If usbrelay package is not installed
102+
skip_test "usbrelay command not found. Please install usbrelay package."
103+
}
104+
105+
dlogi "Reset - plug jack audio"
106+
usbrelay_switch "$relay" 0
107+
108+
for round in $(seq 1 "$round_cnt")
109+
do
110+
for idx in $(seq 0 $((PIPELINE_COUNT - 1)))
111+
do
112+
initialize_audio_params "$idx"
113+
114+
dlogi "===== Testing: (PCM: $pcm [$dev]<$type>) ====="
115+
116+
[[ "$pcm" == *Jack* ]] || {
117+
dlogi "PCM $pcm is not a Jack, skipping..."
118+
continue
119+
}
120+
121+
aplay_opts -D"$dev" -r "$rate" -c "$channel" -f "$fmts" -d "$duration" "/dev/zero" -q || {
122+
func_lib_lsof_error_dump "$snd"
123+
die "aplay on PCM $dev failed."
124+
}
125+
126+
dlogi "Unplug jack audio."
127+
usbrelay_switch "$relay" 1
128+
129+
aplay_opts -D"$dev" -r "$rate" -c "$channel" -f "$fmts" -d "$duration" "/dev/zero" -q || {
130+
func_lib_lsof_error_dump "$snd"
131+
die "aplay on PCM $dev failed."
132+
}
133+
134+
check_control_switch_state "headset" "off" || {
135+
die "unplug headset jack failed."
136+
}
137+
138+
check_control_switch_state "headphone" 'off' || {
139+
die "unplug headphone jack failed."
140+
}
141+
142+
dlogi "Plug jack audio."
143+
usbrelay_switch "$relay" 0
144+
145+
aplay_opts -D"$dev" -r "$rate" -c "$channel" -f "$fmts" -d "$duration" "/dev/zero" -q || {
146+
func_lib_lsof_error_dump "$snd"
147+
die "aplay on PCM $dev failed."
148+
}
149+
150+
check_control_switch_state "headset" "on" || {
151+
die "Plug headset jack failed."
152+
}
153+
154+
check_control_switch_state "headphone" "on" || {
155+
die "Plug headphone jack failed."
156+
}
157+
done
158+
done
159+
160+
sof-kernel-log-check.sh "$KERNEL_CHECKPOINT"
161+
}
162+
163+
{
164+
main "$@"; exit "$?"
165+
}

0 commit comments

Comments
 (0)