1// SPDX-License-Identifier: GPL-2.0
2//
3// mt8183-da7219-max98357.c
4//	--  MT8183-DA7219-MAX98357 ALSA SoC machine driver
5//
6// Copyright (c) 2018 MediaTek Inc.
7// Author: Shunli Wang <shunli.wang@mediatek.com>
8
9#include <linux/input.h>
10#include <linux/module.h>
11#include <linux/of_device.h>
12#include <linux/pinctrl/consumer.h>
13#include <sound/jack.h>
14#include <sound/pcm_params.h>
15#include <sound/soc.h>
16
17#include "../../codecs/da7219-aad.h"
18#include "../../codecs/da7219.h"
19#include "../../codecs/rt1015.h"
20#include "mt8183-afe-common.h"
21
22#define DA7219_CODEC_DAI "da7219-hifi"
23#define DA7219_DEV_NAME "da7219.5-001a"
24#define RT1015_CODEC_DAI "rt1015-aif"
25#define RT1015_DEV0_NAME "rt1015.6-0028"
26#define RT1015_DEV1_NAME "rt1015.6-0029"
27
28struct mt8183_da7219_max98357_priv {
29	struct snd_soc_jack headset_jack, hdmi_jack;
30};
31
32static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
33				       struct snd_pcm_hw_params *params)
34{
35	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
36	unsigned int rate = params_rate(params);
37	unsigned int mclk_fs_ratio = 128;
38	unsigned int mclk_fs = rate * mclk_fs_ratio;
39
40	return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0),
41				      0, mclk_fs, SND_SOC_CLOCK_OUT);
42}
43
44static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
45	.hw_params = mt8183_mt6358_i2s_hw_params,
46};
47
48static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
49				       struct snd_pcm_hw_params *params)
50{
51	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
52	struct snd_soc_dai *codec_dai;
53	unsigned int rate = params_rate(params);
54	unsigned int mclk_fs_ratio = 256;
55	unsigned int mclk_fs = rate * mclk_fs_ratio;
56	unsigned int freq;
57	int ret = 0, j;
58
59	ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
60				     mclk_fs, SND_SOC_CLOCK_OUT);
61	if (ret < 0)
62		dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
63
64	for_each_rtd_codec_dais(rtd, j, codec_dai) {
65		if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
66			ret = snd_soc_dai_set_sysclk(codec_dai,
67						     DA7219_CLKSRC_MCLK,
68						     mclk_fs,
69						     SND_SOC_CLOCK_IN);
70			if (ret < 0)
71				dev_err(rtd->dev, "failed to set sysclk\n");
72
73			if ((rate % 8000) == 0)
74				freq = DA7219_PLL_FREQ_OUT_98304;
75			else
76				freq = DA7219_PLL_FREQ_OUT_90316;
77
78			ret = snd_soc_dai_set_pll(codec_dai, 0,
79						  DA7219_SYSCLK_PLL_SRM,
80						  0, freq);
81			if (ret)
82				dev_err(rtd->dev, "failed to start PLL: %d\n",
83					ret);
84		}
85	}
86
87	return ret;
88}
89
90static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream)
91{
92	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
93	struct snd_soc_dai *codec_dai;
94	int ret = 0, j;
95
96	for_each_rtd_codec_dais(rtd, j, codec_dai) {
97		if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
98			ret = snd_soc_dai_set_pll(codec_dai,
99						  0, DA7219_SYSCLK_MCLK, 0, 0);
100			if (ret < 0) {
101				dev_err(rtd->dev, "failed to stop PLL: %d\n",
102					ret);
103				break;
104			}
105		}
106	}
107
108	return ret;
109}
110
111static const struct snd_soc_ops mt8183_da7219_i2s_ops = {
112	.hw_params = mt8183_da7219_i2s_hw_params,
113	.hw_free = mt8183_da7219_hw_free,
114};
115
116static int
117mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream,
118				   struct snd_pcm_hw_params *params)
119{
120	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
121	unsigned int rate = params_rate(params);
122	struct snd_soc_dai *codec_dai;
123	int ret = 0, i;
124
125	for_each_rtd_codec_dais(rtd, i, codec_dai) {
126		if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) ||
127		    !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) {
128			ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
129			if (ret) {
130				dev_err(rtd->dev, "failed to set bclk ratio\n");
131				return ret;
132			}
133
134			ret = snd_soc_dai_set_pll(codec_dai, 0,
135						  RT1015_PLL_S_BCLK,
136						  rate * 64, rate * 256);
137			if (ret) {
138				dev_err(rtd->dev, "failed to set pll\n");
139				return ret;
140			}
141
142			ret = snd_soc_dai_set_sysclk(codec_dai,
143						     RT1015_SCLK_S_PLL,
144						     rate * 256,
145						     SND_SOC_CLOCK_IN);
146			if (ret) {
147				dev_err(rtd->dev, "failed to set sysclk\n");
148				return ret;
149			}
150		}
151	}
152
153	return mt8183_da7219_i2s_hw_params(substream, params);
154}
155
156static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = {
157	.hw_params = mt8183_da7219_rt1015_i2s_hw_params,
158	.hw_free = mt8183_da7219_hw_free,
159};
160
161static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
162				      struct snd_pcm_hw_params *params)
163{
164	/* fix BE i2s format to 32bit, clean param mask first */
165	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
166			     0, SNDRV_PCM_FORMAT_LAST);
167
168	params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
169
170	return 0;
171}
172
173static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
174					     struct snd_pcm_hw_params *params)
175{
176	/* fix BE i2s format to 32bit, clean param mask first */
177	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
178			     0, SNDRV_PCM_FORMAT_LAST);
179
180	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
181
182	return 0;
183}
184
185static int
186mt8183_da7219_max98357_startup(
187	struct snd_pcm_substream *substream)
188{
189	static const unsigned int rates[] = {
190		48000,
191	};
192	static const struct snd_pcm_hw_constraint_list constraints_rates = {
193		.count = ARRAY_SIZE(rates),
194		.list  = rates,
195		.mask = 0,
196	};
197	static const unsigned int channels[] = {
198		2,
199	};
200	static const struct snd_pcm_hw_constraint_list constraints_channels = {
201		.count = ARRAY_SIZE(channels),
202		.list = channels,
203		.mask = 0,
204	};
205
206	struct snd_pcm_runtime *runtime = substream->runtime;
207
208	snd_pcm_hw_constraint_list(runtime, 0,
209			SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
210	runtime->hw.channels_max = 2;
211	snd_pcm_hw_constraint_list(runtime, 0,
212			SNDRV_PCM_HW_PARAM_CHANNELS,
213			&constraints_channels);
214
215	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
216	snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
217
218	return 0;
219}
220
221static const struct snd_soc_ops mt8183_da7219_max98357_ops = {
222	.startup = mt8183_da7219_max98357_startup,
223};
224
225static int
226mt8183_da7219_max98357_bt_sco_startup(
227	struct snd_pcm_substream *substream)
228{
229	static const unsigned int rates[] = {
230		8000, 16000
231	};
232	static const struct snd_pcm_hw_constraint_list constraints_rates = {
233		.count = ARRAY_SIZE(rates),
234		.list  = rates,
235		.mask = 0,
236	};
237	static const unsigned int channels[] = {
238		1,
239	};
240	static const struct snd_pcm_hw_constraint_list constraints_channels = {
241		.count = ARRAY_SIZE(channels),
242		.list = channels,
243		.mask = 0,
244	};
245
246	struct snd_pcm_runtime *runtime = substream->runtime;
247
248	snd_pcm_hw_constraint_list(runtime, 0,
249			SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
250	runtime->hw.channels_max = 1;
251	snd_pcm_hw_constraint_list(runtime, 0,
252			SNDRV_PCM_HW_PARAM_CHANNELS,
253			&constraints_channels);
254
255	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
256	snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
257
258	return 0;
259}
260
261static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = {
262	.startup = mt8183_da7219_max98357_bt_sco_startup,
263};
264
265/* FE */
266SND_SOC_DAILINK_DEFS(playback1,
267	DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
268	DAILINK_COMP_ARRAY(COMP_DUMMY()),
269	DAILINK_COMP_ARRAY(COMP_EMPTY()));
270
271SND_SOC_DAILINK_DEFS(playback2,
272	DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
273	DAILINK_COMP_ARRAY(COMP_DUMMY()),
274	DAILINK_COMP_ARRAY(COMP_EMPTY()));
275
276SND_SOC_DAILINK_DEFS(playback3,
277	DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
278	DAILINK_COMP_ARRAY(COMP_DUMMY()),
279	DAILINK_COMP_ARRAY(COMP_EMPTY()));
280
281SND_SOC_DAILINK_DEFS(capture1,
282	DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
283	DAILINK_COMP_ARRAY(COMP_DUMMY()),
284	DAILINK_COMP_ARRAY(COMP_EMPTY()));
285
286SND_SOC_DAILINK_DEFS(capture2,
287	DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
288	DAILINK_COMP_ARRAY(COMP_DUMMY()),
289	DAILINK_COMP_ARRAY(COMP_EMPTY()));
290
291SND_SOC_DAILINK_DEFS(capture3,
292	DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
293	DAILINK_COMP_ARRAY(COMP_DUMMY()),
294	DAILINK_COMP_ARRAY(COMP_EMPTY()));
295
296SND_SOC_DAILINK_DEFS(capture_mono,
297	DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
298	DAILINK_COMP_ARRAY(COMP_DUMMY()),
299	DAILINK_COMP_ARRAY(COMP_EMPTY()));
300
301SND_SOC_DAILINK_DEFS(playback_hdmi,
302	DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
303	DAILINK_COMP_ARRAY(COMP_DUMMY()),
304	DAILINK_COMP_ARRAY(COMP_EMPTY()));
305
306/* BE */
307SND_SOC_DAILINK_DEFS(primary_codec,
308	DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
309	DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
310	DAILINK_COMP_ARRAY(COMP_EMPTY()));
311
312SND_SOC_DAILINK_DEFS(pcm1,
313	DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
314	DAILINK_COMP_ARRAY(COMP_DUMMY()),
315	DAILINK_COMP_ARRAY(COMP_EMPTY()));
316
317SND_SOC_DAILINK_DEFS(pcm2,
318	DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
319	DAILINK_COMP_ARRAY(COMP_DUMMY()),
320	DAILINK_COMP_ARRAY(COMP_EMPTY()));
321
322SND_SOC_DAILINK_DEFS(i2s0,
323	DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
324	DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
325	DAILINK_COMP_ARRAY(COMP_EMPTY()));
326
327SND_SOC_DAILINK_DEFS(i2s1,
328	DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
329	DAILINK_COMP_ARRAY(COMP_DUMMY()),
330	DAILINK_COMP_ARRAY(COMP_EMPTY()));
331
332SND_SOC_DAILINK_DEFS(i2s2,
333	DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
334	DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
335	DAILINK_COMP_ARRAY(COMP_EMPTY()));
336
337SND_SOC_DAILINK_DEFS(i2s3_max98357a,
338	DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
339	DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"),
340			   COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
341	DAILINK_COMP_ARRAY(COMP_EMPTY()));
342
343SND_SOC_DAILINK_DEFS(i2s3_rt1015,
344	DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
345	DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI),
346			   COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI),
347			   COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
348	DAILINK_COMP_ARRAY(COMP_EMPTY()));
349
350SND_SOC_DAILINK_DEFS(i2s3_rt1015p,
351	DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
352	DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"),
353			   COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
354	DAILINK_COMP_ARRAY(COMP_EMPTY()));
355
356SND_SOC_DAILINK_DEFS(i2s5,
357	DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
358	DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
359	DAILINK_COMP_ARRAY(COMP_EMPTY()));
360
361SND_SOC_DAILINK_DEFS(tdm,
362	DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
363	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),
364	DAILINK_COMP_ARRAY(COMP_EMPTY()));
365
366static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
367{
368	struct mt8183_da7219_max98357_priv *priv =
369		snd_soc_card_get_drvdata(rtd->card);
370	int ret;
371
372	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
373				    &priv->hdmi_jack, NULL, 0);
374	if (ret)
375		return ret;
376
377	return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component,
378					  &priv->hdmi_jack, NULL);
379}
380
381static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
382	/* FE */
383	{
384		.name = "Playback_1",
385		.stream_name = "Playback_1",
386		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
387			    SND_SOC_DPCM_TRIGGER_PRE},
388		.dynamic = 1,
389		.dpcm_playback = 1,
390		.ops = &mt8183_da7219_max98357_ops,
391		SND_SOC_DAILINK_REG(playback1),
392	},
393	{
394		.name = "Playback_2",
395		.stream_name = "Playback_2",
396		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
397			    SND_SOC_DPCM_TRIGGER_PRE},
398		.dynamic = 1,
399		.dpcm_playback = 1,
400		.ops = &mt8183_da7219_max98357_bt_sco_ops,
401		SND_SOC_DAILINK_REG(playback2),
402	},
403	{
404		.name = "Playback_3",
405		.stream_name = "Playback_3",
406		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
407			    SND_SOC_DPCM_TRIGGER_PRE},
408		.dynamic = 1,
409		.dpcm_playback = 1,
410		SND_SOC_DAILINK_REG(playback3),
411	},
412	{
413		.name = "Capture_1",
414		.stream_name = "Capture_1",
415		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
416			    SND_SOC_DPCM_TRIGGER_PRE},
417		.dynamic = 1,
418		.dpcm_capture = 1,
419		.ops = &mt8183_da7219_max98357_bt_sco_ops,
420		SND_SOC_DAILINK_REG(capture1),
421	},
422	{
423		.name = "Capture_2",
424		.stream_name = "Capture_2",
425		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
426			    SND_SOC_DPCM_TRIGGER_PRE},
427		.dynamic = 1,
428		.dpcm_capture = 1,
429		SND_SOC_DAILINK_REG(capture2),
430	},
431	{
432		.name = "Capture_3",
433		.stream_name = "Capture_3",
434		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
435			    SND_SOC_DPCM_TRIGGER_PRE},
436		.dynamic = 1,
437		.dpcm_capture = 1,
438		.ops = &mt8183_da7219_max98357_ops,
439		SND_SOC_DAILINK_REG(capture3),
440	},
441	{
442		.name = "Capture_Mono_1",
443		.stream_name = "Capture_Mono_1",
444		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
445			    SND_SOC_DPCM_TRIGGER_PRE},
446		.dynamic = 1,
447		.dpcm_capture = 1,
448		SND_SOC_DAILINK_REG(capture_mono),
449	},
450	{
451		.name = "Playback_HDMI",
452		.stream_name = "Playback_HDMI",
453		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
454			    SND_SOC_DPCM_TRIGGER_PRE},
455		.dynamic = 1,
456		.dpcm_playback = 1,
457		SND_SOC_DAILINK_REG(playback_hdmi),
458	},
459	/* BE */
460	{
461		.name = "Primary Codec",
462		.no_pcm = 1,
463		.dpcm_playback = 1,
464		.dpcm_capture = 1,
465		.ignore_suspend = 1,
466		SND_SOC_DAILINK_REG(primary_codec),
467	},
468	{
469		.name = "PCM 1",
470		.no_pcm = 1,
471		.dpcm_playback = 1,
472		.dpcm_capture = 1,
473		.ignore_suspend = 1,
474		SND_SOC_DAILINK_REG(pcm1),
475	},
476	{
477		.name = "PCM 2",
478		.no_pcm = 1,
479		.dpcm_playback = 1,
480		.dpcm_capture = 1,
481		.ignore_suspend = 1,
482		SND_SOC_DAILINK_REG(pcm2),
483	},
484	{
485		.name = "I2S0",
486		.no_pcm = 1,
487		.dpcm_capture = 1,
488		.ignore_suspend = 1,
489		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
490		.ops = &mt8183_mt6358_i2s_ops,
491		SND_SOC_DAILINK_REG(i2s0),
492	},
493	{
494		.name = "I2S1",
495		.no_pcm = 1,
496		.dpcm_playback = 1,
497		.ignore_suspend = 1,
498		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
499		.ops = &mt8183_mt6358_i2s_ops,
500		SND_SOC_DAILINK_REG(i2s1),
501	},
502	{
503		.name = "I2S2",
504		.no_pcm = 1,
505		.dpcm_capture = 1,
506		.ignore_suspend = 1,
507		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
508		.ops = &mt8183_da7219_i2s_ops,
509		SND_SOC_DAILINK_REG(i2s2),
510	},
511	{
512		.name = "I2S3",
513		.no_pcm = 1,
514		.dpcm_playback = 1,
515		.ignore_suspend = 1,
516	},
517	{
518		.name = "I2S5",
519		.no_pcm = 1,
520		.dpcm_playback = 1,
521		.ignore_suspend = 1,
522		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
523		.ops = &mt8183_mt6358_i2s_ops,
524		SND_SOC_DAILINK_REG(i2s5),
525	},
526	{
527		.name = "TDM",
528		.no_pcm = 1,
529		.dai_fmt = SND_SOC_DAIFMT_I2S |
530			   SND_SOC_DAIFMT_IB_IF |
531			   SND_SOC_DAIFMT_CBM_CFM,
532		.dpcm_playback = 1,
533		.ignore_suspend = 1,
534		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
535		.ignore = 1,
536		.init = mt8183_da7219_max98357_hdmi_init,
537		SND_SOC_DAILINK_REG(tdm),
538	},
539};
540
541static int
542mt8183_da7219_max98357_headset_init(struct snd_soc_component *component)
543{
544	int ret;
545	struct mt8183_da7219_max98357_priv *priv =
546			snd_soc_card_get_drvdata(component->card);
547
548	/* Enable Headset and 4 Buttons Jack detection */
549	ret = snd_soc_card_jack_new(component->card,
550				    "Headset Jack",
551				    SND_JACK_HEADSET |
552				    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
553				    SND_JACK_BTN_2 | SND_JACK_BTN_3 |
554				    SND_JACK_LINEOUT,
555				    &priv->headset_jack,
556				    NULL, 0);
557	if (ret)
558		return ret;
559
560	snd_jack_set_key(
561		priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
562	snd_jack_set_key(
563		priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
564	snd_jack_set_key(
565		priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
566	snd_jack_set_key(
567		priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
568
569	da7219_aad_jack_det(component, &priv->headset_jack);
570
571	return 0;
572}
573
574static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {
575	.dlc = COMP_EMPTY(),
576	.init = mt8183_da7219_max98357_headset_init,
577};
578
579static struct snd_soc_codec_conf mt6358_codec_conf[] = {
580	{
581		.dlc = COMP_CODEC_CONF("mt6358-sound"),
582		.name_prefix = "Mt6358",
583	},
584};
585
586static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = {
587	SOC_DAPM_PIN_SWITCH("Speakers"),
588};
589
590static const
591struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = {
592	SND_SOC_DAPM_SPK("Speakers", NULL),
593	SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
594			     "aud_tdm_out_on", "aud_tdm_out_off"),
595};
596
597static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = {
598	{"Speakers", NULL, "Speaker"},
599	{"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
600};
601
602static struct snd_soc_card mt8183_da7219_max98357_card = {
603	.name = "mt8183_da7219_max98357",
604	.owner = THIS_MODULE,
605	.controls = mt8183_da7219_max98357_snd_controls,
606	.num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
607	.dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
608	.num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
609	.dapm_routes = mt8183_da7219_max98357_dapm_routes,
610	.num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
611	.dai_link = mt8183_da7219_dai_links,
612	.num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
613	.aux_dev = &mt8183_da7219_max98357_headset_dev,
614	.num_aux_devs = 1,
615	.codec_conf = mt6358_codec_conf,
616	.num_configs = ARRAY_SIZE(mt6358_codec_conf),
617};
618
619static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = {
620	{
621		.dlc = COMP_CODEC_CONF("mt6358-sound"),
622		.name_prefix = "Mt6358",
623	},
624	{
625		.dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
626		.name_prefix = "Left",
627	},
628	{
629		.dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
630		.name_prefix = "Right",
631	},
632};
633
634static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = {
635	SOC_DAPM_PIN_SWITCH("Left Spk"),
636	SOC_DAPM_PIN_SWITCH("Right Spk"),
637};
638
639static const
640struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = {
641	SND_SOC_DAPM_SPK("Left Spk", NULL),
642	SND_SOC_DAPM_SPK("Right Spk", NULL),
643	SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
644			     "aud_tdm_out_on", "aud_tdm_out_off"),
645};
646
647static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = {
648	{"Left Spk", NULL, "Left SPO"},
649	{"Right Spk", NULL, "Right SPO"},
650	{"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
651};
652
653static struct snd_soc_card mt8183_da7219_rt1015_card = {
654	.name = "mt8183_da7219_rt1015",
655	.owner = THIS_MODULE,
656	.controls = mt8183_da7219_rt1015_snd_controls,
657	.num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls),
658	.dapm_widgets = mt8183_da7219_rt1015_dapm_widgets,
659	.num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets),
660	.dapm_routes = mt8183_da7219_rt1015_dapm_routes,
661	.num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes),
662	.dai_link = mt8183_da7219_dai_links,
663	.num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
664	.aux_dev = &mt8183_da7219_max98357_headset_dev,
665	.num_aux_devs = 1,
666	.codec_conf = mt8183_da7219_rt1015_codec_conf,
667	.num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf),
668};
669
670static struct snd_soc_card mt8183_da7219_rt1015p_card = {
671	.name = "mt8183_da7219_rt1015p",
672	.owner = THIS_MODULE,
673	.controls = mt8183_da7219_max98357_snd_controls,
674	.num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
675	.dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
676	.num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
677	.dapm_routes = mt8183_da7219_max98357_dapm_routes,
678	.num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
679	.dai_link = mt8183_da7219_dai_links,
680	.num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
681	.aux_dev = &mt8183_da7219_max98357_headset_dev,
682	.num_aux_devs = 1,
683	.codec_conf = mt6358_codec_conf,
684	.num_configs = ARRAY_SIZE(mt6358_codec_conf),
685};
686
687static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
688{
689	struct snd_soc_card *card;
690	struct device_node *platform_node, *hdmi_codec;
691	struct snd_soc_dai_link *dai_link;
692	struct mt8183_da7219_max98357_priv *priv;
693	struct pinctrl *pinctrl;
694	const struct of_device_id *match;
695	int ret, i;
696
697	platform_node = of_parse_phandle(pdev->dev.of_node,
698					 "mediatek,platform", 0);
699	if (!platform_node) {
700		dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
701		return -EINVAL;
702	}
703
704	match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev);
705	if (!match || !match->data)
706		return -EINVAL;
707
708	card = (struct snd_soc_card *)match->data;
709	card->dev = &pdev->dev;
710
711	hdmi_codec = of_parse_phandle(pdev->dev.of_node,
712				      "mediatek,hdmi-codec", 0);
713
714	for_each_card_prelinks(card, i, dai_link) {
715		if (strcmp(dai_link->name, "I2S3") == 0) {
716			if (card == &mt8183_da7219_max98357_card) {
717				dai_link->be_hw_params_fixup =
718					mt8183_i2s_hw_params_fixup;
719				dai_link->ops = &mt8183_da7219_i2s_ops;
720				dai_link->cpus = i2s3_max98357a_cpus;
721				dai_link->num_cpus =
722					ARRAY_SIZE(i2s3_max98357a_cpus);
723				dai_link->codecs = i2s3_max98357a_codecs;
724				dai_link->num_codecs =
725					ARRAY_SIZE(i2s3_max98357a_codecs);
726				dai_link->platforms = i2s3_max98357a_platforms;
727				dai_link->num_platforms =
728					ARRAY_SIZE(i2s3_max98357a_platforms);
729			} else if (card == &mt8183_da7219_rt1015_card) {
730				dai_link->be_hw_params_fixup =
731					mt8183_rt1015_i2s_hw_params_fixup;
732				dai_link->ops = &mt8183_da7219_rt1015_i2s_ops;
733				dai_link->cpus = i2s3_rt1015_cpus;
734				dai_link->num_cpus =
735					ARRAY_SIZE(i2s3_rt1015_cpus);
736				dai_link->codecs = i2s3_rt1015_codecs;
737				dai_link->num_codecs =
738					ARRAY_SIZE(i2s3_rt1015_codecs);
739				dai_link->platforms = i2s3_rt1015_platforms;
740				dai_link->num_platforms =
741					ARRAY_SIZE(i2s3_rt1015_platforms);
742			} else if (card == &mt8183_da7219_rt1015p_card) {
743				dai_link->be_hw_params_fixup =
744					mt8183_rt1015_i2s_hw_params_fixup;
745				dai_link->ops = &mt8183_da7219_i2s_ops;
746				dai_link->cpus = i2s3_rt1015p_cpus;
747				dai_link->num_cpus =
748					ARRAY_SIZE(i2s3_rt1015p_cpus);
749				dai_link->codecs = i2s3_rt1015p_codecs;
750				dai_link->num_codecs =
751					ARRAY_SIZE(i2s3_rt1015p_codecs);
752				dai_link->platforms = i2s3_rt1015p_platforms;
753				dai_link->num_platforms =
754					ARRAY_SIZE(i2s3_rt1015p_platforms);
755			}
756		}
757
758		if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
759			dai_link->codecs->of_node = hdmi_codec;
760			dai_link->ignore = 0;
761		}
762
763		if (!dai_link->platforms->name)
764			dai_link->platforms->of_node = platform_node;
765	}
766
767	mt8183_da7219_max98357_headset_dev.dlc.of_node =
768		of_parse_phandle(pdev->dev.of_node,
769				 "mediatek,headset-codec", 0);
770	if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {
771		dev_err(&pdev->dev,
772			"Property 'mediatek,headset-codec' missing/invalid\n");
773		return -EINVAL;
774	}
775
776	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
777	if (!priv)
778		return -ENOMEM;
779
780	snd_soc_card_set_drvdata(card, priv);
781
782	pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);
783	if (IS_ERR(pinctrl)) {
784		ret = PTR_ERR(pinctrl);
785		dev_err(&pdev->dev, "%s failed to select default state %d\n",
786			__func__, ret);
787		return ret;
788	}
789
790	ret = devm_snd_soc_register_card(&pdev->dev, card);
791
792	of_node_put(platform_node);
793	of_node_put(hdmi_codec);
794	return ret;
795}
796
797#ifdef CONFIG_OF
798static const struct of_device_id mt8183_da7219_max98357_dt_match[] = {
799	{
800		.compatible = "mediatek,mt8183_da7219_max98357",
801		.data = &mt8183_da7219_max98357_card,
802	},
803	{
804		.compatible = "mediatek,mt8183_da7219_rt1015",
805		.data = &mt8183_da7219_rt1015_card,
806	},
807	{
808		.compatible = "mediatek,mt8183_da7219_rt1015p",
809		.data = &mt8183_da7219_rt1015p_card,
810	},
811	{}
812};
813#endif
814
815static struct platform_driver mt8183_da7219_max98357_driver = {
816	.driver = {
817		.name = "mt8183_da7219",
818#ifdef CONFIG_OF
819		.of_match_table = mt8183_da7219_max98357_dt_match,
820#endif
821	},
822	.probe = mt8183_da7219_max98357_dev_probe,
823};
824
825module_platform_driver(mt8183_da7219_max98357_driver);
826
827/* Module information */
828MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver");
829MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
830MODULE_LICENSE("GPL v2");
831MODULE_ALIAS("mt8183_da7219_max98357 soc card");
832