xref: /openbmc/linux/sound/soc/codecs/rt715-sdca.c (revision 7ca4282ade77de53b6e9ffa2695566e5d35dab1e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // rt715-sdca.c -- rt715 ALSA SoC audio driver
4 //
5 // Copyright(c) 2020 Realtek Semiconductor Corp.
6 //
7 //
8 //
9 
10 #include <linux/module.h>
11 #include <linux/moduleparam.h>
12 #include <linux/version.h>
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/pm.h>
17 #include <linux/soundwire/sdw.h>
18 #include <linux/regmap.h>
19 #include <linux/slab.h>
20 #include <linux/platform_device.h>
21 #include <sound/core.h>
22 #include <sound/pcm.h>
23 #include <sound/pcm_params.h>
24 #include <sound/soc.h>
25 #include <sound/soc-dapm.h>
26 #include <sound/initval.h>
27 #include <sound/tlv.h>
28 #include <linux/soundwire/sdw_registers.h>
29 
30 #include "rt715-sdca.h"
31 
32 static int rt715_index_write(struct rt715_sdca_priv *rt715, unsigned int nid,
33 		unsigned int reg, unsigned int value)
34 {
35 	struct regmap *regmap = rt715->mbq_regmap;
36 	unsigned int addr;
37 	int ret;
38 
39 	addr = (nid << 20) | reg;
40 
41 	ret = regmap_write(regmap, addr, value);
42 	if (ret < 0)
43 		dev_err(&rt715->slave->dev,
44 				"Failed to set private value: %08x <= %04x %d\n", ret, addr,
45 				value);
46 
47 	return ret;
48 }
49 
50 static int rt715_index_read(struct rt715_sdca_priv *rt715,
51 		unsigned int nid, unsigned int reg, unsigned int *value)
52 {
53 	struct regmap *regmap = rt715->mbq_regmap;
54 	unsigned int addr;
55 	int ret;
56 
57 	addr = (nid << 20) | reg;
58 
59 	ret = regmap_read(regmap, addr, value);
60 	if (ret < 0)
61 		dev_err(&rt715->slave->dev,
62 				"Failed to get private value: %06x => %04x ret=%d\n",
63 				addr, *value, ret);
64 
65 	return ret;
66 }
67 
68 static int rt715_index_update_bits(struct rt715_sdca_priv *rt715,
69 	unsigned int nid, unsigned int reg, unsigned int mask, unsigned int val)
70 {
71 	unsigned int tmp;
72 	int ret;
73 
74 	ret = rt715_index_read(rt715, nid, reg, &tmp);
75 	if (ret < 0)
76 		return ret;
77 
78 	set_mask_bits(&tmp, mask, val);
79 
80 	return rt715_index_write(rt715, nid, reg, tmp);
81 }
82 
83 /* SDCA Volume/Boost control */
84 static int rt715_set_amp_gain_put_sdca(struct snd_kcontrol *kcontrol,
85 		struct snd_ctl_elem_value *ucontrol)
86 {
87 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
88 	struct soc_mixer_control *mc =
89 		(struct soc_mixer_control *)kcontrol->private_value;
90 	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
91 	unsigned int val_l, val_r, gain_l_val, gain_r_val;
92 	int ret;
93 
94 	/* control value to 2s complement */
95 	/* L channel */
96 	gain_l_val = ucontrol->value.integer.value[0];
97 	if (gain_l_val > mc->max)
98 		gain_l_val = mc->max;
99 	val_l = gain_l_val;
100 
101 	if (mc->shift == 8) {
102 		gain_l_val = (gain_l_val * 10) << mc->shift;
103 	} else {
104 		gain_l_val =
105 			((abs(gain_l_val - mc->shift) * RT715_SDCA_DB_STEP) << 8) / 1000;
106 		if (val_l <= mc->shift) {
107 			gain_l_val = ~gain_l_val;
108 			gain_l_val += 1;
109 		}
110 		gain_l_val &= 0xffff;
111 	}
112 
113 	/* R channel */
114 	gain_r_val = ucontrol->value.integer.value[1];
115 	if (gain_r_val > mc->max)
116 		gain_r_val = mc->max;
117 	val_r = gain_r_val;
118 
119 	if (mc->shift == 8) {
120 		gain_r_val = (gain_r_val * 10) << mc->shift;
121 	} else {
122 		gain_r_val =
123 			((abs(gain_r_val - mc->shift) * RT715_SDCA_DB_STEP) << 8) / 1000;
124 		if (val_r <= mc->shift) {
125 			gain_r_val = ~gain_r_val;
126 			gain_r_val += 1;
127 		}
128 		gain_r_val &= 0xffff;
129 	}
130 
131 	/* Lch*/
132 	ret = regmap_write(rt715->mbq_regmap, mc->reg, gain_l_val);
133 	if (ret != 0) {
134 		dev_err(component->dev, "Failed to write 0x%x=0x%x\n", mc->reg,
135 			gain_l_val);
136 		return ret;
137 	}
138 	/* Rch */
139 	ret = regmap_write(rt715->mbq_regmap, mc->rreg, gain_r_val);
140 	if (ret != 0) {
141 		dev_err(component->dev, "Failed to write 0x%x=0x%x\n", mc->rreg,
142 			gain_r_val);
143 		return ret;
144 	}
145 
146 	return 0;
147 }
148 
149 static int rt715_set_amp_gain_get_sdca(struct snd_kcontrol *kcontrol,
150 		struct snd_ctl_elem_value *ucontrol)
151 {
152 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
153 	struct soc_mixer_control *mc =
154 		(struct soc_mixer_control *)kcontrol->private_value;
155 	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
156 	unsigned int val_l, val_r, ctl_l, ctl_r, neg_flag = 0;
157 	int ret;
158 
159 	ret = regmap_read(rt715->mbq_regmap, mc->reg, &val_l);
160 	if (ret < 0)
161 		dev_err(component->dev, "Failed to read 0x%x, ret=%d\n", mc->reg, ret);
162 	ret = regmap_read(rt715->mbq_regmap, mc->rreg, &val_r);
163 	if (ret < 0)
164 		dev_err(component->dev, "Failed to read 0x%x, ret=%d\n", mc->rreg,
165 				ret);
166 
167 	/* L channel */
168 	if (mc->shift == 8) {
169 		ctl_l = (val_l >> mc->shift) / 10;
170 	} else {
171 		ctl_l = val_l;
172 		if (ctl_l & BIT(15)) {
173 			ctl_l = ~(val_l - 1) & 0xffff;
174 			neg_flag = 1;
175 		}
176 		ctl_l *= 1000;
177 		ctl_l >>= 8;
178 		if (neg_flag)
179 			ctl_l = mc->shift - ctl_l / RT715_SDCA_DB_STEP;
180 		else
181 			ctl_l = mc->shift + ctl_l / RT715_SDCA_DB_STEP;
182 	}
183 
184 	neg_flag = 0;
185 	/* R channel */
186 	if (mc->shift == 8) {
187 		ctl_r = (val_r >> mc->shift) / 10;
188 	} else {
189 		ctl_r = val_r;
190 		if (ctl_r & BIT(15)) {
191 			ctl_r = ~(val_r - 1) & 0xffff;
192 			neg_flag = 1;
193 		}
194 		ctl_r *= 1000;
195 		ctl_r >>= 8;
196 		if (neg_flag)
197 			ctl_r = mc->shift - ctl_r / RT715_SDCA_DB_STEP;
198 		else
199 			ctl_r = mc->shift + ctl_r / RT715_SDCA_DB_STEP;
200 	}
201 
202 	ucontrol->value.integer.value[0] = ctl_l;
203 	ucontrol->value.integer.value[1] = ctl_r;
204 
205 	return 0;
206 }
207 
208 static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -17625, 375, 0);
209 static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
210 
211 #define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\
212 	 xhandler_get, xhandler_put) \
213 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
214 	.info = snd_soc_info_volsw, \
215 	.get = xhandler_get, .put = xhandler_put, \
216 	.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
217 					    xmax, xinvert) }
218 
219 static const struct snd_kcontrol_new rt715_snd_controls_sdca[] = {
220 	/* Capture switch */
221 	SOC_DOUBLE_R("FU0A Capture Switch",
222 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
223 			RT715_SDCA_FU_MUTE_CTRL, CH_01),
224 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
225 			RT715_SDCA_FU_MUTE_CTRL, CH_02),
226 			0, 1, 1),
227 	SOC_DOUBLE_R("FU02 1_2 Capture Switch",
228 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
229 			RT715_SDCA_FU_MUTE_CTRL, CH_01),
230 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
231 			RT715_SDCA_FU_MUTE_CTRL, CH_02),
232 			0, 1, 1),
233 	SOC_DOUBLE_R("FU02 3_4 Capture Switch",
234 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
235 			RT715_SDCA_FU_MUTE_CTRL, CH_03),
236 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
237 			RT715_SDCA_FU_MUTE_CTRL, CH_04),
238 			0, 1, 1),
239 	SOC_DOUBLE_R("FU06 1_2 Capture Switch",
240 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
241 			RT715_SDCA_FU_MUTE_CTRL, CH_01),
242 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
243 			RT715_SDCA_FU_MUTE_CTRL, CH_02),
244 			0, 1, 1),
245 	SOC_DOUBLE_R("FU06 3_4 Capture Switch",
246 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
247 			RT715_SDCA_FU_MUTE_CTRL, CH_03),
248 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
249 			RT715_SDCA_FU_MUTE_CTRL, CH_04),
250 			0, 1, 1),
251 	/* Volume Control */
252 	SOC_DOUBLE_R_EXT_TLV("FU0A Capture Volume",
253 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
254 			RT715_SDCA_FU_VOL_CTRL, CH_01),
255 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
256 			RT715_SDCA_FU_VOL_CTRL, CH_02),
257 			0x2f, 0x7f, 0,
258 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
259 		in_vol_tlv),
260 	SOC_DOUBLE_R_EXT_TLV("FU02 1_2 Capture Volume",
261 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
262 			RT715_SDCA_FU_VOL_CTRL, CH_01),
263 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
264 			RT715_SDCA_FU_VOL_CTRL, CH_02),
265 			0x2f, 0x7f, 0,
266 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
267 		in_vol_tlv),
268 	SOC_DOUBLE_R_EXT_TLV("FU02 3_4 Capture Volume",
269 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
270 			RT715_SDCA_FU_VOL_CTRL,
271 			CH_03),
272 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
273 			RT715_SDCA_FU_VOL_CTRL,
274 			CH_04), 0x2f, 0x7f, 0,
275 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
276 		in_vol_tlv),
277 	SOC_DOUBLE_R_EXT_TLV("FU06 1_2 Capture Volume",
278 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
279 			RT715_SDCA_FU_VOL_CTRL,
280 			CH_01),
281 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
282 			RT715_SDCA_FU_VOL_CTRL,
283 			CH_02), 0x2f, 0x7f, 0,
284 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
285 		in_vol_tlv),
286 	SOC_DOUBLE_R_EXT_TLV("FU06 3_4 Capture Volume",
287 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
288 			RT715_SDCA_FU_VOL_CTRL,
289 			CH_03),
290 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
291 			RT715_SDCA_FU_VOL_CTRL,
292 			CH_04), 0x2f, 0x7f, 0,
293 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
294 		in_vol_tlv),
295 	/* MIC Boost Control */
296 	SOC_DOUBLE_R_EXT_TLV("FU0E 1_2 Boost",
297 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
298 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
299 			CH_01),
300 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
301 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
302 			CH_02), 8, 3, 0,
303 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
304 		mic_vol_tlv),
305 	SOC_DOUBLE_R_EXT_TLV("FU0E 3_4 Boost",
306 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
307 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
308 			CH_03),
309 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
310 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
311 			CH_04), 8, 3, 0,
312 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
313 		mic_vol_tlv),
314 	SOC_DOUBLE_R_EXT_TLV("FU0E 5_6 Boost",
315 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
316 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
317 			CH_05),
318 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
319 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
320 			CH_06), 8, 3, 0,
321 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
322 		mic_vol_tlv),
323 	SOC_DOUBLE_R_EXT_TLV("FU0E 7_8 Boost",
324 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
325 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
326 			CH_07),
327 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
328 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
329 			CH_08), 8, 3, 0,
330 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
331 		mic_vol_tlv),
332 	SOC_DOUBLE_R_EXT_TLV("FU0C 1_2 Boost",
333 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
334 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
335 			CH_01),
336 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
337 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
338 			CH_02), 8, 3, 0,
339 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
340 		mic_vol_tlv),
341 	SOC_DOUBLE_R_EXT_TLV("FU0C 3_4 Boost",
342 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
343 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
344 			CH_03),
345 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
346 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
347 			CH_04), 8, 3, 0,
348 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
349 		mic_vol_tlv),
350 	SOC_DOUBLE_R_EXT_TLV("FU0C 5_6 Boost",
351 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
352 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
353 			CH_05),
354 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
355 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
356 			CH_06), 8, 3, 0,
357 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
358 		mic_vol_tlv),
359 	SOC_DOUBLE_R_EXT_TLV("FU0C 7_8 Boost",
360 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
361 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
362 			CH_07),
363 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
364 			RT715_SDCA_FU_DMIC_GAIN_CTRL,
365 			CH_08), 8, 3, 0,
366 		rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca,
367 		mic_vol_tlv),
368 };
369 
370 static int rt715_mux_get(struct snd_kcontrol *kcontrol,
371 			struct snd_ctl_elem_value *ucontrol)
372 {
373 	struct snd_soc_component *component =
374 		snd_soc_dapm_kcontrol_component(kcontrol);
375 	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
376 	unsigned int val, mask_sft;
377 
378 	if (strstr(ucontrol->id.name, "ADC 22 Mux"))
379 		mask_sft = 12;
380 	else if (strstr(ucontrol->id.name, "ADC 23 Mux"))
381 		mask_sft = 8;
382 	else if (strstr(ucontrol->id.name, "ADC 24 Mux"))
383 		mask_sft = 4;
384 	else if (strstr(ucontrol->id.name, "ADC 25 Mux"))
385 		mask_sft = 0;
386 	else
387 		return -EINVAL;
388 
389 	rt715_index_read(rt715, RT715_VENDOR_HDA_CTL,
390 		RT715_HDA_LEGACY_MUX_CTL1, &val);
391 	val = (val >> mask_sft) & 0xf;
392 
393 	/*
394 	 * The first two indices of ADC Mux 24/25 are routed to the same
395 	 * hardware source. ie, ADC Mux 24 0/1 will both connect to MIC2.
396 	 * To have a unique set of inputs, we skip the index1 of the muxes.
397 	 */
398 	if ((strstr(ucontrol->id.name, "ADC 24 Mux") ||
399 		strstr(ucontrol->id.name, "ADC 25 Mux")) && val > 0)
400 		val -= 1;
401 	ucontrol->value.enumerated.item[0] = val;
402 
403 	return 0;
404 }
405 
406 static int rt715_mux_put(struct snd_kcontrol *kcontrol,
407 			struct snd_ctl_elem_value *ucontrol)
408 {
409 	struct snd_soc_component *component =
410 		snd_soc_dapm_kcontrol_component(kcontrol);
411 	struct snd_soc_dapm_context *dapm =
412 				snd_soc_dapm_kcontrol_dapm(kcontrol);
413 	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
414 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
415 	unsigned int *item = ucontrol->value.enumerated.item;
416 	unsigned int val, val2 = 0, change, mask_sft;
417 
418 	if (item[0] >= e->items)
419 		return -EINVAL;
420 
421 	if (strstr(ucontrol->id.name, "ADC 22 Mux"))
422 		mask_sft = 12;
423 	else if (strstr(ucontrol->id.name, "ADC 23 Mux"))
424 		mask_sft = 8;
425 	else if (strstr(ucontrol->id.name, "ADC 24 Mux"))
426 		mask_sft = 4;
427 	else if (strstr(ucontrol->id.name, "ADC 25 Mux"))
428 		mask_sft = 0;
429 	else
430 		return -EINVAL;
431 
432 	/* Verb ID = 0x701h, nid = e->reg */
433 	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
434 
435 	rt715_index_read(rt715, RT715_VENDOR_HDA_CTL,
436 		RT715_HDA_LEGACY_MUX_CTL1, &val2);
437 	val2 = (val2 >> mask_sft) & 0xf;
438 
439 	change = val != val2;
440 
441 	if (change)
442 		rt715_index_update_bits(rt715, RT715_VENDOR_HDA_CTL,
443 			RT715_HDA_LEGACY_MUX_CTL1, 0xf << mask_sft, val << mask_sft);
444 
445 	snd_soc_dapm_mux_update_power(dapm, kcontrol, item[0], e, NULL);
446 
447 	return change;
448 }
449 
450 static const char * const adc_22_23_mux_text[] = {
451 	"MIC1",
452 	"MIC2",
453 	"LINE1",
454 	"LINE2",
455 	"DMIC1",
456 	"DMIC2",
457 	"DMIC3",
458 	"DMIC4",
459 };
460 
461 /*
462  * Due to mux design for nid 24 (MUX_IN3)/25 (MUX_IN4), connection index 0 and
463  * 1 will be connected to the same dmic source, therefore we skip index 1 to
464  * avoid misunderstanding on usage of dapm routing.
465  */
466 static int rt715_adc_24_25_values[] = {
467 	0,
468 	2,
469 	3,
470 	4,
471 	5,
472 };
473 
474 static const char * const adc_24_mux_text[] = {
475 	"MIC2",
476 	"DMIC1",
477 	"DMIC2",
478 	"DMIC3",
479 	"DMIC4",
480 };
481 
482 static const char * const adc_25_mux_text[] = {
483 	"MIC1",
484 	"DMIC1",
485 	"DMIC2",
486 	"DMIC3",
487 	"DMIC4",
488 };
489 
490 static SOC_ENUM_SINGLE_DECL(rt715_adc22_enum, SND_SOC_NOPM, 0,
491 	adc_22_23_mux_text);
492 
493 static SOC_ENUM_SINGLE_DECL(rt715_adc23_enum, SND_SOC_NOPM, 0,
494 	adc_22_23_mux_text);
495 
496 static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc24_enum,
497 	SND_SOC_NOPM, 0, 0xf,
498 	adc_24_mux_text, rt715_adc_24_25_values);
499 static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc25_enum,
500 	SND_SOC_NOPM, 0, 0xf,
501 	adc_25_mux_text, rt715_adc_24_25_values);
502 
503 static const struct snd_kcontrol_new rt715_adc22_mux =
504 	SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt715_adc22_enum,
505 			rt715_mux_get, rt715_mux_put);
506 
507 static const struct snd_kcontrol_new rt715_adc23_mux =
508 	SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt715_adc23_enum,
509 			rt715_mux_get, rt715_mux_put);
510 
511 static const struct snd_kcontrol_new rt715_adc24_mux =
512 	SOC_DAPM_ENUM_EXT("ADC 24 Mux", rt715_adc24_enum,
513 			rt715_mux_get, rt715_mux_put);
514 
515 static const struct snd_kcontrol_new rt715_adc25_mux =
516 	SOC_DAPM_ENUM_EXT("ADC 25 Mux", rt715_adc25_enum,
517 			rt715_mux_get, rt715_mux_put);
518 
519 static int rt715_pde23_24_event(struct snd_soc_dapm_widget *w,
520 	struct snd_kcontrol *kcontrol, int event)
521 {
522 	struct snd_soc_component *component =
523 		snd_soc_dapm_to_component(w->dapm);
524 	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
525 
526 	switch (event) {
527 	case SND_SOC_DAPM_POST_PMU:
528 		regmap_write(rt715->regmap,
529 			SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CREQ_POW_EN,
530 				RT715_SDCA_REQ_POW_CTRL,
531 				CH_00), 0x00);
532 		break;
533 	case SND_SOC_DAPM_PRE_PMD:
534 		regmap_write(rt715->regmap,
535 			SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CREQ_POW_EN,
536 				RT715_SDCA_REQ_POW_CTRL,
537 				CH_00), 0x03);
538 		break;
539 	}
540 	return 0;
541 }
542 
543 static const struct snd_soc_dapm_widget rt715_dapm_widgets[] = {
544 	SND_SOC_DAPM_INPUT("DMIC1"),
545 	SND_SOC_DAPM_INPUT("DMIC2"),
546 	SND_SOC_DAPM_INPUT("DMIC3"),
547 	SND_SOC_DAPM_INPUT("DMIC4"),
548 	SND_SOC_DAPM_INPUT("MIC1"),
549 	SND_SOC_DAPM_INPUT("MIC2"),
550 	SND_SOC_DAPM_INPUT("LINE1"),
551 	SND_SOC_DAPM_INPUT("LINE2"),
552 
553 	SND_SOC_DAPM_SUPPLY("PDE23_24", SND_SOC_NOPM, 0, 0,
554 		rt715_pde23_24_event,
555 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
556 
557 	SND_SOC_DAPM_ADC("ADC 07", NULL, SND_SOC_NOPM, 4, 0),
558 	SND_SOC_DAPM_ADC("ADC 08", NULL, SND_SOC_NOPM, 4, 0),
559 	SND_SOC_DAPM_ADC("ADC 09", NULL, SND_SOC_NOPM, 4, 0),
560 	SND_SOC_DAPM_ADC("ADC 27", NULL, SND_SOC_NOPM, 4, 0),
561 	SND_SOC_DAPM_MUX("ADC 22 Mux", SND_SOC_NOPM, 0, 0,
562 		&rt715_adc22_mux),
563 	SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0,
564 		&rt715_adc23_mux),
565 	SND_SOC_DAPM_MUX("ADC 24 Mux", SND_SOC_NOPM, 0, 0,
566 		&rt715_adc24_mux),
567 	SND_SOC_DAPM_MUX("ADC 25 Mux", SND_SOC_NOPM, 0, 0,
568 		&rt715_adc25_mux),
569 	SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0),
570 	SND_SOC_DAPM_AIF_OUT("DP6TX", "DP6 Capture", 0, SND_SOC_NOPM, 0, 0),
571 };
572 
573 static const struct snd_soc_dapm_route rt715_audio_map[] = {
574 	{"DP6TX", NULL, "ADC 09"},
575 	{"DP6TX", NULL, "ADC 08"},
576 	{"DP4TX", NULL, "ADC 07"},
577 	{"DP4TX", NULL, "ADC 27"},
578 	{"DP4TX", NULL, "ADC 09"},
579 	{"DP4TX", NULL, "ADC 08"},
580 
581 	{"LINE1", NULL, "PDE23_24"},
582 	{"LINE2", NULL, "PDE23_24"},
583 	{"MIC1", NULL, "PDE23_24"},
584 	{"MIC2", NULL, "PDE23_24"},
585 	{"DMIC1", NULL, "PDE23_24"},
586 	{"DMIC2", NULL, "PDE23_24"},
587 	{"DMIC3", NULL, "PDE23_24"},
588 	{"DMIC4", NULL, "PDE23_24"},
589 
590 	{"ADC 09", NULL, "ADC 22 Mux"},
591 	{"ADC 08", NULL, "ADC 23 Mux"},
592 	{"ADC 07", NULL, "ADC 24 Mux"},
593 	{"ADC 27", NULL, "ADC 25 Mux"},
594 	{"ADC 22 Mux", "MIC1", "MIC1"},
595 	{"ADC 22 Mux", "MIC2", "MIC2"},
596 	{"ADC 22 Mux", "LINE1", "LINE1"},
597 	{"ADC 22 Mux", "LINE2", "LINE2"},
598 	{"ADC 22 Mux", "DMIC1", "DMIC1"},
599 	{"ADC 22 Mux", "DMIC2", "DMIC2"},
600 	{"ADC 22 Mux", "DMIC3", "DMIC3"},
601 	{"ADC 22 Mux", "DMIC4", "DMIC4"},
602 	{"ADC 23 Mux", "MIC1", "MIC1"},
603 	{"ADC 23 Mux", "MIC2", "MIC2"},
604 	{"ADC 23 Mux", "LINE1", "LINE1"},
605 	{"ADC 23 Mux", "LINE2", "LINE2"},
606 	{"ADC 23 Mux", "DMIC1", "DMIC1"},
607 	{"ADC 23 Mux", "DMIC2", "DMIC2"},
608 	{"ADC 23 Mux", "DMIC3", "DMIC3"},
609 	{"ADC 23 Mux", "DMIC4", "DMIC4"},
610 	{"ADC 24 Mux", "MIC2", "MIC2"},
611 	{"ADC 24 Mux", "DMIC1", "DMIC1"},
612 	{"ADC 24 Mux", "DMIC2", "DMIC2"},
613 	{"ADC 24 Mux", "DMIC3", "DMIC3"},
614 	{"ADC 24 Mux", "DMIC4", "DMIC4"},
615 	{"ADC 25 Mux", "MIC1", "MIC1"},
616 	{"ADC 25 Mux", "DMIC1", "DMIC1"},
617 	{"ADC 25 Mux", "DMIC2", "DMIC2"},
618 	{"ADC 25 Mux", "DMIC3", "DMIC3"},
619 	{"ADC 25 Mux", "DMIC4", "DMIC4"},
620 };
621 
622 static const struct snd_soc_component_driver soc_codec_dev_rt715_sdca = {
623 	.controls = rt715_snd_controls_sdca,
624 	.num_controls = ARRAY_SIZE(rt715_snd_controls_sdca),
625 	.dapm_widgets = rt715_dapm_widgets,
626 	.num_dapm_widgets = ARRAY_SIZE(rt715_dapm_widgets),
627 	.dapm_routes = rt715_audio_map,
628 	.num_dapm_routes = ARRAY_SIZE(rt715_audio_map),
629 };
630 
631 static int rt715_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
632 				int direction)
633 {
634 	struct rt715_sdw_stream_data *stream;
635 
636 	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
637 	if (!stream)
638 		return -ENOMEM;
639 
640 	stream->sdw_stream = sdw_stream;
641 
642 	/* Use tx_mask or rx_mask to configure stream tag and set dma_data */
643 	if (direction == SNDRV_PCM_STREAM_PLAYBACK)
644 		dai->playback_dma_data = stream;
645 	else
646 		dai->capture_dma_data = stream;
647 
648 	return 0;
649 }
650 
651 static void rt715_shutdown(struct snd_pcm_substream *substream,
652 				struct snd_soc_dai *dai)
653 
654 {
655 	struct rt715_sdw_stream_data *stream;
656 
657 	stream = snd_soc_dai_get_dma_data(dai, substream);
658 	if (!stream)
659 		return;
660 
661 	snd_soc_dai_set_dma_data(dai, substream, NULL);
662 	kfree(stream);
663 }
664 
665 static int rt715_pcm_hw_params(struct snd_pcm_substream *substream,
666 				struct snd_pcm_hw_params *params,
667 				struct snd_soc_dai *dai)
668 {
669 	struct snd_soc_component *component = dai->component;
670 	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
671 	struct sdw_stream_config stream_config;
672 	struct sdw_port_config port_config;
673 	enum sdw_data_direction direction;
674 	struct rt715_sdw_stream_data *stream;
675 	int retval, port, num_channels;
676 	unsigned int val;
677 
678 	stream = snd_soc_dai_get_dma_data(dai, substream);
679 
680 	if (!stream)
681 		return -EINVAL;
682 
683 	if (!rt715->slave)
684 		return -EINVAL;
685 
686 	switch (dai->id) {
687 	case RT715_AIF1:
688 		direction = SDW_DATA_DIR_TX;
689 		port = 6;
690 		rt715_index_write(rt715, RT715_VENDOR_REG, RT715_SDW_INPUT_SEL,
691 			0xa500);
692 		break;
693 	case RT715_AIF2:
694 		direction = SDW_DATA_DIR_TX;
695 		port = 4;
696 		rt715_index_write(rt715, RT715_VENDOR_REG, RT715_SDW_INPUT_SEL,
697 			0xaf00);
698 		break;
699 	default:
700 		dev_err(component->dev, "Invalid DAI id %d\n", dai->id);
701 		return -EINVAL;
702 	}
703 
704 	stream_config.frame_rate =  params_rate(params);
705 	stream_config.ch_count = params_channels(params);
706 	stream_config.bps = snd_pcm_format_width(params_format(params));
707 	stream_config.direction = direction;
708 
709 	num_channels = params_channels(params);
710 	port_config.ch_mask = GENMASK(num_channels - 1, 0);
711 	port_config.num = port;
712 
713 	retval = sdw_stream_add_slave(rt715->slave, &stream_config,
714 					&port_config, 1, stream->sdw_stream);
715 	if (retval) {
716 		dev_err(component->dev, "Unable to configure port, retval:%d\n",
717 			retval);
718 		return retval;
719 	}
720 
721 	switch (params_rate(params)) {
722 	case 8000:
723 		val = 0x1;
724 		break;
725 	case 11025:
726 		val = 0x2;
727 		break;
728 	case 12000:
729 		val = 0x3;
730 		break;
731 	case 16000:
732 		val = 0x4;
733 		break;
734 	case 22050:
735 		val = 0x5;
736 		break;
737 	case 24000:
738 		val = 0x6;
739 		break;
740 	case 32000:
741 		val = 0x7;
742 		break;
743 	case 44100:
744 		val = 0x8;
745 		break;
746 	case 48000:
747 		val = 0x9;
748 		break;
749 	case 88200:
750 		val = 0xa;
751 		break;
752 	case 96000:
753 		val = 0xb;
754 		break;
755 	case 176400:
756 		val = 0xc;
757 		break;
758 	case 192000:
759 		val = 0xd;
760 		break;
761 	case 384000:
762 		val = 0xe;
763 		break;
764 	case 768000:
765 		val = 0xf;
766 		break;
767 	default:
768 		dev_err(component->dev, "Unsupported sample rate %d\n",
769 			params_rate(params));
770 		return -EINVAL;
771 	}
772 
773 	regmap_write(rt715->regmap,
774 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CS_FREQ_IND_EN,
775 			RT715_SDCA_FREQ_IND_CTRL, CH_00), val);
776 
777 	return 0;
778 }
779 
780 static int rt715_pcm_hw_free(struct snd_pcm_substream *substream,
781 				struct snd_soc_dai *dai)
782 {
783 	struct snd_soc_component *component = dai->component;
784 	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
785 	struct rt715_sdw_stream_data *stream =
786 		snd_soc_dai_get_dma_data(dai, substream);
787 
788 	if (!rt715->slave)
789 		return -EINVAL;
790 
791 	sdw_stream_remove_slave(rt715->slave, stream->sdw_stream);
792 	return 0;
793 }
794 
795 #define RT715_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
796 #define RT715_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
797 			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
798 
799 static struct snd_soc_dai_ops rt715_ops = {
800 	.hw_params	= rt715_pcm_hw_params,
801 	.hw_free	= rt715_pcm_hw_free,
802 	.set_sdw_stream	= rt715_set_sdw_stream,
803 	.shutdown	= rt715_shutdown,
804 };
805 
806 static struct snd_soc_dai_driver rt715_dai[] = {
807 	{
808 		.name = "rt715-aif1",
809 		.id = RT715_AIF1,
810 		.capture = {
811 			.stream_name = "DP6 Capture",
812 			.channels_min = 1,
813 			.channels_max = 2,
814 			.rates = RT715_STEREO_RATES,
815 			.formats = RT715_FORMATS,
816 		},
817 		.ops = &rt715_ops,
818 	},
819 	{
820 		.name = "rt715-aif2",
821 		.id = RT715_AIF2,
822 		.capture = {
823 			.stream_name = "DP4 Capture",
824 			.channels_min = 1,
825 			.channels_max = 2,
826 			.rates = RT715_STEREO_RATES,
827 			.formats = RT715_FORMATS,
828 		},
829 		.ops = &rt715_ops,
830 	},
831 };
832 
833 /* Bus clock frequency */
834 #define RT715_CLK_FREQ_9600000HZ 9600000
835 #define RT715_CLK_FREQ_12000000HZ 12000000
836 #define RT715_CLK_FREQ_6000000HZ 6000000
837 #define RT715_CLK_FREQ_4800000HZ 4800000
838 #define RT715_CLK_FREQ_2400000HZ 2400000
839 #define RT715_CLK_FREQ_12288000HZ 12288000
840 
841 int rt715_init(struct device *dev, struct regmap *mbq_regmap,
842 	struct regmap *regmap, struct sdw_slave *slave)
843 {
844 	struct rt715_sdca_priv *rt715;
845 	int ret;
846 
847 	rt715 = devm_kzalloc(dev, sizeof(*rt715), GFP_KERNEL);
848 	if (!rt715)
849 		return -ENOMEM;
850 
851 	dev_set_drvdata(dev, rt715);
852 	rt715->slave = slave;
853 	rt715->regmap = regmap;
854 	rt715->mbq_regmap = mbq_regmap;
855 	rt715->hw_sdw_ver = slave->id.sdw_version;
856 	/*
857 	 * Mark hw_init to false
858 	 * HW init will be performed when device reports present
859 	 */
860 	rt715->hw_init = false;
861 	rt715->first_init = false;
862 
863 	ret = devm_snd_soc_register_component(dev,
864 			&soc_codec_dev_rt715_sdca,
865 			rt715_dai,
866 			ARRAY_SIZE(rt715_dai));
867 
868 	return ret;
869 }
870 
871 int rt715_io_init(struct device *dev, struct sdw_slave *slave)
872 {
873 	struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev);
874 	unsigned int hw_ver;
875 
876 	if (rt715->hw_init)
877 		return 0;
878 
879 	/*
880 	 * PM runtime is only enabled when a Slave reports as Attached
881 	 */
882 	if (!rt715->first_init) {
883 		/* set autosuspend parameters */
884 		pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
885 		pm_runtime_use_autosuspend(&slave->dev);
886 
887 		/* update count of parent 'active' children */
888 		pm_runtime_set_active(&slave->dev);
889 
890 		/* make sure the device does not suspend immediately */
891 		pm_runtime_mark_last_busy(&slave->dev);
892 
893 		pm_runtime_enable(&slave->dev);
894 
895 		rt715->first_init = true;
896 	}
897 
898 	pm_runtime_get_noresume(&slave->dev);
899 
900 	rt715_index_read(rt715, RT715_VENDOR_REG,
901 		RT715_PRODUCT_NUM, &hw_ver);
902 	hw_ver = hw_ver & 0x000f;
903 
904 	/* set clock selector = external */
905 	regmap_write(rt715->regmap,
906 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CX_CLK_SEL_EN,
907 			RT715_SDCA_CX_CLK_SEL_CTRL, CH_00), 0x1);
908 	/* set GPIO_4/5/6 to be 3rd/4th DMIC usage */
909 	if (hw_ver == 0x0)
910 		rt715_index_update_bits(rt715, RT715_VENDOR_REG,
911 			RT715_AD_FUNC_EN, 0x54, 0x54);
912 	else if (hw_ver == 0x1) {
913 		rt715_index_update_bits(rt715, RT715_VENDOR_REG,
914 			RT715_AD_FUNC_EN, 0x55, 0x55);
915 		rt715_index_update_bits(rt715, RT715_VENDOR_REG,
916 			RT715_REV_1, 0x40, 0x40);
917 	}
918 	/* trigger mode = VAD enable */
919 	regmap_write(rt715->regmap,
920 		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,
921 			RT715_SDCA_SMPU_TRIG_EN_CTRL, CH_00), 0x2);
922 	/* SMPU-1 interrupt enable mask */
923 	regmap_update_bits(rt715->regmap, RT715_INT_MASK, 0x1, 0x1);
924 
925 	/* Mark Slave initialization complete */
926 	rt715->hw_init = true;
927 
928 	pm_runtime_mark_last_busy(&slave->dev);
929 	pm_runtime_put_autosuspend(&slave->dev);
930 
931 	return 0;
932 }
933 
934 MODULE_DESCRIPTION("ASoC rt715 driver SDW SDCA");
935 MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>");
936 MODULE_LICENSE("GPL v2");
937