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