sof-soundwire: cleanups for codecs with multiple functions

The load mechanism assumed only one multi-codec in the system, but
we saw in #774 multiple instances of those codecs (rt1320 and rt713).

Make the load mechanism straight:

- introduce file variables
- remove shadow variables
- probe multi-codecs separately and modify the file variables
- test for duplicate file inclusion (in both sof-soundwire / HiFi configs)
- merge dmic configs for rt712,rt713 to one file

This change also improves filters for speaker/headset/mic init includes.

Closes: https://github.com/alsa-project/alsa-ucm-conf/pull/775
Link: https://github.com/alsa-project/alsa-ucm-conf/issues/774
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2026-06-04 15:26:57 +02:00
commit cd342774cd
14 changed files with 293 additions and 194 deletions

View file

@ -16,7 +16,7 @@ If.spk_init_rt1320 {
Condition {
Type String
Needle "rt1320"
Haystack "${var:MultiSpeakerShadow}"
Haystack "${var:SpeakerCodec1}"
}
True {
Macro.num1.rt1320spkled { ForAmps "[12]" Amp 1 }
@ -83,7 +83,7 @@ If.mic_init_rt1320 {
Condition {
Type String
Needle "rt1320"
Haystack "${var:MultiMicShadow}"
Haystack "${var:MicCodec1}"
}
True {
Macro.num1.rt1320micled { ForMics "[12]" Mic 1 }

View file

@ -1,6 +0,0 @@
# RT712-dmic specific volume control settings
BootSequence [
cset "name='rt712-dmic ADC 25 Mux' 'DMIC1'"
cset "name='rt712-dmic FU1E Capture Switch' 1"
]

View file

@ -7,11 +7,24 @@ BootSequence [
cset "name='rt712 FU0F Capture Switch' 1"
]
If.rt712dmic_init {
Condition {
Type String
String1 "rt712-dmic"
String2 "${var:MicCodec1}"
}
True.BootSequence [
cset "name='rt712-dmic ADC 25 Mux' 'DMIC1'"
cset "name='rt712-dmic FU1E Capture Switch' 1"
]
}
If.rt712vb_init {
Condition {
Type RegexMatch
Regex "(rt712(-sdca)?)"
String "${var:MultiMicShadow}"
# guard with '=' to avoid empty or rt712-dmic string matching
Regex "=(rt712(-sdca)?)="
String "=${var:MicCodec1}="
}
True.BootSequence [
# RT712-VB integrated with DMIC

View file

@ -1,6 +0,0 @@
# RT713-dmic specific volume control settings
BootSequence [
cset "name='rt713-dmic ADC 25 Mux' 'DMIC1'"
cset "name='rt713-dmic FU1E Capture Switch' 1"
]

View file

@ -7,11 +7,23 @@ BootSequence [
cset "name='rt713 FU0F Capture Switch' 1"
]
If.rt713dmic_init {
Condition {
Type String
String1 "rt713-dmic"
String2 "${var:MicCodec1}"
}
True.BootSequence [
cset "name='rt713-dmic ADC 25 Mux' 'DMIC1'"
cset "name='rt713-dmic FU1E Capture Switch' 1"
]
}
If.rt713vb_init {
Condition {
Type String
String1 "rt713"
String2 "${var:MultiMicShadow}"
String2 "${var:MicCodec1}"
}
True.BootSequence [
# RT713-VB integrated with DMIC

View file

@ -8,36 +8,43 @@ SectionVerb {
Value.TQ "HiFi"
}
If.multicodec {
If.spk {
Condition {
Type String
Empty "${var:MultiCodec1}"
Empty "${var:SpeakerCodecFile}"
}
False.Include.multicodec.File "/sof-soundwire/${var:MultiCodec1}.conf"
False.Include.a.File "/sof-soundwire/${var:SpeakerCodecFile}.conf"
}
If.spkdev {
If.mic {
Condition {
Type String
Empty "${var:SpeakerCodec1}"
Empty "${var:MicCodecFile}"
}
False.If.dup {
Condition {
Type String
String1 "${var:MicCodecFile}"
String2 "${var:SpeakerCodecFile}"
}
False.Include.a.File "/sof-soundwire/${var:MicCodecFile}.conf"
}
False.Include.spkdev.File "/sof-soundwire/${var:SpeakerCodec1}.conf"
}
If.micdev {
If.headset {
Condition {
Type String
Empty "${var:MicCodec1}"
Empty "${var:HeadsetCodecFile}"
}
False.Include.micdev.File "/sof-soundwire/${var:MicCodec1}.conf"
}
If.hsdev {
Condition {
Type String
Empty "${var:HeadsetCodec1}"
False.If.dup {
Condition {
Type String
# guard with "=" to avoid empty string matching
Needle "=${var:HeadsetCodecFile}="
Haystack "=${var:SpeakerCodecFile}=${var:MicCodecFile}="
}
False.Include.a.File "/sof-soundwire/${var:HeadsetCodecFile}.conf"
}
False.Include.hsdev.File "/sof-soundwire/${var:HeadsetCodec1}.conf"
}
<sof-soundwire/Hdmi.conf>

View file

@ -71,7 +71,7 @@ If.codecmic {
Condition {
Type String
Needle "rt1320"
Haystack "${var:MultiMicShadow}"
Haystack "${var:MicCodec1}"
}
True {
SectionDevice."Mic" {

View file

@ -1,21 +0,0 @@
# Use case Configuration for sof-soundwire card
SectionDevice."Mic" {
Comment "SoundWire microphones"
EnableSequence [
cset "name='rt712-dmic FU1E Capture Switch' 1"
]
DisableSequence [
cset "name='rt712-dmic FU1E Capture Switch' 0"
]
Value {
CapturePriority 100
CapturePCM "hw:${CardId},4"
CaptureSwitch "rt712-dmic FU1E Capture Switch"
CaptureVolume "rt712-dmic FU1E Capture Volume"
CaptureMixerElem "rt712-dmic FU1E"
}
}

View file

@ -1,10 +1,10 @@
# Use case Configuration for sof-soundwire card
If.codecspk {
If.codec_spk {
Condition {
Type RegexMatch
Regex "(rt712(-sdca)?)"
String "${var:MultiSpeakerShadow}"
String "${var:SpeakerCodec1}"
}
True {
SectionDevice."Speaker" {
@ -47,50 +47,89 @@ If.codecspk {
}
}
SectionDevice."Headphones" {
Comment "Headphones"
EnableSequence [
cset "name='Headphone Switch' on"
]
DisableSequence [
cset "name='Headphone Switch' off"
]
Value {
PlaybackPriority 200
PlaybackPCM "hw:${CardId}"
JackControl "Headphone Jack"
}
}
SectionDevice."Headset" {
Comment "Headset Mono Microphone"
EnableSequence [
cset "name='rt712 FU0F Capture Switch' on"
]
DisableSequence [
cset "name='rt712 FU0F Capture Switch' off"
]
Value {
CapturePriority 300
CapturePCM "hw:${CardId},1"
CaptureSwitch "rt712 FU0F Capture Switch"
CaptureVolume "rt712 FU0F Capture Volume"
CaptureMixerElem "rt712 FU0F"
JackControl "Headset Mic Jack"
}
}
If.codecmic {
If.codec_hs {
Condition {
Type RegexMatch
Regex "(rt712(-sdca)?)"
String "${var:MultiMicShadow}"
String "${var:HeadsetCodec1}"
}
True {
SectionDevice."Headphones" {
Comment "Headphones"
EnableSequence [
cset "name='Headphone Switch' on"
]
DisableSequence [
cset "name='Headphone Switch' off"
]
Value {
PlaybackPriority 200
PlaybackPCM "hw:${CardId}"
JackControl "Headphone Jack"
}
}
SectionDevice."Headset" {
Comment "Headset Mono Microphone"
EnableSequence [
cset "name='rt712 FU0F Capture Switch' on"
]
DisableSequence [
cset "name='rt712 FU0F Capture Switch' off"
]
Value {
CapturePriority 300
CapturePCM "hw:${CardId},1"
CaptureSwitch "rt712 FU0F Capture Switch"
CaptureVolume "rt712 FU0F Capture Volume"
CaptureMixerElem "rt712 FU0F"
JackControl "Headset Mic Jack"
}
}
}
}
If.codec_dmic {
Condition {
Type String
String1 "rt712-dmic"
String2 "${var:MicCodec1}"
}
True {
SectionDevice."Mic" {
Comment "SoundWire microphones"
EnableSequence [
cset "name='rt712-dmic FU1E Capture Switch' 1"
]
DisableSequence [
cset "name='rt712-dmic FU1E Capture Switch' 0"
]
Value {
CapturePriority 100
CapturePCM "hw:${CardId},4"
CaptureSwitch "rt712-dmic FU1E Capture Switch"
CaptureVolume "rt712-dmic FU1E Capture Volume"
CaptureMixerElem "rt712-dmic FU1E"
}
}
}
}
If.codec_mic {
Condition {
Type RegexMatch
# guard with '=' to avoid empty or rt712-dmic string matching
Regex "=(rt712(-sdca)?)="
String "=${var:MicCodec1}="
}
True {
SectionDevice."Mic" {

View file

@ -1,21 +0,0 @@
# Use case Configuration for sof-soundwire card
SectionDevice."Mic" {
Comment "SoundWire microphones"
EnableSequence [
cset "name='rt713-dmic FU1E Capture Switch' 1"
]
DisableSequence [
cset "name='rt713-dmic FU1E Capture Switch' 0"
]
Value {
CapturePriority 100
CapturePCM "hw:${CardId},4"
CaptureSwitch "rt713-dmic FU1E Capture Switch"
CaptureVolume "rt713-dmic FU1E Capture Volume"
CaptureMixerElem "rt713-dmic FU1E"
}
}

View file

@ -1,49 +1,87 @@
# Use case Configuration for sof-soundwire card
SectionDevice."Headphones" {
Comment "Headphones"
If.codec_hs {
Condition {
Type RegexMatch
Regex "(rt713(-sdca)?)"
String "${var:HeadsetCodec1}"
}
True {
SectionDevice."Headphones" {
Comment "Headphones"
EnableSequence [
cset "name='Headphone Switch' on"
]
EnableSequence [
cset "name='Headphone Switch' on"
]
DisableSequence [
cset "name='Headphone Switch' off"
]
DisableSequence [
cset "name='Headphone Switch' off"
]
Value {
PlaybackPriority 200
PlaybackPCM "hw:${CardId}"
JackControl "Headphone Jack"
Value {
PlaybackPriority 200
PlaybackPCM "hw:${CardId}"
JackControl "Headphone Jack"
}
}
SectionDevice."Headset" {
Comment "Headset Microphone"
EnableSequence [
cset "name='rt713 FU0F Capture Switch' 1"
]
DisableSequence [
cset "name='rt713 FU0F Capture Switch' 0"
]
Value {
CapturePriority 200
CapturePCM "hw:${CardId},1"
JackControl "Headset Mic Jack"
CaptureSwitch "rt713 FU0F Capture Switch"
CaptureVolume "rt713 FU0F Capture Volume"
CaptureMixerElem "rt713 FU0F"
}
}
}
}
SectionDevice."Headset" {
Comment "Headset Microphone"
If.codec_dmic {
Condition {
Type String
String1 "rt713-dmic"
String2 "${var:MicCodec1}"
}
True {
SectionDevice."Mic" {
Comment "SoundWire microphones"
EnableSequence [
cset "name='rt713 FU0F Capture Switch' 1"
]
EnableSequence [
cset "name='rt713-dmic FU1E Capture Switch' 1"
]
DisableSequence [
cset "name='rt713 FU0F Capture Switch' 0"
]
DisableSequence [
cset "name='rt713-dmic FU1E Capture Switch' 0"
]
Value {
CapturePriority 200
CapturePCM "hw:${CardId},1"
JackControl "Headset Mic Jack"
CaptureSwitch "rt713 FU0F Capture Switch"
CaptureVolume "rt713 FU0F Capture Volume"
CaptureMixerElem "rt713 FU0F"
Value {
CapturePriority 100
CapturePCM "hw:${CardId},4"
CaptureSwitch "rt713-dmic FU1E Capture Switch"
CaptureVolume "rt713-dmic FU1E Capture Volume"
CaptureMixerElem "rt713-dmic FU1E"
}
}
}
}
If.codecmic {
If.codec_mic {
Condition {
Type String
String1 "rt713"
String2 "${var:MultiMicShadow}"
String2 "${var:MicCodec1}"
}
True {
SectionDevice."Mic" {

View file

@ -4,7 +4,7 @@ If.codecmic {
Condition {
Type RegexMatch
Regex "(rt721(-sdca)?)"
String "${var:MultiMicShadow}"
String "${var:MicCodec1}"
}
True {
SectionDevice."Mic" {
@ -33,7 +33,7 @@ If.codecspk {
Condition {
Type RegexMatch
Regex "(rt721(-sdca)?)"
String "${var:MultiSpeakerShadow}"
String "${var:SpeakerCodec1}"
}
True {
SectionDevice."Speaker" {

View file

@ -4,7 +4,7 @@ If.codecmic {
Condition {
Type RegexMatch
Regex "(rt722(-sdca)?)"
String "${var:MultiMicShadow}"
String "${var:MicCodec1}"
}
True {
SectionDevice."Mic" {
@ -33,7 +33,7 @@ If.codecspk {
Condition {
Type RegexMatch
Regex "(rt722(-sdca)?)"
String "${var:MultiSpeakerShadow}"
String "${var:SpeakerCodec1}"
}
True {
SectionDevice."Speaker" {

View file

@ -1,4 +1,4 @@
Syntax 7
Syntax 8
SectionUseCase."HiFi" {
File "/sof-soundwire/HiFi.conf"
@ -18,6 +18,7 @@ Define {
Mics1 "0"
Iec61937Pcms1 ""
MultiCodec1 ""
MultiCodecRegex "rt712|rt713|rt721|rt722|rt1320"
}
DefineRegex {
@ -50,12 +51,19 @@ DefineRegex {
String "${CardComponents}"
}
MultiCodec {
Regex "(rt712|rt713|rt721|rt722|rt1320)"
Regex "(${var:MultiCodecRegex})"
String "${var:SpeakerCodec1} ${var:HeadsetCodec1} ${var:MicCodec1}"
}
}
# check to keep combatibility with older kernels that have two separate spk: tags
# set default file variables after regex evaluation
If.codec_default.Append.Define {
SpeakerCodecFile "${var:SpeakerCodec1}"
MicCodecFile "${var:MicCodec1}"
HeadsetCodecFile "${var:HeadsetCodec1}"
}
# check to keep compatibility with older kernels that have two separate spk: tags
If.old_multi_spk {
Condition {
Type RegexMatch
@ -65,83 +73,119 @@ If.old_multi_spk {
True.Define.SpeakerCodec1 "cs42l43-spk+cs35l56"
}
DefineMacro.MultiCodecInit.If.a {
Condition {
Type String
# guard with "=" to not match the codec name in the middle
Haystack "=${var:SpeakerCodec1}=${var:HeadsetCodec1}=${var:MicCodec1}"
Needle "=${var:__CodecId}"
}
True {
If.spk {
Condition {
Type RegexMatch
# guard with "=" to avoid empty string matching
Regex "=(${var:__CodecId}(-sdca)?)="
String "=${var:SpeakerCodec1}="
}
True.Define.SpeakerCodecFile "${var:__CodecId}"
}
If.headset {
Condition {
Type RegexMatch
# guard with "=" to avoid empty string matching
Regex "=(${var:__CodecId}(-sdca)?)="
String "=${var:HeadsetCodec1}="
}
True.Define.HeadsetCodecFile "${var:__CodecId}"
}
If.mic {
Condition {
Type RegexMatch
# guard with "=" to avoid empty string matching
Regex "=(${var:__CodecId}(-sdca|-dmic)?)="
String "=${var:MicCodec1}="
}
True.Define.MicCodecFile "${var:__CodecId}"
}
}
}
# probe codecs with multiple functions, modify file variables
If.multi_init {
Condition {
Type String
Empty "${var:MultiCodec1}"
}
False {
Define {
MultiSpeakerShadow "${var:SpeakerCodec1}"
MultiMicShadow "${var:MicCodec1}"
Macro.rt712.MultiCodecInit "CodecId=rt712"
Macro.rt713.MultiCodecInit "CodecId=rt713"
Macro.rt721.MultiCodecInit "CodecId=rt721"
Macro.rt722.MultiCodecInit "CodecId=rt722"
Macro.rt1320.MultiCodecInit "CodecId=rt1320"
}
}
If.spk {
Condition {
Type String
Empty "${var:SpeakerCodecFile}"
}
False.If.filter {
Condition {
Type RegexMatch
Regex "(${var:MultiCodecRegex}|rt1318|cs42l43-spk(\\+cs35l56)?|cs35l56((-bridge)|(\\+cs42l43-spk))?)"
String "${var:SpeakerCodecFile}"
}
Include.multi_init.File "/codecs/${var:MultiCodec1}/init.conf"
True.Include.a.File "/codecs/${var:SpeakerCodecFile}/init.conf"
}
}
If.multi_speaker {
If.mic {
Condition {
Type RegexMatch
# guard with "=" to avoid empty string matching
Regex "=(${var:MultiCodec1}(-sdca)?)="
String "=${var:SpeakerCodec1}="
Type String
Empty "${var:MicCodecFile}"
}
True {
Define.SpeakerCodec1 ""
False.If.dup {
Condition {
Type String
String1 "${var:MicCodecFile}"
String2 "${var:SpeakerCodecFile}"
}
False.If.filter {
Condition {
Type RegexMatch
Regex "(${var:MultiCodecRegex}|(acp|cs42l43|cs42l45|cs47l47)-dmic|rt715(-sdca)?)"
String "${var:MicCodecFile}"
}
True.Include.a.File "/codecs/${var:MicCodecFile}/init.conf"
}
}
}
If.multi_mic {
If.headset {
Condition {
Type RegexMatch
# guard with "=" to avoid empty string matching
Regex "=(${var:MultiCodec1}(-sdca)?)="
String "=${var:MicCodec1}="
Type String
Empty "${var:HeadsetCodecFile}"
}
True {
Define.MicCodec1 ""
False.If.dup {
Condition {
Type String
# guard with "=" to avoid empty string matching
Needle "=${var:HeadsetCodecFile}="
Haystack "=${var:SpeakerCodecFile}=${var:MicCodecFile}="
}
False.If.filter {
Condition {
Type RegexMatch
Regex "(${var:MultiCodecRegex}|cs42l43|cs42l45|cs47l47|rt5682|rt700|rt711)"
String "${var:HeadsetCodecFile}"
}
True.Include.a.File "/codecs/${var:HeadsetCodecFile}/init.conf"
}
}
}
If.multi_headset {
Condition {
Type RegexMatch
# guard with "=" to avoid empty string matching
Regex "=(${var:MultiCodec1}(-sdca)?)="
String "=${var:HeadsetCodec1}="
}
True {
Define.HeadsetCodec1 ""
}
}
If.spk_init {
Condition {
Type RegexMatch
Regex "(rt1318(-1)?|cs42l43-spk(\\+cs35l56)?|cs35l56((-bridge)|(\\+cs42l43-spk))?)"
String "${var:SpeakerCodec1}"
}
True.Include.spk_init.File "/codecs/${var:SpeakerCodec1}/init.conf"
}
If.hs_init {
Condition {
Type RegexMatch
Regex "(cs42l43|cs42l45|cs47l47|rt5682|rt700|rt711|rt713(-sdca)?|rt722)"
String "${var:HeadsetCodec1}"
}
True.Include.hs_init.File "/codecs/${var:HeadsetCodec1}/init.conf"
}
If.mic_init {
Condition {
Type RegexMatch
Regex "((acp|cs42l43|cs42l45|cs47l47|rt712|rt713)-dmic|rt715(-sdca)?)"
String "${var:MicCodec1}"
}
True.Include.mic_init.File "/codecs/${var:MicCodec1}/init.conf"
}
If.mic_init_rt715 {
Condition {
Type String