* [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control
@ 2026-03-09 11:12 Mohammad Rafi Shaik
2026-03-09 11:12 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode Mohammad Rafi Shaik
` (4 more replies)
0 siblings, 5 replies; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-09 11:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel
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.
Enhances the sc8280xp machine driver to set the boards spacific
configurations, some of the boards like talos using third party
codec's which need's additional MCLK settings for audio to work.
Mohammad Rafi Shaik (4):
ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
ASoC: qcom: qdsp6: q6prm: add the missing LPASS MCLK clock IDs
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 | 41 +++-
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 137 ++++++++++++-
sound/soc/qcom/qdsp6/q6prm-clocks.c | 5 +
sound/soc/qcom/qdsp6/q6prm.h | 15 ++
sound/soc/qcom/sc8280xp.c | 180 ++++++++++++++++--
5 files changed, 357 insertions(+), 21 deletions(-)
base-commit: a0ae2a256046c0c5d3778d1a194ff2e171f16e5f
--
2.34.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
2026-03-09 11:12 [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control Mohammad Rafi Shaik
@ 2026-03-09 11:12 ` Mohammad Rafi Shaik
2026-03-09 19:55 ` Dmitry Baryshkov
2026-03-10 9:55 ` Krzysztof Kozlowski
2026-03-09 11:12 ` [PATCH v1 2/4] ASoC: qcom: qdsp6: q6prm: add the missing LPASS MCLK clock IDs Mohammad Rafi Shaik
` (3 subsequent siblings)
4 siblings, 2 replies; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-09 11:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel, Srinivas Kandagatla
Extend the qcom,q6apm-lpass-dais device tree binding to explicitly
describe Digital Audio Interface (DAI) child nodes.
Add #address-cells and #size-cells to allow representation of multiple
DAI instances as child nodes, and define a dai@<id> pattern to document
per-DAI properties such as the interface ID and associated clocks.
Qualcomm platforms like talos integrate third-party audio codecs or use
different external audio paths. These designs often require additional
configuration such as explicit MI2S MCLK settings for audio to work.
Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
.../bindings/sound/qcom,q6apm-lpass-dais.yaml | 41 ++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
index 2fb95544d..1d770cbcb 100644
--- a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
@@ -21,6 +21,34 @@ properties:
'#sound-dai-cells':
const: 1
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+# Digital Audio Interfaces
+patternProperties:
+ '^dai@[0-9]+$':
+ type: object
+ description:
+ Q6DSP Digital Audio Interfaces.
+
+ properties:
+ reg:
+ description:
+ Digital Audio Interface ID
+
+ clocks:
+ minItems: 1
+ maxItems: 3
+
+ clock-names:
+ minItems: 1
+ maxItems: 3
+
+ additionalProperties: false
+
required:
- compatible
- '#sound-dai-cells'
@@ -29,7 +57,18 @@ unevaluatedProperties: false
examples:
- |
- dais {
+ #include <dt-bindings/sound/qcom,q6afe.h>
+
+ bedais {
compatible = "qcom,q6apm-lpass-dais";
#sound-dai-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dai@16 {
+ reg = <PRIMARY_MI2S_RX>;
+ clocks = <&q6prmcc LPASS_CLK_ID_MCLK_1
+ LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+ clock-names = "mclk";
+ };
};
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v1 2/4] ASoC: qcom: qdsp6: q6prm: add the missing LPASS MCLK clock IDs
2026-03-09 11:12 [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control Mohammad Rafi Shaik
2026-03-09 11:12 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode Mohammad Rafi Shaik
@ 2026-03-09 11:12 ` Mohammad Rafi Shaik
2026-03-09 14:07 ` Srinivas Kandagatla
2026-03-09 11:12 ` [PATCH v1 3/4] ASoC: qcom: q6apm-lpass-dais: Add MI2S clock control Mohammad Rafi Shaik
` (2 subsequent siblings)
4 siblings, 1 reply; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-09 11:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel, Srinivas Kandagatla
Add the missing LPASS MCLK ids for the q6prm ADSP.
Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
sound/soc/qcom/qdsp6/q6prm-clocks.c | 5 +++++
sound/soc/qcom/qdsp6/q6prm.h | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/sound/soc/qcom/qdsp6/q6prm-clocks.c b/sound/soc/qcom/qdsp6/q6prm-clocks.c
index 4c574b48a..51b131fa9 100644
--- a/sound/soc/qcom/qdsp6/q6prm-clocks.c
+++ b/sound/soc/qcom/qdsp6/q6prm-clocks.c
@@ -42,6 +42,11 @@ static const struct q6dsp_clk_init q6prm_clks[] = {
Q6PRM_CLK(LPASS_CLK_ID_INT5_MI2S_IBIT),
Q6PRM_CLK(LPASS_CLK_ID_INT6_MI2S_IBIT),
Q6PRM_CLK(LPASS_CLK_ID_QUI_MI2S_OSR),
+ Q6PRM_CLK(LPASS_CLK_ID_MCLK_1),
+ Q6PRM_CLK(LPASS_CLK_ID_MCLK_2),
+ Q6PRM_CLK(LPASS_CLK_ID_MCLK_3),
+ Q6PRM_CLK(LPASS_CLK_ID_MCLK_4),
+ Q6PRM_CLK(LPASS_CLK_ID_MCLK_5),
Q6PRM_CLK(LPASS_CLK_ID_WSA_CORE_MCLK),
Q6PRM_CLK(LPASS_CLK_ID_WSA_CORE_NPL_MCLK),
Q6PRM_CLK(LPASS_CLK_ID_VA_CORE_MCLK),
diff --git a/sound/soc/qcom/qdsp6/q6prm.h b/sound/soc/qcom/qdsp6/q6prm.h
index a988a3208..8296370e3 100644
--- a/sound/soc/qcom/qdsp6/q6prm.h
+++ b/sound/soc/qcom/qdsp6/q6prm.h
@@ -52,6 +52,17 @@
/* Clock ID for QUINARY MI2S OSR CLK */
#define Q6PRM_LPASS_CLK_ID_QUI_MI2S_OSR 0x116
+/* Clock ID for MCLK1 */
+#define Q6PRM_LPASS_CLK_ID_MCLK_1 0x300
+/* Clock ID for MCLK2 */
+#define Q6PRM_LPASS_CLK_ID_MCLK_2 0x301
+/* Clock ID for MCLK3 */
+#define Q6PRM_LPASS_CLK_ID_MCLK_3 0x302
+/* Clock ID for MCLK4 */
+#define Q6PRM_LPASS_CLK_ID_MCLK_4 0x303
+/* Clock ID for MCLK5 */
+#define Q6PRM_LPASS_CLK_ID_MCLK_5 0x304
+
#define Q6PRM_LPASS_CLK_ID_WSA_CORE_MCLK 0x305
#define Q6PRM_LPASS_CLK_ID_WSA_CORE_NPL_MCLK 0x306
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v1 3/4] ASoC: qcom: q6apm-lpass-dais: Add MI2S clock control
2026-03-09 11:12 [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control Mohammad Rafi Shaik
2026-03-09 11:12 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode Mohammad Rafi Shaik
2026-03-09 11:12 ` [PATCH v1 2/4] ASoC: qcom: qdsp6: q6prm: add the missing LPASS MCLK clock IDs Mohammad Rafi Shaik
@ 2026-03-09 11:12 ` Mohammad Rafi Shaik
2026-03-11 18:25 ` kernel test robot
2026-03-09 11:13 ` [PATCH v1 4/4] ASoC: qcom: sc8280xp: ASoC: qcom: sc8280xp: enhance machine driver for board-specific config Mohammad Rafi Shaik
2026-03-10 14:02 ` [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control Neil Armstrong
4 siblings, 1 reply; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-09 11:12 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel, Srinivas Kandagatla
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.
Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 137 +++++++++++++++++++++++-
sound/soc/qcom/qdsp6/q6prm.h | 4 +
2 files changed, 139 insertions(+), 2 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
index 528756f13..1e739a474 100644
--- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
@@ -2,10 +2,12 @@
// Copyright (c) 2021, Linaro Limited
#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
+#include <linux/clk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/pcm.h>
@@ -15,13 +17,22 @@
#include "q6dsp-common.h"
#include "audioreach.h"
#include "q6apm.h"
+#include "q6prm.h"
#define AUDIOREACH_BE_PCM_BASE 16
+struct q6apm_dai_priv_data {
+ struct clk *mclk;
+ struct clk *bclk;
+ struct clk *eclk;
+ bool mclk_enabled, bclk_enabled, eclk_enabled;
+};
+
struct q6apm_lpass_dai_data {
struct q6apm_graph *graph[APM_PORT_MAX];
bool is_port_started[APM_PORT_MAX];
struct audioreach_module_config module_config[APM_PORT_MAX];
+ struct q6apm_dai_priv_data priv[APM_PORT_MAX];
};
static int q6dma_set_channel_map(struct snd_soc_dai *dai,
@@ -238,6 +249,70 @@ static int q6apm_lpass_dai_startup(struct snd_pcm_substream *substream, struct s
return 0;
}
+static int q6i2s_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ return q6apm_lpass_dai_startup(substream, dai);
+}
+
+static void q6i2s_lpass_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
+
+ if (dai_data->priv[dai->id].mclk_enabled) {
+ clk_disable_unprepare(dai_data->priv[dai->id].mclk);
+ dai_data->priv[dai->id].mclk_enabled = false;
+ }
+
+ if (dai_data->priv[dai->id].bclk_enabled) {
+ clk_disable_unprepare(dai_data->priv[dai->id].bclk);
+ dai_data->priv[dai->id].bclk_enabled = false;
+ }
+
+ if (dai_data->priv[dai->id].eclk_enabled) {
+ clk_disable_unprepare(dai_data->priv[dai->id].eclk);
+ dai_data->priv[dai->id].eclk_enabled = false;
+ }
+ q6apm_lpass_dai_shutdown(substream, dai);
+}
+
+static int q6i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir)
+{
+ struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
+ struct clk *sysclk;
+ bool *enabled;
+ int ret = 0;
+
+ switch (clk_id) {
+ case LPAIF_MI2S_MCLK:
+ sysclk = dai_data->priv[dai->id].mclk;
+ enabled = &dai_data->priv[dai->id].mclk_enabled;
+ break;
+ case LPAIF_MI2S_BCLK:
+ sysclk = dai_data->priv[dai->id].bclk;
+ enabled = &dai_data->priv[dai->id].bclk_enabled;
+ break;
+ case LPAIF_MI2S_ECLK:
+ sysclk = dai_data->priv[dai->id].eclk;
+ enabled = &dai_data->priv[dai->id].eclk_enabled;
+ break;
+ default:
+ break;
+ }
+
+ if (sysclk) {
+ clk_set_rate(sysclk, freq);
+ ret = clk_prepare_enable(sysclk);
+ if (ret) {
+ dev_err(dai->dev, "Error, Unable to prepare (%d) sysclk\n", clk_id);
+ return ret;
+ }
+
+ *enabled = true;
+ }
+
+ return ret;
+}
+
static int q6i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
@@ -258,11 +333,12 @@ static const struct snd_soc_dai_ops q6dma_ops = {
static const struct snd_soc_dai_ops q6i2s_ops = {
.prepare = q6apm_lpass_dai_prepare,
- .startup = q6apm_lpass_dai_startup,
- .shutdown = q6apm_lpass_dai_shutdown,
+ .startup = q6i2s_dai_startup,
+ .shutdown = q6i2s_lpass_dai_shutdown,
.set_channel_map = q6dma_set_channel_map,
.hw_params = q6dma_hw_params,
.set_fmt = q6i2s_set_fmt,
+ .set_sysclk = q6i2s_set_sysclk,
};
static const struct snd_soc_dai_ops q6hdmi_ops = {
@@ -280,6 +356,59 @@ static const struct snd_soc_component_driver q6apm_lpass_dai_component = {
.use_dai_pcm_id = true,
};
+static int of_q6apm_parse_dai_data(struct device *dev,
+ struct q6apm_lpass_dai_data *data)
+{
+ struct device_node *node;
+ int ret;
+
+ for_each_child_of_node(dev->of_node, node) {
+ struct q6apm_dai_priv_data *priv;
+ int id;
+
+ ret = of_property_read_u32(node, "reg", &id);
+ if (ret || id < 0 || id >= APM_PORT_MAX) {
+ dev_err(dev, "valid dai id not found:%d\n", ret);
+ continue;
+ }
+
+ switch (id) {
+ /* MI2S specific properties */
+ case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
+ case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
+ priv = &data->priv[id];
+ priv->mclk = of_clk_get_by_name(node, "mclk");
+ if (IS_ERR(priv->mclk)) {
+ if (PTR_ERR(priv->mclk) == -EPROBE_DEFER)
+ return dev_err_probe(dev, PTR_ERR(priv->mclk),
+ "unable to get mi2s mclk\n");
+ priv->mclk = NULL;
+ }
+
+ priv->bclk = of_clk_get_by_name(node, "bclk");
+ if (IS_ERR(priv->bclk)) {
+ if (PTR_ERR(priv->bclk) == -EPROBE_DEFER)
+ return dev_err_probe(dev, PTR_ERR(priv->bclk),
+ "unable to get mi2s bclk\n");
+ priv->bclk = NULL;
+ }
+
+ priv->eclk = of_clk_get_by_name(node, "eclk");
+ if (IS_ERR(priv->eclk)) {
+ if (PTR_ERR(priv->eclk) == -EPROBE_DEFER)
+ return dev_err_probe(dev, PTR_ERR(priv->eclk),
+ "unable to get mi2s eclk\n");
+ priv->eclk = NULL;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
static int q6apm_lpass_dai_dev_probe(struct platform_device *pdev)
{
struct q6dsp_audio_port_dai_driver_config cfg;
@@ -287,12 +416,16 @@ static int q6apm_lpass_dai_dev_probe(struct platform_device *pdev)
struct snd_soc_dai_driver *dais;
struct device *dev = &pdev->dev;
int num_dais;
+ int ret;
dai_data = devm_kzalloc(dev, sizeof(*dai_data), GFP_KERNEL);
if (!dai_data)
return -ENOMEM;
dev_set_drvdata(dev, dai_data);
+ ret = of_q6apm_parse_dai_data(dev, dai_data);
+ if (ret)
+ return ret;
memset(&cfg, 0, sizeof(cfg));
cfg.q6i2s_ops = &q6i2s_ops;
diff --git a/sound/soc/qcom/qdsp6/q6prm.h b/sound/soc/qcom/qdsp6/q6prm.h
index 8296370e3..a00d1eda1 100644
--- a/sound/soc/qcom/qdsp6/q6prm.h
+++ b/sound/soc/qcom/qdsp6/q6prm.h
@@ -3,6 +3,10 @@
#ifndef __Q6PRM_H__
#define __Q6PRM_H__
+#define LPAIF_MI2S_MCLK 1
+#define LPAIF_MI2S_BCLK 2
+#define LPAIF_MI2S_ECLK 3
+
/* Clock ID for Primary I2S IBIT */
#define Q6PRM_LPASS_CLK_ID_PRI_MI2S_IBIT 0x100
/* Clock ID for Primary I2S EBIT */
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v1 4/4] ASoC: qcom: sc8280xp: ASoC: qcom: sc8280xp: enhance machine driver for board-specific config
2026-03-09 11:12 [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control Mohammad Rafi Shaik
` (2 preceding siblings ...)
2026-03-09 11:12 ` [PATCH v1 3/4] ASoC: qcom: q6apm-lpass-dais: Add MI2S clock control Mohammad Rafi Shaik
@ 2026-03-09 11:13 ` Mohammad Rafi Shaik
2026-03-10 11:44 ` Neil Armstrong
2026-03-10 14:02 ` [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control Neil Armstrong
4 siblings, 1 reply; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-09 11:13 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel
The sc8280xp machine driver is currently written with a largely
SoC-centric view and assumes a uniform audio topology across all boards.
In practice, multiple products based on the same SoC use different board
designs and external audio components, which require board-specific
configuration to function correctly.
Several Qualcomm platforms like talos integrate third-party audio codecs
or use different external audio paths. These designs often require
additional configuration such as explicit MI2S MCLK settings for audio
to work.
This change enhances the sc8280xp machine driver to support board-specific
configuration such as allowing each board variant to provide its own DAPM
widgets and routes, reflecting the actual audio components and connectors
present and enabling MI2S MCLK programming for boards that use external
codecs requiring a stable master clock.
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
sound/soc/qcom/sc8280xp.c | 180 ++++++++++++++++++++++++++++++++++----
1 file changed, 162 insertions(+), 18 deletions(-)
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 7925aa3f6..c2e9323df 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -12,17 +12,62 @@
#include <sound/jack.h>
#include <linux/input-event-codes.h>
#include "qdsp6/q6afe.h"
+#include "qdsp6/q6apm.h"
+#include "qdsp6/q6prm.h"
#include "common.h"
#include "sdw.h"
+#define MCLK_FREQ 12288000
+#define MCLK_NATIVE_FREQ 11289600
+
+static struct snd_soc_dapm_widget sc8280xp_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
+ SND_SOC_DAPM_SPK("DP0 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP1 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP2 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP3 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP4 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP5 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP6 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP7 Jack", NULL),
+};
+
+struct snd_soc_common {
+ char *driver_name;
+ const struct snd_soc_dapm_widget *dapm_widgets;
+ int num_dapm_widgets;
+ const struct snd_soc_dapm_route *dapm_routes;
+ int num_dapm_routes;
+ bool mi2s_mclk_enable;
+};
+
struct sc8280xp_snd_data {
bool stream_prepared[AFE_PORT_MAX];
struct snd_soc_card *card;
struct snd_soc_jack jack;
struct snd_soc_jack dp_jack[8];
+ struct snd_soc_common *snd_soc_common_priv;
bool jack_setup;
};
+static inline int sc8280xp_get_mclk_feq(unsigned int rate)
+{
+ int freq = MCLK_FREQ;
+
+ switch (rate) {
+ case SNDRV_PCM_RATE_11025:
+ case SNDRV_PCM_RATE_44100:
+ case SNDRV_PCM_RATE_88200:
+ freq = MCLK_NATIVE_FREQ;
+ break;
+ default:
+ break;
+ }
+
+ return freq;
+}
+
static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
{
struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
@@ -32,10 +77,6 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
int dp_pcm_id = 0;
switch (cpu_dai->id) {
- case PRIMARY_MI2S_RX...QUATERNARY_MI2S_TX:
- case QUINARY_MI2S_RX...QUINARY_MI2S_TX:
- snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
- break;
case WSA_CODEC_DMA_RX_0:
case WSA_CODEC_DMA_RX_1:
/*
@@ -96,6 +137,31 @@ static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
return 0;
}
+static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+ int mclk_freq = sc8280xp_get_mclk_feq(params_rate(params));
+
+ switch (cpu_dai->id) {
+ case PRIMARY_MI2S_RX...QUATERNARY_MI2S_TX:
+ case QUINARY_MI2S_RX...QUINARY_MI2S_TX:
+ snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
+
+ if (data->snd_soc_common_priv->mi2s_mclk_enable)
+ snd_soc_dai_set_sysclk(cpu_dai,
+ LPAIF_MI2S_MCLK, mclk_freq,
+ SND_SOC_CLOCK_IN);
+ break;
+ default:
+ break;
+ };
+
+ return 0;
+}
+
static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
@@ -117,6 +183,7 @@ static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream)
static const struct snd_soc_ops sc8280xp_be_ops = {
.startup = qcom_snd_sdw_startup,
.shutdown = qcom_snd_sdw_shutdown,
+ .hw_params = sc8280xp_snd_hw_params,
.hw_free = sc8280xp_snd_hw_free,
.prepare = sc8280xp_snd_prepare,
};
@@ -145,37 +212,114 @@ static int sc8280xp_platform_probe(struct platform_device *pdev)
card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
if (!card)
return -ENOMEM;
- card->owner = THIS_MODULE;
+
/* Allocate the private data */
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
+ data->snd_soc_common_priv = (struct snd_soc_common *)of_device_get_match_data(dev);
+ if (!data->snd_soc_common_priv)
+ return -ENOMEM;
+
+ card->owner = THIS_MODULE;
card->dev = dev;
dev_set_drvdata(dev, card);
snd_soc_card_set_drvdata(card, data);
+ card->dapm_widgets = data->snd_soc_common_priv->dapm_widgets;
+ card->num_dapm_widgets = data->snd_soc_common_priv->num_dapm_widgets;
+ card->dapm_routes = data->snd_soc_common_priv->dapm_routes;
+ card->num_dapm_routes = data->snd_soc_common_priv->num_dapm_routes;
+
ret = qcom_snd_parse_of(card);
if (ret)
return ret;
- card->driver_name = of_device_get_match_data(dev);
+ card->driver_name = data->snd_soc_common_priv->driver_name;
sc8280xp_add_be_ops(card);
return devm_snd_soc_register_card(dev, card);
}
+static struct snd_soc_common kaanapali_priv_data = {
+ .driver_name = "kaanapali",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+};
+
+static struct snd_soc_common qcs9100_priv_data = {
+ .driver_name = "sa8775p",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+};
+
+static struct snd_soc_common qcs615_priv_data = {
+ .driver_name = "qcs615",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+ .mi2s_mclk_enable = true,
+};
+
+static struct snd_soc_common qcm6490_priv_data = {
+ .driver_name = "qcm6490",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+};
+
+static struct snd_soc_common qcs6490_priv_data = {
+ .driver_name = "qcs6490",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+};
+
+static struct snd_soc_common qcs8275_priv_data = {
+ .driver_name = "qcs8300",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+};
+
+static struct snd_soc_common sc8280xp_priv_data = {
+ .driver_name = "sc8280xp",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+};
+
+static struct snd_soc_common sm8450_priv_data = {
+ .driver_name = "sm8450",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+};
+
+static struct snd_soc_common sm8550_priv_data = {
+ .driver_name = "sm8550",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+};
+
+static struct snd_soc_common sm8650_priv_data = {
+ .driver_name = "sm8650",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+};
+
+static struct snd_soc_common sm8750_priv_data = {
+ .driver_name = "sm8750",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+};
+
static const struct of_device_id snd_sc8280xp_dt_match[] = {
- {.compatible = "qcom,kaanapali-sndcard", "kaanapali"},
- {.compatible = "qcom,qcm6490-idp-sndcard", "qcm6490"},
- {.compatible = "qcom,qcs615-sndcard", "qcs615"},
- {.compatible = "qcom,qcs6490-rb3gen2-sndcard", "qcs6490"},
- {.compatible = "qcom,qcs8275-sndcard", "qcs8300"},
- {.compatible = "qcom,qcs9075-sndcard", "sa8775p"},
- {.compatible = "qcom,qcs9100-sndcard", "sa8775p"},
- {.compatible = "qcom,sc8280xp-sndcard", "sc8280xp"},
- {.compatible = "qcom,sm8450-sndcard", "sm8450"},
- {.compatible = "qcom,sm8550-sndcard", "sm8550"},
- {.compatible = "qcom,sm8650-sndcard", "sm8650"},
- {.compatible = "qcom,sm8750-sndcard", "sm8750"},
+ {.compatible = "qcom,kaanapali-sndcard", .data = &kaanapali_priv_data},
+ {.compatible = "qcom,qcm6490-idp-sndcard", .data = &qcm6490_priv_data},
+ {.compatible = "qcom,qcs615-sndcard", .data = &qcs615_priv_data},
+ {.compatible = "qcom,qcs6490-rb3gen2-sndcard", .data = &qcs6490_priv_data},
+ {.compatible = "qcom,qcs8275-sndcard", .data = &qcs8275_priv_data},
+ {.compatible = "qcom,qcs9075-sndcard", .data = &qcs9100_priv_data},
+ {.compatible = "qcom,qcs9100-sndcard", .data = &qcs9100_priv_data},
+ {.compatible = "qcom,sc8280xp-sndcard", .data = &sc8280xp_priv_data},
+ {.compatible = "qcom,sm8450-sndcard", .data = &sm8450_priv_data},
+ {.compatible = "qcom,sm8550-sndcard", .data = &sm8550_priv_data},
+ {.compatible = "qcom,sm8650-sndcard", .data = &sm8650_priv_data},
+ {.compatible = "qcom,sm8750-sndcard", .data = &sm8750_priv_data},
{}
};
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v1 2/4] ASoC: qcom: qdsp6: q6prm: add the missing LPASS MCLK clock IDs
2026-03-09 11:12 ` [PATCH v1 2/4] ASoC: qcom: qdsp6: q6prm: add the missing LPASS MCLK clock IDs Mohammad Rafi Shaik
@ 2026-03-09 14:07 ` Srinivas Kandagatla
2026-03-10 9:30 ` Mohammad Rafi Shaik
0 siblings, 1 reply; 21+ messages in thread
From: Srinivas Kandagatla @ 2026-03-09 14:07 UTC (permalink / raw)
To: Mohammad Rafi Shaik, Srinivas Kandagatla, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jaroslav Kysela, Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel, Srinivas Kandagatla
On 3/9/26 11:12 AM, Mohammad Rafi Shaik wrote:
> Add the missing LPASS MCLK ids for the q6prm ADSP.
>
> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
> ---
This patch has already been submitted previously by Neil, Please pick
the patch from https://lkml.org/lkml/2025/10/6/828
--srini
> sound/soc/qcom/qdsp6/q6prm-clocks.c | 5 +++++
> sound/soc/qcom/qdsp6/q6prm.h | 11 +++++++++++
> 2 files changed, 16 insertions(+)
>
> diff --git a/sound/soc/qcom/qdsp6/q6prm-clocks.c b/sound/soc/qcom/qdsp6/q6prm-clocks.c
> index 4c574b48a..51b131fa9 100644
> --- a/sound/soc/qcom/qdsp6/q6prm-clocks.c
> +++ b/sound/soc/qcom/qdsp6/q6prm-clocks.c
> @@ -42,6 +42,11 @@ static const struct q6dsp_clk_init q6prm_clks[] = {
> Q6PRM_CLK(LPASS_CLK_ID_INT5_MI2S_IBIT),
> Q6PRM_CLK(LPASS_CLK_ID_INT6_MI2S_IBIT),
> Q6PRM_CLK(LPASS_CLK_ID_QUI_MI2S_OSR),
> + Q6PRM_CLK(LPASS_CLK_ID_MCLK_1),
> + Q6PRM_CLK(LPASS_CLK_ID_MCLK_2),
> + Q6PRM_CLK(LPASS_CLK_ID_MCLK_3),
> + Q6PRM_CLK(LPASS_CLK_ID_MCLK_4),
> + Q6PRM_CLK(LPASS_CLK_ID_MCLK_5),
> Q6PRM_CLK(LPASS_CLK_ID_WSA_CORE_MCLK),
> Q6PRM_CLK(LPASS_CLK_ID_WSA_CORE_NPL_MCLK),
> Q6PRM_CLK(LPASS_CLK_ID_VA_CORE_MCLK),
> diff --git a/sound/soc/qcom/qdsp6/q6prm.h b/sound/soc/qcom/qdsp6/q6prm.h
> index a988a3208..8296370e3 100644
> --- a/sound/soc/qcom/qdsp6/q6prm.h
> +++ b/sound/soc/qcom/qdsp6/q6prm.h
> @@ -52,6 +52,17 @@
> /* Clock ID for QUINARY MI2S OSR CLK */
> #define Q6PRM_LPASS_CLK_ID_QUI_MI2S_OSR 0x116
>
> +/* Clock ID for MCLK1 */
> +#define Q6PRM_LPASS_CLK_ID_MCLK_1 0x300
> +/* Clock ID for MCLK2 */
> +#define Q6PRM_LPASS_CLK_ID_MCLK_2 0x301
> +/* Clock ID for MCLK3 */
> +#define Q6PRM_LPASS_CLK_ID_MCLK_3 0x302
> +/* Clock ID for MCLK4 */
> +#define Q6PRM_LPASS_CLK_ID_MCLK_4 0x303
> +/* Clock ID for MCLK5 */
> +#define Q6PRM_LPASS_CLK_ID_MCLK_5 0x304
> +
> #define Q6PRM_LPASS_CLK_ID_WSA_CORE_MCLK 0x305
> #define Q6PRM_LPASS_CLK_ID_WSA_CORE_NPL_MCLK 0x306
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
2026-03-09 11:12 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode Mohammad Rafi Shaik
@ 2026-03-09 19:55 ` Dmitry Baryshkov
2026-03-10 9:41 ` Mohammad Rafi Shaik
2026-03-10 9:55 ` Krzysztof Kozlowski
1 sibling, 1 reply; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-03-09 19:55 UTC (permalink / raw)
To: Mohammad Rafi Shaik
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel, Srinivas Kandagatla
On Mon, Mar 09, 2026 at 04:42:57PM +0530, Mohammad Rafi Shaik wrote:
> Extend the qcom,q6apm-lpass-dais device tree binding to explicitly
> describe Digital Audio Interface (DAI) child nodes.
>
> Add #address-cells and #size-cells to allow representation of multiple
> DAI instances as child nodes, and define a dai@<id> pattern to document
> per-DAI properties such as the interface ID and associated clocks.
Is there a physical device being represented by this DAI subnode?
>
> Qualcomm platforms like talos integrate third-party audio codecs or use
> different external audio paths. These designs often require additional
> configuration such as explicit MI2S MCLK settings for audio to work.
>
> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
> ---
> .../bindings/sound/qcom,q6apm-lpass-dais.yaml | 41 ++++++++++++++++++-
> 1 file changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
> index 2fb95544d..1d770cbcb 100644
> --- a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
> +++ b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
> @@ -21,6 +21,34 @@ properties:
> '#sound-dai-cells':
> const: 1
>
> + '#address-cells':
> + const: 1
> +
> + '#size-cells':
> + const: 0
> +
> +# Digital Audio Interfaces
> +patternProperties:
> + '^dai@[0-9]+$':
> + type: object
> + description:
> + Q6DSP Digital Audio Interfaces.
> +
> + properties:
> + reg:
> + description:
> + Digital Audio Interface ID
> +
> + clocks:
> + minItems: 1
> + maxItems: 3
> +
> + clock-names:
> + minItems: 1
> + maxItems: 3
> +
> + additionalProperties: false
> +
> required:
> - compatible
> - '#sound-dai-cells'
> @@ -29,7 +57,18 @@ unevaluatedProperties: false
>
> examples:
> - |
> - dais {
> + #include <dt-bindings/sound/qcom,q6afe.h>
> +
> + bedais {
> compatible = "qcom,q6apm-lpass-dais";
> #sound-dai-cells = <1>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + dai@16 {
What is @16 in this case? What kind of address or ID correspondings to
the PRIMARY_MI2S_RX?
> + reg = <PRIMARY_MI2S_RX>;
> + clocks = <&q6prmcc LPASS_CLK_ID_MCLK_1
> + LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
> + clock-names = "mclk";
> + };
> };
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 2/4] ASoC: qcom: qdsp6: q6prm: add the missing LPASS MCLK clock IDs
2026-03-09 14:07 ` Srinivas Kandagatla
@ 2026-03-10 9:30 ` Mohammad Rafi Shaik
0 siblings, 0 replies; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-10 9:30 UTC (permalink / raw)
To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel, Srinivas Kandagatla
On 3/9/2026 7:37 PM, Srinivas Kandagatla wrote:
>
>
> On 3/9/26 11:12 AM, Mohammad Rafi Shaik wrote:
>> Add the missing LPASS MCLK ids for the q6prm ADSP.
>>
>> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>> ---
>
>
> This patch has already been submitted previously by Neil, Please pick
> the patch from https://lkml.org/lkml/2025/10/6/828
>
ACK,
sure will pick Neil patch and replace with current patch.
Best Regards,
Rafi.
>
> --srini
>> sound/soc/qcom/qdsp6/q6prm-clocks.c | 5 +++++
>> sound/soc/qcom/qdsp6/q6prm.h | 11 +++++++++++
>> 2 files changed, 16 insertions(+)
>>
>> diff --git a/sound/soc/qcom/qdsp6/q6prm-clocks.c b/sound/soc/qcom/qdsp6/q6prm-clocks.c
>> index 4c574b48a..51b131fa9 100644
>> --- a/sound/soc/qcom/qdsp6/q6prm-clocks.c
>> +++ b/sound/soc/qcom/qdsp6/q6prm-clocks.c
>> @@ -42,6 +42,11 @@ static const struct q6dsp_clk_init q6prm_clks[] = {
>> Q6PRM_CLK(LPASS_CLK_ID_INT5_MI2S_IBIT),
>> Q6PRM_CLK(LPASS_CLK_ID_INT6_MI2S_IBIT),
>> Q6PRM_CLK(LPASS_CLK_ID_QUI_MI2S_OSR),
>> + Q6PRM_CLK(LPASS_CLK_ID_MCLK_1),
>> + Q6PRM_CLK(LPASS_CLK_ID_MCLK_2),
>> + Q6PRM_CLK(LPASS_CLK_ID_MCLK_3),
>> + Q6PRM_CLK(LPASS_CLK_ID_MCLK_4),
>> + Q6PRM_CLK(LPASS_CLK_ID_MCLK_5),
>> Q6PRM_CLK(LPASS_CLK_ID_WSA_CORE_MCLK),
>> Q6PRM_CLK(LPASS_CLK_ID_WSA_CORE_NPL_MCLK),
>> Q6PRM_CLK(LPASS_CLK_ID_VA_CORE_MCLK),
>> diff --git a/sound/soc/qcom/qdsp6/q6prm.h b/sound/soc/qcom/qdsp6/q6prm.h
>> index a988a3208..8296370e3 100644
>> --- a/sound/soc/qcom/qdsp6/q6prm.h
>> +++ b/sound/soc/qcom/qdsp6/q6prm.h
>> @@ -52,6 +52,17 @@
>> /* Clock ID for QUINARY MI2S OSR CLK */
>> #define Q6PRM_LPASS_CLK_ID_QUI_MI2S_OSR 0x116
>>
>> +/* Clock ID for MCLK1 */
>> +#define Q6PRM_LPASS_CLK_ID_MCLK_1 0x300
>> +/* Clock ID for MCLK2 */
>> +#define Q6PRM_LPASS_CLK_ID_MCLK_2 0x301
>> +/* Clock ID for MCLK3 */
>> +#define Q6PRM_LPASS_CLK_ID_MCLK_3 0x302
>> +/* Clock ID for MCLK4 */
>> +#define Q6PRM_LPASS_CLK_ID_MCLK_4 0x303
>> +/* Clock ID for MCLK5 */
>> +#define Q6PRM_LPASS_CLK_ID_MCLK_5 0x304
>> +
>> #define Q6PRM_LPASS_CLK_ID_WSA_CORE_MCLK 0x305
>> #define Q6PRM_LPASS_CLK_ID_WSA_CORE_NPL_MCLK 0x306
>>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
2026-03-09 19:55 ` Dmitry Baryshkov
@ 2026-03-10 9:41 ` Mohammad Rafi Shaik
0 siblings, 0 replies; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-10 9:41 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel, Srinivas Kandagatla
On 3/10/2026 1:25 AM, Dmitry Baryshkov wrote:
> On Mon, Mar 09, 2026 at 04:42:57PM +0530, Mohammad Rafi Shaik wrote:
>> Extend the qcom,q6apm-lpass-dais device tree binding to explicitly
>> describe Digital Audio Interface (DAI) child nodes.
>>
>> Add #address-cells and #size-cells to allow representation of multiple
>> DAI instances as child nodes, and define a dai@<id> pattern to document
>> per-DAI properties such as the interface ID and associated clocks.
>
> Is there a physical device being represented by this DAI subnode?
>
No, the dai@<id> subnode does not represent a separate physical device.
It models an individual LPASS/Q6DSP DAI hw interface instance (for
example, primary mi2s, secondary mi2s, etc.), so that per‑DAI resources
and configuration can be described.
Per‑port description is required because different DAIs may need
different clock inputs (MCLK, BCLK, ECLK) and can be wired differently
depending on the board design. By representing each DAI instance as a
child node, the relevant clocks can be bound to the specific DAI port
that uses them.
Thus, the subnode is used to describe the resources and configuration of
a DAI hw instance, not a standalone physical device.
>>
>> Qualcomm platforms like talos integrate third-party audio codecs or use
>> different external audio paths. These designs often require additional
>> configuration such as explicit MI2S MCLK settings for audio to work.
>>
>> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>> ---
>> .../bindings/sound/qcom,q6apm-lpass-dais.yaml | 41 ++++++++++++++++++-
>> 1 file changed, 40 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>> index 2fb95544d..1d770cbcb 100644
>> --- a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>> +++ b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>> @@ -21,6 +21,34 @@ properties:
>> '#sound-dai-cells':
>> const: 1
>>
>> + '#address-cells':
>> + const: 1
>> +
>> + '#size-cells':
>> + const: 0
>> +
>> +# Digital Audio Interfaces
>> +patternProperties:
>> + '^dai@[0-9]+$':
>> + type: object
>> + description:
>> + Q6DSP Digital Audio Interfaces.
>> +
>> + properties:
>> + reg:
>> + description:
>> + Digital Audio Interface ID
>> +
>> + clocks:
>> + minItems: 1
>> + maxItems: 3
>> +
>> + clock-names:
>> + minItems: 1
>> + maxItems: 3
>> +
>> + additionalProperties: false
>> +
>> required:
>> - compatible
>> - '#sound-dai-cells'
>> @@ -29,7 +57,18 @@ unevaluatedProperties: false
>>
>> examples:
>> - |
>> - dais {
>> + #include <dt-bindings/sound/qcom,q6afe.h>
>> +
>> + bedais {
>> compatible = "qcom,q6apm-lpass-dais";
>> #sound-dai-cells = <1>;
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + dai@16 {
>
> What is @16 in this case? What kind of address or ID correspondings to
> the PRIMARY_MI2S_RX?
>
yes, The @16 value corresponds to the LPASS/Q6DSP DAI ID for
PRIMARY_MI2S_RX.
(defined in :
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git/tree/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h)
Best Regards,
Rafi.
>> + reg = <PRIMARY_MI2S_RX>;
>> + clocks = <&q6prmcc LPASS_CLK_ID_MCLK_1
>> + LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
>> + clock-names = "mclk";
>> + };
>> };
>> --
>> 2.34.1
>>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
2026-03-09 11:12 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode Mohammad Rafi Shaik
2026-03-09 19:55 ` Dmitry Baryshkov
@ 2026-03-10 9:55 ` Krzysztof Kozlowski
2026-03-17 5:27 ` Mohammad Rafi Shaik
1 sibling, 1 reply; 21+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-10 9:55 UTC (permalink / raw)
To: Mohammad Rafi Shaik
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
linux-sound, linux-arm-msm, devicetree, linux-kernel,
Srinivas Kandagatla
On Mon, Mar 09, 2026 at 04:42:57PM +0530, Mohammad Rafi Shaik wrote:
> Extend the qcom,q6apm-lpass-dais device tree binding to explicitly
> describe Digital Audio Interface (DAI) child nodes.
>
> Add #address-cells and #size-cells to allow representation of multiple
> DAI instances as child nodes, and define a dai@<id> pattern to document
> per-DAI properties such as the interface ID and associated clocks.
>
> Qualcomm platforms like talos integrate third-party audio codecs or use
> different external audio paths. These designs often require additional
> configuration such as explicit MI2S MCLK settings for audio to work.
>
> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
> ---
> .../bindings/sound/qcom,q6apm-lpass-dais.yaml | 41 ++++++++++++++++++-
> 1 file changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
> index 2fb95544d..1d770cbcb 100644
> --- a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
> +++ b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
> @@ -21,6 +21,34 @@ properties:
> '#sound-dai-cells':
> const: 1
>
> + '#address-cells':
> + const: 1
> +
> + '#size-cells':
> + const: 0
> +
> +# Digital Audio Interfaces
> +patternProperties:
> + '^dai@[0-9]+$':
> + type: object
> + description:
> + Q6DSP Digital Audio Interfaces.
> +
> + properties:
> + reg:
> + description:
> + Digital Audio Interface ID
> +
> + clocks:
> + minItems: 1
> + maxItems: 3
> +
> + clock-names:
> + minItems: 1
> + maxItems: 3
No, this is just way too generic. There is no such syntax in the kernel
and this should stop you right there. You are not allowed to add your
own style.
I don't think DAI is here a separate device needing its own resources
expressed in DT. This is still part of ADSP so you just described in DT
internal routing between two services on ADSP.
> +
> + additionalProperties: false
> +
> required:
> - compatible
> - '#sound-dai-cells'
> @@ -29,7 +57,18 @@ unevaluatedProperties: false
>
> examples:
> - |
> - dais {
Why?
> + #include <dt-bindings/sound/qcom,q6afe.h>
> +
> + bedais {
> compatible = "qcom,q6apm-lpass-dais";
> #sound-dai-cells = <1>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + dai@16 {
> + reg = <PRIMARY_MI2S_RX>;
> + clocks = <&q6prmcc LPASS_CLK_ID_MCLK_1
> + LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
So one entry, not three.
> + clock-names = "mclk";
> + };
> };
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 4/4] ASoC: qcom: sc8280xp: ASoC: qcom: sc8280xp: enhance machine driver for board-specific config
2026-03-09 11:13 ` [PATCH v1 4/4] ASoC: qcom: sc8280xp: ASoC: qcom: sc8280xp: enhance machine driver for board-specific config Mohammad Rafi Shaik
@ 2026-03-10 11:44 ` Neil Armstrong
2026-03-17 5:35 ` Mohammad Rafi Shaik
0 siblings, 1 reply; 21+ messages in thread
From: Neil Armstrong @ 2026-03-10 11:44 UTC (permalink / raw)
To: Mohammad Rafi Shaik, Srinivas Kandagatla, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jaroslav Kysela, Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel
Hi,
On 3/9/26 12:13, Mohammad Rafi Shaik wrote:
> The sc8280xp machine driver is currently written with a largely
> SoC-centric view and assumes a uniform audio topology across all boards.
> In practice, multiple products based on the same SoC use different board
> designs and external audio components, which require board-specific
> configuration to function correctly.
>
> Several Qualcomm platforms like talos integrate third-party audio codecs
> or use different external audio paths. These designs often require
> additional configuration such as explicit MI2S MCLK settings for audio
> to work.
>
> This change enhances the sc8280xp machine driver to support board-specific
> configuration such as allowing each board variant to provide its own DAPM
> widgets and routes, reflecting the actual audio components and connectors
> present and enabling MI2S MCLK programming for boards that use external
> codecs requiring a stable master clock.
>
> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
> ---
> sound/soc/qcom/sc8280xp.c | 180 ++++++++++++++++++++++++++++++++++----
> 1 file changed, 162 insertions(+), 18 deletions(-)
>
> diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
> index 7925aa3f6..c2e9323df 100644
> --- a/sound/soc/qcom/sc8280xp.c
> +++ b/sound/soc/qcom/sc8280xp.c
> @@ -12,17 +12,62 @@
> #include <sound/jack.h>
> #include <linux/input-event-codes.h>
> #include "qdsp6/q6afe.h"
> +#include "qdsp6/q6apm.h"
> +#include "qdsp6/q6prm.h"
> #include "common.h"
> #include "sdw.h"
>
> +#define MCLK_FREQ 12288000
> +#define MCLK_NATIVE_FREQ 11289600
Where does thos values come from ?
MCLK_FREQ 12288000 == 48000 * 256
MCLK_NATIVE_FREQ 11289600 == 44100 * 256
This is highly specific to a board, the sdm845.c uses:
#define DEFAULT_MCLK_RATE 24576000 == 48000 * 2 * 256
#define MI2S_BCLK_RATE 1536000 == 48000 * 2 * 16
And those are the values we use to output sound on HDMI on all HDK and Dragonboards.
I guess this should be configurable somewhere !
> +
> +static struct snd_soc_dapm_widget sc8280xp_dapm_widgets[] = {
> + SND_SOC_DAPM_HP("Headphone Jack", NULL),
> + SND_SOC_DAPM_MIC("Mic Jack", NULL),
> + SND_SOC_DAPM_SPK("DP0 Jack", NULL),
> + SND_SOC_DAPM_SPK("DP1 Jack", NULL),
> + SND_SOC_DAPM_SPK("DP2 Jack", NULL),
> + SND_SOC_DAPM_SPK("DP3 Jack", NULL),
> + SND_SOC_DAPM_SPK("DP4 Jack", NULL),
> + SND_SOC_DAPM_SPK("DP5 Jack", NULL),
> + SND_SOC_DAPM_SPK("DP6 Jack", NULL),
> + SND_SOC_DAPM_SPK("DP7 Jack", NULL),
> +};
> +
> +struct snd_soc_common {
> + char *driver_name;
> + const struct snd_soc_dapm_widget *dapm_widgets;
> + int num_dapm_widgets;
> + const struct snd_soc_dapm_route *dapm_routes;
> + int num_dapm_routes;
> + bool mi2s_mclk_enable;
> +};
> +
> struct sc8280xp_snd_data {
> bool stream_prepared[AFE_PORT_MAX];
> struct snd_soc_card *card;
> struct snd_soc_jack jack;
> struct snd_soc_jack dp_jack[8];
> + struct snd_soc_common *snd_soc_common_priv;
> bool jack_setup;
> };
>
> +static inline int sc8280xp_get_mclk_feq(unsigned int rate)
_freq
> +{
> + int freq = MCLK_FREQ;
> +
> + switch (rate) {
> + case SNDRV_PCM_RATE_11025:
> + case SNDRV_PCM_RATE_44100:
> + case SNDRV_PCM_RATE_88200:
> + freq = MCLK_NATIVE_FREQ;
> + break;
> + default:
> + break;
> + }
> +
> + return freq;
> +}
> +
> static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
> {
> struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
> @@ -32,10 +77,6 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
> int dp_pcm_id = 0;
>
> switch (cpu_dai->id) {
> - case PRIMARY_MI2S_RX...QUATERNARY_MI2S_TX:
> - case QUINARY_MI2S_RX...QUINARY_MI2S_TX:
> - snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
> - break;
> case WSA_CODEC_DMA_RX_0:
> case WSA_CODEC_DMA_RX_1:
> /*
> @@ -96,6 +137,31 @@ static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
> return 0;
> }
>
> +static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *params)
> +{
> + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
> + struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
> + int mclk_freq = sc8280xp_get_mclk_feq(params_rate(params));
> +
> + switch (cpu_dai->id) {
> + case PRIMARY_MI2S_RX...QUATERNARY_MI2S_TX:
> + case QUINARY_MI2S_RX...QUINARY_MI2S_TX:
> + snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
> +
> + if (data->snd_soc_common_priv->mi2s_mclk_enable)
> + snd_soc_dai_set_sysclk(cpu_dai,
> + LPAIF_MI2S_MCLK, mclk_freq,
> + SND_SOC_CLOCK_IN);
> + break;
> + default:
> + break;
> + };
> +
> + return 0;
> +}
> +
> static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream)
> {
> struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> @@ -117,6 +183,7 @@ static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream)
> static const struct snd_soc_ops sc8280xp_be_ops = {
> .startup = qcom_snd_sdw_startup,
> .shutdown = qcom_snd_sdw_shutdown,
> + .hw_params = sc8280xp_snd_hw_params,
> .hw_free = sc8280xp_snd_hw_free,
> .prepare = sc8280xp_snd_prepare,
> };
> @@ -145,37 +212,114 @@ static int sc8280xp_platform_probe(struct platform_device *pdev)
> card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
> if (!card)
> return -ENOMEM;
> - card->owner = THIS_MODULE;
> +
> /* Allocate the private data */
> data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> if (!data)
> return -ENOMEM;
>
> + data->snd_soc_common_priv = (struct snd_soc_common *)of_device_get_match_data(dev);
> + if (!data->snd_soc_common_priv)
> + return -ENOMEM;
> +
> + card->owner = THIS_MODULE;
> card->dev = dev;
> dev_set_drvdata(dev, card);
> snd_soc_card_set_drvdata(card, data);
> + card->dapm_widgets = data->snd_soc_common_priv->dapm_widgets;
> + card->num_dapm_widgets = data->snd_soc_common_priv->num_dapm_widgets;
> + card->dapm_routes = data->snd_soc_common_priv->dapm_routes;
> + card->num_dapm_routes = data->snd_soc_common_priv->num_dapm_routes;
> +
> ret = qcom_snd_parse_of(card);
> if (ret)
> return ret;
>
> - card->driver_name = of_device_get_match_data(dev);
> + card->driver_name = data->snd_soc_common_priv->driver_name;
> sc8280xp_add_be_ops(card);
> return devm_snd_soc_register_card(dev, card);
> }
>
> +static struct snd_soc_common kaanapali_priv_data = {
> + .driver_name = "kaanapali",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> +};
> +
> +static struct snd_soc_common qcs9100_priv_data = {
> + .driver_name = "sa8775p",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> +};
> +
> +static struct snd_soc_common qcs615_priv_data = {
> + .driver_name = "qcs615",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> + .mi2s_mclk_enable = true,
> +};
> +
> +static struct snd_soc_common qcm6490_priv_data = {
> + .driver_name = "qcm6490",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> +};
> +
> +static struct snd_soc_common qcs6490_priv_data = {
> + .driver_name = "qcs6490",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> +};
> +
> +static struct snd_soc_common qcs8275_priv_data = {
> + .driver_name = "qcs8300",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> +};
> +
> +static struct snd_soc_common sc8280xp_priv_data = {
> + .driver_name = "sc8280xp",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> +};
> +
> +static struct snd_soc_common sm8450_priv_data = {
> + .driver_name = "sm8450",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> +};
> +
> +static struct snd_soc_common sm8550_priv_data = {
> + .driver_name = "sm8550",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> +};
> +
> +static struct snd_soc_common sm8650_priv_data = {
> + .driver_name = "sm8650",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> +};
> +
> +static struct snd_soc_common sm8750_priv_data = {
> + .driver_name = "sm8750",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> +};
> +
> static const struct of_device_id snd_sc8280xp_dt_match[] = {
> - {.compatible = "qcom,kaanapali-sndcard", "kaanapali"},
> - {.compatible = "qcom,qcm6490-idp-sndcard", "qcm6490"},
> - {.compatible = "qcom,qcs615-sndcard", "qcs615"},
> - {.compatible = "qcom,qcs6490-rb3gen2-sndcard", "qcs6490"},
> - {.compatible = "qcom,qcs8275-sndcard", "qcs8300"},
> - {.compatible = "qcom,qcs9075-sndcard", "sa8775p"},
> - {.compatible = "qcom,qcs9100-sndcard", "sa8775p"},
> - {.compatible = "qcom,sc8280xp-sndcard", "sc8280xp"},
> - {.compatible = "qcom,sm8450-sndcard", "sm8450"},
> - {.compatible = "qcom,sm8550-sndcard", "sm8550"},
> - {.compatible = "qcom,sm8650-sndcard", "sm8650"},
> - {.compatible = "qcom,sm8750-sndcard", "sm8750"},
> + {.compatible = "qcom,kaanapali-sndcard", .data = &kaanapali_priv_data},
> + {.compatible = "qcom,qcm6490-idp-sndcard", .data = &qcm6490_priv_data},
> + {.compatible = "qcom,qcs615-sndcard", .data = &qcs615_priv_data},
> + {.compatible = "qcom,qcs6490-rb3gen2-sndcard", .data = &qcs6490_priv_data},
> + {.compatible = "qcom,qcs8275-sndcard", .data = &qcs8275_priv_data},
> + {.compatible = "qcom,qcs9075-sndcard", .data = &qcs9100_priv_data},
> + {.compatible = "qcom,qcs9100-sndcard", .data = &qcs9100_priv_data},
> + {.compatible = "qcom,sc8280xp-sndcard", .data = &sc8280xp_priv_data},
> + {.compatible = "qcom,sm8450-sndcard", .data = &sm8450_priv_data},
> + {.compatible = "qcom,sm8550-sndcard", .data = &sm8550_priv_data},
> + {.compatible = "qcom,sm8650-sndcard", .data = &sm8650_priv_data},
> + {.compatible = "qcom,sm8750-sndcard", .data = &sm8750_priv_data},
> {}
> };
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control
2026-03-09 11:12 [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control Mohammad Rafi Shaik
` (3 preceding siblings ...)
2026-03-09 11:13 ` [PATCH v1 4/4] ASoC: qcom: sc8280xp: ASoC: qcom: sc8280xp: enhance machine driver for board-specific config Mohammad Rafi Shaik
@ 2026-03-10 14:02 ` Neil Armstrong
2026-03-17 5:48 ` Mohammad Rafi Shaik
4 siblings, 1 reply; 21+ messages in thread
From: Neil Armstrong @ 2026-03-10 14:02 UTC (permalink / raw)
To: Mohammad Rafi Shaik, Srinivas Kandagatla, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jaroslav Kysela, Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel
On 3/9/26 12:12, 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.
>
> Enhances the sc8280xp machine driver to set the boards spacific
> configurations, some of the boards like talos using third party
> codec's which need's additional MCLK settings for audio to work.
>
> Mohammad Rafi Shaik (4):
> ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
> ASoC: qcom: qdsp6: q6prm: add the missing LPASS MCLK clock IDs
> 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 | 41 +++-
> sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 137 ++++++++++++-
> sound/soc/qcom/qdsp6/q6prm-clocks.c | 5 +
> sound/soc/qcom/qdsp6/q6prm.h | 15 ++
> sound/soc/qcom/sc8280xp.c | 180 ++++++++++++++++--
> 5 files changed, 357 insertions(+), 21 deletions(-)
>
>
> base-commit: a0ae2a256046c0c5d3778d1a194ff2e171f16e5f
I'm not sure about the overall architecture, but I managed to make the I2S HDMI audio
work on the SM8650 HDK with:
==============================><=======================================
diff --git a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts
index 5bf1af3308ce..8316e17dc76b 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 {
@@ -1056,6 +1076,17 @@ &pon_resin {
status = "okay";
};
+&q6apmbedai {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ 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/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
index f8e1950a74ac..9818fbd8094e 100644
--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -6237,6 +6237,46 @@ wake-pins {
};
};
+ audio_mclk0_default_state: audio-mclk0-default-state {
+ pins = "gpio125";
+ function = "audio_ext_mclk0";
+ drive-strength = <8>;
+ bias-disable;
+ output-high;
+ };
+
+ i2s0_default_state: i2s0-default-state {
+ sck-pins {
+ pins = "gpio126";
+ function = "i2s0_sck";
+ drive-strength = <8>;
+ bias-disable;
+ output-high;
+ };
+
+ data0-pins {
+ pins = "gpio127";
+ function = "i2s0_data0";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ data1-pins {
+ pins = "gpio128";
+ function = "i2s0_data1";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ ws-pins {
+ pins = "gpio129";
+ function = "i2s0_ws";
+ drive-strength = <8>;
+ bias-disable;
+ output-high;
+ };
+ };
+
qup_i2c0_data_clk: qup-i2c0-data-clk-state {
/* SDA, SCL */
pins = "gpio32", "gpio33";
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 7aa87e8a6cc5..c2bd5f2a696d 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -17,8 +17,12 @@
#include "common.h"
#include "sdw.h"
-#define MCLK_FREQ 12288000
-#define MCLK_NATIVE_FREQ 11289600
+#define I2S_MCLKFS 256
+#define I2S_SLOTSIZE 16
+#define I2S_MCLK_RATE(rate, channels) \
+ ((rate) * (channels) * I2S_MCLKFS)
+#define I2S_BIT_RATE(rate, channels) \
+ ((rate) * (channels) * I2S_SLOTSIZE)
static struct snd_soc_dapm_widget sc8280xp_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
@@ -40,6 +44,7 @@ struct snd_soc_common {
const struct snd_soc_dapm_route *dapm_routes;
int num_dapm_routes;
bool mi2s_mclk_enable;
+ bool mi2s_bclk_enable;
};
struct sc8280xp_snd_data {
@@ -51,21 +56,22 @@ struct sc8280xp_snd_data {
bool jack_setup;
};
-static inline int sc8280xp_get_mclk_feq(unsigned int rate)
+static inline int sc8280xp_get_mclk_freq(struct snd_pcm_hw_params *params)
{
- int freq = MCLK_FREQ;
-
switch (rate) {
case SNDRV_PCM_RATE_11025:
case SNDRV_PCM_RATE_44100:
case SNDRV_PCM_RATE_88200:
- freq = MCLK_NATIVE_FREQ;
+ return I2S_MCLK_RATE(44100, params_channels(params));
break;
default:
- break;
+ return I2S_MCLK_RATE(params_rate(params), params_channels(params));
}
+}
- return freq;
+static inline int sc8280xp_get_bclk_freq(struct snd_pcm_hw_params *params)
+{
+ return I2S_BIT_RATE(params_rate(params), params_channels(params));
}
static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
@@ -142,8 +148,13 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
- int mclk_freq = sc8280xp_get_mclk_feq(params_rate(params));
+ int mclk_freq = sc8280xp_get_mclk_freq(params);
+ int bclk_freq = sc8280xp_get_bclk_freq(params);
+ unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_I2S;
switch (cpu_dai->id) {
case PRIMARY_MI2S_RX...QUATERNARY_MI2S_TX:
@@ -154,6 +165,15 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
snd_soc_dai_set_sysclk(cpu_dai,
LPAIF_MI2S_MCLK, mclk_freq,
SND_SOC_CLOCK_IN);
+
+ if (data->snd_soc_common_priv->mi2s_bclk_enable) {
+ snd_soc_dai_set_sysclk(cpu_dai,
+ LPAIF_MI2S_BCLK, bclk_freq,
+ SND_SOC_CLOCK_IN);
+ snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_BC_FC |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_I2S);
+ }
break;
default:
break;
@@ -288,6 +308,7 @@ static struct snd_soc_common sm8450_priv_data = {
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
.mi2s_mclk_enable = true,
+ .mi2s_bclk_enable = true,
};
static struct snd_soc_common sm8550_priv_data = {
@@ -295,6 +316,7 @@ static struct snd_soc_common sm8550_priv_data = {
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
.mi2s_mclk_enable = true,
+ .mi2s_bclk_enable = true,
};
static struct snd_soc_common sm8650_priv_data = {
@@ -302,6 +324,7 @@ static struct snd_soc_common sm8650_priv_data = {
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
.mi2s_mclk_enable = true,
+ .mi2s_bclk_enable = true,
};
static struct snd_soc_common sm8750_priv_data = {
==============================><========================================
Thanks,
Neil
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v1 3/4] ASoC: qcom: q6apm-lpass-dais: Add MI2S clock control
2026-03-09 11:12 ` [PATCH v1 3/4] ASoC: qcom: q6apm-lpass-dais: Add MI2S clock control Mohammad Rafi Shaik
@ 2026-03-11 18:25 ` kernel test robot
0 siblings, 0 replies; 21+ messages in thread
From: kernel test robot @ 2026-03-11 18:25 UTC (permalink / raw)
To: Mohammad Rafi Shaik, Srinivas Kandagatla, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jaroslav Kysela, Takashi Iwai
Cc: llvm, oe-kbuild-all, linux-sound, linux-arm-msm, devicetree,
linux-kernel
Hi Mohammad,
kernel test robot noticed the following build warnings:
[auto build test WARNING on a0ae2a256046c0c5d3778d1a194ff2e171f16e5f]
url: https://github.com/intel-lab-lkp/linux/commits/Mohammad-Rafi-Shaik/ASoC-dt-bindings-qcom-q6apm-lpass-dais-Document-DAI-subnode/20260309-191956
base: a0ae2a256046c0c5d3778d1a194ff2e171f16e5f
patch link: https://lore.kernel.org/r/20260309111300.2484262-4-mohammad.rafi.shaik%40oss.qualcomm.com
patch subject: [PATCH v1 3/4] ASoC: qcom: q6apm-lpass-dais: Add MI2S clock control
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20260312/202603120247.NRy9LSop-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260312/202603120247.NRy9LSop-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603120247.NRy9LSop-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> sound/soc/qcom/qdsp6/q6apm-lpass-dais.c:298:2: warning: variable 'sysclk' is used uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
298 | default:
| ^~~~~~~
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c:302:6: note: uninitialized use occurs here
302 | if (sysclk) {
| ^~~~~~
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c:281:20: note: initialize the variable 'sysclk' to silence this warning
281 | struct clk *sysclk;
| ^
| = NULL
1 warning generated.
vim +/sysclk +298 sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
277
278 static int q6i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir)
279 {
280 struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
281 struct clk *sysclk;
282 bool *enabled;
283 int ret = 0;
284
285 switch (clk_id) {
286 case LPAIF_MI2S_MCLK:
287 sysclk = dai_data->priv[dai->id].mclk;
288 enabled = &dai_data->priv[dai->id].mclk_enabled;
289 break;
290 case LPAIF_MI2S_BCLK:
291 sysclk = dai_data->priv[dai->id].bclk;
292 enabled = &dai_data->priv[dai->id].bclk_enabled;
293 break;
294 case LPAIF_MI2S_ECLK:
295 sysclk = dai_data->priv[dai->id].eclk;
296 enabled = &dai_data->priv[dai->id].eclk_enabled;
297 break;
> 298 default:
299 break;
300 }
301
302 if (sysclk) {
303 clk_set_rate(sysclk, freq);
304 ret = clk_prepare_enable(sysclk);
305 if (ret) {
306 dev_err(dai->dev, "Error, Unable to prepare (%d) sysclk\n", clk_id);
307 return ret;
308 }
309
310 *enabled = true;
311 }
312
313 return ret;
314 }
315
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
2026-03-10 9:55 ` Krzysztof Kozlowski
@ 2026-03-17 5:27 ` Mohammad Rafi Shaik
2026-03-17 7:11 ` Krzysztof Kozlowski
0 siblings, 1 reply; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-17 5:27 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
linux-sound, linux-arm-msm, devicetree, linux-kernel,
Srinivas Kandagatla
On 3/10/2026 3:25 PM, Krzysztof Kozlowski wrote:
> On Mon, Mar 09, 2026 at 04:42:57PM +0530, Mohammad Rafi Shaik wrote:
>> Extend the qcom,q6apm-lpass-dais device tree binding to explicitly
>> describe Digital Audio Interface (DAI) child nodes.
>>
>> Add #address-cells and #size-cells to allow representation of multiple
>> DAI instances as child nodes, and define a dai@<id> pattern to document
>> per-DAI properties such as the interface ID and associated clocks.
>>
>> Qualcomm platforms like talos integrate third-party audio codecs or use
>> different external audio paths. These designs often require additional
>> configuration such as explicit MI2S MCLK settings for audio to work.
>>
>> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>> ---
>> .../bindings/sound/qcom,q6apm-lpass-dais.yaml | 41 ++++++++++++++++++-
>> 1 file changed, 40 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>> index 2fb95544d..1d770cbcb 100644
>> --- a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>> +++ b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>> @@ -21,6 +21,34 @@ properties:
>> '#sound-dai-cells':
>> const: 1
>>
>> + '#address-cells':
>> + const: 1
>> +
>> + '#size-cells':
>> + const: 0
>> +
>> +# Digital Audio Interfaces
>> +patternProperties:
>> + '^dai@[0-9]+$':
>> + type: object
>> + description:
>> + Q6DSP Digital Audio Interfaces.
>> +
>> + properties:
>> + reg:
>> + description:
>> + Digital Audio Interface ID
>> +
>> + clocks:
>> + minItems: 1
>> + maxItems: 3
>> +
>> + clock-names:
>> + minItems: 1
>> + maxItems: 3
>
> No, this is just way too generic. There is no such syntax in the kernel
> and this should stop you right there. You are not allowed to add your
> own style.
>
> I don't think DAI is here a separate device needing its own resources
> expressed in DT. This is still part of ADSP so you just described in DT
> internal routing between two services on ADSP.
>
Thanks for reviewing.
I’d like to clarify that this is not intended to model the DAI as a
separate physical device or to describe internal ADSP routing.
Requirement is to allow the kernel to send clock‑voting requests to the
ADSP. LPASS MCLK routing is not enabled by default on the ADSP, so the
kernel must explicitly request the ADSP to enable the relevant LPASS
MCLKs, which is a real hardware control requirement.
These clocks are LPASS‑owned, and driving them via a third‑party codec
is not appropriate. The intent of adding clock capabilities at the DAI
level is to allow the kernel to associate LPASS clock votes with a
specific DAI instance during stream activity.
While the DAI itself is not a physical device, some DT representation is
required to describe per‑DAI LPASS clock requirements.
I’m open to considering alternative representations, but removing this
entirely would leave no generic way for the kernel to handle correct
LPASS MCLK voting.
>> +
>> + additionalProperties: false
>> +
>> required:
>> - compatible
>> - '#sound-dai-cells'
>> @@ -29,7 +57,18 @@ unevaluatedProperties: false
>>
>> examples:
>> - |
>> - dais {
>
> Why?
>
I renamed the example node to bedais to mirror the node naming used in
Actual DT (q6apmbedai: bedais { ... }).
However, I understand the binding does not require any specific node
name; only the compatible and required properties/child nodes matter.
The rename was done purely to align the actual DT node naming used in
practice and improve cross-referencing clarity.
>> + #include <dt-bindings/sound/qcom,q6afe.h>
>> +
>> + bedais {
>> compatible = "qcom,q6apm-lpass-dais";
>> #sound-dai-cells = <1>;
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + dai@16 {
>> + reg = <PRIMARY_MI2S_RX>;
>> + clocks = <&q6prmcc LPASS_CLK_ID_MCLK_1
>> + LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
>
> So one entry, not three.
>
ACK,
I will add three clock entries for better clarity.
Best Regards,
Rafi.
>> + clock-names = "mclk";
>> + };
>> };
>> --
>> 2.34.1
>>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 4/4] ASoC: qcom: sc8280xp: ASoC: qcom: sc8280xp: enhance machine driver for board-specific config
2026-03-10 11:44 ` Neil Armstrong
@ 2026-03-17 5:35 ` Mohammad Rafi Shaik
0 siblings, 0 replies; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-17 5:35 UTC (permalink / raw)
To: Neil Armstrong, Srinivas Kandagatla, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela,
Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel
On 3/10/2026 5:14 PM, Neil Armstrong wrote:
> Hi,
>
> On 3/9/26 12:13, Mohammad Rafi Shaik wrote:
>> The sc8280xp machine driver is currently written with a largely
>> SoC-centric view and assumes a uniform audio topology across all boards.
>> In practice, multiple products based on the same SoC use different board
>> designs and external audio components, which require board-specific
>> configuration to function correctly.
>>
>> Several Qualcomm platforms like talos integrate third-party audio codecs
>> or use different external audio paths. These designs often require
>> additional configuration such as explicit MI2S MCLK settings for audio
>> to work.
>>
>> This change enhances the sc8280xp machine driver to support board-
>> specific
>> configuration such as allowing each board variant to provide its own DAPM
>> widgets and routes, reflecting the actual audio components and connectors
>> present and enabling MI2S MCLK programming for boards that use external
>> codecs requiring a stable master clock.
>>
>> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>> ---
>> sound/soc/qcom/sc8280xp.c | 180 ++++++++++++++++++++++++++++++++++----
>> 1 file changed, 162 insertions(+), 18 deletions(-)
>>
>> diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
>> index 7925aa3f6..c2e9323df 100644
>> --- a/sound/soc/qcom/sc8280xp.c
>> +++ b/sound/soc/qcom/sc8280xp.c
>> @@ -12,17 +12,62 @@
>> #include <sound/jack.h>
>> #include <linux/input-event-codes.h>
>> #include "qdsp6/q6afe.h"
>> +#include "qdsp6/q6apm.h"
>> +#include "qdsp6/q6prm.h"
>> #include "common.h"
>> #include "sdw.h"
>> +#define MCLK_FREQ 12288000
>> +#define MCLK_NATIVE_FREQ 11289600
>
> Where does thos values come from ?
>
Thanks for the review,
These MCLK rates are default settings in Qualcomm platforms.
so hard codec thes rates
> MCLK_FREQ 12288000 == 48000 * 256
> MCLK_NATIVE_FREQ 11289600 == 44100 * 256
>
> This is highly specific to a board, the sdm845.c uses:
>
> #define DEFAULT_MCLK_RATE 24576000 == 48000 * 2 * 256
> #define MI2S_BCLK_RATE 1536000 == 48000 * 2 * 16
>
> And those are the values we use to output sound on HDMI on all HDK and
> Dragonboards.
>
> I guess this should be configurable somewhere !
>
Thanks for the detailed rate calculations. I’ll consider the suggestions
above and work toward a more generic and flexible approach for
configuring clock rates.
Best Regards,
Rafi
>> +
>> +static struct snd_soc_dapm_widget sc8280xp_dapm_widgets[] = {
>> + SND_SOC_DAPM_HP("Headphone Jack", NULL),
>> + SND_SOC_DAPM_MIC("Mic Jack", NULL),
>> + SND_SOC_DAPM_SPK("DP0 Jack", NULL),
>> + SND_SOC_DAPM_SPK("DP1 Jack", NULL),
>> + SND_SOC_DAPM_SPK("DP2 Jack", NULL),
>> + SND_SOC_DAPM_SPK("DP3 Jack", NULL),
>> + SND_SOC_DAPM_SPK("DP4 Jack", NULL),
>> + SND_SOC_DAPM_SPK("DP5 Jack", NULL),
>> + SND_SOC_DAPM_SPK("DP6 Jack", NULL),
>> + SND_SOC_DAPM_SPK("DP7 Jack", NULL),
>> +};
>> +
>> +struct snd_soc_common {
>> + char *driver_name;
>> + const struct snd_soc_dapm_widget *dapm_widgets;
>> + int num_dapm_widgets;
>> + const struct snd_soc_dapm_route *dapm_routes;
>> + int num_dapm_routes;
>> + bool mi2s_mclk_enable;
>> +};
>> +
>> struct sc8280xp_snd_data {
>> bool stream_prepared[AFE_PORT_MAX];
>> struct snd_soc_card *card;
>> struct snd_soc_jack jack;
>> struct snd_soc_jack dp_jack[8];
>> + struct snd_soc_common *snd_soc_common_priv;
>> bool jack_setup;
>> };
>> +static inline int sc8280xp_get_mclk_feq(unsigned int rate)
>
> _freq
>
>> +{
>> + int freq = MCLK_FREQ;
>> +
>> + switch (rate) {
>> + case SNDRV_PCM_RATE_11025:
>> + case SNDRV_PCM_RATE_44100:
>> + case SNDRV_PCM_RATE_88200:
>> + freq = MCLK_NATIVE_FREQ;
>> + break;
>> + default:
>> + break;
>> + }
>> +
>> + return freq;
>> +}
>> +
>> static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
>> {
>> struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd-
>> >card);
>> @@ -32,10 +77,6 @@ static int sc8280xp_snd_init(struct
>> snd_soc_pcm_runtime *rtd)
>> int dp_pcm_id = 0;
>> switch (cpu_dai->id) {
>> - case PRIMARY_MI2S_RX...QUATERNARY_MI2S_TX:
>> - case QUINARY_MI2S_RX...QUINARY_MI2S_TX:
>> - snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
>> - break;
>> case WSA_CODEC_DMA_RX_0:
>> case WSA_CODEC_DMA_RX_1:
>> /*
>> @@ -96,6 +137,31 @@ static int sc8280xp_be_hw_params_fixup(struct
>> snd_soc_pcm_runtime *rtd,
>> return 0;
>> }
>> +static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
>> + struct snd_pcm_hw_params *params)
>> +{
>> + struct snd_soc_pcm_runtime *rtd =
>> snd_soc_substream_to_rtd(substream);
>> + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
>> + struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd-
>> >card);
>> + int mclk_freq = sc8280xp_get_mclk_feq(params_rate(params));
>> +
>> + switch (cpu_dai->id) {
>> + case PRIMARY_MI2S_RX...QUATERNARY_MI2S_TX:
>> + case QUINARY_MI2S_RX...QUINARY_MI2S_TX:
>> + snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
>> +
>> + if (data->snd_soc_common_priv->mi2s_mclk_enable)
>> + snd_soc_dai_set_sysclk(cpu_dai,
>> + LPAIF_MI2S_MCLK, mclk_freq,
>> + SND_SOC_CLOCK_IN);
>> + break;
>> + default:
>> + break;
>> + };
>> +
>> + return 0;
>> +}
>> +
>> static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream)
>> {
>> struct snd_soc_pcm_runtime *rtd =
>> snd_soc_substream_to_rtd(substream);
>> @@ -117,6 +183,7 @@ static int sc8280xp_snd_hw_free(struct
>> snd_pcm_substream *substream)
>> static const struct snd_soc_ops sc8280xp_be_ops = {
>> .startup = qcom_snd_sdw_startup,
>> .shutdown = qcom_snd_sdw_shutdown,
>> + .hw_params = sc8280xp_snd_hw_params,
>> .hw_free = sc8280xp_snd_hw_free,
>> .prepare = sc8280xp_snd_prepare,
>> };
>> @@ -145,37 +212,114 @@ static int sc8280xp_platform_probe(struct
>> platform_device *pdev)
>> card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
>> if (!card)
>> return -ENOMEM;
>> - card->owner = THIS_MODULE;
>> +
>> /* Allocate the private data */
>> data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
>> if (!data)
>> return -ENOMEM;
>> + data->snd_soc_common_priv = (struct snd_soc_common
>> *)of_device_get_match_data(dev);
>> + if (!data->snd_soc_common_priv)
>> + return -ENOMEM;
>> +
>> + card->owner = THIS_MODULE;
>> card->dev = dev;
>> dev_set_drvdata(dev, card);
>> snd_soc_card_set_drvdata(card, data);
>> + card->dapm_widgets = data->snd_soc_common_priv->dapm_widgets;
>> + card->num_dapm_widgets = data->snd_soc_common_priv-
>> >num_dapm_widgets;
>> + card->dapm_routes = data->snd_soc_common_priv->dapm_routes;
>> + card->num_dapm_routes = data->snd_soc_common_priv->num_dapm_routes;
>> +
>> ret = qcom_snd_parse_of(card);
>> if (ret)
>> return ret;
>> - card->driver_name = of_device_get_match_data(dev);
>> + card->driver_name = data->snd_soc_common_priv->driver_name;
>> sc8280xp_add_be_ops(card);
>> return devm_snd_soc_register_card(dev, card);
>> }
>> +static struct snd_soc_common kaanapali_priv_data = {
>> + .driver_name = "kaanapali",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> +};
>> +
>> +static struct snd_soc_common qcs9100_priv_data = {
>> + .driver_name = "sa8775p",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> +};
>> +
>> +static struct snd_soc_common qcs615_priv_data = {
>> + .driver_name = "qcs615",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> + .mi2s_mclk_enable = true,
>> +};
>> +
>> +static struct snd_soc_common qcm6490_priv_data = {
>> + .driver_name = "qcm6490",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> +};
>> +
>> +static struct snd_soc_common qcs6490_priv_data = {
>> + .driver_name = "qcs6490",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> +};
>> +
>> +static struct snd_soc_common qcs8275_priv_data = {
>> + .driver_name = "qcs8300",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> +};
>> +
>> +static struct snd_soc_common sc8280xp_priv_data = {
>> + .driver_name = "sc8280xp",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> +};
>> +
>> +static struct snd_soc_common sm8450_priv_data = {
>> + .driver_name = "sm8450",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> +};
>> +
>> +static struct snd_soc_common sm8550_priv_data = {
>> + .driver_name = "sm8550",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> +};
>> +
>> +static struct snd_soc_common sm8650_priv_data = {
>> + .driver_name = "sm8650",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> +};
>> +
>> +static struct snd_soc_common sm8750_priv_data = {
>> + .driver_name = "sm8750",
>> + .dapm_widgets = sc8280xp_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
>> +};
>> +
>> static const struct of_device_id snd_sc8280xp_dt_match[] = {
>> - {.compatible = "qcom,kaanapali-sndcard", "kaanapali"},
>> - {.compatible = "qcom,qcm6490-idp-sndcard", "qcm6490"},
>> - {.compatible = "qcom,qcs615-sndcard", "qcs615"},
>> - {.compatible = "qcom,qcs6490-rb3gen2-sndcard", "qcs6490"},
>> - {.compatible = "qcom,qcs8275-sndcard", "qcs8300"},
>> - {.compatible = "qcom,qcs9075-sndcard", "sa8775p"},
>> - {.compatible = "qcom,qcs9100-sndcard", "sa8775p"},
>> - {.compatible = "qcom,sc8280xp-sndcard", "sc8280xp"},
>> - {.compatible = "qcom,sm8450-sndcard", "sm8450"},
>> - {.compatible = "qcom,sm8550-sndcard", "sm8550"},
>> - {.compatible = "qcom,sm8650-sndcard", "sm8650"},
>> - {.compatible = "qcom,sm8750-sndcard", "sm8750"},
>> + {.compatible = "qcom,kaanapali-sndcard", .data =
>> &kaanapali_priv_data},
>> + {.compatible = "qcom,qcm6490-idp-sndcard", .data =
>> &qcm6490_priv_data},
>> + {.compatible = "qcom,qcs615-sndcard", .data = &qcs615_priv_data},
>> + {.compatible = "qcom,qcs6490-rb3gen2-sndcard", .data =
>> &qcs6490_priv_data},
>> + {.compatible = "qcom,qcs8275-sndcard", .data = &qcs8275_priv_data},
>> + {.compatible = "qcom,qcs9075-sndcard", .data = &qcs9100_priv_data},
>> + {.compatible = "qcom,qcs9100-sndcard", .data = &qcs9100_priv_data},
>> + {.compatible = "qcom,sc8280xp-sndcard", .data =
>> &sc8280xp_priv_data},
>> + {.compatible = "qcom,sm8450-sndcard", .data = &sm8450_priv_data},
>> + {.compatible = "qcom,sm8550-sndcard", .data = &sm8550_priv_data},
>> + {.compatible = "qcom,sm8650-sndcard", .data = &sm8650_priv_data},
>> + {.compatible = "qcom,sm8750-sndcard", .data = &sm8750_priv_data},
>> {}
>> };
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control
2026-03-10 14:02 ` [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control Neil Armstrong
@ 2026-03-17 5:48 ` Mohammad Rafi Shaik
0 siblings, 0 replies; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-17 5:48 UTC (permalink / raw)
To: Neil Armstrong, Srinivas Kandagatla, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela,
Takashi Iwai
Cc: Krzysztof Kozlowski, linux-sound, linux-arm-msm, devicetree,
linux-kernel
On 3/10/2026 7:32 PM, Neil Armstrong wrote:
> On 3/9/26 12:12, 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.
>>
>> Enhances the sc8280xp machine driver to set the boards spacific
>> configurations, some of the boards like talos using third party
>> codec's which need's additional MCLK settings for audio to work.
>>
>> Mohammad Rafi Shaik (4):
>> ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
>> ASoC: qcom: qdsp6: q6prm: add the missing LPASS MCLK clock IDs
>> 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 | 41 +++-
>> sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 137 ++++++++++++-
>> sound/soc/qcom/qdsp6/q6prm-clocks.c | 5 +
>> sound/soc/qcom/qdsp6/q6prm.h | 15 ++
>> sound/soc/qcom/sc8280xp.c | 180 ++++++++++++++++--
>> 5 files changed, 357 insertions(+), 21 deletions(-)
>>
>>
>> base-commit: a0ae2a256046c0c5d3778d1a194ff2e171f16e5f
>
>
> I'm not sure about the overall architecture, but I managed to make the
> I2S HDMI audio
> work on the SM8650 HDK with:
>
>
Thanks Neil for validating.
> ==============================><=======================================
> diff --git a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts b/arch/arm64/boot/
> dts/qcom/sm8650-hdk.dts
> index 5bf1af3308ce..8316e17dc76b 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 {
> @@ -1056,6 +1076,17 @@ &pon_resin {
> status = "okay";
> };
>
> +&q6apmbedai {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + 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/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/
> qcom/sm8650.dtsi
> index f8e1950a74ac..9818fbd8094e 100644
> --- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
> @@ -6237,6 +6237,46 @@ wake-pins {
> };
> };
>
> + audio_mclk0_default_state: audio-mclk0-default-state {
> + pins = "gpio125";
> + function = "audio_ext_mclk0";
> + drive-strength = <8>;
> + bias-disable;
> + output-high;
> + };
> +
> + i2s0_default_state: i2s0-default-state {
> + sck-pins {
> + pins = "gpio126";
> + function = "i2s0_sck";
> + drive-strength = <8>;
> + bias-disable;
> + output-high;
> + };
> +
> + data0-pins {
> + pins = "gpio127";
> + function = "i2s0_data0";
> + drive-strength = <8>;
> + bias-disable;
> + };
> +
> + data1-pins {
> + pins = "gpio128";
> + function = "i2s0_data1";
> + drive-strength = <8>;
> + bias-disable;
> + };
> +
> + ws-pins {
> + pins = "gpio129";
> + function = "i2s0_ws";
> + drive-strength = <8>;
> + bias-disable;
> + output-high;
> + };
> + };
> +
> qup_i2c0_data_clk: qup-i2c0-data-clk-state {
> /* SDA, SCL */
> pins = "gpio32", "gpio33";
> diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
> index 7aa87e8a6cc5..c2bd5f2a696d 100644
> --- a/sound/soc/qcom/sc8280xp.c
> +++ b/sound/soc/qcom/sc8280xp.c
> @@ -17,8 +17,12 @@
> #include "common.h"
> #include "sdw.h"
>
> -#define MCLK_FREQ 12288000
> -#define MCLK_NATIVE_FREQ 11289600
> +#define I2S_MCLKFS 256
> +#define I2S_SLOTSIZE 16
> +#define I2S_MCLK_RATE(rate, channels) \
> + ((rate) * (channels) * I2S_MCLKFS)
> +#define I2S_BIT_RATE(rate, channels) \
> + ((rate) * (channels) * I2S_SLOTSIZE)
>
> static struct snd_soc_dapm_widget sc8280xp_dapm_widgets[] = {
> SND_SOC_DAPM_HP("Headphone Jack", NULL),
> @@ -40,6 +44,7 @@ struct snd_soc_common {
> const struct snd_soc_dapm_route *dapm_routes;
> int num_dapm_routes;
> bool mi2s_mclk_enable;
> + bool mi2s_bclk_enable;
> };
>
> struct sc8280xp_snd_data {
> @@ -51,21 +56,22 @@ struct sc8280xp_snd_data {
> bool jack_setup;
> };
>
> -static inline int sc8280xp_get_mclk_feq(unsigned int rate)
> +static inline int sc8280xp_get_mclk_freq(struct snd_pcm_hw_params *params)
> {
> - int freq = MCLK_FREQ;
> -
> switch (rate) {
> case SNDRV_PCM_RATE_11025:
> case SNDRV_PCM_RATE_44100:
> case SNDRV_PCM_RATE_88200:
> - freq = MCLK_NATIVE_FREQ;
> + return I2S_MCLK_RATE(44100, params_channels(params));
> break;
> default:
> - break;
> + return I2S_MCLK_RATE(params_rate(params),
> params_channels(params));
> }
> +}
>
> - return freq;
> +static inline int sc8280xp_get_bclk_freq(struct snd_pcm_hw_params *params)
> +{
> + return I2S_BIT_RATE(params_rate(params), params_channels(params));
> }
>
> static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
> @@ -142,8 +148,13 @@ static int sc8280xp_snd_hw_params(struct
> snd_pcm_substream *substream,
> {
> struct snd_soc_pcm_runtime *rtd =
> snd_soc_substream_to_rtd(substream);
> struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
> + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
> struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
> - int mclk_freq = sc8280xp_get_mclk_feq(params_rate(params));
> + int mclk_freq = sc8280xp_get_mclk_freq(params);
> + int bclk_freq = sc8280xp_get_bclk_freq(params);
> + unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC |
> + SND_SOC_DAIFMT_NB_NF |
> + SND_SOC_DAIFMT_I2S;
>
> switch (cpu_dai->id) {
> case PRIMARY_MI2S_RX...QUATERNARY_MI2S_TX:
> @@ -154,6 +165,15 @@ static int sc8280xp_snd_hw_params(struct
> snd_pcm_substream *substream,
> snd_soc_dai_set_sysclk(cpu_dai,
> LPAIF_MI2S_MCLK, mclk_freq,
> SND_SOC_CLOCK_IN);
> +
> + if (data->snd_soc_common_priv->mi2s_bclk_enable) {
> + snd_soc_dai_set_sysclk(cpu_dai,
> + LPAIF_MI2S_BCLK, bclk_freq,
> + SND_SOC_CLOCK_IN);
> + snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_BC_FC |
> + SND_SOC_DAIFMT_NB_NF |
> + SND_SOC_DAIFMT_I2S);
Rather than hardcoding codec_dai_fmt, it would be better to supply it
through board-specific data. This is codec-dependent configuration and
not directly related to MCLK handling.
I will add the codec DAI format configuration in the next version in a
more generic way, incorporating all your suggestions.
Best Regards,
Rafi
> + }
> break;
> default:
> break;
> @@ -288,6 +308,7 @@ static struct snd_soc_common sm8450_priv_data = {
> .dapm_widgets = sc8280xp_dapm_widgets,
> .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> .mi2s_mclk_enable = true,
> + .mi2s_bclk_enable = true,
> };
>
> static struct snd_soc_common sm8550_priv_data = {
> @@ -295,6 +316,7 @@ static struct snd_soc_common sm8550_priv_data = {
> .dapm_widgets = sc8280xp_dapm_widgets,
> .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> .mi2s_mclk_enable = true,
> + .mi2s_bclk_enable = true,
> };
>
> static struct snd_soc_common sm8650_priv_data = {
> @@ -302,6 +324,7 @@ static struct snd_soc_common sm8650_priv_data = {
> .dapm_widgets = sc8280xp_dapm_widgets,
> .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> .mi2s_mclk_enable = true,
> + .mi2s_bclk_enable = true,
> };
>
> static struct snd_soc_common sm8750_priv_data = {
> ==============================><========================================
>
> Thanks,
> Neil
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
2026-03-17 5:27 ` Mohammad Rafi Shaik
@ 2026-03-17 7:11 ` Krzysztof Kozlowski
2026-03-26 9:57 ` Mohammad Rafi Shaik
0 siblings, 1 reply; 21+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-17 7:11 UTC (permalink / raw)
To: Mohammad Rafi Shaik
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
linux-sound, linux-arm-msm, devicetree, linux-kernel,
Srinivas Kandagatla
On 17/03/2026 06:27, Mohammad Rafi Shaik wrote:
>
>
> On 3/10/2026 3:25 PM, Krzysztof Kozlowski wrote:
>> On Mon, Mar 09, 2026 at 04:42:57PM +0530, Mohammad Rafi Shaik wrote:
>>> Extend the qcom,q6apm-lpass-dais device tree binding to explicitly
>>> describe Digital Audio Interface (DAI) child nodes.
>>>
>>> Add #address-cells and #size-cells to allow representation of multiple
>>> DAI instances as child nodes, and define a dai@<id> pattern to document
>>> per-DAI properties such as the interface ID and associated clocks.
>>>
>>> Qualcomm platforms like talos integrate third-party audio codecs or use
>>> different external audio paths. These designs often require additional
>>> configuration such as explicit MI2S MCLK settings for audio to work.
>>>
>>> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>>> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>>> ---
>>> .../bindings/sound/qcom,q6apm-lpass-dais.yaml | 41 ++++++++++++++++++-
>>> 1 file changed, 40 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>> index 2fb95544d..1d770cbcb 100644
>>> --- a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>> +++ b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>> @@ -21,6 +21,34 @@ properties:
>>> '#sound-dai-cells':
>>> const: 1
>>>
>>> + '#address-cells':
>>> + const: 1
>>> +
>>> + '#size-cells':
>>> + const: 0
>>> +
>>> +# Digital Audio Interfaces
>>> +patternProperties:
>>> + '^dai@[0-9]+$':
>>> + type: object
>>> + description:
>>> + Q6DSP Digital Audio Interfaces.
>>> +
>>> + properties:
>>> + reg:
>>> + description:
>>> + Digital Audio Interface ID
>>> +
>>> + clocks:
>>> + minItems: 1
>>> + maxItems: 3
>>> +
>>> + clock-names:
>>> + minItems: 1
>>> + maxItems: 3
>>
>> No, this is just way too generic. There is no such syntax in the kernel
>> and this should stop you right there. You are not allowed to add your
>> own style.
>>
>> I don't think DAI is here a separate device needing its own resources
>> expressed in DT. This is still part of ADSP so you just described in DT
>> internal routing between two services on ADSP.
>>
>
> Thanks for reviewing.
>
> I’d like to clarify that this is not intended to model the DAI as a
> separate physical device or to describe internal ADSP routing.
If you do not want to represent the physical device, then I don't think
it should be represented at all.
>
> Requirement is to allow the kernel to send clock‑voting requests to the
> ADSP. LPASS MCLK routing is not enabled by default on the ADSP, so the
> kernel must explicitly request the ADSP to enable the relevant LPASS
> MCLKs, which is a real hardware control requirement.
>
> These clocks are LPASS‑owned, and driving them via a third‑party codec
> is not appropriate. The intent of adding clock capabilities at the DAI
> level is to allow the kernel to associate LPASS clock votes with a
> specific DAI instance during stream activity.
>
> While the DAI itself is not a physical device, some DT representation is
> required to describe per‑DAI LPASS clock requirements.
DT's purpose is not to describe software constructs, thus DT is not the
answer to your requirement of mapping clocks to specific DAI needs.
Every person adding software properties made "some DT representation is
required" claim.
>
> I’m open to considering alternative representations, but removing this
> entirely would leave no generic way for the kernel to handle correct
> LPASS MCLK voting.
I imagine that, since this is software construct, the software knows
which DAI needs which clock. Clocks are strictly defined, thus driver
should handle all this.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
2026-03-17 7:11 ` Krzysztof Kozlowski
@ 2026-03-26 9:57 ` Mohammad Rafi Shaik
2026-03-26 10:10 ` Krzysztof Kozlowski
0 siblings, 1 reply; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-26 9:57 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
linux-sound, linux-arm-msm, devicetree, linux-kernel,
Srinivas Kandagatla
On 3/17/2026 12:41 PM, Krzysztof Kozlowski wrote:
> On 17/03/2026 06:27, Mohammad Rafi Shaik wrote:
>>
>>
>> On 3/10/2026 3:25 PM, Krzysztof Kozlowski wrote:
>>> On Mon, Mar 09, 2026 at 04:42:57PM +0530, Mohammad Rafi Shaik wrote:
>>>> Extend the qcom,q6apm-lpass-dais device tree binding to explicitly
>>>> describe Digital Audio Interface (DAI) child nodes.
>>>>
>>>> Add #address-cells and #size-cells to allow representation of multiple
>>>> DAI instances as child nodes, and define a dai@<id> pattern to document
>>>> per-DAI properties such as the interface ID and associated clocks.
>>>>
>>>> Qualcomm platforms like talos integrate third-party audio codecs or use
>>>> different external audio paths. These designs often require additional
>>>> configuration such as explicit MI2S MCLK settings for audio to work.
>>>>
>>>> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>>>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>>>> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>>>> ---
>>>> .../bindings/sound/qcom,q6apm-lpass-dais.yaml | 41 ++++++++++++++++++-
>>>> 1 file changed, 40 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>>> index 2fb95544d..1d770cbcb 100644
>>>> --- a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>>> +++ b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>>> @@ -21,6 +21,34 @@ properties:
>>>> '#sound-dai-cells':
>>>> const: 1
>>>>
>>>> + '#address-cells':
>>>> + const: 1
>>>> +
>>>> + '#size-cells':
>>>> + const: 0
>>>> +
>>>> +# Digital Audio Interfaces
>>>> +patternProperties:
>>>> + '^dai@[0-9]+$':
>>>> + type: object
>>>> + description:
>>>> + Q6DSP Digital Audio Interfaces.
>>>> +
>>>> + properties:
>>>> + reg:
>>>> + description:
>>>> + Digital Audio Interface ID
>>>> +
>>>> + clocks:
>>>> + minItems: 1
>>>> + maxItems: 3
>>>> +
>>>> + clock-names:
>>>> + minItems: 1
>>>> + maxItems: 3
>>>
>>> No, this is just way too generic. There is no such syntax in the kernel
>>> and this should stop you right there. You are not allowed to add your
>>> own style.
>>>
>>> I don't think DAI is here a separate device needing its own resources
>>> expressed in DT. This is still part of ADSP so you just described in DT
>>> internal routing between two services on ADSP.
>>>
>>
>> Thanks for reviewing.
>>
>> I’d like to clarify that this is not intended to model the DAI as a
>> separate physical device or to describe internal ADSP routing.
>
> If you do not want to represent the physical device, then I don't think
> it should be represented at all.
>
>>
>> Requirement is to allow the kernel to send clock‑voting requests to the
>> ADSP. LPASS MCLK routing is not enabled by default on the ADSP, so the
>> kernel must explicitly request the ADSP to enable the relevant LPASS
>> MCLKs, which is a real hardware control requirement.
>>
>> These clocks are LPASS‑owned, and driving them via a third‑party codec
>> is not appropriate. The intent of adding clock capabilities at the DAI
>> level is to allow the kernel to associate LPASS clock votes with a
>> specific DAI instance during stream activity.
>>
>> While the DAI itself is not a physical device, some DT representation is
>> required to describe per‑DAI LPASS clock requirements.
>
> DT's purpose is not to describe software constructs, thus DT is not the
> answer to your requirement of mapping clocks to specific DAI needs.
> Every person adding software properties made "some DT representation is
> required" claim.
>
>>
>> I’m open to considering alternative representations, but removing this
>> entirely would leave no generic way for the kernel to handle correct
>> LPASS MCLK voting.
>
> I imagine that, since this is software construct, the software knows
> which DAI needs which clock. Clocks are strictly defined, thus driver
> should handle all this.
>
No, the MCLK connection is not fixed to a specific DAI.
The LPASS MCLKs
LPASS_CLK_ID_MCLK_1 … LPASS_CLK_ID_MCLK_5
are hard‑wired connection, each physically routed to an external codec
on the board.
Because of this, the clock that must be voted depends purely on the
hardware wiring, not on which DAI (Primary/Secondary/Tertiary/Quaternary
MI2S) is used.
In other words, DAI ↔ MCLK is not a fixed mapping.
Examples:
On Talos‑EVK, the speaker is connected via Primary MI2S, but the
corresponding MCLK line wired to the codec is LPASS_CLK_ID_MCLK_2.
On Kodiak, the customer connected an SGTL5000 codec via Quaternary MI2S,
yet the required MCLK is still LPASS_CLK_ID_MCLK_2.
Instead, the kernel must vote for the MCLK that is physically connected
to the external codec on that specific board.
Thanks & Regards,
Rafi.
>
> Best regards,
> Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
2026-03-26 9:57 ` Mohammad Rafi Shaik
@ 2026-03-26 10:10 ` Krzysztof Kozlowski
2026-03-27 13:16 ` Mohammad Rafi Shaik
0 siblings, 1 reply; 21+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-26 10:10 UTC (permalink / raw)
To: Mohammad Rafi Shaik
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
linux-sound, linux-arm-msm, devicetree, linux-kernel,
Srinivas Kandagatla
On 26/03/2026 10:57, Mohammad Rafi Shaik wrote:
>
>
> On 3/17/2026 12:41 PM, Krzysztof Kozlowski wrote:
>> On 17/03/2026 06:27, Mohammad Rafi Shaik wrote:
>>>
>>>
>>> On 3/10/2026 3:25 PM, Krzysztof Kozlowski wrote:
>>>> On Mon, Mar 09, 2026 at 04:42:57PM +0530, Mohammad Rafi Shaik wrote:
>>>>> Extend the qcom,q6apm-lpass-dais device tree binding to explicitly
>>>>> describe Digital Audio Interface (DAI) child nodes.
>>>>>
>>>>> Add #address-cells and #size-cells to allow representation of multiple
>>>>> DAI instances as child nodes, and define a dai@<id> pattern to document
>>>>> per-DAI properties such as the interface ID and associated clocks.
>>>>>
>>>>> Qualcomm platforms like talos integrate third-party audio codecs or use
>>>>> different external audio paths. These designs often require additional
>>>>> configuration such as explicit MI2S MCLK settings for audio to work.
>>>>>
>>>>> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>>>>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>>>>> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>>>>> ---
>>>>> .../bindings/sound/qcom,q6apm-lpass-dais.yaml | 41 ++++++++++++++++++-
>>>>> 1 file changed, 40 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>>>> index 2fb95544d..1d770cbcb 100644
>>>>> --- a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>>>> +++ b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>>>> @@ -21,6 +21,34 @@ properties:
>>>>> '#sound-dai-cells':
>>>>> const: 1
>>>>>
>>>>> + '#address-cells':
>>>>> + const: 1
>>>>> +
>>>>> + '#size-cells':
>>>>> + const: 0
>>>>> +
>>>>> +# Digital Audio Interfaces
>>>>> +patternProperties:
>>>>> + '^dai@[0-9]+$':
>>>>> + type: object
>>>>> + description:
>>>>> + Q6DSP Digital Audio Interfaces.
>>>>> +
>>>>> + properties:
>>>>> + reg:
>>>>> + description:
>>>>> + Digital Audio Interface ID
>>>>> +
>>>>> + clocks:
>>>>> + minItems: 1
>>>>> + maxItems: 3
>>>>> +
>>>>> + clock-names:
>>>>> + minItems: 1
>>>>> + maxItems: 3
>>>>
>>>> No, this is just way too generic. There is no such syntax in the kernel
>>>> and this should stop you right there. You are not allowed to add your
>>>> own style.
>>>>
>>>> I don't think DAI is here a separate device needing its own resources
>>>> expressed in DT. This is still part of ADSP so you just described in DT
>>>> internal routing between two services on ADSP.
>>>>
>>>
>>> Thanks for reviewing.
>>>
>>> I’d like to clarify that this is not intended to model the DAI as a
>>> separate physical device or to describe internal ADSP routing.
>>
>> If you do not want to represent the physical device, then I don't think
>> it should be represented at all.
>>
>>>
>>> Requirement is to allow the kernel to send clock‑voting requests to the
>>> ADSP. LPASS MCLK routing is not enabled by default on the ADSP, so the
>>> kernel must explicitly request the ADSP to enable the relevant LPASS
>>> MCLKs, which is a real hardware control requirement.
>>>
>>> These clocks are LPASS‑owned, and driving them via a third‑party codec
>>> is not appropriate. The intent of adding clock capabilities at the DAI
>>> level is to allow the kernel to associate LPASS clock votes with a
>>> specific DAI instance during stream activity.
>>>
>>> While the DAI itself is not a physical device, some DT representation is
>>> required to describe per‑DAI LPASS clock requirements.
>>
>> DT's purpose is not to describe software constructs, thus DT is not the
>> answer to your requirement of mapping clocks to specific DAI needs.
>> Every person adding software properties made "some DT representation is
>> required" claim.
>>
>>>
>>> I’m open to considering alternative representations, but removing this
>>> entirely would leave no generic way for the kernel to handle correct
>>> LPASS MCLK voting.
>>
>> I imagine that, since this is software construct, the software knows
>> which DAI needs which clock. Clocks are strictly defined, thus driver
>> should handle all this.
>>
>
> No, the MCLK connection is not fixed to a specific DAI.
>
> The LPASS MCLKs
> LPASS_CLK_ID_MCLK_1 … LPASS_CLK_ID_MCLK_5
>
> are hard‑wired connection, each physically routed to an external codec
> on the board.
>
> Because of this, the clock that must be voted depends purely on the
> hardware wiring, not on which DAI (Primary/Secondary/Tertiary/Quaternary
> MI2S) is used.
If they are routed to external codecs, then they are already present in
these nodes and duplicating them here is not necessary.
>
> In other words, DAI ↔ MCLK is not a fixed mapping.
>
> Examples:
> On Talos‑EVK, the speaker is connected via Primary MI2S, but the
> corresponding MCLK line wired to the codec is LPASS_CLK_ID_MCLK_2.
>
> On Kodiak, the customer connected an SGTL5000 codec via Quaternary MI2S,
> yet the required MCLK is still LPASS_CLK_ID_MCLK_2.
>
> Instead, the kernel must vote for the MCLK that is physically connected
> to the external codec on that specific board.
No, the external codec driver must vote for that MCLK.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
2026-03-26 10:10 ` Krzysztof Kozlowski
@ 2026-03-27 13:16 ` Mohammad Rafi Shaik
2026-03-27 13:23 ` Krzysztof Kozlowski
0 siblings, 1 reply; 21+ messages in thread
From: Mohammad Rafi Shaik @ 2026-03-27 13:16 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
linux-sound, linux-arm-msm, devicetree, linux-kernel,
Srinivas Kandagatla
On 3/26/2026 3:40 PM, Krzysztof Kozlowski wrote:
> On 26/03/2026 10:57, Mohammad Rafi Shaik wrote:
>>
>>
>> On 3/17/2026 12:41 PM, Krzysztof Kozlowski wrote:
>>> On 17/03/2026 06:27, Mohammad Rafi Shaik wrote:
>>>>
>>>>
>>>> On 3/10/2026 3:25 PM, Krzysztof Kozlowski wrote:
>>>>> On Mon, Mar 09, 2026 at 04:42:57PM +0530, Mohammad Rafi Shaik wrote:
>>>>>> Extend the qcom,q6apm-lpass-dais device tree binding to explicitly
>>>>>> describe Digital Audio Interface (DAI) child nodes.
>>>>>>
>>>>>> Add #address-cells and #size-cells to allow representation of multiple
>>>>>> DAI instances as child nodes, and define a dai@<id> pattern to document
>>>>>> per-DAI properties such as the interface ID and associated clocks.
>>>>>>
>>>>>> Qualcomm platforms like talos integrate third-party audio codecs or use
>>>>>> different external audio paths. These designs often require additional
>>>>>> configuration such as explicit MI2S MCLK settings for audio to work.
>>>>>>
>>>>>> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>>>>>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>>>>>> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>>>>>> ---
>>>>>> .../bindings/sound/qcom,q6apm-lpass-dais.yaml | 41 ++++++++++++++++++-
>>>>>> 1 file changed, 40 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>>>>> index 2fb95544d..1d770cbcb 100644
>>>>>> --- a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>>>>> +++ b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml
>>>>>> @@ -21,6 +21,34 @@ properties:
>>>>>> '#sound-dai-cells':
>>>>>> const: 1
>>>>>>
>>>>>> + '#address-cells':
>>>>>> + const: 1
>>>>>> +
>>>>>> + '#size-cells':
>>>>>> + const: 0
>>>>>> +
>>>>>> +# Digital Audio Interfaces
>>>>>> +patternProperties:
>>>>>> + '^dai@[0-9]+$':
>>>>>> + type: object
>>>>>> + description:
>>>>>> + Q6DSP Digital Audio Interfaces.
>>>>>> +
>>>>>> + properties:
>>>>>> + reg:
>>>>>> + description:
>>>>>> + Digital Audio Interface ID
>>>>>> +
>>>>>> + clocks:
>>>>>> + minItems: 1
>>>>>> + maxItems: 3
>>>>>> +
>>>>>> + clock-names:
>>>>>> + minItems: 1
>>>>>> + maxItems: 3
>>>>>
>>>>> No, this is just way too generic. There is no such syntax in the kernel
>>>>> and this should stop you right there. You are not allowed to add your
>>>>> own style.
>>>>>
>>>>> I don't think DAI is here a separate device needing its own resources
>>>>> expressed in DT. This is still part of ADSP so you just described in DT
>>>>> internal routing between two services on ADSP.
>>>>>
>>>>
>>>> Thanks for reviewing.
>>>>
>>>> I’d like to clarify that this is not intended to model the DAI as a
>>>> separate physical device or to describe internal ADSP routing.
>>>
>>> If you do not want to represent the physical device, then I don't think
>>> it should be represented at all.
>>>
>>>>
>>>> Requirement is to allow the kernel to send clock‑voting requests to the
>>>> ADSP. LPASS MCLK routing is not enabled by default on the ADSP, so the
>>>> kernel must explicitly request the ADSP to enable the relevant LPASS
>>>> MCLKs, which is a real hardware control requirement.
>>>>
>>>> These clocks are LPASS‑owned, and driving them via a third‑party codec
>>>> is not appropriate. The intent of adding clock capabilities at the DAI
>>>> level is to allow the kernel to associate LPASS clock votes with a
>>>> specific DAI instance during stream activity.
>>>>
>>>> While the DAI itself is not a physical device, some DT representation is
>>>> required to describe per‑DAI LPASS clock requirements.
>>>
>>> DT's purpose is not to describe software constructs, thus DT is not the
>>> answer to your requirement of mapping clocks to specific DAI needs.
>>> Every person adding software properties made "some DT representation is
>>> required" claim.
>>>
>>>>
>>>> I’m open to considering alternative representations, but removing this
>>>> entirely would leave no generic way for the kernel to handle correct
>>>> LPASS MCLK voting.
>>>
>>> I imagine that, since this is software construct, the software knows
>>> which DAI needs which clock. Clocks are strictly defined, thus driver
>>> should handle all this.
>>>
>>
>> No, the MCLK connection is not fixed to a specific DAI.
>>
>> The LPASS MCLKs
>> LPASS_CLK_ID_MCLK_1 … LPASS_CLK_ID_MCLK_5
>>
>> are hard‑wired connection, each physically routed to an external codec
>> on the board.
>>
>> Because of this, the clock that must be voted depends purely on the
>> hardware wiring, not on which DAI (Primary/Secondary/Tertiary/Quaternary
>> MI2S) is used.
>
> If they are routed to external codecs, then they are already present in
> these nodes and duplicating them here is not necessary.
>
>>
>> In other words, DAI ↔ MCLK is not a fixed mapping.
>>
>> Examples:
>> On Talos‑EVK, the speaker is connected via Primary MI2S, but the
>> corresponding MCLK line wired to the codec is LPASS_CLK_ID_MCLK_2.
>>
>> On Kodiak, the customer connected an SGTL5000 codec via Quaternary MI2S,
>> yet the required MCLK is still LPASS_CLK_ID_MCLK_2.
>>
>> Instead, the kernel must vote for the MCLK that is physically connected
>> to the external codec on that specific board.
>
> No, the external codec driver must vote for that MCLK.
>
I agree that when the MCLK provider is external, it is appropriate for
the codec driver to manage that clock. However, in this case the MCLK
provider is the LPASS/DSP subsystem itself, and the external codec is
only a consumer.
LPASS MCLKs configurations inside the DSP can be lost or reprogrammed
during DSP power collapse or subsystem restart (SSR).
Without visibility into LPASS lifecycle(SSR) events, a third‑party codec
driver cannot reliably perform clock voting or restoration, resulting in
broken or inconsistent audio behavior.
For these reasons, MCLK voting needs to remain owned by the LPASS/HLOS
drivers, which have awareness of DSP power state and board wiring,
Thanks & Regards,
Rafi.
> Best regards,
> Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode
2026-03-27 13:16 ` Mohammad Rafi Shaik
@ 2026-03-27 13:23 ` Krzysztof Kozlowski
0 siblings, 0 replies; 21+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-27 13:23 UTC (permalink / raw)
To: Mohammad Rafi Shaik
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
linux-sound, linux-arm-msm, devicetree, linux-kernel,
Srinivas Kandagatla
On 27/03/2026 14:16, Mohammad Rafi Shaik wrote:
>>
>>>
>>> In other words, DAI ↔ MCLK is not a fixed mapping.
>>>
>>> Examples:
>>> On Talos‑EVK, the speaker is connected via Primary MI2S, but the
>>> corresponding MCLK line wired to the codec is LPASS_CLK_ID_MCLK_2.
>>>
>>> On Kodiak, the customer connected an SGTL5000 codec via Quaternary MI2S,
>>> yet the required MCLK is still LPASS_CLK_ID_MCLK_2.
>>>
>>> Instead, the kernel must vote for the MCLK that is physically connected
>>> to the external codec on that specific board.
>>
>> No, the external codec driver must vote for that MCLK.
>>
>
> I agree that when the MCLK provider is external, it is appropriate for
> the codec driver to manage that clock. However, in this case the MCLK
> provider is the LPASS/DSP subsystem itself, and the external codec is
> only a consumer.
>
> LPASS MCLKs configurations inside the DSP can be lost or reprogrammed
> during DSP power collapse or subsystem restart (SSR).
>
> Without visibility into LPASS lifecycle(SSR) events, a third‑party codec
> driver cannot reliably perform clock voting or restoration, resulting in
> broken or inconsistent audio behavior.
>
> For these reasons, MCLK voting needs to remain owned by the LPASS/HLOS
> drivers, which have awareness of DSP power state and board wiring,
Sounds like you just brought driver model as the arguments here, so not
correct for DT.
But even if we speak about drivers, then I think I also assumption that
only clock consumer driver can manage the clock is not true. The
provider, so LPASS/DSP knows what is happening with entire audio so it
tracks the usage of its clocks and can perform clock
disable/unprepare/prepare/restoration or whatever there is needed.
Anyway, that's not important here. First argument is - you just wrote
stuff for drivers and that we don't want.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-03-27 13:23 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-09 11:12 [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control Mohammad Rafi Shaik
2026-03-09 11:12 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom,q6apm-lpass-dais: Document DAI subnode Mohammad Rafi Shaik
2026-03-09 19:55 ` Dmitry Baryshkov
2026-03-10 9:41 ` Mohammad Rafi Shaik
2026-03-10 9:55 ` Krzysztof Kozlowski
2026-03-17 5:27 ` Mohammad Rafi Shaik
2026-03-17 7:11 ` Krzysztof Kozlowski
2026-03-26 9:57 ` Mohammad Rafi Shaik
2026-03-26 10:10 ` Krzysztof Kozlowski
2026-03-27 13:16 ` Mohammad Rafi Shaik
2026-03-27 13:23 ` Krzysztof Kozlowski
2026-03-09 11:12 ` [PATCH v1 2/4] ASoC: qcom: qdsp6: q6prm: add the missing LPASS MCLK clock IDs Mohammad Rafi Shaik
2026-03-09 14:07 ` Srinivas Kandagatla
2026-03-10 9:30 ` Mohammad Rafi Shaik
2026-03-09 11:12 ` [PATCH v1 3/4] ASoC: qcom: q6apm-lpass-dais: Add MI2S clock control Mohammad Rafi Shaik
2026-03-11 18:25 ` kernel test robot
2026-03-09 11:13 ` [PATCH v1 4/4] ASoC: qcom: sc8280xp: ASoC: qcom: sc8280xp: enhance machine driver for board-specific config Mohammad Rafi Shaik
2026-03-10 11:44 ` Neil Armstrong
2026-03-17 5:35 ` Mohammad Rafi Shaik
2026-03-10 14:02 ` [PATCH v1 0/4] ASoC: qcom: qdsp6: Add MI2S clock control Neil Armstrong
2026-03-17 5:48 ` Mohammad Rafi Shaik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox