1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Rockchip machine ASoC driver for boards using MAX98357A/RT5514/DA7219
4  *
5  * Copyright (c) 2016, ROCKCHIP CORPORATION.  All rights reserved.
6  */
7 
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/slab.h>
11 #include <linux/gpio.h>
12 #include <linux/of_gpio.h>
13 #include <linux/delay.h>
14 #include <linux/spi/spi.h>
15 #include <linux/i2c.h>
16 #include <linux/input.h>
17 #include <sound/core.h>
18 #include <sound/jack.h>
19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include "rockchip_i2s.h"
23 #include "../codecs/da7219.h"
24 #include "../codecs/da7219-aad.h"
25 #include "../codecs/rt5514.h"
26 
27 #define DRV_NAME "rk3399-gru-sound"
28 
29 #define SOUND_FS	256
30 
31 static unsigned int dmic_wakeup_delay;
32 
33 static struct snd_soc_jack rockchip_sound_jack;
34 
35 static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = {
36 	SND_SOC_DAPM_HP("Headphones", NULL),
37 	SND_SOC_DAPM_SPK("Speakers", NULL),
38 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
39 	SND_SOC_DAPM_MIC("Int Mic", NULL),
40 	SND_SOC_DAPM_LINE("HDMI", NULL),
41 };
42 
43 static const struct snd_kcontrol_new rockchip_controls[] = {
44 	SOC_DAPM_PIN_SWITCH("Headphones"),
45 	SOC_DAPM_PIN_SWITCH("Speakers"),
46 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
47 	SOC_DAPM_PIN_SWITCH("Int Mic"),
48 	SOC_DAPM_PIN_SWITCH("HDMI"),
49 };
50 
51 static int rockchip_sound_max98357a_hw_params(struct snd_pcm_substream *substream,
52 			     struct snd_pcm_hw_params *params)
53 {
54 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
55 	unsigned int mclk;
56 	int ret;
57 
58 	mclk = params_rate(params) * SOUND_FS;
59 
60 	ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0);
61 	if (ret) {
62 		dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
63 				__func__, mclk, ret);
64 		return ret;
65 	}
66 
67 	return 0;
68 }
69 
70 static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
71 			     struct snd_pcm_hw_params *params)
72 {
73 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
74 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
75 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
76 	unsigned int mclk;
77 	int ret;
78 
79 	mclk = params_rate(params) * SOUND_FS;
80 
81 	ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
82 				     SND_SOC_CLOCK_OUT);
83 	if (ret < 0) {
84 		dev_err(rtd->card->dev, "Can't set cpu clock out %d\n", ret);
85 		return ret;
86 	}
87 
88 	ret = snd_soc_dai_set_sysclk(codec_dai, RT5514_SCLK_S_MCLK,
89 				     mclk, SND_SOC_CLOCK_IN);
90 	if (ret) {
91 		dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
92 				__func__, params_rate(params) * 512, ret);
93 		return ret;
94 	}
95 
96 	/* Wait for DMIC stable */
97 	msleep(dmic_wakeup_delay);
98 
99 	return 0;
100 }
101 
102 static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
103 			     struct snd_pcm_hw_params *params)
104 {
105 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
106 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
107 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
108 	int mclk, ret;
109 
110 	/* in bypass mode, the mclk has to be one of the frequencies below */
111 	switch (params_rate(params)) {
112 	case 8000:
113 	case 16000:
114 	case 24000:
115 	case 32000:
116 	case 48000:
117 	case 64000:
118 	case 96000:
119 		mclk = 12288000;
120 		break;
121 	case 11025:
122 	case 22050:
123 	case 44100:
124 	case 88200:
125 		mclk = 11289600;
126 		break;
127 	default:
128 		return -EINVAL;
129 	}
130 
131 	ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
132 				     SND_SOC_CLOCK_OUT);
133 	if (ret < 0) {
134 		dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret);
135 		return ret;
136 	}
137 
138 	ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
139 				     SND_SOC_CLOCK_IN);
140 	if (ret < 0) {
141 		dev_err(codec_dai->dev, "Can't set codec clock in %d\n", ret);
142 		return ret;
143 	}
144 
145 	ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
146 	if (ret < 0) {
147 		dev_err(codec_dai->dev, "Can't set pll sysclk mclk %d\n", ret);
148 		return ret;
149 	}
150 
151 	return 0;
152 }
153 
154 static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
155 {
156 	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
157 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
158 	int ret;
159 
160 	/* We need default MCLK and PLL settings for the accessory detection */
161 	ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000,
162 				     SND_SOC_CLOCK_IN);
163 	if (ret < 0) {
164 		dev_err(codec_dai->dev, "Init can't set codec clock in %d\n", ret);
165 		return ret;
166 	}
167 
168 	ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
169 	if (ret < 0) {
170 		dev_err(codec_dai->dev, "Init can't set pll sysclk mclk %d\n", ret);
171 		return ret;
172 	}
173 
174 	/* Enable Headset and 4 Buttons Jack detection */
175 	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
176 				    SND_JACK_HEADSET | SND_JACK_LINEOUT |
177 				    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
178 				    SND_JACK_BTN_2 | SND_JACK_BTN_3,
179 				    &rockchip_sound_jack, NULL, 0);
180 
181 	if (ret) {
182 		dev_err(rtd->card->dev, "New Headset Jack failed! (%d)\n", ret);
183 		return ret;
184 	}
185 
186 	snd_jack_set_key(
187 		rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
188 	snd_jack_set_key(
189 		rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
190 	snd_jack_set_key(
191 		rockchip_sound_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
192 	snd_jack_set_key(
193 		rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
194 
195 	da7219_aad_jack_det(component, &rockchip_sound_jack);
196 
197 	return 0;
198 }
199 
200 static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream,
201 			     struct snd_pcm_hw_params *params)
202 {
203 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
204 	unsigned int mclk;
205 	int ret;
206 
207 	mclk = params_rate(params) * SOUND_FS;
208 
209 	ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0);
210 	if (ret) {
211 		dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
212 				__func__, mclk, ret);
213 		return ret;
214 	}
215 
216 	/* Wait for DMIC stable */
217 	msleep(dmic_wakeup_delay);
218 
219 	return 0;
220 }
221 
222 static int rockchip_sound_startup(struct snd_pcm_substream *substream)
223 {
224 	struct snd_pcm_runtime *runtime = substream->runtime;
225 
226 	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
227 	return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
228 			8000, 96000);
229 }
230 
231 static const struct snd_soc_ops rockchip_sound_max98357a_ops = {
232 	.startup = rockchip_sound_startup,
233 	.hw_params = rockchip_sound_max98357a_hw_params,
234 };
235 
236 static const struct snd_soc_ops rockchip_sound_rt5514_ops = {
237 	.startup = rockchip_sound_startup,
238 	.hw_params = rockchip_sound_rt5514_hw_params,
239 };
240 
241 static const struct snd_soc_ops rockchip_sound_da7219_ops = {
242 	.startup = rockchip_sound_startup,
243 	.hw_params = rockchip_sound_da7219_hw_params,
244 };
245 
246 static const struct snd_soc_ops rockchip_sound_dmic_ops = {
247 	.startup = rockchip_sound_startup,
248 	.hw_params = rockchip_sound_dmic_hw_params,
249 };
250 
251 static struct snd_soc_card rockchip_sound_card = {
252 	.name = "rk3399-gru-sound",
253 	.owner = THIS_MODULE,
254 	.dapm_widgets = rockchip_dapm_widgets,
255 	.num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets),
256 	.controls = rockchip_controls,
257 	.num_controls = ARRAY_SIZE(rockchip_controls),
258 };
259 
260 enum {
261 	DAILINK_CDNDP,
262 	DAILINK_DA7219,
263 	DAILINK_DMIC,
264 	DAILINK_MAX98357A,
265 	DAILINK_RT5514,
266 	DAILINK_RT5514_DSP,
267 };
268 
269 SND_SOC_DAILINK_DEFS(cdndp,
270 	DAILINK_COMP_ARRAY(COMP_EMPTY()),
271 	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "spdif-hifi")),
272 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
273 
274 SND_SOC_DAILINK_DEFS(da7219,
275 	DAILINK_COMP_ARRAY(COMP_EMPTY()),
276 	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "da7219-hifi")),
277 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
278 
279 SND_SOC_DAILINK_DEFS(dmic,
280 	DAILINK_COMP_ARRAY(COMP_EMPTY()),
281 	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "dmic-hifi")),
282 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
283 
284 SND_SOC_DAILINK_DEFS(max98357a,
285 	DAILINK_COMP_ARRAY(COMP_EMPTY()),
286 	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "HiFi")),
287 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
288 
289 SND_SOC_DAILINK_DEFS(rt5514,
290 	DAILINK_COMP_ARRAY(COMP_EMPTY()),
291 	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "rt5514-aif1")),
292 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
293 
294 SND_SOC_DAILINK_DEFS(rt5514_dsp,
295 	DAILINK_COMP_ARRAY(COMP_EMPTY()),
296 	DAILINK_COMP_ARRAY(COMP_DUMMY()),
297 	DAILINK_COMP_ARRAY(COMP_EMPTY()));
298 
299 static const struct snd_soc_dai_link rockchip_dais[] = {
300 	[DAILINK_CDNDP] = {
301 		.name = "DP",
302 		.stream_name = "DP PCM",
303 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
304 			SND_SOC_DAIFMT_CBS_CFS,
305 		SND_SOC_DAILINK_REG(cdndp),
306 	},
307 	[DAILINK_DA7219] = {
308 		.name = "DA7219",
309 		.stream_name = "DA7219 PCM",
310 		.init = rockchip_sound_da7219_init,
311 		.ops = &rockchip_sound_da7219_ops,
312 		/* set da7219 as slave */
313 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
314 			SND_SOC_DAIFMT_CBS_CFS,
315 		SND_SOC_DAILINK_REG(da7219),
316 	},
317 	[DAILINK_DMIC] = {
318 		.name = "DMIC",
319 		.stream_name = "DMIC PCM",
320 		.ops = &rockchip_sound_dmic_ops,
321 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
322 			SND_SOC_DAIFMT_CBS_CFS,
323 		SND_SOC_DAILINK_REG(dmic),
324 	},
325 	[DAILINK_MAX98357A] = {
326 		.name = "MAX98357A",
327 		.stream_name = "MAX98357A PCM",
328 		.ops = &rockchip_sound_max98357a_ops,
329 		/* set max98357a as slave */
330 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
331 			SND_SOC_DAIFMT_CBS_CFS,
332 		SND_SOC_DAILINK_REG(max98357a),
333 	},
334 	[DAILINK_RT5514] = {
335 		.name = "RT5514",
336 		.stream_name = "RT5514 PCM",
337 		.ops = &rockchip_sound_rt5514_ops,
338 		/* set rt5514 as slave */
339 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
340 			SND_SOC_DAIFMT_CBS_CFS,
341 		SND_SOC_DAILINK_REG(rt5514),
342 	},
343 	/* RT5514 DSP for voice wakeup via spi bus */
344 	[DAILINK_RT5514_DSP] = {
345 		.name = "RT5514 DSP",
346 		.stream_name = "Wake on Voice",
347 		SND_SOC_DAILINK_REG(rt5514_dsp),
348 	},
349 };
350 
351 static const struct snd_soc_dapm_route rockchip_sound_cdndp_routes[] = {
352 	/* Output */
353 	{"HDMI", NULL, "TX"},
354 };
355 
356 static const struct snd_soc_dapm_route rockchip_sound_da7219_routes[] = {
357 	/* Output */
358 	{"Headphones", NULL, "HPL"},
359 	{"Headphones", NULL, "HPR"},
360 
361 	/* Input */
362 	{"MIC", NULL, "Headset Mic"},
363 };
364 
365 static const struct snd_soc_dapm_route rockchip_sound_dmic_routes[] = {
366 	/* Input */
367 	{"DMic", NULL, "Int Mic"},
368 };
369 
370 static const struct snd_soc_dapm_route rockchip_sound_max98357a_routes[] = {
371 	/* Output */
372 	{"Speakers", NULL, "Speaker"},
373 };
374 
375 static const struct snd_soc_dapm_route rockchip_sound_rt5514_routes[] = {
376 	/* Input */
377 	{"DMIC1L", NULL, "Int Mic"},
378 	{"DMIC1R", NULL, "Int Mic"},
379 };
380 
381 struct rockchip_sound_route {
382 	const struct snd_soc_dapm_route *routes;
383 	int num_routes;
384 };
385 
386 static const struct rockchip_sound_route rockchip_routes[] = {
387 	[DAILINK_CDNDP] = {
388 		.routes = rockchip_sound_cdndp_routes,
389 		.num_routes = ARRAY_SIZE(rockchip_sound_cdndp_routes),
390 	},
391 	[DAILINK_DA7219] = {
392 		.routes = rockchip_sound_da7219_routes,
393 		.num_routes = ARRAY_SIZE(rockchip_sound_da7219_routes),
394 	},
395 	[DAILINK_DMIC] = {
396 		.routes = rockchip_sound_dmic_routes,
397 		.num_routes = ARRAY_SIZE(rockchip_sound_dmic_routes),
398 	},
399 	[DAILINK_MAX98357A] = {
400 		.routes = rockchip_sound_max98357a_routes,
401 		.num_routes = ARRAY_SIZE(rockchip_sound_max98357a_routes),
402 	},
403 	[DAILINK_RT5514] = {
404 		.routes = rockchip_sound_rt5514_routes,
405 		.num_routes = ARRAY_SIZE(rockchip_sound_rt5514_routes),
406 	},
407 	[DAILINK_RT5514_DSP] = {},
408 };
409 
410 struct dailink_match_data {
411 	const char *compatible;
412 	struct bus_type *bus_type;
413 };
414 
415 static const struct dailink_match_data dailink_match[] = {
416 	[DAILINK_CDNDP] = {
417 		.compatible = "rockchip,rk3399-cdn-dp",
418 	},
419 	[DAILINK_DA7219] = {
420 		.compatible = "dlg,da7219",
421 	},
422 	[DAILINK_DMIC] = {
423 		.compatible = "dmic-codec",
424 	},
425 	[DAILINK_MAX98357A] = {
426 		.compatible = "maxim,max98357a",
427 	},
428 	[DAILINK_RT5514] = {
429 		.compatible = "realtek,rt5514",
430 		.bus_type = &i2c_bus_type,
431 	},
432 	[DAILINK_RT5514_DSP] = {
433 		.compatible = "realtek,rt5514",
434 		.bus_type = &spi_bus_type,
435 	},
436 };
437 
438 static int rockchip_sound_codec_node_match(struct device_node *np_codec)
439 {
440 	struct device *dev;
441 	int i;
442 
443 	for (i = 0; i < ARRAY_SIZE(dailink_match); i++) {
444 		if (!of_device_is_compatible(np_codec,
445 					     dailink_match[i].compatible))
446 			continue;
447 
448 		if (dailink_match[i].bus_type) {
449 			dev = bus_find_device_by_of_node(dailink_match[i].bus_type,
450 							 np_codec);
451 			if (!dev)
452 				continue;
453 			put_device(dev);
454 		}
455 
456 		return i;
457 	}
458 	return -1;
459 }
460 
461 static int rockchip_sound_of_parse_dais(struct device *dev,
462 					struct snd_soc_card *card)
463 {
464 	struct device_node *np_cpu, *np_cpu0, *np_cpu1;
465 	struct device_node *np_codec;
466 	struct snd_soc_dai_link *dai;
467 	struct snd_soc_dapm_route *routes;
468 	int i, index;
469 	int num_routes;
470 
471 	card->dai_link = devm_kzalloc(dev, sizeof(rockchip_dais),
472 				      GFP_KERNEL);
473 	if (!card->dai_link)
474 		return -ENOMEM;
475 
476 	num_routes = 0;
477 	for (i = 0; i < ARRAY_SIZE(rockchip_routes); i++)
478 		num_routes += rockchip_routes[i].num_routes;
479 	routes = devm_kcalloc(dev, num_routes, sizeof(*routes),
480 			      GFP_KERNEL);
481 	if (!routes)
482 		return -ENOMEM;
483 	card->dapm_routes = routes;
484 
485 	np_cpu0 = of_parse_phandle(dev->of_node, "rockchip,cpu", 0);
486 	np_cpu1 = of_parse_phandle(dev->of_node, "rockchip,cpu", 1);
487 
488 	card->num_dapm_routes = 0;
489 	card->num_links = 0;
490 	for (i = 0; i < ARRAY_SIZE(rockchip_dais); i++) {
491 		np_codec = of_parse_phandle(dev->of_node,
492 					    "rockchip,codec", i);
493 		if (!np_codec)
494 			break;
495 
496 		if (!of_device_is_available(np_codec))
497 			continue;
498 
499 		index = rockchip_sound_codec_node_match(np_codec);
500 		if (index < 0)
501 			continue;
502 
503 		switch (index) {
504 		case DAILINK_CDNDP:
505 			np_cpu = np_cpu1;
506 			break;
507 		case DAILINK_RT5514_DSP:
508 			np_cpu = np_codec;
509 			break;
510 		default:
511 			np_cpu = np_cpu0;
512 			break;
513 		}
514 
515 		if (!np_cpu) {
516 			dev_err(dev, "Missing 'rockchip,cpu' for %s\n",
517 				rockchip_dais[index].name);
518 			return -EINVAL;
519 		}
520 
521 		dai = &card->dai_link[card->num_links++];
522 		*dai = rockchip_dais[index];
523 
524 		if (!dai->codecs->name)
525 			dai->codecs->of_node = np_codec;
526 		dai->platforms->of_node = np_cpu;
527 		dai->cpus->of_node = np_cpu;
528 
529 		if (card->num_dapm_routes + rockchip_routes[index].num_routes >
530 		    num_routes) {
531 			dev_err(dev, "Too many routes\n");
532 			return -EINVAL;
533 		}
534 
535 		memcpy(routes + card->num_dapm_routes,
536 		       rockchip_routes[index].routes,
537 		       rockchip_routes[index].num_routes * sizeof(*routes));
538 		card->num_dapm_routes += rockchip_routes[index].num_routes;
539 	}
540 
541 	return 0;
542 }
543 
544 static int rockchip_sound_probe(struct platform_device *pdev)
545 {
546 	struct snd_soc_card *card = &rockchip_sound_card;
547 	int ret;
548 
549 	ret = rockchip_sound_of_parse_dais(&pdev->dev, card);
550 	if (ret < 0) {
551 		dev_err(&pdev->dev, "Failed to parse dais: %d\n", ret);
552 		return ret;
553 	}
554 
555 	/* Set DMIC wakeup delay */
556 	ret = device_property_read_u32(&pdev->dev, "dmic-wakeup-delay-ms",
557 					&dmic_wakeup_delay);
558 	if (ret) {
559 		dmic_wakeup_delay = 0;
560 		dev_dbg(&pdev->dev,
561 			"no optional property 'dmic-wakeup-delay-ms' found, default: no delay\n");
562 	}
563 
564 	card->dev = &pdev->dev;
565 	return devm_snd_soc_register_card(&pdev->dev, card);
566 }
567 
568 static const struct of_device_id rockchip_sound_of_match[] = {
569 	{ .compatible = "rockchip,rk3399-gru-sound", },
570 	{},
571 };
572 
573 static struct platform_driver rockchip_sound_driver = {
574 	.probe = rockchip_sound_probe,
575 	.driver = {
576 		.name = DRV_NAME,
577 		.of_match_table = rockchip_sound_of_match,
578 #ifdef CONFIG_PM
579 		.pm = &snd_soc_pm_ops,
580 #endif
581 	},
582 };
583 
584 module_platform_driver(rockchip_sound_driver);
585 
586 MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>");
587 MODULE_DESCRIPTION("Rockchip ASoC Machine Driver");
588 MODULE_LICENSE("GPL v2");
589 MODULE_ALIAS("platform:" DRV_NAME);
590 MODULE_DEVICE_TABLE(of, rockchip_sound_of_match);
591