blob: 29c2d3407cc7c00b3ceb48844bc93d548f4ddf91 [file] [log] [blame]
Trevor Wu40d605d2021-08-19 16:41:41 +08001// SPDX-License-Identifier: GPL-2.0
Trevor Wu3d00d2c2021-11-29 22:10:56 +08002/*
3 * mt8195-mt6359-rt1019-rt5682.c --
4 * MT8195-MT6359-RT1019-RT5682 ALSA SoC machine driver
5 *
6 * Copyright (c) 2021 MediaTek Inc.
7 * Author: Trevor Wu <trevor.wu@mediatek.com>
8 * YC Hung <yc.hung@mediatek.com>
9 */
Trevor Wu40d605d2021-08-19 16:41:41 +080010
11#include <linux/input.h>
12#include <linux/module.h>
13#include <linux/pm_runtime.h>
14#include <sound/jack.h>
15#include <sound/pcm_params.h>
16#include <sound/rt5682.h>
Trevor Wu3d00d2c2021-11-29 22:10:56 +080017#include <sound/sof.h>
Trevor Wu40d605d2021-08-19 16:41:41 +080018#include <sound/soc.h>
19#include "../../codecs/mt6359.h"
20#include "../../codecs/rt5682.h"
21#include "../common/mtk-afe-platform-driver.h"
Trevor Wuc5ab93e2021-12-28 14:48:21 +080022#include "mt8195-afe-clk.h"
Trevor Wu40d605d2021-08-19 16:41:41 +080023#include "mt8195-afe-common.h"
24
25#define RT1019_CODEC_DAI "HiFi"
26#define RT1019_DEV0_NAME "rt1019p"
27
28#define RT5682_CODEC_DAI "rt5682-aif1"
29#define RT5682_DEV0_NAME "rt5682.2-001a"
30
Trevor Wuc9d57a22021-11-29 22:10:54 +080031#define RT5682S_CODEC_DAI "rt5682s-aif1"
32#define RT5682S_DEV0_NAME "rt5682s.2-001a"
33
Trevor Wu3d00d2c2021-11-29 22:10:56 +080034#define SOF_DMA_DL2 "SOF_DMA_DL2"
35#define SOF_DMA_DL3 "SOF_DMA_DL3"
36#define SOF_DMA_UL4 "SOF_DMA_UL4"
37#define SOF_DMA_UL5 "SOF_DMA_UL5"
38
39struct sof_conn_stream {
40 const char *normal_link;
41 const char *sof_link;
42 const char *sof_dma;
43 int stream_dir;
44};
45
Trevor Wu40d605d2021-08-19 16:41:41 +080046struct mt8195_mt6359_rt1019_rt5682_priv {
47 struct snd_soc_jack headset_jack;
Trevor Wue581e302021-08-19 16:41:42 +080048 struct snd_soc_jack dp_jack;
Trevor Wuef46cd42021-08-19 16:41:43 +080049 struct snd_soc_jack hdmi_jack;
Trevor Wuc5ab93e2021-12-28 14:48:21 +080050 struct clk *i2so1_mclk;
Trevor Wu40d605d2021-08-19 16:41:41 +080051};
52
53static const struct snd_soc_dapm_widget
54 mt8195_mt6359_rt1019_rt5682_widgets[] = {
55 SND_SOC_DAPM_SPK("Speakers", NULL),
56 SND_SOC_DAPM_HP("Headphone Jack", NULL),
57 SND_SOC_DAPM_MIC("Headset Mic", NULL),
Trevor Wu3d00d2c2021-11-29 22:10:56 +080058 SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0),
59 SND_SOC_DAPM_MIXER(SOF_DMA_DL3, SND_SOC_NOPM, 0, 0, NULL, 0),
60 SND_SOC_DAPM_MIXER(SOF_DMA_UL4, SND_SOC_NOPM, 0, 0, NULL, 0),
61 SND_SOC_DAPM_MIXER(SOF_DMA_UL5, SND_SOC_NOPM, 0, 0, NULL, 0),
Trevor Wu40d605d2021-08-19 16:41:41 +080062};
63
64static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = {
65 /* speaker */
66 { "Speakers", NULL, "Speaker" },
67 /* headset */
68 { "Headphone Jack", NULL, "HPOL" },
69 { "Headphone Jack", NULL, "HPOR" },
70 { "IN1P", NULL, "Headset Mic" },
Trevor Wu3d00d2c2021-11-29 22:10:56 +080071 /* SOF Uplink */
72 {SOF_DMA_UL4, NULL, "O034"},
73 {SOF_DMA_UL4, NULL, "O035"},
74 {SOF_DMA_UL5, NULL, "O036"},
75 {SOF_DMA_UL5, NULL, "O037"},
76 /* SOF Downlink */
77 {"I070", NULL, SOF_DMA_DL2},
78 {"I071", NULL, SOF_DMA_DL2},
79 {"I020", NULL, SOF_DMA_DL3},
80 {"I021", NULL, SOF_DMA_DL3},
Trevor Wu40d605d2021-08-19 16:41:41 +080081};
82
83static const struct snd_kcontrol_new mt8195_mt6359_rt1019_rt5682_controls[] = {
84 SOC_DAPM_PIN_SWITCH("Speakers"),
85 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
86 SOC_DAPM_PIN_SWITCH("Headset Mic"),
87};
88
89static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream,
90 struct snd_pcm_hw_params *params)
91{
92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_card *card = rtd->card;
94 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
95 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
96 unsigned int rate = params_rate(params);
Trevor Wu40d605d2021-08-19 16:41:41 +080097 int bitwidth;
98 int ret;
99
100 bitwidth = snd_pcm_format_width(params_format(params));
101 if (bitwidth < 0) {
102 dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
103 return bitwidth;
104 }
105
106 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
107 if (ret) {
108 dev_err(card->dev, "failed to set tdm slot\n");
109 return ret;
110 }
111
Trevor Wuc5ab93e2021-12-28 14:48:21 +0800112 ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, RT5682_PLL1_S_MCLK,
113 rate * 256, rate * 512);
Trevor Wu40d605d2021-08-19 16:41:41 +0800114 if (ret) {
115 dev_err(card->dev, "failed to set pll\n");
116 return ret;
117 }
118
Trevor Wuc5ab93e2021-12-28 14:48:21 +0800119 ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,
120 rate * 512, SND_SOC_CLOCK_IN);
Trevor Wu40d605d2021-08-19 16:41:41 +0800121 if (ret) {
122 dev_err(card->dev, "failed to set sysclk\n");
123 return ret;
124 }
125
Trevor Wuc5ab93e2021-12-28 14:48:21 +0800126 return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 256,
127 SND_SOC_CLOCK_OUT);
Trevor Wu40d605d2021-08-19 16:41:41 +0800128}
129
130static const struct snd_soc_ops mt8195_rt5682_etdm_ops = {
131 .hw_params = mt8195_rt5682_etdm_hw_params,
132};
133
134#define CKSYS_AUD_TOP_CFG 0x032c
135#define CKSYS_AUD_TOP_MON 0x0330
136
137static int mt8195_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)
138{
139 struct snd_soc_component *cmpnt_afe =
140 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
141 struct snd_soc_component *cmpnt_codec =
142 asoc_rtd_to_codec(rtd, 0)->component;
143 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
144 struct mt8195_afe_private *afe_priv = afe->platform_priv;
145 struct mtkaif_param *param = &afe_priv->mtkaif_params;
146 int phase;
147 unsigned int monitor;
148 int mtkaif_calibration_num_phase;
149 int test_done_1, test_done_2, test_done_3;
150 int cycle_1, cycle_2, cycle_3;
151 int prev_cycle_1, prev_cycle_2, prev_cycle_3;
152 int chosen_phase_1, chosen_phase_2, chosen_phase_3;
153 int counter;
154 bool mtkaif_calibration_ok;
155 int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM];
156 int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM];
157 int i;
158
159 dev_info(afe->dev, "%s(), start\n", __func__);
160
161 param->mtkaif_calibration_ok = false;
162 for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) {
163 param->mtkaif_chosen_phase[i] = -1;
164 param->mtkaif_phase_cycle[i] = 0;
165 mtkaif_chosen_phase[i] = -1;
166 mtkaif_phase_cycle[i] = 0;
167 }
168
169 if (IS_ERR(afe_priv->topckgen)) {
170 dev_info(afe->dev, "%s() Cannot find topckgen controller\n",
171 __func__);
172 return 0;
173 }
174
175 pm_runtime_get_sync(afe->dev);
176 mt6359_mtkaif_calibration_enable(cmpnt_codec);
177
178 /* set test type to synchronizer pulse */
179 regmap_update_bits(afe_priv->topckgen,
180 CKSYS_AUD_TOP_CFG, 0xffff, 0x4);
181 mtkaif_calibration_num_phase = 42; /* mt6359: 0 ~ 42 */
182 mtkaif_calibration_ok = true;
183
184 for (phase = 0;
185 phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok;
186 phase++) {
187 mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
188 phase, phase, phase);
189
190 regmap_update_bits(afe_priv->topckgen,
191 CKSYS_AUD_TOP_CFG, 0x1, 0x1);
192
193 test_done_1 = 0;
194 test_done_2 = 0;
195 test_done_3 = 0;
196 cycle_1 = -1;
197 cycle_2 = -1;
198 cycle_3 = -1;
199 counter = 0;
200 while (!(test_done_1 & test_done_2 & test_done_3)) {
201 regmap_read(afe_priv->topckgen,
202 CKSYS_AUD_TOP_MON, &monitor);
203 test_done_1 = (monitor >> 28) & 0x1;
204 test_done_2 = (monitor >> 29) & 0x1;
205 test_done_3 = (monitor >> 30) & 0x1;
206 if (test_done_1 == 1)
207 cycle_1 = monitor & 0xf;
208
209 if (test_done_2 == 1)
210 cycle_2 = (monitor >> 4) & 0xf;
211
212 if (test_done_3 == 1)
213 cycle_3 = (monitor >> 8) & 0xf;
214
215 /* handle if never test done */
216 if (++counter > 10000) {
217 dev_info(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, cycle_3 %d, monitor 0x%x\n",
218 __func__,
219 cycle_1, cycle_2, cycle_3, monitor);
220 mtkaif_calibration_ok = false;
221 break;
222 }
223 }
224
225 if (phase == 0) {
226 prev_cycle_1 = cycle_1;
227 prev_cycle_2 = cycle_2;
228 prev_cycle_3 = cycle_3;
229 }
230
231 if (cycle_1 != prev_cycle_1 &&
232 mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) {
233 mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = phase - 1;
234 mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] = prev_cycle_1;
235 }
236
237 if (cycle_2 != prev_cycle_2 &&
238 mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) {
239 mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = phase - 1;
240 mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] = prev_cycle_2;
241 }
242
243 if (cycle_3 != prev_cycle_3 &&
244 mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) {
245 mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = phase - 1;
246 mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] = prev_cycle_3;
247 }
248
249 regmap_update_bits(afe_priv->topckgen,
250 CKSYS_AUD_TOP_CFG, 0x1, 0x0);
251
252 if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] >= 0 &&
253 mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] >= 0 &&
254 mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] >= 0)
255 break;
256 }
257
258 if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) {
259 mtkaif_calibration_ok = false;
260 chosen_phase_1 = 0;
261 } else {
262 chosen_phase_1 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0];
263 }
264
265 if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) {
266 mtkaif_calibration_ok = false;
267 chosen_phase_2 = 0;
268 } else {
269 chosen_phase_2 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1];
270 }
271
272 if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) {
273 mtkaif_calibration_ok = false;
274 chosen_phase_3 = 0;
275 } else {
276 chosen_phase_3 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2];
277 }
278
279 mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
280 chosen_phase_1,
281 chosen_phase_2,
282 chosen_phase_3);
283
284 mt6359_mtkaif_calibration_disable(cmpnt_codec);
285 pm_runtime_put(afe->dev);
286
287 param->mtkaif_calibration_ok = mtkaif_calibration_ok;
288 param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = chosen_phase_1;
289 param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = chosen_phase_2;
290 param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = chosen_phase_3;
291 for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++)
292 param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i];
293
294 dev_info(afe->dev, "%s(), end, calibration ok %d\n",
295 __func__, param->mtkaif_calibration_ok);
296
297 return 0;
298}
299
300static int mt8195_mt6359_init(struct snd_soc_pcm_runtime *rtd)
301{
302 struct snd_soc_component *cmpnt_codec =
303 asoc_rtd_to_codec(rtd, 0)->component;
304
305 /* set mtkaif protocol */
306 mt6359_set_mtkaif_protocol(cmpnt_codec,
307 MT6359_MTKAIF_PROTOCOL_2_CLK_P2);
308
309 /* mtkaif calibration */
310 mt8195_mt6359_mtkaif_calibration(rtd);
311
312 return 0;
313}
314
315static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd)
316{
317 struct snd_soc_component *cmpnt_codec =
318 asoc_rtd_to_codec(rtd, 0)->component;
319 struct mt8195_mt6359_rt1019_rt5682_priv *priv =
320 snd_soc_card_get_drvdata(rtd->card);
321 struct snd_soc_jack *jack = &priv->headset_jack;
Trevor Wuc5ab93e2021-12-28 14:48:21 +0800322 struct snd_soc_component *cmpnt_afe =
323 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
324 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
325 struct mt8195_afe_private *afe_priv = afe->platform_priv;
Trevor Wu40d605d2021-08-19 16:41:41 +0800326 int ret;
327
Trevor Wuc5ab93e2021-12-28 14:48:21 +0800328 priv->i2so1_mclk = afe_priv->clk[MT8195_CLK_TOP_APLL12_DIV2];
329
Trevor Wu40d605d2021-08-19 16:41:41 +0800330 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
331 SND_JACK_HEADSET | SND_JACK_BTN_0 |
332 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
333 SND_JACK_BTN_3,
334 jack, NULL, 0);
335 if (ret) {
336 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
337 return ret;
338 }
339
340 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
341 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
342 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
343 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
344
345 ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
346 if (ret) {
347 dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret);
348 return ret;
349 }
350
351 return 0;
352};
353
354static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
355 struct snd_pcm_hw_params *params)
356{
Jiaxin Yu03c21922021-12-09 15:32:24 +0800357 /* fix BE i2s format to S24_LE, clean param mask first */
Trevor Wu40d605d2021-08-19 16:41:41 +0800358 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
359 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
360
361 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
362
363 return 0;
364}
365
Trevor Wue581e302021-08-19 16:41:42 +0800366static int mt8195_hdmitx_dptx_startup(struct snd_pcm_substream *substream)
367{
368 static const unsigned int rates[] = {
369 48000
370 };
371 static const unsigned int channels[] = {
372 2, 4, 6, 8
373 };
374 static const struct snd_pcm_hw_constraint_list constraints_rates = {
375 .count = ARRAY_SIZE(rates),
376 .list = rates,
377 .mask = 0,
378 };
379 static const struct snd_pcm_hw_constraint_list constraints_channels = {
380 .count = ARRAY_SIZE(channels),
381 .list = channels,
382 .mask = 0,
383 };
384
385 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
386 struct snd_pcm_runtime *runtime = substream->runtime;
387 int ret;
388
389 ret = snd_pcm_hw_constraint_list(runtime, 0,
390 SNDRV_PCM_HW_PARAM_RATE,
391 &constraints_rates);
392 if (ret < 0) {
393 dev_err(rtd->dev, "hw_constraint_list rate failed\n");
394 return ret;
395 }
396
397 ret = snd_pcm_hw_constraint_list(runtime, 0,
398 SNDRV_PCM_HW_PARAM_CHANNELS,
399 &constraints_channels);
400 if (ret < 0) {
401 dev_err(rtd->dev, "hw_constraint_list channel failed\n");
402 return ret;
403 }
404
405 return 0;
406}
407
408static const struct snd_soc_ops mt8195_hdmitx_dptx_playback_ops = {
409 .startup = mt8195_hdmitx_dptx_startup,
410};
411
Trevor Wu40d605d2021-08-19 16:41:41 +0800412static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream,
413 struct snd_pcm_hw_params *params)
414{
415 struct snd_soc_pcm_runtime *rtd = substream->private_data;
416 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
417 unsigned int rate = params_rate(params);
418 unsigned int mclk_fs_ratio = 256;
419 unsigned int mclk_fs = rate * mclk_fs_ratio;
420
421 return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs,
422 SND_SOC_CLOCK_OUT);
423}
424
Rikard Falkeborn8752d9a2021-11-27 10:31:47 +0100425static const struct snd_soc_ops mt8195_dptx_ops = {
Trevor Wu40d605d2021-08-19 16:41:41 +0800426 .hw_params = mt8195_dptx_hw_params,
427};
428
Trevor Wue581e302021-08-19 16:41:42 +0800429static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
430{
431 struct mt8195_mt6359_rt1019_rt5682_priv *priv =
432 snd_soc_card_get_drvdata(rtd->card);
433 struct snd_soc_component *cmpnt_codec =
434 asoc_rtd_to_codec(rtd, 0)->component;
435 int ret = 0;
436
437 ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_LINEOUT,
438 &priv->dp_jack, NULL, 0);
439 if (ret)
440 return ret;
441
442 return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL);
443}
444
Trevor Wuef46cd42021-08-19 16:41:43 +0800445static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
446{
447 struct mt8195_mt6359_rt1019_rt5682_priv *priv =
448 snd_soc_card_get_drvdata(rtd->card);
449 struct snd_soc_component *cmpnt_codec =
450 asoc_rtd_to_codec(rtd, 0)->component;
451 int ret = 0;
452
453 ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
454 &priv->hdmi_jack, NULL, 0);
455 if (ret)
456 return ret;
457
458 return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
459}
460
Trevor Wu3abe2ee2021-09-17 16:28:05 +0800461static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
462 struct snd_pcm_hw_params *params)
Trevor Wue581e302021-08-19 16:41:42 +0800463
Trevor Wu40d605d2021-08-19 16:41:41 +0800464{
Jiaxin Yu03c21922021-12-09 15:32:24 +0800465 /* fix BE i2s format to S24_LE, clean param mask first */
Trevor Wu40d605d2021-08-19 16:41:41 +0800466 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
467 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
468
469 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
470
471 return 0;
472}
473
474static int mt8195_playback_startup(struct snd_pcm_substream *substream)
475{
476 static const unsigned int rates[] = {
477 48000
478 };
479 static const unsigned int channels[] = {
480 2
481 };
482 static const struct snd_pcm_hw_constraint_list constraints_rates = {
483 .count = ARRAY_SIZE(rates),
484 .list = rates,
485 .mask = 0,
486 };
487 static const struct snd_pcm_hw_constraint_list constraints_channels = {
488 .count = ARRAY_SIZE(channels),
489 .list = channels,
490 .mask = 0,
491 };
492
493 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
494 struct snd_pcm_runtime *runtime = substream->runtime;
495 int ret;
496
497 ret = snd_pcm_hw_constraint_list(runtime, 0,
498 SNDRV_PCM_HW_PARAM_RATE,
499 &constraints_rates);
500 if (ret < 0) {
501 dev_err(rtd->dev, "hw_constraint_list rate failed\n");
502 return ret;
503 }
504
505 ret = snd_pcm_hw_constraint_list(runtime, 0,
506 SNDRV_PCM_HW_PARAM_CHANNELS,
507 &constraints_channels);
508 if (ret < 0) {
509 dev_err(rtd->dev, "hw_constraint_list channel failed\n");
510 return ret;
511 }
512
513 return 0;
514}
515
516static const struct snd_soc_ops mt8195_playback_ops = {
517 .startup = mt8195_playback_startup,
518};
519
520static int mt8195_capture_startup(struct snd_pcm_substream *substream)
521{
522 static const unsigned int rates[] = {
523 48000
524 };
525 static const unsigned int channels[] = {
526 1, 2
527 };
528 static const struct snd_pcm_hw_constraint_list constraints_rates = {
529 .count = ARRAY_SIZE(rates),
530 .list = rates,
531 .mask = 0,
532 };
533 static const struct snd_pcm_hw_constraint_list constraints_channels = {
534 .count = ARRAY_SIZE(channels),
535 .list = channels,
536 .mask = 0,
537 };
538
539 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
540 struct snd_pcm_runtime *runtime = substream->runtime;
541 int ret;
542
543 ret = snd_pcm_hw_constraint_list(runtime, 0,
544 SNDRV_PCM_HW_PARAM_RATE,
545 &constraints_rates);
546 if (ret < 0) {
547 dev_err(rtd->dev, "hw_constraint_list rate failed\n");
548 return ret;
549 }
550
551 ret = snd_pcm_hw_constraint_list(runtime, 0,
552 SNDRV_PCM_HW_PARAM_CHANNELS,
553 &constraints_channels);
554 if (ret < 0) {
555 dev_err(rtd->dev, "hw_constraint_list channel failed\n");
556 return ret;
557 }
558
559 return 0;
560}
561
562static const struct snd_soc_ops mt8195_capture_ops = {
563 .startup = mt8195_capture_startup,
564};
565
Trevor Wuc5ab93e2021-12-28 14:48:21 +0800566static int mt8195_set_bias_level_post(struct snd_soc_card *card,
567 struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
568{
569 struct snd_soc_component *component = dapm->component;
570 struct mt8195_mt6359_rt1019_rt5682_priv *priv =
571 snd_soc_card_get_drvdata(card);
572 int ret;
573
574 /*
575 * It's required to control mclk directly in the set_bias_level_post
576 * function for rt5682 and rt5682s codec, or the unexpected pop happens
577 * at the end of playback.
578 */
579 if (!component ||
580 (strcmp(component->name, RT5682_DEV0_NAME) &&
581 strcmp(component->name, RT5682S_DEV0_NAME)))
582 return 0;
583
584
585 switch (level) {
586 case SND_SOC_BIAS_OFF:
587 if (!__clk_is_enabled(priv->i2so1_mclk))
588 return 0;
589
590 clk_disable_unprepare(priv->i2so1_mclk);
591 dev_dbg(card->dev, "Disable i2so1 mclk\n");
592 break;
593 case SND_SOC_BIAS_ON:
594 ret = clk_prepare_enable(priv->i2so1_mclk);
595 if (ret) {
596 dev_err(card->dev, "Can't enable i2so1 mclk: %d\n", ret);
597 return ret;
598 }
599 dev_dbg(card->dev, "Enable i2so1 mclk\n");
600 break;
601 default:
602 break;
603 }
604
605 return 0;
606}
607
Trevor Wu40d605d2021-08-19 16:41:41 +0800608enum {
609 DAI_LINK_DL2_FE,
610 DAI_LINK_DL3_FE,
611 DAI_LINK_DL6_FE,
612 DAI_LINK_DL7_FE,
613 DAI_LINK_DL8_FE,
614 DAI_LINK_DL10_FE,
615 DAI_LINK_DL11_FE,
616 DAI_LINK_UL1_FE,
617 DAI_LINK_UL2_FE,
618 DAI_LINK_UL3_FE,
619 DAI_LINK_UL4_FE,
620 DAI_LINK_UL5_FE,
621 DAI_LINK_UL6_FE,
622 DAI_LINK_UL8_FE,
623 DAI_LINK_UL9_FE,
624 DAI_LINK_UL10_FE,
625 DAI_LINK_DL_SRC_BE,
626 DAI_LINK_DPTX_BE,
627 DAI_LINK_ETDM1_IN_BE,
628 DAI_LINK_ETDM2_IN_BE,
629 DAI_LINK_ETDM1_OUT_BE,
630 DAI_LINK_ETDM2_OUT_BE,
631 DAI_LINK_ETDM3_OUT_BE,
632 DAI_LINK_PCM1_BE,
633 DAI_LINK_UL_SRC1_BE,
634 DAI_LINK_UL_SRC2_BE,
Trevor Wu3d00d2c2021-11-29 22:10:56 +0800635 DAI_LINK_REGULAR_LAST = DAI_LINK_UL_SRC2_BE,
636 DAI_LINK_SOF_START,
637 DAI_LINK_SOF_DL2_BE = DAI_LINK_SOF_START,
638 DAI_LINK_SOF_DL3_BE,
639 DAI_LINK_SOF_UL4_BE,
640 DAI_LINK_SOF_UL5_BE,
641 DAI_LINK_SOF_END = DAI_LINK_SOF_UL5_BE,
Trevor Wu40d605d2021-08-19 16:41:41 +0800642};
643
Trevor Wu3d00d2c2021-11-29 22:10:56 +0800644#define DAI_LINK_REGULAR_NUM (DAI_LINK_REGULAR_LAST + 1)
645
Trevor Wu40d605d2021-08-19 16:41:41 +0800646/* FE */
647SND_SOC_DAILINK_DEFS(DL2_FE,
648 DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
649 DAILINK_COMP_ARRAY(COMP_DUMMY()),
650 DAILINK_COMP_ARRAY(COMP_EMPTY()));
651
652SND_SOC_DAILINK_DEFS(DL3_FE,
653 DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
654 DAILINK_COMP_ARRAY(COMP_DUMMY()),
655 DAILINK_COMP_ARRAY(COMP_EMPTY()));
656
657SND_SOC_DAILINK_DEFS(DL6_FE,
658 DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
659 DAILINK_COMP_ARRAY(COMP_DUMMY()),
660 DAILINK_COMP_ARRAY(COMP_EMPTY()));
661
662SND_SOC_DAILINK_DEFS(DL7_FE,
663 DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
664 DAILINK_COMP_ARRAY(COMP_DUMMY()),
665 DAILINK_COMP_ARRAY(COMP_EMPTY()));
666
667SND_SOC_DAILINK_DEFS(DL8_FE,
668 DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
669 DAILINK_COMP_ARRAY(COMP_DUMMY()),
670 DAILINK_COMP_ARRAY(COMP_EMPTY()));
671
672SND_SOC_DAILINK_DEFS(DL10_FE,
673 DAILINK_COMP_ARRAY(COMP_CPU("DL10")),
674 DAILINK_COMP_ARRAY(COMP_DUMMY()),
675 DAILINK_COMP_ARRAY(COMP_EMPTY()));
676
677SND_SOC_DAILINK_DEFS(DL11_FE,
678 DAILINK_COMP_ARRAY(COMP_CPU("DL11")),
679 DAILINK_COMP_ARRAY(COMP_DUMMY()),
680 DAILINK_COMP_ARRAY(COMP_EMPTY()));
681
682SND_SOC_DAILINK_DEFS(UL1_FE,
683 DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
684 DAILINK_COMP_ARRAY(COMP_DUMMY()),
685 DAILINK_COMP_ARRAY(COMP_EMPTY()));
686
687SND_SOC_DAILINK_DEFS(UL2_FE,
688 DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
689 DAILINK_COMP_ARRAY(COMP_DUMMY()),
690 DAILINK_COMP_ARRAY(COMP_EMPTY()));
691
692SND_SOC_DAILINK_DEFS(UL3_FE,
693 DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
694 DAILINK_COMP_ARRAY(COMP_DUMMY()),
695 DAILINK_COMP_ARRAY(COMP_EMPTY()));
696
697SND_SOC_DAILINK_DEFS(UL4_FE,
698 DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
699 DAILINK_COMP_ARRAY(COMP_DUMMY()),
700 DAILINK_COMP_ARRAY(COMP_EMPTY()));
701
702SND_SOC_DAILINK_DEFS(UL5_FE,
703 DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
704 DAILINK_COMP_ARRAY(COMP_DUMMY()),
705 DAILINK_COMP_ARRAY(COMP_EMPTY()));
706
707SND_SOC_DAILINK_DEFS(UL6_FE,
708 DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
709 DAILINK_COMP_ARRAY(COMP_DUMMY()),
710 DAILINK_COMP_ARRAY(COMP_EMPTY()));
711
712SND_SOC_DAILINK_DEFS(UL8_FE,
713 DAILINK_COMP_ARRAY(COMP_CPU("UL8")),
714 DAILINK_COMP_ARRAY(COMP_DUMMY()),
715 DAILINK_COMP_ARRAY(COMP_EMPTY()));
716
717SND_SOC_DAILINK_DEFS(UL9_FE,
718 DAILINK_COMP_ARRAY(COMP_CPU("UL9")),
719 DAILINK_COMP_ARRAY(COMP_DUMMY()),
720 DAILINK_COMP_ARRAY(COMP_EMPTY()));
721
722SND_SOC_DAILINK_DEFS(UL10_FE,
723 DAILINK_COMP_ARRAY(COMP_CPU("UL10")),
724 DAILINK_COMP_ARRAY(COMP_DUMMY()),
725 DAILINK_COMP_ARRAY(COMP_EMPTY()));
726
727/* BE */
728SND_SOC_DAILINK_DEFS(DL_SRC_BE,
729 DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")),
730 DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
731 "mt6359-snd-codec-aif1")),
732 DAILINK_COMP_ARRAY(COMP_EMPTY()));
733
734SND_SOC_DAILINK_DEFS(DPTX_BE,
735 DAILINK_COMP_ARRAY(COMP_CPU("DPTX")),
736 DAILINK_COMP_ARRAY(COMP_DUMMY()),
737 DAILINK_COMP_ARRAY(COMP_EMPTY()));
738
739SND_SOC_DAILINK_DEFS(ETDM1_IN_BE,
740 DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")),
741 DAILINK_COMP_ARRAY(COMP_DUMMY()),
742 DAILINK_COMP_ARRAY(COMP_EMPTY()));
743
744SND_SOC_DAILINK_DEFS(ETDM2_IN_BE,
745 DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")),
Trevor Wuc9d57a22021-11-29 22:10:54 +0800746 DAILINK_COMP_ARRAY(COMP_DUMMY()),
Trevor Wu40d605d2021-08-19 16:41:41 +0800747 DAILINK_COMP_ARRAY(COMP_EMPTY()));
748
749SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE,
750 DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")),
Trevor Wuc9d57a22021-11-29 22:10:54 +0800751 DAILINK_COMP_ARRAY(COMP_DUMMY()),
Trevor Wu40d605d2021-08-19 16:41:41 +0800752 DAILINK_COMP_ARRAY(COMP_EMPTY()));
753
754SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE,
755 DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")),
756 DAILINK_COMP_ARRAY(COMP_CODEC(RT1019_DEV0_NAME,
757 RT1019_CODEC_DAI)),
758 DAILINK_COMP_ARRAY(COMP_EMPTY()));
759
760SND_SOC_DAILINK_DEFS(ETDM3_OUT_BE,
761 DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")),
762 DAILINK_COMP_ARRAY(COMP_DUMMY()),
763 DAILINK_COMP_ARRAY(COMP_EMPTY()));
764
765SND_SOC_DAILINK_DEFS(PCM1_BE,
766 DAILINK_COMP_ARRAY(COMP_CPU("PCM1")),
767 DAILINK_COMP_ARRAY(COMP_DUMMY()),
768 DAILINK_COMP_ARRAY(COMP_EMPTY()));
769
770SND_SOC_DAILINK_DEFS(UL_SRC1_BE,
771 DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC1")),
772 DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
773 "mt6359-snd-codec-aif1"),
774 COMP_CODEC("dmic-codec",
775 "dmic-hifi")),
776 DAILINK_COMP_ARRAY(COMP_EMPTY()));
777
778SND_SOC_DAILINK_DEFS(UL_SRC2_BE,
779 DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC2")),
780 DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
781 "mt6359-snd-codec-aif2")),
782 DAILINK_COMP_ARRAY(COMP_EMPTY()));
783
Trevor Wu3d00d2c2021-11-29 22:10:56 +0800784SND_SOC_DAILINK_DEFS(AFE_SOF_DL2,
785 DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")),
786 DAILINK_COMP_ARRAY(COMP_DUMMY()),
787 DAILINK_COMP_ARRAY(COMP_EMPTY()));
788
789SND_SOC_DAILINK_DEFS(AFE_SOF_DL3,
790 DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL3")),
791 DAILINK_COMP_ARRAY(COMP_DUMMY()),
792 DAILINK_COMP_ARRAY(COMP_EMPTY()));
793
794SND_SOC_DAILINK_DEFS(AFE_SOF_UL4,
795 DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL4")),
796 DAILINK_COMP_ARRAY(COMP_DUMMY()),
797 DAILINK_COMP_ARRAY(COMP_EMPTY()));
798
799SND_SOC_DAILINK_DEFS(AFE_SOF_UL5,
800 DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL5")),
801 DAILINK_COMP_ARRAY(COMP_DUMMY()),
802 DAILINK_COMP_ARRAY(COMP_EMPTY()));
803
804static const struct sof_conn_stream g_sof_conn_streams[] = {
805 { "ETDM2_OUT_BE", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK},
806 { "ETDM1_OUT_BE", "AFE_SOF_DL3", SOF_DMA_DL3, SNDRV_PCM_STREAM_PLAYBACK},
807 { "UL_SRC1_BE", "AFE_SOF_UL4", SOF_DMA_UL4, SNDRV_PCM_STREAM_CAPTURE},
808 { "ETDM2_IN_BE", "AFE_SOF_UL5", SOF_DMA_UL5, SNDRV_PCM_STREAM_CAPTURE},
809};
810
811/* fixup the BE DAI link to match any values from topology */
812static int mt8195_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
813 struct snd_pcm_hw_params *params)
814{
815 struct snd_soc_card *card = rtd->card;
816 struct snd_soc_dai_link *sof_dai_link = NULL;
817 struct snd_soc_pcm_runtime *runtime;
818 struct snd_soc_dai *cpu_dai;
819 int i, j, ret = 0;
820
821 for (i = 0; i < ARRAY_SIZE(g_sof_conn_streams); i++) {
822 const struct sof_conn_stream *conn = &g_sof_conn_streams[i];
823
824 if (strcmp(rtd->dai_link->name, conn->normal_link))
825 continue;
826
827 for_each_card_rtds(card, runtime) {
828 if (strcmp(runtime->dai_link->name, conn->sof_link))
829 continue;
830
831 for_each_rtd_cpu_dais(runtime, j, cpu_dai) {
832 if (cpu_dai->stream_active[conn->stream_dir] > 0) {
833 sof_dai_link = runtime->dai_link;
834 break;
835 }
836 }
837 break;
838 }
839
840 if (sof_dai_link && sof_dai_link->be_hw_params_fixup)
841 ret = sof_dai_link->be_hw_params_fixup(runtime, params);
842
843 break;
844 }
845
846 if (!strcmp(rtd->dai_link->name, "ETDM2_IN_BE") ||
847 !strcmp(rtd->dai_link->name, "ETDM1_OUT_BE")) {
848 mt8195_etdm_hw_params_fixup(runtime, params);
849 }
850
851 return ret;
852}
853
854static int mt8195_mt6359_rt1019_rt5682_card_late_probe(struct snd_soc_card *card)
855{
856 struct snd_soc_pcm_runtime *runtime;
Dan Carpenter9abc21c2021-12-08 18:11:45 +0300857 struct snd_soc_component *sof_comp = NULL;
Trevor Wu3d00d2c2021-11-29 22:10:56 +0800858 int i;
859
860 /* 1. find sof component */
861 for_each_card_rtds(card, runtime) {
862 for (i = 0; i < runtime->num_components; i++) {
863 if (!runtime->components[i]->driver->name)
864 continue;
865 if (!strcmp(runtime->components[i]->driver->name, "sof-audio-component")) {
866 sof_comp = runtime->components[i];
867 break;
868 }
869 }
870 }
871
872 if (!sof_comp) {
873 dev_info(card->dev, " probe without component\n");
874 return 0;
875 }
876 /* 2. add route path and fixup callback */
877 for (i = 0; i < ARRAY_SIZE(g_sof_conn_streams); i++) {
878 const struct sof_conn_stream *conn = &g_sof_conn_streams[i];
879 struct snd_soc_pcm_runtime *sof_rtd = NULL;
880 struct snd_soc_pcm_runtime *normal_rtd = NULL;
881 struct snd_soc_pcm_runtime *rtd = NULL;
882
883 for_each_card_rtds(card, rtd) {
884 if (!strcmp(rtd->dai_link->name, conn->sof_link)) {
885 sof_rtd = rtd;
886 continue;
887 }
888 if (!strcmp(rtd->dai_link->name, conn->normal_link)) {
889 normal_rtd = rtd;
890 continue;
891 }
892 if (normal_rtd && sof_rtd)
893 break;
894 }
895 if (normal_rtd && sof_rtd) {
896 int j;
897 struct snd_soc_dai *cpu_dai;
898
899 for_each_rtd_cpu_dais(sof_rtd, j, cpu_dai) {
900 struct snd_soc_dapm_route route;
901 struct snd_soc_dapm_path *p = NULL;
902 struct snd_soc_dapm_widget *play_widget =
903 cpu_dai->playback_widget;
904 struct snd_soc_dapm_widget *cap_widget =
905 cpu_dai->capture_widget;
906 memset(&route, 0, sizeof(route));
907 if (conn->stream_dir == SNDRV_PCM_STREAM_CAPTURE &&
908 cap_widget) {
909 snd_soc_dapm_widget_for_each_sink_path(cap_widget, p) {
910 route.source = conn->sof_dma;
911 route.sink = p->sink->name;
912 snd_soc_dapm_add_routes(&card->dapm, &route, 1);
913 }
914 } else if (conn->stream_dir == SNDRV_PCM_STREAM_PLAYBACK &&
915 play_widget){
916 snd_soc_dapm_widget_for_each_source_path(play_widget, p) {
917 route.source = p->source->name;
918 route.sink = conn->sof_dma;
919 snd_soc_dapm_add_routes(&card->dapm, &route, 1);
920 }
921 } else {
922 dev_err(cpu_dai->dev, "stream dir and widget not pair\n");
923 }
924 }
925 normal_rtd->dai_link->be_hw_params_fixup = mt8195_dai_link_fixup;
926 }
927 }
928
929 return 0;
930}
931
Trevor Wu40d605d2021-08-19 16:41:41 +0800932static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
933 /* FE */
934 [DAI_LINK_DL2_FE] = {
935 .name = "DL2_FE",
936 .stream_name = "DL2 Playback",
937 .trigger = {
938 SND_SOC_DPCM_TRIGGER_POST,
939 SND_SOC_DPCM_TRIGGER_POST,
940 },
941 .dynamic = 1,
942 .dpcm_playback = 1,
943 .ops = &mt8195_playback_ops,
944 SND_SOC_DAILINK_REG(DL2_FE),
945 },
946 [DAI_LINK_DL3_FE] = {
947 .name = "DL3_FE",
948 .stream_name = "DL3 Playback",
949 .trigger = {
950 SND_SOC_DPCM_TRIGGER_POST,
951 SND_SOC_DPCM_TRIGGER_POST,
952 },
953 .dynamic = 1,
954 .dpcm_playback = 1,
955 .ops = &mt8195_playback_ops,
956 SND_SOC_DAILINK_REG(DL3_FE),
957 },
958 [DAI_LINK_DL6_FE] = {
959 .name = "DL6_FE",
960 .stream_name = "DL6 Playback",
961 .trigger = {
962 SND_SOC_DPCM_TRIGGER_POST,
963 SND_SOC_DPCM_TRIGGER_POST,
964 },
965 .dynamic = 1,
966 .dpcm_playback = 1,
967 .ops = &mt8195_playback_ops,
968 SND_SOC_DAILINK_REG(DL6_FE),
969 },
970 [DAI_LINK_DL7_FE] = {
971 .name = "DL7_FE",
972 .stream_name = "DL7 Playback",
973 .trigger = {
974 SND_SOC_DPCM_TRIGGER_PRE,
975 SND_SOC_DPCM_TRIGGER_PRE,
976 },
977 .dynamic = 1,
978 .dpcm_playback = 1,
979 SND_SOC_DAILINK_REG(DL7_FE),
980 },
981 [DAI_LINK_DL8_FE] = {
982 .name = "DL8_FE",
983 .stream_name = "DL8 Playback",
984 .trigger = {
985 SND_SOC_DPCM_TRIGGER_POST,
986 SND_SOC_DPCM_TRIGGER_POST,
987 },
988 .dynamic = 1,
989 .dpcm_playback = 1,
990 .ops = &mt8195_playback_ops,
991 SND_SOC_DAILINK_REG(DL8_FE),
992 },
993 [DAI_LINK_DL10_FE] = {
994 .name = "DL10_FE",
995 .stream_name = "DL10 Playback",
996 .trigger = {
997 SND_SOC_DPCM_TRIGGER_POST,
998 SND_SOC_DPCM_TRIGGER_POST,
999 },
1000 .dynamic = 1,
1001 .dpcm_playback = 1,
Trevor Wue581e302021-08-19 16:41:42 +08001002 .ops = &mt8195_hdmitx_dptx_playback_ops,
Trevor Wu40d605d2021-08-19 16:41:41 +08001003 SND_SOC_DAILINK_REG(DL10_FE),
1004 },
1005 [DAI_LINK_DL11_FE] = {
1006 .name = "DL11_FE",
1007 .stream_name = "DL11 Playback",
1008 .trigger = {
1009 SND_SOC_DPCM_TRIGGER_POST,
1010 SND_SOC_DPCM_TRIGGER_POST,
1011 },
1012 .dynamic = 1,
1013 .dpcm_playback = 1,
1014 .ops = &mt8195_playback_ops,
1015 SND_SOC_DAILINK_REG(DL11_FE),
1016 },
1017 [DAI_LINK_UL1_FE] = {
1018 .name = "UL1_FE",
1019 .stream_name = "UL1 Capture",
1020 .trigger = {
1021 SND_SOC_DPCM_TRIGGER_PRE,
1022 SND_SOC_DPCM_TRIGGER_PRE,
1023 },
1024 .dynamic = 1,
1025 .dpcm_capture = 1,
1026 SND_SOC_DAILINK_REG(UL1_FE),
1027 },
1028 [DAI_LINK_UL2_FE] = {
1029 .name = "UL2_FE",
1030 .stream_name = "UL2 Capture",
1031 .trigger = {
1032 SND_SOC_DPCM_TRIGGER_POST,
1033 SND_SOC_DPCM_TRIGGER_POST,
1034 },
1035 .dynamic = 1,
1036 .dpcm_capture = 1,
1037 .ops = &mt8195_capture_ops,
1038 SND_SOC_DAILINK_REG(UL2_FE),
1039 },
1040 [DAI_LINK_UL3_FE] = {
1041 .name = "UL3_FE",
1042 .stream_name = "UL3 Capture",
1043 .trigger = {
1044 SND_SOC_DPCM_TRIGGER_POST,
1045 SND_SOC_DPCM_TRIGGER_POST,
1046 },
1047 .dynamic = 1,
1048 .dpcm_capture = 1,
1049 .ops = &mt8195_capture_ops,
1050 SND_SOC_DAILINK_REG(UL3_FE),
1051 },
1052 [DAI_LINK_UL4_FE] = {
1053 .name = "UL4_FE",
1054 .stream_name = "UL4 Capture",
1055 .trigger = {
1056 SND_SOC_DPCM_TRIGGER_POST,
1057 SND_SOC_DPCM_TRIGGER_POST,
1058 },
1059 .dynamic = 1,
1060 .dpcm_capture = 1,
1061 .ops = &mt8195_capture_ops,
1062 SND_SOC_DAILINK_REG(UL4_FE),
1063 },
1064 [DAI_LINK_UL5_FE] = {
1065 .name = "UL5_FE",
1066 .stream_name = "UL5 Capture",
1067 .trigger = {
1068 SND_SOC_DPCM_TRIGGER_POST,
1069 SND_SOC_DPCM_TRIGGER_POST,
1070 },
1071 .dynamic = 1,
1072 .dpcm_capture = 1,
1073 .ops = &mt8195_capture_ops,
1074 SND_SOC_DAILINK_REG(UL5_FE),
1075 },
1076 [DAI_LINK_UL6_FE] = {
1077 .name = "UL6_FE",
1078 .stream_name = "UL6 Capture",
1079 .trigger = {
1080 SND_SOC_DPCM_TRIGGER_PRE,
1081 SND_SOC_DPCM_TRIGGER_PRE,
1082 },
1083 .dynamic = 1,
1084 .dpcm_capture = 1,
1085 SND_SOC_DAILINK_REG(UL6_FE),
1086 },
1087 [DAI_LINK_UL8_FE] = {
1088 .name = "UL8_FE",
1089 .stream_name = "UL8 Capture",
1090 .trigger = {
1091 SND_SOC_DPCM_TRIGGER_POST,
1092 SND_SOC_DPCM_TRIGGER_POST,
1093 },
1094 .dynamic = 1,
1095 .dpcm_capture = 1,
1096 .ops = &mt8195_capture_ops,
1097 SND_SOC_DAILINK_REG(UL8_FE),
1098 },
1099 [DAI_LINK_UL9_FE] = {
1100 .name = "UL9_FE",
1101 .stream_name = "UL9 Capture",
1102 .trigger = {
1103 SND_SOC_DPCM_TRIGGER_POST,
1104 SND_SOC_DPCM_TRIGGER_POST,
1105 },
1106 .dynamic = 1,
1107 .dpcm_capture = 1,
1108 .ops = &mt8195_capture_ops,
1109 SND_SOC_DAILINK_REG(UL9_FE),
1110 },
1111 [DAI_LINK_UL10_FE] = {
1112 .name = "UL10_FE",
1113 .stream_name = "UL10 Capture",
1114 .trigger = {
1115 SND_SOC_DPCM_TRIGGER_POST,
1116 SND_SOC_DPCM_TRIGGER_POST,
1117 },
1118 .dynamic = 1,
1119 .dpcm_capture = 1,
1120 .ops = &mt8195_capture_ops,
1121 SND_SOC_DAILINK_REG(UL10_FE),
1122 },
1123 /* BE */
1124 [DAI_LINK_DL_SRC_BE] = {
1125 .name = "DL_SRC_BE",
Trevor Wu40d605d2021-08-19 16:41:41 +08001126 .no_pcm = 1,
1127 .dpcm_playback = 1,
1128 SND_SOC_DAILINK_REG(DL_SRC_BE),
1129 },
1130 [DAI_LINK_DPTX_BE] = {
1131 .name = "DPTX_BE",
1132 .no_pcm = 1,
1133 .dpcm_playback = 1,
1134 .ops = &mt8195_dptx_ops,
Trevor Wu3abe2ee2021-09-17 16:28:05 +08001135 .be_hw_params_fixup = mt8195_dptx_hw_params_fixup,
Trevor Wu40d605d2021-08-19 16:41:41 +08001136 SND_SOC_DAILINK_REG(DPTX_BE),
1137 },
1138 [DAI_LINK_ETDM1_IN_BE] = {
1139 .name = "ETDM1_IN_BE",
1140 .no_pcm = 1,
1141 .dai_fmt = SND_SOC_DAIFMT_I2S |
1142 SND_SOC_DAIFMT_NB_NF |
1143 SND_SOC_DAIFMT_CBS_CFS,
1144 .dpcm_capture = 1,
1145 SND_SOC_DAILINK_REG(ETDM1_IN_BE),
1146 },
1147 [DAI_LINK_ETDM2_IN_BE] = {
1148 .name = "ETDM2_IN_BE",
1149 .no_pcm = 1,
1150 .dai_fmt = SND_SOC_DAIFMT_I2S |
1151 SND_SOC_DAIFMT_NB_NF |
1152 SND_SOC_DAIFMT_CBS_CFS,
1153 .dpcm_capture = 1,
1154 .init = mt8195_rt5682_init,
1155 .ops = &mt8195_rt5682_etdm_ops,
1156 .be_hw_params_fixup = mt8195_etdm_hw_params_fixup,
1157 SND_SOC_DAILINK_REG(ETDM2_IN_BE),
1158 },
1159 [DAI_LINK_ETDM1_OUT_BE] = {
1160 .name = "ETDM1_OUT_BE",
1161 .no_pcm = 1,
1162 .dai_fmt = SND_SOC_DAIFMT_I2S |
1163 SND_SOC_DAIFMT_NB_NF |
1164 SND_SOC_DAIFMT_CBS_CFS,
1165 .dpcm_playback = 1,
1166 .ops = &mt8195_rt5682_etdm_ops,
1167 .be_hw_params_fixup = mt8195_etdm_hw_params_fixup,
1168 SND_SOC_DAILINK_REG(ETDM1_OUT_BE),
1169 },
1170 [DAI_LINK_ETDM2_OUT_BE] = {
1171 .name = "ETDM2_OUT_BE",
1172 .no_pcm = 1,
1173 .dai_fmt = SND_SOC_DAIFMT_I2S |
1174 SND_SOC_DAIFMT_NB_NF |
1175 SND_SOC_DAIFMT_CBS_CFS,
1176 .dpcm_playback = 1,
1177 SND_SOC_DAILINK_REG(ETDM2_OUT_BE),
1178 },
1179 [DAI_LINK_ETDM3_OUT_BE] = {
1180 .name = "ETDM3_OUT_BE",
1181 .no_pcm = 1,
1182 .dai_fmt = SND_SOC_DAIFMT_I2S |
1183 SND_SOC_DAIFMT_NB_NF |
1184 SND_SOC_DAIFMT_CBS_CFS,
1185 .dpcm_playback = 1,
1186 SND_SOC_DAILINK_REG(ETDM3_OUT_BE),
1187 },
1188 [DAI_LINK_PCM1_BE] = {
1189 .name = "PCM1_BE",
1190 .no_pcm = 1,
1191 .dai_fmt = SND_SOC_DAIFMT_I2S |
1192 SND_SOC_DAIFMT_NB_NF |
1193 SND_SOC_DAIFMT_CBS_CFS,
Trevor Wudb5e1c22021-12-30 16:47:31 +08001194 .dpcm_playback = 1,
Trevor Wu40d605d2021-08-19 16:41:41 +08001195 .dpcm_capture = 1,
1196 SND_SOC_DAILINK_REG(PCM1_BE),
1197 },
1198 [DAI_LINK_UL_SRC1_BE] = {
1199 .name = "UL_SRC1_BE",
1200 .no_pcm = 1,
1201 .dpcm_capture = 1,
1202 SND_SOC_DAILINK_REG(UL_SRC1_BE),
1203 },
1204 [DAI_LINK_UL_SRC2_BE] = {
1205 .name = "UL_SRC2_BE",
1206 .no_pcm = 1,
1207 .dpcm_capture = 1,
1208 SND_SOC_DAILINK_REG(UL_SRC2_BE),
1209 },
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001210 /* SOF BE */
1211 [DAI_LINK_SOF_DL2_BE] = {
1212 .name = "AFE_SOF_DL2",
1213 .no_pcm = 1,
1214 .dpcm_playback = 1,
1215 SND_SOC_DAILINK_REG(AFE_SOF_DL2),
1216 },
1217 [DAI_LINK_SOF_DL3_BE] = {
1218 .name = "AFE_SOF_DL3",
1219 .no_pcm = 1,
1220 .dpcm_playback = 1,
1221 SND_SOC_DAILINK_REG(AFE_SOF_DL3),
1222 },
1223 [DAI_LINK_SOF_UL4_BE] = {
1224 .name = "AFE_SOF_UL4",
1225 .no_pcm = 1,
1226 .dpcm_capture = 1,
1227 SND_SOC_DAILINK_REG(AFE_SOF_UL4),
1228 },
1229 [DAI_LINK_SOF_UL5_BE] = {
1230 .name = "AFE_SOF_UL5",
1231 .no_pcm = 1,
1232 .dpcm_capture = 1,
1233 SND_SOC_DAILINK_REG(AFE_SOF_UL5),
1234 },
Trevor Wu40d605d2021-08-19 16:41:41 +08001235};
1236
1237static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = {
1238 .name = "mt8195_r1019_5682",
1239 .owner = THIS_MODULE,
1240 .dai_link = mt8195_mt6359_rt1019_rt5682_dai_links,
1241 .num_links = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_dai_links),
1242 .controls = mt8195_mt6359_rt1019_rt5682_controls,
1243 .num_controls = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_controls),
1244 .dapm_widgets = mt8195_mt6359_rt1019_rt5682_widgets,
1245 .num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_widgets),
1246 .dapm_routes = mt8195_mt6359_rt1019_rt5682_routes,
1247 .num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_routes),
Trevor Wuc5ab93e2021-12-28 14:48:21 +08001248 .set_bias_level_post = mt8195_set_bias_level_post,
Trevor Wu40d605d2021-08-19 16:41:41 +08001249};
1250
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001251static int mt8195_dailink_parse_of(struct snd_soc_card *card, struct device_node *np,
1252 const char *propname)
1253{
1254 struct device *dev = card->dev;
1255 struct snd_soc_dai_link *link;
1256 const char *dai_name = NULL;
1257 int i, j, ret, num_links;
1258
1259 num_links = of_property_count_strings(np, "mediatek,dai-link");
1260
1261 if (num_links < 0 || num_links > ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_dai_links)) {
1262 dev_dbg(dev, "number of dai-link is invalid\n");
1263 return -EINVAL;
1264 }
1265
1266 card->dai_link = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL);
1267 if (!card->dai_link)
1268 return -ENOMEM;
1269
1270 card->num_links = 0;
1271 link = card->dai_link;
1272
1273 for (i = 0; i < num_links; i++) {
1274 ret = of_property_read_string_index(np, propname, i, &dai_name);
1275 if (ret) {
1276 dev_dbg(dev, "ASoC: Property '%s' index %d could not be read: %d\n",
1277 propname, i, ret);
1278 return -EINVAL;
1279 }
1280
1281 for (j = 0; j < ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_dai_links); j++) {
1282 if (!strcmp(dai_name, mt8195_mt6359_rt1019_rt5682_dai_links[j].name)) {
1283 memcpy(link, &mt8195_mt6359_rt1019_rt5682_dai_links[j],
1284 sizeof(struct snd_soc_dai_link));
1285 link++;
1286 card->num_links++;
1287 break;
1288 }
1289 }
1290 }
1291
1292 if (card->num_links != num_links)
1293 return -EINVAL;
1294
1295 return 0;
1296}
1297
Trevor Wu40d605d2021-08-19 16:41:41 +08001298static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
1299{
1300 struct snd_soc_card *card = &mt8195_mt6359_rt1019_rt5682_soc_card;
Trevor Wu40d605d2021-08-19 16:41:41 +08001301 struct snd_soc_dai_link *dai_link;
Trevor Wubd8bec12021-10-01 11:16:01 +08001302 struct mt8195_mt6359_rt1019_rt5682_priv *priv;
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001303 struct device_node *platform_node, *adsp_node, *dp_node, *hdmi_node;
Trevor Wuc9d57a22021-11-29 22:10:54 +08001304 int is5682s = 0;
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001305 int init6359 = 0;
1306 int sof_on = 0;
Trevor Wu40d605d2021-08-19 16:41:41 +08001307 int ret, i;
1308
1309 card->dev = &pdev->dev;
1310
Trevor Wuc9d57a22021-11-29 22:10:54 +08001311 ret = snd_soc_of_parse_card_name(card, "model");
1312 if (ret) {
1313 dev_err(&pdev->dev, "%s new card name parsing error %d\n",
1314 __func__, ret);
1315 return ret;
1316 }
1317
1318 if (strstr(card->name, "_5682s"))
1319 is5682s = 1;
1320
Trevor Wubd8bec12021-10-01 11:16:01 +08001321 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1322 if (!priv)
1323 return -ENOMEM;
1324
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001325 platform_node = of_parse_phandle(pdev->dev.of_node,
1326 "mediatek,platform", 0);
1327 if (!platform_node) {
Trevor Wu40d605d2021-08-19 16:41:41 +08001328 dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n");
1329 return -EINVAL;
1330 }
1331
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001332 adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0);
1333 if (adsp_node)
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001334 sof_on = 1;
1335
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001336 dp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,dptx-codec", 0);
1337 hdmi_node = of_parse_phandle(pdev->dev.of_node,
1338 "mediatek,hdmi-codec", 0);
1339
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001340 if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) {
1341 ret = mt8195_dailink_parse_of(card, pdev->dev.of_node,
1342 "mediatek,dai-link");
1343 if (ret) {
1344 dev_dbg(&pdev->dev, "Parse dai-link fail\n");
1345 return -EINVAL;
1346 }
1347 } else {
1348 if (!sof_on)
1349 card->num_links = DAI_LINK_REGULAR_NUM;
1350 }
1351
Trevor Wu40d605d2021-08-19 16:41:41 +08001352 for_each_card_prelinks(card, i, dai_link) {
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001353 if (!dai_link->platforms->name) {
1354 if (!strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")) && sof_on)
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001355 dai_link->platforms->of_node = adsp_node;
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001356 else
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001357 dai_link->platforms->of_node = platform_node;
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001358 }
Trevor Wue581e302021-08-19 16:41:42 +08001359
1360 if (strcmp(dai_link->name, "DPTX_BE") == 0) {
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001361 if (!dp_node) {
Trevor Wu7eac1e22021-09-03 14:00:49 +08001362 dev_dbg(&pdev->dev, "No property 'dptx-codec'\n");
1363 } else {
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001364 dai_link->codecs->of_node = dp_node;
Trevor Wu7eac1e22021-09-03 14:00:49 +08001365 dai_link->codecs->name = NULL;
1366 dai_link->codecs->dai_name = "i2s-hifi";
1367 dai_link->init = mt8195_dptx_codec_init;
Trevor Wue581e302021-08-19 16:41:42 +08001368 }
Trevor Wuc9d57a22021-11-29 22:10:54 +08001369 } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001370 if (!hdmi_node) {
Trevor Wu7eac1e22021-09-03 14:00:49 +08001371 dev_dbg(&pdev->dev, "No property 'hdmi-codec'\n");
1372 } else {
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001373 dai_link->codecs->of_node = hdmi_node;
Trevor Wu7eac1e22021-09-03 14:00:49 +08001374 dai_link->codecs->name = NULL;
1375 dai_link->codecs->dai_name = "i2s-hifi";
1376 dai_link->init = mt8195_hdmi_codec_init;
Trevor Wuef46cd42021-08-19 16:41:43 +08001377 }
Trevor Wuc9d57a22021-11-29 22:10:54 +08001378 } else if (strcmp(dai_link->name, "ETDM1_OUT_BE") == 0 ||
1379 strcmp(dai_link->name, "ETDM2_IN_BE") == 0) {
1380 dai_link->codecs->name =
1381 is5682s ? RT5682S_DEV0_NAME : RT5682_DEV0_NAME;
1382 dai_link->codecs->dai_name =
1383 is5682s ? RT5682S_CODEC_DAI : RT5682_CODEC_DAI;
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001384 } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 ||
1385 strcmp(dai_link->name, "UL_SRC1_BE") == 0 ||
1386 strcmp(dai_link->name, "UL_SRC2_BE") == 0) {
1387 if (!init6359) {
1388 dai_link->init = mt8195_mt6359_init;
1389 init6359 = 1;
1390 }
Trevor Wuef46cd42021-08-19 16:41:43 +08001391 }
Trevor Wu40d605d2021-08-19 16:41:41 +08001392 }
1393
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001394 if (sof_on)
1395 card->late_probe = mt8195_mt6359_rt1019_rt5682_card_late_probe;
1396
Trevor Wu40d605d2021-08-19 16:41:41 +08001397 snd_soc_card_set_drvdata(card, priv);
1398
1399 ret = devm_snd_soc_register_card(&pdev->dev, card);
Bixuan Cuib2fc2c92021-09-11 16:12:46 +08001400
Tzung-Bi Shih082482a2021-12-24 14:47:19 +08001401 of_node_put(platform_node);
1402 of_node_put(adsp_node);
1403 of_node_put(dp_node);
1404 of_node_put(hdmi_node);
Trevor Wu40d605d2021-08-19 16:41:41 +08001405 return ret;
1406}
1407
1408#ifdef CONFIG_OF
1409static const struct of_device_id mt8195_mt6359_rt1019_rt5682_dt_match[] = {
1410 {.compatible = "mediatek,mt8195_mt6359_rt1019_rt5682",},
1411 {}
1412};
1413#endif
1414
1415static const struct dev_pm_ops mt8195_mt6359_rt1019_rt5682_pm_ops = {
1416 .poweroff = snd_soc_poweroff,
1417 .restore = snd_soc_resume,
1418};
1419
1420static struct platform_driver mt8195_mt6359_rt1019_rt5682_driver = {
1421 .driver = {
1422 .name = "mt8195_mt6359_rt1019_rt5682",
1423#ifdef CONFIG_OF
1424 .of_match_table = mt8195_mt6359_rt1019_rt5682_dt_match,
1425#endif
1426 .pm = &mt8195_mt6359_rt1019_rt5682_pm_ops,
1427 },
1428 .probe = mt8195_mt6359_rt1019_rt5682_dev_probe,
Trevor Wu40d605d2021-08-19 16:41:41 +08001429};
1430
1431module_platform_driver(mt8195_mt6359_rt1019_rt5682_driver);
1432
1433/* Module information */
1434MODULE_DESCRIPTION("MT8195-MT6359-RT1019-RT5682 ALSA SoC machine driver");
1435MODULE_AUTHOR("Trevor Wu <trevor.wu@mediatek.com>");
Trevor Wu3d00d2c2021-11-29 22:10:56 +08001436MODULE_AUTHOR("YC Hung <yc.hung@mediatek.com>");
1437MODULE_LICENSE("GPL");
Trevor Wu40d605d2021-08-19 16:41:41 +08001438MODULE_ALIAS("mt8195_mt6359_rt1019_rt5682 soc card");