* [PATCH 0/6] ASoC: Fix controls that write another control's bits
@ 2026-10-08 13:09 HyeongJun An
2026-10-08 13:09 ` [PATCH 1/6] ASoC: cs42l56: Put the Limiter Cushion control on the limiter register HyeongJun An
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: HyeongJun An @ 2026-10-08 13:09 UTC (permalink / raw)
To: Mark Brown; +Cc: Liam Girdwood, linux-sound, linux-kernel, HyeongJun An
In the es8316 thread Mark suggested checking at registration time for
controls whose register fields overlap [1]. Before adding such a check,
I wanted to see what it would find in the tree today.
A script expanded the control tables of every ASoC driver built by
allmodconfig and looked for two controls in one table whose register
fields overlap. It found 80 pairs in 33 drivers. Most are real bugs.
The rest are deliberate, where two names drive the same field, such as
the AC and DRC mode thresholds in sta32x.
This series fixes six that I could confirm against the vendor
datasheet. In each one, writing a control changes a different control,
and the bits it should own cannot be reached. Most date back to the
first version of the driver.
One more is left out on purpose. The cs42l56 ADC Mute Switch writes the
ADC invert bits. The real mute bits are also written by the
cs42l56_mute() callback on every stream start and stop, so moving the
control there would let the stream mute override it. I am not sure
whether you would rather move it or drop it.
I have none of this hardware, so these are checked against the
datasheets only. More fixes, checked against the register headers,
and the registration time check would follow.
[1] https://lore.kernel.org/all/0fefbfe1-021b-46b2-8945-15956e75e37f@sirena.org.uk/
HyeongJun An (6):
ASoC: cs42l56: Put the Limiter Cushion control on the limiter register
ASoC: cs42l52: Fix the NG Type Switch bit
ASoC: pcm3168a: Fix the DAC zero flag polarity bit
ASoC: max98371: Fix the Speaker DHT Min Volume bits
ASoC: wm8978: Fix the 128x oversampling switch bits
ASoC: nau8822: Fix the 128x oversampling switch bits
sound/soc/codecs/cs42l52.c | 2 +-
sound/soc/codecs/cs42l56.c | 2 +-
sound/soc/codecs/max98371.c | 2 +-
sound/soc/codecs/nau8822.c | 4 ++--
sound/soc/codecs/pcm3168a.c | 2 +-
sound/soc/codecs/wm8978.c | 4 ++--
6 files changed, 8 insertions(+), 8 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/6] ASoC: cs42l56: Put the Limiter Cushion control on the limiter register
2026-10-08 13:09 [PATCH 0/6] ASoC: Fix controls that write another control's bits HyeongJun An
@ 2026-10-08 13:09 ` HyeongJun An
2026-10-08 13:09 ` [PATCH 2/6] ASoC: cs42l52: Fix the NG Type Switch bit HyeongJun An
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: HyeongJun An @ 2026-10-08 13:09 UTC (permalink / raw)
To: Mark Brown
Cc: Liam Girdwood, linux-sound, linux-kernel, HyeongJun An,
David Rhodes, Richard Fitzgerald, Jaroslav Kysela, Takashi Iwai,
patches
The Limiter Cushion control writes bits 4:2 of the ALC Thresholds
register. Those bits are ALCMIN, which the ALC MIN control owns. The
datasheet puts CUSH at bits 4:2 of the Limit Thresholds Control
register, next to LMAX, which the Limiter MAX control already uses.
So setting the limiter cushion changes the ALC minimum threshold, and
the cushion itself cannot be set.
Use CS42L56_LIM_THRESHOLD_CTL.
Fixes: 272b5edd3b8f ("ASoC: Add support for CS42L56 CODEC")
Link: https://statics.cirrus.com/pubs/proDatasheet/CS42L56_F2.pdf
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
---
sound/soc/codecs/cs42l56.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c
index ad45e8fdb393..54d23857b0ad 100644
--- a/sound/soc/codecs/cs42l56.c
+++ b/sound/soc/codecs/cs42l56.c
@@ -481,7 +481,7 @@ static const struct snd_kcontrol_new cs42l56_snd_controls[] = {
0, 0x3f, 0, 0),
SOC_SINGLE_TLV("Limiter MAX", CS42L56_LIM_THRESHOLD_CTL,
5, 0x07, 1, alc_tlv),
- SOC_SINGLE_TLV("Limiter Cushion", CS42L56_ALC_THRESHOLD,
+ SOC_SINGLE_TLV("Limiter Cushion", CS42L56_LIM_THRESHOLD_CTL,
2, 0x07, 1, alc_tlv),
SOC_SINGLE("NG Switch", CS42L56_NOISE_GATE_CTL, 6, 1, 1),
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/6] ASoC: cs42l52: Fix the NG Type Switch bit
2026-10-08 13:09 [PATCH 0/6] ASoC: Fix controls that write another control's bits HyeongJun An
2026-10-08 13:09 ` [PATCH 1/6] ASoC: cs42l56: Put the Limiter Cushion control on the limiter register HyeongJun An
@ 2026-10-08 13:09 ` HyeongJun An
2026-10-08 13:09 ` [PATCH 3/6] ASoC: pcm3168a: Fix the DAC zero flag polarity bit HyeongJun An
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: HyeongJun An @ 2026-10-08 13:09 UTC (permalink / raw)
To: Mark Brown
Cc: Liam Girdwood, linux-sound, linux-kernel, HyeongJun An,
David Rhodes, Richard Fitzgerald, Jaroslav Kysela, Takashi Iwai,
patches
The NG Type Switch enum selects between "Apply Specific" and "Apply
All", which is the NGALL bit. The datasheet puts NGALL at bit 7 of the
Noise Gate Control register. The enum uses bit 6, which is NG, the
noise gate enable owned by the NG Enable Switch. cs42l52.h names it
CS42L52_NG_ENABLE_SHIFT. cs42l56 has the same Noise Gate register and
puts its NG All Switch at bit 7.
So changing the noise gate type turns the noise gate on or off, and
NGALL cannot be set.
Use bit 7.
Fixes: dfe0f98b8d2e ("ASoC: Add support for CS42L52 Codec")
Link: https://statics.cirrus.com/pubs/proDatasheet/CS42L52_F2.pdf
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
---
sound/soc/codecs/cs42l52.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 5f033556099a..1d3334886402 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -290,7 +290,7 @@ static const char * const cs42l52_ng_type_text[] = {
};
static SOC_ENUM_SINGLE_DECL(ng_type_enum,
- CS42L52_NOISE_GATE_CTL, 6,
+ CS42L52_NOISE_GATE_CTL, 7,
cs42l52_ng_type_text);
static const char * const left_swap_text[] = {
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/6] ASoC: pcm3168a: Fix the DAC zero flag polarity bit
2026-10-08 13:09 [PATCH 0/6] ASoC: Fix controls that write another control's bits HyeongJun An
2026-10-08 13:09 ` [PATCH 1/6] ASoC: cs42l56: Put the Limiter Cushion control on the limiter register HyeongJun An
2026-10-08 13:09 ` [PATCH 2/6] ASoC: cs42l52: Fix the NG Type Switch bit HyeongJun An
@ 2026-10-08 13:09 ` HyeongJun An
2026-10-09 10:51 ` Cezary Rojewski
2026-10-08 13:09 ` [PATCH 4/6] ASoC: max98371: Fix the Speaker DHT Min Volume bits HyeongJun An
` (2 subsequent siblings)
5 siblings, 1 reply; 8+ messages in thread
From: HyeongJun An @ 2026-10-08 13:09 UTC (permalink / raw)
To: Mark Brown
Cc: Liam Girdwood, linux-sound, linux-kernel, HyeongJun An,
Shenghao Ding, Kevin Lu, Baojun Xu, Sen Wang, Jaroslav Kysela,
Takashi Iwai
The DAC Zero Flag Polarity enum uses PCM3168A_DAC_ATSPDA_SHIFT, which
is bit 6 of register 70. That bit is ATSPDA, the attenuation speed,
which the DAC Volume Rate Multiplier enum already owns. The datasheet
puts ZREV, the zero flag polarity, at bit 0. The header defines
PCM3168A_DAC_ZREV_SHIFT for it, but nothing uses it.
So changing the zero flag polarity changes the attenuation speed, and
ZREV cannot be set.
Use PCM3168A_DAC_ZREV_SHIFT.
Fixes: a9b17a638af5 ("ASoC: pcm3168a: Add driver for pcm3168a codec")
Link: https://www.ti.com/lit/ds/symlink/pcm3168a.pdf
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
---
sound/soc/codecs/pcm3168a.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
index cb6a6f08f2f8..6f45ea4869a7 100644
--- a/sound/soc/codecs/pcm3168a.c
+++ b/sound/soc/codecs/pcm3168a.c
@@ -103,7 +103,7 @@ static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_zf_func, PCM3168A_DAC_ATT_DEMP_ZF,
static const char *const pcm3168a_pol[] = { "Active High", "Active Low" };
static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_zf_pol, PCM3168A_DAC_ATT_DEMP_ZF,
- PCM3168A_DAC_ATSPDA_SHIFT, pcm3168a_pol);
+ PCM3168A_DAC_ZREV_SHIFT, pcm3168a_pol);
static const char *const pcm3168a_con[] = { "Differential", "Single-Ended" };
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/6] ASoC: max98371: Fix the Speaker DHT Min Volume bits
2026-10-08 13:09 [PATCH 0/6] ASoC: Fix controls that write another control's bits HyeongJun An
` (2 preceding siblings ...)
2026-10-08 13:09 ` [PATCH 3/6] ASoC: pcm3168a: Fix the DAC zero flag polarity bit HyeongJun An
@ 2026-10-08 13:09 ` HyeongJun An
2026-10-08 13:09 ` [PATCH 5/6] ASoC: wm8978: Fix the 128x oversampling switch bits HyeongJun An
2026-10-08 13:09 ` [PATCH 6/6] ASoC: nau8822: " HyeongJun An
5 siblings, 0 replies; 8+ messages in thread
From: HyeongJun An @ 2026-10-08 13:09 UTC (permalink / raw)
To: Mark Brown
Cc: Liam Girdwood, linux-sound, linux-kernel, HyeongJun An,
Jaroslav Kysela, Takashi Iwai
Register 0x31 holds two 4-bit fields. The datasheet puts SPK_GAIN_MIN
at bits 7:4 and DHT_VROT_PNT at bits 3:0. The Speaker DHT Min Volume
and Speaker DHT Rotation Volume controls both use bits 3:0.
So setting the minimum speaker gain changes the DHT rotation point, and
SPK_GAIN_MIN cannot be set.
Move Speaker DHT Min Volume to bits 7:4.
Fixes: ca2cd6bc6663 ("ASoC: Add max98371 codec driver")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
---
sound/soc/codecs/max98371.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c
index b62bd98f2252..72bcdb0d1289 100644
--- a/sound/soc/codecs/max98371.c
+++ b/sound/soc/codecs/max98371.c
@@ -166,7 +166,7 @@ static const struct snd_kcontrol_new max98371_snd_controls[] = {
0, (1<<MAX98371_DHT_MAX_WIDTH)-1, 0,
max98371_dht_max_gain),
SOC_SINGLE_TLV("Speaker DHT Min Volume", MAX98371_DHT_GAIN,
- 0, (1<<MAX98371_DHT_GAIN_WIDTH)-1, 0,
+ 4, (1<<MAX98371_DHT_GAIN_WIDTH)-1, 0,
max98371_dht_min_gain),
SOC_SINGLE_TLV("Speaker DHT Rotation Volume", MAX98371_DHT_GAIN,
0, (1<<MAX98371_DHT_ROT_WIDTH)-1, 0,
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 5/6] ASoC: wm8978: Fix the 128x oversampling switch bits
2026-10-08 13:09 [PATCH 0/6] ASoC: Fix controls that write another control's bits HyeongJun An
` (3 preceding siblings ...)
2026-10-08 13:09 ` [PATCH 4/6] ASoC: max98371: Fix the Speaker DHT Min Volume bits HyeongJun An
@ 2026-10-08 13:09 ` HyeongJun An
2026-10-08 13:09 ` [PATCH 6/6] ASoC: nau8822: " HyeongJun An
5 siblings, 0 replies; 8+ messages in thread
From: HyeongJun An @ 2026-10-08 13:09 UTC (permalink / raw)
To: Mark Brown
Cc: Liam Girdwood, linux-sound, linux-kernel, HyeongJun An,
Jaroslav Kysela, Takashi Iwai, patches
The DAC and ADC 128x Oversampling Switches use bit 5 of R10 and R14.
Table 66 of the WM8978 datasheet puts DACOSR128 and ADCOSR128 at bit 3
of those registers.
In R14, bit 5 is inside HPFCUT[6:4], which the High Pass Cut Off
control owns. So turning on ADC oversampling changes the high pass
cut-off, and the oversampling bit cannot be set. In R10, bit 5 is
reserved, so the DAC switch has no effect.
Use bit 3 for both.
Fixes: 823dba519122 ("ASoC: Fix broken bitfield definitions in WM8978")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
---
sound/soc/codecs/wm8978.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 25cc433c7653..258bc9f88f52 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -255,9 +255,9 @@ static const struct snd_kcontrol_new wm8978_snd_controls[] = {
/* DAC / ADC oversampling */
SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL,
- 5, 1, 0),
+ 3, 1, 0),
SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL,
- 5, 1, 0),
+ 3, 1, 0),
};
/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 6/6] ASoC: nau8822: Fix the 128x oversampling switch bits
2026-10-08 13:09 [PATCH 0/6] ASoC: Fix controls that write another control's bits HyeongJun An
` (4 preceding siblings ...)
2026-10-08 13:09 ` [PATCH 5/6] ASoC: wm8978: Fix the 128x oversampling switch bits HyeongJun An
@ 2026-10-08 13:09 ` HyeongJun An
5 siblings, 0 replies; 8+ messages in thread
From: HyeongJun An @ 2026-10-08 13:09 UTC (permalink / raw)
To: Mark Brown
Cc: Liam Girdwood, linux-sound, linux-kernel, HyeongJun An,
Jaroslav Kysela, Takashi Iwai
The DAC and ADC 128x Oversampling Switches use bit 5 of R10 and R14.
The NAU8822 datasheet register map puts DACOS and ADCOS at bit 3 of
those registers.
In R14, bit 5 is inside HPF[6:4], which the High Pass Cut Off control
owns. So turning on ADC oversampling changes the high pass cut-off, and
the oversampling bit cannot be set. In R10, bit 5 is reserved, so the
DAC switch has no effect.
Use bit 3 for both.
Fixes: 1e3cb6c321be ("ASoC: nau8822: new codec driver")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
---
sound/soc/codecs/nau8822.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c
index db1931d7b901..d91a0bed2025 100644
--- a/sound/soc/codecs/nau8822.c
+++ b/sound/soc/codecs/nau8822.c
@@ -383,9 +383,9 @@ static const struct snd_kcontrol_new nau8822_snd_controls[] = {
NAU8822_REG_RIGHT_ADC_BOOST_CONTROL, 0, 7, 0, boost_tlv),
SOC_SINGLE("DAC 128x Oversampling Switch",
- NAU8822_REG_DAC_CONTROL, 5, 1, 0),
+ NAU8822_REG_DAC_CONTROL, 3, 1, 0),
SOC_SINGLE("ADC 128x Oversampling Switch",
- NAU8822_REG_ADC_CONTROL, 5, 1, 0),
+ NAU8822_REG_ADC_CONTROL, 3, 1, 0),
};
/* LMAIN and RMAIN Mixer */
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 3/6] ASoC: pcm3168a: Fix the DAC zero flag polarity bit
2026-10-08 13:09 ` [PATCH 3/6] ASoC: pcm3168a: Fix the DAC zero flag polarity bit HyeongJun An
@ 2026-10-09 10:51 ` Cezary Rojewski
0 siblings, 0 replies; 8+ messages in thread
From: Cezary Rojewski @ 2026-10-09 10:51 UTC (permalink / raw)
To: HyeongJun An
Cc: Liam Girdwood, linux-sound, linux-kernel, Shenghao Ding,
Kevin Lu, Baojun Xu, Sen Wang, Jaroslav Kysela, Takashi Iwai,
Mark Brown
On 10/8/2026 3:09 PM, HyeongJun An wrote:
> The DAC Zero Flag Polarity enum uses PCM3168A_DAC_ATSPDA_SHIFT, which
> is bit 6 of register 70. That bit is ATSPDA, the attenuation speed,
> which the DAC Volume Rate Multiplier enum already owns. The datasheet
> puts ZREV, the zero flag polarity, at bit 0. The header defines
> PCM3168A_DAC_ZREV_SHIFT for it, but nothing uses it.
>
> So changing the zero flag polarity changes the attenuation speed, and
> ZREV cannot be set.
>
> Use PCM3168A_DAC_ZREV_SHIFT.
The entire message could be summarized with:
Field DAC Zero flag polarity select (ZREV) is found at offset 0 in
register DAC Control 3 (0x46), not at offset 6 - DAC Attenuation speed
(ATSPDA).
In regard to the commit title, you're not fixing the bit. Your change
actually makes pcm3168a_dac_zf_pol kctl useful and working.
ASoC: codecs: pcm3168a: Fix definition of DAC Zero polarity control
>
> Fixes: a9b17a638af5 ("ASoC: pcm3168a: Add driver for pcm3168a codec")
> Link: https://www.ti.com/lit/ds/symlink/pcm3168a.pdf
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
> ---
> sound/soc/codecs/pcm3168a.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
> index cb6a6f08f2f8..6f45ea4869a7 100644
> --- a/sound/soc/codecs/pcm3168a.c
> +++ b/sound/soc/codecs/pcm3168a.c
> @@ -103,7 +103,7 @@ static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_zf_func, PCM3168A_DAC_ATT_DEMP_ZF,
> static const char *const pcm3168a_pol[] = { "Active High", "Active Low" };
>
> static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_zf_pol, PCM3168A_DAC_ATT_DEMP_ZF,
> - PCM3168A_DAC_ATSPDA_SHIFT, pcm3168a_pol);
> + PCM3168A_DAC_ZREV_SHIFT, pcm3168a_pol);
Good catch. Not using the kctl with Intel's DSP + pcm3168a configuration
but won't hurt to say that no regression occurred.
I'd prefer to see a better message and commit title though the code
looks good:
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-10-09 10:51 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-08 13:09 [PATCH 0/6] ASoC: Fix controls that write another control's bits HyeongJun An
2026-10-08 13:09 ` [PATCH 1/6] ASoC: cs42l56: Put the Limiter Cushion control on the limiter register HyeongJun An
2026-10-08 13:09 ` [PATCH 2/6] ASoC: cs42l52: Fix the NG Type Switch bit HyeongJun An
2026-10-08 13:09 ` [PATCH 3/6] ASoC: pcm3168a: Fix the DAC zero flag polarity bit HyeongJun An
2026-10-09 10:51 ` Cezary Rojewski
2026-10-08 13:09 ` [PATCH 4/6] ASoC: max98371: Fix the Speaker DHT Min Volume bits HyeongJun An
2026-10-08 13:09 ` [PATCH 5/6] ASoC: wm8978: Fix the 128x oversampling switch bits HyeongJun An
2026-10-08 13:09 ` [PATCH 6/6] ASoC: nau8822: " HyeongJun An
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®