Skip to content

Commit b5952dd

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 4a5a1d9 commit b5952dd

File tree

3 files changed

+206
-0
lines changed

3 files changed

+206
-0
lines changed

case-lib/relay.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
# Check if usbrelay is installed
19+
command -v usbrelay || {
20+
# If usbrelay package is not installed
21+
skip_test "usbrelay command not found. Please install usbrelay package."
22+
}
23+
24+
dlogi "Setting usbrelay switch $switch_name to $state."
25+
usbrelay "$switch_name=$state" || {
26+
# if not detect relays hw module, skip the test
27+
die "Failed to set usbrelay switch $switch_name to $state.
28+
The usbrelay hw module is not responding or no relays detected.
29+
Check hardware connection."
30+
}
31+
32+
# wait for the switch to settle
33+
sleep "$USBRELAY_SETTLE_TIME"
34+
35+
# Display current state of the switch
36+
current_state=$(usbrelay | grep "$switch_name" | awk -F= '{print $2}')
37+
38+
# Check if current_state is equal to the requested state
39+
[[ "$current_state" == "$state" ]] || {
40+
die "usbrelay switch $switch_name failed to set to $state (current: $current_state)"
41+
}
42+
43+
if [[ "$current_state" == "1" ]]; then
44+
dlogi "Current state of $switch_name is: on"
45+
elif [[ "$current_state" == "0" ]]; then
46+
dlogi "Current state of $switch_name is: off"
47+
else
48+
die "Invalid state for $switch_name: $current_state"
49+
fi
50+
}

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

0 commit comments

Comments
 (0)