* [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support
@ 2026-10-14 9:12 Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 1/9] ASoC: dt-bindings: qcom: Add Shikra RX and VA macro codecs Mohammad Rafi Shaik
` (8 more replies)
0 siblings, 9 replies; 14+ messages in thread
From: Mohammad Rafi Shaik @ 2026-10-14 9:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Mohammad Rafi Shaik, linux-arm-msm, linux-sound, devicetree,
linux-kernel, Krzysztof Kozlowski, Srinivas Kandagatla,
Ajay Kumar Nandam, Prasad Kumpatla, Sarath Ganapathiraju
This series adds audio support for two Qualcomm SoC platforms — Shikra
and Hawi — by extending the LPASS codec macro drivers for version 4.1
and 4.0 respectively, and by adding SoundWire microphone capture support
to the VA macro.
Shikra (LPASS codec v4.1)
--------------------------
The first part of the series targets the Shikra platform, which
integrates LPASS codec version 4.1. This is not backwards-compatible
with previously described compatibles, so new DT bindings and
standalone compatibles are introduced for the RX and VA macros.
Driver changes include version detection enhancements (including a fix
for the missing v2.9 version string in the common helper), FS counter
bypass programming required before the codec is enabled, and a v4.1
specific regmap configuration covering the additional adaptive filter
(ADPT) blocks at 0x0800..0x09a4.
SoundWire microphone support (VA macro)
----------------------------------------
The VA decimators previously only supported DMIC inputs. A new patch
extends them to accept SoundWire microphone (SMIC) sources as well,
updating the ADC_DMIC_SEL mux programming to be resolved at decimator
enable time rather than at mixer write time, ensuring correct operation
regardless of the order in which userspace restores controls. DMIC-
specific HPF programming is skipped when an SMIC source is active.
Hawi (LPASS codec v4.0)
------------------------
The final three patches, add support for the Hawi (and Maili) platform
which integrates LPASS codec v4.0.
While v4.0 shares the same RX and VA macro register layout as the
existing v2.5+ path and reuses those helpers, the TX macro is based on
Bolero v4.0 — an extension of the v9.x TX macro that adds a port-select
stage in the SWR microphone input path and an adaptive filter (ADPT)
block. The ADPT block must be disabled before a decimator is enabled;
this is gated on a new has_adpt flag in match data since the register
does not exist on earlier versions.
New DT bindings document the RX, TX and VA macro compatibles for Hawi,
noting the clock differences: the RX macro uses the 'lpr' clock rather
than 'macro', and the VA macro takes an additional 'heartbeatpulse'
clock sourced from the LPASS VA CSR rate generator.
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
Changes in v5:
- dt-bindings: rx-macro: drop the redundant clocks "minItems" from the shikra
conditional, it is already set at the top level suggested by Krzysztof.
- va-macro: shikra: do not hardcode the codec version in match data, read it
back from the hardware and cross check it against the register layout
selected by the compatible, reported by Ajay, Sashiko.
- va-macro: SoundWire mic: do not let a write to the DMIC/SMIC mux that is not
part of the active path reprogram the shared ADC_DMIC_SEL bit of a running
capture, reported by Sashiko.
- va-macro: SoundWire mic: clarify that only the HPF zero gate assertion is
specific to the DMIC path, in both the commit message and the code as
suggested by Ajay.
- Add device tree bindings for Maili.
- Prevent duplicate registration of TX DECn MUX controls as suggested by
Mark.
- Add v4.0-specific regmap_config and default register table.
- Link to v4: https://lore.kernel.org/all/20260922-add_shikra_support-v1-0-6c6cb6444caf@oss.qualcomm.com/
Changes in v4:
- Added three new patches for Hawi / LPASS codec v4.0 support (DT bindings,
TX macro Bolero v4.0, RX/VA macro v4.0)
- Fixed all issues reported by Sashiko in v3.
- Link to v3: https://lore.kernel.org/all/20260917-add_shikra_support-v3-0-fc0e79c341aa@oss.qualcomm.com/
Changes in v3:
- Added Shikra-specific clock constraints for RX and VA Macro DT bindings.
- Restricted clock and clock-names properties to align with Shikra hardware requirements.
- Removed dead code from patch 3 of v2, as suggested by Krzysztof.
- Replaced open-coded checks with a flag-based conditional for LPASS
codec v4.1 specific configurations.
- Reused existing SoundWire microphone widgets, as suggested by Srinivas.
- Switched the regmap cache type to REGCACHE_MAPLE.
- Link to v2: https://patch.msgid.link/20260910-add_shikra_support-v2-0-fdd2129c696c@oss.qualcomm.com
Changes in v2:
- Updated FS CONTROL and ADPT only for version 4.1, as suggested by Krzysztof.
- Addressed Konrad's review comments from v1 by replacing magic numbers and
lower hex reg values where appropriate.
- Link to v1: https://patch.msgid.link/20260608172023.2965292-1-mohammad.rafi.shaik@oss.qualcomm.com
To: Srinivas Kandagatla <srini@kernel.org>
To: Liam Girdwood <lgirdwood@gmail.com>
To: Mark Brown <broonie@kernel.org>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Jaroslav Kysela <perex@perex.cz>
To: Takashi Iwai <tiwai@suse.com>
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-sound@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
Mohammad Rafi Shaik (5):
ASoC: dt-bindings: qcom: Add Shikra RX and VA macro codecs
ASoC: qcom: lpass-macro-common: Add missing v2.9 version string
ASoC: qcom: lpass-rx-macro: Add shikra compatible
ASoC: qcom: lpass-va-macro: Add shikra compatible
ASoC: qcom: lpass-va-macro: Add SoundWire microphone support
Prasad Kumpatla (4):
ASoC: dt-bindings: qcom: Add Hawi LPASS macro codecs
ASoC: dt-bindings: qcom: Add Maili LPASS macro codecs
ASoC: qcom: lpass-tx-macro: Add support for Bolero v4.0
ASoC: qcom: lpass: Add support for LPASS codec v4.0
.../bindings/sound/qcom,lpass-rx-macro.yaml | 39 ++
.../bindings/sound/qcom,lpass-tx-macro.yaml | 23 +
.../bindings/sound/qcom,lpass-va-macro.yaml | 40 ++
sound/soc/codecs/lpass-macro-common.h | 9 +
sound/soc/codecs/lpass-rx-macro.c | 19 +
sound/soc/codecs/lpass-tx-macro.c | 576 ++++++++++++++++++++-
sound/soc/codecs/lpass-va-macro.c | 442 +++++++++++++++-
7 files changed, 1122 insertions(+), 26 deletions(-)
---
base-commit: 631a161db2c5168dd836242571724baba3561a1f
change-id: 20261014-add_shikra_support_v5-7ca922588a98
Best regards,
--
Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v5 1/9] ASoC: dt-bindings: qcom: Add Shikra RX and VA macro codecs
2026-10-14 9:12 [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support Mohammad Rafi Shaik
@ 2026-10-14 9:12 ` Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 2/9] ASoC: qcom: lpass-macro-common: Add missing v2.9 version string Mohammad Rafi Shaik
` (7 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Mohammad Rafi Shaik @ 2026-10-14 9:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Mohammad Rafi Shaik, linux-arm-msm, linux-sound, devicetree,
linux-kernel, Krzysztof Kozlowski
Document compatibles for Qualcomm shikra rx and va macro codecs.
This SoC does not provide macro and dcodec clock so reflect that in
the bindings.
Shikra integrates LPASS codec version 4.1, which is not backwards
compatible with the already described compatibles.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
.../devicetree/bindings/sound/qcom,lpass-rx-macro.yaml | 16 ++++++++++++++++
.../devicetree/bindings/sound/qcom,lpass-va-macro.yaml | 17 +++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
index 4988e7ed6..db63a75f1 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
@@ -14,6 +14,7 @@ properties:
oneOf:
- enum:
- qcom,sc7280-lpass-rx-macro
+ - qcom,shikra-lpass-rx-macro
- qcom,sm6115-lpass-rx-macro
- qcom,sm8250-lpass-rx-macro
- qcom,sm8450-lpass-rx-macro
@@ -138,6 +139,21 @@ allOf:
- const: dcodec
- const: fsgen
+ - if:
+ properties:
+ compatible:
+ enum:
+ - qcom,shikra-lpass-rx-macro
+ then:
+ properties:
+ clocks:
+ maxItems: 3
+ clock-names:
+ items:
+ - const: mclk
+ - const: npl
+ - const: fsgen
+
unevaluatedProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
index aea31fbda..683ebf702 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
@@ -14,6 +14,7 @@ properties:
oneOf:
- enum:
- qcom,sc7280-lpass-va-macro
+ - qcom,shikra-lpass-va-macro
- qcom,sm6115-lpass-va-macro
- qcom,sm8250-lpass-va-macro
- qcom,sm8450-lpass-va-macro
@@ -168,6 +169,22 @@ allOf:
- const: macro
- const: dcodec
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,shikra-lpass-va-macro
+ then:
+ properties:
+ clocks:
+ minItems: 2
+ maxItems: 2
+ clock-names:
+ items:
+ - const: mclk
+ - const: npl
+
unevaluatedProperties: false
examples:
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v5 2/9] ASoC: qcom: lpass-macro-common: Add missing v2.9 version string
2026-10-14 9:12 [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 1/9] ASoC: dt-bindings: qcom: Add Shikra RX and VA macro codecs Mohammad Rafi Shaik
@ 2026-10-14 9:12 ` Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 3/9] ASoC: qcom: lpass-rx-macro: Add shikra compatible Mohammad Rafi Shaik
` (6 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Mohammad Rafi Shaik @ 2026-10-14 9:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Mohammad Rafi Shaik, linux-arm-msm, linux-sound, devicetree,
linux-kernel, Srinivas Kandagatla, Ajay Kumar Nandam
LPASS_CODEC_VERSION_2_9 is detected by lpass-va-macro.c and consumed by
lpass-wsa-macro.c, but lpass_macro_get_codec_version_string() never
learned about it, so the probe log reports "LPASS Codec Version NA" on
those parts.
Add the missing case.
Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Reviewed-by: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com>
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
sound/soc/codecs/lpass-macro-common.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/lpass-macro-common.h b/sound/soc/codecs/lpass-macro-common.h
index 10ad68201..573b2145e 100644
--- a/sound/soc/codecs/lpass-macro-common.h
+++ b/sound/soc/codecs/lpass-macro-common.h
@@ -68,6 +68,8 @@ static inline const char *lpass_macro_get_codec_version_string(int version)
return "v2.7";
case LPASS_CODEC_VERSION_2_8:
return "v2.8";
+ case LPASS_CODEC_VERSION_2_9:
+ return "v2.9";
default:
break;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v5 3/9] ASoC: qcom: lpass-rx-macro: Add shikra compatible
2026-10-14 9:12 [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 1/9] ASoC: dt-bindings: qcom: Add Shikra RX and VA macro codecs Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 2/9] ASoC: qcom: lpass-macro-common: Add missing v2.9 version string Mohammad Rafi Shaik
@ 2026-10-14 9:12 ` Mohammad Rafi Shaik
2026-10-14 9:28 ` sashiko-bot
2026-10-14 9:12 ` [PATCH v5 4/9] ASoC: qcom: lpass-va-macro: " Mohammad Rafi Shaik
` (5 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Mohammad Rafi Shaik @ 2026-10-14 9:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Mohammad Rafi Shaik, linux-arm-msm, linux-sound, devicetree,
linux-kernel, Ajay Kumar Nandam
Add shikra RX macro compatible data and hook it into the LPASS codec
v4.1 flow.
The RX macro register layout of LPASS codec v4.1 matches the v2.5+
layout, so reuse the existing v2.5 register access helpers, controls
and widgets for it.
v4.1 additionally requires the FS counter to be bypassed before it is
enabled during MCLK enable. This is a property of the codec version and
not of the board, so key it off the version detected by the VA macro
rather than off match data.
Reviewed-by: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com>
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
sound/soc/codecs/lpass-macro-common.h | 3 +++
sound/soc/codecs/lpass-rx-macro.c | 14 ++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/sound/soc/codecs/lpass-macro-common.h b/sound/soc/codecs/lpass-macro-common.h
index 573b2145e..b52665b11 100644
--- a/sound/soc/codecs/lpass-macro-common.h
+++ b/sound/soc/codecs/lpass-macro-common.h
@@ -30,6 +30,7 @@ enum lpass_codec_version {
LPASS_CODEC_VERSION_2_7,
LPASS_CODEC_VERSION_2_8,
LPASS_CODEC_VERSION_2_9,
+ LPASS_CODEC_VERSION_4_1,
};
struct lpass_macro {
@@ -70,6 +71,8 @@ static inline const char *lpass_macro_get_codec_version_string(int version)
return "v2.8";
case LPASS_CODEC_VERSION_2_9:
return "v2.9";
+ case LPASS_CODEC_VERSION_4_1:
+ return "v4.1";
default:
break;
}
diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c
index c41eb8de6..93ceee878 100644
--- a/sound/soc/codecs/lpass-rx-macro.c
+++ b/sound/soc/codecs/lpass-rx-macro.c
@@ -60,6 +60,7 @@
#define CDC_RX_FS_MCLK_CNT_ENABLE BIT(0)
#define CDC_RX_FS_MCLK_CNT_CLR_MASK BIT(1)
#define CDC_RX_FS_MCLK_CNT_CLR BIT(1)
+#define CDC_RX_FS_CNT_BYPASS BIT(7)
#define CDC_RX_CLK_RST_CTRL_SWR_CONTROL (0x0108)
#define CDC_RX_SWR_CLK_EN_MASK BIT(0)
#define CDC_RX_SWR_RESET_MASK BIT(1)
@@ -652,6 +653,7 @@ struct rx_macro {
bool is_ear_mode_on;
bool hph_pwr_mode;
bool hph_hd2_mode;
+ bool fs_cnt_bypass;
struct snd_soc_component *component;
unsigned long active_ch_mask[RX_MACRO_MAX_DAIS];
unsigned long active_ch_cnt[RX_MACRO_MAX_DAIS];
@@ -1613,6 +1615,7 @@ static bool rx_is_rw_register(struct device *dev, unsigned int reg)
case LPASS_CODEC_VERSION_2_6:
case LPASS_CODEC_VERSION_2_7:
case LPASS_CODEC_VERSION_2_8:
+ case LPASS_CODEC_VERSION_4_1:
return rx_2_5_is_rw_register(dev, reg);
default:
break;
@@ -2045,6 +2048,11 @@ static int rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable)
CDC_RX_CLK_MCLK2_ENABLE);
regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
CDC_RX_FS_MCLK_CNT_CLR_MASK, 0x00);
+
+ if (rx->fs_cnt_bypass)
+ regmap_set_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
+ CDC_RX_FS_CNT_BYPASS);
+
regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
CDC_RX_FS_MCLK_CNT_EN_MASK,
CDC_RX_FS_MCLK_CNT_ENABLE);
@@ -3652,6 +3660,7 @@ static int rx_macro_component_probe(struct snd_soc_component *component)
case LPASS_CODEC_VERSION_2_6:
case LPASS_CODEC_VERSION_2_7:
case LPASS_CODEC_VERSION_2_8:
+ case LPASS_CODEC_VERSION_4_1:
controls = rx_macro_2_5_snd_controls;
num_controls = ARRAY_SIZE(rx_macro_2_5_snd_controls);
widgets = rx_macro_2_5_dapm_widgets;
@@ -3837,8 +3846,10 @@ static int rx_macro_probe(struct platform_device *pdev)
case LPASS_CODEC_VERSION_2_6:
case LPASS_CODEC_VERSION_2_7:
case LPASS_CODEC_VERSION_2_8:
+ case LPASS_CODEC_VERSION_4_1:
rx->rxn_reg_stride = 0xc0;
rx->rxn_reg_stride2 = 0x0;
+ rx->fs_cnt_bypass = (rx->codec_version == LPASS_CODEC_VERSION_4_1);
def_count = ARRAY_SIZE(rx_defaults) + ARRAY_SIZE(rx_2_5_defaults);
reg_defaults = kmalloc_objs(struct reg_default, def_count);
if (!reg_defaults)
@@ -3951,6 +3962,9 @@ static const struct of_device_id rx_macro_dt_match[] = {
}, {
.compatible = "qcom,sc8280xp-lpass-rx-macro",
.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,
+ }, {
+ .compatible = "qcom,shikra-lpass-rx-macro",
+ .data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,
},
{ }
};
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v5 4/9] ASoC: qcom: lpass-va-macro: Add shikra compatible
2026-10-14 9:12 [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support Mohammad Rafi Shaik
` (2 preceding siblings ...)
2026-10-14 9:12 ` [PATCH v5 3/9] ASoC: qcom: lpass-rx-macro: Add shikra compatible Mohammad Rafi Shaik
@ 2026-10-14 9:12 ` Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 5/9] ASoC: qcom: lpass-va-macro: Add SoundWire microphone support Mohammad Rafi Shaik
` (4 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Mohammad Rafi Shaik @ 2026-10-14 9:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Mohammad Rafi Shaik, linux-arm-msm, linux-sound, devicetree,
linux-kernel
Add shikra specific VA macro data and register programming needed by
the LPASS codec v4.1 implementation.
LPASS codec v4.1 extends the VA macro with four adaptive filter (ADPT)
blocks at 0x0800..0x09a4 and requires the FS counter to be bypassed
before it is enabled.
Add the new registers as a separate reg_default array, used by a v4.1
specific regmap config.
The register layout has to be chosen before the regmap exists, i.e.
before CDC_VA_TOP_CSR_CORE_ID_* can be read, so it comes from match data;
probe then cross checks it against the version reported by the hardware.
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
sound/soc/codecs/lpass-va-macro.c | 284 +++++++++++++++++++++++++++++++++++++-
1 file changed, 277 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c
index 03d6434a4..53828dd80 100644
--- a/sound/soc/codecs/lpass-va-macro.c
+++ b/sound/soc/codecs/lpass-va-macro.c
@@ -26,6 +26,7 @@
#define CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL (0x0004)
#define CDC_VA_FS_CONTROL_EN BIT(0)
#define CDC_VA_FS_COUNTER_CLR BIT(1)
+#define CDC_VA_FS_CNT_BYPASS BIT(7)
#define CDC_VA_CLK_RST_CTRL_SWR_CONTROL (0x0008)
#define CDC_VA_SWR_RESET_MASK BIT(1)
#define CDC_VA_SWR_RESET_ENABLE BIT(1)
@@ -156,7 +157,54 @@
#define CDC_VA_TX3_TX_PATH_SEC5 (0x05A4)
#define CDC_VA_TX3_TX_PATH_SEC6 (0x05A8)
+/* LPASS codec v4.1 adaptive filter (ADPT) blocks */
+#define CDC_VA_CDC_ADPT0_ADPT_CTRL 0x0800
+#define CDC_VA_ADPT_CTRL_EN_MASK GENMASK(7, 0)
+#define CDC_VA_CDC_ADPT0_ADPT_GAIN_0 0x0804
+#define CDC_VA_CDC_ADPT0_ADPT_GAIN_1 0x0808
+#define CDC_VA_CDC_ADPT0_DH_FSM_CTRL 0x080c
+#define CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_0 0x0810
+#define CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_1 0x0814
+#define CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_2 0x0818
+#define CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_3 0x081c
+#define CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_4 0x0820
+#define CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_5 0x0824
+
+#define CDC_VA_CDC_ADPT1_ADPT_CTRL 0x0880
+#define CDC_VA_CDC_ADPT1_ADPT_GAIN_0 0x0884
+#define CDC_VA_CDC_ADPT1_ADPT_GAIN_1 0x0888
+#define CDC_VA_CDC_ADPT1_DH_FSM_CTRL 0x088c
+#define CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_0 0x0890
+#define CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_1 0x0894
+#define CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_2 0x0898
+#define CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_3 0x089c
+#define CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_4 0x08a0
+#define CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_5 0x08a4
+
+#define CDC_VA_CDC_ADPT2_ADPT_CTRL 0x0900
+#define CDC_VA_CDC_ADPT2_ADPT_GAIN_0 0x0904
+#define CDC_VA_CDC_ADPT2_ADPT_GAIN_1 0x0908
+#define CDC_VA_CDC_ADPT2_DH_FSM_CTRL 0x090c
+#define CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_0 0x0910
+#define CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_1 0x0914
+#define CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_2 0x0918
+#define CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_3 0x091c
+#define CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_4 0x0920
+#define CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_5 0x0924
+
+#define CDC_VA_CDC_ADPT3_ADPT_CTRL 0x0980
+#define CDC_VA_CDC_ADPT3_ADPT_GAIN_0 0x0984
+#define CDC_VA_CDC_ADPT3_ADPT_GAIN_1 0x0988
+#define CDC_VA_CDC_ADPT3_DH_FSM_CTRL 0x098c
+#define CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_0 0x0990
+#define CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_1 0x0994
+#define CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_2 0x0998
+#define CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_3 0x099c
+#define CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_4 0x09a0
+#define CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_5 0x09a4
+
#define VA_MAX_OFFSET (0x07A8)
+#define VA_4_1_MAX_OFFSET 0x09a4
#define VA_MACRO_NUM_DECIMATORS 4
#define VA_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
@@ -210,7 +258,8 @@ struct va_macro {
u16 dmic_clk_div;
bool has_swr_master;
bool has_npl_clk;
-
+ bool fs_cnt_bypass;
+ bool has_adpt;
int dec_mode[VA_MACRO_NUM_DECIMATORS];
struct regmap *regmap;
struct clk *mclk;
@@ -237,6 +286,7 @@ struct va_macro_data {
bool has_swr_master;
bool has_npl_clk;
int version;
+ const struct regmap_config *regmap_config;
};
static const struct va_macro_data sm8250_va_data = {
@@ -357,6 +407,127 @@ static const struct reg_default va_defaults[] = {
{ CDC_VA_TX3_TX_PATH_SEC6, 0x00},
};
+static const struct reg_default va_4_1_defaults[] = {
+ /* VA macro */
+ { CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
+ { CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
+ { CDC_VA_CLK_RST_CTRL_SWR_CONTROL, 0x00},
+ { CDC_VA_TOP_CSR_TOP_CFG0, 0x00},
+ { CDC_VA_TOP_CSR_DMIC0_CTL, 0x00},
+ { CDC_VA_TOP_CSR_DMIC1_CTL, 0x00},
+ { CDC_VA_TOP_CSR_DMIC2_CTL, 0x00},
+ { CDC_VA_TOP_CSR_DMIC3_CTL, 0x00},
+ { CDC_VA_TOP_CSR_DMIC_CFG, 0x80},
+ { CDC_VA_TOP_CSR_DEBUG_BUS, 0x00},
+ { CDC_VA_TOP_CSR_DEBUG_EN, 0x00},
+ { CDC_VA_TOP_CSR_TX_I2S_CTL, 0x0C},
+ { CDC_VA_TOP_CSR_I2S_CLK, 0x00},
+ { CDC_VA_TOP_CSR_I2S_RESET, 0x00},
+ { CDC_VA_TOP_CSR_CORE_ID_0, 0x00},
+ { CDC_VA_TOP_CSR_CORE_ID_1, 0x00},
+ { CDC_VA_TOP_CSR_CORE_ID_2, 0x00},
+ { CDC_VA_TOP_CSR_CORE_ID_3, 0x00},
+ { CDC_VA_TOP_CSR_SWR_MIC_CTL0, 0xEE},
+ { CDC_VA_TOP_CSR_SWR_MIC_CTL1, 0xEE},
+ { CDC_VA_TOP_CSR_SWR_MIC_CTL2, 0xEE},
+ { CDC_VA_TOP_CSR_SWR_CTRL, 0x06},
+ /* VA core */
+ { CDC_VA_INP_MUX_ADC_MUX0_CFG0, 0x00},
+ { CDC_VA_INP_MUX_ADC_MUX0_CFG1, 0x00},
+ { CDC_VA_INP_MUX_ADC_MUX1_CFG0, 0x00},
+ { CDC_VA_INP_MUX_ADC_MUX1_CFG1, 0x00},
+ { CDC_VA_INP_MUX_ADC_MUX2_CFG0, 0x00},
+ { CDC_VA_INP_MUX_ADC_MUX2_CFG1, 0x00},
+ { CDC_VA_INP_MUX_ADC_MUX3_CFG0, 0x00},
+ { CDC_VA_INP_MUX_ADC_MUX3_CFG1, 0x00},
+ { CDC_VA_TX0_TX_PATH_CTL, 0x04},
+ { CDC_VA_TX0_TX_PATH_CFG0, 0x10},
+ { CDC_VA_TX0_TX_PATH_CFG1, 0x0B},
+ { CDC_VA_TX0_TX_VOL_CTL, 0x00},
+ { CDC_VA_TX0_TX_PATH_SEC0, 0x00},
+ { CDC_VA_TX0_TX_PATH_SEC1, 0x00},
+ { CDC_VA_TX0_TX_PATH_SEC2, 0x01},
+ { CDC_VA_TX0_TX_PATH_SEC3, 0x3C},
+ { CDC_VA_TX0_TX_PATH_SEC4, 0x20},
+ { CDC_VA_TX0_TX_PATH_SEC5, 0x00},
+ { CDC_VA_TX0_TX_PATH_SEC6, 0x00},
+ { CDC_VA_TX0_TX_PATH_SEC7, 0x25},
+ { CDC_VA_TX1_TX_PATH_CTL, 0x04},
+ { CDC_VA_TX1_TX_PATH_CFG0, 0x10},
+ { CDC_VA_TX1_TX_PATH_CFG1, 0x0B},
+ { CDC_VA_TX1_TX_VOL_CTL, 0x00},
+ { CDC_VA_TX1_TX_PATH_SEC0, 0x00},
+ { CDC_VA_TX1_TX_PATH_SEC1, 0x00},
+ { CDC_VA_TX1_TX_PATH_SEC2, 0x01},
+ { CDC_VA_TX1_TX_PATH_SEC3, 0x3C},
+ { CDC_VA_TX1_TX_PATH_SEC4, 0x20},
+ { CDC_VA_TX1_TX_PATH_SEC5, 0x00},
+ { CDC_VA_TX1_TX_PATH_SEC6, 0x00},
+ { CDC_VA_TX2_TX_PATH_CTL, 0x04},
+ { CDC_VA_TX2_TX_PATH_CFG0, 0x10},
+ { CDC_VA_TX2_TX_PATH_CFG1, 0x0B},
+ { CDC_VA_TX2_TX_VOL_CTL, 0x00},
+ { CDC_VA_TX2_TX_PATH_SEC0, 0x00},
+ { CDC_VA_TX2_TX_PATH_SEC1, 0x00},
+ { CDC_VA_TX2_TX_PATH_SEC2, 0x01},
+ { CDC_VA_TX2_TX_PATH_SEC3, 0x3C},
+ { CDC_VA_TX2_TX_PATH_SEC4, 0x20},
+ { CDC_VA_TX2_TX_PATH_SEC5, 0x00},
+ { CDC_VA_TX2_TX_PATH_SEC6, 0x00},
+ { CDC_VA_TX3_TX_PATH_CTL, 0x04},
+ { CDC_VA_TX3_TX_PATH_CFG0, 0x10},
+ { CDC_VA_TX3_TX_PATH_CFG1, 0x0B},
+ { CDC_VA_TX3_TX_VOL_CTL, 0x00},
+ { CDC_VA_TX3_TX_PATH_SEC0, 0x00},
+ { CDC_VA_TX3_TX_PATH_SEC1, 0x00},
+ { CDC_VA_TX3_TX_PATH_SEC2, 0x01},
+ { CDC_VA_TX3_TX_PATH_SEC3, 0x3C},
+ { CDC_VA_TX3_TX_PATH_SEC4, 0x20},
+ { CDC_VA_TX3_TX_PATH_SEC5, 0x00},
+ { CDC_VA_TX3_TX_PATH_SEC6, 0x00},
+ /* ADPT blocks */
+ { CDC_VA_CDC_ADPT0_ADPT_CTRL, 0x51},
+ { CDC_VA_CDC_ADPT0_ADPT_GAIN_0, 0x11},
+ { CDC_VA_CDC_ADPT0_ADPT_GAIN_1, 0x01},
+ { CDC_VA_CDC_ADPT0_DH_FSM_CTRL, 0x02},
+ { CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_0, 0x77},
+ { CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_1, 0x64},
+ { CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_2, 0x00},
+ { CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_3, 0x41},
+ { CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_4, 0x04},
+ { CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_5, 0x01},
+ { CDC_VA_CDC_ADPT1_ADPT_CTRL, 0x51},
+ { CDC_VA_CDC_ADPT1_ADPT_GAIN_0, 0x11},
+ { CDC_VA_CDC_ADPT1_ADPT_GAIN_1, 0x01},
+ { CDC_VA_CDC_ADPT1_DH_FSM_CTRL, 0x02},
+ { CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_0, 0x77},
+ { CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_1, 0x64},
+ { CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_2, 0x00},
+ { CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_3, 0x41},
+ { CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_4, 0x04},
+ { CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_5, 0x01},
+ { CDC_VA_CDC_ADPT2_ADPT_CTRL, 0x51},
+ { CDC_VA_CDC_ADPT2_ADPT_GAIN_0, 0x11},
+ { CDC_VA_CDC_ADPT2_ADPT_GAIN_1, 0x01},
+ { CDC_VA_CDC_ADPT2_DH_FSM_CTRL, 0x02},
+ { CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_0, 0x77},
+ { CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_1, 0x64},
+ { CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_2, 0x00},
+ { CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_3, 0x41},
+ { CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_4, 0x04},
+ { CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_5, 0x01},
+ { CDC_VA_CDC_ADPT3_ADPT_CTRL, 0x51},
+ { CDC_VA_CDC_ADPT3_ADPT_GAIN_0, 0x11},
+ { CDC_VA_CDC_ADPT3_ADPT_GAIN_1, 0x01},
+ { CDC_VA_CDC_ADPT3_DH_FSM_CTRL, 0x02},
+ { CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_0, 0x77},
+ { CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_1, 0x64},
+ { CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_2, 0x00},
+ { CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_3, 0x41},
+ { CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_4, 0x04},
+ { CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_5, 0x01},
+};
+
static bool va_is_rw_register(struct device *dev, unsigned int reg)
{
switch (reg) {
@@ -430,6 +601,46 @@ static bool va_is_rw_register(struct device *dev, unsigned int reg)
case CDC_VA_TX3_TX_PATH_SEC4:
case CDC_VA_TX3_TX_PATH_SEC5:
case CDC_VA_TX3_TX_PATH_SEC6:
+ case CDC_VA_CDC_ADPT0_ADPT_CTRL:
+ case CDC_VA_CDC_ADPT0_ADPT_GAIN_0:
+ case CDC_VA_CDC_ADPT0_ADPT_GAIN_1:
+ case CDC_VA_CDC_ADPT0_DH_FSM_CTRL:
+ case CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_0:
+ case CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_1:
+ case CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_2:
+ case CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_3:
+ case CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_4:
+ case CDC_VA_CDC_ADPT0_CUTOFF_FSM_CTRL_5:
+ case CDC_VA_CDC_ADPT1_ADPT_CTRL:
+ case CDC_VA_CDC_ADPT1_ADPT_GAIN_0:
+ case CDC_VA_CDC_ADPT1_ADPT_GAIN_1:
+ case CDC_VA_CDC_ADPT1_DH_FSM_CTRL:
+ case CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_0:
+ case CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_1:
+ case CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_2:
+ case CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_3:
+ case CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_4:
+ case CDC_VA_CDC_ADPT1_CUTOFF_FSM_CTRL_5:
+ case CDC_VA_CDC_ADPT2_ADPT_CTRL:
+ case CDC_VA_CDC_ADPT2_ADPT_GAIN_0:
+ case CDC_VA_CDC_ADPT2_ADPT_GAIN_1:
+ case CDC_VA_CDC_ADPT2_DH_FSM_CTRL:
+ case CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_0:
+ case CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_1:
+ case CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_2:
+ case CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_3:
+ case CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_4:
+ case CDC_VA_CDC_ADPT2_CUTOFF_FSM_CTRL_5:
+ case CDC_VA_CDC_ADPT3_ADPT_CTRL:
+ case CDC_VA_CDC_ADPT3_ADPT_GAIN_0:
+ case CDC_VA_CDC_ADPT3_ADPT_GAIN_1:
+ case CDC_VA_CDC_ADPT3_DH_FSM_CTRL:
+ case CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_0:
+ case CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_1:
+ case CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_2:
+ case CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_3:
+ case CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_4:
+ case CDC_VA_CDC_ADPT3_CUTOFF_FSM_CTRL_5:
return true;
}
@@ -463,6 +674,26 @@ static const struct regmap_config va_regmap_config = {
.writeable_reg = va_is_rw_register,
};
+static const struct regmap_config va_4_1_regmap_config = {
+ .name = "va_macro",
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .cache_type = REGCACHE_MAPLE,
+ .reg_defaults = va_4_1_defaults,
+ .num_reg_defaults = ARRAY_SIZE(va_4_1_defaults),
+ .max_register = VA_4_1_MAX_OFFSET,
+ .volatile_reg = va_is_volatile_register,
+ .readable_reg = va_is_readable_register,
+ .writeable_reg = va_is_rw_register,
+};
+
+static const struct va_macro_data shikra_va_data = {
+ .has_swr_master = true,
+ .has_npl_clk = true,
+ .regmap_config = &va_4_1_regmap_config,
+};
+
static int va_clk_rsc_fs_gen_request(struct va_macro *va, bool enable)
{
struct regmap *regmap = va->regmap;
@@ -471,10 +702,14 @@ static int va_clk_rsc_fs_gen_request(struct va_macro *va, bool enable)
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_MCLK_CONTROL,
CDC_VA_MCLK_CONTROL_EN,
CDC_VA_MCLK_CONTROL_EN);
- /* clear the fs counter */
+
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL,
CDC_VA_FS_CONTROL_EN | CDC_VA_FS_COUNTER_CLR,
CDC_VA_FS_CONTROL_EN | CDC_VA_FS_COUNTER_CLR);
+
+ if (va->fs_cnt_bypass)
+ regmap_set_bits(regmap, CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL,
+ CDC_VA_FS_CNT_BYPASS);
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL,
CDC_VA_FS_CONTROL_EN | CDC_VA_FS_COUNTER_CLR,
CDC_VA_FS_CONTROL_EN);
@@ -503,7 +738,7 @@ static int va_macro_mclk_enable(struct va_macro *va, bool mclk_enable)
if (mclk_enable) {
va_clk_rsc_fs_gen_request(va, true);
regcache_mark_dirty(regmap);
- regcache_sync_region(regmap, 0x0, VA_MAX_OFFSET);
+ regcache_sync_region(regmap, 0x0, regmap_get_max_register(regmap));
} else {
va_clk_rsc_fs_gen_request(va, false);
}
@@ -749,6 +984,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w,
unsigned int decimator;
u16 tx_vol_ctl_reg, dec_cfg_reg, hpf_gate_reg;
u16 tx_gain_ctl_reg;
+ u16 adpt_ctrl_reg;
u8 hpf_cut_off_freq;
struct va_macro *va = snd_soc_component_get_drvdata(comp);
@@ -763,6 +999,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w,
VA_MACRO_TX_PATH_OFFSET * decimator;
tx_gain_ctl_reg = CDC_VA_TX0_TX_VOL_CTL +
VA_MACRO_TX_PATH_OFFSET * decimator;
+ adpt_ctrl_reg = CDC_VA_CDC_ADPT0_ADPT_CTRL + decimator * VA_MACRO_TX_PATH_OFFSET;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -772,6 +1009,10 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w,
/* Enable TX PGA Mute */
break;
case SND_SOC_DAPM_POST_PMU:
+ if (va->has_adpt)
+ snd_soc_component_update_bits(comp, adpt_ctrl_reg,
+ CDC_VA_ADPT_CTRL_EN_MASK, 0x00);
+
/* Enable TX CLK */
snd_soc_component_update_bits(comp, tx_vol_ctl_reg,
CDC_VA_TX_PATH_CLK_EN_MASK,
@@ -1526,6 +1767,14 @@ static int va_macro_set_lpass_codec_version(struct va_macro *va)
default:
break;
}
+ } else if (maj == 4) {
+ switch (min) {
+ case 1:
+ version = LPASS_CODEC_VERSION_4_1;
+ break;
+ default:
+ break;
+ }
}
if (version == LPASS_CODEC_VERSION_UNKNOWN) {
@@ -1547,6 +1796,7 @@ static int va_macro_probe(struct platform_device *pdev)
const struct va_macro_data *data;
struct va_macro *va;
void __iomem *base;
+ bool has_adpt_layout;
u32 sample_rate = 0;
int ret;
int rpm_ret;
@@ -1556,6 +1806,7 @@ static int va_macro_probe(struct platform_device *pdev)
return -ENOMEM;
va->dev = dev;
+ data = of_device_get_match_data(dev);
va->macro = devm_clk_get_optional(dev, "macro");
if (IS_ERR(va->macro))
@@ -1592,15 +1843,15 @@ static int va_macro_probe(struct platform_device *pdev)
goto err;
}
- va->regmap = devm_regmap_init_mmio(dev, base, &va_regmap_config);
+ dev_set_drvdata(dev, va);
+
+ va->regmap = devm_regmap_init_mmio(dev, base,
+ data->regmap_config ?: &va_regmap_config);
if (IS_ERR(va->regmap)) {
ret = -EINVAL;
goto err;
}
- dev_set_drvdata(dev, va);
-
- data = of_device_get_match_data(dev);
va->has_swr_master = data->has_swr_master;
va->has_npl_clk = data->has_npl_clk;
@@ -1654,6 +1905,24 @@ static int va_macro_probe(struct platform_device *pdev)
goto err_rpm_put;
}
+ va->fs_cnt_bypass = (lpass_macro_get_codec_version() == LPASS_CODEC_VERSION_4_1);
+ va->has_adpt = (lpass_macro_get_codec_version() == LPASS_CODEC_VERSION_4_1);
+
+ /*
+ * The register layout comes from match data, as it has to be picked
+ * before CDC_VA_TOP_CSR_CORE_ID_* can be read. Now that the codec
+ * version is known, make sure the two agree, so that the ADPT blocks
+ * are neither programmed outside the register window nor programmed
+ * on a codec that does not implement them.
+ */
+ has_adpt_layout = data->regmap_config == &va_4_1_regmap_config;
+ if (va->has_adpt != has_adpt_layout) {
+ dev_err(dev, "LPASS codec %s does not match the compatible\n",
+ lpass_macro_get_codec_version_string(lpass_macro_get_codec_version()));
+ ret = -EINVAL;
+ goto err_rpm_put;
+ }
+
if (va->has_swr_master) {
/* Set default CLK div to 1 */
regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL0,
@@ -1775,6 +2044,7 @@ static const struct of_device_id va_macro_dt_match[] = {
{ .compatible = "qcom,sm8450-lpass-va-macro", .data = &sm8450_va_data },
{ .compatible = "qcom,sm8550-lpass-va-macro", .data = &sm8550_va_data },
{ .compatible = "qcom,sc8280xp-lpass-va-macro", .data = &sm8450_va_data },
+ { .compatible = "qcom,shikra-lpass-va-macro", .data = &shikra_va_data },
{}
};
MODULE_DEVICE_TABLE(of, va_macro_dt_match);
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v5 5/9] ASoC: qcom: lpass-va-macro: Add SoundWire microphone support
2026-10-14 9:12 [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support Mohammad Rafi Shaik
` (3 preceding siblings ...)
2026-10-14 9:12 ` [PATCH v5 4/9] ASoC: qcom: lpass-va-macro: " Mohammad Rafi Shaik
@ 2026-10-14 9:12 ` Mohammad Rafi Shaik
2026-10-14 9:30 ` sashiko-bot
2026-10-14 9:12 ` [PATCH v5 6/9] ASoC: dt-bindings: qcom: Add Hawi LPASS macro codecs Mohammad Rafi Shaik
` (3 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Mohammad Rafi Shaik @ 2026-10-14 9:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Mohammad Rafi Shaik, linux-arm-msm, linux-sound, devicetree,
linux-kernel
The VA decimators can currently capture audio only from DMIC inputs.
Add support for routing audio from SoundWire microphone (SMIC) inputs
as well.
Update the decimator source selection logic to switch between DMIC and
SMIC sources based on the active input path.
The ADC_DMIC_SEL bit of CDC_VA_TXn_TX_PATH_CFG0 is shared by the DMIC and
the SoundWire mic mux, so a mixer write to the mux that is not part of the
active path can leave it stale. Program it from the resolved mux state
when the decimator is enabled, so capture does not depend on the order in
which userspace restores the two controls.
Add a helper to detect whether a decimator is using a SoundWire microphone
input. Use this information to skip DMIC-specific HPF programming sequences
when the decimator is configured for an SMIC source.
This enables VA decimators to capture audio from either DMIC or SoundWire
microphone inputs.
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
sound/soc/codecs/lpass-va-macro.c | 154 ++++++++++++++++++++++++++++++++++++--
1 file changed, 147 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c
index 53828dd80..cdef2b187 100644
--- a/sound/soc/codecs/lpass-va-macro.c
+++ b/sound/soc/codecs/lpass-va-macro.c
@@ -762,6 +762,16 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
return 0;
}
+static bool is_amic_enabled(struct snd_soc_component *comp, int decimator)
+{
+ u16 adc_mux_reg;
+
+ adc_mux_reg = CDC_VA_INP_MUX_ADC_MUX0_CFG1 +
+ VA_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+
+ return snd_soc_component_read(comp, adc_mux_reg) & BIT(0);
+}
+
static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -771,20 +781,26 @@ static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val;
u16 mic_sel_reg;
+ int decimator;
+ bool smic_mux;
val = ucontrol->value.enumerated.item[0];
switch (e->reg) {
case CDC_VA_INP_MUX_ADC_MUX0_CFG0:
+ decimator = 0;
mic_sel_reg = CDC_VA_TX0_TX_PATH_CFG0;
break;
case CDC_VA_INP_MUX_ADC_MUX1_CFG0:
+ decimator = 1;
mic_sel_reg = CDC_VA_TX1_TX_PATH_CFG0;
break;
case CDC_VA_INP_MUX_ADC_MUX2_CFG0:
+ decimator = 2;
mic_sel_reg = CDC_VA_TX2_TX_PATH_CFG0;
break;
case CDC_VA_INP_MUX_ADC_MUX3_CFG0:
+ decimator = 3;
mic_sel_reg = CDC_VA_TX3_TX_PATH_CFG0;
break;
default:
@@ -793,10 +809,24 @@ static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
return -EINVAL;
}
- if (val != 0)
+ /*
+ * SMIC enums use shift 0 (lower nibble of CFG0), DMIC enums use
+ * shift 4 (upper nibble of CFG0). Use e->shift_l to distinguish them
+ * without relying on widget name comparisons.
+ */
+ smic_mux = (e->shift_l == 0);
+
+ /*
+ * Both muxes feed the same decimator and share ADC_DMIC_SEL, so only
+ * the one the decimator is routed through may program it. A write to
+ * the mux that is not part of the active path would otherwise switch
+ * the input domain of a running capture.
+ */
+ if (val != 0 && smic_mux == is_amic_enabled(component, decimator))
snd_soc_component_update_bits(component, mic_sel_reg,
CDC_VA_TX_PATH_ADC_DMIC_SEL_MASK,
- CDC_VA_TX_PATH_ADC_DMIC_SEL_DMIC);
+ smic_mux ? CDC_VA_TX_PATH_ADC_DMIC_SEL_ADC :
+ CDC_VA_TX_PATH_ADC_DMIC_SEL_DMIC);
return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
}
@@ -986,7 +1016,6 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w,
u16 tx_gain_ctl_reg;
u16 adpt_ctrl_reg;
u8 hpf_cut_off_freq;
-
struct va_macro *va = snd_soc_component_get_drvdata(comp);
decimator = w->shift;
@@ -1003,6 +1032,18 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ /*
+ * ADC_DMIC_SEL is shared by the DMIC and the SoundWire mic
+ * mux, so its value depends on the order in which userspace
+ * restores the two controls. Program it from the resolved
+ * mux state of this decimator, which is what selects the
+ * input domain.
+ */
+ snd_soc_component_update_bits(comp, dec_cfg_reg,
+ CDC_VA_TX_PATH_ADC_DMIC_SEL_MASK,
+ is_amic_enabled(comp, decimator) ?
+ CDC_VA_TX_PATH_ADC_DMIC_SEL_ADC :
+ CDC_VA_TX_PATH_ADC_DMIC_SEL_DMIC);
snd_soc_component_update_bits(comp,
dec_cfg_reg, CDC_VA_ADC_MODE_MASK,
va->dec_mode[decimator] << CDC_VA_ADC_MODE_SHIFT);
@@ -1017,9 +1058,15 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(comp, tx_vol_ctl_reg,
CDC_VA_TX_PATH_CLK_EN_MASK,
CDC_VA_TX_PATH_CLK_EN);
- snd_soc_component_update_bits(comp, hpf_gate_reg,
- CDC_VA_TX_HPF_ZERO_GATE_MASK,
- CDC_VA_TX_HPF_ZERO_GATE);
+ /*
+ * Only the HPF zero gate assertion is specific to the DMIC
+ * path; the cutoff programming and the gate release below
+ * apply to both input domains.
+ */
+ if (!is_amic_enabled(comp, decimator))
+ snd_soc_component_update_bits(comp, hpf_gate_reg,
+ CDC_VA_TX_HPF_ZERO_GATE_MASK,
+ CDC_VA_TX_HPF_ZERO_GATE);
usleep_range(1000, 1010);
hpf_cut_off_freq = (snd_soc_component_read(comp, dec_cfg_reg) &
@@ -1045,7 +1092,6 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w,
0x0);
}
-
usleep_range(1000, 1010);
snd_soc_component_update_bits(comp, hpf_gate_reg,
CDC_VA_TX_HPF_ZERO_GATE_MASK,
@@ -1245,6 +1291,39 @@ static const char * const adc_mux_text[] = {
"VA_DMIC", "SWR_MIC"
};
+static const char * const smic_mux_text[] = {
+ "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "SWR_MIC0", "SWR_MIC1",
+ "SWR_MIC2", "SWR_MIC3", "SWR_MIC4", "SWR_MIC5", "SWR_MIC6", "SWR_MIC7"
+};
+
+static SOC_ENUM_SINGLE_DECL(va_smic0_enum, CDC_VA_INP_MUX_ADC_MUX0_CFG0,
+ 0, smic_mux_text);
+
+static SOC_ENUM_SINGLE_DECL(va_smic1_enum, CDC_VA_INP_MUX_ADC_MUX1_CFG0,
+ 0, smic_mux_text);
+
+static SOC_ENUM_SINGLE_DECL(va_smic2_enum, CDC_VA_INP_MUX_ADC_MUX2_CFG0,
+ 0, smic_mux_text);
+
+static SOC_ENUM_SINGLE_DECL(va_smic3_enum, CDC_VA_INP_MUX_ADC_MUX3_CFG0,
+ 0, smic_mux_text);
+
+static const struct snd_kcontrol_new va_smic0_mux = SOC_DAPM_ENUM_EXT("va_smic0",
+ va_smic0_enum, snd_soc_dapm_get_enum_double,
+ va_macro_put_dec_enum);
+
+static const struct snd_kcontrol_new va_smic1_mux = SOC_DAPM_ENUM_EXT("va_smic1",
+ va_smic1_enum, snd_soc_dapm_get_enum_double,
+ va_macro_put_dec_enum);
+
+static const struct snd_kcontrol_new va_smic2_mux = SOC_DAPM_ENUM_EXT("va_smic2",
+ va_smic2_enum, snd_soc_dapm_get_enum_double,
+ va_macro_put_dec_enum);
+
+static const struct snd_kcontrol_new va_smic3_mux = SOC_DAPM_ENUM_EXT("va_smic3",
+ va_smic3_enum, snd_soc_dapm_get_enum_double,
+ va_macro_put_dec_enum);
+
static SOC_ENUM_SINGLE_DECL(va_dec0_enum, CDC_VA_INP_MUX_ADC_MUX0_CFG1,
0, adc_mux_text);
static SOC_ENUM_SINGLE_DECL(va_dec1_enum, CDC_VA_INP_MUX_ADC_MUX1_CFG1,
@@ -1380,6 +1459,11 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = {
SND_SOC_DAPM_MUX("VA DMIC MUX2", SND_SOC_NOPM, 0, 0, &va_dmic2_mux),
SND_SOC_DAPM_MUX("VA DMIC MUX3", SND_SOC_NOPM, 0, 0, &va_dmic3_mux),
+ SND_SOC_DAPM_MUX("VA SMIC MUX0", SND_SOC_NOPM, 0, 0, &va_smic0_mux),
+ SND_SOC_DAPM_MUX("VA SMIC MUX1", SND_SOC_NOPM, 0, 0, &va_smic1_mux),
+ SND_SOC_DAPM_MUX("VA SMIC MUX2", SND_SOC_NOPM, 0, 0, &va_smic2_mux),
+ SND_SOC_DAPM_MUX("VA SMIC MUX3", SND_SOC_NOPM, 0, 0, &va_smic3_mux),
+
SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-micb", 0, 0),
SND_SOC_DAPM_INPUT("DMIC0 Pin"),
SND_SOC_DAPM_INPUT("DMIC1 Pin"),
@@ -1524,6 +1608,62 @@ static const struct snd_soc_dapm_route va_audio_map[] = {
{"VA DMIC MUX3", "DMIC6", "VA DMIC6"},
{"VA DMIC MUX3", "DMIC7", "VA DMIC7"},
+ {"VA DEC0 MUX", "SWR_MIC", "VA SMIC MUX0"},
+ {"VA SMIC MUX0", "ADC0", "VA SWR_ADC0"},
+ {"VA SMIC MUX0", "ADC1", "VA SWR_ADC1"},
+ {"VA SMIC MUX0", "ADC2", "VA SWR_ADC2"},
+ {"VA SMIC MUX0", "ADC3", "VA SWR_ADC3"},
+ {"VA SMIC MUX0", "SWR_MIC0", "VA SWR_MIC0"},
+ {"VA SMIC MUX0", "SWR_MIC1", "VA SWR_MIC1"},
+ {"VA SMIC MUX0", "SWR_MIC2", "VA SWR_MIC2"},
+ {"VA SMIC MUX0", "SWR_MIC3", "VA SWR_MIC3"},
+ {"VA SMIC MUX0", "SWR_MIC4", "VA SWR_MIC4"},
+ {"VA SMIC MUX0", "SWR_MIC5", "VA SWR_MIC5"},
+ {"VA SMIC MUX0", "SWR_MIC6", "VA SWR_MIC6"},
+ {"VA SMIC MUX0", "SWR_MIC7", "VA SWR_MIC7"},
+
+ {"VA DEC1 MUX", "SWR_MIC", "VA SMIC MUX1"},
+ {"VA SMIC MUX1", "ADC0", "VA SWR_ADC0"},
+ {"VA SMIC MUX1", "ADC1", "VA SWR_ADC1"},
+ {"VA SMIC MUX1", "ADC2", "VA SWR_ADC2"},
+ {"VA SMIC MUX1", "ADC3", "VA SWR_ADC3"},
+ {"VA SMIC MUX1", "SWR_MIC0", "VA SWR_MIC0"},
+ {"VA SMIC MUX1", "SWR_MIC1", "VA SWR_MIC1"},
+ {"VA SMIC MUX1", "SWR_MIC2", "VA SWR_MIC2"},
+ {"VA SMIC MUX1", "SWR_MIC3", "VA SWR_MIC3"},
+ {"VA SMIC MUX1", "SWR_MIC4", "VA SWR_MIC4"},
+ {"VA SMIC MUX1", "SWR_MIC5", "VA SWR_MIC5"},
+ {"VA SMIC MUX1", "SWR_MIC6", "VA SWR_MIC6"},
+ {"VA SMIC MUX1", "SWR_MIC7", "VA SWR_MIC7"},
+
+ {"VA DEC2 MUX", "SWR_MIC", "VA SMIC MUX2"},
+ {"VA SMIC MUX2", "ADC0", "VA SWR_ADC0"},
+ {"VA SMIC MUX2", "ADC1", "VA SWR_ADC1"},
+ {"VA SMIC MUX2", "ADC2", "VA SWR_ADC2"},
+ {"VA SMIC MUX2", "ADC3", "VA SWR_ADC3"},
+ {"VA SMIC MUX2", "SWR_MIC0", "VA SWR_MIC0"},
+ {"VA SMIC MUX2", "SWR_MIC1", "VA SWR_MIC1"},
+ {"VA SMIC MUX2", "SWR_MIC2", "VA SWR_MIC2"},
+ {"VA SMIC MUX2", "SWR_MIC3", "VA SWR_MIC3"},
+ {"VA SMIC MUX2", "SWR_MIC4", "VA SWR_MIC4"},
+ {"VA SMIC MUX2", "SWR_MIC5", "VA SWR_MIC5"},
+ {"VA SMIC MUX2", "SWR_MIC6", "VA SWR_MIC6"},
+ {"VA SMIC MUX2", "SWR_MIC7", "VA SWR_MIC7"},
+
+ {"VA DEC3 MUX", "SWR_MIC", "VA SMIC MUX3"},
+ {"VA SMIC MUX3", "ADC0", "VA SWR_ADC0"},
+ {"VA SMIC MUX3", "ADC1", "VA SWR_ADC1"},
+ {"VA SMIC MUX3", "ADC2", "VA SWR_ADC2"},
+ {"VA SMIC MUX3", "ADC3", "VA SWR_ADC3"},
+ {"VA SMIC MUX3", "SWR_MIC0", "VA SWR_MIC0"},
+ {"VA SMIC MUX3", "SWR_MIC1", "VA SWR_MIC1"},
+ {"VA SMIC MUX3", "SWR_MIC2", "VA SWR_MIC2"},
+ {"VA SMIC MUX3", "SWR_MIC3", "VA SWR_MIC3"},
+ {"VA SMIC MUX3", "SWR_MIC4", "VA SWR_MIC4"},
+ {"VA SMIC MUX3", "SWR_MIC5", "VA SWR_MIC5"},
+ {"VA SMIC MUX3", "SWR_MIC6", "VA SWR_MIC6"},
+ {"VA SMIC MUX3", "SWR_MIC7", "VA SWR_MIC7"},
+
{ "VA DMIC0", NULL, "DMIC0 Pin" },
{ "VA DMIC1", NULL, "DMIC1 Pin" },
{ "VA DMIC2", NULL, "DMIC2 Pin" },
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v5 6/9] ASoC: dt-bindings: qcom: Add Hawi LPASS macro codecs
2026-10-14 9:12 [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support Mohammad Rafi Shaik
` (4 preceding siblings ...)
2026-10-14 9:12 ` [PATCH v5 5/9] ASoC: qcom: lpass-va-macro: Add SoundWire microphone support Mohammad Rafi Shaik
@ 2026-10-14 9:12 ` Mohammad Rafi Shaik
2026-10-14 9:35 ` sashiko-bot
2026-10-14 9:12 ` [PATCH v5 7/9] ASoC: dt-bindings: qcom: Add Maili " Mohammad Rafi Shaik
` (2 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Mohammad Rafi Shaik @ 2026-10-14 9:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Mohammad Rafi Shaik, linux-arm-msm, linux-sound, devicetree,
linux-kernel, Prasad Kumpatla
From: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
Document compatibles for the RX, TX and VA macro codecs found in the
Low Power Audio SubSystem (LPASS) of the Qualcomm Hawi SoC.
All three macros differ from SM8550, so describe them as standalone
compatibles with their own clock constraints rather than as SM8550
fallbacks: the RX macro uses the 'lpr' clock instead of the 'macro'
clock, the TX macro is based on Bolero v4.0, and the VA macro takes an
additional "heartbeatpulse" clock sourced from the LPASS VA CSR rate
generator.
Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
.../bindings/sound/qcom,lpass-rx-macro.yaml | 19 +++++++++++++++++++
.../bindings/sound/qcom,lpass-tx-macro.yaml | 19 +++++++++++++++++++
.../bindings/sound/qcom,lpass-va-macro.yaml | 19 +++++++++++++++++++
3 files changed, 57 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
index db63a75f1..142955b85 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
@@ -13,6 +13,7 @@ properties:
compatible:
oneOf:
- enum:
+ - qcom,hawi-lpass-rx-macro
- qcom,sc7280-lpass-rx-macro
- qcom,shikra-lpass-rx-macro
- qcom,sm6115-lpass-rx-macro
@@ -139,6 +140,24 @@ allOf:
- const: dcodec
- const: fsgen
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,hawi-lpass-rx-macro
+ then:
+ properties:
+ clocks:
+ minItems: 4
+ maxItems: 4
+ clock-names:
+ items:
+ - const: mclk
+ - const: lpr
+ - const: dcodec
+ - const: fsgen
+
- if:
properties:
compatible:
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
index d8682ff2e..2df72450d 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
@@ -13,6 +13,7 @@ properties:
compatible:
oneOf:
- enum:
+ - qcom,hawi-lpass-tx-macro
- qcom,sc7280-lpass-tx-macro
- qcom,sm6115-lpass-tx-macro
- qcom,sm8250-lpass-tx-macro
@@ -142,6 +143,24 @@ allOf:
- const: dcodec
- const: fsgen
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,hawi-lpass-tx-macro
+ then:
+ properties:
+ clocks:
+ minItems: 4
+ maxItems: 4
+ clock-names:
+ items:
+ - const: mclk
+ - const: lpr
+ - const: dcodec
+ - const: fsgen
+
unevaluatedProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
index 683ebf702..7d56f9c36 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
@@ -13,6 +13,7 @@ properties:
compatible:
oneOf:
- enum:
+ - qcom,hawi-lpass-va-macro
- qcom,sc7280-lpass-va-macro
- qcom,shikra-lpass-va-macro
- qcom,sm6115-lpass-va-macro
@@ -185,6 +186,24 @@ allOf:
- const: mclk
- const: npl
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,hawi-lpass-va-macro
+ then:
+ properties:
+ clocks:
+ minItems: 4
+ maxItems: 4
+ clock-names:
+ items:
+ - const: mclk
+ - const: lpr
+ - const: dcodec
+ - const: heartbeatpulse
+
unevaluatedProperties: false
examples:
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v5 7/9] ASoC: dt-bindings: qcom: Add Maili LPASS macro codecs
2026-10-14 9:12 [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support Mohammad Rafi Shaik
` (5 preceding siblings ...)
2026-10-14 9:12 ` [PATCH v5 6/9] ASoC: dt-bindings: qcom: Add Hawi LPASS macro codecs Mohammad Rafi Shaik
@ 2026-10-14 9:12 ` Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 8/9] ASoC: qcom: lpass-tx-macro: Add support for Bolero v4.0 Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 9/9] ASoC: qcom: lpass: Add support for LPASS codec v4.0 Mohammad Rafi Shaik
8 siblings, 0 replies; 14+ messages in thread
From: Mohammad Rafi Shaik @ 2026-10-14 9:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Mohammad Rafi Shaik, linux-arm-msm, linux-sound, devicetree,
linux-kernel, Prasad Kumpatla
From: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
Add compatibles for the RX, TX and VA macro codecs found in the Low
Power Audio SubSystem (LPASS) of the Qualcomm Maili SoC.
The Maili RX, TX and VA macros are identical to their Hawi counterparts,
so document them with the corresponding Hawi compatible as fallback.
Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml | 4 ++++
Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml | 4 ++++
Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml | 4 ++++
3 files changed, 12 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
index 142955b85..41b578f83 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
@@ -29,6 +29,10 @@ properties:
- qcom,sm8750-lpass-rx-macro
- qcom,x1e80100-lpass-rx-macro
- const: qcom,sm8550-lpass-rx-macro
+ - items:
+ - enum:
+ - qcom,maili-lpass-rx-macro
+ - const: qcom,hawi-lpass-rx-macro
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
index 2df72450d..900ed97dc 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
@@ -28,6 +28,10 @@ properties:
- qcom,sm8750-lpass-tx-macro
- qcom,x1e80100-lpass-tx-macro
- const: qcom,sm8550-lpass-tx-macro
+ - items:
+ - enum:
+ - qcom,maili-lpass-tx-macro
+ - const: qcom,hawi-lpass-tx-macro
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
index 7d56f9c36..9b8d9afd0 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
@@ -30,6 +30,10 @@ properties:
- qcom,sm8750-lpass-va-macro
- qcom,x1e80100-lpass-va-macro
- const: qcom,sm8550-lpass-va-macro
+ - items:
+ - enum:
+ - qcom,maili-lpass-va-macro
+ - const: qcom,hawi-lpass-va-macro
reg:
maxItems: 1
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v5 8/9] ASoC: qcom: lpass-tx-macro: Add support for Bolero v4.0
2026-10-14 9:12 [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support Mohammad Rafi Shaik
` (6 preceding siblings ...)
2026-10-14 9:12 ` [PATCH v5 7/9] ASoC: dt-bindings: qcom: Add Maili " Mohammad Rafi Shaik
@ 2026-10-14 9:12 ` Mohammad Rafi Shaik
2026-10-14 9:35 ` sashiko-bot
2026-10-14 9:12 ` [PATCH v5 9/9] ASoC: qcom: lpass: Add support for LPASS codec v4.0 Mohammad Rafi Shaik
8 siblings, 1 reply; 14+ messages in thread
From: Mohammad Rafi Shaik @ 2026-10-14 9:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Mohammad Rafi Shaik, linux-arm-msm, linux-sound, devicetree,
linux-kernel, Prasad Kumpatla, Sarath Ganapathiraju
From: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
Hawi integrates the Bolero v4.0 TX macro. This version extends the
existing TX macro register layout with CFG2 port-select registers,
per-path CFG2 registers and an ADPT control block.
Add the v4.0 register defaults and extend the regmap accessors and
maximum register offset only for the v4.0 match data. Use REGCACHE_MAPLE
for the TX macro regmap since the register defaults are sparse and the
v4.0 layout extends the register range.
Bolero v4.0 also needs a different decimator mux enum. Move the common
TX DEC widgets out of the shared widget table and register exactly one
decimator widget table per version. This avoids duplicate TX DECn MUX
DAPM widgets while keeping the v4.0-specific enum and DAPM events.
Add the v4.0 SMIC, WSA and port-select mux widgets and routes, and
disable the ADPT block before enabling a decimator on v4.0 hardware.
Co-developed-by: Sarath Ganapathiraju <sarath.ganapathiraju@oss.qualcomm.com>
Signed-off-by: Sarath Ganapathiraju <sarath.ganapathiraju@oss.qualcomm.com>
Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
sound/soc/codecs/lpass-macro-common.h | 1 +
sound/soc/codecs/lpass-tx-macro.c | 576 +++++++++++++++++++++++++++++++++-
2 files changed, 565 insertions(+), 12 deletions(-)
diff --git a/sound/soc/codecs/lpass-macro-common.h b/sound/soc/codecs/lpass-macro-common.h
index b52665b11..707b22a6b 100644
--- a/sound/soc/codecs/lpass-macro-common.h
+++ b/sound/soc/codecs/lpass-macro-common.h
@@ -16,6 +16,7 @@ enum lpass_version {
LPASS_VER_9_2_0,
LPASS_VER_10_0_0,
LPASS_VER_11_0_0,
+ LPASS_VER_15_0_0,
};
enum lpass_codec_version {
diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c
index 6deaaabe4..6480a6c90 100644
--- a/sound/soc/codecs/lpass-tx-macro.c
+++ b/sound/soc/codecs/lpass-tx-macro.c
@@ -4,6 +4,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/clk.h>
+#include <linux/cleanup.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/pm_clock.h>
@@ -67,6 +68,14 @@
#define CDC_TX_INP_MUX_ADC_MUX6_CFG1 (0x0134)
#define CDC_TX_INP_MUX_ADC_MUX7_CFG0 (0x0138)
#define CDC_TX_INP_MUX_ADC_MUX7_CFG1 (0x013C)
+#define CDC_TX_INP_MUX_ADC_MUX0_CFG2 (0x0140)
+#define CDC_TX_INP_MUX_ADC_MUX1_CFG2 (0x0144)
+#define CDC_TX_INP_MUX_ADC_MUX2_CFG2 (0x0148)
+#define CDC_TX_INP_MUX_ADC_MUX3_CFG2 (0x014C)
+#define CDC_TX_INP_MUX_ADC_MUX4_CFG2 (0x0150)
+#define CDC_TX_INP_MUX_ADC_MUX5_CFG2 (0x0154)
+#define CDC_TX_INP_MUX_ADC_MUX6_CFG2 (0x0158)
+#define CDC_TX_INP_MUX_ADC_MUX7_CFG2 (0x015C)
#define CDC_TX_ANC0_CLK_RESET_CTL (0x0200)
#define CDC_TX_ANC0_MODE_1_CTL (0x0204)
#define CDC_TX_ANC0_MODE_2_CTL (0x0208)
@@ -108,6 +117,17 @@
#define CDC_TX0_TX_PATH_SEC5 (0x0424)
#define CDC_TX0_TX_PATH_SEC6 (0x0428)
#define CDC_TX0_TX_PATH_SEC7 (0x042C)
+#define CDC_TX0_TX_PATH_CFG2 (0x0430)
+#define CDC_TX1_TX_PATH_CFG2 (0x04B0)
+#define CDC_TX2_TX_PATH_CFG2 (0x0530)
+#define CDC_TX3_TX_PATH_CFG2 (0x05B0)
+#define CDC_TX4_TX_PATH_CFG2 (0x0630)
+#define CDC_TX5_TX_PATH_CFG2 (0x06B0)
+#define CDC_TX6_TX_PATH_CFG2 (0x0730)
+#define CDC_TX7_TX_PATH_CFG2 (0x07B0)
+#define CDC_ADPT0_ADPT_CTRL (0x0800)
+#define CDC_TX_ADPT_CTRL_EN_MASK GENMASK(7, 0)
+
#define CDC_TX0_MBHC_CTL_EN_MASK BIT(6)
#define CDC_TX1_TX_PATH_CTL (0x0480)
#define CDC_TX1_TX_PATH_CFG0 (0x0484)
@@ -186,7 +206,8 @@
#define CDC_TX7_TX_PATH_SEC4 (0x07A0)
#define CDC_TX7_TX_PATH_SEC5 (0x07A4)
#define CDC_TX7_TX_PATH_SEC6 (0x07A8)
-#define TX_MAX_OFFSET (0x07A8)
+#define TX_MAX_OFFSET (CDC_TX7_TX_PATH_SEC6)
+#define TX_4_0_MAX_OFFSET (CDC_ADPT0_ADPT_CTRL)
#define TX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
@@ -258,6 +279,9 @@ struct hpf_work {
struct tx_macro_data {
unsigned int flags;
unsigned int ver;
+ bool has_adpt;
+ const struct snd_soc_dapm_widget *dec_widgets;
+ size_t dec_widgets_num;
const struct snd_soc_dapm_widget *extra_widgets;
size_t extra_widgets_num;
const struct snd_soc_dapm_route *extra_routes;
@@ -434,6 +458,26 @@ static struct reg_default tx_defaults[] = {
{ CDC_TX7_TX_PATH_SEC6, 0x00},
};
+static const struct reg_default tx_4_0_defaults[] = {
+ { CDC_TX_INP_MUX_ADC_MUX0_CFG2, 0x00},
+ { CDC_TX_INP_MUX_ADC_MUX1_CFG2, 0x00},
+ { CDC_TX_INP_MUX_ADC_MUX2_CFG2, 0x00},
+ { CDC_TX_INP_MUX_ADC_MUX3_CFG2, 0x00},
+ { CDC_TX_INP_MUX_ADC_MUX4_CFG2, 0x00},
+ { CDC_TX_INP_MUX_ADC_MUX5_CFG2, 0x00},
+ { CDC_TX_INP_MUX_ADC_MUX6_CFG2, 0x00},
+ { CDC_TX_INP_MUX_ADC_MUX7_CFG2, 0x00},
+ { CDC_TX0_TX_PATH_CFG2, 0x03},
+ { CDC_TX1_TX_PATH_CFG2, 0x03},
+ { CDC_TX2_TX_PATH_CFG2, 0x03},
+ { CDC_TX3_TX_PATH_CFG2, 0x03},
+ { CDC_TX4_TX_PATH_CFG2, 0x03},
+ { CDC_TX5_TX_PATH_CFG2, 0x03},
+ { CDC_TX6_TX_PATH_CFG2, 0x03},
+ { CDC_TX7_TX_PATH_CFG2, 0x03},
+ { CDC_ADPT0_ADPT_CTRL, 0x00},
+};
+
static bool tx_is_volatile_register(struct device *dev, unsigned int reg)
{
/* Update volatile list for tx/tx macros */
@@ -597,6 +641,32 @@ static bool tx_is_rw_register(struct device *dev, unsigned int reg)
return false;
}
+static bool tx_4_0_is_rw_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CDC_TX_INP_MUX_ADC_MUX0_CFG2:
+ case CDC_TX_INP_MUX_ADC_MUX1_CFG2:
+ case CDC_TX_INP_MUX_ADC_MUX2_CFG2:
+ case CDC_TX_INP_MUX_ADC_MUX3_CFG2:
+ case CDC_TX_INP_MUX_ADC_MUX4_CFG2:
+ case CDC_TX_INP_MUX_ADC_MUX5_CFG2:
+ case CDC_TX_INP_MUX_ADC_MUX6_CFG2:
+ case CDC_TX_INP_MUX_ADC_MUX7_CFG2:
+ case CDC_TX0_TX_PATH_CFG2:
+ case CDC_TX1_TX_PATH_CFG2:
+ case CDC_TX2_TX_PATH_CFG2:
+ case CDC_TX3_TX_PATH_CFG2:
+ case CDC_TX4_TX_PATH_CFG2:
+ case CDC_TX5_TX_PATH_CFG2:
+ case CDC_TX6_TX_PATH_CFG2:
+ case CDC_TX7_TX_PATH_CFG2:
+ case CDC_ADPT0_ADPT_CTRL:
+ return true;
+ default:
+ return tx_is_rw_register(dev, reg);
+ }
+}
+
static const struct regmap_config tx_regmap_config = {
.name = "tx_macro",
.reg_bits = 16,
@@ -604,8 +674,7 @@ static const struct regmap_config tx_regmap_config = {
.reg_stride = 4,
.cache_type = REGCACHE_MAPLE,
.max_register = TX_MAX_OFFSET,
- .reg_defaults = tx_defaults,
- .num_reg_defaults = ARRAY_SIZE(tx_defaults),
+ /* .reg_defaults and .num_reg_defaults set in probe() */
.writeable_reg = tx_is_rw_register,
.volatile_reg = tx_is_volatile_register,
.readable_reg = tx_is_rw_register,
@@ -929,6 +998,10 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ /* Disable the ADPT block before enabling the decimator */
+ if (tx->data->has_adpt)
+ snd_soc_component_write_field(component, CDC_ADPT0_ADPT_CTRL,
+ CDC_TX_ADPT_CTRL_EN_MASK, 0x0);
adc_mux_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG1(decimator);
if (snd_soc_component_read(component, adc_mux_reg) & SWR_MIC) {
adc_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG0(decimator);
@@ -1456,6 +1529,17 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("TX DMIC6"),
SND_SOC_DAPM_INPUT("TX DMIC7"),
+ SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
+ tx_macro_mclk_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+ NULL, 0),
+};
+
+static const struct snd_soc_dapm_widget tx_macro_dec_dapm_widgets[] = {
SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM,
TX_MACRO_DEC0, 0,
&tx_dec0_mux, tx_macro_enable_dec,
@@ -1503,14 +1587,6 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = {
&tx_dec7_mux, tx_macro_enable_dec,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
- tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
- NULL, 0),
};
static const struct snd_soc_dapm_route tx_audio_map[] = {
@@ -2027,6 +2103,418 @@ static const struct snd_soc_dapm_route tx_audio_map_v9_2[] = {
{"TX SMIC MUX7", "SWR_MIC11", "TX SWR_INPUT11"},
};
+static const char * const adc_mux_text_v9_3[] = {
+ "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1", "RX_SWR_MIC"
+};
+
+static SOC_ENUM_SINGLE_DECL(tx_dec0_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX0_CFG1,
+ 0, adc_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_dec1_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX1_CFG1,
+ 0, adc_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_dec2_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX2_CFG1,
+ 0, adc_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_dec3_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX3_CFG1,
+ 0, adc_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_dec4_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX4_CFG1,
+ 0, adc_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_dec5_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX5_CFG1,
+ 0, adc_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_dec6_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX6_CFG1,
+ 0, adc_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_dec7_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX7_CFG1,
+ 0, adc_mux_text_v9_3);
+
+static const struct snd_kcontrol_new tx_dec0_mux_v9_3 =
+ SOC_DAPM_ENUM("tx_dec0", tx_dec0_enum_v9_3);
+static const struct snd_kcontrol_new tx_dec1_mux_v9_3 =
+ SOC_DAPM_ENUM("tx_dec1", tx_dec1_enum_v9_3);
+static const struct snd_kcontrol_new tx_dec2_mux_v9_3 =
+ SOC_DAPM_ENUM("tx_dec2", tx_dec2_enum_v9_3);
+static const struct snd_kcontrol_new tx_dec3_mux_v9_3 =
+ SOC_DAPM_ENUM("tx_dec3", tx_dec3_enum_v9_3);
+static const struct snd_kcontrol_new tx_dec4_mux_v9_3 =
+ SOC_DAPM_ENUM("tx_dec4", tx_dec4_enum_v9_3);
+static const struct snd_kcontrol_new tx_dec5_mux_v9_3 =
+ SOC_DAPM_ENUM("tx_dec5", tx_dec5_enum_v9_3);
+static const struct snd_kcontrol_new tx_dec6_mux_v9_3 =
+ SOC_DAPM_ENUM("tx_dec6", tx_dec6_enum_v9_3);
+static const struct snd_kcontrol_new tx_dec7_mux_v9_3 =
+ SOC_DAPM_ENUM("tx_dec7", tx_dec7_enum_v9_3);
+
+static const char * const smic_mux_text_v9_3[] = {
+ "ZERO", "SWR_MIC0", "SWR_MIC1", "SWR_MIC2", "SWR_MIC3",
+ "SWR_MIC4", "SWR_MIC5", "SWR_MIC6", "SWR_MIC7",
+};
+
+static SOC_ENUM_SINGLE_DECL(tx_smic0_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX0_CFG0,
+ 0, smic_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_smic1_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX1_CFG0,
+ 0, smic_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_smic2_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX2_CFG0,
+ 0, smic_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_smic3_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX3_CFG0,
+ 0, smic_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_smic4_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX4_CFG0,
+ 0, smic_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_smic5_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX5_CFG0,
+ 0, smic_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_smic6_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX6_CFG0,
+ 0, smic_mux_text_v9_3);
+static SOC_ENUM_SINGLE_DECL(tx_smic7_enum_v9_3, CDC_TX_INP_MUX_ADC_MUX7_CFG0,
+ 0, smic_mux_text_v9_3);
+
+static const struct snd_kcontrol_new tx_smic0_mux_v9_3 = SOC_DAPM_ENUM_EXT("tx_smic0",
+ tx_smic0_enum_v9_3, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum);
+static const struct snd_kcontrol_new tx_smic1_mux_v9_3 = SOC_DAPM_ENUM_EXT("tx_smic1",
+ tx_smic1_enum_v9_3, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum);
+static const struct snd_kcontrol_new tx_smic2_mux_v9_3 = SOC_DAPM_ENUM_EXT("tx_smic2",
+ tx_smic2_enum_v9_3, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum);
+static const struct snd_kcontrol_new tx_smic3_mux_v9_3 = SOC_DAPM_ENUM_EXT("tx_smic3",
+ tx_smic3_enum_v9_3, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum);
+static const struct snd_kcontrol_new tx_smic4_mux_v9_3 = SOC_DAPM_ENUM_EXT("tx_smic4",
+ tx_smic4_enum_v9_3, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum);
+static const struct snd_kcontrol_new tx_smic5_mux_v9_3 = SOC_DAPM_ENUM_EXT("tx_smic5",
+ tx_smic5_enum_v9_3, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum);
+static const struct snd_kcontrol_new tx_smic6_mux_v9_3 = SOC_DAPM_ENUM_EXT("tx_smic6",
+ tx_smic6_enum_v9_3, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum);
+static const struct snd_kcontrol_new tx_smic7_mux_v9_3 = SOC_DAPM_ENUM_EXT("tx_smic7",
+ tx_smic7_enum_v9_3, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum);
+
+static const char * const tx_wsa_mux_text[] = {
+ "NO_WSA", "WSA1", "WSA2", "WSA3", "WSA4"
+};
+
+static SOC_ENUM_SINGLE_DECL(tx_wsa_mux0_enum, CDC_TX_INP_MUX_ADC_MUX0_CFG1,
+ 4, tx_wsa_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_wsa_mux1_enum, CDC_TX_INP_MUX_ADC_MUX1_CFG1,
+ 4, tx_wsa_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_wsa_mux2_enum, CDC_TX_INP_MUX_ADC_MUX2_CFG1,
+ 4, tx_wsa_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_wsa_mux3_enum, CDC_TX_INP_MUX_ADC_MUX3_CFG1,
+ 4, tx_wsa_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_wsa_mux4_enum, CDC_TX_INP_MUX_ADC_MUX4_CFG1,
+ 4, tx_wsa_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_wsa_mux5_enum, CDC_TX_INP_MUX_ADC_MUX5_CFG1,
+ 4, tx_wsa_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_wsa_mux6_enum, CDC_TX_INP_MUX_ADC_MUX6_CFG1,
+ 4, tx_wsa_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_wsa_mux7_enum, CDC_TX_INP_MUX_ADC_MUX7_CFG1,
+ 4, tx_wsa_mux_text);
+
+static const struct snd_kcontrol_new tx_wsa_mux0_mux =
+ SOC_DAPM_ENUM("tx_wsa_mux0", tx_wsa_mux0_enum);
+static const struct snd_kcontrol_new tx_wsa_mux1_mux =
+ SOC_DAPM_ENUM("tx_wsa_mux1", tx_wsa_mux1_enum);
+static const struct snd_kcontrol_new tx_wsa_mux2_mux =
+ SOC_DAPM_ENUM("tx_wsa_mux2", tx_wsa_mux2_enum);
+static const struct snd_kcontrol_new tx_wsa_mux3_mux =
+ SOC_DAPM_ENUM("tx_wsa_mux3", tx_wsa_mux3_enum);
+static const struct snd_kcontrol_new tx_wsa_mux4_mux =
+ SOC_DAPM_ENUM("tx_wsa_mux4", tx_wsa_mux4_enum);
+static const struct snd_kcontrol_new tx_wsa_mux5_mux =
+ SOC_DAPM_ENUM("tx_wsa_mux5", tx_wsa_mux5_enum);
+static const struct snd_kcontrol_new tx_wsa_mux6_mux =
+ SOC_DAPM_ENUM("tx_wsa_mux6", tx_wsa_mux6_enum);
+static const struct snd_kcontrol_new tx_wsa_mux7_mux =
+ SOC_DAPM_ENUM("tx_wsa_mux7", tx_wsa_mux7_enum);
+
+static const char * const tx_psel_mux_text[] = {
+ "PORT0", "PORT1", "PORT2", "PORT3", "PORT4"
+};
+
+static SOC_ENUM_SINGLE_DECL(tx_psel_mux0_enum, CDC_TX_INP_MUX_ADC_MUX0_CFG2,
+ 0, tx_psel_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_psel_mux1_enum, CDC_TX_INP_MUX_ADC_MUX1_CFG2,
+ 0, tx_psel_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_psel_mux2_enum, CDC_TX_INP_MUX_ADC_MUX2_CFG2,
+ 0, tx_psel_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_psel_mux3_enum, CDC_TX_INP_MUX_ADC_MUX3_CFG2,
+ 0, tx_psel_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_psel_mux4_enum, CDC_TX_INP_MUX_ADC_MUX4_CFG2,
+ 0, tx_psel_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_psel_mux5_enum, CDC_TX_INP_MUX_ADC_MUX5_CFG2,
+ 0, tx_psel_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_psel_mux6_enum, CDC_TX_INP_MUX_ADC_MUX6_CFG2,
+ 0, tx_psel_mux_text);
+static SOC_ENUM_SINGLE_DECL(tx_psel_mux7_enum, CDC_TX_INP_MUX_ADC_MUX7_CFG2,
+ 0, tx_psel_mux_text);
+
+static const struct snd_kcontrol_new tx_psel_mux0_mux =
+ SOC_DAPM_ENUM("tx_psel_mux0", tx_psel_mux0_enum);
+static const struct snd_kcontrol_new tx_psel_mux1_mux =
+ SOC_DAPM_ENUM("tx_psel_mux1", tx_psel_mux1_enum);
+static const struct snd_kcontrol_new tx_psel_mux2_mux =
+ SOC_DAPM_ENUM("tx_psel_mux2", tx_psel_mux2_enum);
+static const struct snd_kcontrol_new tx_psel_mux3_mux =
+ SOC_DAPM_ENUM("tx_psel_mux3", tx_psel_mux3_enum);
+static const struct snd_kcontrol_new tx_psel_mux4_mux =
+ SOC_DAPM_ENUM("tx_psel_mux4", tx_psel_mux4_enum);
+static const struct snd_kcontrol_new tx_psel_mux5_mux =
+ SOC_DAPM_ENUM("tx_psel_mux5", tx_psel_mux5_enum);
+static const struct snd_kcontrol_new tx_psel_mux6_mux =
+ SOC_DAPM_ENUM("tx_psel_mux6", tx_psel_mux6_enum);
+static const struct snd_kcontrol_new tx_psel_mux7_mux =
+ SOC_DAPM_ENUM("tx_psel_mux7", tx_psel_mux7_enum);
+
+static const struct snd_soc_dapm_widget tx_macro_dec_dapm_widgets_v15[] = {
+ SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC0, 0,
+ &tx_dec0_mux_v9_3, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC1, 0,
+ &tx_dec1_mux_v9_3, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC2, 0,
+ &tx_dec2_mux_v9_3, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC3, 0,
+ &tx_dec3_mux_v9_3, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC4, 0,
+ &tx_dec4_mux_v9_3, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC5, 0,
+ &tx_dec5_mux_v9_3, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC6, 0,
+ &tx_dec6_mux_v9_3, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC7, 0,
+ &tx_dec7_mux_v9_3, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v15[] = {
+ SND_SOC_DAPM_MUX("TX SMIC MUX0", SND_SOC_NOPM, 0, 0, &tx_smic0_mux_v9_3),
+ SND_SOC_DAPM_MUX("TX SMIC MUX1", SND_SOC_NOPM, 0, 0, &tx_smic1_mux_v9_3),
+ SND_SOC_DAPM_MUX("TX SMIC MUX2", SND_SOC_NOPM, 0, 0, &tx_smic2_mux_v9_3),
+ SND_SOC_DAPM_MUX("TX SMIC MUX3", SND_SOC_NOPM, 0, 0, &tx_smic3_mux_v9_3),
+ SND_SOC_DAPM_MUX("TX SMIC MUX4", SND_SOC_NOPM, 0, 0, &tx_smic4_mux_v9_3),
+ SND_SOC_DAPM_MUX("TX SMIC MUX5", SND_SOC_NOPM, 0, 0, &tx_smic5_mux_v9_3),
+ SND_SOC_DAPM_MUX("TX SMIC MUX6", SND_SOC_NOPM, 0, 0, &tx_smic6_mux_v9_3),
+ SND_SOC_DAPM_MUX("TX SMIC MUX7", SND_SOC_NOPM, 0, 0, &tx_smic7_mux_v9_3),
+
+ SND_SOC_DAPM_MUX("TX WSA MUX0", SND_SOC_NOPM, 0, 0, &tx_wsa_mux0_mux),
+ SND_SOC_DAPM_MUX("TX WSA MUX1", SND_SOC_NOPM, 0, 0, &tx_wsa_mux1_mux),
+ SND_SOC_DAPM_MUX("TX WSA MUX2", SND_SOC_NOPM, 0, 0, &tx_wsa_mux2_mux),
+ SND_SOC_DAPM_MUX("TX WSA MUX3", SND_SOC_NOPM, 0, 0, &tx_wsa_mux3_mux),
+ SND_SOC_DAPM_MUX("TX WSA MUX4", SND_SOC_NOPM, 0, 0, &tx_wsa_mux4_mux),
+ SND_SOC_DAPM_MUX("TX WSA MUX5", SND_SOC_NOPM, 0, 0, &tx_wsa_mux5_mux),
+ SND_SOC_DAPM_MUX("TX WSA MUX6", SND_SOC_NOPM, 0, 0, &tx_wsa_mux6_mux),
+ SND_SOC_DAPM_MUX("TX WSA MUX7", SND_SOC_NOPM, 0, 0, &tx_wsa_mux7_mux),
+
+ SND_SOC_DAPM_MUX("TX PORT SEL MUX0", SND_SOC_NOPM, 0, 0, &tx_psel_mux0_mux),
+ SND_SOC_DAPM_MUX("TX PORT SEL MUX1", SND_SOC_NOPM, 0, 0, &tx_psel_mux1_mux),
+ SND_SOC_DAPM_MUX("TX PORT SEL MUX2", SND_SOC_NOPM, 0, 0, &tx_psel_mux2_mux),
+ SND_SOC_DAPM_MUX("TX PORT SEL MUX3", SND_SOC_NOPM, 0, 0, &tx_psel_mux3_mux),
+ SND_SOC_DAPM_MUX("TX PORT SEL MUX4", SND_SOC_NOPM, 0, 0, &tx_psel_mux4_mux),
+ SND_SOC_DAPM_MUX("TX PORT SEL MUX5", SND_SOC_NOPM, 0, 0, &tx_psel_mux5_mux),
+ SND_SOC_DAPM_MUX("TX PORT SEL MUX6", SND_SOC_NOPM, 0, 0, &tx_psel_mux6_mux),
+ SND_SOC_DAPM_MUX("TX PORT SEL MUX7", SND_SOC_NOPM, 0, 0, &tx_psel_mux7_mux),
+
+ SND_SOC_DAPM_INPUT("TX SWR_INPUT"),
+};
+
+static const struct snd_soc_dapm_route tx_audio_map_v15[] = {
+ /* DEC0 */
+ {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"},
+ {"TX SMIC MUX0", NULL, "TX_SWR_CLK"},
+ {"TX SMIC MUX0", "SWR_MIC0", "TX WSA MUX0"},
+ {"TX SMIC MUX0", "SWR_MIC1", "TX WSA MUX0"},
+ {"TX SMIC MUX0", "SWR_MIC2", "TX WSA MUX0"},
+ {"TX SMIC MUX0", "SWR_MIC3", "TX WSA MUX0"},
+ {"TX SMIC MUX0", "SWR_MIC4", "TX WSA MUX0"},
+ {"TX SMIC MUX0", "SWR_MIC5", "TX WSA MUX0"},
+ {"TX SMIC MUX0", "SWR_MIC6", "TX WSA MUX0"},
+ {"TX SMIC MUX0", "SWR_MIC7", "TX WSA MUX0"},
+ {"TX WSA MUX0", "NO_WSA", "TX PORT SEL MUX0"},
+ {"TX WSA MUX0", "WSA1", "TX PORT SEL MUX0"},
+ {"TX WSA MUX0", "WSA2", "TX PORT SEL MUX0"},
+ {"TX WSA MUX0", "WSA3", "TX PORT SEL MUX0"},
+ {"TX WSA MUX0", "WSA4", "TX PORT SEL MUX0"},
+ {"TX PORT SEL MUX0", "PORT0", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX0", "PORT1", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX0", "PORT2", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX0", "PORT3", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX0", "PORT4", "TX SWR_INPUT"},
+
+ /* DEC1 */
+ {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"},
+ {"TX SMIC MUX1", NULL, "TX_SWR_CLK"},
+ {"TX SMIC MUX1", "SWR_MIC0", "TX WSA MUX1"},
+ {"TX SMIC MUX1", "SWR_MIC1", "TX WSA MUX1"},
+ {"TX SMIC MUX1", "SWR_MIC2", "TX WSA MUX1"},
+ {"TX SMIC MUX1", "SWR_MIC3", "TX WSA MUX1"},
+ {"TX SMIC MUX1", "SWR_MIC4", "TX WSA MUX1"},
+ {"TX SMIC MUX1", "SWR_MIC5", "TX WSA MUX1"},
+ {"TX SMIC MUX1", "SWR_MIC6", "TX WSA MUX1"},
+ {"TX SMIC MUX1", "SWR_MIC7", "TX WSA MUX1"},
+ {"TX WSA MUX1", "NO_WSA", "TX PORT SEL MUX1"},
+ {"TX WSA MUX1", "WSA1", "TX PORT SEL MUX1"},
+ {"TX WSA MUX1", "WSA2", "TX PORT SEL MUX1"},
+ {"TX WSA MUX1", "WSA3", "TX PORT SEL MUX1"},
+ {"TX WSA MUX1", "WSA4", "TX PORT SEL MUX1"},
+ {"TX PORT SEL MUX1", "PORT0", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX1", "PORT1", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX1", "PORT2", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX1", "PORT3", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX1", "PORT4", "TX SWR_INPUT"},
+
+ /* DEC2 */
+ {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"},
+ {"TX SMIC MUX2", NULL, "TX_SWR_CLK"},
+ {"TX SMIC MUX2", "SWR_MIC0", "TX WSA MUX2"},
+ {"TX SMIC MUX2", "SWR_MIC1", "TX WSA MUX2"},
+ {"TX SMIC MUX2", "SWR_MIC2", "TX WSA MUX2"},
+ {"TX SMIC MUX2", "SWR_MIC3", "TX WSA MUX2"},
+ {"TX SMIC MUX2", "SWR_MIC4", "TX WSA MUX2"},
+ {"TX SMIC MUX2", "SWR_MIC5", "TX WSA MUX2"},
+ {"TX SMIC MUX2", "SWR_MIC6", "TX WSA MUX2"},
+ {"TX SMIC MUX2", "SWR_MIC7", "TX WSA MUX2"},
+ {"TX WSA MUX2", "NO_WSA", "TX PORT SEL MUX2"},
+ {"TX WSA MUX2", "WSA1", "TX PORT SEL MUX2"},
+ {"TX WSA MUX2", "WSA2", "TX PORT SEL MUX2"},
+ {"TX WSA MUX2", "WSA3", "TX PORT SEL MUX2"},
+ {"TX WSA MUX2", "WSA4", "TX PORT SEL MUX2"},
+ {"TX PORT SEL MUX2", "PORT0", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX2", "PORT1", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX2", "PORT2", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX2", "PORT3", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX2", "PORT4", "TX SWR_INPUT"},
+
+ /* DEC3 */
+ {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"},
+ {"TX SMIC MUX3", NULL, "TX_SWR_CLK"},
+ {"TX SMIC MUX3", "SWR_MIC0", "TX WSA MUX3"},
+ {"TX SMIC MUX3", "SWR_MIC1", "TX WSA MUX3"},
+ {"TX SMIC MUX3", "SWR_MIC2", "TX WSA MUX3"},
+ {"TX SMIC MUX3", "SWR_MIC3", "TX WSA MUX3"},
+ {"TX SMIC MUX3", "SWR_MIC4", "TX WSA MUX3"},
+ {"TX SMIC MUX3", "SWR_MIC5", "TX WSA MUX3"},
+ {"TX SMIC MUX3", "SWR_MIC6", "TX WSA MUX3"},
+ {"TX SMIC MUX3", "SWR_MIC7", "TX WSA MUX3"},
+ {"TX WSA MUX3", "NO_WSA", "TX PORT SEL MUX3"},
+ {"TX WSA MUX3", "WSA1", "TX PORT SEL MUX3"},
+ {"TX WSA MUX3", "WSA2", "TX PORT SEL MUX3"},
+ {"TX WSA MUX3", "WSA3", "TX PORT SEL MUX3"},
+ {"TX WSA MUX3", "WSA4", "TX PORT SEL MUX3"},
+ {"TX PORT SEL MUX3", "PORT0", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX3", "PORT1", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX3", "PORT2", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX3", "PORT3", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX3", "PORT4", "TX SWR_INPUT"},
+
+ /* DEC4 */
+ {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"},
+ {"TX SMIC MUX4", NULL, "TX_SWR_CLK"},
+ {"TX SMIC MUX4", "SWR_MIC0", "TX WSA MUX4"},
+ {"TX SMIC MUX4", "SWR_MIC1", "TX WSA MUX4"},
+ {"TX SMIC MUX4", "SWR_MIC2", "TX WSA MUX4"},
+ {"TX SMIC MUX4", "SWR_MIC3", "TX WSA MUX4"},
+ {"TX SMIC MUX4", "SWR_MIC4", "TX WSA MUX4"},
+ {"TX SMIC MUX4", "SWR_MIC5", "TX WSA MUX4"},
+ {"TX SMIC MUX4", "SWR_MIC6", "TX WSA MUX4"},
+ {"TX SMIC MUX4", "SWR_MIC7", "TX WSA MUX4"},
+ {"TX WSA MUX4", "NO_WSA", "TX PORT SEL MUX4"},
+ {"TX WSA MUX4", "WSA1", "TX PORT SEL MUX4"},
+ {"TX WSA MUX4", "WSA2", "TX PORT SEL MUX4"},
+ {"TX WSA MUX4", "WSA3", "TX PORT SEL MUX4"},
+ {"TX WSA MUX4", "WSA4", "TX PORT SEL MUX4"},
+ {"TX PORT SEL MUX4", "PORT0", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX4", "PORT1", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX4", "PORT2", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX4", "PORT3", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX4", "PORT4", "TX SWR_INPUT"},
+
+ /* DEC5 */
+ {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"},
+ {"TX SMIC MUX5", NULL, "TX_SWR_CLK"},
+ {"TX SMIC MUX5", "SWR_MIC0", "TX WSA MUX5"},
+ {"TX SMIC MUX5", "SWR_MIC1", "TX WSA MUX5"},
+ {"TX SMIC MUX5", "SWR_MIC2", "TX WSA MUX5"},
+ {"TX SMIC MUX5", "SWR_MIC3", "TX WSA MUX5"},
+ {"TX SMIC MUX5", "SWR_MIC4", "TX WSA MUX5"},
+ {"TX SMIC MUX5", "SWR_MIC5", "TX WSA MUX5"},
+ {"TX SMIC MUX5", "SWR_MIC6", "TX WSA MUX5"},
+ {"TX SMIC MUX5", "SWR_MIC7", "TX WSA MUX5"},
+ {"TX WSA MUX5", "NO_WSA", "TX PORT SEL MUX5"},
+ {"TX WSA MUX5", "WSA1", "TX PORT SEL MUX5"},
+ {"TX WSA MUX5", "WSA2", "TX PORT SEL MUX5"},
+ {"TX WSA MUX5", "WSA3", "TX PORT SEL MUX5"},
+ {"TX WSA MUX5", "WSA4", "TX PORT SEL MUX5"},
+ {"TX PORT SEL MUX5", "PORT0", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX5", "PORT1", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX5", "PORT2", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX5", "PORT3", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX5", "PORT4", "TX SWR_INPUT"},
+
+ /* DEC6 */
+ {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"},
+ {"TX SMIC MUX6", NULL, "TX_SWR_CLK"},
+ {"TX SMIC MUX6", "SWR_MIC0", "TX WSA MUX6"},
+ {"TX SMIC MUX6", "SWR_MIC1", "TX WSA MUX6"},
+ {"TX SMIC MUX6", "SWR_MIC2", "TX WSA MUX6"},
+ {"TX SMIC MUX6", "SWR_MIC3", "TX WSA MUX6"},
+ {"TX SMIC MUX6", "SWR_MIC4", "TX WSA MUX6"},
+ {"TX SMIC MUX6", "SWR_MIC5", "TX WSA MUX6"},
+ {"TX SMIC MUX6", "SWR_MIC6", "TX WSA MUX6"},
+ {"TX SMIC MUX6", "SWR_MIC7", "TX WSA MUX6"},
+ {"TX WSA MUX6", "NO_WSA", "TX PORT SEL MUX6"},
+ {"TX WSA MUX6", "WSA1", "TX PORT SEL MUX6"},
+ {"TX WSA MUX6", "WSA2", "TX PORT SEL MUX6"},
+ {"TX WSA MUX6", "WSA3", "TX PORT SEL MUX6"},
+ {"TX WSA MUX6", "WSA4", "TX PORT SEL MUX6"},
+ {"TX PORT SEL MUX6", "PORT0", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX6", "PORT1", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX6", "PORT2", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX6", "PORT3", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX6", "PORT4", "TX SWR_INPUT"},
+
+ /* DEC7 */
+ {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"},
+ {"TX SMIC MUX7", NULL, "TX_SWR_CLK"},
+ {"TX SMIC MUX7", "SWR_MIC0", "TX WSA MUX7"},
+ {"TX SMIC MUX7", "SWR_MIC1", "TX WSA MUX7"},
+ {"TX SMIC MUX7", "SWR_MIC2", "TX WSA MUX7"},
+ {"TX SMIC MUX7", "SWR_MIC3", "TX WSA MUX7"},
+ {"TX SMIC MUX7", "SWR_MIC4", "TX WSA MUX7"},
+ {"TX SMIC MUX7", "SWR_MIC5", "TX WSA MUX7"},
+ {"TX SMIC MUX7", "SWR_MIC6", "TX WSA MUX7"},
+ {"TX SMIC MUX7", "SWR_MIC7", "TX WSA MUX7"},
+ {"TX WSA MUX7", "NO_WSA", "TX PORT SEL MUX7"},
+ {"TX WSA MUX7", "WSA1", "TX PORT SEL MUX7"},
+ {"TX WSA MUX7", "WSA2", "TX PORT SEL MUX7"},
+ {"TX WSA MUX7", "WSA3", "TX PORT SEL MUX7"},
+ {"TX WSA MUX7", "WSA4", "TX PORT SEL MUX7"},
+ {"TX PORT SEL MUX7", "PORT0", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX7", "PORT1", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX7", "PORT2", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX7", "PORT3", "TX SWR_INPUT"},
+ {"TX PORT SEL MUX7", "PORT4", "TX SWR_INPUT"},
+};
+
static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
SOC_SINGLE_S8_TLV("TX_DEC0 Volume",
CDC_TX0_TX_VOL_CTL,
@@ -2085,8 +2573,21 @@ static int tx_macro_component_extend(struct snd_soc_component *comp)
{
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(comp);
struct tx_macro *tx = snd_soc_component_get_drvdata(comp);
+ const struct snd_soc_dapm_widget *dec_widgets = tx_macro_dec_dapm_widgets;
+ size_t dec_widgets_num = ARRAY_SIZE(tx_macro_dec_dapm_widgets);
int ret;
+ if (tx->data->dec_widgets_num) {
+ dec_widgets = tx->data->dec_widgets;
+ dec_widgets_num = tx->data->dec_widgets_num;
+ }
+
+ ret = snd_soc_dapm_new_controls(dapm, dec_widgets, dec_widgets_num);
+ if (ret) {
+ dev_err(tx->dev, "failed to add decimator widgets: %d\n", ret);
+ return ret;
+ }
+
if (tx->data->extra_widgets_num) {
ret = snd_soc_dapm_new_controls(dapm, tx->data->extra_widgets,
tx->data->extra_widgets_num);
@@ -2250,6 +2751,9 @@ static int tx_macro_probe(struct platform_device *pdev)
struct device_node *np = dev->of_node;
struct tx_macro *tx;
void __iomem *base;
+ struct reg_default *reg_defaults __free(kfree) = NULL;
+ struct regmap_config *reg_config __free(kfree) = NULL;
+ size_t def_count;
int ret, reg;
tx = devm_kzalloc(dev, sizeof(*tx), GFP_KERNEL);
@@ -2304,7 +2808,40 @@ static int tx_macro_probe(struct platform_device *pdev)
}
}
- tx->regmap = devm_regmap_init_mmio(dev, base, &tx_regmap_config);
+ reg_config = kmemdup(&tx_regmap_config, sizeof(*reg_config), GFP_KERNEL);
+ if (!reg_config) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ reg_config->reg_defaults = tx_defaults;
+ reg_config->num_reg_defaults = ARRAY_SIZE(tx_defaults);
+
+ switch (tx->data->ver) {
+ case LPASS_VER_15_0_0:
+ def_count = ARRAY_SIZE(tx_defaults) + ARRAY_SIZE(tx_4_0_defaults);
+ reg_defaults = kmalloc_objs(*reg_defaults, def_count);
+ if (!reg_defaults) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ memcpy(®_defaults[0], tx_defaults, sizeof(tx_defaults));
+ memcpy(®_defaults[ARRAY_SIZE(tx_defaults)],
+ tx_4_0_defaults, sizeof(tx_4_0_defaults));
+ regcache_sort_defaults(reg_defaults, def_count);
+
+ reg_config->max_register = TX_4_0_MAX_OFFSET;
+ reg_config->reg_defaults = reg_defaults;
+ reg_config->num_reg_defaults = def_count;
+ reg_config->writeable_reg = tx_4_0_is_rw_register;
+ reg_config->readable_reg = tx_4_0_is_rw_register;
+ break;
+ default:
+ break;
+ }
+
+ tx->regmap = devm_regmap_init_mmio(dev, base, reg_config);
if (IS_ERR(tx->regmap)) {
ret = PTR_ERR(tx->regmap);
goto err;
@@ -2477,6 +3014,18 @@ static const struct tx_macro_data lpass_ver_11 = {
.extra_routes_num = ARRAY_SIZE(tx_audio_map_v9_2),
};
+static const struct tx_macro_data lpass_ver_15 = {
+ .flags = LPASS_MACRO_FLAG_RESET_SWR,
+ .ver = LPASS_VER_15_0_0,
+ .has_adpt = true,
+ .dec_widgets = tx_macro_dec_dapm_widgets_v15,
+ .dec_widgets_num = ARRAY_SIZE(tx_macro_dec_dapm_widgets_v15),
+ .extra_widgets = tx_macro_dapm_widgets_v15,
+ .extra_widgets_num = ARRAY_SIZE(tx_macro_dapm_widgets_v15),
+ .extra_routes = tx_audio_map_v15,
+ .extra_routes_num = ARRAY_SIZE(tx_audio_map_v15),
+};
+
static const struct of_device_id tx_macro_dt_match[] = {
{
/*
@@ -2499,6 +3048,9 @@ static const struct of_device_id tx_macro_dt_match[] = {
}, {
.compatible = "qcom,sm8550-lpass-tx-macro",
.data = &lpass_ver_11,
+ }, {
+ .compatible = "qcom,hawi-lpass-tx-macro",
+ .data = &lpass_ver_15,
}, {
.compatible = "qcom,sc8280xp-lpass-tx-macro",
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v5 9/9] ASoC: qcom: lpass: Add support for LPASS codec v4.0
2026-10-14 9:12 [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support Mohammad Rafi Shaik
` (7 preceding siblings ...)
2026-10-14 9:12 ` [PATCH v5 8/9] ASoC: qcom: lpass-tx-macro: Add support for Bolero v4.0 Mohammad Rafi Shaik
@ 2026-10-14 9:12 ` Mohammad Rafi Shaik
8 siblings, 0 replies; 14+ messages in thread
From: Mohammad Rafi Shaik @ 2026-10-14 9:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Mohammad Rafi Shaik, linux-arm-msm, linux-sound, devicetree,
linux-kernel, Prasad Kumpatla
From: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
Hawi and Maili use the LPASS codec v4.0, which the macro drivers do not
yet recognise.
Add LPASS_CODEC_VERSION_4_0 and its "v4.0" version string, and detect it
in the VA macro when the hardware reports major version 4, minor 0.
The RX macro register layout of LPASS codec v4.0 matches the v2.5+
layout, so reuse the existing v2.5 register access helpers, controls,
widgets and register defaults for it. Unlike v4.1, v4.0 does not need
the FS counter bypass or the adaptive filter blocks, so those stay keyed
off v4.1 only.
Add the "qcom,hawi-lpass-rx-macro" and "qcom,hawi-lpass-va-macro"
compatibles, both pointing at the sm8550 match data, so the version is
read back from the hardware at probe.
Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
sound/soc/codecs/lpass-macro-common.h | 3 +++
sound/soc/codecs/lpass-rx-macro.c | 5 +++++
sound/soc/codecs/lpass-va-macro.c | 4 ++++
3 files changed, 12 insertions(+)
diff --git a/sound/soc/codecs/lpass-macro-common.h b/sound/soc/codecs/lpass-macro-common.h
index 707b22a6b..a51a6012a 100644
--- a/sound/soc/codecs/lpass-macro-common.h
+++ b/sound/soc/codecs/lpass-macro-common.h
@@ -31,6 +31,7 @@ enum lpass_codec_version {
LPASS_CODEC_VERSION_2_7,
LPASS_CODEC_VERSION_2_8,
LPASS_CODEC_VERSION_2_9,
+ LPASS_CODEC_VERSION_4_0,
LPASS_CODEC_VERSION_4_1,
};
@@ -72,6 +73,8 @@ static inline const char *lpass_macro_get_codec_version_string(int version)
return "v2.8";
case LPASS_CODEC_VERSION_2_9:
return "v2.9";
+ case LPASS_CODEC_VERSION_4_0:
+ return "v4.0";
case LPASS_CODEC_VERSION_4_1:
return "v4.1";
default:
diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c
index 93ceee878..b7c1eff05 100644
--- a/sound/soc/codecs/lpass-rx-macro.c
+++ b/sound/soc/codecs/lpass-rx-macro.c
@@ -1615,6 +1615,7 @@ static bool rx_is_rw_register(struct device *dev, unsigned int reg)
case LPASS_CODEC_VERSION_2_6:
case LPASS_CODEC_VERSION_2_7:
case LPASS_CODEC_VERSION_2_8:
+ case LPASS_CODEC_VERSION_4_0:
case LPASS_CODEC_VERSION_4_1:
return rx_2_5_is_rw_register(dev, reg);
default:
@@ -3660,6 +3661,7 @@ static int rx_macro_component_probe(struct snd_soc_component *component)
case LPASS_CODEC_VERSION_2_6:
case LPASS_CODEC_VERSION_2_7:
case LPASS_CODEC_VERSION_2_8:
+ case LPASS_CODEC_VERSION_4_0:
case LPASS_CODEC_VERSION_4_1:
controls = rx_macro_2_5_snd_controls;
num_controls = ARRAY_SIZE(rx_macro_2_5_snd_controls);
@@ -3846,6 +3848,7 @@ static int rx_macro_probe(struct platform_device *pdev)
case LPASS_CODEC_VERSION_2_6:
case LPASS_CODEC_VERSION_2_7:
case LPASS_CODEC_VERSION_2_8:
+ case LPASS_CODEC_VERSION_4_0:
case LPASS_CODEC_VERSION_4_1:
rx->rxn_reg_stride = 0xc0;
rx->rxn_reg_stride2 = 0x0;
@@ -3959,6 +3962,8 @@ static const struct of_device_id rx_macro_dt_match[] = {
.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,
}, {
.compatible = "qcom,sm8550-lpass-rx-macro",
+ }, {
+ .compatible = "qcom,hawi-lpass-rx-macro",
}, {
.compatible = "qcom,sc8280xp-lpass-rx-macro",
.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,
diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c
index cdef2b187..94e3c26e6 100644
--- a/sound/soc/codecs/lpass-va-macro.c
+++ b/sound/soc/codecs/lpass-va-macro.c
@@ -1909,6 +1909,9 @@ static int va_macro_set_lpass_codec_version(struct va_macro *va)
}
} else if (maj == 4) {
switch (min) {
+ case 0:
+ version = LPASS_CODEC_VERSION_4_0;
+ break;
case 1:
version = LPASS_CODEC_VERSION_4_1;
break;
@@ -2183,6 +2186,7 @@ static const struct of_device_id va_macro_dt_match[] = {
{ .compatible = "qcom,sm8250-lpass-va-macro", .data = &sm8250_va_data },
{ .compatible = "qcom,sm8450-lpass-va-macro", .data = &sm8450_va_data },
{ .compatible = "qcom,sm8550-lpass-va-macro", .data = &sm8550_va_data },
+ { .compatible = "qcom,hawi-lpass-va-macro", .data = &sm8550_va_data },
{ .compatible = "qcom,sc8280xp-lpass-va-macro", .data = &sm8450_va_data },
{ .compatible = "qcom,shikra-lpass-va-macro", .data = &shikra_va_data },
{}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v5 3/9] ASoC: qcom: lpass-rx-macro: Add shikra compatible
2026-10-14 9:12 ` [PATCH v5 3/9] ASoC: qcom: lpass-rx-macro: Add shikra compatible Mohammad Rafi Shaik
@ 2026-10-14 9:28 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-10-14 9:28 UTC (permalink / raw)
To: Mohammad Rafi Shaik; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] sound/soc: data race on rx_mclk_users leads to premature MCLK disable
--
commit 3e23cc050d00484d829b0a64e250b4871e497cc8
Author: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
ASoC: qcom: lpass-rx-macro: Add shikra compatible
This commit adds the shikra RX macro compatible data and hooks it into the
LPASS codec v4.1 flow. It reuses existing v2.5 register access helpers and
configures the FS counter to be bypassed before MCLK is enabled.
> diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c
> index c41eb8de61609..93ceee878b78a 100644
> --- a/sound/soc/codecs/lpass-rx-macro.c
> +++ b/sound/soc/codecs/lpass-rx-macro.c
[ ... ]
> @@ -2041,20 +2044,25 @@ static int rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable)
>
> if (mclk_enable) {
> if (rx->rx_mclk_users == 0) {
> regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
> CDC_RX_CLK_MCLK_EN_MASK |
> CDC_RX_CLK_MCLK2_EN_MASK,
> CDC_RX_CLK_MCLK_ENABLE |
> CDC_RX_CLK_MCLK2_ENABLE);
> regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
> CDC_RX_FS_MCLK_CNT_CLR_MASK, 0x00);
> +
> + if (rx->fs_cnt_bypass)
> + regmap_set_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
> + CDC_RX_FS_CNT_BYPASS);
> +
> regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
> CDC_RX_FS_MCLK_CNT_EN_MASK,
> CDC_RX_FS_MCLK_CNT_ENABLE);
> regcache_mark_dirty(regmap);
> ret = regcache_sync(regmap);
> if (ret)
> return ret;
> }
> rx->rx_mclk_users++;
[Severity: Medium]
Could this function be susceptible to a data race on rx->rx_mclk_users?
It appears that rx_macro_mclk_enable() can be called from two different
concurrency domains without internal locking: swclk_gate_enable() and
swclk_gate_disable() (which execute under the clock framework's prepare_lock
mutex) and rx_macro_mclk_event() (which executes under ALSA DAPM's
dapm_mutex).
If the rx->rx_mclk_users counter is checked and modified non-atomically,
could concurrent stream start and clock enable events cause a lost increment?
If an increment is lost, when one stream later stops, rx_mclk_users could
drop to 0 prematurely, disabling the MCLK hardware while the other stream
is still actively relying on it.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261014-add_shikra_support_v5-v5-0-fb9f0667e613@oss.qualcomm.com?part=3
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v5 5/9] ASoC: qcom: lpass-va-macro: Add SoundWire microphone support
2026-10-14 9:12 ` [PATCH v5 5/9] ASoC: qcom: lpass-va-macro: Add SoundWire microphone support Mohammad Rafi Shaik
@ 2026-10-14 9:30 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-10-14 9:30 UTC (permalink / raw)
To: Mohammad Rafi Shaik; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] ASoC: qcom: lpass-va-macro: Stale hardware domain state when switching decimator mux dynamically
--
commit 06fa19ab9efeab4b7696e8d81e98eecb28b18195
Author: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
ASoC: qcom: lpass-va-macro: Add SoundWire microphone support
The VA decimators can currently capture audio only from DMIC inputs.
Add support for routing audio from SoundWire microphone (SMIC) inputs
as well.
> diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c
> index 53828dd80b832..cdef2b187407e 100644
> --- a/sound/soc/codecs/lpass-va-macro.c
> +++ b/sound/soc/codecs/lpass-va-macro.c
[ ... ]
> @@ -1003,6 +1032,18 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w,
>
> switch (event) {
> case SND_SOC_DAPM_PRE_PMU:
> + /*
> + * ADC_DMIC_SEL is shared by the DMIC and the SoundWire mic
> + * mux, so its value depends on the order in which userspace
> + * restores the two controls. Program it from the resolved
> + * mux state of this decimator, which is what selects the
> + * input domain.
> + */
> + snd_soc_component_update_bits(comp, dec_cfg_reg,
> + CDC_VA_TX_PATH_ADC_DMIC_SEL_MASK,
> + is_amic_enabled(comp, decimator) ?
> + CDC_VA_TX_PATH_ADC_DMIC_SEL_ADC :
> + CDC_VA_TX_PATH_ADC_DMIC_SEL_DMIC);
[Severity: Medium]
The outer decimator muxes like va_dec0_mux are defined using the standard
SOC_DAPM_ENUM macro. Unlike the inner muxes like va_smic0_mux which have
custom put callbacks (va_macro_put_dec_enum), the outer muxes lack a custom
put callback to sync this register on the fly.
If an active capture stream is running and the outer decimator mux is
dynamically toggled between VA_DMIC and SWR_MIC, the mux widget remains
powered. Since the power state doesn't cycle, DAPM will bypass the
SND_SOC_DAPM_PRE_PMU event in va_macro_enable_dec() shown here.
Will this cause ADC_DMIC_SEL to become stale and the hardware to continue
capturing from the old domain while DAPM routes the new one, resulting in
silent or corrupted audio until the stream is restarted?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261014-add_shikra_support_v5-v5-0-fb9f0667e613@oss.qualcomm.com?part=5
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v5 8/9] ASoC: qcom: lpass-tx-macro: Add support for Bolero v4.0
2026-10-14 9:12 ` [PATCH v5 8/9] ASoC: qcom: lpass-tx-macro: Add support for Bolero v4.0 Mohammad Rafi Shaik
@ 2026-10-14 9:35 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-10-14 9:35 UTC (permalink / raw)
To: Mohammad Rafi Shaik; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] cleanup: Mixing goto-based error handling with __free() scope-based cleanup
- [Medium] ASoC: qcom: lpass-tx-macro: SWR_MIC bitwise check misidentifies RX_SWR_MIC
--
commit 64e799e2b76860a53ceff3f36c16c6368d70c60e
Author: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
ASoC: qcom: lpass-tx-macro: Add support for Bolero v4.0
This commit adds support for the Bolero v4.0 TX macro in the Hawi platform.
It introduces v4.0 specific register defaults, extends regmap accessors, and
registers a separate decimator widget table to handle the new mux enum and
DAPM events.
> diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c
> index 6deaaabe43afa..6480a6c9032e3 100644
> --- a/sound/soc/codecs/lpass-tx-macro.c
> +++ b/sound/soc/codecs/lpass-tx-macro.c
[ ... ]
> @@ -929,6 +998,10 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
>
> switch (event) {
> case SND_SOC_DAPM_PRE_PMU:
> + /* Disable the ADPT block before enabling the decimator */
> + if (tx->data->has_adpt)
> + snd_soc_component_write_field(component, CDC_ADPT0_ADPT_CTRL,
> + CDC_TX_ADPT_CTRL_EN_MASK, 0x0);
> adc_mux_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG1(decimator);
> if (snd_soc_component_read(component, adc_mux_reg) & SWR_MIC) {
[Severity: Medium]
Will this bitwise check incorrectly match the newly added RX_SWR_MIC?
The adc_mux_text_v9_3 enum added below introduces RX_SWR_MIC at index 3. When
RX_SWR_MIC is selected, snd_soc_component_read() & SWR_MIC evaluates to
3 & 1 == 1 (true).
This erroneously triggers SWR_MIC-specific logic for RX_SWR_MIC in both
tx_macro_enable_dec() and is_amic_enabled(). If a machine driver routes
RX_SWR_MIC and powers it up, the PRE_PMU block will read the irrelevant SMIC
mux register and overwrite CDC_TX_TOP_CSR_SWR_DMICn_CTL if the leftover value
is >= 5.
Even if not routed, the teardown bug in PRE_PMD executes when userspace
switches the mux away from an active path to RX_SWR_MIC.
[ ... ]
> @@ -2027,6 +2103,418 @@ static const struct snd_soc_dapm_route tx_audio_map_v9_2[] = {
> {"TX SMIC MUX7", "SWR_MIC11", "TX SWR_INPUT11"},
> };
>
> +static const char * const adc_mux_text_v9_3[] = {
> + "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1", "RX_SWR_MIC"
> +};
[ ... ]
> @@ -2250,6 +2751,9 @@ static int tx_macro_probe(struct platform_device *pdev)
> struct device_node *np = dev->of_node;
> struct tx_macro *tx;
> void __iomem *base;
> + struct reg_default *reg_defaults __free(kfree) = NULL;
> + struct regmap_config *reg_config __free(kfree) = NULL;
> + size_t def_count;
> int ret, reg;
[ ... ]
> @@ -2304,7 +2808,40 @@ static int tx_macro_probe(struct platform_device *pdev)
> }
> }
>
> - tx->regmap = devm_regmap_init_mmio(dev, base, &tx_regmap_config);
> + reg_config = kmemdup(&tx_regmap_config, sizeof(*reg_config), GFP_KERNEL);
> + if (!reg_config) {
> + ret = -ENOMEM;
> + goto err;
> + }
[Severity: Medium]
Is it safe to mix goto-based error handling with scope-based cleanup in this
function?
The new reg_defaults and reg_config pointers are declared with the
__free(kfree) attribute for automatic scope-based cleanup. However,
tx_macro_probe() handles errors unconditionally by jumping to the err or
err_rpm_put labels via goto statements.
The global Linux kernel cleanup guidelines explicitly forbid mixing goto-based
error paths with __free() cleanup blocks in the same function. Doing so causes
confusing ownership semantics and can lead to bugs where the compiler emits
cleanup instructions at label destinations that interfere with the expected
control flow. The subsystem rules require converting all resources to
scope-based cleanup or converting none of them.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261014-add_shikra_support_v5-v5-0-fb9f0667e613@oss.qualcomm.com?part=8
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v5 6/9] ASoC: dt-bindings: qcom: Add Hawi LPASS macro codecs
2026-10-14 9:12 ` [PATCH v5 6/9] ASoC: dt-bindings: qcom: Add Hawi LPASS macro codecs Mohammad Rafi Shaik
@ 2026-10-14 9:35 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-10-14 9:35 UTC (permalink / raw)
To: Mohammad Rafi Shaik; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] dt-bindings: erroneous 'lpr' clock requirement for TX and VA macros
- [Low] dt-bindings: qcom: lpass-tx: copy-pasted clock prevents block sharing
--
commit 8329a2400381810d27d8768d8793aa64ce4220c0
Author: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
ASoC: dt-bindings: qcom: Add Hawi LPASS macro codecs
This commit documents the compatibles for the RX, TX, and VA macro codecs in
the Qualcomm Hawi SoC. It details the specific clock constraints for each
macro compared to the SM8550 generation.
> diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
> index d8682ff2e82c5..2df72450d36f5 100644
> --- a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
> +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
[ ... ]
> @@ -142,6 +143,24 @@ allOf:
> - const: dcodec
> - const: fsgen
>
> + - if:
> + properties:
> + compatible:
> + contains:
> + enum:
> + - qcom,hawi-lpass-tx-macro
> + then:
> + properties:
> + clocks:
> + minItems: 4
> + maxItems: 4
> + clock-names:
> + items:
> + - const: mclk
> + - const: lpr
> + - const: dcodec
> + - const: fsgen
[Severity: Low]
Does this erroneously expect the lpr clock instead of the macro clock?
The commit message explicitly states that only the RX macro uses the lpr
clock instead of macro, which suggests the TX macro should still use the
macro clock.
If this is a copy-paste error and is corrected to macro, the clock
constraints here become identical to the SM8550 TX macro. Should this new
compatible be added to the prior generation's if block rather than
duplicating the entire block, as per the dt-bindings guidelines?
> diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
> index 683ebf702ba8a..7d56f9c360566 100644
> --- a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
> +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
[ ... ]
> @@ -185,6 +186,24 @@ allOf:
> - const: mclk
> - const: npl
>
> + - if:
> + properties:
> + compatible:
> + contains:
> + enum:
> + - qcom,hawi-lpass-va-macro
> + then:
> + properties:
> + clocks:
> + minItems: 4
> + maxItems: 4
> + clock-names:
> + items:
> + - const: mclk
> + - const: lpr
> + - const: dcodec
> + - const: heartbeatpulse
[Severity: Low]
Similar to the TX macro above, does this schema improperly require the
lpr clock?
The commit message indicates that the VA macro simply takes an additional
heartbeatpulse clock, which implies it should retain the macro clock
rather than switching to lpr.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261014-add_shikra_support_v5-v5-0-fb9f0667e613@oss.qualcomm.com?part=6
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-10-14 9:35 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-14 9:12 [PATCH v5 0/9] ASoC: qcom: Add shikra and Hawi LPASS macro support Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 1/9] ASoC: dt-bindings: qcom: Add Shikra RX and VA macro codecs Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 2/9] ASoC: qcom: lpass-macro-common: Add missing v2.9 version string Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 3/9] ASoC: qcom: lpass-rx-macro: Add shikra compatible Mohammad Rafi Shaik
2026-10-14 9:28 ` sashiko-bot
2026-10-14 9:12 ` [PATCH v5 4/9] ASoC: qcom: lpass-va-macro: " Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 5/9] ASoC: qcom: lpass-va-macro: Add SoundWire microphone support Mohammad Rafi Shaik
2026-10-14 9:30 ` sashiko-bot
2026-10-14 9:12 ` [PATCH v5 6/9] ASoC: dt-bindings: qcom: Add Hawi LPASS macro codecs Mohammad Rafi Shaik
2026-10-14 9:35 ` sashiko-bot
2026-10-14 9:12 ` [PATCH v5 7/9] ASoC: dt-bindings: qcom: Add Maili " Mohammad Rafi Shaik
2026-10-14 9:12 ` [PATCH v5 8/9] ASoC: qcom: lpass-tx-macro: Add support for Bolero v4.0 Mohammad Rafi Shaik
2026-10-14 9:35 ` sashiko-bot
2026-10-14 9:12 ` [PATCH v5 9/9] ASoC: qcom: lpass: Add support for LPASS codec v4.0 Mohammad Rafi Shaik
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.