Devicetree
 help / color / mirror / Atom feed
* [PATCH 0/5] Add audio support for QCS6490 RubikPi3
@ 2026-06-06 18:58 Hongyang Zhao
  2026-06-06 18:58 ` [PATCH 1/5] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Hongyang Zhao @ 2026-06-06 18:58 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Daniel Drake, Katsuhiro Suzuki, Matteo Martelli,
	Binbin Zhou, Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-msm,
	Hongyang Zhao, mohammad.rafi.shaik, rosh, Krzysztof Kozlowski,
	Neil Armstrong, Srinivas Kandagatla

Add audio support for the Thundercomm RubikPi3 board based on QCS6490.

RubikPi3 uses AudioReach/GPR on the ADSP, an ES8316 headset codec on
primary MI2S, HDMI audio through the LT9611 bridge, and SPDIF TX/RX
on tertiary MI2S exposed on the 40-pin header.

The series first documents the ES8316 jack detect inversion property
and the board-specific Qualcomm sound card compatible. It then adds the
missing q6prm MCLK IDs required to drive the external codec MCLK.

The sc8280xp machine driver is extended with per-card data so the
RubikPi3 MI2S DAI format, MCLK, BE parameters and headset jack pins
can be handled without adding DAI format properties to devicetree.

The final patch describes the RubikPi3 audio hardware in devicetree.

Tested on Thundercomm RubikPi3:
- HDMI playback
- Headset playback and capture
- Headset jack detection

Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
Hongyang Zhao (4):
      ASoC: dt-bindings: es8316: Document jack detect inversion
      ASoC: dt-bindings: qcom,sm8250: Add QCS6490 RubikPi3 sound card
      ASoC: qcom: sc8280xp: Add per-card data
      arm64: dts: qcom: qcs6490-rubikpi3: Add audio support

Neil Armstrong (1):
      ASoC: qcom: qdsp6: q6prm: add the missing MCLK clock IDs

 .../devicetree/bindings/sound/everest,es8316.yaml  |   5 +
 .../devicetree/bindings/sound/qcom,sm8250.yaml     |   1 +
 .../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 196 +++++++++++++
 sound/soc/qcom/common.c                            |  75 ++++-
 sound/soc/qcom/common.h                            |   6 +-
 sound/soc/qcom/qdsp6/q6prm-clocks.c                |   5 +
 sound/soc/qcom/qdsp6/q6prm.h                       |  11 +
 sound/soc/qcom/sc8280xp.c                          | 319 +++++++++++++++++++--
 8 files changed, 575 insertions(+), 43 deletions(-)
---
base-commit: 6e845bcb78c95af935094040bd4edc3c2b6dd784
change-id: 20260605-rubikpi-next-20260605-fdda114824d7

Best regards,
--  
Hongyang Zhao <hongyang.zhao@thundersoft.com>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/5] ASoC: dt-bindings: es8316: Document jack detect inversion
  2026-06-06 18:58 [PATCH 0/5] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
@ 2026-06-06 18:58 ` Hongyang Zhao
  2026-06-06 18:58 ` [PATCH 2/5] ASoC: dt-bindings: qcom,sm8250: Add QCS6490 RubikPi3 sound card Hongyang Zhao
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Hongyang Zhao @ 2026-06-06 18:58 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Daniel Drake, Katsuhiro Suzuki, Matteo Martelli,
	Binbin Zhou, Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-msm,
	Hongyang Zhao, mohammad.rafi.shaik, rosh, Krzysztof Kozlowski

The ES8316 codec driver already supports the everest,jack-detect-inverted
property to invert the jack detection logic, but the property is not
documented in the devicetree binding.

Document the property.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
 Documentation/devicetree/bindings/sound/everest,es8316.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/everest,es8316.yaml b/Documentation/devicetree/bindings/sound/everest,es8316.yaml
index fe5d938ca310..a0a4c1c99cf3 100644
--- a/Documentation/devicetree/bindings/sound/everest,es8316.yaml
+++ b/Documentation/devicetree/bindings/sound/everest,es8316.yaml
@@ -60,6 +60,11 @@ properties:
   "#sound-dai-cells":
     const: 0
 
+  everest,jack-detect-inverted:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Defined to invert the jack detection.
+
 required:
   - compatible
   - reg

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/5] ASoC: dt-bindings: qcom,sm8250: Add QCS6490 RubikPi3 sound card
  2026-06-06 18:58 [PATCH 0/5] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
  2026-06-06 18:58 ` [PATCH 1/5] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
@ 2026-06-06 18:58 ` Hongyang Zhao
  2026-06-06 18:58 ` [PATCH 3/5] ASoC: qcom: qdsp6: q6prm: add the missing MCLK clock IDs Hongyang Zhao
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Hongyang Zhao @ 2026-06-06 18:58 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Daniel Drake, Katsuhiro Suzuki, Matteo Martelli,
	Binbin Zhou, Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-msm,
	Hongyang Zhao, mohammad.rafi.shaik, rosh

Add the thundercomm,qcs6490-rubikpi3-sndcard compatible for the QCS6490
Thundercomm RubikPi3 sound card.

Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
 Documentation/devicetree/bindings/sound/qcom,sm8250.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
index 15f38622b98b..d95e072fab25 100644
--- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
@@ -48,6 +48,7 @@ properties:
           - qcom,sm8250-sndcard
           - qcom,sm8450-sndcard
           - qcom,x1e80100-sndcard
+          - thundercomm,qcs6490-rubikpi3-sndcard
 
   audio-routing:
     $ref: /schemas/types.yaml#/definitions/non-unique-string-array

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/5] ASoC: qcom: qdsp6: q6prm: add the missing MCLK clock IDs
  2026-06-06 18:58 [PATCH 0/5] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
  2026-06-06 18:58 ` [PATCH 1/5] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
  2026-06-06 18:58 ` [PATCH 2/5] ASoC: dt-bindings: qcom,sm8250: Add QCS6490 RubikPi3 sound card Hongyang Zhao
@ 2026-06-06 18:58 ` Hongyang Zhao
  2026-06-06 18:58 ` [PATCH 4/5] ASoC: qcom: sc8280xp: Add per-card data Hongyang Zhao
  2026-06-06 18:58 ` [PATCH 5/5] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
  4 siblings, 0 replies; 8+ messages in thread
From: Hongyang Zhao @ 2026-06-06 18:58 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Daniel Drake, Katsuhiro Suzuki, Matteo Martelli,
	Binbin Zhou, Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-msm,
	Hongyang Zhao, mohammad.rafi.shaik, rosh, Neil Armstrong,
	Srinivas Kandagatla

From: Neil Armstrong <neil.armstrong@linaro.org>

Add the missing MCLK ids for the q6prm DSP interface.

Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
 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 4c574b48ab00..51b131fa9531 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 a988a32086fe..6917e70bcb8a 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.43.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/5] ASoC: qcom: sc8280xp: Add per-card data
  2026-06-06 18:58 [PATCH 0/5] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
                   ` (2 preceding siblings ...)
  2026-06-06 18:58 ` [PATCH 3/5] ASoC: qcom: qdsp6: q6prm: add the missing MCLK clock IDs Hongyang Zhao
@ 2026-06-06 18:58 ` Hongyang Zhao
  2026-06-06 21:28   ` sashiko-bot
  2026-06-06 18:58 ` [PATCH 5/5] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
  4 siblings, 1 reply; 8+ messages in thread
From: Hongyang Zhao @ 2026-06-06 18:58 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Daniel Drake, Katsuhiro Suzuki, Matteo Martelli,
	Binbin Zhou, Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-msm,
	Hongyang Zhao, mohammad.rafi.shaik, rosh

The sc8280xp machine driver currently uses the OF match data only as a
driver name, which makes it difficult to describe board-specific MI2S
codec requirements.

Convert the match data to a per-card data structure and add data for
the QCS6490 RubikPi3. The RubikPi3 data configures the ES8316 MI2S DAI
format, MCLK rate, BE hardware parameters and headset jack pins.

Add a common headset jack helper which accepts board-specific DAPM pins
for codecs that are not connected through the WCD TX codec DMA path.

Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
 sound/soc/qcom/common.c   |  75 ++++++++---
 sound/soc/qcom/common.h   |   6 +-
 sound/soc/qcom/sc8280xp.c | 319 ++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 357 insertions(+), 43 deletions(-)

diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c
index cf1f3a767cee..5e7a01418ad8 100644
--- a/sound/soc/qcom/common.c
+++ b/sound/soc/qcom/common.c
@@ -201,26 +201,30 @@ static struct snd_soc_jack_pin qcom_headset_jack_pins[] = {
 	},
 };
 
-int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
-			    struct snd_soc_jack *jack, bool *jack_setup)
+static int qcom_snd_headset_jack_init(struct snd_soc_card *card,
+				      struct snd_soc_jack *jack,
+				      bool *jack_setup,
+				      struct snd_soc_jack_pin *pins,
+				      unsigned int num_pins)
 {
-	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 snd_soc_card *card = rtd->card;
-	int rval, i;
+	int rval;
+
+	if (!pins) {
+		pins = qcom_headset_jack_pins;
+		num_pins = ARRAY_SIZE(qcom_headset_jack_pins);
+	}
 
 	if (!*jack_setup) {
 		rval = snd_soc_card_jack_new_pins(card, "Headset Jack",
-					     SND_JACK_HEADSET | SND_JACK_LINEOUT |
-					     SND_JACK_MECHANICAL |
-					     SND_JACK_BTN_0 | SND_JACK_BTN_1 |
-					     SND_JACK_BTN_2 | SND_JACK_BTN_3 |
-					     SND_JACK_BTN_4 | SND_JACK_BTN_5,
-					     jack, qcom_headset_jack_pins,
-					     ARRAY_SIZE(qcom_headset_jack_pins));
+						  SND_JACK_HEADSET | SND_JACK_LINEOUT |
+						  SND_JACK_MECHANICAL |
+						  SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+						  SND_JACK_BTN_2 | SND_JACK_BTN_3 |
+						  SND_JACK_BTN_4 | SND_JACK_BTN_5,
+						  jack, pins, num_pins);
 
 		if (rval < 0) {
-			dev_err(card->dev, "Unable to add Headphone Jack\n");
+			dev_err(card->dev, "Unable to add Headset Jack\n");
 			return rval;
 		}
 
@@ -231,6 +235,48 @@ int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
 		*jack_setup = true;
 	}
 
+	return 0;
+}
+
+int qcom_snd_headset_jack_setup(struct snd_soc_pcm_runtime *rtd,
+				struct snd_soc_jack *jack,
+				bool *jack_setup,
+				struct snd_soc_jack_pin *pins,
+				unsigned int num_pins)
+{
+	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
+	struct snd_soc_card *card = rtd->card;
+	int rval, i;
+
+	rval = qcom_snd_headset_jack_init(card, jack, jack_setup,
+					  pins, num_pins);
+	if (rval)
+		return rval;
+
+	for_each_rtd_codec_dais(rtd, i, codec_dai) {
+		rval = snd_soc_component_set_jack(codec_dai->component, jack, NULL);
+		if (rval != 0 && rval != -ENOTSUPP) {
+			dev_warn(card->dev, "Failed to set jack: %d\n", rval);
+			return rval;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(qcom_snd_headset_jack_setup);
+
+int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
+			    struct snd_soc_jack *jack, bool *jack_setup)
+{
+	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 snd_soc_card *card = rtd->card;
+	int rval, i;
+
+	rval = qcom_snd_headset_jack_init(card, jack, jack_setup, NULL, 0);
+	if (rval)
+		return rval;
+
 	switch (cpu_dai->id) {
 	case TX_CODEC_DMA_TX_0:
 	case TX_CODEC_DMA_TX_1:
@@ -250,7 +296,6 @@ int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
 		break;
 	}
 
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(qcom_snd_wcd_jack_setup);
diff --git a/sound/soc/qcom/common.h b/sound/soc/qcom/common.h
index ee6662885593..6d023f76f27e 100644
--- a/sound/soc/qcom/common.h
+++ b/sound/soc/qcom/common.h
@@ -10,10 +10,14 @@
 #define LPASS_MAX_PORT			(SENARY_MI2S_TX + 1)
 
 int qcom_snd_parse_of(struct snd_soc_card *card);
+int qcom_snd_headset_jack_setup(struct snd_soc_pcm_runtime *rtd,
+				struct snd_soc_jack *jack,
+				bool *jack_setup,
+				struct snd_soc_jack_pin *pins,
+				unsigned int num_pins);
 int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
 			    struct snd_soc_jack *jack, bool *jack_setup);
 int qcom_snd_dp_jack_setup(struct snd_soc_pcm_runtime *rtd,
 			   struct snd_soc_jack *dp_jack, int id);
 
-
 #endif
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 7925aa3f63ba..1ccd7437cc52 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -15,26 +15,127 @@
 #include "common.h"
 #include "sdw.h"
 
+struct sc8280xp_mi2s_codec_config {
+	unsigned int cpu_dai_id;
+	unsigned int dai_fmt;
+	unsigned int sysclk_rate;
+};
+
+struct sc8280xp_be_hw_params {
+	unsigned int rate;
+	snd_pcm_format_t format;
+	unsigned int channels_min;
+	unsigned int channels_max;
+};
+
+struct sc8280xp_be_hw_params_config {
+	unsigned int cpu_dai_id;
+	struct sc8280xp_be_hw_params hw_params;
+};
+
+struct sc8280xp_sndcard_data {
+	const char *driver_name;
+	struct sc8280xp_be_hw_params default_be_hw_params;
+	const struct sc8280xp_mi2s_codec_config *mi2s_codec_configs;
+	int num_mi2s_codec_configs;
+	const struct sc8280xp_be_hw_params_config *be_hw_params_configs;
+	int num_be_hw_params_configs;
+	const unsigned int *headset_jack_dais;
+	int num_headset_jack_dais;
+	struct snd_soc_jack_pin *headset_jack_pins;
+	unsigned int num_headset_jack_pins;
+};
+
 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];
+	const struct sc8280xp_sndcard_data *card_data;
 	bool jack_setup;
 };
 
+static const struct sc8280xp_mi2s_codec_config *
+sc8280xp_snd_get_mi2s_codec_config(const struct sc8280xp_sndcard_data *card_data,
+				   unsigned int cpu_dai_id)
+{
+	int i;
+
+	for (i = 0; i < card_data->num_mi2s_codec_configs; i++) {
+		if (card_data->mi2s_codec_configs[i].cpu_dai_id == cpu_dai_id)
+			return &card_data->mi2s_codec_configs[i];
+	}
+
+	return NULL;
+}
+
+static const struct sc8280xp_be_hw_params *
+sc8280xp_snd_get_be_hw_params(const struct sc8280xp_sndcard_data *card_data,
+			      unsigned int cpu_dai_id)
+{
+	int i;
+
+	for (i = 0; i < card_data->num_be_hw_params_configs; i++) {
+		if (card_data->be_hw_params_configs[i].cpu_dai_id == cpu_dai_id)
+			return &card_data->be_hw_params_configs[i].hw_params;
+	}
+
+	return NULL;
+}
+
+static bool sc8280xp_snd_is_headset_jack_dai(const struct sc8280xp_sndcard_data *card_data,
+					     unsigned int cpu_dai_id)
+{
+	int i;
+
+	for (i = 0; i < card_data->num_headset_jack_dais; i++) {
+		if (card_data->headset_jack_dais[i] == cpu_dai_id)
+			return true;
+	}
+
+	return false;
+}
+
 static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+	const struct sc8280xp_sndcard_data *card_data = data->card_data;
+	const struct sc8280xp_mi2s_codec_config *mi2s_config;
 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+	struct snd_soc_dai *codec_dai;
 	struct snd_soc_card *card = rtd->card;
 	struct snd_soc_jack *dp_jack  = NULL;
 	int dp_pcm_id = 0;
+	int i, ret;
 
 	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);
+
+		mi2s_config = sc8280xp_snd_get_mi2s_codec_config(card_data,
+								 cpu_dai->id);
+		if (mi2s_config) {
+			for_each_rtd_codec_dais(rtd, i, codec_dai) {
+				if (mi2s_config->dai_fmt) {
+					ret = snd_soc_dai_set_fmt(codec_dai,
+								  mi2s_config->dai_fmt);
+					if (ret && ret != -ENOTSUPP)
+						return ret;
+				}
+
+				if (mi2s_config->sysclk_rate) {
+					ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+								     mi2s_config->sysclk_rate,
+								     SND_SOC_CLOCK_IN);
+					if (ret && ret != -ENOTSUPP)
+						return dev_err_probe(card->dev, ret,
+								     "%s: failed to set sysclk for %s\n",
+								     rtd->dai_link->name,
+								     codec_dai->name);
+				}
+			}
+		}
 		break;
 	case WSA_CODEC_DMA_RX_0:
 	case WSA_CODEC_DMA_RX_1:
@@ -64,34 +165,56 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
 	if (dp_jack)
 		return qcom_snd_dp_jack_setup(rtd, dp_jack, dp_pcm_id);
 
+	if (sc8280xp_snd_is_headset_jack_dai(card_data, cpu_dai->id))
+		return qcom_snd_headset_jack_setup(rtd, &data->jack,
+						   &data->jack_setup,
+						   card_data->headset_jack_pins,
+						   card_data->num_headset_jack_pins);
+
+	if (card_data->headset_jack_dais)
+		return 0;
+
 	return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
 }
 
 static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
-				     struct snd_pcm_hw_params *params)
+				       struct snd_pcm_hw_params *params)
 {
+	struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+	const struct sc8280xp_sndcard_data *card_data = data->card_data;
+	const struct sc8280xp_be_hw_params *be_hw_params;
 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 	struct snd_interval *rate = hw_param_interval(params,
 					SNDRV_PCM_HW_PARAM_RATE);
 	struct snd_interval *channels = hw_param_interval(params,
 					SNDRV_PCM_HW_PARAM_CHANNELS);
 	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+	bool use_default = false;
 
-	rate->min = rate->max = 48000;
-	snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
-	channels->min = 2;
-	channels->max = 2;
-	switch (cpu_dai->id) {
-	case TX_CODEC_DMA_TX_0:
-	case TX_CODEC_DMA_TX_1:
-	case TX_CODEC_DMA_TX_2:
-	case TX_CODEC_DMA_TX_3:
-		channels->min = 1;
-		break;
-	default:
-		break;
+	be_hw_params = sc8280xp_snd_get_be_hw_params(card_data, cpu_dai->id);
+	if (!be_hw_params) {
+		be_hw_params = &card_data->default_be_hw_params;
+		use_default = true;
 	}
 
+	rate->min = be_hw_params->rate;
+	rate->max = be_hw_params->rate;
+	snd_mask_set_format(fmt, be_hw_params->format);
+	channels->min = be_hw_params->channels_min;
+	channels->max = be_hw_params->channels_max;
+
+	if (use_default) {
+		switch (cpu_dai->id) {
+		case TX_CODEC_DMA_TX_0:
+		case TX_CODEC_DMA_TX_1:
+		case TX_CODEC_DMA_TX_2:
+		case TX_CODEC_DMA_TX_3:
+			channels->min = 1;
+			break;
+		default:
+			break;
+		}
+	}
 
 	return 0;
 }
@@ -146,36 +269,178 @@ static int sc8280xp_platform_probe(struct platform_device *pdev)
 	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->card_data = of_device_get_match_data(dev);
+	if (!data->card_data)
+		return -EINVAL;
 
 	card->dev = dev;
+	card->driver_name = data->card_data->driver_name;
+
 	dev_set_drvdata(dev, card);
 	snd_soc_card_set_drvdata(card, data);
 	ret = qcom_snd_parse_of(card);
 	if (ret)
 		return ret;
 
-	card->driver_name = of_device_get_match_data(dev);
 	sc8280xp_add_be_ops(card);
 	return devm_snd_soc_register_card(dev, card);
 }
 
+#define SC8280XP_SND_DATA(_driver_name)				\
+	.driver_name = _driver_name,				\
+	.default_be_hw_params = {				\
+		.rate = 48000,					\
+		.format = SNDRV_PCM_FORMAT_S16_LE,		\
+		.channels_min = 2,				\
+		.channels_max = 2,				\
+	}
+
+static const struct sc8280xp_sndcard_data kaanapali_data = {
+	SC8280XP_SND_DATA("kaanapali"),
+};
+
+static const struct sc8280xp_sndcard_data qcm6490_data = {
+	SC8280XP_SND_DATA("qcm6490"),
+};
+
+static const struct sc8280xp_sndcard_data qcs615_data = {
+	SC8280XP_SND_DATA("qcs615"),
+};
+
+static const struct sc8280xp_sndcard_data qcs6490_data = {
+	SC8280XP_SND_DATA("qcs6490"),
+};
+
+static const struct sc8280xp_sndcard_data qcs8300_data = {
+	SC8280XP_SND_DATA("qcs8300"),
+};
+
+static const struct sc8280xp_mi2s_codec_config qcs6490_rubikpi3_mi2s_codec_configs[] = {
+	{
+		.cpu_dai_id = PRIMARY_MI2S_RX,
+		.dai_fmt = SND_SOC_DAIFMT_BC_FC |
+			   SND_SOC_DAIFMT_NB_NF |
+			   SND_SOC_DAIFMT_I2S,
+		.sysclk_rate = 19200000,
+	},
+	{
+		.cpu_dai_id = PRIMARY_MI2S_TX,
+		.dai_fmt = SND_SOC_DAIFMT_BC_FC |
+			   SND_SOC_DAIFMT_NB_NF |
+			   SND_SOC_DAIFMT_I2S,
+		.sysclk_rate = 19200000,
+	},
+};
+
+static const unsigned int qcs6490_rubikpi3_headset_jack_dais[] = {
+	PRIMARY_MI2S_RX,
+};
+
+static struct snd_soc_jack_pin qcs6490_rubikpi3_headset_jack_pins[] = {
+	{
+		.pin = "Mic Jack",
+		.mask = SND_JACK_HEADPHONE,
+	},
+	{
+		.pin = "Headphone Jack",
+		.mask = SND_JACK_HEADPHONE,
+	},
+};
+
+static const struct sc8280xp_be_hw_params_config qcs6490_rubikpi3_be_hw_params_configs[] = {
+	{
+		.cpu_dai_id = PRIMARY_MI2S_TX,
+		.hw_params = {
+			.rate = 48000,
+			.format = SNDRV_PCM_FORMAT_S16_LE,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+	},
+	{
+		.cpu_dai_id = QUATERNARY_MI2S_RX,
+		.hw_params = {
+			.rate = 48000,
+			.format = SNDRV_PCM_FORMAT_S16_LE,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+	},
+	{
+		.cpu_dai_id = TERTIARY_MI2S_RX,
+		.hw_params = {
+			.rate = 48000,
+			.format = SNDRV_PCM_FORMAT_S32_LE,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+	},
+	{
+		.cpu_dai_id = TERTIARY_MI2S_TX,
+		.hw_params = {
+			.rate = 48000,
+			.format = SNDRV_PCM_FORMAT_S32_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+	},
+};
+
+static const struct sc8280xp_sndcard_data qcs6490_rubikpi3_data = {
+	SC8280XP_SND_DATA("qcs6490"),
+	.mi2s_codec_configs = qcs6490_rubikpi3_mi2s_codec_configs,
+	.num_mi2s_codec_configs = ARRAY_SIZE(qcs6490_rubikpi3_mi2s_codec_configs),
+	.be_hw_params_configs = qcs6490_rubikpi3_be_hw_params_configs,
+	.num_be_hw_params_configs = ARRAY_SIZE(qcs6490_rubikpi3_be_hw_params_configs),
+	.headset_jack_dais = qcs6490_rubikpi3_headset_jack_dais,
+	.num_headset_jack_dais = ARRAY_SIZE(qcs6490_rubikpi3_headset_jack_dais),
+	.headset_jack_pins = qcs6490_rubikpi3_headset_jack_pins,
+	.num_headset_jack_pins = ARRAY_SIZE(qcs6490_rubikpi3_headset_jack_pins),
+};
+
+static const struct sc8280xp_sndcard_data sa8775p_data = {
+	SC8280XP_SND_DATA("sa8775p"),
+};
+
+static const struct sc8280xp_sndcard_data sc8280xp_data = {
+	SC8280XP_SND_DATA("sc8280xp"),
+};
+
+static const struct sc8280xp_sndcard_data sm8450_data = {
+	SC8280XP_SND_DATA("sm8450"),
+};
+
+static const struct sc8280xp_sndcard_data sm8550_data = {
+	SC8280XP_SND_DATA("sm8550"),
+};
+
+static const struct sc8280xp_sndcard_data sm8650_data = {
+	SC8280XP_SND_DATA("sm8650"),
+};
+
+static const struct sc8280xp_sndcard_data sm8750_data = {
+	SC8280XP_SND_DATA("sm8750"),
+};
+
 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 = "thundercomm,qcs6490-rubikpi3-sndcard", .data = &qcs6490_rubikpi3_data },
+	{ .compatible = "qcom,kaanapali-sndcard", .data = &kaanapali_data },
+	{ .compatible = "qcom,qcm6490-idp-sndcard", .data = &qcm6490_data },
+	{ .compatible = "qcom,qcs615-sndcard", .data = &qcs615_data },
+	{ .compatible = "qcom,qcs6490-rb3gen2-sndcard", .data = &qcs6490_data },
+	{ .compatible = "qcom,qcs8275-sndcard", .data = &qcs8300_data },
+	{ .compatible = "qcom,qcs9075-sndcard", .data = &sa8775p_data },
+	{ .compatible = "qcom,qcs9100-sndcard", .data = &sa8775p_data },
+	{ .compatible = "qcom,sc8280xp-sndcard", .data = &sc8280xp_data },
+	{ .compatible = "qcom,sm8450-sndcard", .data = &sm8450_data },
+	{ .compatible = "qcom,sm8550-sndcard", .data = &sm8550_data },
+	{ .compatible = "qcom,sm8650-sndcard", .data = &sm8650_data },
+	{ .compatible = "qcom,sm8750-sndcard", .data = &sm8750_data },
 	{}
 };
 

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/5] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
  2026-06-06 18:58 [PATCH 0/5] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
                   ` (3 preceding siblings ...)
  2026-06-06 18:58 ` [PATCH 4/5] ASoC: qcom: sc8280xp: Add per-card data Hongyang Zhao
@ 2026-06-06 18:58 ` Hongyang Zhao
  2026-06-06 21:33   ` sashiko-bot
  4 siblings, 1 reply; 8+ messages in thread
From: Hongyang Zhao @ 2026-06-06 18:58 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Daniel Drake, Katsuhiro Suzuki, Matteo Martelli,
	Binbin Zhou, Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-msm,
	Hongyang Zhao, mohammad.rafi.shaik, rosh

Add audio support for the Thundercomm RubikPi3 board.

Enable AudioReach and describe the ES8316 headset codec, the LT9611
HDMI codec endpoint and the SPDIF TX/RX endpoints exposed on the
40-pin header. Add the sound card DAI links, LPASS pin configuration
and ES8316 fixed 3.3V supply.

Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
 .../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 196 +++++++++++++++++++++
 1 file changed, 196 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
index f47efca42d48..3249176b4c77 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
@@ -19,6 +19,7 @@
 #include "pm7325.dtsi"
 #include "pm8350c.dtsi" /* PM7350C */
 #include "pmk8350.dtsi" /* PMK7325 */
+#include "qcs6490-audioreach.dtsi"
 
 /delete-node/ &adsp_mem;
 /delete-node/ &cdsp_mem;
@@ -128,6 +129,23 @@ fan0: pwm-fan {
 		pinctrl-names = "default";
 	};
 
+	vreg_es8316_3v3: vreg-es8316-3v3 {
+		compatible = "regulator-fixed";
+
+		regulator-name = "vreg_es8316_3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+
+		gpio = <&tlmm 117 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+
+		pinctrl-0 = <&es8316_power_on>;
+		pinctrl-names = "default";
+
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
 	vreg_eth_1v8: regulator-eth-1v8 {
 		compatible = "regulator-fixed";
 
@@ -346,6 +364,16 @@ active-config0 {
 		};
 	};
 
+	spdif_rx: spdif-rx {
+		compatible = "linux,spdif-dir";
+		#sound-dai-cells = <0>;
+	};
+
+	spdif_tx: spdif-tx {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+	};
+
 	usb1-sbu-mux {
 		compatible = "pericom,pi3usb102", "gpio-sbu-mux";
 
@@ -727,6 +755,23 @@ &gpu_zap_shader {
 	firmware-name = "qcom/qcs6490/a660_zap.mbn";
 };
 
+&i2c0 {
+	status = "okay";
+
+	es8316: audio-codec@11 {
+		compatible = "everest,es8316";
+		reg = <0x11>;
+		#sound-dai-cells = <0>;
+
+		clocks = <&q6prmcc LPASS_CLK_ID_MCLK_1 LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+		clock-names = "mclk";
+
+		interrupts-extended = <&tlmm 63 IRQ_TYPE_EDGE_BOTH>;
+
+		everest,jack-detect-inverted;
+	};
+};
+
 /* Pin 3, 5 in 40-pin connector */
 &i2c1 {
 	status = "okay";
@@ -740,6 +785,7 @@ &i2c9 {
 	lt9611_codec: hdmi-bridge@39 {
 		compatible = "lontium,lt9611";
 		reg = <0x39>;
+		#sound-dai-cells = <1>;
 
 		interrupts-extended = <&tlmm 20 IRQ_TYPE_EDGE_FALLING>;
 		reset-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
@@ -970,6 +1016,15 @@ &pon_resin {
 	status = "okay";
 };
 
+&q6apmbedai {
+	pinctrl-0 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>,
+		    <&mi2s0_sclk>, <&mi2s0_ws>,
+		    <&lpass_qua_mi2s_sclk>, <&lpass_qua_mi2s_ws>, <&lpass_qua_mi2s_data>,
+		    <&lpass_lpi_i2s1_clk>, <&lpass_lpi_i2s1_ws>,
+		    <&lpass_lpi_i2s1_data0>, <&lpass_lpi_i2s1_data1>;
+	pinctrl-names = "default";
+};
+
 &qupv3_id_0 {
 	firmware-name = "qcom/qcm6490/qupv3fw.elf";
 
@@ -1006,6 +1061,96 @@ &sdhc_2 {
 	status = "okay";
 };
 
+&sound {
+	compatible = "thundercomm,qcs6490-rubikpi3-sndcard";
+	model = "QCS6490-Thundercomm-RubikPi3";
+
+	audio-routing =
+		"Headphone Jack", "HPOL",
+		"Headphone Jack", "HPOR",
+		"MIC2", "Mic Jack";
+
+	mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-PRIMARY";
+
+		codec {
+			sound-dai = <&es8316>;
+		};
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+		};
+
+		platform {
+			sound-dai = <&q6apm>;
+		};
+	};
+
+	mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-PRIMARY";
+
+		codec {
+			sound-dai = <&es8316>;
+		};
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+		};
+
+		platform {
+			sound-dai = <&q6apm>;
+		};
+	};
+
+	quaternary-mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF_RXTX-RX-PRIMARY";
+
+		codec {
+			sound-dai = <&lt9611_codec 0>;
+		};
+
+		cpu {
+			sound-dai = <&q6apmbedai QUATERNARY_MI2S_RX>;
+		};
+
+		platform {
+			sound-dai = <&q6apm>;
+		};
+	};
+
+	tert-mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-TERTIARY";
+
+		codec {
+			sound-dai = <&spdif_tx>;
+		};
+
+		cpu {
+			sound-dai = <&q6apmbedai TERTIARY_MI2S_RX>;
+		};
+
+		platform {
+			sound-dai = <&q6apm>;
+		};
+	};
+
+	tert-mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-TERTIARY";
+
+		codec {
+			sound-dai = <&spdif_rx>;
+		};
+
+		cpu {
+			sound-dai = <&q6apmbedai TERTIARY_MI2S_TX>;
+		};
+
+		platform {
+			sound-dai = <&q6apm>;
+		};
+	};
+};
+
 /* Pin 19, 21, 23, 24 in 40-pin connector */
 &spi12 {
 	status = "okay";
@@ -1220,6 +1365,50 @@ &sdc2_data {
 	drive-strength = <10>;
 };
 
+&lpass_tlmm {
+	lpass_qua_mi2s_sclk: qua-mi2s-sclk-state {
+		pins = "gpio0";
+		function = "qua_mi2s_sclk";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	lpass_qua_mi2s_ws: qua-mi2s-ws-state {
+		pins = "gpio1";
+		function = "qua_mi2s_ws";
+		drive-strength = <8>;
+		output-high;
+	};
+
+	lpass_qua_mi2s_data: qua-mi2s-data-state {
+		pins = "gpio2", "gpio3", "gpio4";
+		function = "qua_mi2s_data";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	lpass_lpi_i2s1_clk: lpi-i2s1-clk-state {
+		pins = "gpio6";
+		function = "i2s1_clk";
+	};
+
+	lpass_lpi_i2s1_ws: lpi-i2s1-ws-state {
+		pins = "gpio7";
+		function = "i2s1_ws";
+	};
+
+	lpass_lpi_i2s1_data0: lpi-i2s1-data0-state {
+		pins = "gpio8";
+		function = "i2s1_data";
+	};
+
+	lpass_lpi_i2s1_data1: lpi-i2s1-data1-state {
+		pins = "gpio9";
+		function = "i2s1_data";
+	};
+};
+
 &tlmm {
 	pcie1_reset_n: pcie1-reset-n-state {
 		pins = "gpio2";
@@ -1387,6 +1576,13 @@ pcie0_wake_n: pcie0-wake-n-state {
 		bias-pull-up;
 	};
 
+	es8316_power_on: es8316-power-on-state {
+		pins = "gpio117";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+	};
+
 	wifi_power_on: wifi-power-on-state {
 		pins = "gpio125";
 		function = "gpio";

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/5] ASoC: qcom: sc8280xp: Add per-card data
  2026-06-06 18:58 ` [PATCH 4/5] ASoC: qcom: sc8280xp: Add per-card data Hongyang Zhao
@ 2026-06-06 21:28   ` sashiko-bot
  0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-06-06 21:28 UTC (permalink / raw)
  To: Hongyang Zhao; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Incorrect DAPM pin mask for 'Mic Jack' in qcs6490_rubikpi3_headset_jack_pins causes microphone detection failure.
--

commit 869054356ad0f6ae035a50e1d5d5e99577638b9b
Author: Hongyang Zhao <hongyang.zhao@thundersoft.com>

ASoC: qcom: sc8280xp: Add per-card data

This commit converts the sc8280xp machine driver match data to a per-card data
structure to support board-specific MI2S codec requirements. It adds data for
the QCS6490 RubikPi3 and a common headset jack helper.

> diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
> index 7925aa3f63ba0..1ccd7437cc52d 100644
> --- a/sound/soc/qcom/sc8280xp.c
> +++ b/sound/soc/qcom/sc8280xp.c

[ ... ]

> +static struct snd_soc_jack_pin qcs6490_rubikpi3_headset_jack_pins[] = {
> +	{
> +		.pin = "Mic Jack",
> +		.mask = SND_JACK_HEADPHONE,

[Severity: Medium]
Does this mask prevent correct DAPM routing for the microphone? It looks like
SND_JACK_HEADPHONE is used instead of SND_JACK_MICROPHONE for the Mic Jack pin.

> +	},
> +	{
> +		.pin = "Headphone Jack",
> +		.mask = SND_JACK_HEADPHONE,
> +	},
> +};

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260607-rubikpi-next-20260605-v1-0-7f334e16fea6@thundersoft.com?part=4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 5/5] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
  2026-06-06 18:58 ` [PATCH 5/5] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
@ 2026-06-06 21:33   ` sashiko-bot
  0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-06-06 21:33 UTC (permalink / raw)
  To: Hongyang Zhao; +Cc: conor+dt, robh, devicetree

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Missing pinctrl configuration for the ES8316 headphone jack detect interrupt pin.
- [Medium] Hardware interface mismatch for the AudioReach SPDIF endpoint, mapping LPI I2S pins to the non-LPI Tertiary MI2S DAI.
- [Low] Mismatch in interrupt trigger type between the Device Tree and the ES8316 codec driver.
--

commit 078ec2554bd70bae155ad4d9140ebdc8a69a5dec
Author: Hongyang Zhao <hongyang.zhao@thundersoft.com>

arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
    
This commit adds audio support for the Thundercomm RubikPi3 board. It enables
AudioReach, the ES8316 headset codec, LT9611 HDMI codec, and SPDIF endpoints.
It also describes the sound card DAI links and LPASS pin configurations.

> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
> index f47efca42d48d..3249176b4c778 100644
> --- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
[ ... ]
> @@ -727,6 +755,23 @@ &gpu_zap_shader {
>  	firmware-name = "qcom/qcs6490/a660_zap.mbn";
>  };
>  
> +&i2c0 {
> +	status = "okay";
> +
> +	es8316: audio-codec@11 {
> +		compatible = "everest,es8316";
> +		reg = <0x11>;
> +		#sound-dai-cells = <0>;
> +
> +		clocks = <&q6prmcc LPASS_CLK_ID_MCLK_1 LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
> +		clock-names = "mclk";
> +
> +		interrupts-extended = <&tlmm 63 IRQ_TYPE_EDGE_BOTH>;

[Severity: High]
Are we missing the pinctrl configuration for this interrupt pin?

The es8316 node declares an interrupt on tlmm GPIO 63, but there doesn't
appear to be a corresponding pinctrl-0 property to mux the pin and set its
bias (e.g., bias-disable or bias-pull-down).

Could this leave the interrupt line floating and trigger an interrupt storm?

[Severity: Low]
Is IRQ_TYPE_EDGE_BOTH correct for this codec?

The device tree configures the ES8316 interrupt as IRQ_TYPE_EDGE_BOTH,
but the driver explicitly requests IRQF_TRIGGER_HIGH when it calls
devm_request_threaded_irq().

While the kernel safely overrides the DT configuration with the driver's
request via __irq_set_trigger(), does the DT need an update to match the
actual hardware configuration applied?

> +
> +		everest,jack-detect-inverted;
> +	};
> +};
> +
[ ... ]
> @@ -1006,6 +1061,96 @@ &sdhc_2 {
>  	status = "okay";
>  };
>  
> +&sound {
> +	compatible = "thundercomm,qcs6490-rubikpi3-sndcard";
> +	model = "QCS6490-Thundercomm-RubikPi3";
[ ... ]
> +	tert-mi2s-playback-dai-link {
> +		link-name = "MI2S-LPAIF-RX-TERTIARY";
> +
> +		codec {
> +			sound-dai = <&spdif_tx>;
> +		};
> +
> +		cpu {
> +			sound-dai = <&q6apmbedai TERTIARY_MI2S_RX>;

[Severity: Medium]
Is this DAI link binding to the correct hardware interface?

The physical pins are configured for the LPI I2S1 interface earlier in
q6apmbedai:

&q6apmbedai {
        pinctrl-0 = <&mi2s0_data0>, ...
                    <&lpass_lpi_i2s1_clk>, <&lpass_lpi_i2s1_ws>,
                    <&lpass_lpi_i2s1_data0>, <&lpass_lpi_i2s1_data1>;
}

However, this DAI link binds the CPU DAI to TERTIARY_MI2S_RX, which
corresponds to the main LPAIF Tertiary MI2S hardware block rather than
the LPI I2S1 interface.

Will this cause the AudioReach DSP to route audio to the main LPAIF instead,
leaving the SPDIF pins on the 40-pin header silent?

> +		};
> +
> +		platform {
> +			sound-dai = <&q6apm>;
> +		};
> +	};

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260607-rubikpi-next-20260605-v1-0-7f334e16fea6@thundersoft.com?part=5

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-06-06 21:33 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-06 18:58 [PATCH 0/5] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
2026-06-06 18:58 ` [PATCH 1/5] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
2026-06-06 18:58 ` [PATCH 2/5] ASoC: dt-bindings: qcom,sm8250: Add QCS6490 RubikPi3 sound card Hongyang Zhao
2026-06-06 18:58 ` [PATCH 3/5] ASoC: qcom: qdsp6: q6prm: add the missing MCLK clock IDs Hongyang Zhao
2026-06-06 18:58 ` [PATCH 4/5] ASoC: qcom: sc8280xp: Add per-card data Hongyang Zhao
2026-06-06 21:28   ` sashiko-bot
2026-06-06 18:58 ` [PATCH 5/5] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
2026-06-06 21:33   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox