[PATCH] ASoC: qcom: sdm845: Disable the quaternary MI2S bit clock on shutdown
From: yoxcu
Date: Tue Oct 13 2026 - 17:01:47 EST
From: Michael Auer <mick@xxxxxxxx>
sdm845_snd_startup() enables the quaternary MI2S bit clock in the ADSP,
but sdm845_snd_shutdown() never disables it. After the first stream on
this port the clock stays on.
On the OnePlus 6 the speaker amplifier is on this port. After the first
playback the ADSP no longer power collapses: it slept under 9 s in 5
hours. With this change it sleeps again when audio is idle (about 40 s
of 45 s).
Refcount the clock like the other MI2S and TDM ports and disable it
when the last user is gone.
Fixes: 5caf64c633a3 ("ASoC: qcom: sdm845: add support to DB845c and Lenovo Yoga")
Assisted-by: LLM
Signed-off-by: Michael Auer <mick@xxxxxxxx>
---
Tested on a OnePlus 6 with an sdm845-mainline 7.1-rc1 based kernel:
the bit clock is set at stream start and set to 0 when the stream is
closed, and the ADSP power collapses again. On sound/for-next it was
only build tested (W=1). Not tested on the other boards that use QUAT
MI2S (DB845c HDMI, Xiaomi beryllium and polaris).
sound/soc/qcom/sdm845.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
index f0fbec9c8df2..85951397cb2b 100644
--- a/sound/soc/qcom/sdm845.c
+++ b/sound/soc/qcom/sdm845.c
@@ -43,6 +43,7 @@ struct sdm845_snd_data {
bool stream_prepared[AFE_PORT_MAX];
uint32_t pri_mi2s_clk_count;
uint32_t sec_mi2s_clk_count;
+ uint32_t quat_mi2s_clk_count;
uint32_t quat_tdm_clk_count;
};
@@ -372,9 +373,11 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
break;
case QUATERNARY_MI2S_RX:
codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
- snd_soc_dai_set_sysclk(cpu_dai,
- Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
- MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
+ if (++(data->quat_mi2s_clk_count) == 1) {
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
+ MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
+ }
snd_soc_dai_set_fmt(cpu_dai, fmt);
snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
break;
@@ -483,8 +486,16 @@ static void sdm845_snd_shutdown(struct snd_pcm_substream *substream)
0, SNDRV_PCM_STREAM_PLAYBACK);
}
break;
- case SLIMBUS_0_RX...SLIMBUS_6_TX:
+
case QUATERNARY_MI2S_RX:
+ if (--(data->quat_mi2s_clk_count) == 0) {
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
+ 0, SNDRV_PCM_STREAM_PLAYBACK);
+ }
+ break;
+
+ case SLIMBUS_0_RX...SLIMBUS_6_TX:
break;
default:
base-commit: 631a161db2c5168dd836242571724baba3561a1f
--
2.43.0