Re: [PATCH v2 0/3] ASoC: qcom: qdsp6: Add MI2S clock control
From: Neil Armstrong
Date: Mon Jun 08 2026 - 04:24:10 EST
On 6/8/26 04:30, Mohammad Rafi Shaik wrote:
Add support for MI2S clock control within q6apm-lpass DAIs, including
handling of MCLK, BCLK, and ECLK via the DAI .set_sysclk callback.
Each MI2S port now retrieves its clock handles from the device tree,
allowing per-port clock configuration and proper enable/disable during
startup and shutdown.
On platforms such as Monaco and Lemans, third-party codecs are
hardware-wired to the SoC and do not always have an in-tree codec
driver to manage their clocks. For these designs, clock line
enablement must be driven from the platform side, and this
series provides the necessary support for that.
On QAIF-based platforms such as Shikra and Hawi, responsibility
for voting I2S MCLK and bit-clock has moved from the DSP to the
kernel. This series introduces the required device tree binding
support to represent and vote for these clocks from the kernel.
Enhances the sc8280xp machine driver to set the boards spacific
configurations.
This series depends on:
- https://lore.kernel.org/all/20260607-rubikpi-next-20260605-v1-3-7f334e16fea6@xxxxxxxxxxxxxxx/
---
Changes in v3:
- Added a detailed commit description to clearly explain the need for this change.
- Improved the machine driver based on Neil’s feedback.
- Link to v1: https://lore.kernel.org/all/20260309111300.2484262-1-mohammad.rafi.shaik@xxxxxxxxxxxxxxxx/
---
Mohammad Rafi Shaik (3):
ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
ASoC: qcom: q6apm-lpass-dais: Add MI2S clock control
ASoC: qcom: sc8280xp: ASoC: qcom: sc8280xp: enhance machine driver for
board-specific config
.../bindings/sound/qcom,q6apm-lpass-dais.yaml | 57 +++++
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 137 ++++++++++-
sound/soc/qcom/qdsp6/q6prm.h | 4 +
sound/soc/qcom/sc8280xp.c | 213 ++++++++++++++++--
4 files changed, 391 insertions(+), 20 deletions(-)
base-commit: 6e845bcb78c95af935094040bd4edc3c2b6dd784
prerequisite-patch-id: 2f1bd3efac328030dd8efe28fb95f84603868043
Tested-by: Neil Armstrong <neil.armstrong@xxxxxxxxxx> # on SM8650-HDK
With:
```
diff --git a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts
index eabc828c05b4..69327c4857e1 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts
@@ -218,6 +218,22 @@ platform {
sound-dai = <&q6apm>;
};
};
+
+ pri-mi2s-dai-link {
+ link-name = "HDMI Playback";
+
+ cpu {
+ sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+ };
+
+ codec {
+ sound-dai = <<9611_codec 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
};
vph_pwr: regulator-vph-pwr {
@@ -853,6 +869,7 @@ &i2c6 {
lt9611_codec: hdmi-bridge@2b {
compatible = "lontium,lt9611uxc";
reg = <0x2b>;
+ #sound-dai-cells = <1>;
interrupts-extended = <&tlmm 85 IRQ_TYPE_EDGE_FALLING>;
@@ -861,7 +878,10 @@ lt9611_codec: hdmi-bridge@2b {
vdd-supply = <<9611_1v2>;
vcc-supply = <<9611_3v3>;
- pinctrl-0 = <<9611_irq_pin>, <<9611_rst_pin>;
+ pinctrl-0 = <<9611_irq_pin>,
+ <<9611_rst_pin>,
+ <&i2s0_default_state>,
+ <&audio_mclk0_default_state>;
pinctrl-names = "default";
ports {
@@ -1072,6 +1092,19 @@ &pon_resin {
status = "okay";
};
+&q6apmbedai {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dai@16 {
+ reg = <PRIMARY_MI2S_RX>;
+ clocks = <&q6prmcc LPASS_CLK_ID_MCLK_1 LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+ clock-names = "mclk",
+ "bclk";
+ };
+};
+
&qup_i2c3_data_clk {
/* Use internal I2C pull-up */
bias-pull-up = <2200>;
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 1f3afc6d015c..7b34ff533e0d 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -320,18 +320,36 @@ static struct snd_soc_common sm8450_priv_data = {
.driver_name = "sm8450",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+ /* I2S Connected to HDMI */
+ .mi2s_mclk_enable = true,
+ .mi2s_bclk_enable = true,
+ .codec_dai_fmt = SND_SOC_DAIFMT_BC_FC |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_I2S,
};
static struct snd_soc_common sm8550_priv_data = {
.driver_name = "sm8550",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+ /* I2S Connected to HDMI */
+ .mi2s_mclk_enable = true,
+ .mi2s_bclk_enable = true,
+ .codec_dai_fmt = SND_SOC_DAIFMT_BC_FC |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_I2S,
};
static struct snd_soc_common sm8650_priv_data = {
.driver_name = "sm8650",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+ /* I2S Connected to HDMI */
+ .mi2s_mclk_enable = true,
+ .mi2s_bclk_enable = true,
+ .codec_dai_fmt = SND_SOC_DAIFMT_BC_FC |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_I2S,
};
static struct snd_soc_common sm8750_priv_data = {
```
Thanks,
Neil