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