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