* [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3
@ 2026-07-15 14:02 Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
` (6 more replies)
0 siblings, 7 replies; 13+ messages in thread
From: Hongyang Zhao @ 2026-07-15 14:02 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: Mohammad Rafi Shaik, Neil Armstrong, Dmitry Baryshkov,
Roger Shimizu, linux-sound, devicetree, linux-kernel,
linux-arm-msm, Hongyang Zhao, Krzysztof Kozlowski
Add audio support for the Thundercomm RubikPi3 board based on QCS6490.
RubikPi3 uses AudioReach/GPR on the ADSP. An ES8316 codec connected to
primary MI2S provides headset playback, headset capture and jack
detection. The LT9611 bridge connected to quaternary MI2S provides HDMI
audio playback.
The series first documents the existing ES8316 jack-detect inversion
property and adds a board-specific Qualcomm sound-card compatible. A
generic Qualcomm headset helper is then added for codecs which implement
component jack detection but are not connected through a WCD codec DMA
link.
The sc8280xp machine driver board data is converted to a per-DAI
representation. This allows each backend to select its own DAI format,
clock programming and jack setup. RubikPi3 uses this to drive the ES8316
with a 19.2 MHz MCLK and to avoid unsupported sysclk programming on the
LT9611 HDMI link.
The final patch describes the two audio paths, clocks, pin control,
codec power and jack-detect wiring in the RubikPi3 device tree.
This series is based on next-20260710 and depends on Rafi's
q6apm-lpass-dais MI2S clock control series and Neil's q6prm MCLK clock
ID patch:
Depends-on: https://lore.kernel.org/all/20260714145250.2473461-1-mohammad.rafi.shaik@oss.qualcomm.com/
Depends-on: https://lore.kernel.org/all/20251008-topic-sm8x50-next-hdk-i2s-v2-1-6b7d38d4ad5e@linaro.org/
Tested on Thundercomm RubikPi3:
- HDMI playback
- Headset playback and capture
- Headset jack detection
Changes in v2:
- Rebased onto next-20260710 and Rafi's latest q6apm-lpass-dais MI2S
clock control series (v5).
- Dropped the bundled q6prm MCLK ID patch and added a dependency on
Neil's existing patch.
- Split the generic headset helper, per-DAI driver refactoring and
RubikPi3 machine data into separate patches.
- Reworked the sc8280xp board data from global flags to per-DAI
configuration and migrated existing users.
- Explained why the existing QCM6490 and QCS6490 sound-card compatibles
cannot be reused for RubikPi3.
- Moved MI2S pin control to the sound card and fixed audio-routing
formatting as requested during v1 review.
- Added primary MI2S backend clock subnodes for MCLK and BCLK control.
- Dropped the untested SPDIF links from the device tree.
- Verified HDMI and headset playback, headset capture and jack detection
on hardware.
Link: https://lore.kernel.org/all/20260607-rubikpi-next-20260605-v1-0-7f334e16fea6@thundersoft.com/
Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
Hongyang Zhao (6):
ASoC: dt-bindings: es8316: Document jack detect inversion
ASoC: dt-bindings: qcom,sm8250: Add RubikPi 3 sound card
ASoC: qcom: common: Add generic headset jack helpers
ASoC: qcom: sc8280xp: Add per-DAI board configuration
ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support
arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
.../devicetree/bindings/sound/everest,es8316.yaml | 5 +
.../devicetree/bindings/sound/qcom,sm8250.yaml | 1 +
.../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 159 ++++++++++++++++++
sound/soc/qcom/common.c | 61 ++++++-
sound/soc/qcom/common.h | 3 +
sound/soc/qcom/sc8280xp.c | 177 ++++++++++++++++++---
6 files changed, 375 insertions(+), 31 deletions(-)
---
base-commit: bee763d5f341b99cf472afeb508d4988f62a6ca1
change-id: 20260605-rubikpi-next-20260605-fdda114824d7
prerequisite-message-id: <20260714145250.2473461-1-mohammad.rafi.shaik@oss.qualcomm.com>
prerequisite-patch-id: 2e26f868c659376d3a1dd4c3e3d34ddb24aa226d
prerequisite-patch-id: aa51a266a595ff79730f56920b7c552e53285869
prerequisite-patch-id: b469932718c83bffa60b62c84dfc4cc8abc199e3
prerequisite-patch-id: 2f1bd3efac328030dd8efe28fb95f84603868043
Best regards,
--
Hongyang Zhao <hongyang.zhao@thundersoft.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion
2026-07-15 14:02 [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
@ 2026-07-15 14:02 ` Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 2/6] ASoC: dt-bindings: qcom,sm8250: Add RubikPi 3 sound card Hongyang Zhao
` (5 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Hongyang Zhao @ 2026-07-15 14:02 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: Mohammad Rafi Shaik, Neil Armstrong, Dmitry Baryshkov,
Roger Shimizu, linux-sound, devicetree, linux-kernel,
linux-arm-msm, Hongyang Zhao, Krzysztof Kozlowski
The ES8316 driver supports the everest,jack-detect-inverted property to
account for boards which invert the codec jack-detect signal. However,
the property is not described by the binding, so a valid user of the
driver fails schema validation because the binding rejects unknown
properties.
Document the flag so boards can describe the jack-detect polarity used
by their wiring.
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] 13+ messages in thread
* [PATCH v2 2/6] ASoC: dt-bindings: qcom,sm8250: Add RubikPi 3 sound card
2026-07-15 14:02 [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
@ 2026-07-15 14:02 ` Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 3/6] ASoC: qcom: common: Add generic headset jack helpers Hongyang Zhao
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Hongyang Zhao @ 2026-07-15 14:02 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: Mohammad Rafi Shaik, Neil Armstrong, Dmitry Baryshkov,
Roger Shimizu, linux-sound, devicetree, linux-kernel,
linux-arm-msm, Hongyang Zhao
The QCS6490-based Thundercomm RubikPi 3 routes primary MI2S to an
external ES8316 headset codec and quaternary MI2S to the LT9611 HDMI
bridge. This requires board-specific DAI clocking and jack setup in the
sc8280xp machine driver.
The existing QCM6490 and QCS6490 compatibles select machine data for
boards using different codec and audio routing arrangements, so they
cannot be used as compatible fallbacks for RubikPi 3.
Add a dedicated compatible to select the RubikPi 3 machine data.
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 dae440ecab59..01bc494286fb 100644
--- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
@@ -49,6 +49,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] 13+ messages in thread
* [PATCH v2 3/6] ASoC: qcom: common: Add generic headset jack helpers
2026-07-15 14:02 [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 2/6] ASoC: dt-bindings: qcom,sm8250: Add RubikPi 3 sound card Hongyang Zhao
@ 2026-07-15 14:02 ` Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 4/6] ASoC: qcom: sc8280xp: Add per-DAI board configuration Hongyang Zhao
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Hongyang Zhao @ 2026-07-15 14:02 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: Mohammad Rafi Shaik, Neil Armstrong, Dmitry Baryshkov,
Roger Shimizu, linux-sound, devicetree, linux-kernel,
linux-arm-msm, Hongyang Zhao
qcom_snd_wcd_jack_setup() combines creation of the card-level headset
jack with the WCD-specific operation of attaching jack detection to
codecs on the TX codec DMA links. External codecs connected over MI2S
also provide component jack detection, but cannot use the WCD-specific
DAI filtering.
Factor the common jack allocation, DAPM pin registration and headset
button mappings into a private initializer. Reuse it from the existing
WCD path and add a generic setup helper which attaches the jack to every
codec component in a runtime.
Add a matching cleanup helper so machine drivers can detach component
jack detection when the DAI link exits. The WCD setup behavior remains
unchanged.
Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
sound/soc/qcom/common.c | 61 ++++++++++++++++++++++++++++++++++++++++++-------
sound/soc/qcom/common.h | 3 +++
2 files changed, 56 insertions(+), 8 deletions(-)
diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c
index edc4611691f7..c48819a0ed78 100644
--- a/sound/soc/qcom/common.c
+++ b/sound/soc/qcom/common.c
@@ -184,13 +184,11 @@ 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_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 (!*jack_setup) {
rval = snd_soc_card_jack_new_pins(card, "Headset Jack",
@@ -214,6 +212,55 @@ 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_dai *codec_dai;
+ struct snd_soc_card *card = rtd->card;
+ int rval, i;
+
+ rval = qcom_snd_headset_jack_init(card, jack, jack_setup);
+ 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);
+ qcom_snd_headset_jack_cleanup(rtd);
+ return rval;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qcom_snd_headset_jack_setup);
+
+void qcom_snd_headset_jack_cleanup(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_dai *codec_dai;
+ int i;
+
+ for_each_rtd_codec_dais(rtd, i, codec_dai)
+ snd_soc_component_set_jack(codec_dai->component, NULL, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_snd_headset_jack_cleanup);
+
+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);
+ if (rval)
+ return rval;
+
switch (cpu_dai->id) {
case TX_CODEC_DMA_TX_0:
case TX_CODEC_DMA_TX_1:
@@ -232,8 +279,6 @@ int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
default:
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..0a255b08e873 100644
--- a/sound/soc/qcom/common.h
+++ b/sound/soc/qcom/common.h
@@ -10,6 +10,9 @@
#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);
+void qcom_snd_headset_jack_cleanup(struct snd_soc_pcm_runtime *rtd);
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,
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 4/6] ASoC: qcom: sc8280xp: Add per-DAI board configuration
2026-07-15 14:02 [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
` (2 preceding siblings ...)
2026-07-15 14:02 ` [PATCH v2 3/6] ASoC: qcom: common: Add generic headset jack helpers Hongyang Zhao
@ 2026-07-15 14:02 ` Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support Hongyang Zhao
` (2 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Hongyang Zhao @ 2026-07-15 14:02 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: Mohammad Rafi Shaik, Neil Armstrong, Dmitry Baryshkov,
Roger Shimizu, linux-sound, devicetree, linux-kernel,
linux-arm-msm, Hongyang Zhao
The board data currently applies codec format, sysclk, MI2S clock and
jack setup policy to every backend DAI on a sound card. That works for
boards with a uniform audio topology, but it cannot describe a card
which connects codecs with different clock requirements to different
MI2S interfaces.
Introduce an optional per-DAI configuration table indexed by the CPU DAI
ID. Each entry can select the codec DAI format, override the MCLK rate,
enable CPU MCLK and BCLK programming, request codec sysclk setup and
choose the jack setup path. Use one jack setup enum instead of unrelated
boolean flags so a DAI cannot select conflicting setup methods.
Migrate the existing WCD headset cards to the new representation. All
in-tree WCD capture links handled by this driver use TX_CODEC_DMA_TX_3;
cards sharing a compatible but lacking that link simply have no matching
runtime. This preserves existing behavior while allowing mixed-codec
cards to configure each link independently.
Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
sound/soc/qcom/sc8280xp.c | 138 ++++++++++++++++++++++++++++++++++++++--------
1 file changed, 115 insertions(+), 23 deletions(-)
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 109e39b93b2d..885ec1e3e575 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -37,6 +37,26 @@ static struct snd_soc_dapm_widget sc8280xp_dapm_widgets[] = {
SND_SOC_DAPM_SPK("DP7 Jack", NULL),
};
+enum sc8280xp_jack_setup {
+ SC8280XP_JACK_SETUP_NONE,
+ SC8280XP_JACK_SETUP_CODEC,
+ SC8280XP_JACK_SETUP_WCD,
+};
+
+struct sc8280xp_dai_data {
+ unsigned int id;
+ unsigned int codec_dai_fmt;
+ unsigned int mclk_rate;
+ bool codec_sysclk_set;
+ bool mi2s_mclk_enable;
+ bool mi2s_bclk_enable;
+ enum sc8280xp_jack_setup jack_setup;
+};
+
+#define SC8280XP_DAI_DATA(...) \
+ .dai_data = (const struct sc8280xp_dai_data[]) { __VA_ARGS__ }, \
+ .num_dai_data = ARRAY_SIZE(((const struct sc8280xp_dai_data[]) { __VA_ARGS__ }))
+
struct snd_soc_common {
const char *driver_name;
const struct snd_soc_dapm_widget *dapm_widgets;
@@ -45,11 +65,8 @@ struct snd_soc_common {
int num_dapm_routes;
const struct snd_kcontrol_new *controls;
int num_controls;
- unsigned int codec_dai_fmt;
- bool codec_sysclk_set;
- bool mi2s_mclk_enable;
- bool mi2s_bclk_enable;
- bool wcd_jack;
+ const struct sc8280xp_dai_data *dai_data;
+ size_t num_dai_data;
};
struct sc8280xp_snd_data {
@@ -61,6 +78,20 @@ struct sc8280xp_snd_data {
bool jack_setup;
};
+static const struct sc8280xp_dai_data *sc8280xp_get_dai_data(
+ const struct snd_soc_common *common,
+ unsigned int id)
+{
+ size_t i;
+
+ for (i = 0; i < common->num_dai_data; i++) {
+ if (common->dai_data[i].id == id)
+ return &common->dai_data[i];
+ }
+
+ return NULL;
+}
+
static inline int sc8280xp_get_mclk_freq(struct snd_pcm_hw_params *params)
{
int rate = params_rate(params);
@@ -88,10 +119,14 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
{
struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ const struct sc8280xp_dai_data *dai_data;
struct snd_soc_card *card = rtd->card;
struct snd_soc_jack *dp_jack = NULL;
int dp_pcm_id = 0;
+ dai_data = sc8280xp_get_dai_data(data->snd_soc_common_priv,
+ cpu_dai->id);
+
switch (cpu_dai->id) {
case WSA_CODEC_DMA_RX_0:
case WSA_CODEC_DMA_RX_1:
@@ -121,10 +156,18 @@ 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 (data->snd_soc_common_priv->wcd_jack)
- return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
+ if (!dai_data)
+ return 0;
- return 0;
+ switch (dai_data->jack_setup) {
+ case SC8280XP_JACK_SETUP_CODEC:
+ return qcom_snd_headset_jack_setup(rtd, &data->jack,
+ &data->jack_setup);
+ case SC8280XP_JACK_SETUP_WCD:
+ return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
+ default:
+ return 0;
+ }
}
static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
@@ -163,10 +206,17 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
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_freq(params);
+ const struct sc8280xp_dai_data *dai_data;
+ int mclk_freq;
int bclk_freq = sc8280xp_get_bclk_freq(params);
int ret;
+ dai_data = sc8280xp_get_dai_data(data->snd_soc_common_priv,
+ cpu_dai->id);
+ mclk_freq = dai_data && dai_data->mclk_rate ?
+ dai_data->mclk_rate :
+ sc8280xp_get_mclk_freq(params);
+
switch (cpu_dai->id) {
case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
@@ -175,14 +225,14 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
if (ret && ret != -EOPNOTSUPP)
return ret;
- if (data->snd_soc_common_priv->codec_dai_fmt) {
+ if (dai_data && dai_data->codec_dai_fmt) {
ret = snd_soc_dai_set_fmt(codec_dai,
- data->snd_soc_common_priv->codec_dai_fmt);
+ dai_data->codec_dai_fmt);
if (ret && ret != -EOPNOTSUPP)
return ret;
}
- if (data->snd_soc_common_priv->mi2s_mclk_enable) {
+ if (dai_data && dai_data->mi2s_mclk_enable) {
ret = snd_soc_dai_set_sysclk(cpu_dai,
LPAIF_MI2S_MCLK, mclk_freq,
SND_SOC_CLOCK_OUT);
@@ -190,7 +240,7 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
return ret;
}
- if (data->snd_soc_common_priv->mi2s_bclk_enable) {
+ if (dai_data && dai_data->mi2s_bclk_enable) {
ret = snd_soc_dai_set_sysclk(cpu_dai,
LPAIF_MI2S_BCLK, bclk_freq,
SND_SOC_CLOCK_OUT);
@@ -198,7 +248,7 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
return ret;
}
- if (data->snd_soc_common_priv->codec_sysclk_set) {
+ if (dai_data && dai_data->codec_sysclk_set) {
ret = snd_soc_dai_set_sysclk(codec_dai,
0, mclk_freq,
SND_SOC_CLOCK_IN);
@@ -231,6 +281,20 @@ static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream)
return qcom_snd_sdw_hw_free(substream, &data->stream_prepared[cpu_dai->id]);
}
+static void sc8280xp_snd_exit(struct snd_soc_pcm_runtime *rtd)
+{
+ struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ const struct sc8280xp_dai_data *dai_data;
+
+ dai_data = sc8280xp_get_dai_data(data->snd_soc_common_priv,
+ cpu_dai->id);
+ if (dai_data && dai_data->jack_setup == SC8280XP_JACK_SETUP_CODEC) {
+ qcom_snd_headset_jack_cleanup(rtd);
+ data->jack_setup = false;
+ }
+}
+
static const struct snd_soc_ops sc8280xp_be_ops = {
.startup = qcom_snd_sdw_startup,
.shutdown = qcom_snd_sdw_shutdown,
@@ -247,6 +311,7 @@ static void sc8280xp_add_be_ops(struct snd_soc_card *card)
for_each_card_prelinks(card, i, link) {
if (link->no_pcm == 1) {
link->init = sc8280xp_snd_init;
+ link->exit = sc8280xp_snd_exit;
link->be_hw_params_fixup = sc8280xp_be_hw_params_fixup;
link->ops = &sc8280xp_be_ops;
}
@@ -297,14 +362,20 @@ static const struct snd_soc_common eliza_priv_data = {
.driver_name = "eliza",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
- .wcd_jack = true,
+ SC8280XP_DAI_DATA({
+ .id = TX_CODEC_DMA_TX_3,
+ .jack_setup = SC8280XP_JACK_SETUP_WCD,
+ }),
};
static const struct snd_soc_common kaanapali_priv_data = {
.driver_name = "kaanapali",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
- .wcd_jack = true,
+ SC8280XP_DAI_DATA({
+ .id = TX_CODEC_DMA_TX_3,
+ .jack_setup = SC8280XP_JACK_SETUP_WCD,
+ }),
};
static const struct snd_soc_common qcs9100_priv_data = {
@@ -323,14 +394,20 @@ static const struct snd_soc_common qcm6490_priv_data = {
.driver_name = "qcm6490",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
- .wcd_jack = true,
+ SC8280XP_DAI_DATA({
+ .id = TX_CODEC_DMA_TX_3,
+ .jack_setup = SC8280XP_JACK_SETUP_WCD,
+ }),
};
static const struct snd_soc_common qcs6490_priv_data = {
.driver_name = "qcs6490",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
- .wcd_jack = true,
+ SC8280XP_DAI_DATA({
+ .id = TX_CODEC_DMA_TX_3,
+ .jack_setup = SC8280XP_JACK_SETUP_WCD,
+ }),
};
static const struct snd_soc_common qcs8275_priv_data = {
@@ -343,35 +420,50 @@ static const struct snd_soc_common sc8280xp_priv_data = {
.driver_name = "sc8280xp",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
- .wcd_jack = true,
+ SC8280XP_DAI_DATA({
+ .id = TX_CODEC_DMA_TX_3,
+ .jack_setup = SC8280XP_JACK_SETUP_WCD,
+ }),
};
static const struct snd_soc_common sm8450_priv_data = {
.driver_name = "sm8450",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
- .wcd_jack = true,
+ SC8280XP_DAI_DATA({
+ .id = TX_CODEC_DMA_TX_3,
+ .jack_setup = SC8280XP_JACK_SETUP_WCD,
+ }),
};
static const struct snd_soc_common sm8550_priv_data = {
.driver_name = "sm8550",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
- .wcd_jack = true,
+ SC8280XP_DAI_DATA({
+ .id = TX_CODEC_DMA_TX_3,
+ .jack_setup = SC8280XP_JACK_SETUP_WCD,
+ }),
};
static const struct snd_soc_common sm8650_priv_data = {
.driver_name = "sm8650",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
- .wcd_jack = true,
+ SC8280XP_DAI_DATA({
+ .id = TX_CODEC_DMA_TX_3,
+ .jack_setup = SC8280XP_JACK_SETUP_WCD,
+ }),
};
static const struct snd_soc_common sm8750_priv_data = {
.driver_name = "sm8750",
.dapm_widgets = sc8280xp_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
- .wcd_jack = true,
+ SC8280XP_DAI_DATA({
+ .id = TX_CODEC_DMA_TX_3,
+ .jack_setup = SC8280XP_JACK_SETUP_WCD,
+ }),
};
static const struct of_device_id snd_sc8280xp_dt_match[] = {
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support
2026-07-15 14:02 [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
` (3 preceding siblings ...)
2026-07-15 14:02 ` [PATCH v2 4/6] ASoC: qcom: sc8280xp: Add per-DAI board configuration Hongyang Zhao
@ 2026-07-15 14:02 ` Hongyang Zhao
2026-07-15 18:08 ` Mohammad Rafi Shaik
2026-07-15 14:02 ` [PATCH v2 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
2026-07-16 8:11 ` [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Krzysztof Kozlowski
6 siblings, 1 reply; 13+ messages in thread
From: Hongyang Zhao @ 2026-07-15 14:02 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: Mohammad Rafi Shaik, Neil Armstrong, Dmitry Baryshkov,
Roger Shimizu, linux-sound, devicetree, linux-kernel,
linux-arm-msm, Hongyang Zhao
RubikPi 3 connects an ES8316 codec to the primary MI2S interface for
headset playback and capture, and an LT9611 bridge to the quaternary
MI2S interface for HDMI audio.
Add board-specific DAI data for these links. Configure both directions
of the primary interface for I2S with normal clock polarity and the
codec as bit and frame clock consumer. Program the LPASS MCLK and BCLK,
drive the ES8316 with its required 19.2 MHz MCLK, and enable the generic
codec jack-detection setup on the playback link.
Configure the quaternary playback link with the same I2S clock format.
Do not request a codec sysclk for this link because the LT9611 HDMI
codec DAI does not implement set_sysclk().
Select this configuration through the RubikPi 3 sound-card compatible.
Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
sound/soc/qcom/sc8280xp.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 885ec1e3e575..1354eecb56c9 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -410,6 +410,41 @@ static const struct snd_soc_common qcs6490_priv_data = {
}),
};
+static const struct snd_soc_common qcs6490_rubikpi3_priv_data = {
+ .driver_name = "qcs6490",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+ SC8280XP_DAI_DATA(
+ {
+ .id = PRIMARY_MI2S_RX,
+ .codec_dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_BC_FC,
+ .mclk_rate = 19200000,
+ .codec_sysclk_set = true,
+ .mi2s_mclk_enable = true,
+ .mi2s_bclk_enable = true,
+ .jack_setup = SC8280XP_JACK_SETUP_CODEC,
+ },
+ {
+ .id = PRIMARY_MI2S_TX,
+ .codec_dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_BC_FC,
+ .mclk_rate = 19200000,
+ .codec_sysclk_set = true,
+ .mi2s_mclk_enable = true,
+ .mi2s_bclk_enable = true,
+ },
+ {
+ .id = QUATERNARY_MI2S_RX,
+ .codec_dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_BC_FC,
+ }
+ ),
+};
+
static const struct snd_soc_common qcs8275_priv_data = {
.driver_name = "qcs8300",
.dapm_widgets = sc8280xp_dapm_widgets,
@@ -480,6 +515,10 @@ static const struct of_device_id snd_sc8280xp_dt_match[] = {
{ .compatible = "qcom,sm8550-sndcard", .data = &sm8550_priv_data },
{ .compatible = "qcom,sm8650-sndcard", .data = &sm8650_priv_data },
{ .compatible = "qcom,sm8750-sndcard", .data = &sm8750_priv_data },
+ {
+ .compatible = "thundercomm,qcs6490-rubikpi3-sndcard",
+ .data = &qcs6490_rubikpi3_priv_data,
+ },
{}
};
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
2026-07-15 14:02 [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
` (4 preceding siblings ...)
2026-07-15 14:02 ` [PATCH v2 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support Hongyang Zhao
@ 2026-07-15 14:02 ` Hongyang Zhao
2026-07-15 18:17 ` Mohammad Rafi Shaik
2026-07-16 8:11 ` [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Krzysztof Kozlowski
6 siblings, 1 reply; 13+ messages in thread
From: Hongyang Zhao @ 2026-07-15 14:02 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: Mohammad Rafi Shaik, Neil Armstrong, Dmitry Baryshkov,
Roger Shimizu, linux-sound, devicetree, linux-kernel,
linux-arm-msm, Hongyang Zhao
RubikPi 3 uses the AudioReach firmware path for its external audio
interfaces. The primary MI2S interface connects to an ES8316 codec for
headset playback and capture, while the quaternary MI2S interface feeds
the LT9611 HDMI bridge.
Enable the AudioReach description and add the three DAI links. Describe
the primary MI2S MCLK and bit clock inputs under the backend DAI so the
machine driver can control them. Add the primary and quaternary pin
configurations to the sound card and make the LT9611 codec DAI
addressable.
Describe the ES8316, its 3.3 V enable supply, 19.2 MHz MCLK and inverted
GPIO jack-detect signal. Route the codec headphone outputs and microphone
input to the board headset connector.
Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
.../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 159 +++++++++++++++++++++
1 file changed, 159 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
index d8a9a7e47bdc..7b010823d692 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: regulator-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";
@@ -727,6 +745,26 @@ &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_LEVEL_HIGH>;
+
+ pinctrl-0 = <&es8316_jack_detect>;
+ pinctrl-names = "default";
+
+ everest,jack-detect-inverted;
+ };
+};
+
/* Pin 3, 5 in 40-pin connector */
&i2c1 {
status = "okay";
@@ -740,6 +778,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>;
@@ -978,6 +1017,27 @@ &pon_resin {
status = "okay";
};
+&q6apmbedai {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dai@10 {
+ 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";
+ };
+
+ dai@11 {
+ reg = <PRIMARY_MI2S_TX>;
+ 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";
+ };
+};
+
&qupv3_id_0 {
firmware-name = "qcom/qcm6490/qupv3fw.elf";
@@ -1014,6 +1074,69 @@ &sdhc_2 {
status = "okay";
};
+&sound {
+ compatible = "thundercomm,qcs6490-rubikpi3-sndcard";
+ model = "QCS6490-Thundercomm-RubikPi3";
+
+ pinctrl-0 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>,
+ <&mi2s0_sclk>, <&mi2s0_ws>,
+ <&lpass_qua_mi2s_sclk>, <&lpass_qua_mi2s_ws>,
+ <&lpass_qua_mi2s_data>;
+ pinctrl-names = "default";
+
+ 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 = <<9611_codec 0>;
+ };
+
+ cpu {
+ sound-dai = <&q6apmbedai QUATERNARY_MI2S_RX>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+};
+
/* Pin 19, 21, 23, 24 in 40-pin connector */
&spi12 {
status = "okay";
@@ -1228,6 +1351,29 @@ &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;
+ };
+
+ lpass_qua_mi2s_ws: qua-mi2s-ws-state {
+ pins = "gpio1";
+ function = "qua_mi2s_ws";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ lpass_qua_mi2s_data: qua-mi2s-data-state {
+ pins = "gpio2", "gpio3", "gpio4";
+ function = "qua_mi2s_data";
+ drive-strength = <8>;
+ bias-disable;
+ };
+};
+
&tlmm {
pcie1_reset_n: pcie1-reset-n-state {
pins = "gpio2";
@@ -1366,6 +1512,12 @@ m2_vcc_pin: m2-vcc-state {
input-disable;
};
+ es8316_jack_detect: es8316-jack-detect-state {
+ pins = "gpio63";
+ function = "gpio";
+ bias-disable;
+ };
+
lt9611_vcc_pin: lt9611-vcc-pin-state {
pins = "gpio83";
function = "gpio";
@@ -1395,6 +1547,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] 13+ messages in thread
* Re: [PATCH v2 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support
2026-07-15 14:02 ` [PATCH v2 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support Hongyang Zhao
@ 2026-07-15 18:08 ` Mohammad Rafi Shaik
2026-07-16 9:15 ` Hongyang Zhao
0 siblings, 1 reply; 13+ messages in thread
From: Mohammad Rafi Shaik @ 2026-07-15 18:08 UTC (permalink / raw)
To: Hongyang Zhao, 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: Neil Armstrong, Dmitry Baryshkov, Roger Shimizu, linux-sound,
devicetree, linux-kernel, linux-arm-msm
On 7/15/2026 7:32 PM, Hongyang Zhao wrote:
> RubikPi 3 connects an ES8316 codec to the primary MI2S interface for
> headset playback and capture, and an LT9611 bridge to the quaternary
> MI2S interface for HDMI audio.
>
> Add board-specific DAI data for these links. Configure both directions
> of the primary interface for I2S with normal clock polarity and the
> codec as bit and frame clock consumer. Program the LPASS MCLK and BCLK,
> drive the ES8316 with its required 19.2 MHz MCLK, and enable the generic
> codec jack-detection setup on the playback link.
>
> Configure the quaternary playback link with the same I2S clock format.
> Do not request a codec sysclk for this link because the LT9611 HDMI
> codec DAI does not implement set_sysclk().
>
> Select this configuration through the RubikPi 3 sound-card compatible.
>
> Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
> ---
> sound/soc/qcom/sc8280xp.c | 39 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
>
> diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
> index 885ec1e3e575..1354eecb56c9 100644
> --- a/sound/soc/qcom/sc8280xp.c
> +++ b/sound/soc/qcom/sc8280xp.c
> @@ -410,6 +410,41 @@ static const struct snd_soc_common qcs6490_priv_data = {
> }),
> };
>
> +static const struct snd_soc_common qcs6490_rubikpi3_priv_data = {
> + .driver_name = "qcs6490",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> + SC8280XP_DAI_DATA(
Where is SC8280XP_DAI_DATA() defined?
> + {
> + .id = PRIMARY_MI2S_RX,
> + .codec_dai_fmt = SND_SOC_DAIFMT_I2S |
> + SND_SOC_DAIFMT_NB_NF |
> + SND_SOC_DAIFMT_BC_FC,
codec_dai_fmt appears to be identical for all MI2S DAIs. Can this be
moved into the common initialization path instead of being specified per
DAI.
> + .mclk_rate = 19200000,
Is this mclk frequency fixed ?
Typically, audio MCLK is expected to be 12.288 MHz or 24.576 MHz.
> + .codec_sysclk_set = true,
> + .mi2s_mclk_enable = true,
Drop this mclk_enable flag; your already enabled from the codec node.
is not ?
+&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";
+
> + .mi2s_bclk_enable = true,
> + .jack_setup = SC8280XP_JACK_SETUP_CODEC,
.jack_setup is not part of snd_soc_common
Best regards,
Rafi
> + },
> + {
> + .id = PRIMARY_MI2S_TX,
> + .codec_dai_fmt = SND_SOC_DAIFMT_I2S |
> + SND_SOC_DAIFMT_NB_NF |
> + SND_SOC_DAIFMT_BC_FC,
> + .mclk_rate = 19200000,
> + .codec_sysclk_set = true,
> + .mi2s_mclk_enable = true,
> + .mi2s_bclk_enable = true,
> + },
> + {
> + .id = QUATERNARY_MI2S_RX,
> + .codec_dai_fmt = SND_SOC_DAIFMT_I2S |
> + SND_SOC_DAIFMT_NB_NF |
> + SND_SOC_DAIFMT_BC_FC,
> + }
> + ),
> +};
> +
> static const struct snd_soc_common qcs8275_priv_data = {
> .driver_name = "qcs8300",
> .dapm_widgets = sc8280xp_dapm_widgets,
> @@ -480,6 +515,10 @@ static const struct of_device_id snd_sc8280xp_dt_match[] = {
> { .compatible = "qcom,sm8550-sndcard", .data = &sm8550_priv_data },
> { .compatible = "qcom,sm8650-sndcard", .data = &sm8650_priv_data },
> { .compatible = "qcom,sm8750-sndcard", .data = &sm8750_priv_data },
> + {
> + .compatible = "thundercomm,qcs6490-rubikpi3-sndcard",
> + .data = &qcs6490_rubikpi3_priv_data,
> + },
> {}
> };
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
2026-07-15 14:02 ` [PATCH v2 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
@ 2026-07-15 18:17 ` Mohammad Rafi Shaik
2026-07-16 9:52 ` Hongyang Zhao
0 siblings, 1 reply; 13+ messages in thread
From: Mohammad Rafi Shaik @ 2026-07-15 18:17 UTC (permalink / raw)
To: Hongyang Zhao, 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: Neil Armstrong, Dmitry Baryshkov, Roger Shimizu, linux-sound,
devicetree, linux-kernel, linux-arm-msm
On 7/15/2026 7:32 PM, Hongyang Zhao wrote:
> RubikPi 3 uses the AudioReach firmware path for its external audio
> interfaces. The primary MI2S interface connects to an ES8316 codec for
> headset playback and capture, while the quaternary MI2S interface feeds
> the LT9611 HDMI bridge.
>
> Enable the AudioReach description and add the three DAI links. Describe
> the primary MI2S MCLK and bit clock inputs under the backend DAI so the
> machine driver can control them. Add the primary and quaternary pin
> configurations to the sound card and make the LT9611 codec DAI
> addressable.
>
> Describe the ES8316, its 3.3 V enable supply, 19.2 MHz MCLK and inverted
> GPIO jack-detect signal. Route the codec headphone outputs and microphone
> input to the board headset connector.
>
> Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
> ---
> .../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 159 +++++++++++++++++++++
> 1 file changed, 159 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
> index d8a9a7e47bdc..7b010823d692 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: regulator-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";
>
> @@ -727,6 +745,26 @@ &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_LEVEL_HIGH>;
> +
> + pinctrl-0 = <&es8316_jack_detect>;
> + pinctrl-names = "default";
> +
> + everest,jack-detect-inverted;
> + };
> +};
> +
> /* Pin 3, 5 in 40-pin connector */
> &i2c1 {
> status = "okay";
> @@ -740,6 +778,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>;
> @@ -978,6 +1017,27 @@ &pon_resin {
> status = "okay";
> };
>
> +&q6apmbedai {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + dai@10 {
> + reg = <PRIMARY_MI2S_RX>;
> + clocks = <&q6prmcc LPASS_CLK_ID_MCLK_1 LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
Drop this; it is already enabled from the codec node.
Why is the same clock being enabled in two places?
> + <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
> + clock-names = "mclk",
> + "bclk";
> + };
> +
> + dai@11 {
> + reg = <PRIMARY_MI2S_TX>;
> + 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";
> + };
> +};
> +
> &qupv3_id_0 {
> firmware-name = "qcom/qcm6490/qupv3fw.elf";
>
> @@ -1014,6 +1074,69 @@ &sdhc_2 {
> status = "okay";
> };
>
> +&sound {
> + compatible = "thundercomm,qcs6490-rubikpi3-sndcard";
> + model = "QCS6490-Thundercomm-RubikPi3";
> +
> + pinctrl-0 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>,
> + <&mi2s0_sclk>, <&mi2s0_ws>,
> + <&lpass_qua_mi2s_sclk>, <&lpass_qua_mi2s_ws>,
> + <&lpass_qua_mi2s_data>;
> + pinctrl-names = "default";
> +
> + audio-routing = "Headphone Jack", "HPOL",
> + "Headphone Jack", "HPOR",
> + "MIC2", "Mic Jack";
> +
> + mi2s-playback-dai-link {
> + link-name = "MI2S-LPAIF-RX-PRIMARY";
> +
What does "MI2S-LPAIF-RX-PRIMARY" represents?
> + 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 = <<9611_codec 0>;
> + };
> +
> + cpu {
> + sound-dai = <&q6apmbedai QUATERNARY_MI2S_RX>;
> + };
> +
> + platform {
> + sound-dai = <&q6apm>;
> + };
> + };
> +};
> +
> /* Pin 19, 21, 23, 24 in 40-pin connector */
> &spi12 {
> status = "okay";
> @@ -1228,6 +1351,29 @@ &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;
> + };
> +
> + lpass_qua_mi2s_ws: qua-mi2s-ws-state {
> + pins = "gpio1";
> + function = "qua_mi2s_ws";
> + drive-strength = <8>;
> + bias-disable;
> + };
> +
> + lpass_qua_mi2s_data: qua-mi2s-data-state {
> + pins = "gpio2", "gpio3", "gpio4";
> + function = "qua_mi2s_data";
> + drive-strength = <8>;
> + bias-disable;
> + };
> +};
> +
> &tlmm {
> pcie1_reset_n: pcie1-reset-n-state {
> pins = "gpio2";
> @@ -1366,6 +1512,12 @@ m2_vcc_pin: m2-vcc-state {
> input-disable;
> };
>
> + es8316_jack_detect: es8316-jack-detect-state {
> + pins = "gpio63";
> + function = "gpio";
> + bias-disable;
> + };
> +
> lt9611_vcc_pin: lt9611-vcc-pin-state {
> pins = "gpio83";
> function = "gpio";
> @@ -1395,6 +1547,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";
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3
2026-07-15 14:02 [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
` (5 preceding siblings ...)
2026-07-15 14:02 ` [PATCH v2 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
@ 2026-07-16 8:11 ` Krzysztof Kozlowski
2026-07-16 8:46 ` Hongyang Zhao
6 siblings, 1 reply; 13+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-16 8:11 UTC (permalink / raw)
To: Hongyang Zhao
Cc: 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, Mohammad Rafi Shaik,
Neil Armstrong, Dmitry Baryshkov, Roger Shimizu, linux-sound,
devicetree, linux-kernel, linux-arm-msm, Krzysztof Kozlowski
On Wed, Jul 15, 2026 at 10:02:49PM +0800, Hongyang Zhao wrote:
> Add audio support for the Thundercomm RubikPi3 board based on QCS6490.
>
> RubikPi3 uses AudioReach/GPR on the ADSP. An ES8316 codec connected to
> primary MI2S provides headset playback, headset capture and jack
> detection. The LT9611 bridge connected to quaternary MI2S provides HDMI
> audio playback.
>
> The series first documents the existing ES8316 jack-detect inversion
> property and adds a board-specific Qualcomm sound-card compatible. A
> generic Qualcomm headset helper is then added for codecs which implement
> component jack detection but are not connected through a WCD codec DMA
> link.
>
> The sc8280xp machine driver board data is converted to a per-DAI
> representation. This allows each backend to select its own DAI format,
> clock programming and jack setup. RubikPi3 uses this to drive the ES8316
> with a 19.2 MHz MCLK and to avoid unsupported sysclk programming on the
> LT9611 HDMI link.
>
> The final patch describes the two audio paths, clocks, pin control,
> codec power and jack-detect wiring in the RubikPi3 device tree.
>
> This series is based on next-20260710 and depends on Rafi's
> q6apm-lpass-dais MI2S clock control series and Neil's q6prm MCLK clock
> ID patch:
>
> Depends-on: https://lore.kernel.org/all/20260714145250.2473461-1-mohammad.rafi.shaik@oss.qualcomm.com/
> Depends-on: https://lore.kernel.org/all/20251008-topic-sm8x50-next-hdk-i2s-v2-1-6b7d38d4ad5e@linaro.org/
That's RFC with comments, so why do you send your patchset knowing IT
CANNOT BE merged?
Last days Mark complained, Rob complained, sure, we can ignore
maintainers, but just stop for a second and think: what can we do with
your patchset? Really, what can we do?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3
2026-07-16 8:11 ` [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Krzysztof Kozlowski
@ 2026-07-16 8:46 ` Hongyang Zhao
0 siblings, 0 replies; 13+ messages in thread
From: Hongyang Zhao @ 2026-07-16 8:46 UTC (permalink / raw)
To: krzk
Cc: andersson, broonie, conor+dt, devicetree, dmitry.baryshkov, drake,
hongyang.zhao, katsuhiro, konradybcio, krzk+dt,
krzysztof.kozlowski, lgirdwood, linux-arm-msm, linux-kernel,
linux-sound, matteomartelli3, mohammad.rafi.shaik, neil.armstrong,
perex, robh, rosh, srini, tiwai, zhoubinbin
On Wed, Jul 15, 2026 at 10:02:49PM +0800, Hongyang Zhao wrote:
> > Add audio support for the Thundercomm RubikPi3 board based on QCS6490.
> >
> > RubikPi3 uses AudioReach/GPR on the ADSP. An ES8316 codec connected to
> > primary MI2S provides headset playback, headset capture and jack
> > detection. The LT9611 bridge connected to quaternary MI2S provides HDMI
> > audio playback.
> >
> > The series first documents the existing ES8316 jack-detect inversion
> > property and adds a board-specific Qualcomm sound-card compatible. A
> > generic Qualcomm headset helper is then added for codecs which implement
> > component jack detection but are not connected through a WCD codec DMA
> > link.
> >
> > The sc8280xp machine driver board data is converted to a per-DAI
> > representation. This allows each backend to select its own DAI format,
> > clock programming and jack setup. RubikPi3 uses this to drive the ES8316
> > with a 19.2 MHz MCLK and to avoid unsupported sysclk programming on the
> > LT9611 HDMI link.
> >
> > The final patch describes the two audio paths, clocks, pin control,
> > codec power and jack-detect wiring in the RubikPi3 device tree.
> >
> > This series is based on next-20260710 and depends on Rafi's
> > q6apm-lpass-dais MI2S clock control series and Neil's q6prm MCLK clock
> > ID patch:
> >
> > Depends-on: https://lore.kernel.org/all/20260714145250.2473461-1-mohammad.rafi.shaik@oss.qualcomm.com/
> > Depends-on: https://lore.kernel.org/all/20251008-topic-sm8x50-next-hdk-i2s-v2-1-6b7d38d4ad5e@linaro.org/
>
> That's RFC with comments, so why do you send your patchset knowing IT
> CANNOT BE merged?
>
> Last days Mark complained, Rob complained, sure, we can ignore
> maintainers, but just stop for a second and think: what can we do with
> your patchset? Really, what can we do?
>
> Best regards,
> Krzysztof
Hi Krzysztof,
You are right. I missed the RFC tag on Neil's series and misunderstood
the status of that dependency.
In v1 I carried Neil's MCLK clock-ID patch. I changed this to a
Depends-on reference in v2 because I did not want to resend somebody
else's work without coordination. I now understand that this still
leaves the RubikPi series non-actionable while the dependency remains
an RFC.
Please consider this series withdrawn. I will coordinate with Neil
about the MCLK clock-ID change and wait until the prerequisite work is
in a mergeable state before sending another revision.
Sorry for wasting your and the other maintainers' review time.
Best regards,
Hongyang
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support
2026-07-15 18:08 ` Mohammad Rafi Shaik
@ 2026-07-16 9:15 ` Hongyang Zhao
0 siblings, 0 replies; 13+ messages in thread
From: Hongyang Zhao @ 2026-07-16 9:15 UTC (permalink / raw)
To: mohammad.rafi.shaik
Cc: andersson, broonie, conor+dt, devicetree, dmitry.baryshkov, drake,
hongyang.zhao, katsuhiro, konradybcio, krzk+dt, lgirdwood,
linux-arm-msm, linux-kernel, linux-sound, matteomartelli3,
neil.armstrong, perex, robh, rosh, srini, tiwai, zhoubinbin
Hi Rafi,
Thank you for the review.
> On 7/15/2026 7:32 PM, Hongyang Zhao wrote:
> > RubikPi 3 connects an ES8316 codec to the primary MI2S interface for
> > headset playback and capture, and an LT9611 bridge to the quaternary
> > MI2S interface for HDMI audio.
> >
> > Add board-specific DAI data for these links. Configure both directions
> > of the primary interface for I2S with normal clock polarity and the
> > codec as bit and frame clock consumer. Program the LPASS MCLK and BCLK,
> > drive the ES8316 with its required 19.2 MHz MCLK, and enable the generic
> > codec jack-detection setup on the playback link.
> >
> > Configure the quaternary playback link with the same I2S clock format.
> > Do not request a codec sysclk for this link because the LT9611 HDMI
> > codec DAI does not implement set_sysclk().
> >
> > Select this configuration through the RubikPi 3 sound-card compatible.
> >
> > Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
> > ---
> > sound/soc/qcom/sc8280xp.c | 39 +++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 39 insertions(+)
> >
> > diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
> > index 885ec1e3e575..1354eecb56c9 100644
> > --- a/sound/soc/qcom/sc8280xp.c
> > +++ b/sound/soc/qcom/sc8280xp.c
> > @@ -410,6 +410,41 @@ static const struct snd_soc_common qcs6490_priv_data = {
> > }),
> > };
> >
> > +static const struct snd_soc_common qcs6490_rubikpi3_priv_data = {
> > + .driver_name = "qcs6490",
> > + .dapm_widgets = sc8280xp_dapm_widgets,
> > + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> > + SC8280XP_DAI_DATA(
>
> Where is SC8280XP_DAI_DATA() defined?
It is introduced by the preceding patch 4/6.
https://lore.kernel.org/linux-arm-msm/20260715-rubikpi-next-20260605-v2-4-67601d7a8581@thundersoft.com/
It initializes snd_soc_common::dai_data with an array of
struct sc8280xp_dai_data and sets num_dai_data.
Patch 4/6 reached the mailing list after your reply, so the definition
was not visible when you reviewed this patch.
>
> > + {
> > + .id = PRIMARY_MI2S_RX,
> > + .codec_dai_fmt = SND_SOC_DAIFMT_I2S |
> > + SND_SOC_DAIFMT_NB_NF |
> > + SND_SOC_DAIFMT_BC_FC,
>
> codec_dai_fmt appears to be identical for all MI2S DAIs. Can this be
> moved into the common initialization path instead of being specified per
> DAI.
>
> > + .mclk_rate = 19200000,
>
> Is this mclk frequency fixed ?
>
> Typically, audio MCLK is expected to be 12.288 MHz or 24.576 MHz.
Yes. The RubikPi 3 machine configuration intentionally sets the ES8316
sysclk to 19.2 MHz. At the fixed 48 kHz backend rate this gives an
MCLK/LRCK ratio of 400, which is explicitly supported and documented by
the ES8316 driver.
>
> > + .codec_sysclk_set = true,
> > + .mi2s_mclk_enable = true,
>
> Drop this mclk_enable flag; your already enabled from the codec node.
>
> is not ?
Agreed. The ES8316 codec node is now the only MCLK consumer. The Primary
MI2S RX and TX CPU backends only configure BCLK. The machine driver
still calls the ES8316 set_sysclk() operation with 19.2 MHz to set the
clock rate and sample-rate constraints, but it no longer enables MCLK
through the CPU DAI.
>
> +&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";
> +
>
> > + .mi2s_bclk_enable = true,
> > + .jack_setup = SC8280XP_JACK_SETUP_CODEC,
>
> .jack_setup is not part of snd_soc_common
jack_setup is a member of struct sc8280xp_dai_data, introduced in 4/6.
SC8280XP_DAI_DATA() places these entries in snd_soc_common::dai_data.
This was also obscured by patch 4/6 arriving after your review.
>
> Best regards,
> Rafi
>
> > + },
> > + {
> > + .id = PRIMARY_MI2S_TX,
> > + .codec_dai_fmt = SND_SOC_DAIFMT_I2S |
> > + SND_SOC_DAIFMT_NB_NF |
> > + SND_SOC_DAIFMT_BC_FC,
> > + .mclk_rate = 19200000,
> > + .codec_sysclk_set = true,
> > + .mi2s_mclk_enable = true,
> > + .mi2s_bclk_enable = true,
> > + },
> > + {
> > + .id = QUATERNARY_MI2S_RX,
> > + .codec_dai_fmt = SND_SOC_DAIFMT_I2S |
> > + SND_SOC_DAIFMT_NB_NF |
> > + SND_SOC_DAIFMT_BC_FC,
> > + }
> > + ),
> > +};
> > +
> > static const struct snd_soc_common qcs8275_priv_data = {
> > .driver_name = "qcs8300",
> > .dapm_widgets = sc8280xp_dapm_widgets,
> > @@ -480,6 +515,10 @@ static const struct of_device_id snd_sc8280xp_dt_match[] = {
> > { .compatible = "qcom,sm8550-sndcard", .data = &sm8550_priv_data },
> > { .compatible = "qcom,sm8650-sndcard", .data = &sm8650_priv_data },
> > { .compatible = "qcom,sm8750-sndcard", .data = &sm8750_priv_data },
> > + {
> > + .compatible = "thundercomm,qcs6490-rubikpi3-sndcard",
> > + .data = &qcs6490_rubikpi3_priv_data,
> > + },
> > {}
> > };
> >
> >
Best regards,
Hongyang
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
2026-07-15 18:17 ` Mohammad Rafi Shaik
@ 2026-07-16 9:52 ` Hongyang Zhao
0 siblings, 0 replies; 13+ messages in thread
From: Hongyang Zhao @ 2026-07-16 9:52 UTC (permalink / raw)
To: mohammad.rafi.shaik
Cc: andersson, broonie, conor+dt, devicetree, dmitry.baryshkov, drake,
hongyang.zhao, katsuhiro, konradybcio, krzk+dt, lgirdwood,
linux-arm-msm, linux-kernel, linux-sound, matteomartelli3,
neil.armstrong, perex, robh, rosh, srini, tiwai, zhoubinbin
Hi Rafi,
Thank you for the review.
On 7/15/2026 7:32 PM, Hongyang Zhao wrote:
> > RubikPi 3 uses the AudioReach firmware path for its external audio
> > interfaces. The primary MI2S interface connects to an ES8316 codec for
> > headset playback and capture, while the quaternary MI2S interface feeds
> > the LT9611 HDMI bridge.
> >
> > Enable the AudioReach description and add the three DAI links. Describe
> > the primary MI2S MCLK and bit clock inputs under the backend DAI so the
> > machine driver can control them. Add the primary and quaternary pin
> > configurations to the sound card and make the LT9611 codec DAI
> > addressable.
> >
> > Describe the ES8316, its 3.3 V enable supply, 19.2 MHz MCLK and inverted
> > GPIO jack-detect signal. Route the codec headphone outputs and microphone
> > input to the board headset connector.
> >
> > Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
> > ---
> > .../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 159 +++++++++++++++++++++
> > 1 file changed, 159 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
> > index d8a9a7e47bdc..7b010823d692 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: regulator-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";
> >
> > @@ -727,6 +745,26 @@ &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_LEVEL_HIGH>;
> > +
> > + pinctrl-0 = <&es8316_jack_detect>;
> > + pinctrl-names = "default";
> > +
> > + everest,jack-detect-inverted;
> > + };
> > +};
> > +
> > /* Pin 3, 5 in 40-pin connector */
> > &i2c1 {
> > status = "okay";
> > @@ -740,6 +778,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>;
> > @@ -978,6 +1017,27 @@ &pon_resin {
> > status = "okay";
> > };
> >
> > +&q6apmbedai {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + dai@10 {
> > + reg = <PRIMARY_MI2S_RX>;
> > + clocks = <&q6prmcc LPASS_CLK_ID_MCLK_1 LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
>
> Drop this; it is already enabled from the codec node.
>
> Why is the same clock being enabled in two places?
Agreed. I removed MCLK from both Primary MI2S backend nodes. They now
describe only BCLK, for example:
dai@10 {
reg = <PRIMARY_MI2S_RX>;
clocks = <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
clock-names = "bclk";
};
The ES8316 codec node is the sole MCLK consumer. The corresponding
machine data also no longer enables CPU-side MCLK.
>
> > + <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
> > + clock-names = "mclk",
> > + "bclk";
> > + };
> > +
> > + dai@11 {
> > + reg = <PRIMARY_MI2S_TX>;
> > + 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";
> > + };
> > +};
> > +
> > &qupv3_id_0 {
> > firmware-name = "qcom/qcm6490/qupv3fw.elf";
> >
> > @@ -1014,6 +1074,69 @@ &sdhc_2 {
> > status = "okay";
> > };
> >
> > +&sound {
> > + compatible = "thundercomm,qcs6490-rubikpi3-sndcard";
> > + model = "QCS6490-Thundercomm-RubikPi3";
> > +
> > + pinctrl-0 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>,
> > + <&mi2s0_sclk>, <&mi2s0_ws>,
> > + <&lpass_qua_mi2s_sclk>, <&lpass_qua_mi2s_ws>,
> > + <&lpass_qua_mi2s_data>;
> > + pinctrl-names = "default";
> > +
> > + audio-routing = "Headphone Jack", "HPOL",
> > + "Headphone Jack", "HPOR",
> > + "MIC2", "Mic Jack";
> > +
> > + mi2s-playback-dai-link {
> > + link-name = "MI2S-LPAIF-RX-PRIMARY";
> > +
>
> What does "MI2S-LPAIF-RX-PRIMARY" represents?
The original name was intended to describe the primary MI2S receive
path through LPAIF, but I agree that it was not clear.
Following the naming used by other Qualcomm sound card device trees, I
have changed the DAI link names to:
- "Primary MI2S Playback"
- "Primary MI2S Capture"
- "HDMI Playback"
>
> > + 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 = <<9611_codec 0>;
> > + };
> > +
> > + cpu {
> > + sound-dai = <&q6apmbedai QUATERNARY_MI2S_RX>;
> > + };
> > +
> > + platform {
> > + sound-dai = <&q6apm>;
> > + };
> > + };
> > +};
> > +
> > /* Pin 19, 21, 23, 24 in 40-pin connector */
> > &spi12 {
> > status = "okay";
> > @@ -1228,6 +1351,29 @@ &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;
> > + };
> > +
> > + lpass_qua_mi2s_ws: qua-mi2s-ws-state {
> > + pins = "gpio1";
> > + function = "qua_mi2s_ws";
> > + drive-strength = <8>;
> > + bias-disable;
> > + };
> > +
> > + lpass_qua_mi2s_data: qua-mi2s-data-state {
> > + pins = "gpio2", "gpio3", "gpio4";
> > + function = "qua_mi2s_data";
> > + drive-strength = <8>;
> > + bias-disable;
> > + };
> > +};
> > +
> > &tlmm {
> > pcie1_reset_n: pcie1-reset-n-state {
> > pins = "gpio2";
> > @@ -1366,6 +1512,12 @@ m2_vcc_pin: m2-vcc-state {
> > input-disable;
> > };
> >
> > + es8316_jack_detect: es8316-jack-detect-state {
> > + pins = "gpio63";
> > + function = "gpio";
> > + bias-disable;
> > + };
> > +
> > lt9611_vcc_pin: lt9611-vcc-pin-state {
> > pins = "gpio83";
> > function = "gpio";
> > @@ -1395,6 +1547,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";
> >
Best regards,
Hongyang
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-07-16 11:38 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-15 14:02 [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 2/6] ASoC: dt-bindings: qcom,sm8250: Add RubikPi 3 sound card Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 3/6] ASoC: qcom: common: Add generic headset jack helpers Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 4/6] ASoC: qcom: sc8280xp: Add per-DAI board configuration Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support Hongyang Zhao
2026-07-15 18:08 ` Mohammad Rafi Shaik
2026-07-16 9:15 ` Hongyang Zhao
2026-07-15 14:02 ` [PATCH v2 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
2026-07-15 18:17 ` Mohammad Rafi Shaik
2026-07-16 9:52 ` Hongyang Zhao
2026-07-16 8:11 ` [PATCH v2 0/6] Add audio support for QCS6490 RubikPi3 Krzysztof Kozlowski
2026-07-16 8:46 ` Hongyang Zhao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox