File Index
Files and directories
Sign in
FILE

mt8186-mt6366.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/mediatek/mt8186/mt8186-mt6366.c C
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// mt8186-mt6366.c
   4//	--  MT8186-MT6366 ALSA SoC machine driver
   5//
   6// Copyright (c) 2022 MediaTek Inc.
   7// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
   8//
   9// Copyright (c) 2024 Collabora Ltd.
  10//                    AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
  11//
  12
  13#include <linux/gpio/consumer.h>
  14#include <linux/input.h>
  15#include <linux/module.h>
  16#include <linux/of.h>
  17#include <sound/jack.h>
  18#include <sound/pcm_params.h>
  19#include <sound/rt5682.h>
  20#include <sound/soc.h>
  21
  22#include "../../codecs/da7219.h"
  23#include "../../codecs/mt6358.h"
  24#include "../../codecs/rt5682.h"
  25#include "../common/mtk-afe-platform-driver.h"
  26#include "../common/mtk-dsp-sof-common.h"
  27#include "../common/mtk-soc-card.h"
  28#include "../common/mtk-soundcard-driver.h"
  29#include "mt8186-afe-common.h"
  30#include "mt8186-afe-clk.h"
  31#include "mt8186-afe-gpio.h"
  32#include "mt8186-mt6366-common.h"
  33
  34#define RT1019_CODEC_DAI	"HiFi"
  35#define RT1019_DEV0_NAME	"rt1019p"
  36
  37#define RT5682S_CODEC_DAI	"rt5682s-aif1"
  38#define RT5682S_DEV0_NAME	"rt5682s.5-001a"
  39
  40#define DA7219_CODEC_DAI	"da7219-hifi"
  41#define DA7219_DEV_NAME		"da7219.5-001a"
  42
  43#define SOF_DMA_DL1 "SOF_DMA_DL1"
  44#define SOF_DMA_DL2 "SOF_DMA_DL2"
  45#define SOF_DMA_UL1 "SOF_DMA_UL1"
  46#define SOF_DMA_UL2 "SOF_DMA_UL2"
  47
  48#define DA7219_CODEC_PRESENT	BIT(0)
  49
  50struct mt8186_mt6366_rt1019_rt5682s_priv {
  51	struct gpio_desc *dmic_sel;
  52	int dmic_switch;
  53};
  54
  55enum mt8186_jacks {
  56	MT8186_JACK_HEADSET,
  57	MT8186_JACK_HDMI,
  58	MT8186_JACK_MAX,
  59};
  60
  61/* Headset jack detection DAPM pins */
  62static struct snd_soc_jack_pin mt8186_jack_pins[] = {
  63	{
  64		.pin = "Headphone",
  65		.mask = SND_JACK_HEADPHONE,
  66	},
  67	{
  68		.pin = "Headset Mic",
  69		.mask = SND_JACK_MICROPHONE,
  70	},
  71};
  72
  73static struct snd_soc_codec_conf mt8186_mt6366_rt1019_rt5682s_codec_conf[] = {
  74	{
  75		.dlc = COMP_CODEC_CONF("mt6358-sound"),
  76		.name_prefix = "Mt6366",
  77	},
  78	{
  79		.dlc = COMP_CODEC_CONF("bt-sco"),
  80		.name_prefix = "Mt8186 bt",
  81	},
  82	{
  83		.dlc = COMP_CODEC_CONF("hdmi-audio-codec"),
  84		.name_prefix = "Mt8186 hdmi",
  85	},
  86};
  87
  88static int dmic_get(struct snd_kcontrol *kcontrol,
  89		    struct snd_ctl_elem_value *ucontrol)
  90{
  91	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
  92	struct snd_soc_card *card = snd_soc_dapm_to_card(dapm);
  93	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
  94	struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv;
  95
  96	ucontrol->value.integer.value[0] = priv->dmic_switch;
  97	return 0;
  98}
  99
 100static int dmic_set(struct snd_kcontrol *kcontrol,
 101		    struct snd_ctl_elem_value *ucontrol)
 102{
 103	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
 104	struct snd_soc_card *card = snd_soc_dapm_to_card(dapm);
 105	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
 106	struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv;
 107
 108	priv->dmic_switch = ucontrol->value.integer.value[0];
 109	if (priv->dmic_sel) {
 110		gpiod_set_value(priv->dmic_sel, priv->dmic_switch);
 111		dev_dbg(card->dev, "dmic_set_value %d\n",
 112			 priv->dmic_switch);
 113	}
 114	return 0;
 115}
 116
 117static const char * const dmic_mux_text[] = {
 118	"Front Mic",
 119	"Rear Mic",
 120};
 121
 122static SOC_ENUM_SINGLE_DECL(mt8186_dmic_enum,
 123			    SND_SOC_NOPM, 0, dmic_mux_text);
 124
 125static const struct snd_kcontrol_new mt8186_dmic_mux_control =
 126	SOC_DAPM_ENUM_EXT("DMIC Select Mux", mt8186_dmic_enum,
 127			  dmic_get, dmic_set);
 128
 129static const struct snd_soc_dapm_widget dmic_widgets[] = {
 130	SND_SOC_DAPM_MIC("DMIC", NULL),
 131	SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0, &mt8186_dmic_mux_control),
 132};
 133
 134static const struct snd_soc_dapm_route dmic_map[] = {
 135	/* digital mics */
 136	{"Dmic Mux", "Front Mic", "DMIC"},
 137	{"Dmic Mux", "Rear Mic", "DMIC"},
 138};
 139
 140static int primary_codec_init(struct snd_soc_pcm_runtime *rtd)
 141{
 142	struct snd_soc_card *card = rtd->card;
 143	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
 144	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
 145	struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv;
 146	int ret;
 147
 148	ret = mt8186_mt6366_init(rtd);
 149
 150	if (ret) {
 151		dev_err(card->dev, "mt8186_mt6366_init failed: %d\n", ret);
 152		return ret;
 153	}
 154
 155	if (!priv->dmic_sel) {
 156		dev_dbg(card->dev, "dmic_sel is null\n");
 157		return 0;
 158	}
 159
 160	ret = snd_soc_dapm_new_controls(dapm, dmic_widgets,
 161					ARRAY_SIZE(dmic_widgets));
 162	if (ret) {
 163		dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
 164		/* Don't need to add routes if widget addition failed */
 165		return ret;
 166	}
 167
 168	ret = snd_soc_dapm_add_routes(dapm, dmic_map,
 169				      ARRAY_SIZE(dmic_map));
 170
 171	if (ret)
 172		dev_err(card->dev, "DMic map addition failed: %d\n", ret);
 173
 174	return ret;
 175}
 176
 177static int mt8186_headset_codec_init(struct snd_soc_pcm_runtime *rtd)
 178{
 179	struct snd_soc_component *cmpnt_afe =
 180		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
 181	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
 182	struct mtk_soc_card_data *soc_card_data =
 183		snd_soc_card_get_drvdata(rtd->card);
 184	struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8186_JACK_HEADSET];
 185	struct snd_soc_component *cmpnt_codec =
 186		snd_soc_rtd_to_codec(rtd, 0)->component;
 187	const int hs_keys_rt5682[] = {
 188		KEY_PLAYPAUSE, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_VOICECOMMAND
 189	};
 190	const int hs_keys_da7219[] = {
 191		KEY_PLAYPAUSE, KEY_VOICECOMMAND, KEY_VOLUMEUP, KEY_VOLUMEDOWN
 192	};
 193	const int *hs_keys;
 194	int ret;
 195	int type;
 196
 197	ret = mt8186_dai_i2s_set_share(afe, "I2S1", "I2S0");
 198	if (ret) {
 199		dev_err(rtd->dev, "Failed to set up shared clocks\n");
 200		return ret;
 201	}
 202
 203	ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
 204				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
 205				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
 206				    SND_JACK_BTN_3,
 207				    jack, mt8186_jack_pins,
 208				    ARRAY_SIZE(mt8186_jack_pins));
 209	if (ret) {
 210		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
 211		return ret;
 212	}
 213
 214	if (soc_card_data->card_data->flags & DA7219_CODEC_PRESENT)
 215		hs_keys = hs_keys_da7219;
 216	else
 217		hs_keys = hs_keys_rt5682;
 218
 219	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, hs_keys[0]);
 220	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, hs_keys[1]);
 221	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, hs_keys[2]);
 222	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, hs_keys[3]);
 223
 224	type = SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3;
 225	return snd_soc_component_set_jack(cmpnt_codec, jack, (void *)&type);
 226}
 227
 228static int mt8186_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
 229				       struct snd_pcm_hw_params *params)
 230{
 231	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 232	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 233	struct snd_soc_dai *codec_dai;
 234	unsigned int rate = params_rate(params);
 235	unsigned int mclk_fs_ratio = 256;
 236	unsigned int mclk_fs = rate * mclk_fs_ratio;
 237	unsigned int freq;
 238	int ret, j;
 239
 240	ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
 241	if (ret < 0) {
 242		dev_err(rtd->dev, "failed to set cpu dai sysclk: %d\n", ret);
 243		return ret;
 244	}
 245
 246	for_each_rtd_codec_dais(rtd, j, codec_dai) {
 247		if (strcmp(codec_dai->component->name, DA7219_DEV_NAME))
 248			continue;
 249
 250		ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK,
 251					     mclk_fs, SND_SOC_CLOCK_IN);
 252		if (ret < 0) {
 253			dev_err(rtd->dev, "failed to set sysclk: %d\n", ret);
 254			return ret;
 255		}
 256
 257		if ((rate % 8000) == 0)
 258			freq = DA7219_PLL_FREQ_OUT_98304;
 259		else
 260			freq = DA7219_PLL_FREQ_OUT_90316;
 261
 262		ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM,
 263					  0, freq);
 264		if (ret) {
 265			dev_err(rtd->dev, "failed to start PLL: %d\n", ret);
 266			return ret;
 267		}
 268	}
 269
 270	return 0;
 271}
 272
 273static int mt8186_da7219_i2s_hw_free(struct snd_pcm_substream *substream)
 274{
 275	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 276	struct snd_soc_dai *codec_dai;
 277	int j, ret;
 278
 279	for_each_rtd_codec_dais(rtd, j, codec_dai) {
 280		if (strcmp(codec_dai->component->name, DA7219_DEV_NAME))
 281			continue;
 282
 283		ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
 284		if (ret < 0) {
 285			dev_err(rtd->dev, "failed to stop PLL: %d\n", ret);
 286			return ret;
 287		}
 288	}
 289
 290	return 0;
 291}
 292
 293static const struct snd_soc_ops mt8186_da7219_i2s_ops = {
 294	.hw_params = mt8186_da7219_i2s_hw_params,
 295	.hw_free = mt8186_da7219_i2s_hw_free,
 296};
 297
 298static int mt8186_rt5682s_i2s_hw_params(struct snd_pcm_substream *substream,
 299					struct snd_pcm_hw_params *params)
 300{
 301	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 302	struct snd_soc_card *card = rtd->card;
 303	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 304	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
 305	unsigned int rate = params_rate(params);
 306	unsigned int mclk_fs_ratio = 128;
 307	unsigned int mclk_fs = rate * mclk_fs_ratio;
 308	int bitwidth;
 309	int ret;
 310
 311	bitwidth = snd_pcm_format_width(params_format(params));
 312	if (bitwidth < 0) {
 313		dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
 314		return bitwidth;
 315	}
 316
 317	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
 318	if (ret) {
 319		dev_err(card->dev, "failed to set tdm slot\n");
 320		return ret;
 321	}
 322
 323	ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1,
 324				  RT5682_PLL1_S_BCLK1,
 325				  params_rate(params) * 64,
 326				  params_rate(params) * 512);
 327	if (ret) {
 328		dev_err(card->dev, "failed to set pll\n");
 329		return ret;
 330	}
 331
 332	ret = snd_soc_dai_set_sysclk(codec_dai,
 333				     RT5682_SCLK_S_PLL1,
 334				     params_rate(params) * 512,
 335				     SND_SOC_CLOCK_IN);
 336	if (ret) {
 337		dev_err(card->dev, "failed to set sysclk\n");
 338		return ret;
 339	}
 340
 341	return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
 342}
 343
 344static const struct snd_soc_ops mt8186_rt5682s_i2s_ops = {
 345	.hw_params = mt8186_rt5682s_i2s_hw_params,
 346};
 347
 348static int mt8186_mt6366_rt1019_rt5682s_hdmi_init(struct snd_soc_pcm_runtime *rtd)
 349{
 350	struct snd_soc_component *cmpnt_afe =
 351		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
 352	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
 353	struct snd_soc_component *cmpnt_codec =
 354		snd_soc_rtd_to_codec(rtd, 0)->component;
 355	struct mtk_soc_card_data *soc_card_data =
 356		snd_soc_card_get_drvdata(rtd->card);
 357	struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8186_JACK_HDMI];
 358	int ret;
 359
 360	ret = mt8186_dai_i2s_set_share(afe, "I2S2", "I2S3");
 361	if (ret) {
 362		dev_err(rtd->dev, "Failed to set up shared clocks\n");
 363		return ret;
 364	}
 365
 366	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_AVOUT, jack);
 367	if (ret) {
 368		dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
 369		return ret;
 370	}
 371
 372	return snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
 373}
 374
 375static int mt8186_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 376				  struct snd_pcm_hw_params *params,
 377				  snd_pcm_format_t fmt)
 378{
 379	struct snd_interval *channels = hw_param_interval(params,
 380		SNDRV_PCM_HW_PARAM_CHANNELS);
 381
 382	dev_dbg(rtd->dev, "%s(), fix format to %d\n", __func__, fmt);
 383
 384	/* fix BE i2s channel to 2 channel */
 385	channels->min = 2;
 386	channels->max = 2;
 387
 388	/* clean param mask first */
 389	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
 390			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
 391
 392	params_set_format(params, fmt);
 393
 394	return 0;
 395}
 396
 397static int mt8186_i2s_hw_params_24le_fixup(struct snd_soc_pcm_runtime *rtd,
 398					   struct snd_pcm_hw_params *params)
 399{
 400	return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S24_LE);
 401}
 402
 403static int mt8186_i2s_hw_params_32le_fixup(struct snd_soc_pcm_runtime *rtd,
 404					   struct snd_pcm_hw_params *params)
 405{
 406	return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S32_LE);
 407}
 408
 409/* fixup the BE DAI link to match any values from topology */
 410static int mt8186_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
 411				     struct snd_pcm_hw_params *params)
 412{
 413	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);
 414	int ret;
 415
 416	ret = mtk_sof_dai_link_fixup(rtd, params);
 417
 418	if (!strcmp(rtd->dai_link->name, "I2S0") ||
 419	    !strcmp(rtd->dai_link->name, "I2S1") ||
 420	    !strcmp(rtd->dai_link->name, "I2S2")) {
 421		if (soc_card_data->card_data->flags & DA7219_CODEC_PRESENT)
 422			mt8186_i2s_hw_params_32le_fixup(rtd, params);
 423		else
 424			mt8186_i2s_hw_params_24le_fixup(rtd, params);
 425	} else if (!strcmp(rtd->dai_link->name, "I2S3")) {
 426		if (soc_card_data->card_data->flags & DA7219_CODEC_PRESENT)
 427			mt8186_i2s_hw_params_24le_fixup(rtd, params);
 428		else
 429			mt8186_i2s_hw_params_32le_fixup(rtd, params);
 430	}
 431
 432	return ret;
 433}
 434
 435/* FE */
 436SND_SOC_DAILINK_DEFS(playback1,
 437		     DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
 438		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 439		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 440
 441SND_SOC_DAILINK_DEFS(playback12,
 442		     DAILINK_COMP_ARRAY(COMP_CPU("DL12")),
 443		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 444		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 445
 446SND_SOC_DAILINK_DEFS(playback2,
 447		     DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
 448		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 449		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 450
 451SND_SOC_DAILINK_DEFS(playback3,
 452		     DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
 453		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 454		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 455
 456SND_SOC_DAILINK_DEFS(playback4,
 457		     DAILINK_COMP_ARRAY(COMP_CPU("DL4")),
 458		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 459		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 460
 461SND_SOC_DAILINK_DEFS(playback5,
 462		     DAILINK_COMP_ARRAY(COMP_CPU("DL5")),
 463		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 464		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 465
 466SND_SOC_DAILINK_DEFS(playback6,
 467		     DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
 468		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 469		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 470
 471SND_SOC_DAILINK_DEFS(playback7,
 472		     DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
 473		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 474		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 475
 476SND_SOC_DAILINK_DEFS(playback8,
 477		     DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
 478		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 479		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 480
 481SND_SOC_DAILINK_DEFS(capture1,
 482		     DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
 483		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 484		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 485
 486SND_SOC_DAILINK_DEFS(capture2,
 487		     DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
 488		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 489		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 490
 491SND_SOC_DAILINK_DEFS(capture3,
 492		     DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
 493		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 494		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 495
 496SND_SOC_DAILINK_DEFS(capture4,
 497		     DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
 498		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 499		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 500
 501SND_SOC_DAILINK_DEFS(capture5,
 502		     DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
 503		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 504		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 505
 506SND_SOC_DAILINK_DEFS(capture6,
 507		     DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
 508		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 509		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 510
 511SND_SOC_DAILINK_DEFS(capture7,
 512		     DAILINK_COMP_ARRAY(COMP_CPU("UL7")),
 513		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 514		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 515
 516/* hostless */
 517SND_SOC_DAILINK_DEFS(hostless_lpbk,
 518		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless LPBK DAI")),
 519		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 520		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 521SND_SOC_DAILINK_DEFS(hostless_fm,
 522		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless FM DAI")),
 523		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 524		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 525SND_SOC_DAILINK_DEFS(hostless_src1,
 526		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_1_DAI")),
 527		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 528		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 529SND_SOC_DAILINK_DEFS(hostless_src_bargein,
 530		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_Bargein_DAI")),
 531		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 532		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 533
 534/* BE */
 535SND_SOC_DAILINK_DEFS(adda,
 536		     DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
 537		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound",
 538						   "mt6358-snd-codec-aif1"),
 539					COMP_CODEC("dmic-codec",
 540						   "dmic-hifi")),
 541		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 542SND_SOC_DAILINK_DEFS(i2s0,
 543		     DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
 544		     DAILINK_COMP_ARRAY(COMP_EMPTY()),
 545		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 546SND_SOC_DAILINK_DEFS(i2s1,
 547		     DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
 548		     DAILINK_COMP_ARRAY(COMP_EMPTY()),
 549		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 550SND_SOC_DAILINK_DEFS(i2s2,
 551		     DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
 552		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 553		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 554SND_SOC_DAILINK_DEFS(i2s3,
 555		     DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
 556		     DAILINK_COMP_ARRAY(COMP_EMPTY()),
 557		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 558SND_SOC_DAILINK_DEFS(hw_gain1,
 559		     DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 1")),
 560		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 561		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 562SND_SOC_DAILINK_DEFS(hw_gain2,
 563		     DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 2")),
 564		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 565		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 566SND_SOC_DAILINK_DEFS(hw_src1,
 567		     DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_1")),
 568		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 569		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 570SND_SOC_DAILINK_DEFS(hw_src2,
 571		     DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_2")),
 572		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 573		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 574SND_SOC_DAILINK_DEFS(connsys_i2s,
 575		     DAILINK_COMP_ARRAY(COMP_CPU("CONNSYS_I2S")),
 576		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 577		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 578SND_SOC_DAILINK_DEFS(pcm1,
 579		     DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
 580		     DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm-wb")),
 581		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 582SND_SOC_DAILINK_DEFS(tdm_in,
 583		     DAILINK_COMP_ARRAY(COMP_CPU("TDM IN")),
 584		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 585		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 586
 587/* hostless */
 588SND_SOC_DAILINK_DEFS(hostless_ul1,
 589		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL1 DAI")),
 590		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 591		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 592SND_SOC_DAILINK_DEFS(hostless_ul2,
 593		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL2 DAI")),
 594		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 595		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 596SND_SOC_DAILINK_DEFS(hostless_ul3,
 597		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL3 DAI")),
 598		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 599		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 600SND_SOC_DAILINK_DEFS(hostless_ul5,
 601		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL5 DAI")),
 602		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 603		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 604SND_SOC_DAILINK_DEFS(hostless_ul6,
 605		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL6 DAI")),
 606		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 607		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 608SND_SOC_DAILINK_DEFS(hostless_hw_gain_aaudio,
 609		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless HW Gain AAudio DAI")),
 610		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 611		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 612SND_SOC_DAILINK_DEFS(hostless_src_aaudio,
 613		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless SRC AAudio DAI")),
 614		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 615		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 616SND_SOC_DAILINK_DEFS(AFE_SOF_DL1,
 617		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL1")),
 618		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 619		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 620
 621SND_SOC_DAILINK_DEFS(AFE_SOF_DL2,
 622		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")),
 623		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 624		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 625
 626SND_SOC_DAILINK_DEFS(AFE_SOF_UL1,
 627		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL1")),
 628		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 629		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 630
 631SND_SOC_DAILINK_DEFS(AFE_SOF_UL2,
 632		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL2")),
 633		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
 634		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 635
 636static const struct sof_conn_stream g_sof_conn_streams[] = {
 637	{ "I2S1", "AFE_SOF_DL1", SOF_DMA_DL1, SNDRV_PCM_STREAM_PLAYBACK},
 638	{ "I2S3", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK},
 639	{ "Primary Codec", "AFE_SOF_UL1", SOF_DMA_UL1, SNDRV_PCM_STREAM_CAPTURE},
 640	{ "I2S0", "AFE_SOF_UL2", SOF_DMA_UL2, SNDRV_PCM_STREAM_CAPTURE},
 641};
 642
 643static struct snd_soc_dai_link mt8186_mt6366_rt1019_rt5682s_dai_links[] = {
 644	/* Front End DAI links */
 645	{
 646		.name = "Playback_1",
 647		.stream_name = "Playback_1",
 648		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 649			    SND_SOC_DPCM_TRIGGER_PRE},
 650		.dynamic = 1,
 651		.playback_only = 1,
 652		.dpcm_merged_format = 1,
 653		.dpcm_merged_chan = 1,
 654		.dpcm_merged_rate = 1,
 655		.ops = &mtk_soundcard_common_playback_ops,
 656		SND_SOC_DAILINK_REG(playback1),
 657	},
 658	{
 659		.name = "Playback_12",
 660		.stream_name = "Playback_12",
 661		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 662			    SND_SOC_DPCM_TRIGGER_PRE},
 663		.dynamic = 1,
 664		.playback_only = 1,
 665		SND_SOC_DAILINK_REG(playback12),
 666	},
 667	{
 668		.name = "Playback_2",
 669		.stream_name = "Playback_2",
 670		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 671			    SND_SOC_DPCM_TRIGGER_PRE},
 672		.dynamic = 1,
 673		.playback_only = 1,
 674		.dpcm_merged_format = 1,
 675		.dpcm_merged_chan = 1,
 676		.dpcm_merged_rate = 1,
 677		SND_SOC_DAILINK_REG(playback2),
 678	},
 679	{
 680		.name = "Playback_3",
 681		.stream_name = "Playback_3",
 682		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 683			    SND_SOC_DPCM_TRIGGER_PRE},
 684		.dynamic = 1,
 685		.playback_only = 1,
 686		.dpcm_merged_format = 1,
 687		.dpcm_merged_chan = 1,
 688		.dpcm_merged_rate = 1,
 689		.ops = &mtk_soundcard_common_playback_ops,
 690		SND_SOC_DAILINK_REG(playback3),
 691	},
 692	{
 693		.name = "Playback_4",
 694		.stream_name = "Playback_4",
 695		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 696			    SND_SOC_DPCM_TRIGGER_PRE},
 697		.dynamic = 1,
 698		.playback_only = 1,
 699		SND_SOC_DAILINK_REG(playback4),
 700	},
 701	{
 702		.name = "Playback_5",
 703		.stream_name = "Playback_5",
 704		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 705			    SND_SOC_DPCM_TRIGGER_PRE},
 706		.dynamic = 1,
 707		.playback_only = 1,
 708		SND_SOC_DAILINK_REG(playback5),
 709	},
 710	{
 711		.name = "Playback_6",
 712		.stream_name = "Playback_6",
 713		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 714			    SND_SOC_DPCM_TRIGGER_PRE},
 715		.dynamic = 1,
 716		.playback_only = 1,
 717		SND_SOC_DAILINK_REG(playback6),
 718	},
 719	{
 720		.name = "Playback_7",
 721		.stream_name = "Playback_7",
 722		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 723			    SND_SOC_DPCM_TRIGGER_PRE},
 724		.dynamic = 1,
 725		.playback_only = 1,
 726		SND_SOC_DAILINK_REG(playback7),
 727	},
 728	{
 729		.name = "Playback_8",
 730		.stream_name = "Playback_8",
 731		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 732			    SND_SOC_DPCM_TRIGGER_PRE},
 733		.dynamic = 1,
 734		.playback_only = 1,
 735		SND_SOC_DAILINK_REG(playback8),
 736	},
 737	{
 738		.name = "Capture_1",
 739		.stream_name = "Capture_1",
 740		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 741			    SND_SOC_DPCM_TRIGGER_PRE},
 742		.dynamic = 1,
 743		.capture_only = 1,
 744		SND_SOC_DAILINK_REG(capture1),
 745	},
 746	{
 747		.name = "Capture_2",
 748		.stream_name = "Capture_2",
 749		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 750			    SND_SOC_DPCM_TRIGGER_PRE},
 751		.dynamic = 1,
 752		.capture_only = 1,
 753		.dpcm_merged_format = 1,
 754		.dpcm_merged_chan = 1,
 755		.dpcm_merged_rate = 1,
 756		.ops = &mtk_soundcard_common_capture_ops,
 757		SND_SOC_DAILINK_REG(capture2),
 758	},
 759	{
 760		.name = "Capture_3",
 761		.stream_name = "Capture_3",
 762		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 763			    SND_SOC_DPCM_TRIGGER_PRE},
 764		.dynamic = 1,
 765		.capture_only = 1,
 766		SND_SOC_DAILINK_REG(capture3),
 767	},
 768	{
 769		.name = "Capture_4",
 770		.stream_name = "Capture_4",
 771		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 772			    SND_SOC_DPCM_TRIGGER_PRE},
 773		.dynamic = 1,
 774		.capture_only = 1,
 775		.dpcm_merged_format = 1,
 776		.dpcm_merged_chan = 1,
 777		.dpcm_merged_rate = 1,
 778		.ops = &mtk_soundcard_common_capture_ops,
 779		SND_SOC_DAILINK_REG(capture4),
 780	},
 781	{
 782		.name = "Capture_5",
 783		.stream_name = "Capture_5",
 784		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 785			    SND_SOC_DPCM_TRIGGER_PRE},
 786		.dynamic = 1,
 787		.capture_only = 1,
 788		SND_SOC_DAILINK_REG(capture5),
 789	},
 790	{
 791		.name = "Capture_6",
 792		.stream_name = "Capture_6",
 793		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 794			    SND_SOC_DPCM_TRIGGER_PRE},
 795		.dynamic = 1,
 796		.capture_only = 1,
 797		.dpcm_merged_format = 1,
 798		.dpcm_merged_chan = 1,
 799		.dpcm_merged_rate = 1,
 800		SND_SOC_DAILINK_REG(capture6),
 801	},
 802	{
 803		.name = "Capture_7",
 804		.stream_name = "Capture_7",
 805		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 806			    SND_SOC_DPCM_TRIGGER_PRE},
 807		.dynamic = 1,
 808		.capture_only = 1,
 809		SND_SOC_DAILINK_REG(capture7),
 810	},
 811	{
 812		.name = "Hostless_LPBK",
 813		.stream_name = "Hostless_LPBK",
 814		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 815			    SND_SOC_DPCM_TRIGGER_PRE},
 816		.dynamic = 1,
 817		.ignore_suspend = 1,
 818		SND_SOC_DAILINK_REG(hostless_lpbk),
 819	},
 820	{
 821		.name = "Hostless_FM",
 822		.stream_name = "Hostless_FM",
 823		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 824			    SND_SOC_DPCM_TRIGGER_PRE},
 825		.dynamic = 1,
 826		.ignore_suspend = 1,
 827		SND_SOC_DAILINK_REG(hostless_fm),
 828	},
 829	{
 830		.name = "Hostless_SRC_1",
 831		.stream_name = "Hostless_SRC_1",
 832		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 833			    SND_SOC_DPCM_TRIGGER_PRE},
 834		.dynamic = 1,
 835		.ignore_suspend = 1,
 836		SND_SOC_DAILINK_REG(hostless_src1),
 837	},
 838	{
 839		.name = "Hostless_SRC_Bargein",
 840		.stream_name = "Hostless_SRC_Bargein",
 841		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 842			    SND_SOC_DPCM_TRIGGER_PRE},
 843		.dynamic = 1,
 844		.ignore_suspend = 1,
 845		SND_SOC_DAILINK_REG(hostless_src_bargein),
 846	},
 847	{
 848		.name = "Hostless_HW_Gain_AAudio",
 849		.stream_name = "Hostless_HW_Gain_AAudio",
 850		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 851			    SND_SOC_DPCM_TRIGGER_PRE},
 852		.dynamic = 1,
 853		.capture_only = 1,
 854		.ignore_suspend = 1,
 855		SND_SOC_DAILINK_REG(hostless_hw_gain_aaudio),
 856	},
 857	{
 858		.name = "Hostless_SRC_AAudio",
 859		.stream_name = "Hostless_SRC_AAudio",
 860		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
 861			    SND_SOC_DPCM_TRIGGER_PRE},
 862		.dynamic = 1,
 863		.ignore_suspend = 1,
 864		SND_SOC_DAILINK_REG(hostless_src_aaudio),
 865	},
 866	/* Back End DAI links */
 867	{
 868		.name = "Primary Codec",
 869		.no_pcm = 1,
 870		.ignore_suspend = 1,
 871		.init = primary_codec_init,
 872		SND_SOC_DAILINK_REG(adda),
 873	},
 874	{
 875		.name = "I2S3",
 876		.no_pcm = 1,
 877		.dai_fmt = SND_SOC_DAIFMT_I2S |
 878			   SND_SOC_DAIFMT_IB_IF |
 879			   SND_SOC_DAIFMT_CBP_CFP,
 880		.playback_only = 1,
 881		.ignore_suspend = 1,
 882		.init = mt8186_mt6366_rt1019_rt5682s_hdmi_init,
 883		SND_SOC_DAILINK_REG(i2s3),
 884	},
 885	{
 886		.name = "I2S0",
 887		.no_pcm = 1,
 888		.capture_only = 1,
 889		.ignore_suspend = 1,
 890		.ops = &mt8186_rt5682s_i2s_ops,
 891		SND_SOC_DAILINK_REG(i2s0),
 892	},
 893	{
 894		.name = "I2S1",
 895		.no_pcm = 1,
 896		.playback_only = 1,
 897		.ignore_suspend = 1,
 898		.init = mt8186_headset_codec_init,
 899		SND_SOC_DAILINK_REG(i2s1),
 900	},
 901	{
 902		.name = "I2S2",
 903		.no_pcm = 1,
 904		.capture_only = 1,
 905		.ignore_suspend = 1,
 906		SND_SOC_DAILINK_REG(i2s2),
 907	},
 908	{
 909		.name = "HW Gain 1",
 910		.no_pcm = 1,
 911		.ignore_suspend = 1,
 912		SND_SOC_DAILINK_REG(hw_gain1),
 913	},
 914	{
 915		.name = "HW Gain 2",
 916		.no_pcm = 1,
 917		.ignore_suspend = 1,
 918		SND_SOC_DAILINK_REG(hw_gain2),
 919	},
 920	{
 921		.name = "HW_SRC_1",
 922		.no_pcm = 1,
 923		.ignore_suspend = 1,
 924		SND_SOC_DAILINK_REG(hw_src1),
 925	},
 926	{
 927		.name = "HW_SRC_2",
 928		.no_pcm = 1,
 929		.ignore_suspend = 1,
 930		SND_SOC_DAILINK_REG(hw_src2),
 931	},
 932	{
 933		.name = "CONNSYS_I2S",
 934		.no_pcm = 1,
 935		.capture_only = 1,
 936		.ignore_suspend = 1,
 937		SND_SOC_DAILINK_REG(connsys_i2s),
 938	},
 939	{
 940		.name = "PCM 1",
 941		.dai_fmt = SND_SOC_DAIFMT_I2S |
 942			   SND_SOC_DAIFMT_NB_IF,
 943		.no_pcm = 1,
 944		.ignore_suspend = 1,
 945		SND_SOC_DAILINK_REG(pcm1),
 946	},
 947	{
 948		.name = "TDM IN",
 949		.no_pcm = 1,
 950		.capture_only = 1,
 951		.ignore_suspend = 1,
 952		SND_SOC_DAILINK_REG(tdm_in),
 953	},
 954	/* dummy BE for ul memif to record from dl memif */
 955	{
 956		.name = "Hostless_UL1",
 957		.no_pcm = 1,
 958		.capture_only = 1,
 959		.ignore_suspend = 1,
 960		SND_SOC_DAILINK_REG(hostless_ul1),
 961	},
 962	{
 963		.name = "Hostless_UL2",
 964		.no_pcm = 1,
 965		.capture_only = 1,
 966		.ignore_suspend = 1,
 967		SND_SOC_DAILINK_REG(hostless_ul2),
 968	},
 969	{
 970		.name = "Hostless_UL3",
 971		.no_pcm = 1,
 972		.capture_only = 1,
 973		.ignore_suspend = 1,
 974		SND_SOC_DAILINK_REG(hostless_ul3),
 975	},
 976	{
 977		.name = "Hostless_UL5",
 978		.no_pcm = 1,
 979		.capture_only = 1,
 980		.ignore_suspend = 1,
 981		SND_SOC_DAILINK_REG(hostless_ul5),
 982	},
 983	{
 984		.name = "Hostless_UL6",
 985		.no_pcm = 1,
 986		.capture_only = 1,
 987		.ignore_suspend = 1,
 988		SND_SOC_DAILINK_REG(hostless_ul6),
 989	},
 990	/* SOF BE */
 991	{
 992		.name = "AFE_SOF_DL1",
 993		.no_pcm = 1,
 994		.playback_only = 1,
 995		SND_SOC_DAILINK_REG(AFE_SOF_DL1),
 996	},
 997	{
 998		.name = "AFE_SOF_DL2",
 999		.no_pcm = 1,
1000		.playback_only = 1,
1001		SND_SOC_DAILINK_REG(AFE_SOF_DL2),
1002	},
1003	{
1004		.name = "AFE_SOF_UL1",
1005		.no_pcm = 1,
1006		.capture_only = 1,
1007		SND_SOC_DAILINK_REG(AFE_SOF_UL1),
1008	},
1009	{
1010		.name = "AFE_SOF_UL2",
1011		.no_pcm = 1,
1012		.capture_only = 1,
1013		SND_SOC_DAILINK_REG(AFE_SOF_UL2),
1014	},
1015};
1016
1017static const struct snd_soc_dapm_widget
1018mt8186_mt6366_da7219_max98357_widgets[] = {
1019	SND_SOC_DAPM_SPK("Speakers", NULL),
1020	SND_SOC_DAPM_HP("Headphones", NULL),
1021	SND_SOC_DAPM_MIC("Headset Mic", NULL),
1022	SND_SOC_DAPM_LINE("Line Out", NULL),
1023	SND_SOC_DAPM_LINE("HDMI1", NULL),
1024	SND_SOC_DAPM_MIXER(SOF_DMA_DL1, SND_SOC_NOPM, 0, 0, NULL, 0),
1025	SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0),
1026	SND_SOC_DAPM_MIXER(SOF_DMA_UL1, SND_SOC_NOPM, 0, 0, NULL, 0),
1027	SND_SOC_DAPM_MIXER(SOF_DMA_UL2, SND_SOC_NOPM, 0, 0, NULL, 0),
1028};
1029
1030static const struct snd_soc_dapm_widget
1031mt8186_mt6366_rt1019_rt5682s_widgets[] = {
1032	SND_SOC_DAPM_SPK("Speakers", NULL),
1033	SND_SOC_DAPM_HP("Headphone", NULL),
1034	SND_SOC_DAPM_MIC("Headset Mic", NULL),
1035	SND_SOC_DAPM_OUTPUT("HDMI1"),
1036	SND_SOC_DAPM_MIXER(SOF_DMA_DL1, SND_SOC_NOPM, 0, 0, NULL, 0),
1037	SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0),
1038	SND_SOC_DAPM_MIXER(SOF_DMA_UL1, SND_SOC_NOPM, 0, 0, NULL, 0),
1039	SND_SOC_DAPM_MIXER(SOF_DMA_UL2, SND_SOC_NOPM, 0, 0, NULL, 0),
1040};
1041
1042static const struct snd_soc_dapm_route
1043mt8186_mt6366_rt1019_rt5682s_routes[] = {
1044	/* SPK */
1045	{ "Speakers", NULL, "Speaker" },
1046	/* Headset */
1047	{ "Headphone", NULL, "HPOL" },
1048	{ "Headphone", NULL, "HPOR" },
1049	{ "IN1P", NULL, "Headset Mic" },
1050	/* HDMI */
1051	{ "HDMI1", NULL, "TX" },
1052	/* SOF Uplink */
1053	{SOF_DMA_UL1, NULL, "UL1_CH1"},
1054	{SOF_DMA_UL1, NULL, "UL1_CH2"},
1055	{SOF_DMA_UL2, NULL, "UL2_CH1"},
1056	{SOF_DMA_UL2, NULL, "UL2_CH2"},
1057	/* SOF Downlink */
1058	{"DSP_DL1_VIRT", NULL, SOF_DMA_DL1},
1059	{"DSP_DL2_VIRT", NULL, SOF_DMA_DL2},
1060};
1061
1062static const struct snd_soc_dapm_route mt8186_mt6366_rt5650_routes[] = {
1063	/* SPK */
1064	{"Speakers", NULL, "SPOL"},
1065	{"Speakers", NULL, "SPOR"},
1066	/* Headset */
1067	{ "Headphone", NULL, "HPOL" },
1068	{ "Headphone", NULL, "HPOR" },
1069	{ "IN1P", NULL, "Headset Mic" },
1070	{ "IN1N", NULL, "Headset Mic"},
1071	/* HDMI */
1072	{ "HDMI1", NULL, "TX" },
1073	/* SOF Uplink */
1074	{SOF_DMA_UL1, NULL, "UL1_CH1"},
1075	{SOF_DMA_UL1, NULL, "UL1_CH2"},
1076	{SOF_DMA_UL2, NULL, "UL2_CH1"},
1077	{SOF_DMA_UL2, NULL, "UL2_CH2"},
1078	/* SOF Downlink */
1079	{"DSP_DL1_VIRT", NULL, SOF_DMA_DL1},
1080	{"DSP_DL2_VIRT", NULL, SOF_DMA_DL2},
1081};
1082
1083static const struct snd_kcontrol_new mt8186_mt6366_da7219_max98357_controls[] = {
1084	SOC_DAPM_PIN_SWITCH("Speakers"),
1085	SOC_DAPM_PIN_SWITCH("Headphones"),
1086	SOC_DAPM_PIN_SWITCH("Headset Mic"),
1087	SOC_DAPM_PIN_SWITCH("Line Out"),
1088	SOC_DAPM_PIN_SWITCH("HDMI1"),
1089};
1090
1091static const struct snd_kcontrol_new
1092mt8186_mt6366_rt1019_rt5682s_controls[] = {
1093	SOC_DAPM_PIN_SWITCH("Speakers"),
1094	SOC_DAPM_PIN_SWITCH("Headphone"),
1095	SOC_DAPM_PIN_SWITCH("Headset Mic"),
1096	SOC_DAPM_PIN_SWITCH("HDMI1"),
1097};
1098
1099static struct snd_soc_card mt8186_mt6366_da7219_max98357_soc_card = {
1100	.name = "mt8186_da7219_max98357",
1101	.owner = THIS_MODULE,
1102	.dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
1103	.num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
1104	.controls = mt8186_mt6366_da7219_max98357_controls,
1105	.num_controls = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_controls),
1106	.dapm_widgets = mt8186_mt6366_da7219_max98357_widgets,
1107	.num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_widgets),
1108	.dapm_routes = mt8186_mt6366_rt1019_rt5682s_routes,
1109	.num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_routes),
1110	.codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
1111	.num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
1112};
1113
1114static struct snd_soc_card mt8186_mt6366_rt1019_rt5682s_soc_card = {
1115	.name = "mt8186_rt1019_rt5682s",
1116	.owner = THIS_MODULE,
1117	.dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
1118	.num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
1119	.controls = mt8186_mt6366_rt1019_rt5682s_controls,
1120	.num_controls = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_controls),
1121	.dapm_widgets = mt8186_mt6366_rt1019_rt5682s_widgets,
1122	.num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_widgets),
1123	.dapm_routes = mt8186_mt6366_rt1019_rt5682s_routes,
1124	.num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_routes),
1125	.codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
1126	.num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
1127};
1128
1129static struct snd_soc_card mt8186_mt6366_rt5682s_max98360_soc_card = {
1130	.name = "mt8186_rt5682s_max98360",
1131	.owner = THIS_MODULE,
1132	.dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
1133	.num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
1134	.controls = mt8186_mt6366_rt1019_rt5682s_controls,
1135	.num_controls = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_controls),
1136	.dapm_widgets = mt8186_mt6366_rt1019_rt5682s_widgets,
1137	.num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_widgets),
1138	.dapm_routes = mt8186_mt6366_rt1019_rt5682s_routes,
1139	.num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_routes),
1140	.codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
1141	.num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
1142};
1143
1144static struct snd_soc_card mt8186_mt6366_rt5650_soc_card = {
1145	.name = "mt8186_rt5650",
1146	.owner = THIS_MODULE,
1147	.dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
1148	.num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
1149	.controls = mt8186_mt6366_rt1019_rt5682s_controls,
1150	.num_controls = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_controls),
1151	.dapm_widgets = mt8186_mt6366_rt1019_rt5682s_widgets,
1152	.num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_widgets),
1153	.dapm_routes = mt8186_mt6366_rt5650_routes,
1154	.num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt5650_routes),
1155	.codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
1156	.num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
1157};
1158
1159static int mt8186_mt6366_legacy_probe(struct mtk_soc_card_data *soc_card_data)
1160{
1161	struct mtk_platform_card_data *card_data = soc_card_data->card_data;
1162	struct snd_soc_card *card = card_data->card;
1163	struct device *dev = card->dev;
1164	struct snd_soc_dai_link *dai_link;
1165	struct device_node *headset_codec, *playback_codec;
1166	int ret, i;
1167
1168	playback_codec = of_get_child_by_name(dev->of_node, "playback-codecs");
1169	if (!playback_codec)
1170		return dev_err_probe(dev, -EINVAL,
1171				     "Property 'playback-codecs' missing or invalid\n");
1172
1173	headset_codec = of_get_child_by_name(dev->of_node, "headset-codec");
1174	if (!headset_codec) {
1175		of_node_put(playback_codec);
1176		return dev_err_probe(dev, -EINVAL,
1177				     "Property 'headset-codec' missing or invalid\n");
1178	}
1179
1180	for_each_card_prelinks(card, i, dai_link) {
1181		ret = mt8186_mt6366_card_set_be_link(card, dai_link, playback_codec, "I2S3");
1182		if (ret) {
1183			dev_err_probe(dev, ret, "%s set playback_codec fail\n",
1184				      dai_link->name);
1185			break;
1186		}
1187
1188		ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S0");
1189		if (ret) {
1190			dev_err_probe(dev, ret, "%s set headset_codec fail\n",
1191				      dai_link->name);
1192			break;
1193		}
1194
1195		ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S1");
1196		if (ret) {
1197			dev_err_probe(dev, ret, "%s set headset_codec fail\n",
1198				      dai_link->name);
1199			break;
1200		}
1201	}
1202	of_node_put(headset_codec);
1203	of_node_put(playback_codec);
1204
1205	return ret;
1206}
1207
1208static int mt8186_mt6366_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy)
1209{
1210	struct mtk_platform_card_data *card_data = soc_card_data->card_data;
1211	struct snd_soc_card *card = card_data->card;
1212	struct snd_soc_dai_link *dai_link;
1213	struct mt8186_mt6366_rt1019_rt5682s_priv *mach_priv;
1214	int i, ret;
1215
1216	mach_priv = devm_kzalloc(card->dev, sizeof(*mach_priv), GFP_KERNEL);
1217	if (!mach_priv)
1218		return -ENOMEM;
1219
1220	soc_card_data->mach_priv = mach_priv;
1221
1222	mach_priv->dmic_sel = devm_gpiod_get_optional(card->dev,
1223						      "dmic", GPIOD_OUT_LOW);
1224	if (IS_ERR(mach_priv->dmic_sel))
1225		return dev_err_probe(card->dev, PTR_ERR(mach_priv->dmic_sel),
1226				     "DMIC gpio failed\n");
1227
1228	for_each_card_prelinks(card, i, dai_link) {
1229		if (strcmp(dai_link->name, "I2S0") == 0 ||
1230		    strcmp(dai_link->name, "I2S1") == 0 ||
1231		    strcmp(dai_link->name, "I2S2") == 0) {
1232			if (card_data->flags & DA7219_CODEC_PRESENT) {
1233				dai_link->be_hw_params_fixup = mt8186_i2s_hw_params_32le_fixup;
1234				dai_link->ops = &mt8186_da7219_i2s_ops;
1235			} else {
1236				dai_link->be_hw_params_fixup = mt8186_i2s_hw_params_24le_fixup;
1237				dai_link->ops = &mt8186_rt5682s_i2s_ops;
1238			}
1239		} else if (strcmp(dai_link->name, "I2S3") == 0) {
1240			if (card_data->flags & DA7219_CODEC_PRESENT)
1241				dai_link->be_hw_params_fixup = mt8186_i2s_hw_params_24le_fixup;
1242			else
1243				dai_link->be_hw_params_fixup = mt8186_i2s_hw_params_32le_fixup;
1244		}
1245	}
1246
1247	if (legacy) {
1248		ret = mt8186_mt6366_legacy_probe(soc_card_data);
1249		if (ret)
1250			return ret;
1251	}
1252
1253	ret = mt8186_afe_gpio_init(card->dev);
1254	if (ret)
1255		return dev_err_probe(card->dev, ret, "init AFE gpio error\n");
1256
1257	return 0;
1258}
1259
1260static const unsigned int mt8186_pcm_playback_channels[] = { 2 };
1261static const unsigned int mt8186_pcm_capture_channels[] = { 1, 2 };
1262static const unsigned int mt8186_pcm_rates[] = { 48000 };
1263
1264static const struct snd_pcm_hw_constraint_list mt8186_rate_constraint = {
1265	.list = mt8186_pcm_rates,
1266	.count = ARRAY_SIZE(mt8186_pcm_rates)
1267};
1268
1269static const struct mtk_pcm_constraints_data mt8186_pcm_constraints[MTK_CONSTRAINT_CAPTURE + 1] = {
1270	[MTK_CONSTRAINT_PLAYBACK] = {
1271		.channels = &(const struct snd_pcm_hw_constraint_list) {
1272			.list = mt8186_pcm_playback_channels,
1273			.count = ARRAY_SIZE(mt8186_pcm_playback_channels)
1274		},
1275		.rates = &mt8186_rate_constraint,
1276	},
1277	[MTK_CONSTRAINT_CAPTURE] = {
1278		.channels = &(const struct snd_pcm_hw_constraint_list) {
1279			.list = mt8186_pcm_capture_channels,
1280			.count = ARRAY_SIZE(mt8186_pcm_capture_channels)
1281		},
1282		.rates = &mt8186_rate_constraint,
1283	}
1284};
1285
1286static const struct mtk_sof_priv mt8186_sof_priv = {
1287	.conn_streams = g_sof_conn_streams,
1288	.num_streams = ARRAY_SIZE(g_sof_conn_streams),
1289	.sof_dai_link_fixup = mt8186_sof_dai_link_fixup
1290};
1291
1292static const struct mtk_soundcard_pdata mt8186_mt6366_da7219_max98357_pdata = {
1293	.card_data = &(struct mtk_platform_card_data) {
1294		.card = &mt8186_mt6366_da7219_max98357_soc_card,
1295		.num_jacks = MT8186_JACK_MAX,
1296		.pcm_constraints = mt8186_pcm_constraints,
1297		.num_pcm_constraints = ARRAY_SIZE(mt8186_pcm_constraints),
1298		.flags = DA7219_CODEC_PRESENT,
1299	},
1300	.sof_priv = &mt8186_sof_priv,
1301	.soc_probe = mt8186_mt6366_soc_card_probe
1302};
1303
1304static const struct mtk_soundcard_pdata mt8186_mt6366_rt1019_rt5682s_pdata = {
1305	.card_data = &(struct mtk_platform_card_data) {
1306		.card = &mt8186_mt6366_rt1019_rt5682s_soc_card,
1307		.num_jacks = MT8186_JACK_MAX,
1308		.pcm_constraints = mt8186_pcm_constraints,
1309		.num_pcm_constraints = ARRAY_SIZE(mt8186_pcm_constraints),
1310	},
1311	.sof_priv = &mt8186_sof_priv,
1312	.soc_probe = mt8186_mt6366_soc_card_probe
1313};
1314
1315static const struct mtk_soundcard_pdata mt8186_mt6366_rt5682s_max98360_pdata = {
1316	.card_data = &(struct mtk_platform_card_data) {
1317		.card = &mt8186_mt6366_rt5682s_max98360_soc_card,
1318		.num_jacks = MT8186_JACK_MAX,
1319		.pcm_constraints = mt8186_pcm_constraints,
1320		.num_pcm_constraints = ARRAY_SIZE(mt8186_pcm_constraints),
1321	},
1322	.sof_priv = &mt8186_sof_priv,
1323	.soc_probe = mt8186_mt6366_soc_card_probe
1324};
1325
1326static const struct mtk_soundcard_pdata mt8186_mt6366_rt5650_pdata = {
1327	.card_data = &(struct mtk_platform_card_data) {
1328		.card = &mt8186_mt6366_rt5650_soc_card,
1329		.num_jacks = MT8186_JACK_MAX,
1330		.pcm_constraints = mt8186_pcm_constraints,
1331		.num_pcm_constraints = ARRAY_SIZE(mt8186_pcm_constraints),
1332	},
1333	.sof_priv = &mt8186_sof_priv,
1334	.soc_probe = mt8186_mt6366_soc_card_probe
1335};
1336
1337#if IS_ENABLED(CONFIG_OF)
1338static const struct of_device_id mt8186_mt6366_dt_match[] = {
1339	{
1340		.compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound",
1341		.data = &mt8186_mt6366_rt1019_rt5682s_pdata,
1342	},
1343	{
1344		.compatible = "mediatek,mt8186-mt6366-rt5682s-max98360-sound",
1345		.data = &mt8186_mt6366_rt5682s_max98360_pdata,
1346	},
1347	{
1348		.compatible = "mediatek,mt8186-mt6366-rt5650-sound",
1349		.data = &mt8186_mt6366_rt5650_pdata,
1350	},
1351	{
1352		.compatible = "mediatek,mt8186-mt6366-da7219-max98357-sound",
1353		.data = &mt8186_mt6366_da7219_max98357_pdata,
1354	},
1355	{ /* sentinel */ }
1356};
1357MODULE_DEVICE_TABLE(of, mt8186_mt6366_dt_match);
1358#endif
1359
1360static struct platform_driver mt8186_mt6366_driver = {
1361	.driver = {
1362		.name = "mt8186_mt6366",
1363#if IS_ENABLED(CONFIG_OF)
1364		.of_match_table = mt8186_mt6366_dt_match,
1365#endif
1366		.pm = &snd_soc_pm_ops,
1367	},
1368	.probe = mtk_soundcard_common_probe,
1369};
1370
1371module_platform_driver(mt8186_mt6366_driver);
1372
1373/* Module information */
1374MODULE_DESCRIPTION("MT8186-MT6366 ALSA SoC machine driver");
1375MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
1376MODULE_LICENSE("GPL v2");
1377MODULE_ALIAS("mt8186_mt6366 soc card");
~/ Read-only file preview.