1*1c50ec75SAlexandre Mergnat // SPDX-License-Identifier: GPL-2.0 2*1c50ec75SAlexandre Mergnat /* 3*1c50ec75SAlexandre Mergnat * MediaTek 8365 ALSA SoC Audio DAI DMIC Control 4*1c50ec75SAlexandre Mergnat * 5*1c50ec75SAlexandre Mergnat * Copyright (c) 2024 MediaTek Inc. 6*1c50ec75SAlexandre Mergnat * Authors: Jia Zeng <jia.zeng@mediatek.com> 7*1c50ec75SAlexandre Mergnat * Alexandre Mergnat <amergnat@baylibre.com> 8*1c50ec75SAlexandre Mergnat */ 9*1c50ec75SAlexandre Mergnat 10*1c50ec75SAlexandre Mergnat #include <linux/bitops.h> 11*1c50ec75SAlexandre Mergnat #include <linux/regmap.h> 12*1c50ec75SAlexandre Mergnat #include <sound/pcm_params.h> 13*1c50ec75SAlexandre Mergnat #include "mt8365-afe-clk.h" 14*1c50ec75SAlexandre Mergnat #include "mt8365-afe-common.h" 15*1c50ec75SAlexandre Mergnat 16*1c50ec75SAlexandre Mergnat struct mt8365_dmic_data { 17*1c50ec75SAlexandre Mergnat bool two_wire_mode; 18*1c50ec75SAlexandre Mergnat unsigned int clk_phase_sel_ch1; 19*1c50ec75SAlexandre Mergnat unsigned int clk_phase_sel_ch2; 20*1c50ec75SAlexandre Mergnat bool iir_on; 21*1c50ec75SAlexandre Mergnat unsigned int irr_mode; 22*1c50ec75SAlexandre Mergnat unsigned int dmic_mode; 23*1c50ec75SAlexandre Mergnat unsigned int dmic_channel; 24*1c50ec75SAlexandre Mergnat }; 25*1c50ec75SAlexandre Mergnat 26*1c50ec75SAlexandre Mergnat static int get_chan_reg(unsigned int channel) 27*1c50ec75SAlexandre Mergnat { 28*1c50ec75SAlexandre Mergnat switch (channel) { 29*1c50ec75SAlexandre Mergnat case 8: 30*1c50ec75SAlexandre Mergnat fallthrough; 31*1c50ec75SAlexandre Mergnat case 7: 32*1c50ec75SAlexandre Mergnat return AFE_DMIC3_UL_SRC_CON0; 33*1c50ec75SAlexandre Mergnat case 6: 34*1c50ec75SAlexandre Mergnat fallthrough; 35*1c50ec75SAlexandre Mergnat case 5: 36*1c50ec75SAlexandre Mergnat return AFE_DMIC2_UL_SRC_CON0; 37*1c50ec75SAlexandre Mergnat case 4: 38*1c50ec75SAlexandre Mergnat fallthrough; 39*1c50ec75SAlexandre Mergnat case 3: 40*1c50ec75SAlexandre Mergnat return AFE_DMIC1_UL_SRC_CON0; 41*1c50ec75SAlexandre Mergnat case 2: 42*1c50ec75SAlexandre Mergnat fallthrough; 43*1c50ec75SAlexandre Mergnat case 1: 44*1c50ec75SAlexandre Mergnat return AFE_DMIC0_UL_SRC_CON0; 45*1c50ec75SAlexandre Mergnat default: 46*1c50ec75SAlexandre Mergnat return -EINVAL; 47*1c50ec75SAlexandre Mergnat } 48*1c50ec75SAlexandre Mergnat } 49*1c50ec75SAlexandre Mergnat 50*1c50ec75SAlexandre Mergnat /* DAI Drivers */ 51*1c50ec75SAlexandre Mergnat 52*1c50ec75SAlexandre Mergnat static void audio_dmic_adda_enable(struct mtk_base_afe *afe) 53*1c50ec75SAlexandre Mergnat { 54*1c50ec75SAlexandre Mergnat mt8365_dai_enable_adda_on(afe); 55*1c50ec75SAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0, 56*1c50ec75SAlexandre Mergnat AFE_ADDA_UL_DL_DMIC_CLKDIV_ON, 57*1c50ec75SAlexandre Mergnat AFE_ADDA_UL_DL_DMIC_CLKDIV_ON); 58*1c50ec75SAlexandre Mergnat } 59*1c50ec75SAlexandre Mergnat 60*1c50ec75SAlexandre Mergnat static void audio_dmic_adda_disable(struct mtk_base_afe *afe) 61*1c50ec75SAlexandre Mergnat { 62*1c50ec75SAlexandre Mergnat regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0, 63*1c50ec75SAlexandre Mergnat AFE_ADDA_UL_DL_DMIC_CLKDIV_ON, 64*1c50ec75SAlexandre Mergnat ~AFE_ADDA_UL_DL_DMIC_CLKDIV_ON); 65*1c50ec75SAlexandre Mergnat mt8365_dai_disable_adda_on(afe); 66*1c50ec75SAlexandre Mergnat } 67*1c50ec75SAlexandre Mergnat 68*1c50ec75SAlexandre Mergnat static void mt8365_dai_enable_dmic(struct mtk_base_afe *afe, 69*1c50ec75SAlexandre Mergnat struct snd_pcm_substream *substream, 70*1c50ec75SAlexandre Mergnat struct snd_soc_dai *dai) 71*1c50ec75SAlexandre Mergnat { 72*1c50ec75SAlexandre Mergnat struct mt8365_afe_private *afe_priv = afe->platform_priv; 73*1c50ec75SAlexandre Mergnat struct mt8365_dmic_data *dmic_data = afe_priv->dai_priv[MT8365_AFE_IO_DMIC]; 74*1c50ec75SAlexandre Mergnat unsigned int val_mask; 75*1c50ec75SAlexandre Mergnat int reg = get_chan_reg(dmic_data->dmic_channel); 76*1c50ec75SAlexandre Mergnat 77*1c50ec75SAlexandre Mergnat if (reg < 0) 78*1c50ec75SAlexandre Mergnat return; 79*1c50ec75SAlexandre Mergnat 80*1c50ec75SAlexandre Mergnat /* val and mask will be always same to enable */ 81*1c50ec75SAlexandre Mergnat val_mask = DMIC_TOP_CON_CH1_ON | 82*1c50ec75SAlexandre Mergnat DMIC_TOP_CON_CH2_ON | 83*1c50ec75SAlexandre Mergnat DMIC_TOP_CON_SRC_ON; 84*1c50ec75SAlexandre Mergnat 85*1c50ec75SAlexandre Mergnat regmap_update_bits(afe->regmap, reg, val_mask, val_mask); 86*1c50ec75SAlexandre Mergnat } 87*1c50ec75SAlexandre Mergnat 88*1c50ec75SAlexandre Mergnat static void mt8365_dai_disable_dmic(struct mtk_base_afe *afe, 89*1c50ec75SAlexandre Mergnat struct snd_pcm_substream *substream, 90*1c50ec75SAlexandre Mergnat struct snd_soc_dai *dai) 91*1c50ec75SAlexandre Mergnat { 92*1c50ec75SAlexandre Mergnat struct mt8365_afe_private *afe_priv = afe->platform_priv; 93*1c50ec75SAlexandre Mergnat struct mt8365_dmic_data *dmic_data = afe_priv->dai_priv[MT8365_AFE_IO_DMIC]; 94*1c50ec75SAlexandre Mergnat unsigned int mask; 95*1c50ec75SAlexandre Mergnat int reg = get_chan_reg(dmic_data->dmic_channel); 96*1c50ec75SAlexandre Mergnat 97*1c50ec75SAlexandre Mergnat if (reg < 0) 98*1c50ec75SAlexandre Mergnat return; 99*1c50ec75SAlexandre Mergnat 100*1c50ec75SAlexandre Mergnat dev_dbg(afe->dev, "%s dmic_channel %d\n", __func__, dmic_data->dmic_channel); 101*1c50ec75SAlexandre Mergnat 102*1c50ec75SAlexandre Mergnat mask = DMIC_TOP_CON_CH1_ON | 103*1c50ec75SAlexandre Mergnat DMIC_TOP_CON_CH2_ON | 104*1c50ec75SAlexandre Mergnat DMIC_TOP_CON_SRC_ON | 105*1c50ec75SAlexandre Mergnat DMIC_TOP_CON_SDM3_LEVEL_MODE; 106*1c50ec75SAlexandre Mergnat 107*1c50ec75SAlexandre Mergnat /* Set all masked values to 0 */ 108*1c50ec75SAlexandre Mergnat regmap_update_bits(afe->regmap, reg, mask, 0); 109*1c50ec75SAlexandre Mergnat } 110*1c50ec75SAlexandre Mergnat 111*1c50ec75SAlexandre Mergnat static const struct reg_sequence mt8365_dmic_iir_coeff[] = { 112*1c50ec75SAlexandre Mergnat { AFE_DMIC0_IIR_COEF_02_01, 0x00000000 }, 113*1c50ec75SAlexandre Mergnat { AFE_DMIC0_IIR_COEF_04_03, 0x00003FB8 }, 114*1c50ec75SAlexandre Mergnat { AFE_DMIC0_IIR_COEF_06_05, 0x3FB80000 }, 115*1c50ec75SAlexandre Mergnat { AFE_DMIC0_IIR_COEF_08_07, 0x3FB80000 }, 116*1c50ec75SAlexandre Mergnat { AFE_DMIC0_IIR_COEF_10_09, 0x0000C048 }, 117*1c50ec75SAlexandre Mergnat { AFE_DMIC1_IIR_COEF_02_01, 0x00000000 }, 118*1c50ec75SAlexandre Mergnat { AFE_DMIC1_IIR_COEF_04_03, 0x00003FB8 }, 119*1c50ec75SAlexandre Mergnat { AFE_DMIC1_IIR_COEF_06_05, 0x3FB80000 }, 120*1c50ec75SAlexandre Mergnat { AFE_DMIC1_IIR_COEF_08_07, 0x3FB80000 }, 121*1c50ec75SAlexandre Mergnat { AFE_DMIC1_IIR_COEF_10_09, 0x0000C048 }, 122*1c50ec75SAlexandre Mergnat { AFE_DMIC2_IIR_COEF_02_01, 0x00000000 }, 123*1c50ec75SAlexandre Mergnat { AFE_DMIC2_IIR_COEF_04_03, 0x00003FB8 }, 124*1c50ec75SAlexandre Mergnat { AFE_DMIC2_IIR_COEF_06_05, 0x3FB80000 }, 125*1c50ec75SAlexandre Mergnat { AFE_DMIC2_IIR_COEF_08_07, 0x3FB80000 }, 126*1c50ec75SAlexandre Mergnat { AFE_DMIC2_IIR_COEF_10_09, 0x0000C048 }, 127*1c50ec75SAlexandre Mergnat { AFE_DMIC3_IIR_COEF_02_01, 0x00000000 }, 128*1c50ec75SAlexandre Mergnat { AFE_DMIC3_IIR_COEF_04_03, 0x00003FB8 }, 129*1c50ec75SAlexandre Mergnat { AFE_DMIC3_IIR_COEF_06_05, 0x3FB80000 }, 130*1c50ec75SAlexandre Mergnat { AFE_DMIC3_IIR_COEF_08_07, 0x3FB80000 }, 131*1c50ec75SAlexandre Mergnat { AFE_DMIC3_IIR_COEF_10_09, 0x0000C048 }, 132*1c50ec75SAlexandre Mergnat }; 133*1c50ec75SAlexandre Mergnat 134*1c50ec75SAlexandre Mergnat static int mt8365_dai_load_dmic_iir_coeff_table(struct mtk_base_afe *afe) 135*1c50ec75SAlexandre Mergnat { 136*1c50ec75SAlexandre Mergnat return regmap_multi_reg_write(afe->regmap, 137*1c50ec75SAlexandre Mergnat mt8365_dmic_iir_coeff, 138*1c50ec75SAlexandre Mergnat ARRAY_SIZE(mt8365_dmic_iir_coeff)); 139*1c50ec75SAlexandre Mergnat } 140*1c50ec75SAlexandre Mergnat 141*1c50ec75SAlexandre Mergnat static int mt8365_dai_configure_dmic(struct mtk_base_afe *afe, 142*1c50ec75SAlexandre Mergnat struct snd_pcm_substream *substream, 143*1c50ec75SAlexandre Mergnat struct snd_soc_dai *dai) 144*1c50ec75SAlexandre Mergnat { 145*1c50ec75SAlexandre Mergnat struct mt8365_afe_private *afe_priv = afe->platform_priv; 146*1c50ec75SAlexandre Mergnat struct mt8365_dmic_data *dmic_data = afe_priv->dai_priv[MT8365_AFE_IO_DMIC]; 147*1c50ec75SAlexandre Mergnat bool two_wire_mode = dmic_data->two_wire_mode; 148*1c50ec75SAlexandre Mergnat unsigned int clk_phase_sel_ch1 = dmic_data->clk_phase_sel_ch1; 149*1c50ec75SAlexandre Mergnat unsigned int clk_phase_sel_ch2 = dmic_data->clk_phase_sel_ch2; 150*1c50ec75SAlexandre Mergnat unsigned int val = 0; 151*1c50ec75SAlexandre Mergnat unsigned int rate = dai->rate; 152*1c50ec75SAlexandre Mergnat int reg = get_chan_reg(dai->channels); 153*1c50ec75SAlexandre Mergnat 154*1c50ec75SAlexandre Mergnat if (reg < 0) 155*1c50ec75SAlexandre Mergnat return -EINVAL; 156*1c50ec75SAlexandre Mergnat 157*1c50ec75SAlexandre Mergnat dmic_data->dmic_channel = dai->channels; 158*1c50ec75SAlexandre Mergnat 159*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_SDM3_LEVEL_MODE; 160*1c50ec75SAlexandre Mergnat 161*1c50ec75SAlexandre Mergnat if (two_wire_mode) { 162*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_TWO_WIRE_MODE; 163*1c50ec75SAlexandre Mergnat } else { 164*1c50ec75SAlexandre Mergnat val |= FIELD_PREP(DMIC_TOP_CON_CK_PHASE_SEL_CH1, 165*1c50ec75SAlexandre Mergnat clk_phase_sel_ch1); 166*1c50ec75SAlexandre Mergnat val |= FIELD_PREP(DMIC_TOP_CON_CK_PHASE_SEL_CH2, 167*1c50ec75SAlexandre Mergnat clk_phase_sel_ch2); 168*1c50ec75SAlexandre Mergnat } 169*1c50ec75SAlexandre Mergnat 170*1c50ec75SAlexandre Mergnat switch (rate) { 171*1c50ec75SAlexandre Mergnat case 48000: 172*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_VOICE_MODE_48K; 173*1c50ec75SAlexandre Mergnat break; 174*1c50ec75SAlexandre Mergnat case 32000: 175*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_VOICE_MODE_32K; 176*1c50ec75SAlexandre Mergnat break; 177*1c50ec75SAlexandre Mergnat case 16000: 178*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_VOICE_MODE_16K; 179*1c50ec75SAlexandre Mergnat break; 180*1c50ec75SAlexandre Mergnat case 8000: 181*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_VOICE_MODE_8K; 182*1c50ec75SAlexandre Mergnat break; 183*1c50ec75SAlexandre Mergnat default: 184*1c50ec75SAlexandre Mergnat return -EINVAL; 185*1c50ec75SAlexandre Mergnat } 186*1c50ec75SAlexandre Mergnat 187*1c50ec75SAlexandre Mergnat regmap_update_bits(afe->regmap, reg, DMIC_TOP_CON_CONFIG_MASK, val); 188*1c50ec75SAlexandre Mergnat 189*1c50ec75SAlexandre Mergnat return 0; 190*1c50ec75SAlexandre Mergnat } 191*1c50ec75SAlexandre Mergnat 192*1c50ec75SAlexandre Mergnat static int mt8365_dai_dmic_startup(struct snd_pcm_substream *substream, 193*1c50ec75SAlexandre Mergnat struct snd_soc_dai *dai) 194*1c50ec75SAlexandre Mergnat { 195*1c50ec75SAlexandre Mergnat struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 196*1c50ec75SAlexandre Mergnat 197*1c50ec75SAlexandre Mergnat mt8365_afe_enable_main_clk(afe); 198*1c50ec75SAlexandre Mergnat 199*1c50ec75SAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC0_ADC); 200*1c50ec75SAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC1_ADC); 201*1c50ec75SAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC2_ADC); 202*1c50ec75SAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC3_ADC); 203*1c50ec75SAlexandre Mergnat 204*1c50ec75SAlexandre Mergnat audio_dmic_adda_enable(afe); 205*1c50ec75SAlexandre Mergnat 206*1c50ec75SAlexandre Mergnat return 0; 207*1c50ec75SAlexandre Mergnat } 208*1c50ec75SAlexandre Mergnat 209*1c50ec75SAlexandre Mergnat static void mt8365_dai_dmic_shutdown(struct snd_pcm_substream *substream, 210*1c50ec75SAlexandre Mergnat struct snd_soc_dai *dai) 211*1c50ec75SAlexandre Mergnat { 212*1c50ec75SAlexandre Mergnat struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 213*1c50ec75SAlexandre Mergnat 214*1c50ec75SAlexandre Mergnat mt8365_dai_disable_dmic(afe, substream, dai); 215*1c50ec75SAlexandre Mergnat audio_dmic_adda_disable(afe); 216*1c50ec75SAlexandre Mergnat /* HW Request delay 125us before CG off */ 217*1c50ec75SAlexandre Mergnat usleep_range(125, 300); 218*1c50ec75SAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC3_ADC); 219*1c50ec75SAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC2_ADC); 220*1c50ec75SAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC1_ADC); 221*1c50ec75SAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC0_ADC); 222*1c50ec75SAlexandre Mergnat 223*1c50ec75SAlexandre Mergnat mt8365_afe_disable_main_clk(afe); 224*1c50ec75SAlexandre Mergnat } 225*1c50ec75SAlexandre Mergnat 226*1c50ec75SAlexandre Mergnat static int mt8365_dai_dmic_prepare(struct snd_pcm_substream *substream, 227*1c50ec75SAlexandre Mergnat struct snd_soc_dai *dai) 228*1c50ec75SAlexandre Mergnat { 229*1c50ec75SAlexandre Mergnat struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 230*1c50ec75SAlexandre Mergnat 231*1c50ec75SAlexandre Mergnat mt8365_dai_configure_dmic(afe, substream, dai); 232*1c50ec75SAlexandre Mergnat mt8365_dai_enable_dmic(afe, substream, dai); 233*1c50ec75SAlexandre Mergnat 234*1c50ec75SAlexandre Mergnat return 0; 235*1c50ec75SAlexandre Mergnat } 236*1c50ec75SAlexandre Mergnat 237*1c50ec75SAlexandre Mergnat static const struct snd_soc_dai_ops mt8365_afe_dmic_ops = { 238*1c50ec75SAlexandre Mergnat .startup = mt8365_dai_dmic_startup, 239*1c50ec75SAlexandre Mergnat .shutdown = mt8365_dai_dmic_shutdown, 240*1c50ec75SAlexandre Mergnat .prepare = mt8365_dai_dmic_prepare, 241*1c50ec75SAlexandre Mergnat }; 242*1c50ec75SAlexandre Mergnat 243*1c50ec75SAlexandre Mergnat static struct snd_soc_dai_driver mtk_dai_dmic_driver[] = { 244*1c50ec75SAlexandre Mergnat { 245*1c50ec75SAlexandre Mergnat .name = "DMIC", 246*1c50ec75SAlexandre Mergnat .id = MT8365_AFE_IO_DMIC, 247*1c50ec75SAlexandre Mergnat .capture = { 248*1c50ec75SAlexandre Mergnat .stream_name = "DMIC Capture", 249*1c50ec75SAlexandre Mergnat .channels_min = 1, 250*1c50ec75SAlexandre Mergnat .channels_max = 8, 251*1c50ec75SAlexandre Mergnat .rates = SNDRV_PCM_RATE_16000 | 252*1c50ec75SAlexandre Mergnat SNDRV_PCM_RATE_32000 | 253*1c50ec75SAlexandre Mergnat SNDRV_PCM_RATE_48000, 254*1c50ec75SAlexandre Mergnat .formats = SNDRV_PCM_FMTBIT_S16_LE | 255*1c50ec75SAlexandre Mergnat SNDRV_PCM_FMTBIT_S32_LE, 256*1c50ec75SAlexandre Mergnat }, 257*1c50ec75SAlexandre Mergnat .ops = &mt8365_afe_dmic_ops, 258*1c50ec75SAlexandre Mergnat } 259*1c50ec75SAlexandre Mergnat }; 260*1c50ec75SAlexandre Mergnat 261*1c50ec75SAlexandre Mergnat /* DAI Controls */ 262*1c50ec75SAlexandre Mergnat 263*1c50ec75SAlexandre Mergnat /* Values for 48kHz mode */ 264*1c50ec75SAlexandre Mergnat static const char * const iir_mode_src[] = { 265*1c50ec75SAlexandre Mergnat "SW custom", "5Hz", "10Hz", "25Hz", "50Hz", "65Hz" 266*1c50ec75SAlexandre Mergnat }; 267*1c50ec75SAlexandre Mergnat 268*1c50ec75SAlexandre Mergnat static SOC_ENUM_SINGLE_DECL(iir_mode, AFE_DMIC0_UL_SRC_CON0, 7, iir_mode_src); 269*1c50ec75SAlexandre Mergnat 270*1c50ec75SAlexandre Mergnat static const struct snd_kcontrol_new mtk_dai_dmic_controls[] = { 271*1c50ec75SAlexandre Mergnat SOC_SINGLE("DMIC IIR Switch", AFE_DMIC0_UL_SRC_CON0, DMIC_TOP_CON_IIR_ON, 1, 0), 272*1c50ec75SAlexandre Mergnat SOC_ENUM("DMIC IIR Mode", iir_mode), 273*1c50ec75SAlexandre Mergnat }; 274*1c50ec75SAlexandre Mergnat 275*1c50ec75SAlexandre Mergnat /* DAI widget */ 276*1c50ec75SAlexandre Mergnat 277*1c50ec75SAlexandre Mergnat static const struct snd_soc_dapm_widget mtk_dai_dmic_widgets[] = { 278*1c50ec75SAlexandre Mergnat SND_SOC_DAPM_INPUT("DMIC In"), 279*1c50ec75SAlexandre Mergnat }; 280*1c50ec75SAlexandre Mergnat 281*1c50ec75SAlexandre Mergnat /* DAI route */ 282*1c50ec75SAlexandre Mergnat 283*1c50ec75SAlexandre Mergnat static const struct snd_soc_dapm_route mtk_dai_dmic_routes[] = { 284*1c50ec75SAlexandre Mergnat {"I14", NULL, "DMIC Capture"}, 285*1c50ec75SAlexandre Mergnat {"I15", NULL, "DMIC Capture"}, 286*1c50ec75SAlexandre Mergnat {"I16", NULL, "DMIC Capture"}, 287*1c50ec75SAlexandre Mergnat {"I17", NULL, "DMIC Capture"}, 288*1c50ec75SAlexandre Mergnat {"I18", NULL, "DMIC Capture"}, 289*1c50ec75SAlexandre Mergnat {"I19", NULL, "DMIC Capture"}, 290*1c50ec75SAlexandre Mergnat {"I20", NULL, "DMIC Capture"}, 291*1c50ec75SAlexandre Mergnat {"I21", NULL, "DMIC Capture"}, 292*1c50ec75SAlexandre Mergnat {"DMIC Capture", NULL, "DMIC In"}, 293*1c50ec75SAlexandre Mergnat }; 294*1c50ec75SAlexandre Mergnat 295*1c50ec75SAlexandre Mergnat static int init_dmic_priv_data(struct mtk_base_afe *afe) 296*1c50ec75SAlexandre Mergnat { 297*1c50ec75SAlexandre Mergnat struct mt8365_afe_private *afe_priv = afe->platform_priv; 298*1c50ec75SAlexandre Mergnat struct mt8365_dmic_data *dmic_priv; 299*1c50ec75SAlexandre Mergnat struct device_node *np = afe->dev->of_node; 300*1c50ec75SAlexandre Mergnat unsigned int temps[4]; 301*1c50ec75SAlexandre Mergnat int ret; 302*1c50ec75SAlexandre Mergnat 303*1c50ec75SAlexandre Mergnat dmic_priv = devm_kzalloc(afe->dev, sizeof(*dmic_priv), GFP_KERNEL); 304*1c50ec75SAlexandre Mergnat if (!dmic_priv) 305*1c50ec75SAlexandre Mergnat return -ENOMEM; 306*1c50ec75SAlexandre Mergnat 307*1c50ec75SAlexandre Mergnat ret = of_property_read_u32_array(np, "mediatek,dmic-mode", 308*1c50ec75SAlexandre Mergnat &temps[0], 309*1c50ec75SAlexandre Mergnat 1); 310*1c50ec75SAlexandre Mergnat if (ret == 0) 311*1c50ec75SAlexandre Mergnat dmic_priv->two_wire_mode = !!temps[0]; 312*1c50ec75SAlexandre Mergnat 313*1c50ec75SAlexandre Mergnat if (!dmic_priv->two_wire_mode) { 314*1c50ec75SAlexandre Mergnat dmic_priv->clk_phase_sel_ch1 = 0; 315*1c50ec75SAlexandre Mergnat dmic_priv->clk_phase_sel_ch2 = 4; 316*1c50ec75SAlexandre Mergnat } 317*1c50ec75SAlexandre Mergnat 318*1c50ec75SAlexandre Mergnat afe_priv->dai_priv[MT8365_AFE_IO_DMIC] = dmic_priv; 319*1c50ec75SAlexandre Mergnat return 0; 320*1c50ec75SAlexandre Mergnat } 321*1c50ec75SAlexandre Mergnat 322*1c50ec75SAlexandre Mergnat int mt8365_dai_dmic_register(struct mtk_base_afe *afe) 323*1c50ec75SAlexandre Mergnat { 324*1c50ec75SAlexandre Mergnat struct mtk_base_afe_dai *dai; 325*1c50ec75SAlexandre Mergnat 326*1c50ec75SAlexandre Mergnat dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 327*1c50ec75SAlexandre Mergnat if (!dai) 328*1c50ec75SAlexandre Mergnat return -ENOMEM; 329*1c50ec75SAlexandre Mergnat 330*1c50ec75SAlexandre Mergnat list_add(&dai->list, &afe->sub_dais); 331*1c50ec75SAlexandre Mergnat dai->dai_drivers = mtk_dai_dmic_driver; 332*1c50ec75SAlexandre Mergnat dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_dmic_driver); 333*1c50ec75SAlexandre Mergnat dai->controls = mtk_dai_dmic_controls; 334*1c50ec75SAlexandre Mergnat dai->num_controls = ARRAY_SIZE(mtk_dai_dmic_controls); 335*1c50ec75SAlexandre Mergnat dai->dapm_widgets = mtk_dai_dmic_widgets; 336*1c50ec75SAlexandre Mergnat dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_dmic_widgets); 337*1c50ec75SAlexandre Mergnat dai->dapm_routes = mtk_dai_dmic_routes; 338*1c50ec75SAlexandre Mergnat dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_dmic_routes); 339*1c50ec75SAlexandre Mergnat return init_dmic_priv_data(afe); 340*1c50ec75SAlexandre Mergnat } 341