* [PATCH v3 0/6] Add audio support for QCS6490 Rubik Pi 3
@ 2026-09-04 10:02 Hongyang Zhao
2026-09-04 10:02 ` [PATCH v3 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Hongyang Zhao @ 2026-09-04 10: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, Roger Shimizu, linux-sound, linux-kernel,
linux-arm-msm, devicetree, Hongyang Zhao, Krzysztof Kozlowski
Add audio support for the Thundercomm Rubik Pi 3, based on QCS6490.
The board uses AudioReach/GPR on the ADSP. An ES8316 codec on primary
MI2S provides headset playback, capture and jack detection, while the
LT9611 bridge on quaternary MI2S provides HDMI playback.
Document the ES8316 jack-detect inversion property and add a dedicated
sound-card compatible. Factor out a generic Qualcomm headset helper for
external codecs, extend the sc8280xp machine driver with optional per-DAI
clock and jack configuration, and describe the audio hardware in the board
device tree. Existing cards continue to use their card-wide defaults, and
the DAI format remains card-wide.
This series is based on next-20260902. The required q6prm MCLK IDs, q6apm
MI2S clock control and ES8316 regulator support are present in that tree,
so there are no external dependencies.
Tested on Rubik Pi 3 with HDMI playback, headset playback and capture, and
headset jack detection. The bindings and board DTB were also validated
against next-20260902.
Corresponding AudioReach topology and alsa-ucm-conf updates have also
been tested and will be submitted separately to their respective upstream
projects.
Changes in v3:
- Rebase onto next-20260902 and drop the external dependencies, which are
now present in linux-next.
- Adapt the machine driver to the current board data, keeping existing
card-wide settings as fallbacks and codec_dai_fmt card-wide.
- Describe MCLK at the ES8316 codec and BCLK at the primary MI2S backend
DAIs.
- Use the upstream ES8316 supplies without regulator-always-on or
regulator-boot-on, and assign the shared GPIO117 pinctrl state to only
one fixed regulator.
- Put capture before playback and use human-readable link names.
Link: https://lore.kernel.org/r/20260715-rubikpi-next-20260605-v2-0-67601d7a8581@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 | 169 +++++++++++++++++++++
sound/soc/qcom/common.c | 61 +++++++-
sound/soc/qcom/common.h | 3 +
sound/soc/qcom/sc8280xp.c | 130 ++++++++++++++--
6 files changed, 352 insertions(+), 17 deletions(-)
---
base-commit: 32b6ef9a5d0eca44f9cd91f52f4faa89f145a0de
change-id: 20260605-rubikpi-next-20260605-fdda114824d7
Best regards,
--
Hongyang Zhao <hongyang.zhao@thundersoft.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion
2026-09-04 10:02 [PATCH v3 0/6] Add audio support for QCS6490 Rubik Pi 3 Hongyang Zhao
@ 2026-09-04 10:02 ` Hongyang Zhao
2026-09-04 10:49 ` sashiko-bot
2026-09-04 10:02 ` [PATCH v3 2/6] ASoC: dt-bindings: qcom,sm8250: Add RubikPi 3 sound card Hongyang Zhao
` (4 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Hongyang Zhao @ 2026-09-04 10: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, Roger Shimizu, linux-sound, linux-kernel,
linux-arm-msm, devicetree, 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 f4ff23120c5b..9060358a9080 100644
--- a/Documentation/devicetree/bindings/sound/everest,es8316.yaml
+++ b/Documentation/devicetree/bindings/sound/everest,es8316.yaml
@@ -84,6 +84,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] 11+ messages in thread
* [PATCH v3 2/6] ASoC: dt-bindings: qcom,sm8250: Add RubikPi 3 sound card
2026-09-04 10:02 [PATCH v3 0/6] Add audio support for QCS6490 Rubik Pi 3 Hongyang Zhao
2026-09-04 10:02 ` [PATCH v3 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
@ 2026-09-04 10:02 ` Hongyang Zhao
2026-09-04 10:02 ` [PATCH v3 3/6] ASoC: qcom: common: Add generic headset jack helpers Hongyang Zhao
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Hongyang Zhao @ 2026-09-04 10: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, Roger Shimizu, linux-sound, linux-kernel,
linux-arm-msm, devicetree, 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 1536fcd96d68..fc7bccdace0f 100644
--- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
@@ -54,6 +54,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] 11+ messages in thread
* [PATCH v3 3/6] ASoC: qcom: common: Add generic headset jack helpers
2026-09-04 10:02 [PATCH v3 0/6] Add audio support for QCS6490 Rubik Pi 3 Hongyang Zhao
2026-09-04 10:02 ` [PATCH v3 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
2026-09-04 10:02 ` [PATCH v3 2/6] ASoC: dt-bindings: qcom,sm8250: Add RubikPi 3 sound card Hongyang Zhao
@ 2026-09-04 10:02 ` Hongyang Zhao
2026-09-04 10:54 ` sashiko-bot
2026-09-04 10:02 ` [PATCH v3 4/6] ASoC: qcom: sc8280xp: Add per-DAI board configuration Hongyang Zhao
` (2 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Hongyang Zhao @ 2026-09-04 10: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, Roger Shimizu, linux-sound, linux-kernel,
linux-arm-msm, devicetree, 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.
Treat -ENOTSUPP as a no-op because snd_soc_component_set_jack() uses it
for components which do not provide a set_jack callback.
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 d9f256d51973..83b745f617a8 100644
--- a/sound/soc/qcom/common.c
+++ b/sound/soc/qcom/common.c
@@ -339,13 +339,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",
@@ -369,6 +367,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 LPI_MI2S_RX_0:
case TX_CODEC_DMA_TX_0:
@@ -388,8 +435,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 c1deac109f24..b6204a32bd64 100644
--- a/sound/soc/qcom/common.h
+++ b/sound/soc/qcom/common.h
@@ -24,6 +24,9 @@ int qcom_snd_apply_dai_tdm_slots_cfg(struct snd_soc_pcm_runtime *rtd,
const struct qcom_snd_tdm_slot_cfg *cpu_cfg,
const struct qcom_snd_tdm_slot_cfg *codec_cfg);
int qcom_snd_apply_dai_tdm_slots(struct snd_soc_pcm_runtime *rtd);
+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] 11+ messages in thread
* [PATCH v3 4/6] ASoC: qcom: sc8280xp: Add per-DAI board configuration
2026-09-04 10:02 [PATCH v3 0/6] Add audio support for QCS6490 Rubik Pi 3 Hongyang Zhao
` (2 preceding siblings ...)
2026-09-04 10:02 ` [PATCH v3 3/6] ASoC: qcom: common: Add generic headset jack helpers Hongyang Zhao
@ 2026-09-04 10:02 ` Hongyang Zhao
2026-09-04 10:58 ` sashiko-bot
2026-09-04 10:02 ` [PATCH v3 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support Hongyang Zhao
2026-09-04 10:02 ` [PATCH v3 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
5 siblings, 1 reply; 11+ messages in thread
From: Hongyang Zhao @ 2026-09-04 10: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, Roger Shimizu, linux-sound, linux-kernel,
linux-arm-msm, devicetree, Hongyang Zhao
The board data currently applies codec sysclk, MI2S clock and jack setup
policy to every backend DAI on a sound card. This cannot describe a card
whose codecs have different clock requirements on different MI2S
interfaces.
Add an optional per-DAI configuration table indexed by CPU DAI ID. Each
entry can override the MCLK rate, CPU MCLK and BCLK programming, codec
sysclk setup and jack setup path. Keep the codec DAI format card-wide.
Cards without a matching per-DAI entry continue to use the existing
card-wide settings, keeping all current board data unchanged.
Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
sound/soc/qcom/sc8280xp.c | 107 ++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 98 insertions(+), 9 deletions(-)
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 4d48e1012cd4..368a54c2cdf8 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -58,6 +58,25 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
SND_SOC_DAPM_SPK("Speaker", 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 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 qcom_snd_soc_common {
const char *driver_name;
const struct snd_soc_dapm_widget *dapm_widgets;
@@ -71,6 +90,8 @@ struct qcom_snd_soc_common {
bool mi2s_mclk_enable;
bool mi2s_bclk_enable;
bool wcd_jack;
+ const struct sc8280xp_dai_data *dai_data;
+ size_t num_dai_data;
int (*snd_prepare)(struct snd_pcm_substream *substream);
};
@@ -83,6 +104,20 @@ struct sc8280xp_snd_data {
bool jack_setup;
};
+static const struct sc8280xp_dai_data *
+sc8280xp_get_dai_data(const struct qcom_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);
@@ -112,13 +147,22 @@ static int sc8280xp_tdm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
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_dai *codec_dai;
struct qcom_snd_tdm_slot_cfg cpu_cfg;
struct qcom_snd_tdm_slot_cfg codec_cfg;
+ bool codec_sysclk_set = data->priv->codec_sysclk_set;
+ bool mi2s_bclk_enable = data->priv->mi2s_bclk_enable;
int bclk_freq;
int ret;
int i;
+ dai_data = sc8280xp_get_dai_data(data->priv, cpu_dai->id);
+ if (dai_data) {
+ codec_sysclk_set = dai_data->codec_sysclk_set;
+ mi2s_bclk_enable = dai_data->mi2s_bclk_enable;
+ }
+
ret = qcom_snd_get_dai_tdm_slots(rtd, &cpu_cfg, &codec_cfg);
if (ret)
return ret == -ENOENT ? 0 : ret;
@@ -147,7 +191,7 @@ static int sc8280xp_tdm_hw_params(struct snd_pcm_substream *substream,
if (bclk_freq <= 0)
return -EINVAL;
- if (data->priv->mi2s_bclk_enable) {
+ if (mi2s_bclk_enable) {
ret = snd_soc_dai_set_sysclk(cpu_dai, LPAIF_MI2S_BCLK, bclk_freq,
SND_SOC_CLOCK_IN);
if (ret && ret != -ENOTSUPP) {
@@ -157,7 +201,7 @@ static int sc8280xp_tdm_hw_params(struct snd_pcm_substream *substream,
}
}
- if (data->priv->codec_sysclk_set) {
+ if (codec_sysclk_set) {
for_each_rtd_codec_dais(rtd, i, codec_dai) {
ret = snd_soc_dai_set_sysclk(codec_dai, 0, bclk_freq,
SND_SOC_CLOCK_IN);
@@ -176,10 +220,13 @@ 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->priv, cpu_dai->id);
+
switch (cpu_dai->id) {
case WSA_CODEC_DMA_RX_0:
case WSA_CODEC_DMA_RX_1:
@@ -209,10 +256,24 @@ 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->priv->wcd_jack)
- return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
+ if (!dai_data) {
+ if (data->priv->wcd_jack)
+ return qcom_snd_wcd_jack_setup(rtd, &data->jack,
+ &data->jack_setup);
- 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,
@@ -251,10 +312,24 @@ 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;
+ bool codec_sysclk_set = data->priv->codec_sysclk_set;
+ bool mi2s_mclk_enable = data->priv->mi2s_mclk_enable;
+ bool mi2s_bclk_enable = data->priv->mi2s_bclk_enable;
+ int mclk_freq;
int bclk_freq = sc8280xp_get_bclk_freq(params);
int ret;
+ dai_data = sc8280xp_get_dai_data(data->priv, cpu_dai->id);
+ mclk_freq = sc8280xp_get_mclk_freq(params);
+ if (dai_data) {
+ codec_sysclk_set = dai_data->codec_sysclk_set;
+ mi2s_mclk_enable = dai_data->mi2s_mclk_enable;
+ mi2s_bclk_enable = dai_data->mi2s_bclk_enable;
+ if (dai_data->mclk_rate)
+ mclk_freq = dai_data->mclk_rate;
+ }
+
switch (cpu_dai->id) {
case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
@@ -271,7 +346,7 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
return ret;
}
- if (data->priv->mi2s_mclk_enable) {
+ if (mi2s_mclk_enable) {
ret = snd_soc_dai_set_sysclk(cpu_dai,
LPAIF_MI2S_MCLK, mclk_freq,
SND_SOC_CLOCK_OUT);
@@ -279,7 +354,7 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
return ret;
}
- if (data->priv->mi2s_bclk_enable) {
+ if (mi2s_bclk_enable) {
ret = snd_soc_dai_set_sysclk(cpu_dai,
LPAIF_MI2S_BCLK, bclk_freq,
SND_SOC_CLOCK_OUT);
@@ -287,7 +362,7 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
return ret;
}
- if (data->priv->codec_sysclk_set) {
+ if (codec_sysclk_set) {
ret = snd_soc_dai_set_sysclk(codec_dai,
0, mclk_freq,
SND_SOC_CLOCK_IN);
@@ -368,6 +443,19 @@ 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->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,
@@ -384,6 +472,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;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support
2026-09-04 10:02 [PATCH v3 0/6] Add audio support for QCS6490 Rubik Pi 3 Hongyang Zhao
` (3 preceding siblings ...)
2026-09-04 10:02 ` [PATCH v3 4/6] ASoC: qcom: sc8280xp: Add per-DAI board configuration Hongyang Zhao
@ 2026-09-04 10:02 ` Hongyang Zhao
2026-09-04 10:02 ` [PATCH v3 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
5 siblings, 0 replies; 11+ messages in thread
From: Hongyang Zhao @ 2026-09-04 10: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, Roger Shimizu, linux-sound, linux-kernel,
linux-arm-msm, devicetree, Hongyang Zhao
RubikPi 3 connects an ES8316 codec to primary MI2S for headset playback
and capture, and an LT9611 bridge to quaternary MI2S for HDMI audio.
Add per-DAI data for the primary playback and capture links. Configure
the codecs for I2S with normal clock polarity and as bit and frame clock
consumers. Program the primary MI2S BCLK, configure the ES8316 for its
fixed 19.2 MHz MCLK and enable component jack detection on the playback
link.
The HDMI link inherits the card-wide I2S format but does not request
codec sysclk programming because the LT9611 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 | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 368a54c2cdf8..73009f9bb8e4 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -577,6 +577,28 @@ static const struct qcom_snd_soc_common qcs6490_priv_data = {
.wcd_jack = true,
};
+static const struct qcom_snd_soc_common rubikpi3_priv_data = {
+ .driver_name = "qcs6490",
+ .dapm_widgets = sc8280xp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
+ .codec_dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_BC_FC,
+ SC8280XP_DAI_DATA({
+ .id = PRIMARY_MI2S_RX,
+ .mclk_rate = 19200000,
+ .codec_sysclk_set = true,
+ .mi2s_bclk_enable = true,
+ .jack_setup = SC8280XP_JACK_SETUP_CODEC,
+ }, {
+ .id = PRIMARY_MI2S_TX,
+ .mclk_rate = 19200000,
+ .codec_sysclk_set = true,
+ .mi2s_bclk_enable = true,
+ }
+ ),
+};
+
static const struct qcom_snd_soc_common qcs8275_priv_data = {
.driver_name = "qcs8300",
.dapm_widgets = max98090_dapm_widgets,
@@ -656,6 +678,7 @@ static const struct of_device_id snd_sc8280xp_dt_match[] = {
{ .compatible = "qcom,qcm6490-idp-sndcard", .data = &qcm6490_priv_data },
{ .compatible = "qcom,qcs615-sndcard", .data = &qcs615_priv_data },
{ .compatible = "qcom,qcs6490-rb3gen2-sndcard", .data = &qcs6490_priv_data },
+ { .compatible = "thundercomm,qcs6490-rubikpi3-sndcard", .data = &rubikpi3_priv_data },
{ .compatible = "qcom,qcs8275-sndcard", .data = &qcs8275_priv_data },
{ .compatible = "qcom,qcs9075-sndcard", .data = &qcs9100_priv_data },
{ .compatible = "qcom,qcs9100-sndcard", .data = &qcs9100_priv_data },
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
2026-09-04 10:02 [PATCH v3 0/6] Add audio support for QCS6490 Rubik Pi 3 Hongyang Zhao
` (4 preceding siblings ...)
2026-09-04 10:02 ` [PATCH v3 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support Hongyang Zhao
@ 2026-09-04 10:02 ` Hongyang Zhao
2026-09-04 10:59 ` sashiko-bot
5 siblings, 1 reply; 11+ messages in thread
From: Hongyang Zhao @ 2026-09-04 10: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, Roger Shimizu, linux-sound, linux-kernel,
linux-arm-msm, devicetree, Hongyang Zhao
RubikPi 3 uses the AudioReach firmware path for its external audio
interfaces. Primary MI2S connects to an ES8316 codec for headset playback
and capture, while quaternary MI2S feeds the LT9611 HDMI bridge.
Describe the ES8316 supplies, MCLK, jack detection and audio routing, and
add the primary and quaternary MI2S links. The 1.8 V and 3.3 V codec
supplies are both controlled by GPIO117.
Signed-off-by: Hongyang Zhao <hongyang.zhao@thundersoft.com>
---
.../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 169 +++++++++++++++++++++
1 file changed, 169 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
index 0f21777c480b..10277bee86b3 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,33 @@ fan0: pwm-fan {
pinctrl-names = "default";
};
+ vreg_es8316_1v8: regulator-es8316-1v8 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "vreg_es8316_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 117 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&es8316_power_on>;
+ pinctrl-names = "default";
+
+ vin-supply = <&vreg_l18b_1p8>;
+ };
+
+ 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;
+ };
+
vreg_eth_1v8: regulator-eth-1v8 {
compatible = "regulator-fixed";
@@ -743,6 +771,30 @@ &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>;
+ avdd-supply = <&vreg_es8316_3v3>;
+ cpvdd-supply = <&vreg_es8316_1v8>;
+ dvdd-supply = <&vreg_es8316_1v8>;
+ pvdd-supply = <&vreg_es8316_1v8>;
+
+ pinctrl-0 = <&es8316_jack_detect>;
+ pinctrl-names = "default";
+
+ everest,jack-detect-inverted;
+ };
+};
+
/* Pin 3, 5 in 40-pin connector */
&i2c1 {
status = "okay";
@@ -756,6 +808,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>;
@@ -994,6 +1047,23 @@ &pon_resin {
status = "okay";
};
+&q6apmbedai {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dai@10 {
+ reg = <PRIMARY_MI2S_RX>;
+ clocks = <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+ clock-names = "bclk";
+ };
+
+ dai@11 {
+ reg = <PRIMARY_MI2S_TX>;
+ clocks = <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+ clock-names = "bclk";
+ };
+};
+
&qupv3_id_0 {
firmware-name = "qcom/qcm6490/qupv3fw.elf";
@@ -1030,6 +1100,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-capture-dai-link {
+ link-name = "Primary MI2S Capture";
+
+ codec {
+ sound-dai = <&es8316>;
+ };
+
+ cpu {
+ sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+
+ mi2s-playback-dai-link {
+ link-name = "Primary MI2S Playback";
+
+ codec {
+ sound-dai = <&es8316>;
+ };
+
+ cpu {
+ sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+
+ quaternary-mi2s-playback-dai-link {
+ link-name = "HDMI Playback";
+
+ 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";
@@ -1244,6 +1377,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";
@@ -1389,6 +1545,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";
@@ -1418,6 +1580,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] 11+ messages in thread
* Re: [PATCH v3 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion
2026-09-04 10:02 ` [PATCH v3 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
@ 2026-09-04 10:49 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-09-04 10:49 UTC (permalink / raw)
To: Hongyang Zhao; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The newly added property `everest,jack-detect-inverted` is not restricted to `everest,es8316`, allowing invalid configurations for `everest,es8311` and `everest,es8323` to silently bypass schema validation.
--
commit 9fc0fc78c1e3b0ad9527382c3b761e13ee89bf26
Author: Hongyang Zhao <hongyang.zhao@thundersoft.com>
Subject: ASoC: dt-bindings: es8316: Document jack detect inversion
This commit documents the everest,jack-detect-inverted property to allow
boards to describe the jack-detect polarity used by their wiring for the
ES8316 driver without failing schema validation.
> diff --git a/Documentation/devicetree/bindings/sound/everest,es8316.yaml b/Documentation/devicetree/bindings/sound/everest,es8316.yaml
> index f4ff23120c5b5..9060358a9080c 100644
> --- a/Documentation/devicetree/bindings/sound/everest,es8316.yaml
> +++ b/Documentation/devicetree/bindings/sound/everest,es8316.yaml
> @@ -84,6 +84,11 @@ properties:
> "#sound-dai-cells":
> const: 0
>
> + everest,jack-detect-inverted:
> + $ref: /schemas/types.yaml#/definitions/flag
> + description:
> + Defined to invert the jack detection.
> +
[Severity: Low]
Since this property in Documentation/devicetree/bindings/sound/everest,es8316.yaml
is specifically for the ES8316, does it need to be restricted in the
existing allOf conditional block?
Currently, the schema uses an if block to disable ES8316-only supplies for
other codecs like ES8311 and ES8323:
allOf:
- if:
properties:
compatible:
not:
contains:
const: everest,es8316
then:
properties:
avdd-supply: false
cpvdd-supply: false
dvdd-supply: false
pvdd-supply: false
Without adding everest,jack-detect-inverted: false to this block, won't
invalid configurations using this property on ES8311 or ES8323 devices
silently pass schema validation?
> required:
> - compatible
> - reg
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904-rubikpi-next-20260605-v3-0-f49146d85af3@thundersoft.com?part=1
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 3/6] ASoC: qcom: common: Add generic headset jack helpers
2026-09-04 10:02 ` [PATCH v3 3/6] ASoC: qcom: common: Add generic headset jack helpers Hongyang Zhao
@ 2026-09-04 10:54 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-09-04 10:54 UTC (permalink / raw)
To: Hongyang Zhao; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing cleanup in qcom_snd_wcd_jack_setup error path leads to a Use-After-Free of the jack object.
- [High] Static array `qcom_headset_jack_pins` suffers from list corruption if multiple sound cards are instantiated.
--
commit b92ab42f39f7bdd943113ea9586e913e225e1a7f
Author: Hongyang Zhao <hongyang.zhao@thundersoft.com>
ASoC: qcom: common: Add generic headset jack helpers
This commit factors out common jack allocation and DAPM pin registration
into a private initializer. It adds a generic setup helper to attach jacks
to codec components and a matching cleanup helper. The WCD setup behavior
remains unchanged.
> diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c
> index d9f256d519733..83b745f617a86 100644
> --- a/sound/soc/qcom/common.c
> +++ b/sound/soc/qcom/common.c
> @@ -339,13 +339,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",
[Severity: High]
This is a pre-existing issue, but can this static array usage cause list
corruption if multiple sound cards are instantiated concurrently?
qcom_headset_jack_pins is a global static array passed into
snd_soc_card_jack_new_pins() here. The ALSA core function
snd_soc_jack_add_pins() directly mutates this array by calling
INIT_LIST_HEAD and list_add on the embedded list nodes of each element.
If multiple sound cards or multiple instances of a machine driver are
instantiated, the !*jack_setup check evaluates to true for the new instance
since the boolean resides in the per-card private data. The second instance
would overwrite the list_head pointers in the shared static array elements,
corrupting the linked lists of the first card and causing list traversal
crashes.
[ ... ]
> +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) {
[Severity: High]
This is a pre-existing issue, but I noticed the new generic helper
qcom_snd_headset_jack_setup() includes a cleanup on failure, whereas
this existing function does not.
In qcom_snd_wcd_jack_setup(), if snd_soc_component_set_jack() fails for a
codec DAI after successfully configuring earlier DAIs in the loop, the
function returns immediately without rolling back the configurations:
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;
}
}
A probe failure will cause the sound card and its dynamically allocated
snd_soc_jack structure to be freed.
The successfully configured codec components (which reside in separate
codec drivers and persist beyond the sound card probe failure) will retain
dangling pointers to the freed jack. If a hardware jack event triggers an
interrupt later, the codec driver will attempt to report it using the
dangling pointer, resulting in a use-after-free kernel panic.
Should this function be updated to use a cleanup mechanism similar to what
was added for the new generic setup helper?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904-rubikpi-next-20260605-v3-0-f49146d85af3@thundersoft.com?part=3
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 4/6] ASoC: qcom: sc8280xp: Add per-DAI board configuration
2026-09-04 10:02 ` [PATCH v3 4/6] ASoC: qcom: sc8280xp: Add per-DAI board configuration Hongyang Zhao
@ 2026-09-04 10:58 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-09-04 10:58 UTC (permalink / raw)
To: Hongyang Zhao; +Cc: robh, devicetree, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing reset of `data->jack_setup` in `sc8280xp_snd_exit` for WCD jack configurations leads to a Use-After-Free during deferred probing or component unbind/bind cycles.
--
commit 3a7610af2c37c8b0b947c4604289cd1535efab41
Author: Hongyang Zhao <hongyang.zhao@thundersoft.com>
ASoC: qcom: sc8280xp: Add per-DAI board configuration
This commit introduces an optional per-DAI configuration table indexed
by CPU DAI ID for the SC8280XP sound card. This allows overriding
card-wide settings for MCLK, BCLK, sysclk, and jack setup on a per-DAI
basis.
> diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
> index 4d48e1012cd4b..368a54c2cdf8d 100644
> --- a/sound/soc/qcom/sc8280xp.c
> +++ b/sound/soc/qcom/sc8280xp.c
[ ... ]
> @@ -368,6 +443,19 @@ 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->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;
> + }
> +}
[Severity: High]
This is a pre-existing issue, but since this new exit callback cleans up
the codec jack state, should it also reset the WCD jack state?
When an ASoC component is unbound, the ASoC core unregisters the sound
card and frees the ALSA snd_card, which automatically frees the underlying
snd_jack object. However, the machine driver's sc8280xp_snd_data outlives
the card unbind because it is tied to the platform device.
Because data->jack_setup is not reset to false for WCD configurations
here, when the component is rebound, sc8280xp_snd_init() sees the stale
true value. This skips creating a new jack and passes the dangling
jack->jack pointer to the codec via snd_soc_component_set_jack(). A
subsequent jack event from the codec could then dereference this freed
pointer.
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904-rubikpi-next-20260605-v3-0-f49146d85af3@thundersoft.com?part=4
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
2026-09-04 10:02 ` [PATCH v3 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
@ 2026-09-04 10:59 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-09-04 10:59 UTC (permalink / raw)
To: Hongyang Zhao; +Cc: conor+dt, robh, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Undefined pinctrl labels used in the sound node cause device tree compilation failure.
--
commit d72f2352a4f5bf62c0a3db9c3ccca60e51c060c1
Author: Hongyang Zhao <hongyang.zhao@thundersoft.com>
arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
This commit adds audio support for the RubikPi 3 using the AudioReach
firmware path. It describes the ES8316 supplies, MCLK, jack detection,
audio routing, and adds the primary and quaternary MI2S links.
> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
> index 13e8e62f6205a..0322658337ea0 100644
> --- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
[ ... ]
> @@ -1014,6 +1084,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>,
[Severity: Low]
Will this device tree compile successfully when using make dtbs?
The primary MI2S pinctrl labels (&mi2s0_data0, &mi2s0_data1, &mi2s0_mclk,
&mi2s0_sclk, and &mi2s0_ws) referenced in the sound node do not appear to be
defined in this file or its included .dtsi files. Referencing an undefined
label usually causes the Device Tree Compiler to abort with a fatal
"Reference to non-existent node or label" error.
> + <&lpass_qua_mi2s_sclk>, <&lpass_qua_mi2s_ws>,
> + <&lpass_qua_mi2s_data>;
> + pinctrl-names = "default";
> +
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904-rubikpi-next-20260605-v3-0-f49146d85af3@thundersoft.com?part=6
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-09-04 11:18 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 10:02 [PATCH v3 0/6] Add audio support for QCS6490 Rubik Pi 3 Hongyang Zhao
2026-09-04 10:02 ` [PATCH v3 1/6] ASoC: dt-bindings: es8316: Document jack detect inversion Hongyang Zhao
2026-09-04 10:49 ` sashiko-bot
2026-09-04 10:02 ` [PATCH v3 2/6] ASoC: dt-bindings: qcom,sm8250: Add RubikPi 3 sound card Hongyang Zhao
2026-09-04 10:02 ` [PATCH v3 3/6] ASoC: qcom: common: Add generic headset jack helpers Hongyang Zhao
2026-09-04 10:54 ` sashiko-bot
2026-09-04 10:02 ` [PATCH v3 4/6] ASoC: qcom: sc8280xp: Add per-DAI board configuration Hongyang Zhao
2026-09-04 10:58 ` sashiko-bot
2026-09-04 10:02 ` [PATCH v3 5/6] ASoC: qcom: sc8280xp: Add RubikPi 3 sound card support Hongyang Zhao
2026-09-04 10:02 ` [PATCH v3 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support Hongyang Zhao
2026-09-04 10:59 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox