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 { Condition {
Type String Type String
Needle "rt1320" Needle "rt1320"
Haystack "${var:MultiSpeakerShadow}" Haystack "${var:SpeakerCodec1}"
} }
True { True {
Macro.num1.rt1320spkled { ForAmps "[12]" Amp 1 } Macro.num1.rt1320spkled { ForAmps "[12]" Amp 1 }
@ -83,7 +83,7 @@ If.mic_init_rt1320 {
Condition { Condition {
Type String Type String
Needle "rt1320" Needle "rt1320"
Haystack "${var:MultiMicShadow}" Haystack "${var:MicCodec1}"
} }
True { True {
Macro.num1.rt1320micled { ForMics "[12]" Mic 1 } 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" 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 { If.rt712vb_init {
Condition { Condition {
Type RegexMatch Type RegexMatch
Regex "(rt712(-sdca)?)" # guard with '=' to avoid empty or rt712-dmic string matching
String "${var:MultiMicShadow}" Regex "=(rt712(-sdca)?)="
String "=${var:MicCodec1}="
} }
True.BootSequence [ True.BootSequence [
# RT712-VB integrated with DMIC # 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" 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 { If.rt713vb_init {
Condition { Condition {
Type String Type String
String1 "rt713" String1 "rt713"
String2 "${var:MultiMicShadow}" String2 "${var:MicCodec1}"
} }
True.BootSequence [ True.BootSequence [
# RT713-VB integrated with DMIC # RT713-VB integrated with DMIC

View file

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

View file

@ -71,7 +71,7 @@ If.codecmic {
Condition { Condition {
Type String Type String
Needle "rt1320" Needle "rt1320"
Haystack "${var:MultiMicShadow}" Haystack "${var:MicCodec1}"
} }
True { True {
SectionDevice."Mic" { 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 # Use case Configuration for sof-soundwire card
If.codecspk { If.codec_spk {
Condition { Condition {
Type RegexMatch Type RegexMatch
Regex "(rt712(-sdca)?)" Regex "(rt712(-sdca)?)"
String "${var:MultiSpeakerShadow}" String "${var:SpeakerCodec1}"
} }
True { True {
SectionDevice."Speaker" { SectionDevice."Speaker" {
@ -47,50 +47,89 @@ If.codecspk {
} }
} }
SectionDevice."Headphones" { If.codec_hs {
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 {
Condition { Condition {
Type RegexMatch Type RegexMatch
Regex "(rt712(-sdca)?)" 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 { True {
SectionDevice."Mic" { 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 # Use case Configuration for sof-soundwire card
SectionDevice."Headphones" { If.codec_hs {
Comment "Headphones" Condition {
Type RegexMatch
Regex "(rt713(-sdca)?)"
String "${var:HeadsetCodec1}"
}
True {
SectionDevice."Headphones" {
Comment "Headphones"
EnableSequence [ EnableSequence [
cset "name='Headphone Switch' on" cset "name='Headphone Switch' on"
] ]
DisableSequence [ DisableSequence [
cset "name='Headphone Switch' off" cset "name='Headphone Switch' off"
] ]
Value { Value {
PlaybackPriority 200 PlaybackPriority 200
PlaybackPCM "hw:${CardId}" PlaybackPCM "hw:${CardId}"
JackControl "Headphone Jack" 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" { If.codec_dmic {
Comment "Headset Microphone" Condition {
Type String
String1 "rt713-dmic"
String2 "${var:MicCodec1}"
}
True {
SectionDevice."Mic" {
Comment "SoundWire microphones"
EnableSequence [ EnableSequence [
cset "name='rt713 FU0F Capture Switch' 1" cset "name='rt713-dmic FU1E Capture Switch' 1"
] ]
DisableSequence [ DisableSequence [
cset "name='rt713 FU0F Capture Switch' 0" cset "name='rt713-dmic FU1E Capture Switch' 0"
] ]
Value { Value {
CapturePriority 200 CapturePriority 100
CapturePCM "hw:${CardId},1" CapturePCM "hw:${CardId},4"
JackControl "Headset Mic Jack" CaptureSwitch "rt713-dmic FU1E Capture Switch"
CaptureSwitch "rt713 FU0F Capture Switch" CaptureVolume "rt713-dmic FU1E Capture Volume"
CaptureVolume "rt713 FU0F Capture Volume" CaptureMixerElem "rt713-dmic FU1E"
CaptureMixerElem "rt713 FU0F" }
}
} }
} }
If.codecmic { If.codec_mic {
Condition { Condition {
Type String Type String
String1 "rt713" String1 "rt713"
String2 "${var:MultiMicShadow}" String2 "${var:MicCodec1}"
} }
True { True {
SectionDevice."Mic" { SectionDevice."Mic" {

View file

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

View file

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

View file

@ -1,4 +1,4 @@
Syntax 7 Syntax 8
SectionUseCase."HiFi" { SectionUseCase."HiFi" {
File "/sof-soundwire/HiFi.conf" File "/sof-soundwire/HiFi.conf"
@ -18,6 +18,7 @@ Define {
Mics1 "0" Mics1 "0"
Iec61937Pcms1 "" Iec61937Pcms1 ""
MultiCodec1 "" MultiCodec1 ""
MultiCodecRegex "rt712|rt713|rt721|rt722|rt1320"
} }
DefineRegex { DefineRegex {
@ -50,12 +51,19 @@ DefineRegex {
String "${CardComponents}" String "${CardComponents}"
} }
MultiCodec { MultiCodec {
Regex "(rt712|rt713|rt721|rt722|rt1320)" Regex "(${var:MultiCodecRegex})"
String "${var:SpeakerCodec1} ${var:HeadsetCodec1} ${var:MicCodec1}" 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 { If.old_multi_spk {
Condition { Condition {
Type RegexMatch Type RegexMatch
@ -65,83 +73,119 @@ If.old_multi_spk {
True.Define.SpeakerCodec1 "cs42l43-spk+cs35l56" 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 { If.multi_init {
Condition { Condition {
Type String Type String
Empty "${var:MultiCodec1}" Empty "${var:MultiCodec1}"
} }
False { False {
Define { Macro.rt712.MultiCodecInit "CodecId=rt712"
MultiSpeakerShadow "${var:SpeakerCodec1}" Macro.rt713.MultiCodecInit "CodecId=rt713"
MultiMicShadow "${var:MicCodec1}" 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 { Condition {
Type RegexMatch Type String
# guard with "=" to avoid empty string matching Empty "${var:MicCodecFile}"
Regex "=(${var:MultiCodec1}(-sdca)?)="
String "=${var:SpeakerCodec1}="
} }
True { False.If.dup {
Define.SpeakerCodec1 "" 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 { Condition {
Type RegexMatch Type String
# guard with "=" to avoid empty string matching Empty "${var:HeadsetCodecFile}"
Regex "=(${var:MultiCodec1}(-sdca)?)="
String "=${var:MicCodec1}="
} }
True { False.If.dup {
Define.MicCodec1 "" 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 { If.mic_init_rt715 {
Condition { Condition {
Type String Type String