armbian_build/patch/kernel/archive/sm8250-6.12/0006-ASoC-qcom-sm8250-Add-tdm-support.patch
2024-12-05 00:23:00 +01:00

127 lines
3.9 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jianhua Lu <lujianhua000@gmail.com>
Date: Mon, 11 Dec 2023 09:23:28 +0800
Subject: ASoC: qcom: sm8250: Add tdm support
---
sound/soc/qcom/sm8250.c | 75 ++++++++++
1 file changed, 75 insertions(+)
diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c
index 111111111111..222222222222 100644
--- a/sound/soc/qcom/sm8250.c
+++ b/sound/soc/qcom/sm8250.c
@@ -16,6 +16,9 @@
#define DRIVER_NAME "sm8250"
#define MI2S_BCLK_RATE 1536000
+#define TDM_BCLK_RATE 12288000
+
+static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
struct sm8250_snd_data {
bool stream_prepared[AFE_PORT_MAX];
@@ -32,6 +35,57 @@ static int sm8250_snd_init(struct snd_soc_pcm_runtime *rtd)
return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
}
+static int sm8250_tdm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+
+ int ret = 0;
+ int channels, slots, slot_width;
+
+ channels = params_channels(params);
+ slots = 8;
+ slot_width = 32;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0x03,
+ slots, slot_width);
+ if (ret < 0) {
+ dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
+ channels, tdm_slot_offset);
+ if (ret < 0) {
+ dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0,
+ slots, slot_width);
+ if (ret < 0) {
+ dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
+ tdm_slot_offset, 0, NULL);
+ if (ret < 0) {
+ dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -53,6 +107,7 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
+ int ret,j;
switch (cpu_dai->id) {
case PRIMARY_MI2S_RX:
@@ -71,6 +126,21 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream)
snd_soc_dai_set_fmt(cpu_dai, fmt);
snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
break;
+ case TERTIARY_TDM_RX_0:
+ codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_DSP_A;
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT,
+ TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
+
+ for_each_rtd_codec_dais(rtd, j, codec_dai) {
+ ret = snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
+ snd_soc_dai_set_sysclk(codec_dai, 0, TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
+ if (ret < 0) {
+ dev_err(rtd->dev, "TDM fmt err:%d\n", ret);
+ return ret;
+ }
+ }
+ break;
default:
break;
}
@@ -96,6 +166,11 @@ static int sm8250_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sm8250_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
+ switch (cpu_dai->id) {
+ case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
+ return sm8250_tdm_snd_hw_params(substream, params);
+ }
+
return qcom_snd_sdw_hw_params(substream, params, &pdata->sruntime[cpu_dai->id]);
}
--
Armbian