1*7c58c88eSAlexandre Mergnat // SPDX-License-Identifier: GPL-2.0 2*7c58c88eSAlexandre Mergnat /* 3*7c58c88eSAlexandre Mergnat * MediaTek 8365 ALSA SoC Audio DAI ADDA Control 4*7c58c88eSAlexandre Mergnat * 5*7c58c88eSAlexandre Mergnat * Copyright (c) 2024 MediaTek Inc. 6*7c58c88eSAlexandre Mergnat * Authors: Jia Zeng <jia.zeng@mediatek.com> 7*7c58c88eSAlexandre Mergnat * Alexandre Mergnat <amergnat@baylibre.com> 8*7c58c88eSAlexandre Mergnat */ 9*7c58c88eSAlexandre Mergnat 10*7c58c88eSAlexandre Mergnat #include <linux/bitops.h> 11*7c58c88eSAlexandre Mergnat #include <linux/regmap.h> 12*7c58c88eSAlexandre Mergnat #include <sound/pcm_params.h> 13*7c58c88eSAlexandre Mergnat #include "mt8365-afe-clk.h" 14*7c58c88eSAlexandre Mergnat #include "mt8365-afe-common.h" 15*7c58c88eSAlexandre Mergnat #include "../common/mtk-dai-adda-common.h" 16*7c58c88eSAlexandre Mergnat 17*7c58c88eSAlexandre Mergnat static int adda_afe_on_ref_cnt; 18*7c58c88eSAlexandre Mergnat 19*7c58c88eSAlexandre Mergnat /* DAI Drivers */ 20*7c58c88eSAlexandre Mergnat 21*7c58c88eSAlexandre Mergnat static int mt8365_dai_set_adda_out(struct mtk_base_afe *afe, unsigned int rate) 22*7c58c88eSAlexandre Mergnat { 23*7c58c88eSAlexandre Mergnat unsigned int val; 24*7c58c88eSAlexandre Mergnat 25*7c58c88eSAlexandre Mergnat if (rate == 8000 || rate == 16000) 26*7c58c88eSAlexandre Mergnat val = AFE_ADDA_DL_VOICE_DATA; 27*7c58c88eSAlexandre Mergnat else 28*7c58c88eSAlexandre Mergnat val = 0; 29*7c58c88eSAlexandre Mergnat 30*7c58c88eSAlexandre Mergnat val |= FIELD_PREP(AFE_ADDA_DL_SAMPLING_RATE, 31*7c58c88eSAlexandre Mergnat mtk_adda_dl_rate_transform(afe, rate)); 32*7c58c88eSAlexandre Mergnat val |= AFE_ADDA_DL_8X_UPSAMPLE | 33*7c58c88eSAlexandre Mergnat AFE_ADDA_DL_MUTE_OFF_CH1 | 34*7c58c88eSAlexandre Mergnat AFE_ADDA_DL_MUTE_OFF_CH2 | 35*7c58c88eSAlexandre Mergnat AFE_ADDA_DL_DEGRADE_GAIN; 36*7c58c88eSAlexandre Mergnat 37*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_PREDIS_CON0, 0xffffffff, 0); 38*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_PREDIS_CON1, 0xffffffff, 0); 39*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, 0xffffffff, val); 40*7c58c88eSAlexandre Mergnat /* SA suggest apply -0.3db to audio/speech path */ 41*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON1, 42*7c58c88eSAlexandre Mergnat 0xffffffff, 0xf74f0000); 43*7c58c88eSAlexandre Mergnat /* SA suggest use default value for sdm */ 44*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON, 45*7c58c88eSAlexandre Mergnat 0xffffffff, 0x0700701e); 46*7c58c88eSAlexandre Mergnat 47*7c58c88eSAlexandre Mergnat return 0; 48*7c58c88eSAlexandre Mergnat } 49*7c58c88eSAlexandre Mergnat 50*7c58c88eSAlexandre Mergnat static int mt8365_dai_set_adda_in(struct mtk_base_afe *afe, unsigned int rate) 51*7c58c88eSAlexandre Mergnat { 52*7c58c88eSAlexandre Mergnat unsigned int val; 53*7c58c88eSAlexandre Mergnat 54*7c58c88eSAlexandre Mergnat val = FIELD_PREP(AFE_ADDA_UL_SAMPLING_RATE, 55*7c58c88eSAlexandre Mergnat mtk_adda_ul_rate_transform(afe, rate)); 56*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 57*7c58c88eSAlexandre Mergnat AFE_ADDA_UL_SAMPLING_RATE, val); 58*7c58c88eSAlexandre Mergnat /* Using Internal ADC */ 59*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, 0x1, 0x0); 60*7c58c88eSAlexandre Mergnat 61*7c58c88eSAlexandre Mergnat return 0; 62*7c58c88eSAlexandre Mergnat } 63*7c58c88eSAlexandre Mergnat 64*7c58c88eSAlexandre Mergnat int mt8365_dai_enable_adda_on(struct mtk_base_afe *afe) 65*7c58c88eSAlexandre Mergnat { 66*7c58c88eSAlexandre Mergnat unsigned long flags; 67*7c58c88eSAlexandre Mergnat struct mt8365_afe_private *afe_priv = afe->platform_priv; 68*7c58c88eSAlexandre Mergnat 69*7c58c88eSAlexandre Mergnat spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); 70*7c58c88eSAlexandre Mergnat 71*7c58c88eSAlexandre Mergnat adda_afe_on_ref_cnt++; 72*7c58c88eSAlexandre Mergnat if (adda_afe_on_ref_cnt == 1) 73*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0, 74*7c58c88eSAlexandre Mergnat AFE_ADDA_UL_DL_ADDA_AFE_ON, 75*7c58c88eSAlexandre Mergnat AFE_ADDA_UL_DL_ADDA_AFE_ON); 76*7c58c88eSAlexandre Mergnat 77*7c58c88eSAlexandre Mergnat spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); 78*7c58c88eSAlexandre Mergnat 79*7c58c88eSAlexandre Mergnat return 0; 80*7c58c88eSAlexandre Mergnat } 81*7c58c88eSAlexandre Mergnat 82*7c58c88eSAlexandre Mergnat int mt8365_dai_disable_adda_on(struct mtk_base_afe *afe) 83*7c58c88eSAlexandre Mergnat { 84*7c58c88eSAlexandre Mergnat unsigned long flags; 85*7c58c88eSAlexandre Mergnat struct mt8365_afe_private *afe_priv = afe->platform_priv; 86*7c58c88eSAlexandre Mergnat 87*7c58c88eSAlexandre Mergnat spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); 88*7c58c88eSAlexandre Mergnat 89*7c58c88eSAlexandre Mergnat adda_afe_on_ref_cnt--; 90*7c58c88eSAlexandre Mergnat if (adda_afe_on_ref_cnt == 0) 91*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0, 92*7c58c88eSAlexandre Mergnat AFE_ADDA_UL_DL_ADDA_AFE_ON, 93*7c58c88eSAlexandre Mergnat ~AFE_ADDA_UL_DL_ADDA_AFE_ON); 94*7c58c88eSAlexandre Mergnat else if (adda_afe_on_ref_cnt < 0) { 95*7c58c88eSAlexandre Mergnat adda_afe_on_ref_cnt = 0; 96*7c58c88eSAlexandre Mergnat dev_warn(afe->dev, "Abnormal adda_on ref count. Force it to 0\n"); 97*7c58c88eSAlexandre Mergnat } 98*7c58c88eSAlexandre Mergnat 99*7c58c88eSAlexandre Mergnat spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); 100*7c58c88eSAlexandre Mergnat 101*7c58c88eSAlexandre Mergnat return 0; 102*7c58c88eSAlexandre Mergnat } 103*7c58c88eSAlexandre Mergnat 104*7c58c88eSAlexandre Mergnat static void mt8365_dai_set_adda_out_enable(struct mtk_base_afe *afe, 105*7c58c88eSAlexandre Mergnat bool enable) 106*7c58c88eSAlexandre Mergnat { 107*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, 0x1, enable); 108*7c58c88eSAlexandre Mergnat 109*7c58c88eSAlexandre Mergnat if (enable) 110*7c58c88eSAlexandre Mergnat mt8365_dai_enable_adda_on(afe); 111*7c58c88eSAlexandre Mergnat else 112*7c58c88eSAlexandre Mergnat mt8365_dai_disable_adda_on(afe); 113*7c58c88eSAlexandre Mergnat } 114*7c58c88eSAlexandre Mergnat 115*7c58c88eSAlexandre Mergnat static void mt8365_dai_set_adda_in_enable(struct mtk_base_afe *afe, bool enable) 116*7c58c88eSAlexandre Mergnat { 117*7c58c88eSAlexandre Mergnat if (enable) { 118*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 0x1, 0x1); 119*7c58c88eSAlexandre Mergnat mt8365_dai_enable_adda_on(afe); 120*7c58c88eSAlexandre Mergnat /* enable aud_pad_top fifo */ 121*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, 122*7c58c88eSAlexandre Mergnat 0xffffffff, 0x31); 123*7c58c88eSAlexandre Mergnat } else { 124*7c58c88eSAlexandre Mergnat /* disable aud_pad_top fifo */ 125*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, 126*7c58c88eSAlexandre Mergnat 0xffffffff, 0x30); 127*7c58c88eSAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 0x1, 0x0); 128*7c58c88eSAlexandre Mergnat /* de suggest disable ADDA_UL_SRC at least wait 125us */ 129*7c58c88eSAlexandre Mergnat usleep_range(150, 300); 130*7c58c88eSAlexandre Mergnat mt8365_dai_disable_adda_on(afe); 131*7c58c88eSAlexandre Mergnat } 132*7c58c88eSAlexandre Mergnat } 133*7c58c88eSAlexandre Mergnat 134*7c58c88eSAlexandre Mergnat static int mt8365_dai_int_adda_startup(struct snd_pcm_substream *substream, 135*7c58c88eSAlexandre Mergnat struct snd_soc_dai *dai) 136*7c58c88eSAlexandre Mergnat { 137*7c58c88eSAlexandre Mergnat struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 138*7c58c88eSAlexandre Mergnat unsigned int stream = substream->stream; 139*7c58c88eSAlexandre Mergnat 140*7c58c88eSAlexandre Mergnat mt8365_afe_enable_main_clk(afe); 141*7c58c88eSAlexandre Mergnat 142*7c58c88eSAlexandre Mergnat if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 143*7c58c88eSAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DAC); 144*7c58c88eSAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DAC_PREDIS); 145*7c58c88eSAlexandre Mergnat } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { 146*7c58c88eSAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_ADC); 147*7c58c88eSAlexandre Mergnat } 148*7c58c88eSAlexandre Mergnat 149*7c58c88eSAlexandre Mergnat return 0; 150*7c58c88eSAlexandre Mergnat } 151*7c58c88eSAlexandre Mergnat 152*7c58c88eSAlexandre Mergnat static void mt8365_dai_int_adda_shutdown(struct snd_pcm_substream *substream, 153*7c58c88eSAlexandre Mergnat struct snd_soc_dai *dai) 154*7c58c88eSAlexandre Mergnat { 155*7c58c88eSAlexandre Mergnat struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 156*7c58c88eSAlexandre Mergnat struct mt8365_afe_private *afe_priv = afe->platform_priv; 157*7c58c88eSAlexandre Mergnat struct mt8365_be_dai_data *be = 158*7c58c88eSAlexandre Mergnat &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; 159*7c58c88eSAlexandre Mergnat unsigned int stream = substream->stream; 160*7c58c88eSAlexandre Mergnat 161*7c58c88eSAlexandre Mergnat if (be->prepared[stream]) { 162*7c58c88eSAlexandre Mergnat if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 163*7c58c88eSAlexandre Mergnat mt8365_dai_set_adda_out_enable(afe, false); 164*7c58c88eSAlexandre Mergnat mt8365_afe_set_i2s_out_enable(afe, false); 165*7c58c88eSAlexandre Mergnat } else { 166*7c58c88eSAlexandre Mergnat mt8365_dai_set_adda_in_enable(afe, false); 167*7c58c88eSAlexandre Mergnat } 168*7c58c88eSAlexandre Mergnat be->prepared[stream] = false; 169*7c58c88eSAlexandre Mergnat } 170*7c58c88eSAlexandre Mergnat 171*7c58c88eSAlexandre Mergnat if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 172*7c58c88eSAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DAC_PREDIS); 173*7c58c88eSAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DAC); 174*7c58c88eSAlexandre Mergnat } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { 175*7c58c88eSAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_ADC); 176*7c58c88eSAlexandre Mergnat } 177*7c58c88eSAlexandre Mergnat 178*7c58c88eSAlexandre Mergnat mt8365_afe_disable_main_clk(afe); 179*7c58c88eSAlexandre Mergnat } 180*7c58c88eSAlexandre Mergnat 181*7c58c88eSAlexandre Mergnat static int mt8365_dai_int_adda_prepare(struct snd_pcm_substream *substream, 182*7c58c88eSAlexandre Mergnat struct snd_soc_dai *dai) 183*7c58c88eSAlexandre Mergnat { 184*7c58c88eSAlexandre Mergnat struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 185*7c58c88eSAlexandre Mergnat struct mt8365_afe_private *afe_priv = afe->platform_priv; 186*7c58c88eSAlexandre Mergnat struct mt8365_be_dai_data *be = 187*7c58c88eSAlexandre Mergnat &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; 188*7c58c88eSAlexandre Mergnat unsigned int rate = substream->runtime->rate; 189*7c58c88eSAlexandre Mergnat int bit_width = snd_pcm_format_width(substream->runtime->format); 190*7c58c88eSAlexandre Mergnat int ret; 191*7c58c88eSAlexandre Mergnat 192*7c58c88eSAlexandre Mergnat dev_info(afe->dev, "%s '%s' rate = %u\n", __func__, 193*7c58c88eSAlexandre Mergnat snd_pcm_stream_str(substream), rate); 194*7c58c88eSAlexandre Mergnat 195*7c58c88eSAlexandre Mergnat if (be->prepared[substream->stream]) { 196*7c58c88eSAlexandre Mergnat dev_info(afe->dev, "%s '%s' prepared already\n", 197*7c58c88eSAlexandre Mergnat __func__, snd_pcm_stream_str(substream)); 198*7c58c88eSAlexandre Mergnat return 0; 199*7c58c88eSAlexandre Mergnat } 200*7c58c88eSAlexandre Mergnat 201*7c58c88eSAlexandre Mergnat if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 202*7c58c88eSAlexandre Mergnat ret = mt8365_dai_set_adda_out(afe, rate); 203*7c58c88eSAlexandre Mergnat if (ret) 204*7c58c88eSAlexandre Mergnat return ret; 205*7c58c88eSAlexandre Mergnat 206*7c58c88eSAlexandre Mergnat ret = mt8365_afe_set_i2s_out(afe, rate, bit_width); 207*7c58c88eSAlexandre Mergnat if (ret) 208*7c58c88eSAlexandre Mergnat return ret; 209*7c58c88eSAlexandre Mergnat 210*7c58c88eSAlexandre Mergnat mt8365_dai_set_adda_out_enable(afe, true); 211*7c58c88eSAlexandre Mergnat mt8365_afe_set_i2s_out_enable(afe, true); 212*7c58c88eSAlexandre Mergnat } else { 213*7c58c88eSAlexandre Mergnat ret = mt8365_dai_set_adda_in(afe, rate); 214*7c58c88eSAlexandre Mergnat if (ret) 215*7c58c88eSAlexandre Mergnat return ret; 216*7c58c88eSAlexandre Mergnat 217*7c58c88eSAlexandre Mergnat mt8365_dai_set_adda_in_enable(afe, true); 218*7c58c88eSAlexandre Mergnat } 219*7c58c88eSAlexandre Mergnat be->prepared[substream->stream] = true; 220*7c58c88eSAlexandre Mergnat return 0; 221*7c58c88eSAlexandre Mergnat } 222*7c58c88eSAlexandre Mergnat 223*7c58c88eSAlexandre Mergnat static const struct snd_soc_dai_ops mt8365_afe_int_adda_ops = { 224*7c58c88eSAlexandre Mergnat .startup = mt8365_dai_int_adda_startup, 225*7c58c88eSAlexandre Mergnat .shutdown = mt8365_dai_int_adda_shutdown, 226*7c58c88eSAlexandre Mergnat .prepare = mt8365_dai_int_adda_prepare, 227*7c58c88eSAlexandre Mergnat }; 228*7c58c88eSAlexandre Mergnat 229*7c58c88eSAlexandre Mergnat static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { 230*7c58c88eSAlexandre Mergnat { 231*7c58c88eSAlexandre Mergnat .name = "INT ADDA", 232*7c58c88eSAlexandre Mergnat .id = MT8365_AFE_IO_INT_ADDA, 233*7c58c88eSAlexandre Mergnat .playback = { 234*7c58c88eSAlexandre Mergnat .stream_name = "INT ADDA Playback", 235*7c58c88eSAlexandre Mergnat .channels_min = 1, 236*7c58c88eSAlexandre Mergnat .channels_max = 2, 237*7c58c88eSAlexandre Mergnat .rates = SNDRV_PCM_RATE_8000_48000, 238*7c58c88eSAlexandre Mergnat .formats = SNDRV_PCM_FMTBIT_S16_LE, 239*7c58c88eSAlexandre Mergnat }, 240*7c58c88eSAlexandre Mergnat .capture = { 241*7c58c88eSAlexandre Mergnat .stream_name = "INT ADDA Capture", 242*7c58c88eSAlexandre Mergnat .channels_min = 1, 243*7c58c88eSAlexandre Mergnat .channels_max = 2, 244*7c58c88eSAlexandre Mergnat .rates = SNDRV_PCM_RATE_16000 | 245*7c58c88eSAlexandre Mergnat SNDRV_PCM_RATE_32000 | 246*7c58c88eSAlexandre Mergnat SNDRV_PCM_RATE_48000, 247*7c58c88eSAlexandre Mergnat .formats = SNDRV_PCM_FMTBIT_S16_LE | 248*7c58c88eSAlexandre Mergnat SNDRV_PCM_FMTBIT_S32_LE, 249*7c58c88eSAlexandre Mergnat }, 250*7c58c88eSAlexandre Mergnat .ops = &mt8365_afe_int_adda_ops, 251*7c58c88eSAlexandre Mergnat } 252*7c58c88eSAlexandre Mergnat }; 253*7c58c88eSAlexandre Mergnat 254*7c58c88eSAlexandre Mergnat /* DAI Controls */ 255*7c58c88eSAlexandre Mergnat 256*7c58c88eSAlexandre Mergnat static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { 257*7c58c88eSAlexandre Mergnat SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN3, 258*7c58c88eSAlexandre Mergnat 10, 1, 0), 259*7c58c88eSAlexandre Mergnat }; 260*7c58c88eSAlexandre Mergnat 261*7c58c88eSAlexandre Mergnat static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { 262*7c58c88eSAlexandre Mergnat SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN4, 263*7c58c88eSAlexandre Mergnat 11, 1, 0), 264*7c58c88eSAlexandre Mergnat }; 265*7c58c88eSAlexandre Mergnat 266*7c58c88eSAlexandre Mergnat static const struct snd_kcontrol_new int_adda_o03_o04_enable_ctl = 267*7c58c88eSAlexandre Mergnat SOC_DAPM_SINGLE_VIRT("Switch", 1); 268*7c58c88eSAlexandre Mergnat 269*7c58c88eSAlexandre Mergnat /* DAI widget */ 270*7c58c88eSAlexandre Mergnat 271*7c58c88eSAlexandre Mergnat static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { 272*7c58c88eSAlexandre Mergnat SND_SOC_DAPM_SWITCH("INT ADDA O03_O04", SND_SOC_NOPM, 0, 0, 273*7c58c88eSAlexandre Mergnat &int_adda_o03_o04_enable_ctl), 274*7c58c88eSAlexandre Mergnat /* inter-connections */ 275*7c58c88eSAlexandre Mergnat SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, 276*7c58c88eSAlexandre Mergnat mtk_adda_dl_ch1_mix, 277*7c58c88eSAlexandre Mergnat ARRAY_SIZE(mtk_adda_dl_ch1_mix)), 278*7c58c88eSAlexandre Mergnat SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, 279*7c58c88eSAlexandre Mergnat mtk_adda_dl_ch2_mix, 280*7c58c88eSAlexandre Mergnat ARRAY_SIZE(mtk_adda_dl_ch2_mix)), 281*7c58c88eSAlexandre Mergnat }; 282*7c58c88eSAlexandre Mergnat 283*7c58c88eSAlexandre Mergnat /* DAI route */ 284*7c58c88eSAlexandre Mergnat 285*7c58c88eSAlexandre Mergnat static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { 286*7c58c88eSAlexandre Mergnat {"INT ADDA O03_O04", "Switch", "O03"}, 287*7c58c88eSAlexandre Mergnat {"INT ADDA O03_O04", "Switch", "O04"}, 288*7c58c88eSAlexandre Mergnat {"INT ADDA Playback", NULL, "INT ADDA O03_O04"}, 289*7c58c88eSAlexandre Mergnat {"INT ADDA Playback", NULL, "ADDA_DL_CH1"}, 290*7c58c88eSAlexandre Mergnat {"INT ADDA Playback", NULL, "ADDA_DL_CH2"}, 291*7c58c88eSAlexandre Mergnat {"AIN Mux", "INT ADC", "INT ADDA Capture"}, 292*7c58c88eSAlexandre Mergnat {"ADDA_DL_CH1", "GAIN1_OUT_CH1", "Hostless FM DL"}, 293*7c58c88eSAlexandre Mergnat {"ADDA_DL_CH2", "GAIN1_OUT_CH2", "Hostless FM DL"}, 294*7c58c88eSAlexandre Mergnat }; 295*7c58c88eSAlexandre Mergnat 296*7c58c88eSAlexandre Mergnat int mt8365_dai_adda_register(struct mtk_base_afe *afe) 297*7c58c88eSAlexandre Mergnat { 298*7c58c88eSAlexandre Mergnat struct mtk_base_afe_dai *dai; 299*7c58c88eSAlexandre Mergnat 300*7c58c88eSAlexandre Mergnat dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 301*7c58c88eSAlexandre Mergnat if (!dai) 302*7c58c88eSAlexandre Mergnat return -ENOMEM; 303*7c58c88eSAlexandre Mergnat list_add(&dai->list, &afe->sub_dais); 304*7c58c88eSAlexandre Mergnat dai->dai_drivers = mtk_dai_adda_driver; 305*7c58c88eSAlexandre Mergnat dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); 306*7c58c88eSAlexandre Mergnat dai->dapm_widgets = mtk_dai_adda_widgets; 307*7c58c88eSAlexandre Mergnat dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); 308*7c58c88eSAlexandre Mergnat dai->dapm_routes = mtk_dai_adda_routes; 309*7c58c88eSAlexandre Mergnat dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); 310*7c58c88eSAlexandre Mergnat return 0; 311*7c58c88eSAlexandre Mergnat } 312