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
get_chan_reg(unsigned int channel)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
audio_dmic_adda_enable(struct mtk_base_afe * afe)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
audio_dmic_adda_disable(struct mtk_base_afe * afe)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
mt8365_dai_enable_dmic(struct mtk_base_afe * afe,struct snd_pcm_substream * substream,struct snd_soc_dai * dai)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
mt8365_dai_disable_dmic(struct mtk_base_afe * afe,struct snd_pcm_substream * substream,struct snd_soc_dai * dai)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
mt8365_dai_configure_dmic(struct mtk_base_afe * afe,struct snd_pcm_substream * substream,struct snd_soc_dai * dai)111*1c50ec75SAlexandre Mergnat static int mt8365_dai_configure_dmic(struct mtk_base_afe *afe,
112*1c50ec75SAlexandre Mergnat struct snd_pcm_substream *substream,
113*1c50ec75SAlexandre Mergnat struct snd_soc_dai *dai)
114*1c50ec75SAlexandre Mergnat {
115*1c50ec75SAlexandre Mergnat struct mt8365_afe_private *afe_priv = afe->platform_priv;
116*1c50ec75SAlexandre Mergnat struct mt8365_dmic_data *dmic_data = afe_priv->dai_priv[MT8365_AFE_IO_DMIC];
117*1c50ec75SAlexandre Mergnat bool two_wire_mode = dmic_data->two_wire_mode;
118*1c50ec75SAlexandre Mergnat unsigned int clk_phase_sel_ch1 = dmic_data->clk_phase_sel_ch1;
119*1c50ec75SAlexandre Mergnat unsigned int clk_phase_sel_ch2 = dmic_data->clk_phase_sel_ch2;
120*1c50ec75SAlexandre Mergnat unsigned int val = 0;
121*1c50ec75SAlexandre Mergnat unsigned int rate = dai->rate;
122*1c50ec75SAlexandre Mergnat int reg = get_chan_reg(dai->channels);
123*1c50ec75SAlexandre Mergnat
124*1c50ec75SAlexandre Mergnat if (reg < 0)
125*1c50ec75SAlexandre Mergnat return -EINVAL;
126*1c50ec75SAlexandre Mergnat
127*1c50ec75SAlexandre Mergnat dmic_data->dmic_channel = dai->channels;
128*1c50ec75SAlexandre Mergnat
129*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_SDM3_LEVEL_MODE;
130*1c50ec75SAlexandre Mergnat
131*1c50ec75SAlexandre Mergnat if (two_wire_mode) {
132*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_TWO_WIRE_MODE;
133*1c50ec75SAlexandre Mergnat } else {
134*1c50ec75SAlexandre Mergnat val |= FIELD_PREP(DMIC_TOP_CON_CK_PHASE_SEL_CH1,
135*1c50ec75SAlexandre Mergnat clk_phase_sel_ch1);
136*1c50ec75SAlexandre Mergnat val |= FIELD_PREP(DMIC_TOP_CON_CK_PHASE_SEL_CH2,
137*1c50ec75SAlexandre Mergnat clk_phase_sel_ch2);
138*1c50ec75SAlexandre Mergnat }
139*1c50ec75SAlexandre Mergnat
140*1c50ec75SAlexandre Mergnat switch (rate) {
141*1c50ec75SAlexandre Mergnat case 48000:
142*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_VOICE_MODE_48K;
143*1c50ec75SAlexandre Mergnat break;
144*1c50ec75SAlexandre Mergnat case 32000:
145*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_VOICE_MODE_32K;
146*1c50ec75SAlexandre Mergnat break;
147*1c50ec75SAlexandre Mergnat case 16000:
148*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_VOICE_MODE_16K;
149*1c50ec75SAlexandre Mergnat break;
150*1c50ec75SAlexandre Mergnat case 8000:
151*1c50ec75SAlexandre Mergnat val |= DMIC_TOP_CON_VOICE_MODE_8K;
152*1c50ec75SAlexandre Mergnat break;
153*1c50ec75SAlexandre Mergnat default:
154*1c50ec75SAlexandre Mergnat return -EINVAL;
155*1c50ec75SAlexandre Mergnat }
156*1c50ec75SAlexandre Mergnat
157*1c50ec75SAlexandre Mergnat regmap_update_bits(afe->regmap, reg, DMIC_TOP_CON_CONFIG_MASK, val);
158*1c50ec75SAlexandre Mergnat
159*1c50ec75SAlexandre Mergnat return 0;
160*1c50ec75SAlexandre Mergnat }
161*1c50ec75SAlexandre Mergnat
mt8365_dai_dmic_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)162*1c50ec75SAlexandre Mergnat static int mt8365_dai_dmic_startup(struct snd_pcm_substream *substream,
163*1c50ec75SAlexandre Mergnat struct snd_soc_dai *dai)
164*1c50ec75SAlexandre Mergnat {
165*1c50ec75SAlexandre Mergnat struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
166*1c50ec75SAlexandre Mergnat
167*1c50ec75SAlexandre Mergnat mt8365_afe_enable_main_clk(afe);
168*1c50ec75SAlexandre Mergnat
169*1c50ec75SAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC0_ADC);
170*1c50ec75SAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC1_ADC);
171*1c50ec75SAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC2_ADC);
172*1c50ec75SAlexandre Mergnat mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC3_ADC);
173*1c50ec75SAlexandre Mergnat
174*1c50ec75SAlexandre Mergnat audio_dmic_adda_enable(afe);
175*1c50ec75SAlexandre Mergnat
176*1c50ec75SAlexandre Mergnat return 0;
177*1c50ec75SAlexandre Mergnat }
178*1c50ec75SAlexandre Mergnat
mt8365_dai_dmic_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)179*1c50ec75SAlexandre Mergnat static void mt8365_dai_dmic_shutdown(struct snd_pcm_substream *substream,
180*1c50ec75SAlexandre Mergnat struct snd_soc_dai *dai)
181*1c50ec75SAlexandre Mergnat {
182*1c50ec75SAlexandre Mergnat struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
183*1c50ec75SAlexandre Mergnat
184*1c50ec75SAlexandre Mergnat mt8365_dai_disable_dmic(afe, substream, dai);
185*1c50ec75SAlexandre Mergnat audio_dmic_adda_disable(afe);
186*1c50ec75SAlexandre Mergnat /* HW Request delay 125us before CG off */
187*1c50ec75SAlexandre Mergnat usleep_range(125, 300);
188*1c50ec75SAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC3_ADC);
189*1c50ec75SAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC2_ADC);
190*1c50ec75SAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC1_ADC);
191*1c50ec75SAlexandre Mergnat mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC0_ADC);
192*1c50ec75SAlexandre Mergnat
193*1c50ec75SAlexandre Mergnat mt8365_afe_disable_main_clk(afe);
194*1c50ec75SAlexandre Mergnat }
195*1c50ec75SAlexandre Mergnat
mt8365_dai_dmic_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)196*1c50ec75SAlexandre Mergnat static int mt8365_dai_dmic_prepare(struct snd_pcm_substream *substream,
197*1c50ec75SAlexandre Mergnat struct snd_soc_dai *dai)
198*1c50ec75SAlexandre Mergnat {
199*1c50ec75SAlexandre Mergnat struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
200*1c50ec75SAlexandre Mergnat
201*1c50ec75SAlexandre Mergnat mt8365_dai_configure_dmic(afe, substream, dai);
202*1c50ec75SAlexandre Mergnat mt8365_dai_enable_dmic(afe, substream, dai);
203*1c50ec75SAlexandre Mergnat
204*1c50ec75SAlexandre Mergnat return 0;
205*1c50ec75SAlexandre Mergnat }
206*1c50ec75SAlexandre Mergnat
207*1c50ec75SAlexandre Mergnat static const struct snd_soc_dai_ops mt8365_afe_dmic_ops = {
208*1c50ec75SAlexandre Mergnat .startup = mt8365_dai_dmic_startup,
209*1c50ec75SAlexandre Mergnat .shutdown = mt8365_dai_dmic_shutdown,
210*1c50ec75SAlexandre Mergnat .prepare = mt8365_dai_dmic_prepare,
211*1c50ec75SAlexandre Mergnat };
212*1c50ec75SAlexandre Mergnat
213*1c50ec75SAlexandre Mergnat static struct snd_soc_dai_driver mtk_dai_dmic_driver[] = {
214*1c50ec75SAlexandre Mergnat {
215*1c50ec75SAlexandre Mergnat .name = "DMIC",
216*1c50ec75SAlexandre Mergnat .id = MT8365_AFE_IO_DMIC,
217*1c50ec75SAlexandre Mergnat .capture = {
218*1c50ec75SAlexandre Mergnat .stream_name = "DMIC Capture",
219*1c50ec75SAlexandre Mergnat .channels_min = 1,
220*1c50ec75SAlexandre Mergnat .channels_max = 8,
221*1c50ec75SAlexandre Mergnat .rates = SNDRV_PCM_RATE_16000 |
222*1c50ec75SAlexandre Mergnat SNDRV_PCM_RATE_32000 |
223*1c50ec75SAlexandre Mergnat SNDRV_PCM_RATE_48000,
224*1c50ec75SAlexandre Mergnat .formats = SNDRV_PCM_FMTBIT_S16_LE |
225*1c50ec75SAlexandre Mergnat SNDRV_PCM_FMTBIT_S32_LE,
226*1c50ec75SAlexandre Mergnat },
227*1c50ec75SAlexandre Mergnat .ops = &mt8365_afe_dmic_ops,
228*1c50ec75SAlexandre Mergnat }
229*1c50ec75SAlexandre Mergnat };
230*1c50ec75SAlexandre Mergnat
231*1c50ec75SAlexandre Mergnat /* DAI Controls */
232*1c50ec75SAlexandre Mergnat
233*1c50ec75SAlexandre Mergnat /* Values for 48kHz mode */
234*1c50ec75SAlexandre Mergnat static const char * const iir_mode_src[] = {
235*1c50ec75SAlexandre Mergnat "SW custom", "5Hz", "10Hz", "25Hz", "50Hz", "65Hz"
236*1c50ec75SAlexandre Mergnat };
237*1c50ec75SAlexandre Mergnat
238*1c50ec75SAlexandre Mergnat static SOC_ENUM_SINGLE_DECL(iir_mode, AFE_DMIC0_UL_SRC_CON0, 7, iir_mode_src);
239*1c50ec75SAlexandre Mergnat
240*1c50ec75SAlexandre Mergnat static const struct snd_kcontrol_new mtk_dai_dmic_controls[] = {
241*1c50ec75SAlexandre Mergnat SOC_SINGLE("DMIC IIR Switch", AFE_DMIC0_UL_SRC_CON0, DMIC_TOP_CON_IIR_ON, 1, 0),
242*1c50ec75SAlexandre Mergnat SOC_ENUM("DMIC IIR Mode", iir_mode),
243*1c50ec75SAlexandre Mergnat };
244*1c50ec75SAlexandre Mergnat
245*1c50ec75SAlexandre Mergnat /* DAI widget */
246*1c50ec75SAlexandre Mergnat
247*1c50ec75SAlexandre Mergnat static const struct snd_soc_dapm_widget mtk_dai_dmic_widgets[] = {
248*1c50ec75SAlexandre Mergnat SND_SOC_DAPM_INPUT("DMIC In"),
249*1c50ec75SAlexandre Mergnat };
250*1c50ec75SAlexandre Mergnat
251*1c50ec75SAlexandre Mergnat /* DAI route */
252*1c50ec75SAlexandre Mergnat
253*1c50ec75SAlexandre Mergnat static const struct snd_soc_dapm_route mtk_dai_dmic_routes[] = {
254*1c50ec75SAlexandre Mergnat {"I14", NULL, "DMIC Capture"},
255*1c50ec75SAlexandre Mergnat {"I15", NULL, "DMIC Capture"},
256*1c50ec75SAlexandre Mergnat {"I16", NULL, "DMIC Capture"},
257*1c50ec75SAlexandre Mergnat {"I17", NULL, "DMIC Capture"},
258*1c50ec75SAlexandre Mergnat {"I18", NULL, "DMIC Capture"},
259*1c50ec75SAlexandre Mergnat {"I19", NULL, "DMIC Capture"},
260*1c50ec75SAlexandre Mergnat {"I20", NULL, "DMIC Capture"},
261*1c50ec75SAlexandre Mergnat {"I21", NULL, "DMIC Capture"},
262*1c50ec75SAlexandre Mergnat {"DMIC Capture", NULL, "DMIC In"},
263*1c50ec75SAlexandre Mergnat };
264*1c50ec75SAlexandre Mergnat
init_dmic_priv_data(struct mtk_base_afe * afe)265*1c50ec75SAlexandre Mergnat static int init_dmic_priv_data(struct mtk_base_afe *afe)
266*1c50ec75SAlexandre Mergnat {
267*1c50ec75SAlexandre Mergnat struct mt8365_afe_private *afe_priv = afe->platform_priv;
268*1c50ec75SAlexandre Mergnat struct mt8365_dmic_data *dmic_priv;
269*1c50ec75SAlexandre Mergnat struct device_node *np = afe->dev->of_node;
270*1c50ec75SAlexandre Mergnat unsigned int temps[4];
271*1c50ec75SAlexandre Mergnat int ret;
272*1c50ec75SAlexandre Mergnat
273*1c50ec75SAlexandre Mergnat dmic_priv = devm_kzalloc(afe->dev, sizeof(*dmic_priv), GFP_KERNEL);
274*1c50ec75SAlexandre Mergnat if (!dmic_priv)
275*1c50ec75SAlexandre Mergnat return -ENOMEM;
276*1c50ec75SAlexandre Mergnat
277*1c50ec75SAlexandre Mergnat ret = of_property_read_u32_array(np, "mediatek,dmic-mode",
278*1c50ec75SAlexandre Mergnat &temps[0],
279*1c50ec75SAlexandre Mergnat 1);
280*1c50ec75SAlexandre Mergnat if (ret == 0)
281*1c50ec75SAlexandre Mergnat dmic_priv->two_wire_mode = !!temps[0];
282*1c50ec75SAlexandre Mergnat
283*1c50ec75SAlexandre Mergnat if (!dmic_priv->two_wire_mode) {
284*1c50ec75SAlexandre Mergnat dmic_priv->clk_phase_sel_ch1 = 0;
285*1c50ec75SAlexandre Mergnat dmic_priv->clk_phase_sel_ch2 = 4;
286*1c50ec75SAlexandre Mergnat }
287*1c50ec75SAlexandre Mergnat
288*1c50ec75SAlexandre Mergnat afe_priv->dai_priv[MT8365_AFE_IO_DMIC] = dmic_priv;
289*1c50ec75SAlexandre Mergnat return 0;
290*1c50ec75SAlexandre Mergnat }
291*1c50ec75SAlexandre Mergnat
mt8365_dai_dmic_register(struct mtk_base_afe * afe)292*1c50ec75SAlexandre Mergnat int mt8365_dai_dmic_register(struct mtk_base_afe *afe)
293*1c50ec75SAlexandre Mergnat {
294*1c50ec75SAlexandre Mergnat struct mtk_base_afe_dai *dai;
295*1c50ec75SAlexandre Mergnat
296*1c50ec75SAlexandre Mergnat dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
297*1c50ec75SAlexandre Mergnat if (!dai)
298*1c50ec75SAlexandre Mergnat return -ENOMEM;
299*1c50ec75SAlexandre Mergnat
300*1c50ec75SAlexandre Mergnat list_add(&dai->list, &afe->sub_dais);
301*1c50ec75SAlexandre Mergnat dai->dai_drivers = mtk_dai_dmic_driver;
302*1c50ec75SAlexandre Mergnat dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_dmic_driver);
303*1c50ec75SAlexandre Mergnat dai->controls = mtk_dai_dmic_controls;
304*1c50ec75SAlexandre Mergnat dai->num_controls = ARRAY_SIZE(mtk_dai_dmic_controls);
305*1c50ec75SAlexandre Mergnat dai->dapm_widgets = mtk_dai_dmic_widgets;
306*1c50ec75SAlexandre Mergnat dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_dmic_widgets);
307*1c50ec75SAlexandre Mergnat dai->dapm_routes = mtk_dai_dmic_routes;
308*1c50ec75SAlexandre Mergnat dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_dmic_routes);
309*1c50ec75SAlexandre Mergnat return init_dmic_priv_data(afe);
310*1c50ec75SAlexandre Mergnat }
311