1*42a589e8SKaiChieh Chuang // SPDX-License-Identifier: GPL-2.0 2*42a589e8SKaiChieh Chuang // 3*42a589e8SKaiChieh Chuang // MediaTek ALSA SoC Audio DAI ADDA Control 4*42a589e8SKaiChieh Chuang // 5*42a589e8SKaiChieh Chuang // Copyright (c) 2018 MediaTek Inc. 6*42a589e8SKaiChieh Chuang // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com> 7*42a589e8SKaiChieh Chuang 8*42a589e8SKaiChieh Chuang #include <linux/regmap.h> 9*42a589e8SKaiChieh Chuang #include <linux/delay.h> 10*42a589e8SKaiChieh Chuang #include "mt6797-afe-common.h" 11*42a589e8SKaiChieh Chuang #include "mt6797-interconnection.h" 12*42a589e8SKaiChieh Chuang #include "mt6797-reg.h" 13*42a589e8SKaiChieh Chuang 14*42a589e8SKaiChieh Chuang enum { 15*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_8K = 0, 16*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_11K = 1, 17*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_12K = 2, 18*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_16K = 3, 19*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_22K = 4, 20*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_24K = 5, 21*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_32K = 6, 22*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_44K = 7, 23*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_48K = 8, 24*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_96K = 9, 25*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_DL_RATE_192K = 10, 26*42a589e8SKaiChieh Chuang }; 27*42a589e8SKaiChieh Chuang 28*42a589e8SKaiChieh Chuang enum { 29*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_UL_RATE_8K = 0, 30*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_UL_RATE_16K = 1, 31*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_UL_RATE_32K = 2, 32*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_UL_RATE_48K = 3, 33*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_UL_RATE_96K = 4, 34*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_UL_RATE_192K = 5, 35*42a589e8SKaiChieh Chuang MTK_AFE_ADDA_UL_RATE_48K_HD = 6, 36*42a589e8SKaiChieh Chuang }; 37*42a589e8SKaiChieh Chuang 38*42a589e8SKaiChieh Chuang static unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe, 39*42a589e8SKaiChieh Chuang unsigned int rate) 40*42a589e8SKaiChieh Chuang { 41*42a589e8SKaiChieh Chuang switch (rate) { 42*42a589e8SKaiChieh Chuang case 8000: 43*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_8K; 44*42a589e8SKaiChieh Chuang case 11025: 45*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_11K; 46*42a589e8SKaiChieh Chuang case 12000: 47*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_12K; 48*42a589e8SKaiChieh Chuang case 16000: 49*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_16K; 50*42a589e8SKaiChieh Chuang case 22050: 51*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_22K; 52*42a589e8SKaiChieh Chuang case 24000: 53*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_24K; 54*42a589e8SKaiChieh Chuang case 32000: 55*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_32K; 56*42a589e8SKaiChieh Chuang case 44100: 57*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_44K; 58*42a589e8SKaiChieh Chuang case 48000: 59*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_48K; 60*42a589e8SKaiChieh Chuang case 96000: 61*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_96K; 62*42a589e8SKaiChieh Chuang case 192000: 63*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_192K; 64*42a589e8SKaiChieh Chuang default: 65*42a589e8SKaiChieh Chuang dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", 66*42a589e8SKaiChieh Chuang __func__, rate); 67*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_DL_RATE_48K; 68*42a589e8SKaiChieh Chuang } 69*42a589e8SKaiChieh Chuang } 70*42a589e8SKaiChieh Chuang 71*42a589e8SKaiChieh Chuang static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe, 72*42a589e8SKaiChieh Chuang unsigned int rate) 73*42a589e8SKaiChieh Chuang { 74*42a589e8SKaiChieh Chuang switch (rate) { 75*42a589e8SKaiChieh Chuang case 8000: 76*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_UL_RATE_8K; 77*42a589e8SKaiChieh Chuang case 16000: 78*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_UL_RATE_16K; 79*42a589e8SKaiChieh Chuang case 32000: 80*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_UL_RATE_32K; 81*42a589e8SKaiChieh Chuang case 48000: 82*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_UL_RATE_48K; 83*42a589e8SKaiChieh Chuang case 96000: 84*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_UL_RATE_96K; 85*42a589e8SKaiChieh Chuang case 192000: 86*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_UL_RATE_192K; 87*42a589e8SKaiChieh Chuang default: 88*42a589e8SKaiChieh Chuang dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", 89*42a589e8SKaiChieh Chuang __func__, rate); 90*42a589e8SKaiChieh Chuang return MTK_AFE_ADDA_UL_RATE_48K; 91*42a589e8SKaiChieh Chuang } 92*42a589e8SKaiChieh Chuang } 93*42a589e8SKaiChieh Chuang 94*42a589e8SKaiChieh Chuang /* dai component */ 95*42a589e8SKaiChieh Chuang static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { 96*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0), 97*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0), 98*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0), 99*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3, 100*42a589e8SKaiChieh Chuang I_ADDA_UL_CH2, 1, 0), 101*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3, 102*42a589e8SKaiChieh Chuang I_ADDA_UL_CH1, 1, 0), 103*42a589e8SKaiChieh Chuang }; 104*42a589e8SKaiChieh Chuang 105*42a589e8SKaiChieh Chuang static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { 106*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0), 107*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0), 108*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0), 109*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0), 110*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0), 111*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0), 112*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4, 113*42a589e8SKaiChieh Chuang I_ADDA_UL_CH2, 1, 0), 114*42a589e8SKaiChieh Chuang SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4, 115*42a589e8SKaiChieh Chuang I_ADDA_UL_CH1, 1, 0), 116*42a589e8SKaiChieh Chuang }; 117*42a589e8SKaiChieh Chuang 118*42a589e8SKaiChieh Chuang static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, 119*42a589e8SKaiChieh Chuang struct snd_kcontrol *kcontrol, 120*42a589e8SKaiChieh Chuang int event) 121*42a589e8SKaiChieh Chuang { 122*42a589e8SKaiChieh Chuang struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 123*42a589e8SKaiChieh Chuang struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 124*42a589e8SKaiChieh Chuang 125*42a589e8SKaiChieh Chuang dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", 126*42a589e8SKaiChieh Chuang __func__, w->name, event); 127*42a589e8SKaiChieh Chuang 128*42a589e8SKaiChieh Chuang switch (event) { 129*42a589e8SKaiChieh Chuang case SND_SOC_DAPM_POST_PMD: 130*42a589e8SKaiChieh Chuang /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ 131*42a589e8SKaiChieh Chuang usleep_range(125, 135); 132*42a589e8SKaiChieh Chuang break; 133*42a589e8SKaiChieh Chuang default: 134*42a589e8SKaiChieh Chuang break; 135*42a589e8SKaiChieh Chuang } 136*42a589e8SKaiChieh Chuang 137*42a589e8SKaiChieh Chuang return 0; 138*42a589e8SKaiChieh Chuang } 139*42a589e8SKaiChieh Chuang 140*42a589e8SKaiChieh Chuang enum { 141*42a589e8SKaiChieh Chuang SUPPLY_SEQ_AUD_TOP_PDN, 142*42a589e8SKaiChieh Chuang SUPPLY_SEQ_ADDA_AFE_ON, 143*42a589e8SKaiChieh Chuang SUPPLY_SEQ_ADDA_DL_ON, 144*42a589e8SKaiChieh Chuang SUPPLY_SEQ_ADDA_UL_ON, 145*42a589e8SKaiChieh Chuang }; 146*42a589e8SKaiChieh Chuang 147*42a589e8SKaiChieh Chuang static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { 148*42a589e8SKaiChieh Chuang /* adda */ 149*42a589e8SKaiChieh Chuang SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, 150*42a589e8SKaiChieh Chuang mtk_adda_dl_ch1_mix, 151*42a589e8SKaiChieh Chuang ARRAY_SIZE(mtk_adda_dl_ch1_mix)), 152*42a589e8SKaiChieh Chuang SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, 153*42a589e8SKaiChieh Chuang mtk_adda_dl_ch2_mix, 154*42a589e8SKaiChieh Chuang ARRAY_SIZE(mtk_adda_dl_ch2_mix)), 155*42a589e8SKaiChieh Chuang 156*42a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON, 157*42a589e8SKaiChieh Chuang AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0, 158*42a589e8SKaiChieh Chuang NULL, 0), 159*42a589e8SKaiChieh Chuang 160*42a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON, 161*42a589e8SKaiChieh Chuang AFE_ADDA_DL_SRC2_CON0, 162*42a589e8SKaiChieh Chuang DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, 163*42a589e8SKaiChieh Chuang NULL, 0), 164*42a589e8SKaiChieh Chuang 165*42a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, 166*42a589e8SKaiChieh Chuang AFE_ADDA_UL_SRC_CON0, 167*42a589e8SKaiChieh Chuang UL_SRC_ON_TMP_CTL_SFT, 0, 168*42a589e8SKaiChieh Chuang mtk_adda_ul_event, 169*42a589e8SKaiChieh Chuang SND_SOC_DAPM_POST_PMD), 170*42a589e8SKaiChieh Chuang 171*42a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("aud_dac_clk", SUPPLY_SEQ_AUD_TOP_PDN, 172*42a589e8SKaiChieh Chuang AUDIO_TOP_CON0, PDN_DAC_SFT, 1, 173*42a589e8SKaiChieh Chuang NULL, 0), 174*42a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("aud_dac_predis_clk", SUPPLY_SEQ_AUD_TOP_PDN, 175*42a589e8SKaiChieh Chuang AUDIO_TOP_CON0, PDN_DAC_PREDIS_SFT, 1, 176*42a589e8SKaiChieh Chuang NULL, 0), 177*42a589e8SKaiChieh Chuang 178*42a589e8SKaiChieh Chuang SND_SOC_DAPM_SUPPLY_S("aud_adc_clk", SUPPLY_SEQ_AUD_TOP_PDN, 179*42a589e8SKaiChieh Chuang AUDIO_TOP_CON0, PDN_ADC_SFT, 1, 180*42a589e8SKaiChieh Chuang NULL, 0), 181*42a589e8SKaiChieh Chuang 182*42a589e8SKaiChieh Chuang SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"), 183*42a589e8SKaiChieh Chuang }; 184*42a589e8SKaiChieh Chuang 185*42a589e8SKaiChieh Chuang static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { 186*42a589e8SKaiChieh Chuang /* playback */ 187*42a589e8SKaiChieh Chuang {"ADDA_DL_CH1", "DL1_CH1", "DL1"}, 188*42a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL1_CH1", "DL1"}, 189*42a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL1_CH2", "DL1"}, 190*42a589e8SKaiChieh Chuang 191*42a589e8SKaiChieh Chuang {"ADDA_DL_CH1", "DL2_CH1", "DL2"}, 192*42a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL2_CH1", "DL2"}, 193*42a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL2_CH2", "DL2"}, 194*42a589e8SKaiChieh Chuang 195*42a589e8SKaiChieh Chuang {"ADDA_DL_CH1", "DL3_CH1", "DL3"}, 196*42a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL3_CH1", "DL3"}, 197*42a589e8SKaiChieh Chuang {"ADDA_DL_CH2", "DL3_CH2", "DL3"}, 198*42a589e8SKaiChieh Chuang 199*42a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "ADDA_DL_CH1"}, 200*42a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "ADDA_DL_CH2"}, 201*42a589e8SKaiChieh Chuang 202*42a589e8SKaiChieh Chuang /* adda enable */ 203*42a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "ADDA Enable"}, 204*42a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "ADDA Playback Enable"}, 205*42a589e8SKaiChieh Chuang {"ADDA Capture", NULL, "ADDA Enable"}, 206*42a589e8SKaiChieh Chuang {"ADDA Capture", NULL, "ADDA Capture Enable"}, 207*42a589e8SKaiChieh Chuang 208*42a589e8SKaiChieh Chuang /* clk */ 209*42a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "mtkaif_26m_clk"}, 210*42a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "aud_dac_clk"}, 211*42a589e8SKaiChieh Chuang {"ADDA Playback", NULL, "aud_dac_predis_clk"}, 212*42a589e8SKaiChieh Chuang 213*42a589e8SKaiChieh Chuang {"ADDA Capture", NULL, "mtkaif_26m_clk"}, 214*42a589e8SKaiChieh Chuang {"ADDA Capture", NULL, "aud_adc_clk"}, 215*42a589e8SKaiChieh Chuang }; 216*42a589e8SKaiChieh Chuang 217*42a589e8SKaiChieh Chuang /* dai ops */ 218*42a589e8SKaiChieh Chuang static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, 219*42a589e8SKaiChieh Chuang struct snd_pcm_hw_params *params, 220*42a589e8SKaiChieh Chuang struct snd_soc_dai *dai) 221*42a589e8SKaiChieh Chuang { 222*42a589e8SKaiChieh Chuang struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 223*42a589e8SKaiChieh Chuang unsigned int rate = params_rate(params); 224*42a589e8SKaiChieh Chuang 225*42a589e8SKaiChieh Chuang dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", 226*42a589e8SKaiChieh Chuang __func__, dai->id, substream->stream, rate); 227*42a589e8SKaiChieh Chuang 228*42a589e8SKaiChieh Chuang if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 229*42a589e8SKaiChieh Chuang unsigned int dl_src2_con0 = 0; 230*42a589e8SKaiChieh Chuang unsigned int dl_src2_con1 = 0; 231*42a589e8SKaiChieh Chuang 232*42a589e8SKaiChieh Chuang /* clean predistortion */ 233*42a589e8SKaiChieh Chuang regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0); 234*42a589e8SKaiChieh Chuang regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0); 235*42a589e8SKaiChieh Chuang 236*42a589e8SKaiChieh Chuang /* set input sampling rate */ 237*42a589e8SKaiChieh Chuang dl_src2_con0 = adda_dl_rate_transform(afe, rate) << 28; 238*42a589e8SKaiChieh Chuang 239*42a589e8SKaiChieh Chuang /* set output mode */ 240*42a589e8SKaiChieh Chuang switch (rate) { 241*42a589e8SKaiChieh Chuang case 192000: 242*42a589e8SKaiChieh Chuang dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */ 243*42a589e8SKaiChieh Chuang dl_src2_con0 |= 1 << 14; 244*42a589e8SKaiChieh Chuang break; 245*42a589e8SKaiChieh Chuang case 96000: 246*42a589e8SKaiChieh Chuang dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */ 247*42a589e8SKaiChieh Chuang dl_src2_con0 |= 1 << 14; 248*42a589e8SKaiChieh Chuang break; 249*42a589e8SKaiChieh Chuang default: 250*42a589e8SKaiChieh Chuang dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */ 251*42a589e8SKaiChieh Chuang break; 252*42a589e8SKaiChieh Chuang } 253*42a589e8SKaiChieh Chuang 254*42a589e8SKaiChieh Chuang /* turn off mute function */ 255*42a589e8SKaiChieh Chuang dl_src2_con0 |= (0x03 << 11); 256*42a589e8SKaiChieh Chuang 257*42a589e8SKaiChieh Chuang /* set voice input data if input sample rate is 8k or 16k */ 258*42a589e8SKaiChieh Chuang if (rate == 8000 || rate == 16000) 259*42a589e8SKaiChieh Chuang dl_src2_con0 |= 0x01 << 5; 260*42a589e8SKaiChieh Chuang 261*42a589e8SKaiChieh Chuang if (rate < 96000) { 262*42a589e8SKaiChieh Chuang /* SA suggest apply -0.3db to audio/speech path */ 263*42a589e8SKaiChieh Chuang dl_src2_con1 = 0xf74f0000; 264*42a589e8SKaiChieh Chuang } else { 265*42a589e8SKaiChieh Chuang /* SA suggest apply -0.3db to audio/speech path 266*42a589e8SKaiChieh Chuang * with DL gain set to half, 267*42a589e8SKaiChieh Chuang * 0xFFFF = 0dB -> 0x8000 = 0dB when 96k, 192k 268*42a589e8SKaiChieh Chuang */ 269*42a589e8SKaiChieh Chuang dl_src2_con1 = 0x7ba70000; 270*42a589e8SKaiChieh Chuang } 271*42a589e8SKaiChieh Chuang 272*42a589e8SKaiChieh Chuang /* turn on down-link gain */ 273*42a589e8SKaiChieh Chuang dl_src2_con0 = dl_src2_con0 | (0x01 << 1); 274*42a589e8SKaiChieh Chuang 275*42a589e8SKaiChieh Chuang regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0); 276*42a589e8SKaiChieh Chuang regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1); 277*42a589e8SKaiChieh Chuang } else { 278*42a589e8SKaiChieh Chuang unsigned int voice_mode = 0; 279*42a589e8SKaiChieh Chuang unsigned int ul_src_con0 = 0; /* default value */ 280*42a589e8SKaiChieh Chuang 281*42a589e8SKaiChieh Chuang /* Using Internal ADC */ 282*42a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap, 283*42a589e8SKaiChieh Chuang AFE_ADDA_TOP_CON0, 284*42a589e8SKaiChieh Chuang 0x1 << 0, 285*42a589e8SKaiChieh Chuang 0x0 << 0); 286*42a589e8SKaiChieh Chuang 287*42a589e8SKaiChieh Chuang voice_mode = adda_ul_rate_transform(afe, rate); 288*42a589e8SKaiChieh Chuang 289*42a589e8SKaiChieh Chuang ul_src_con0 |= (voice_mode << 17) & (0x7 << 17); 290*42a589e8SKaiChieh Chuang 291*42a589e8SKaiChieh Chuang /* up8x txif sat on */ 292*42a589e8SKaiChieh Chuang regmap_write(afe->regmap, AFE_ADDA_NEWIF_CFG0, 0x03F87201); 293*42a589e8SKaiChieh Chuang 294*42a589e8SKaiChieh Chuang if (rate >= 96000) { /* hires */ 295*42a589e8SKaiChieh Chuang /* use hires format [1 0 23] */ 296*42a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap, 297*42a589e8SKaiChieh Chuang AFE_ADDA_NEWIF_CFG0, 298*42a589e8SKaiChieh Chuang 0x1 << 5, 299*42a589e8SKaiChieh Chuang 0x1 << 5); 300*42a589e8SKaiChieh Chuang 301*42a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap, 302*42a589e8SKaiChieh Chuang AFE_ADDA_NEWIF_CFG2, 303*42a589e8SKaiChieh Chuang 0xf << 28, 304*42a589e8SKaiChieh Chuang voice_mode << 28); 305*42a589e8SKaiChieh Chuang } else { /* normal 8~48k */ 306*42a589e8SKaiChieh Chuang /* use fixed 260k anc path */ 307*42a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap, 308*42a589e8SKaiChieh Chuang AFE_ADDA_NEWIF_CFG2, 309*42a589e8SKaiChieh Chuang 0xf << 28, 310*42a589e8SKaiChieh Chuang 8 << 28); 311*42a589e8SKaiChieh Chuang 312*42a589e8SKaiChieh Chuang /* ul_use_cic_out */ 313*42a589e8SKaiChieh Chuang ul_src_con0 |= 0x1 << 20; 314*42a589e8SKaiChieh Chuang } 315*42a589e8SKaiChieh Chuang 316*42a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap, 317*42a589e8SKaiChieh Chuang AFE_ADDA_NEWIF_CFG2, 318*42a589e8SKaiChieh Chuang 0xf << 28, 319*42a589e8SKaiChieh Chuang 8 << 28); 320*42a589e8SKaiChieh Chuang 321*42a589e8SKaiChieh Chuang regmap_update_bits(afe->regmap, 322*42a589e8SKaiChieh Chuang AFE_ADDA_UL_SRC_CON0, 323*42a589e8SKaiChieh Chuang 0xfffffffe, 324*42a589e8SKaiChieh Chuang ul_src_con0); 325*42a589e8SKaiChieh Chuang } 326*42a589e8SKaiChieh Chuang 327*42a589e8SKaiChieh Chuang return 0; 328*42a589e8SKaiChieh Chuang } 329*42a589e8SKaiChieh Chuang 330*42a589e8SKaiChieh Chuang static const struct snd_soc_dai_ops mtk_dai_adda_ops = { 331*42a589e8SKaiChieh Chuang .hw_params = mtk_dai_adda_hw_params, 332*42a589e8SKaiChieh Chuang }; 333*42a589e8SKaiChieh Chuang 334*42a589e8SKaiChieh Chuang /* dai driver */ 335*42a589e8SKaiChieh Chuang #define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\ 336*42a589e8SKaiChieh Chuang SNDRV_PCM_RATE_96000 |\ 337*42a589e8SKaiChieh Chuang SNDRV_PCM_RATE_192000) 338*42a589e8SKaiChieh Chuang 339*42a589e8SKaiChieh Chuang #define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ 340*42a589e8SKaiChieh Chuang SNDRV_PCM_RATE_16000 |\ 341*42a589e8SKaiChieh Chuang SNDRV_PCM_RATE_32000 |\ 342*42a589e8SKaiChieh Chuang SNDRV_PCM_RATE_48000 |\ 343*42a589e8SKaiChieh Chuang SNDRV_PCM_RATE_96000 |\ 344*42a589e8SKaiChieh Chuang SNDRV_PCM_RATE_192000) 345*42a589e8SKaiChieh Chuang 346*42a589e8SKaiChieh Chuang #define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 347*42a589e8SKaiChieh Chuang SNDRV_PCM_FMTBIT_S24_LE |\ 348*42a589e8SKaiChieh Chuang SNDRV_PCM_FMTBIT_S32_LE) 349*42a589e8SKaiChieh Chuang 350*42a589e8SKaiChieh Chuang static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { 351*42a589e8SKaiChieh Chuang { 352*42a589e8SKaiChieh Chuang .name = "ADDA", 353*42a589e8SKaiChieh Chuang .id = MT6797_DAI_ADDA, 354*42a589e8SKaiChieh Chuang .playback = { 355*42a589e8SKaiChieh Chuang .stream_name = "ADDA Playback", 356*42a589e8SKaiChieh Chuang .channels_min = 1, 357*42a589e8SKaiChieh Chuang .channels_max = 2, 358*42a589e8SKaiChieh Chuang .rates = MTK_ADDA_PLAYBACK_RATES, 359*42a589e8SKaiChieh Chuang .formats = MTK_ADDA_FORMATS, 360*42a589e8SKaiChieh Chuang }, 361*42a589e8SKaiChieh Chuang .capture = { 362*42a589e8SKaiChieh Chuang .stream_name = "ADDA Capture", 363*42a589e8SKaiChieh Chuang .channels_min = 1, 364*42a589e8SKaiChieh Chuang .channels_max = 2, 365*42a589e8SKaiChieh Chuang .rates = MTK_ADDA_CAPTURE_RATES, 366*42a589e8SKaiChieh Chuang .formats = MTK_ADDA_FORMATS, 367*42a589e8SKaiChieh Chuang }, 368*42a589e8SKaiChieh Chuang .ops = &mtk_dai_adda_ops, 369*42a589e8SKaiChieh Chuang }, 370*42a589e8SKaiChieh Chuang }; 371*42a589e8SKaiChieh Chuang 372*42a589e8SKaiChieh Chuang int mt6797_dai_adda_register(struct mtk_base_afe *afe) 373*42a589e8SKaiChieh Chuang { 374*42a589e8SKaiChieh Chuang int id = MT6797_DAI_ADDA; 375*42a589e8SKaiChieh Chuang 376*42a589e8SKaiChieh Chuang afe->sub_dais[id].dai_drivers = mtk_dai_adda_driver; 377*42a589e8SKaiChieh Chuang afe->sub_dais[id].num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); 378*42a589e8SKaiChieh Chuang 379*42a589e8SKaiChieh Chuang afe->sub_dais[id].dapm_widgets = mtk_dai_adda_widgets; 380*42a589e8SKaiChieh Chuang afe->sub_dais[id].num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); 381*42a589e8SKaiChieh Chuang afe->sub_dais[id].dapm_routes = mtk_dai_adda_routes; 382*42a589e8SKaiChieh Chuang afe->sub_dais[id].num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); 383*42a589e8SKaiChieh Chuang return 0; 384*42a589e8SKaiChieh Chuang } 385