xref: /linux/sound/soc/mediatek/mt8365/mt8365-dai-dmic.c (revision 1c50ec75ce6c0c6b5736499393e522f73e19d0cf)
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