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