From 233d36a96009682208cc4ca1139b9e5641a8bf09 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Sep 2026 09:28:01 +0100 Subject: ASoC: codecs: lpass-wsa-macro: use v2.5 Compander1 addresses on v2.5+ wsa_macro_set_spkr_mode() unconditionally writes CDC_WSA_COMPANDER1_CTL3 (0x5CC) and CDC_WSA_COMPANDER1_CTL7 (0x5DC). On v2.5+ silicon these registers moved to CDC_2_5_WSA_COMPANDER1_CTL3 (0x5EC) and CDC_2_5_WSA_COMPANDER1_CTL7 (0x5FC); the v2.1 addresses are dead on that hardware, so the update_bits() calls take a bus error: wsa_macro 6c90000.codec: ASoC error (-5): at snd_soc_component_update_bits() on 6c90000.codec for register: [0x000005dc] The flat regcache had been hiding the read side of this by returning the zero-initialised cache slot instead of doing a bus read, so the error only becomes visible once the cache reports the miss honestly and regmap falls back to a real bus read. Select the correct address for Compander1 CTL3/CTL7 based on codec_version. The Compander0 and Boost registers used in the same function have the same address across versions, so they stay unchanged. Also collapse the two mode branches to a single sequence with mode-selected values, which is what the switch was doing anyway. Fixes: 727de4fbc546 ("ASoC: codecs: lpass-wsa-macro: Correct support for newer v2.5 version") Cc: stable@vger.kernel.org Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260908082806.648797-2-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-wsa-macro.c | 42 +++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index cfd2ac0a6cda..7a2b0cf9398a 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -1129,27 +1129,35 @@ static const struct regmap_config wsa_regmap_config = { int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode) { struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); + unsigned int comp1_ctl3, comp1_ctl7; + u8 comp_val, boost_val; wsa->spkr_mode = mode; - switch (mode) { - case WSA_MACRO_SPKR_MODE_1: - snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00); - snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00); - snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00); - snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00); - snd_soc_component_update_bits(component, CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44); - snd_soc_component_update_bits(component, CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44); - break; - default: - snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80); - snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80); - snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01); - snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01); - snd_soc_component_update_bits(component, CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58); - snd_soc_component_update_bits(component, CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58); - break; + /* Compander1 CTL3/CTL7 moved on v2.5+ silicon. */ + if (wsa->codec_version >= LPASS_CODEC_VERSION_2_5) { + comp1_ctl3 = CDC_2_5_WSA_COMPANDER1_CTL3; + comp1_ctl7 = CDC_2_5_WSA_COMPANDER1_CTL7; + } else { + comp1_ctl3 = CDC_WSA_COMPANDER1_CTL3; + comp1_ctl7 = CDC_WSA_COMPANDER1_CTL7; } + + if (mode == WSA_MACRO_SPKR_MODE_1) { + comp_val = 0x00; + boost_val = 0x44; + } else { + comp_val = 0x80; + boost_val = 0x58; + } + + snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL3, 0x80, comp_val); + snd_soc_component_update_bits(component, comp1_ctl3, 0x80, comp_val); + snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL7, 0x01, comp_val ? 0x01 : 0x00); + snd_soc_component_update_bits(component, comp1_ctl7, 0x01, comp_val ? 0x01 : 0x00); + snd_soc_component_update_bits(component, CDC_WSA_BOOST0_BOOST_CTL, 0x7C, boost_val); + snd_soc_component_update_bits(component, CDC_WSA_BOOST1_BOOST_CTL, 0x7C, boost_val); + return 0; } EXPORT_SYMBOL(wsa_macro_set_spkr_mode); -- cgit v1.2.3 From 246c785491bb265b9716a512057cee8f1a5a3280 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Sep 2026 09:28:02 +0100 Subject: ASoC: codecs: lpass-{rx,wsa}-macro: sort reg_defaults before regmap init Both drivers build the reg_defaults array by concatenating a base table with a codec-version-specific one; the resulting array is not in register-address order because the version-specific ranges overlap the base range. Regmap detects this and prints wsa_macro 6c90000.codec: Driver needs fixing: Unsorted reg_defaults, sorting the copy rx_macro 6a70000.codec: Driver needs fixing: Unsorted reg_defaults, sorting the copy then sorts its own copy at runtime. Call regcache_sort_defaults() on the concatenated array before handing it to regmap so the warning goes away and regmap does not have to sort a second time. Keeping the base/version-specific split is deliberate for readability, so a static reorder is not appropriate here. Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260908082806.648797-3-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-rx-macro.c | 2 ++ sound/soc/codecs/lpass-wsa-macro.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 282a6aaa9986..45d8d51e55ad 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -3852,6 +3852,8 @@ static int rx_macro_probe(struct platform_device *pdev) return -EINVAL; } + regcache_sort_defaults(reg_defaults, def_count); + struct regmap_config *reg_config __free(kfree) = kmemdup(&rx_regmap_config, sizeof(*reg_config), GFP_KERNEL); diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index 7a2b0cf9398a..4d7e7e30f460 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -2763,6 +2763,8 @@ static int wsa_macro_probe(struct platform_device *pdev) return -EINVAL; } + regcache_sort_defaults(reg_defaults, def_count); + struct regmap_config *reg_config __free(kfree) = kmemdup(&wsa_regmap_config, sizeof(*reg_config), GFP_KERNEL); -- cgit v1.2.3 From ce7164c89b5c9c9afe12b97ee3fae93250fdf814 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Sep 2026 09:28:03 +0100 Subject: ASoC: codecs: lpass-wsa-macro: switch cache to REGCACHE_MAPLE REGCACHE_FLAT hides missing-default reads by returning the zero- initialised cache slot instead of doing a bus read. The caller can't tell that value apart from a real hardware value, so any un-defaulted, readable, non-volatile register that gets read silently returns wrong data. Since commit e062bdfdd6ad ("regmap: warn users about uninitialized flat cache") regmap dev_warn_once()s the first such miss, but any subsequent miss stays silent. Switch to REGCACHE_MAPLE. A cache miss returns -ENOENT and the regmap core falls back to a real bus read, so the caller always gets the true hardware value. Write-cache behaviour is unchanged. Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260908082806.648797-4-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-wsa-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index 4d7e7e30f460..d254518634cf 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -1109,7 +1109,7 @@ static const struct regmap_config wsa_regmap_config = { .reg_bits = 16, .val_bits = 32, /* 8 but with 32 bit read/write */ .reg_stride = 4, - .cache_type = REGCACHE_FLAT, + .cache_type = REGCACHE_MAPLE, /* .reg_defaults and .num_reg_defaults set in probe() */ .max_register = WSA_MAX_OFFSET, .writeable_reg = wsa_is_writeable_register, -- cgit v1.2.3 From 384bd7cf40530b32e838a38977902de6bc7f4d19 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Sep 2026 09:28:04 +0100 Subject: ASoC: codecs: lpass-rx-macro: switch cache to REGCACHE_MAPLE REGCACHE_FLAT hides missing-default reads by returning the zero- initialised cache slot instead of doing a bus read. The caller can't tell that value apart from a real hardware value, so any un-defaulted, readable, non-volatile register that gets read silently returns wrong data. Since commit e062bdfdd6ad ("regmap: warn users about uninitialized flat cache") regmap dev_warn_once()s the first such miss, but any subsequent miss stays silent. Switch to REGCACHE_MAPLE. A cache miss returns -ENOENT and the regmap core falls back to a real bus read, so the caller always gets the true hardware value. Write-cache behaviour is unchanged. Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260908082806.648797-5-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-rx-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 45d8d51e55ad..30c7a0a70aeb 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -1673,7 +1673,7 @@ static const struct regmap_config rx_regmap_config = { .reg_bits = 16, .val_bits = 32, /* 8 but with 32 bit read/write */ .reg_stride = 4, - .cache_type = REGCACHE_FLAT, + .cache_type = REGCACHE_MAPLE, .max_register = RX_MAX_OFFSET, .writeable_reg = rx_is_writeable_register, .volatile_reg = rx_is_volatile_register, -- cgit v1.2.3 From 8ed9306885eb7e242ad0f859e1fbc2d822d3d0eb Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Sep 2026 09:28:05 +0100 Subject: ASoC: codecs: lpass-tx-macro: switch cache to REGCACHE_MAPLE REGCACHE_FLAT hides missing-default reads by returning the zero- initialised cache slot instead of doing a bus read. The caller can't tell that value apart from a real hardware value, so any un-defaulted, readable, non-volatile register that gets read silently returns wrong data. Since commit e062bdfdd6ad ("regmap: warn users about uninitialized flat cache") regmap dev_warn_once()s the first such miss, but any subsequent miss stays silent. Switch to REGCACHE_MAPLE. A cache miss returns -ENOENT and the regmap core falls back to a real bus read, so the caller always gets the true hardware value. Write-cache behaviour is unchanged. Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260908082806.648797-6-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-tx-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index a8e83eb60ba2..6f362b196f47 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -602,7 +602,7 @@ static const struct regmap_config tx_regmap_config = { .reg_bits = 16, .val_bits = 32, .reg_stride = 4, - .cache_type = REGCACHE_FLAT, + .cache_type = REGCACHE_MAPLE, .max_register = TX_MAX_OFFSET, .reg_defaults = tx_defaults, .num_reg_defaults = ARRAY_SIZE(tx_defaults), -- cgit v1.2.3 From 322a9e0850b41a628b59c29be89f499acba9f1c8 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Sep 2026 09:28:06 +0100 Subject: ASoC: codecs: lpass-va-macro: switch cache to REGCACHE_MAPLE REGCACHE_FLAT hides missing-default reads by returning the zero- initialised cache slot instead of doing a bus read. The caller can't tell that value apart from a real hardware value, so any un-defaulted, readable, non-volatile register that gets read silently returns wrong data. Since commit e062bdfdd6ad ("regmap: warn users about uninitialized flat cache") regmap dev_warn_once()s the first such miss, but any subsequent miss stays silent. Switch to REGCACHE_MAPLE. A cache miss returns -ENOENT and the regmap core falls back to a real bus read, so the caller always gets the true hardware value. Write-cache behaviour is unchanged. Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260908082806.648797-7-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-va-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c index dbc5795b9273..f0797715ab54 100644 --- a/sound/soc/codecs/lpass-va-macro.c +++ b/sound/soc/codecs/lpass-va-macro.c @@ -454,7 +454,7 @@ static const struct regmap_config va_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, - .cache_type = REGCACHE_FLAT, + .cache_type = REGCACHE_MAPLE, .reg_defaults = va_defaults, .num_reg_defaults = ARRAY_SIZE(va_defaults), .max_register = VA_MAX_OFFSET, -- cgit v1.2.3