142a589e8SKaiChieh Chuang // SPDX-License-Identifier: GPL-2.0
242a589e8SKaiChieh Chuang //
342a589e8SKaiChieh Chuang // MediaTek ALSA SoC Audio DAI ADDA Control
442a589e8SKaiChieh Chuang //
542a589e8SKaiChieh Chuang // Copyright (c) 2018 MediaTek Inc.
642a589e8SKaiChieh Chuang // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
742a589e8SKaiChieh Chuang
842a589e8SKaiChieh Chuang #include <linux/regmap.h>
942a589e8SKaiChieh Chuang #include <linux/delay.h>
1042a589e8SKaiChieh Chuang #include "mt6797-afe-common.h"
1142a589e8SKaiChieh Chuang #include "mt6797-interconnection.h"
1242a589e8SKaiChieh Chuang #include "mt6797-reg.h"
13*d6c01755SAngeloGioacchino Del Regno #include "../common/mtk-dai-adda-common.h"
1442a589e8SKaiChieh Chuang
1542a589e8SKaiChieh Chuang /* dai component */
1642a589e8SKaiChieh Chuang static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = {
1742a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0),
1842a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0),
1942a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0),
2042a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3,
2142a589e8SKaiChieh Chuang I_ADDA_UL_CH2, 1, 0),
2242a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3,
2342a589e8SKaiChieh Chuang I_ADDA_UL_CH1, 1, 0),
242c1a5c04SKai Chieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3,
252c1a5c04SKai Chieh Chuang I_PCM_1_CAP_CH1, 1, 0),
262c1a5c04SKai Chieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3,
272c1a5c04SKai Chieh Chuang I_PCM_2_CAP_CH1, 1, 0),
2842a589e8SKaiChieh Chuang };
2942a589e8SKaiChieh Chuang
3042a589e8SKaiChieh Chuang static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = {
3142a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0),
3242a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0),
3342a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0),
3442a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0),
3542a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0),
3642a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0),
3742a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4,
3842a589e8SKaiChieh Chuang I_ADDA_UL_CH2, 1, 0),
3942a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4,
4042a589e8SKaiChieh Chuang I_ADDA_UL_CH1, 1, 0),
412c1a5c04SKai Chieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4,
422c1a5c04SKai Chieh Chuang I_PCM_1_CAP_CH1, 1, 0),
432c1a5c04SKai Chieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4,
442c1a5c04SKai Chieh Chuang I_PCM_2_CAP_CH1, 1, 0),
452c1a5c04SKai Chieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4,
462c1a5c04SKai Chieh Chuang I_PCM_1_CAP_CH2, 1, 0),
472c1a5c04SKai Chieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4,
482c1a5c04SKai Chieh Chuang I_PCM_2_CAP_CH2, 1, 0),
4942a589e8SKaiChieh Chuang };
5042a589e8SKaiChieh Chuang
mtk_adda_ul_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)5142a589e8SKaiChieh Chuang static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
5242a589e8SKaiChieh Chuang struct snd_kcontrol *kcontrol,
5342a589e8SKaiChieh Chuang int event)
5442a589e8SKaiChieh Chuang {
5542a589e8SKaiChieh Chuang struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
5642a589e8SKaiChieh Chuang struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
5742a589e8SKaiChieh Chuang
5842a589e8SKaiChieh Chuang dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
5942a589e8SKaiChieh Chuang __func__, w->name, event);
6042a589e8SKaiChieh Chuang
6142a589e8SKaiChieh Chuang switch (event) {
6242a589e8SKaiChieh Chuang case SND_SOC_DAPM_POST_PMD:
6342a589e8SKaiChieh Chuang /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
6442a589e8SKaiChieh Chuang usleep_range(125, 135);
6542a589e8SKaiChieh Chuang break;
6642a589e8SKaiChieh Chuang default:
6742a589e8SKaiChieh Chuang break;
6842a589e8SKaiChieh Chuang }
6942a589e8SKaiChieh Chuang
7042a589e8SKaiChieh Chuang return 0;
7142a589e8SKaiChieh Chuang }
7242a589e8SKaiChieh Chuang
7342a589e8SKaiChieh Chuang enum {
7442a589e8SKaiChieh Chuang SUPPLY_SEQ_AUD_TOP_PDN,
7542a589e8SKaiChieh Chuang SUPPLY_SEQ_ADDA_AFE_ON,
7642a589e8SKaiChieh Chuang SUPPLY_SEQ_ADDA_DL_ON,
7742a589e8SKaiChieh Chuang SUPPLY_SEQ_ADDA_UL_ON,
7842a589e8SKaiChieh Chuang };
7942a589e8SKaiChieh Chuang
8042a589e8SKaiChieh Chuang static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
8142a589e8SKaiChieh Chuang /* adda */
8242a589e8SKaiChieh Chuang SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0,
8342a589e8SKaiChieh Chuang mtk_adda_dl_ch1_mix,
8442a589e8SKaiChieh Chuang ARRAY_SIZE(mtk_adda_dl_ch1_mix)),
8542a589e8SKaiChieh Chuang SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0,
8642a589e8SKaiChieh Chuang mtk_adda_dl_ch2_mix,
8742a589e8SKaiChieh Chuang ARRAY_SIZE(mtk_adda_dl_ch2_mix)),
8842a589e8SKaiChieh Chuang
8942a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
9042a589e8SKaiChieh Chuang AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0,
9142a589e8SKaiChieh Chuang NULL, 0),
9242a589e8SKaiChieh Chuang
9342a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
9442a589e8SKaiChieh Chuang AFE_ADDA_DL_SRC2_CON0,
9542a589e8SKaiChieh Chuang DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0,
9642a589e8SKaiChieh Chuang NULL, 0),
9742a589e8SKaiChieh Chuang
9842a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
9942a589e8SKaiChieh Chuang AFE_ADDA_UL_SRC_CON0,
10042a589e8SKaiChieh Chuang UL_SRC_ON_TMP_CTL_SFT, 0,
10142a589e8SKaiChieh Chuang mtk_adda_ul_event,
10242a589e8SKaiChieh Chuang SND_SOC_DAPM_POST_PMD),
10342a589e8SKaiChieh Chuang
10442a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("aud_dac_clk", SUPPLY_SEQ_AUD_TOP_PDN,
10542a589e8SKaiChieh Chuang AUDIO_TOP_CON0, PDN_DAC_SFT, 1,
10642a589e8SKaiChieh Chuang NULL, 0),
10742a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("aud_dac_predis_clk", SUPPLY_SEQ_AUD_TOP_PDN,
10842a589e8SKaiChieh Chuang AUDIO_TOP_CON0, PDN_DAC_PREDIS_SFT, 1,
10942a589e8SKaiChieh Chuang NULL, 0),
11042a589e8SKaiChieh Chuang
11142a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("aud_adc_clk", SUPPLY_SEQ_AUD_TOP_PDN,
11242a589e8SKaiChieh Chuang AUDIO_TOP_CON0, PDN_ADC_SFT, 1,
11342a589e8SKaiChieh Chuang NULL, 0),
11442a589e8SKaiChieh Chuang
11542a589e8SKaiChieh Chuang SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"),
11642a589e8SKaiChieh Chuang };
11742a589e8SKaiChieh Chuang
11842a589e8SKaiChieh Chuang static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
11942a589e8SKaiChieh Chuang /* playback */
12042a589e8SKaiChieh Chuang {"ADDA_DL_CH1", "DL1_CH1", "DL1"},
12142a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL1_CH1", "DL1"},
12242a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL1_CH2", "DL1"},
12342a589e8SKaiChieh Chuang
12442a589e8SKaiChieh Chuang {"ADDA_DL_CH1", "DL2_CH1", "DL2"},
12542a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL2_CH1", "DL2"},
12642a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL2_CH2", "DL2"},
12742a589e8SKaiChieh Chuang
12842a589e8SKaiChieh Chuang {"ADDA_DL_CH1", "DL3_CH1", "DL3"},
12942a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL3_CH1", "DL3"},
13042a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL3_CH2", "DL3"},
13142a589e8SKaiChieh Chuang
13242a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "ADDA_DL_CH1"},
13342a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "ADDA_DL_CH2"},
13442a589e8SKaiChieh Chuang
13542a589e8SKaiChieh Chuang /* adda enable */
13642a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "ADDA Enable"},
13742a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "ADDA Playback Enable"},
13842a589e8SKaiChieh Chuang {"ADDA Capture", NULL, "ADDA Enable"},
13942a589e8SKaiChieh Chuang {"ADDA Capture", NULL, "ADDA Capture Enable"},
14042a589e8SKaiChieh Chuang
14142a589e8SKaiChieh Chuang /* clk */
14242a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "mtkaif_26m_clk"},
14342a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "aud_dac_clk"},
14442a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "aud_dac_predis_clk"},
14542a589e8SKaiChieh Chuang
14642a589e8SKaiChieh Chuang {"ADDA Capture", NULL, "mtkaif_26m_clk"},
14742a589e8SKaiChieh Chuang {"ADDA Capture", NULL, "aud_adc_clk"},
14842a589e8SKaiChieh Chuang };
14942a589e8SKaiChieh Chuang
15042a589e8SKaiChieh Chuang /* dai ops */
mtk_dai_adda_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)15142a589e8SKaiChieh Chuang static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
15242a589e8SKaiChieh Chuang struct snd_pcm_hw_params *params,
15342a589e8SKaiChieh Chuang struct snd_soc_dai *dai)
15442a589e8SKaiChieh Chuang {
15542a589e8SKaiChieh Chuang struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
15642a589e8SKaiChieh Chuang unsigned int rate = params_rate(params);
15742a589e8SKaiChieh Chuang
15842a589e8SKaiChieh Chuang dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
15942a589e8SKaiChieh Chuang __func__, dai->id, substream->stream, rate);
16042a589e8SKaiChieh Chuang
16142a589e8SKaiChieh Chuang if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
16242a589e8SKaiChieh Chuang unsigned int dl_src2_con0 = 0;
16342a589e8SKaiChieh Chuang unsigned int dl_src2_con1 = 0;
16442a589e8SKaiChieh Chuang
16542a589e8SKaiChieh Chuang /* clean predistortion */
16642a589e8SKaiChieh Chuang regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0);
16742a589e8SKaiChieh Chuang regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0);
16842a589e8SKaiChieh Chuang
16942a589e8SKaiChieh Chuang /* set input sampling rate */
170*d6c01755SAngeloGioacchino Del Regno dl_src2_con0 = mtk_adda_dl_rate_transform(afe, rate) << 28;
17142a589e8SKaiChieh Chuang
17242a589e8SKaiChieh Chuang /* set output mode */
17342a589e8SKaiChieh Chuang switch (rate) {
17442a589e8SKaiChieh Chuang case 192000:
17542a589e8SKaiChieh Chuang dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */
17642a589e8SKaiChieh Chuang dl_src2_con0 |= 1 << 14;
17742a589e8SKaiChieh Chuang break;
17842a589e8SKaiChieh Chuang case 96000:
17942a589e8SKaiChieh Chuang dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */
18042a589e8SKaiChieh Chuang dl_src2_con0 |= 1 << 14;
18142a589e8SKaiChieh Chuang break;
18242a589e8SKaiChieh Chuang default:
18342a589e8SKaiChieh Chuang dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */
18442a589e8SKaiChieh Chuang break;
18542a589e8SKaiChieh Chuang }
18642a589e8SKaiChieh Chuang
18742a589e8SKaiChieh Chuang /* turn off mute function */
18842a589e8SKaiChieh Chuang dl_src2_con0 |= (0x03 << 11);
18942a589e8SKaiChieh Chuang
19042a589e8SKaiChieh Chuang /* set voice input data if input sample rate is 8k or 16k */
19142a589e8SKaiChieh Chuang if (rate == 8000 || rate == 16000)
19242a589e8SKaiChieh Chuang dl_src2_con0 |= 0x01 << 5;
19342a589e8SKaiChieh Chuang
19442a589e8SKaiChieh Chuang if (rate < 96000) {
19542a589e8SKaiChieh Chuang /* SA suggest apply -0.3db to audio/speech path */
19642a589e8SKaiChieh Chuang dl_src2_con1 = 0xf74f0000;
19742a589e8SKaiChieh Chuang } else {
19842a589e8SKaiChieh Chuang /* SA suggest apply -0.3db to audio/speech path
19942a589e8SKaiChieh Chuang * with DL gain set to half,
20042a589e8SKaiChieh Chuang * 0xFFFF = 0dB -> 0x8000 = 0dB when 96k, 192k
20142a589e8SKaiChieh Chuang */
20242a589e8SKaiChieh Chuang dl_src2_con1 = 0x7ba70000;
20342a589e8SKaiChieh Chuang }
20442a589e8SKaiChieh Chuang
20542a589e8SKaiChieh Chuang /* turn on down-link gain */
20642a589e8SKaiChieh Chuang dl_src2_con0 = dl_src2_con0 | (0x01 << 1);
20742a589e8SKaiChieh Chuang
20842a589e8SKaiChieh Chuang regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0);
20942a589e8SKaiChieh Chuang regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1);
21042a589e8SKaiChieh Chuang } else {
21142a589e8SKaiChieh Chuang unsigned int voice_mode = 0;
21242a589e8SKaiChieh Chuang unsigned int ul_src_con0 = 0; /* default value */
21342a589e8SKaiChieh Chuang
21442a589e8SKaiChieh Chuang /* Using Internal ADC */
21542a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap,
21642a589e8SKaiChieh Chuang AFE_ADDA_TOP_CON0,
21742a589e8SKaiChieh Chuang 0x1 << 0,
21842a589e8SKaiChieh Chuang 0x0 << 0);
21942a589e8SKaiChieh Chuang
220*d6c01755SAngeloGioacchino Del Regno voice_mode = mtk_adda_ul_rate_transform(afe, rate);
22142a589e8SKaiChieh Chuang
22242a589e8SKaiChieh Chuang ul_src_con0 |= (voice_mode << 17) & (0x7 << 17);
22342a589e8SKaiChieh Chuang
22442a589e8SKaiChieh Chuang /* up8x txif sat on */
22542a589e8SKaiChieh Chuang regmap_write(afe->regmap, AFE_ADDA_NEWIF_CFG0, 0x03F87201);
22642a589e8SKaiChieh Chuang
22742a589e8SKaiChieh Chuang if (rate >= 96000) { /* hires */
22842a589e8SKaiChieh Chuang /* use hires format [1 0 23] */
22942a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap,
23042a589e8SKaiChieh Chuang AFE_ADDA_NEWIF_CFG0,
23142a589e8SKaiChieh Chuang 0x1 << 5,
23242a589e8SKaiChieh Chuang 0x1 << 5);
23342a589e8SKaiChieh Chuang
23442a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap,
23542a589e8SKaiChieh Chuang AFE_ADDA_NEWIF_CFG2,
23642a589e8SKaiChieh Chuang 0xf << 28,
23742a589e8SKaiChieh Chuang voice_mode << 28);
23842a589e8SKaiChieh Chuang } else { /* normal 8~48k */
23942a589e8SKaiChieh Chuang /* use fixed 260k anc path */
24042a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap,
24142a589e8SKaiChieh Chuang AFE_ADDA_NEWIF_CFG2,
24242a589e8SKaiChieh Chuang 0xf << 28,
24342a589e8SKaiChieh Chuang 8 << 28);
24442a589e8SKaiChieh Chuang
24542a589e8SKaiChieh Chuang /* ul_use_cic_out */
24642a589e8SKaiChieh Chuang ul_src_con0 |= 0x1 << 20;
24742a589e8SKaiChieh Chuang }
24842a589e8SKaiChieh Chuang
24942a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap,
25042a589e8SKaiChieh Chuang AFE_ADDA_NEWIF_CFG2,
25142a589e8SKaiChieh Chuang 0xf << 28,
25242a589e8SKaiChieh Chuang 8 << 28);
25342a589e8SKaiChieh Chuang
25442a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap,
25542a589e8SKaiChieh Chuang AFE_ADDA_UL_SRC_CON0,
25642a589e8SKaiChieh Chuang 0xfffffffe,
25742a589e8SKaiChieh Chuang ul_src_con0);
25842a589e8SKaiChieh Chuang }
25942a589e8SKaiChieh Chuang
26042a589e8SKaiChieh Chuang return 0;
26142a589e8SKaiChieh Chuang }
26242a589e8SKaiChieh Chuang
26342a589e8SKaiChieh Chuang static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
26442a589e8SKaiChieh Chuang .hw_params = mtk_dai_adda_hw_params,
26542a589e8SKaiChieh Chuang };
26642a589e8SKaiChieh Chuang
26742a589e8SKaiChieh Chuang /* dai driver */
26842a589e8SKaiChieh Chuang #define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
26942a589e8SKaiChieh Chuang SNDRV_PCM_RATE_96000 |\
27042a589e8SKaiChieh Chuang SNDRV_PCM_RATE_192000)
27142a589e8SKaiChieh Chuang
27242a589e8SKaiChieh Chuang #define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
27342a589e8SKaiChieh Chuang SNDRV_PCM_RATE_16000 |\
27442a589e8SKaiChieh Chuang SNDRV_PCM_RATE_32000 |\
27542a589e8SKaiChieh Chuang SNDRV_PCM_RATE_48000 |\
27642a589e8SKaiChieh Chuang SNDRV_PCM_RATE_96000 |\
27742a589e8SKaiChieh Chuang SNDRV_PCM_RATE_192000)
27842a589e8SKaiChieh Chuang
27942a589e8SKaiChieh Chuang #define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
28042a589e8SKaiChieh Chuang SNDRV_PCM_FMTBIT_S24_LE |\
28142a589e8SKaiChieh Chuang SNDRV_PCM_FMTBIT_S32_LE)
28242a589e8SKaiChieh Chuang
28342a589e8SKaiChieh Chuang static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
28442a589e8SKaiChieh Chuang {
28542a589e8SKaiChieh Chuang .name = "ADDA",
28642a589e8SKaiChieh Chuang .id = MT6797_DAI_ADDA,
28742a589e8SKaiChieh Chuang .playback = {
28842a589e8SKaiChieh Chuang .stream_name = "ADDA Playback",
28942a589e8SKaiChieh Chuang .channels_min = 1,
29042a589e8SKaiChieh Chuang .channels_max = 2,
29142a589e8SKaiChieh Chuang .rates = MTK_ADDA_PLAYBACK_RATES,
29242a589e8SKaiChieh Chuang .formats = MTK_ADDA_FORMATS,
29342a589e8SKaiChieh Chuang },
29442a589e8SKaiChieh Chuang .capture = {
29542a589e8SKaiChieh Chuang .stream_name = "ADDA Capture",
29642a589e8SKaiChieh Chuang .channels_min = 1,
29742a589e8SKaiChieh Chuang .channels_max = 2,
29842a589e8SKaiChieh Chuang .rates = MTK_ADDA_CAPTURE_RATES,
29942a589e8SKaiChieh Chuang .formats = MTK_ADDA_FORMATS,
30042a589e8SKaiChieh Chuang },
30142a589e8SKaiChieh Chuang .ops = &mtk_dai_adda_ops,
30242a589e8SKaiChieh Chuang },
30342a589e8SKaiChieh Chuang };
30442a589e8SKaiChieh Chuang
mt6797_dai_adda_register(struct mtk_base_afe * afe)30542a589e8SKaiChieh Chuang int mt6797_dai_adda_register(struct mtk_base_afe *afe)
30642a589e8SKaiChieh Chuang {
307c1d9b419SKaiChieh Chuang struct mtk_base_afe_dai *dai;
30842a589e8SKaiChieh Chuang
309c1d9b419SKaiChieh Chuang dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
310c1d9b419SKaiChieh Chuang if (!dai)
311c1d9b419SKaiChieh Chuang return -ENOMEM;
31242a589e8SKaiChieh Chuang
313c1d9b419SKaiChieh Chuang list_add(&dai->list, &afe->sub_dais);
314c1d9b419SKaiChieh Chuang
315c1d9b419SKaiChieh Chuang dai->dai_drivers = mtk_dai_adda_driver;
316c1d9b419SKaiChieh Chuang dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
317c1d9b419SKaiChieh Chuang
318c1d9b419SKaiChieh Chuang dai->dapm_widgets = mtk_dai_adda_widgets;
319c1d9b419SKaiChieh Chuang dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
320c1d9b419SKaiChieh Chuang dai->dapm_routes = mtk_dai_adda_routes;
321c1d9b419SKaiChieh Chuang dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
32242a589e8SKaiChieh Chuang return 0;
32342a589e8SKaiChieh Chuang }
324