1094e30efSTrevor Wu // SPDX-License-Identifier: GPL-2.0 2094e30efSTrevor Wu /* 3094e30efSTrevor Wu * mt8195-mt6359.c -- 4094e30efSTrevor Wu * MT8195-MT6359 ALSA SoC machine driver code 5094e30efSTrevor Wu * 6094e30efSTrevor Wu * Copyright (c) 2022 MediaTek Inc. 7094e30efSTrevor Wu * Author: Trevor Wu <trevor.wu@mediatek.com> 8094e30efSTrevor Wu * YC Hung <yc.hung@mediatek.com> 9094e30efSTrevor Wu */ 10094e30efSTrevor Wu 11094e30efSTrevor Wu #include <linux/input.h> 12094e30efSTrevor Wu #include <linux/module.h> 13094e30efSTrevor Wu #include <linux/of_device.h> 14094e30efSTrevor Wu #include <linux/pm_runtime.h> 15094e30efSTrevor Wu #include <sound/jack.h> 16094e30efSTrevor Wu #include <sound/pcm_params.h> 17094e30efSTrevor Wu #include <sound/rt5682.h> 18094e30efSTrevor Wu #include <sound/soc.h> 19094e30efSTrevor Wu #include "../../codecs/mt6359.h" 20094e30efSTrevor Wu #include "../../codecs/rt1011.h" 21094e30efSTrevor Wu #include "../../codecs/rt5682.h" 22094e30efSTrevor Wu #include "../common/mtk-afe-platform-driver.h" 23094e30efSTrevor Wu #include "mt8195-afe-clk.h" 24094e30efSTrevor Wu #include "mt8195-afe-common.h" 25094e30efSTrevor Wu 26094e30efSTrevor Wu #define RT1011_SPEAKER_AMP_PRESENT BIT(0) 27094e30efSTrevor Wu #define RT1019_SPEAKER_AMP_PRESENT BIT(1) 2886a6b9c9STrevor Wu #define MAX98390_SPEAKER_AMP_PRESENT BIT(2) 29094e30efSTrevor Wu 30094e30efSTrevor Wu #define RT1011_CODEC_DAI "rt1011-aif" 31094e30efSTrevor Wu #define RT1011_DEV0_NAME "rt1011.2-0038" 32094e30efSTrevor Wu #define RT1011_DEV1_NAME "rt1011.2-0039" 33094e30efSTrevor Wu 34094e30efSTrevor Wu #define RT1019_CODEC_DAI "HiFi" 35094e30efSTrevor Wu #define RT1019_DEV0_NAME "rt1019p" 36094e30efSTrevor Wu 3786a6b9c9STrevor Wu #define MAX98390_CODEC_DAI "max98390-aif1" 3886a6b9c9STrevor Wu #define MAX98390_DEV0_NAME "max98390.2-0038" /* right */ 3986a6b9c9STrevor Wu #define MAX98390_DEV1_NAME "max98390.2-0039" /* left */ 4086a6b9c9STrevor Wu 41094e30efSTrevor Wu #define RT5682_CODEC_DAI "rt5682-aif1" 42094e30efSTrevor Wu #define RT5682_DEV0_NAME "rt5682.2-001a" 43094e30efSTrevor Wu 44094e30efSTrevor Wu #define RT5682S_CODEC_DAI "rt5682s-aif1" 45094e30efSTrevor Wu #define RT5682S_DEV0_NAME "rt5682s.2-001a" 46094e30efSTrevor Wu 47094e30efSTrevor Wu #define SOF_DMA_DL2 "SOF_DMA_DL2" 48094e30efSTrevor Wu #define SOF_DMA_DL3 "SOF_DMA_DL3" 49094e30efSTrevor Wu #define SOF_DMA_UL4 "SOF_DMA_UL4" 50094e30efSTrevor Wu #define SOF_DMA_UL5 "SOF_DMA_UL5" 51094e30efSTrevor Wu 52094e30efSTrevor Wu struct mt8195_card_data { 53094e30efSTrevor Wu const char *name; 54094e30efSTrevor Wu unsigned long quirk; 55094e30efSTrevor Wu }; 56094e30efSTrevor Wu 57094e30efSTrevor Wu struct sof_conn_stream { 58094e30efSTrevor Wu const char *normal_link; 59094e30efSTrevor Wu const char *sof_link; 60094e30efSTrevor Wu const char *sof_dma; 61094e30efSTrevor Wu int stream_dir; 62094e30efSTrevor Wu }; 63094e30efSTrevor Wu 64094e30efSTrevor Wu struct mt8195_mt6359_priv { 65094e30efSTrevor Wu struct snd_soc_jack headset_jack; 66094e30efSTrevor Wu struct snd_soc_jack dp_jack; 67094e30efSTrevor Wu struct snd_soc_jack hdmi_jack; 68094e30efSTrevor Wu struct clk *i2so1_mclk; 69094e30efSTrevor Wu }; 70094e30efSTrevor Wu 71094e30efSTrevor Wu static const struct snd_soc_dapm_widget mt8195_mt6359_widgets[] = { 723a0323c2STrevor Wu SND_SOC_DAPM_HP("Headphone", NULL), 73094e30efSTrevor Wu SND_SOC_DAPM_MIC("Headset Mic", NULL), 74094e30efSTrevor Wu SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0), 75094e30efSTrevor Wu SND_SOC_DAPM_MIXER(SOF_DMA_DL3, SND_SOC_NOPM, 0, 0, NULL, 0), 76094e30efSTrevor Wu SND_SOC_DAPM_MIXER(SOF_DMA_UL4, SND_SOC_NOPM, 0, 0, NULL, 0), 77094e30efSTrevor Wu SND_SOC_DAPM_MIXER(SOF_DMA_UL5, SND_SOC_NOPM, 0, 0, NULL, 0), 78094e30efSTrevor Wu }; 79094e30efSTrevor Wu 80094e30efSTrevor Wu static const struct snd_soc_dapm_route mt8195_mt6359_routes[] = { 81094e30efSTrevor Wu /* headset */ 823a0323c2STrevor Wu { "Headphone", NULL, "HPOL" }, 833a0323c2STrevor Wu { "Headphone", NULL, "HPOR" }, 84094e30efSTrevor Wu { "IN1P", NULL, "Headset Mic" }, 85094e30efSTrevor Wu /* SOF Uplink */ 86094e30efSTrevor Wu {SOF_DMA_UL4, NULL, "O034"}, 87094e30efSTrevor Wu {SOF_DMA_UL4, NULL, "O035"}, 88094e30efSTrevor Wu {SOF_DMA_UL5, NULL, "O036"}, 89094e30efSTrevor Wu {SOF_DMA_UL5, NULL, "O037"}, 90094e30efSTrevor Wu /* SOF Downlink */ 91094e30efSTrevor Wu {"I070", NULL, SOF_DMA_DL2}, 92094e30efSTrevor Wu {"I071", NULL, SOF_DMA_DL2}, 93094e30efSTrevor Wu {"I020", NULL, SOF_DMA_DL3}, 94094e30efSTrevor Wu {"I021", NULL, SOF_DMA_DL3}, 95094e30efSTrevor Wu }; 96094e30efSTrevor Wu 97094e30efSTrevor Wu static const struct snd_kcontrol_new mt8195_mt6359_controls[] = { 983a0323c2STrevor Wu SOC_DAPM_PIN_SWITCH("Headphone"), 99094e30efSTrevor Wu SOC_DAPM_PIN_SWITCH("Headset Mic"), 100094e30efSTrevor Wu }; 101094e30efSTrevor Wu 102094e30efSTrevor Wu static const struct snd_soc_dapm_widget mt8195_dual_speaker_widgets[] = { 1033a0323c2STrevor Wu SND_SOC_DAPM_SPK("Left Spk", NULL), 1043a0323c2STrevor Wu SND_SOC_DAPM_SPK("Right Spk", NULL), 105094e30efSTrevor Wu }; 106094e30efSTrevor Wu 107094e30efSTrevor Wu static const struct snd_kcontrol_new mt8195_dual_speaker_controls[] = { 1083a0323c2STrevor Wu SOC_DAPM_PIN_SWITCH("Left Spk"), 1093a0323c2STrevor Wu SOC_DAPM_PIN_SWITCH("Right Spk"), 110094e30efSTrevor Wu }; 111094e30efSTrevor Wu 112094e30efSTrevor Wu static const struct snd_soc_dapm_widget mt8195_speaker_widgets[] = { 1133a0323c2STrevor Wu SND_SOC_DAPM_SPK("Ext Spk", NULL), 114094e30efSTrevor Wu }; 115094e30efSTrevor Wu 116094e30efSTrevor Wu static const struct snd_kcontrol_new mt8195_speaker_controls[] = { 1173a0323c2STrevor Wu SOC_DAPM_PIN_SWITCH("Ext Spk"), 118094e30efSTrevor Wu }; 119094e30efSTrevor Wu 120094e30efSTrevor Wu static const struct snd_soc_dapm_route mt8195_rt1011_routes[] = { 1213a0323c2STrevor Wu { "Left Spk", NULL, "Left SPO" }, 1223a0323c2STrevor Wu { "Right Spk", NULL, "Right SPO" }, 123094e30efSTrevor Wu }; 124094e30efSTrevor Wu 125094e30efSTrevor Wu static const struct snd_soc_dapm_route mt8195_rt1019_routes[] = { 1263a0323c2STrevor Wu { "Ext Spk", NULL, "Speaker" }, 127094e30efSTrevor Wu }; 128094e30efSTrevor Wu 12986a6b9c9STrevor Wu static const struct snd_soc_dapm_route mt8195_max98390_routes[] = { 13086a6b9c9STrevor Wu { "Left Spk", NULL, "Left BE_OUT" }, 13186a6b9c9STrevor Wu { "Right Spk", NULL, "Right BE_OUT" }, 13286a6b9c9STrevor Wu }; 13386a6b9c9STrevor Wu 134094e30efSTrevor Wu #define CKSYS_AUD_TOP_CFG 0x032c 135094e30efSTrevor Wu #define CKSYS_AUD_TOP_MON 0x0330 136094e30efSTrevor Wu 137094e30efSTrevor Wu static int mt8195_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) 138094e30efSTrevor Wu { 139094e30efSTrevor Wu struct snd_soc_component *cmpnt_afe = 140094e30efSTrevor Wu snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 141094e30efSTrevor Wu struct snd_soc_component *cmpnt_codec = 142094e30efSTrevor Wu asoc_rtd_to_codec(rtd, 0)->component; 143094e30efSTrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 144094e30efSTrevor Wu struct mt8195_afe_private *afe_priv = afe->platform_priv; 145094e30efSTrevor Wu struct mtkaif_param *param = &afe_priv->mtkaif_params; 146094e30efSTrevor Wu int chosen_phase_1, chosen_phase_2, chosen_phase_3; 147094e30efSTrevor Wu int prev_cycle_1, prev_cycle_2, prev_cycle_3; 148094e30efSTrevor Wu int test_done_1, test_done_2, test_done_3; 149094e30efSTrevor Wu int cycle_1, cycle_2, cycle_3; 150094e30efSTrevor Wu int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM]; 151094e30efSTrevor Wu int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM]; 152094e30efSTrevor Wu int mtkaif_calibration_num_phase; 153094e30efSTrevor Wu bool mtkaif_calibration_ok; 154094e30efSTrevor Wu unsigned int monitor; 155094e30efSTrevor Wu int counter; 156094e30efSTrevor Wu int phase; 157094e30efSTrevor Wu int i; 158094e30efSTrevor Wu 159094e30efSTrevor Wu dev_dbg(afe->dev, "%s(), start\n", __func__); 160094e30efSTrevor Wu 161094e30efSTrevor Wu param->mtkaif_calibration_ok = false; 162094e30efSTrevor Wu for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) { 163094e30efSTrevor Wu param->mtkaif_chosen_phase[i] = -1; 164094e30efSTrevor Wu param->mtkaif_phase_cycle[i] = 0; 165094e30efSTrevor Wu mtkaif_chosen_phase[i] = -1; 166094e30efSTrevor Wu mtkaif_phase_cycle[i] = 0; 167094e30efSTrevor Wu } 168094e30efSTrevor Wu 169094e30efSTrevor Wu if (IS_ERR(afe_priv->topckgen)) { 170094e30efSTrevor Wu dev_info(afe->dev, "%s() Cannot find topckgen controller\n", 171094e30efSTrevor Wu __func__); 172094e30efSTrevor Wu return 0; 173094e30efSTrevor Wu } 174094e30efSTrevor Wu 175094e30efSTrevor Wu pm_runtime_get_sync(afe->dev); 176094e30efSTrevor Wu mt6359_mtkaif_calibration_enable(cmpnt_codec); 177094e30efSTrevor Wu 178094e30efSTrevor Wu /* set test type to synchronizer pulse */ 179094e30efSTrevor Wu regmap_update_bits(afe_priv->topckgen, 180094e30efSTrevor Wu CKSYS_AUD_TOP_CFG, 0xffff, 0x4); 181094e30efSTrevor Wu mtkaif_calibration_num_phase = 42; /* mt6359: 0 ~ 42 */ 182094e30efSTrevor Wu mtkaif_calibration_ok = true; 183094e30efSTrevor Wu 184094e30efSTrevor Wu for (phase = 0; 185094e30efSTrevor Wu phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok; 186094e30efSTrevor Wu phase++) { 187094e30efSTrevor Wu mt6359_set_mtkaif_calibration_phase(cmpnt_codec, 188094e30efSTrevor Wu phase, phase, phase); 189094e30efSTrevor Wu 190094e30efSTrevor Wu regmap_update_bits(afe_priv->topckgen, 191094e30efSTrevor Wu CKSYS_AUD_TOP_CFG, 0x1, 0x1); 192094e30efSTrevor Wu 193094e30efSTrevor Wu test_done_1 = 0; 194094e30efSTrevor Wu test_done_2 = 0; 195094e30efSTrevor Wu test_done_3 = 0; 196094e30efSTrevor Wu cycle_1 = -1; 197094e30efSTrevor Wu cycle_2 = -1; 198094e30efSTrevor Wu cycle_3 = -1; 199094e30efSTrevor Wu counter = 0; 200094e30efSTrevor Wu while (!(test_done_1 & test_done_2 & test_done_3)) { 201094e30efSTrevor Wu regmap_read(afe_priv->topckgen, 202094e30efSTrevor Wu CKSYS_AUD_TOP_MON, &monitor); 203094e30efSTrevor Wu test_done_1 = (monitor >> 28) & 0x1; 204094e30efSTrevor Wu test_done_2 = (monitor >> 29) & 0x1; 205094e30efSTrevor Wu test_done_3 = (monitor >> 30) & 0x1; 206094e30efSTrevor Wu if (test_done_1 == 1) 207094e30efSTrevor Wu cycle_1 = monitor & 0xf; 208094e30efSTrevor Wu 209094e30efSTrevor Wu if (test_done_2 == 1) 210094e30efSTrevor Wu cycle_2 = (monitor >> 4) & 0xf; 211094e30efSTrevor Wu 212094e30efSTrevor Wu if (test_done_3 == 1) 213094e30efSTrevor Wu cycle_3 = (monitor >> 8) & 0xf; 214094e30efSTrevor Wu 215094e30efSTrevor Wu /* handle if never test done */ 216094e30efSTrevor Wu if (++counter > 10000) { 217094e30efSTrevor Wu dev_info(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, cycle_3 %d, monitor 0x%x\n", 218094e30efSTrevor Wu __func__, 219094e30efSTrevor Wu cycle_1, cycle_2, cycle_3, monitor); 220094e30efSTrevor Wu mtkaif_calibration_ok = false; 221094e30efSTrevor Wu break; 222094e30efSTrevor Wu } 223094e30efSTrevor Wu } 224094e30efSTrevor Wu 225094e30efSTrevor Wu if (phase == 0) { 226094e30efSTrevor Wu prev_cycle_1 = cycle_1; 227094e30efSTrevor Wu prev_cycle_2 = cycle_2; 228094e30efSTrevor Wu prev_cycle_3 = cycle_3; 229094e30efSTrevor Wu } 230094e30efSTrevor Wu 231094e30efSTrevor Wu if (cycle_1 != prev_cycle_1 && 232094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) { 233094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = phase - 1; 234094e30efSTrevor Wu mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] = prev_cycle_1; 235094e30efSTrevor Wu } 236094e30efSTrevor Wu 237094e30efSTrevor Wu if (cycle_2 != prev_cycle_2 && 238094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) { 239094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = phase - 1; 240094e30efSTrevor Wu mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] = prev_cycle_2; 241094e30efSTrevor Wu } 242094e30efSTrevor Wu 243094e30efSTrevor Wu if (cycle_3 != prev_cycle_3 && 244094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) { 245094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = phase - 1; 246094e30efSTrevor Wu mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] = prev_cycle_3; 247094e30efSTrevor Wu } 248094e30efSTrevor Wu 249094e30efSTrevor Wu regmap_update_bits(afe_priv->topckgen, 250094e30efSTrevor Wu CKSYS_AUD_TOP_CFG, 0x1, 0x0); 251094e30efSTrevor Wu 252094e30efSTrevor Wu if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] >= 0 && 253094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] >= 0 && 254094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] >= 0) 255094e30efSTrevor Wu break; 256094e30efSTrevor Wu } 257094e30efSTrevor Wu 258094e30efSTrevor Wu if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) { 259094e30efSTrevor Wu mtkaif_calibration_ok = false; 260094e30efSTrevor Wu chosen_phase_1 = 0; 261094e30efSTrevor Wu } else { 262094e30efSTrevor Wu chosen_phase_1 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0]; 263094e30efSTrevor Wu } 264094e30efSTrevor Wu 265094e30efSTrevor Wu if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) { 266094e30efSTrevor Wu mtkaif_calibration_ok = false; 267094e30efSTrevor Wu chosen_phase_2 = 0; 268094e30efSTrevor Wu } else { 269094e30efSTrevor Wu chosen_phase_2 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1]; 270094e30efSTrevor Wu } 271094e30efSTrevor Wu 272094e30efSTrevor Wu if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) { 273094e30efSTrevor Wu mtkaif_calibration_ok = false; 274094e30efSTrevor Wu chosen_phase_3 = 0; 275094e30efSTrevor Wu } else { 276094e30efSTrevor Wu chosen_phase_3 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2]; 277094e30efSTrevor Wu } 278094e30efSTrevor Wu 279094e30efSTrevor Wu mt6359_set_mtkaif_calibration_phase(cmpnt_codec, 280094e30efSTrevor Wu chosen_phase_1, 281094e30efSTrevor Wu chosen_phase_2, 282094e30efSTrevor Wu chosen_phase_3); 283094e30efSTrevor Wu 284094e30efSTrevor Wu mt6359_mtkaif_calibration_disable(cmpnt_codec); 285094e30efSTrevor Wu pm_runtime_put(afe->dev); 286094e30efSTrevor Wu 287094e30efSTrevor Wu param->mtkaif_calibration_ok = mtkaif_calibration_ok; 288094e30efSTrevor Wu param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = chosen_phase_1; 289094e30efSTrevor Wu param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = chosen_phase_2; 290094e30efSTrevor Wu param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = chosen_phase_3; 291094e30efSTrevor Wu for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) 292094e30efSTrevor Wu param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i]; 293094e30efSTrevor Wu 294094e30efSTrevor Wu dev_info(afe->dev, "%s(), end, calibration ok %d\n", 295094e30efSTrevor Wu __func__, param->mtkaif_calibration_ok); 296094e30efSTrevor Wu 297094e30efSTrevor Wu return 0; 298094e30efSTrevor Wu } 299094e30efSTrevor Wu 300094e30efSTrevor Wu static int mt8195_mt6359_init(struct snd_soc_pcm_runtime *rtd) 301094e30efSTrevor Wu { 302094e30efSTrevor Wu struct snd_soc_component *cmpnt_codec = 303094e30efSTrevor Wu asoc_rtd_to_codec(rtd, 0)->component; 304094e30efSTrevor Wu 305094e30efSTrevor Wu /* set mtkaif protocol */ 306094e30efSTrevor Wu mt6359_set_mtkaif_protocol(cmpnt_codec, 307094e30efSTrevor Wu MT6359_MTKAIF_PROTOCOL_2_CLK_P2); 308094e30efSTrevor Wu 309094e30efSTrevor Wu /* mtkaif calibration */ 310094e30efSTrevor Wu mt8195_mt6359_mtkaif_calibration(rtd); 311094e30efSTrevor Wu 312094e30efSTrevor Wu return 0; 313094e30efSTrevor Wu } 314094e30efSTrevor Wu 315094e30efSTrevor Wu static int mt8195_hdmitx_dptx_startup(struct snd_pcm_substream *substream) 316094e30efSTrevor Wu { 317094e30efSTrevor Wu static const unsigned int rates[] = { 318094e30efSTrevor Wu 48000 319094e30efSTrevor Wu }; 320094e30efSTrevor Wu static const unsigned int channels[] = { 321094e30efSTrevor Wu 2, 4, 6, 8 322094e30efSTrevor Wu }; 323094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_rates = { 324094e30efSTrevor Wu .count = ARRAY_SIZE(rates), 325094e30efSTrevor Wu .list = rates, 326094e30efSTrevor Wu .mask = 0, 327094e30efSTrevor Wu }; 328094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_channels = { 329094e30efSTrevor Wu .count = ARRAY_SIZE(channels), 330094e30efSTrevor Wu .list = channels, 331094e30efSTrevor Wu .mask = 0, 332094e30efSTrevor Wu }; 333094e30efSTrevor Wu 334094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 335094e30efSTrevor Wu struct snd_pcm_runtime *runtime = substream->runtime; 336094e30efSTrevor Wu int ret; 337094e30efSTrevor Wu 338094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 339094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_RATE, 340094e30efSTrevor Wu &constraints_rates); 341094e30efSTrevor Wu if (ret < 0) { 342094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list rate failed\n"); 343094e30efSTrevor Wu return ret; 344094e30efSTrevor Wu } 345094e30efSTrevor Wu 346094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 347094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_CHANNELS, 348094e30efSTrevor Wu &constraints_channels); 349094e30efSTrevor Wu if (ret < 0) { 350094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list channel failed\n"); 351094e30efSTrevor Wu return ret; 352094e30efSTrevor Wu } 353094e30efSTrevor Wu 354094e30efSTrevor Wu return 0; 355094e30efSTrevor Wu } 356094e30efSTrevor Wu 357094e30efSTrevor Wu static const struct snd_soc_ops mt8195_hdmitx_dptx_playback_ops = { 358094e30efSTrevor Wu .startup = mt8195_hdmitx_dptx_startup, 359094e30efSTrevor Wu }; 360094e30efSTrevor Wu 361094e30efSTrevor Wu static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream, 362094e30efSTrevor Wu struct snd_pcm_hw_params *params) 363094e30efSTrevor Wu { 364094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = substream->private_data; 365094e30efSTrevor Wu struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 366094e30efSTrevor Wu 367094e30efSTrevor Wu return snd_soc_dai_set_sysclk(cpu_dai, 0, params_rate(params) * 256, 368094e30efSTrevor Wu SND_SOC_CLOCK_OUT); 369094e30efSTrevor Wu } 370094e30efSTrevor Wu 371094e30efSTrevor Wu static const struct snd_soc_ops mt8195_dptx_ops = { 372094e30efSTrevor Wu .hw_params = mt8195_dptx_hw_params, 373094e30efSTrevor Wu }; 374094e30efSTrevor Wu 375094e30efSTrevor Wu static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) 376094e30efSTrevor Wu { 377094e30efSTrevor Wu struct mt8195_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); 378094e30efSTrevor Wu struct snd_soc_component *cmpnt_codec = 379094e30efSTrevor Wu asoc_rtd_to_codec(rtd, 0)->component; 380094e30efSTrevor Wu int ret; 381094e30efSTrevor Wu 382094e30efSTrevor Wu ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_LINEOUT, 383094e30efSTrevor Wu &priv->dp_jack, NULL, 0); 384094e30efSTrevor Wu if (ret) 385094e30efSTrevor Wu return ret; 386094e30efSTrevor Wu 387094e30efSTrevor Wu return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL); 388094e30efSTrevor Wu } 389094e30efSTrevor Wu 390094e30efSTrevor Wu static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd) 391094e30efSTrevor Wu { 392094e30efSTrevor Wu struct mt8195_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); 393094e30efSTrevor Wu struct snd_soc_component *cmpnt_codec = 394094e30efSTrevor Wu asoc_rtd_to_codec(rtd, 0)->component; 395094e30efSTrevor Wu int ret; 396094e30efSTrevor Wu 397094e30efSTrevor Wu ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, 398094e30efSTrevor Wu &priv->hdmi_jack, NULL, 0); 399094e30efSTrevor Wu if (ret) 400094e30efSTrevor Wu return ret; 401094e30efSTrevor Wu 402094e30efSTrevor Wu return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL); 403094e30efSTrevor Wu } 404094e30efSTrevor Wu 405094e30efSTrevor Wu static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 406094e30efSTrevor Wu struct snd_pcm_hw_params *params) 407094e30efSTrevor Wu { 408094e30efSTrevor Wu /* fix BE i2s format to S24_LE, clean param mask first */ 409094e30efSTrevor Wu snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 410094e30efSTrevor Wu 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); 411094e30efSTrevor Wu 412094e30efSTrevor Wu params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 413094e30efSTrevor Wu 414094e30efSTrevor Wu return 0; 415094e30efSTrevor Wu } 416094e30efSTrevor Wu 417094e30efSTrevor Wu static int mt8195_playback_startup(struct snd_pcm_substream *substream) 418094e30efSTrevor Wu { 419094e30efSTrevor Wu static const unsigned int rates[] = { 420094e30efSTrevor Wu 48000 421094e30efSTrevor Wu }; 422094e30efSTrevor Wu static const unsigned int channels[] = { 423094e30efSTrevor Wu 2 424094e30efSTrevor Wu }; 425094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_rates = { 426094e30efSTrevor Wu .count = ARRAY_SIZE(rates), 427094e30efSTrevor Wu .list = rates, 428094e30efSTrevor Wu .mask = 0, 429094e30efSTrevor Wu }; 430094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_channels = { 431094e30efSTrevor Wu .count = ARRAY_SIZE(channels), 432094e30efSTrevor Wu .list = channels, 433094e30efSTrevor Wu .mask = 0, 434094e30efSTrevor Wu }; 435094e30efSTrevor Wu 436094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 437094e30efSTrevor Wu struct snd_pcm_runtime *runtime = substream->runtime; 438094e30efSTrevor Wu int ret; 439094e30efSTrevor Wu 440094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 441094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_RATE, 442094e30efSTrevor Wu &constraints_rates); 443094e30efSTrevor Wu if (ret < 0) { 444094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list rate failed\n"); 445094e30efSTrevor Wu return ret; 446094e30efSTrevor Wu } 447094e30efSTrevor Wu 448094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 449094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_CHANNELS, 450094e30efSTrevor Wu &constraints_channels); 451094e30efSTrevor Wu if (ret < 0) { 452094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list channel failed\n"); 453094e30efSTrevor Wu return ret; 454094e30efSTrevor Wu } 455094e30efSTrevor Wu 456094e30efSTrevor Wu return 0; 457094e30efSTrevor Wu } 458094e30efSTrevor Wu 459094e30efSTrevor Wu static const struct snd_soc_ops mt8195_playback_ops = { 460094e30efSTrevor Wu .startup = mt8195_playback_startup, 461094e30efSTrevor Wu }; 462094e30efSTrevor Wu 463094e30efSTrevor Wu static int mt8195_capture_startup(struct snd_pcm_substream *substream) 464094e30efSTrevor Wu { 465094e30efSTrevor Wu static const unsigned int rates[] = { 466094e30efSTrevor Wu 48000 467094e30efSTrevor Wu }; 468094e30efSTrevor Wu static const unsigned int channels[] = { 469094e30efSTrevor Wu 1, 2 470094e30efSTrevor Wu }; 471094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_rates = { 472094e30efSTrevor Wu .count = ARRAY_SIZE(rates), 473094e30efSTrevor Wu .list = rates, 474094e30efSTrevor Wu .mask = 0, 475094e30efSTrevor Wu }; 476094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_channels = { 477094e30efSTrevor Wu .count = ARRAY_SIZE(channels), 478094e30efSTrevor Wu .list = channels, 479094e30efSTrevor Wu .mask = 0, 480094e30efSTrevor Wu }; 481094e30efSTrevor Wu 482094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 483094e30efSTrevor Wu struct snd_pcm_runtime *runtime = substream->runtime; 484094e30efSTrevor Wu int ret; 485094e30efSTrevor Wu 486094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 487094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_RATE, 488094e30efSTrevor Wu &constraints_rates); 489094e30efSTrevor Wu if (ret < 0) { 490094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list rate failed\n"); 491094e30efSTrevor Wu return ret; 492094e30efSTrevor Wu } 493094e30efSTrevor Wu 494094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 495094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_CHANNELS, 496094e30efSTrevor Wu &constraints_channels); 497094e30efSTrevor Wu if (ret < 0) { 498094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list channel failed\n"); 499094e30efSTrevor Wu return ret; 500094e30efSTrevor Wu } 501094e30efSTrevor Wu 502094e30efSTrevor Wu return 0; 503094e30efSTrevor Wu } 504094e30efSTrevor Wu 505094e30efSTrevor Wu static const struct snd_soc_ops mt8195_capture_ops = { 506094e30efSTrevor Wu .startup = mt8195_capture_startup, 507094e30efSTrevor Wu }; 508094e30efSTrevor Wu 509094e30efSTrevor Wu static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream, 510094e30efSTrevor Wu struct snd_pcm_hw_params *params) 511094e30efSTrevor Wu { 512094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = substream->private_data; 513094e30efSTrevor Wu struct snd_soc_card *card = rtd->card; 514094e30efSTrevor Wu struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 515094e30efSTrevor Wu struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 516094e30efSTrevor Wu unsigned int rate = params_rate(params); 517094e30efSTrevor Wu int bitwidth; 518094e30efSTrevor Wu int ret; 519094e30efSTrevor Wu 520094e30efSTrevor Wu bitwidth = snd_pcm_format_width(params_format(params)); 521094e30efSTrevor Wu if (bitwidth < 0) { 522094e30efSTrevor Wu dev_err(card->dev, "invalid bit width: %d\n", bitwidth); 523094e30efSTrevor Wu return bitwidth; 524094e30efSTrevor Wu } 525094e30efSTrevor Wu 526094e30efSTrevor Wu ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth); 527094e30efSTrevor Wu if (ret) { 528094e30efSTrevor Wu dev_err(card->dev, "failed to set tdm slot\n"); 529094e30efSTrevor Wu return ret; 530094e30efSTrevor Wu } 531094e30efSTrevor Wu 532094e30efSTrevor Wu ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, RT5682_PLL1_S_MCLK, 533094e30efSTrevor Wu rate * 256, rate * 512); 534094e30efSTrevor Wu if (ret) { 535094e30efSTrevor Wu dev_err(card->dev, "failed to set pll\n"); 536094e30efSTrevor Wu return ret; 537094e30efSTrevor Wu } 538094e30efSTrevor Wu 539094e30efSTrevor Wu ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1, 540094e30efSTrevor Wu rate * 512, SND_SOC_CLOCK_IN); 541094e30efSTrevor Wu if (ret) { 542094e30efSTrevor Wu dev_err(card->dev, "failed to set sysclk\n"); 543094e30efSTrevor Wu return ret; 544094e30efSTrevor Wu } 545094e30efSTrevor Wu 546094e30efSTrevor Wu return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 256, 547094e30efSTrevor Wu SND_SOC_CLOCK_OUT); 548094e30efSTrevor Wu } 549094e30efSTrevor Wu 550094e30efSTrevor Wu static const struct snd_soc_ops mt8195_rt5682_etdm_ops = { 551094e30efSTrevor Wu .hw_params = mt8195_rt5682_etdm_hw_params, 552094e30efSTrevor Wu }; 553094e30efSTrevor Wu 554094e30efSTrevor Wu static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd) 555094e30efSTrevor Wu { 556094e30efSTrevor Wu struct snd_soc_component *cmpnt_codec = 557094e30efSTrevor Wu asoc_rtd_to_codec(rtd, 0)->component; 558094e30efSTrevor Wu struct mt8195_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); 559094e30efSTrevor Wu struct snd_soc_jack *jack = &priv->headset_jack; 560094e30efSTrevor Wu struct snd_soc_component *cmpnt_afe = 561094e30efSTrevor Wu snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 562094e30efSTrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 563094e30efSTrevor Wu struct mt8195_afe_private *afe_priv = afe->platform_priv; 564094e30efSTrevor Wu int ret; 565094e30efSTrevor Wu 566094e30efSTrevor Wu priv->i2so1_mclk = afe_priv->clk[MT8195_CLK_TOP_APLL12_DIV2]; 567094e30efSTrevor Wu 568094e30efSTrevor Wu ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", 569094e30efSTrevor Wu SND_JACK_HEADSET | SND_JACK_BTN_0 | 570094e30efSTrevor Wu SND_JACK_BTN_1 | SND_JACK_BTN_2 | 571094e30efSTrevor Wu SND_JACK_BTN_3, 572094e30efSTrevor Wu jack, NULL, 0); 573094e30efSTrevor Wu if (ret) { 574094e30efSTrevor Wu dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); 575094e30efSTrevor Wu return ret; 576094e30efSTrevor Wu } 577094e30efSTrevor Wu 578094e30efSTrevor Wu snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 579094e30efSTrevor Wu snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 580094e30efSTrevor Wu snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 581094e30efSTrevor Wu snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 582094e30efSTrevor Wu 583094e30efSTrevor Wu ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL); 584094e30efSTrevor Wu if (ret) { 585094e30efSTrevor Wu dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret); 586094e30efSTrevor Wu return ret; 587094e30efSTrevor Wu } 588094e30efSTrevor Wu 589094e30efSTrevor Wu return 0; 590094e30efSTrevor Wu }; 591094e30efSTrevor Wu 592094e30efSTrevor Wu static int mt8195_rt1011_etdm_hw_params(struct snd_pcm_substream *substream, 593094e30efSTrevor Wu struct snd_pcm_hw_params *params) 594094e30efSTrevor Wu { 595094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 596094e30efSTrevor Wu struct snd_soc_dai *codec_dai; 597094e30efSTrevor Wu struct snd_soc_card *card = rtd->card; 598094e30efSTrevor Wu int srate, i, ret; 599094e30efSTrevor Wu 600094e30efSTrevor Wu srate = params_rate(params); 601094e30efSTrevor Wu 602094e30efSTrevor Wu for_each_rtd_codec_dais(rtd, i, codec_dai) { 603094e30efSTrevor Wu ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK, 604094e30efSTrevor Wu 64 * srate, 256 * srate); 605094e30efSTrevor Wu if (ret < 0) { 606094e30efSTrevor Wu dev_err(card->dev, "codec_dai clock not set\n"); 607094e30efSTrevor Wu return ret; 608094e30efSTrevor Wu } 609094e30efSTrevor Wu 610094e30efSTrevor Wu ret = snd_soc_dai_set_sysclk(codec_dai, 611094e30efSTrevor Wu RT1011_FS_SYS_PRE_S_PLL1, 612094e30efSTrevor Wu 256 * srate, SND_SOC_CLOCK_IN); 613094e30efSTrevor Wu if (ret < 0) { 614094e30efSTrevor Wu dev_err(card->dev, "codec_dai clock not set\n"); 615094e30efSTrevor Wu return ret; 616094e30efSTrevor Wu } 617094e30efSTrevor Wu } 618094e30efSTrevor Wu return 0; 619094e30efSTrevor Wu } 620094e30efSTrevor Wu 621094e30efSTrevor Wu static const struct snd_soc_ops mt8195_rt1011_etdm_ops = { 622094e30efSTrevor Wu .hw_params = mt8195_rt1011_etdm_hw_params, 623094e30efSTrevor Wu }; 624094e30efSTrevor Wu 625094e30efSTrevor Wu static int mt8195_rt1011_init(struct snd_soc_pcm_runtime *rtd) 626094e30efSTrevor Wu { 627094e30efSTrevor Wu struct snd_soc_card *card = rtd->card; 628094e30efSTrevor Wu int ret; 629094e30efSTrevor Wu 630094e30efSTrevor Wu ret = snd_soc_dapm_new_controls(&card->dapm, mt8195_dual_speaker_widgets, 631094e30efSTrevor Wu ARRAY_SIZE(mt8195_dual_speaker_widgets)); 632094e30efSTrevor Wu if (ret) { 633094e30efSTrevor Wu dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); 634094e30efSTrevor Wu /* Don't need to add routes if widget addition failed */ 635094e30efSTrevor Wu return ret; 636094e30efSTrevor Wu } 637094e30efSTrevor Wu 638094e30efSTrevor Wu ret = snd_soc_add_card_controls(card, mt8195_dual_speaker_controls, 639094e30efSTrevor Wu ARRAY_SIZE(mt8195_dual_speaker_controls)); 640094e30efSTrevor Wu if (ret) { 641094e30efSTrevor Wu dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 642094e30efSTrevor Wu return ret; 643094e30efSTrevor Wu } 644094e30efSTrevor Wu 645094e30efSTrevor Wu ret = snd_soc_dapm_add_routes(&card->dapm, mt8195_rt1011_routes, 646094e30efSTrevor Wu ARRAY_SIZE(mt8195_rt1011_routes)); 647094e30efSTrevor Wu if (ret) 648094e30efSTrevor Wu dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); 649094e30efSTrevor Wu 650094e30efSTrevor Wu return ret; 651094e30efSTrevor Wu } 652094e30efSTrevor Wu 653094e30efSTrevor Wu static int mt8195_rt1019_init(struct snd_soc_pcm_runtime *rtd) 654094e30efSTrevor Wu { 655094e30efSTrevor Wu struct snd_soc_card *card = rtd->card; 656094e30efSTrevor Wu int ret; 657094e30efSTrevor Wu 658094e30efSTrevor Wu ret = snd_soc_dapm_new_controls(&card->dapm, mt8195_speaker_widgets, 659094e30efSTrevor Wu ARRAY_SIZE(mt8195_speaker_widgets)); 660094e30efSTrevor Wu if (ret) { 661094e30efSTrevor Wu dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); 662094e30efSTrevor Wu /* Don't need to add routes if widget addition failed */ 663094e30efSTrevor Wu return ret; 664094e30efSTrevor Wu } 665094e30efSTrevor Wu 666094e30efSTrevor Wu ret = snd_soc_add_card_controls(card, mt8195_speaker_controls, 667094e30efSTrevor Wu ARRAY_SIZE(mt8195_speaker_controls)); 668094e30efSTrevor Wu if (ret) { 669094e30efSTrevor Wu dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 670094e30efSTrevor Wu return ret; 671094e30efSTrevor Wu } 672094e30efSTrevor Wu 673094e30efSTrevor Wu ret = snd_soc_dapm_add_routes(&card->dapm, mt8195_rt1019_routes, 674094e30efSTrevor Wu ARRAY_SIZE(mt8195_rt1019_routes)); 675094e30efSTrevor Wu if (ret) 676094e30efSTrevor Wu dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); 677094e30efSTrevor Wu 678094e30efSTrevor Wu return ret; 679094e30efSTrevor Wu } 680094e30efSTrevor Wu 68186a6b9c9STrevor Wu static int mt8195_max98390_init(struct snd_soc_pcm_runtime *rtd) 68286a6b9c9STrevor Wu { 68386a6b9c9STrevor Wu struct snd_soc_card *card = rtd->card; 68486a6b9c9STrevor Wu int ret; 68586a6b9c9STrevor Wu 68686a6b9c9STrevor Wu ret = snd_soc_dapm_new_controls(&card->dapm, mt8195_dual_speaker_widgets, 68786a6b9c9STrevor Wu ARRAY_SIZE(mt8195_dual_speaker_widgets)); 68886a6b9c9STrevor Wu if (ret) { 68986a6b9c9STrevor Wu dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); 69086a6b9c9STrevor Wu /* Don't need to add routes if widget addition failed */ 69186a6b9c9STrevor Wu return ret; 69286a6b9c9STrevor Wu } 69386a6b9c9STrevor Wu 69486a6b9c9STrevor Wu ret = snd_soc_add_card_controls(card, mt8195_dual_speaker_controls, 69586a6b9c9STrevor Wu ARRAY_SIZE(mt8195_dual_speaker_controls)); 69686a6b9c9STrevor Wu if (ret) { 69786a6b9c9STrevor Wu dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 69886a6b9c9STrevor Wu return ret; 69986a6b9c9STrevor Wu } 70086a6b9c9STrevor Wu 70186a6b9c9STrevor Wu ret = snd_soc_dapm_add_routes(&card->dapm, mt8195_max98390_routes, 70286a6b9c9STrevor Wu ARRAY_SIZE(mt8195_max98390_routes)); 70386a6b9c9STrevor Wu if (ret) 70486a6b9c9STrevor Wu dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); 70586a6b9c9STrevor Wu 70686a6b9c9STrevor Wu return ret; 70786a6b9c9STrevor Wu } 70886a6b9c9STrevor Wu 709094e30efSTrevor Wu static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 710094e30efSTrevor Wu struct snd_pcm_hw_params *params) 711094e30efSTrevor Wu { 712094e30efSTrevor Wu /* fix BE i2s format to S24_LE, clean param mask first */ 713094e30efSTrevor Wu snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 714094e30efSTrevor Wu 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); 715094e30efSTrevor Wu 716094e30efSTrevor Wu params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 717094e30efSTrevor Wu 718094e30efSTrevor Wu return 0; 719094e30efSTrevor Wu } 720094e30efSTrevor Wu 721094e30efSTrevor Wu static int mt8195_set_bias_level_post(struct snd_soc_card *card, 722094e30efSTrevor Wu struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) 723094e30efSTrevor Wu { 724094e30efSTrevor Wu struct snd_soc_component *component = dapm->component; 725094e30efSTrevor Wu struct mt8195_mt6359_priv *priv = snd_soc_card_get_drvdata(card); 726094e30efSTrevor Wu int ret; 727094e30efSTrevor Wu 728094e30efSTrevor Wu /* 729094e30efSTrevor Wu * It's required to control mclk directly in the set_bias_level_post 730094e30efSTrevor Wu * function for rt5682 and rt5682s codec, or the unexpected pop happens 731094e30efSTrevor Wu * at the end of playback. 732094e30efSTrevor Wu */ 733094e30efSTrevor Wu if (!component || 734094e30efSTrevor Wu (strcmp(component->name, RT5682_DEV0_NAME) && 735094e30efSTrevor Wu strcmp(component->name, RT5682S_DEV0_NAME))) 736094e30efSTrevor Wu return 0; 737094e30efSTrevor Wu 738094e30efSTrevor Wu switch (level) { 739094e30efSTrevor Wu case SND_SOC_BIAS_OFF: 740094e30efSTrevor Wu if (!__clk_is_enabled(priv->i2so1_mclk)) 741094e30efSTrevor Wu return 0; 742094e30efSTrevor Wu 743094e30efSTrevor Wu clk_disable_unprepare(priv->i2so1_mclk); 744094e30efSTrevor Wu dev_dbg(card->dev, "Disable i2so1 mclk\n"); 745094e30efSTrevor Wu break; 746094e30efSTrevor Wu case SND_SOC_BIAS_ON: 747094e30efSTrevor Wu ret = clk_prepare_enable(priv->i2so1_mclk); 748094e30efSTrevor Wu if (ret) { 749094e30efSTrevor Wu dev_err(card->dev, "Can't enable i2so1 mclk: %d\n", ret); 750094e30efSTrevor Wu return ret; 751094e30efSTrevor Wu } 752094e30efSTrevor Wu dev_dbg(card->dev, "Enable i2so1 mclk\n"); 753094e30efSTrevor Wu break; 754094e30efSTrevor Wu default: 755094e30efSTrevor Wu break; 756094e30efSTrevor Wu } 757094e30efSTrevor Wu 758094e30efSTrevor Wu return 0; 759094e30efSTrevor Wu } 760094e30efSTrevor Wu 761094e30efSTrevor Wu enum { 762094e30efSTrevor Wu DAI_LINK_DL2_FE, 763094e30efSTrevor Wu DAI_LINK_DL3_FE, 764094e30efSTrevor Wu DAI_LINK_DL6_FE, 765094e30efSTrevor Wu DAI_LINK_DL7_FE, 766094e30efSTrevor Wu DAI_LINK_DL8_FE, 767094e30efSTrevor Wu DAI_LINK_DL10_FE, 768094e30efSTrevor Wu DAI_LINK_DL11_FE, 769094e30efSTrevor Wu DAI_LINK_UL1_FE, 770094e30efSTrevor Wu DAI_LINK_UL2_FE, 771094e30efSTrevor Wu DAI_LINK_UL3_FE, 772094e30efSTrevor Wu DAI_LINK_UL4_FE, 773094e30efSTrevor Wu DAI_LINK_UL5_FE, 774094e30efSTrevor Wu DAI_LINK_UL6_FE, 775094e30efSTrevor Wu DAI_LINK_UL8_FE, 776094e30efSTrevor Wu DAI_LINK_UL9_FE, 777094e30efSTrevor Wu DAI_LINK_UL10_FE, 778094e30efSTrevor Wu DAI_LINK_DL_SRC_BE, 779094e30efSTrevor Wu DAI_LINK_DPTX_BE, 780094e30efSTrevor Wu DAI_LINK_ETDM1_IN_BE, 781094e30efSTrevor Wu DAI_LINK_ETDM2_IN_BE, 782094e30efSTrevor Wu DAI_LINK_ETDM1_OUT_BE, 783094e30efSTrevor Wu DAI_LINK_ETDM2_OUT_BE, 784094e30efSTrevor Wu DAI_LINK_ETDM3_OUT_BE, 785094e30efSTrevor Wu DAI_LINK_PCM1_BE, 786094e30efSTrevor Wu DAI_LINK_UL_SRC1_BE, 787094e30efSTrevor Wu DAI_LINK_UL_SRC2_BE, 788094e30efSTrevor Wu DAI_LINK_REGULAR_LAST = DAI_LINK_UL_SRC2_BE, 789094e30efSTrevor Wu DAI_LINK_SOF_START, 790094e30efSTrevor Wu DAI_LINK_SOF_DL2_BE = DAI_LINK_SOF_START, 791094e30efSTrevor Wu DAI_LINK_SOF_DL3_BE, 792094e30efSTrevor Wu DAI_LINK_SOF_UL4_BE, 793094e30efSTrevor Wu DAI_LINK_SOF_UL5_BE, 794094e30efSTrevor Wu DAI_LINK_SOF_END = DAI_LINK_SOF_UL5_BE, 795094e30efSTrevor Wu }; 796094e30efSTrevor Wu 797094e30efSTrevor Wu #define DAI_LINK_REGULAR_NUM (DAI_LINK_REGULAR_LAST + 1) 798094e30efSTrevor Wu 799094e30efSTrevor Wu /* FE */ 800094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL2_FE, 801094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 802094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 803094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 804094e30efSTrevor Wu 805094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL3_FE, 806094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 807094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 808094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 809094e30efSTrevor Wu 810094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL6_FE, 811094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL6")), 812094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 813094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 814094e30efSTrevor Wu 815094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL7_FE, 816094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL7")), 817094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 818094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 819094e30efSTrevor Wu 820094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL8_FE, 821094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL8")), 822094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 823094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 824094e30efSTrevor Wu 825094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL10_FE, 826094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL10")), 827094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 828094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 829094e30efSTrevor Wu 830094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL11_FE, 831094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL11")), 832094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 833094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 834094e30efSTrevor Wu 835094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL1_FE, 836094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 837094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 838094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 839094e30efSTrevor Wu 840094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL2_FE, 841094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 842094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 843094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 844094e30efSTrevor Wu 845094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL3_FE, 846094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 847094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 848094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 849094e30efSTrevor Wu 850094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL4_FE, 851094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL4")), 852094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 853094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 854094e30efSTrevor Wu 855094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL5_FE, 856094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL5")), 857094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 858094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 859094e30efSTrevor Wu 860094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL6_FE, 861094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL6")), 862094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 863094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 864094e30efSTrevor Wu 865094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL8_FE, 866094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL8")), 867094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 868094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 869094e30efSTrevor Wu 870094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL9_FE, 871094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL9")), 872094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 873094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 874094e30efSTrevor Wu 875094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL10_FE, 876094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL10")), 877094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 878094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 879094e30efSTrevor Wu 880094e30efSTrevor Wu /* BE */ 881094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL_SRC_BE, 882094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")), 883094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", 884094e30efSTrevor Wu "mt6359-snd-codec-aif1")), 885094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 886094e30efSTrevor Wu 887094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DPTX_BE, 888094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DPTX")), 889094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 890094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 891094e30efSTrevor Wu 892094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(ETDM1_IN_BE, 893094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")), 894094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 895094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 896094e30efSTrevor Wu 897094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(ETDM2_IN_BE, 898094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")), 899094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 900094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 901094e30efSTrevor Wu 902094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE, 903094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")), 904094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 905094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 906094e30efSTrevor Wu 907094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE, 908094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")), 909094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 910094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 911094e30efSTrevor Wu 912094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(ETDM3_OUT_BE, 913094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")), 914094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 915094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 916094e30efSTrevor Wu 917094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(PCM1_BE, 918094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("PCM1")), 919094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 920094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 921094e30efSTrevor Wu 922094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL_SRC1_BE, 923094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC1")), 924094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", 925094e30efSTrevor Wu "mt6359-snd-codec-aif1"), 926094e30efSTrevor Wu COMP_CODEC("dmic-codec", 927094e30efSTrevor Wu "dmic-hifi")), 928094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 929094e30efSTrevor Wu 930094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL_SRC2_BE, 931094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC2")), 932094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", 933094e30efSTrevor Wu "mt6359-snd-codec-aif2")), 934094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 935094e30efSTrevor Wu 936094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(AFE_SOF_DL2, 937094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")), 938094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 939094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 940094e30efSTrevor Wu 941094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(AFE_SOF_DL3, 942094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL3")), 943094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 944094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 945094e30efSTrevor Wu 946094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(AFE_SOF_UL4, 947094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL4")), 948094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 949094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 950094e30efSTrevor Wu 951094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(AFE_SOF_UL5, 952094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL5")), 953094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 954094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 955094e30efSTrevor Wu 956094e30efSTrevor Wu /* codec */ 957094e30efSTrevor Wu SND_SOC_DAILINK_DEF(rt1019_comps, 958094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC(RT1019_DEV0_NAME, 959094e30efSTrevor Wu RT1019_CODEC_DAI))); 960094e30efSTrevor Wu 961094e30efSTrevor Wu SND_SOC_DAILINK_DEF(rt1011_comps, 962094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC(RT1011_DEV0_NAME, 963094e30efSTrevor Wu RT1011_CODEC_DAI), 964094e30efSTrevor Wu COMP_CODEC(RT1011_DEV1_NAME, 965094e30efSTrevor Wu RT1011_CODEC_DAI))); 966094e30efSTrevor Wu 96786a6b9c9STrevor Wu SND_SOC_DAILINK_DEF(max98390_comps, 96886a6b9c9STrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC(MAX98390_DEV0_NAME, 96986a6b9c9STrevor Wu MAX98390_CODEC_DAI), 97086a6b9c9STrevor Wu COMP_CODEC(MAX98390_DEV1_NAME, 97186a6b9c9STrevor Wu MAX98390_CODEC_DAI))); 97286a6b9c9STrevor Wu 973094e30efSTrevor Wu static const struct sof_conn_stream g_sof_conn_streams[] = { 974094e30efSTrevor Wu { "ETDM2_OUT_BE", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK}, 975094e30efSTrevor Wu { "ETDM1_OUT_BE", "AFE_SOF_DL3", SOF_DMA_DL3, SNDRV_PCM_STREAM_PLAYBACK}, 976094e30efSTrevor Wu { "UL_SRC1_BE", "AFE_SOF_UL4", SOF_DMA_UL4, SNDRV_PCM_STREAM_CAPTURE}, 977094e30efSTrevor Wu { "ETDM2_IN_BE", "AFE_SOF_UL5", SOF_DMA_UL5, SNDRV_PCM_STREAM_CAPTURE}, 978094e30efSTrevor Wu }; 979094e30efSTrevor Wu 980094e30efSTrevor Wu static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { 981094e30efSTrevor Wu /* FE */ 982094e30efSTrevor Wu [DAI_LINK_DL2_FE] = { 983094e30efSTrevor Wu .name = "DL2_FE", 984094e30efSTrevor Wu .stream_name = "DL2 Playback", 985094e30efSTrevor Wu .trigger = { 986094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 987094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 988094e30efSTrevor Wu }, 989094e30efSTrevor Wu .dynamic = 1, 990094e30efSTrevor Wu .dpcm_playback = 1, 991094e30efSTrevor Wu .ops = &mt8195_playback_ops, 992094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL2_FE), 993094e30efSTrevor Wu }, 994094e30efSTrevor Wu [DAI_LINK_DL3_FE] = { 995094e30efSTrevor Wu .name = "DL3_FE", 996094e30efSTrevor Wu .stream_name = "DL3 Playback", 997094e30efSTrevor Wu .trigger = { 998094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 999094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1000094e30efSTrevor Wu }, 1001094e30efSTrevor Wu .dynamic = 1, 1002094e30efSTrevor Wu .dpcm_playback = 1, 1003094e30efSTrevor Wu .ops = &mt8195_playback_ops, 1004094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL3_FE), 1005094e30efSTrevor Wu }, 1006094e30efSTrevor Wu [DAI_LINK_DL6_FE] = { 1007094e30efSTrevor Wu .name = "DL6_FE", 1008094e30efSTrevor Wu .stream_name = "DL6 Playback", 1009094e30efSTrevor Wu .trigger = { 1010094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1011094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1012094e30efSTrevor Wu }, 1013094e30efSTrevor Wu .dynamic = 1, 1014094e30efSTrevor Wu .dpcm_playback = 1, 1015094e30efSTrevor Wu .ops = &mt8195_playback_ops, 1016094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL6_FE), 1017094e30efSTrevor Wu }, 1018094e30efSTrevor Wu [DAI_LINK_DL7_FE] = { 1019094e30efSTrevor Wu .name = "DL7_FE", 1020094e30efSTrevor Wu .stream_name = "DL7 Playback", 1021094e30efSTrevor Wu .trigger = { 1022094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 1023094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 1024094e30efSTrevor Wu }, 1025094e30efSTrevor Wu .dynamic = 1, 1026094e30efSTrevor Wu .dpcm_playback = 1, 1027094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL7_FE), 1028094e30efSTrevor Wu }, 1029094e30efSTrevor Wu [DAI_LINK_DL8_FE] = { 1030094e30efSTrevor Wu .name = "DL8_FE", 1031094e30efSTrevor Wu .stream_name = "DL8 Playback", 1032094e30efSTrevor Wu .trigger = { 1033094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1034094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1035094e30efSTrevor Wu }, 1036094e30efSTrevor Wu .dynamic = 1, 1037094e30efSTrevor Wu .dpcm_playback = 1, 1038094e30efSTrevor Wu .ops = &mt8195_playback_ops, 1039094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL8_FE), 1040094e30efSTrevor Wu }, 1041094e30efSTrevor Wu [DAI_LINK_DL10_FE] = { 1042094e30efSTrevor Wu .name = "DL10_FE", 1043094e30efSTrevor Wu .stream_name = "DL10 Playback", 1044094e30efSTrevor Wu .trigger = { 1045094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1046094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1047094e30efSTrevor Wu }, 1048094e30efSTrevor Wu .dynamic = 1, 1049094e30efSTrevor Wu .dpcm_playback = 1, 1050094e30efSTrevor Wu .ops = &mt8195_hdmitx_dptx_playback_ops, 1051094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL10_FE), 1052094e30efSTrevor Wu }, 1053094e30efSTrevor Wu [DAI_LINK_DL11_FE] = { 1054094e30efSTrevor Wu .name = "DL11_FE", 1055094e30efSTrevor Wu .stream_name = "DL11 Playback", 1056094e30efSTrevor Wu .trigger = { 1057094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1058094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1059094e30efSTrevor Wu }, 1060094e30efSTrevor Wu .dynamic = 1, 1061094e30efSTrevor Wu .dpcm_playback = 1, 1062094e30efSTrevor Wu .ops = &mt8195_playback_ops, 1063094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL11_FE), 1064094e30efSTrevor Wu }, 1065094e30efSTrevor Wu [DAI_LINK_UL1_FE] = { 1066094e30efSTrevor Wu .name = "UL1_FE", 1067094e30efSTrevor Wu .stream_name = "UL1 Capture", 1068094e30efSTrevor Wu .trigger = { 1069094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 1070094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 1071094e30efSTrevor Wu }, 1072094e30efSTrevor Wu .dynamic = 1, 1073094e30efSTrevor Wu .dpcm_capture = 1, 1074094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL1_FE), 1075094e30efSTrevor Wu }, 1076094e30efSTrevor Wu [DAI_LINK_UL2_FE] = { 1077094e30efSTrevor Wu .name = "UL2_FE", 1078094e30efSTrevor Wu .stream_name = "UL2 Capture", 1079094e30efSTrevor Wu .trigger = { 1080094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1081094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1082094e30efSTrevor Wu }, 1083094e30efSTrevor Wu .dynamic = 1, 1084094e30efSTrevor Wu .dpcm_capture = 1, 1085094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1086094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL2_FE), 1087094e30efSTrevor Wu }, 1088094e30efSTrevor Wu [DAI_LINK_UL3_FE] = { 1089094e30efSTrevor Wu .name = "UL3_FE", 1090094e30efSTrevor Wu .stream_name = "UL3 Capture", 1091094e30efSTrevor Wu .trigger = { 1092094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1093094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1094094e30efSTrevor Wu }, 1095094e30efSTrevor Wu .dynamic = 1, 1096094e30efSTrevor Wu .dpcm_capture = 1, 1097094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1098094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL3_FE), 1099094e30efSTrevor Wu }, 1100094e30efSTrevor Wu [DAI_LINK_UL4_FE] = { 1101094e30efSTrevor Wu .name = "UL4_FE", 1102094e30efSTrevor Wu .stream_name = "UL4 Capture", 1103094e30efSTrevor Wu .trigger = { 1104094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1105094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1106094e30efSTrevor Wu }, 1107094e30efSTrevor Wu .dynamic = 1, 1108094e30efSTrevor Wu .dpcm_capture = 1, 1109094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1110094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL4_FE), 1111094e30efSTrevor Wu }, 1112094e30efSTrevor Wu [DAI_LINK_UL5_FE] = { 1113094e30efSTrevor Wu .name = "UL5_FE", 1114094e30efSTrevor Wu .stream_name = "UL5 Capture", 1115094e30efSTrevor Wu .trigger = { 1116094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1117094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1118094e30efSTrevor Wu }, 1119094e30efSTrevor Wu .dynamic = 1, 1120094e30efSTrevor Wu .dpcm_capture = 1, 1121094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1122094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL5_FE), 1123094e30efSTrevor Wu }, 1124094e30efSTrevor Wu [DAI_LINK_UL6_FE] = { 1125094e30efSTrevor Wu .name = "UL6_FE", 1126094e30efSTrevor Wu .stream_name = "UL6 Capture", 1127094e30efSTrevor Wu .trigger = { 1128094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 1129094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 1130094e30efSTrevor Wu }, 1131094e30efSTrevor Wu .dynamic = 1, 1132094e30efSTrevor Wu .dpcm_capture = 1, 1133094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL6_FE), 1134094e30efSTrevor Wu }, 1135094e30efSTrevor Wu [DAI_LINK_UL8_FE] = { 1136094e30efSTrevor Wu .name = "UL8_FE", 1137094e30efSTrevor Wu .stream_name = "UL8 Capture", 1138094e30efSTrevor Wu .trigger = { 1139094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1140094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1141094e30efSTrevor Wu }, 1142094e30efSTrevor Wu .dynamic = 1, 1143094e30efSTrevor Wu .dpcm_capture = 1, 1144094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1145094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL8_FE), 1146094e30efSTrevor Wu }, 1147094e30efSTrevor Wu [DAI_LINK_UL9_FE] = { 1148094e30efSTrevor Wu .name = "UL9_FE", 1149094e30efSTrevor Wu .stream_name = "UL9 Capture", 1150094e30efSTrevor Wu .trigger = { 1151094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1152094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1153094e30efSTrevor Wu }, 1154094e30efSTrevor Wu .dynamic = 1, 1155094e30efSTrevor Wu .dpcm_capture = 1, 1156094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1157094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL9_FE), 1158094e30efSTrevor Wu }, 1159094e30efSTrevor Wu [DAI_LINK_UL10_FE] = { 1160094e30efSTrevor Wu .name = "UL10_FE", 1161094e30efSTrevor Wu .stream_name = "UL10 Capture", 1162094e30efSTrevor Wu .trigger = { 1163094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1164094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1165094e30efSTrevor Wu }, 1166094e30efSTrevor Wu .dynamic = 1, 1167094e30efSTrevor Wu .dpcm_capture = 1, 1168094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1169094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL10_FE), 1170094e30efSTrevor Wu }, 1171094e30efSTrevor Wu /* BE */ 1172094e30efSTrevor Wu [DAI_LINK_DL_SRC_BE] = { 1173094e30efSTrevor Wu .name = "DL_SRC_BE", 1174094e30efSTrevor Wu .no_pcm = 1, 1175094e30efSTrevor Wu .dpcm_playback = 1, 1176094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL_SRC_BE), 1177094e30efSTrevor Wu }, 1178094e30efSTrevor Wu [DAI_LINK_DPTX_BE] = { 1179094e30efSTrevor Wu .name = "DPTX_BE", 1180094e30efSTrevor Wu .no_pcm = 1, 1181094e30efSTrevor Wu .dpcm_playback = 1, 1182094e30efSTrevor Wu .ops = &mt8195_dptx_ops, 1183094e30efSTrevor Wu .be_hw_params_fixup = mt8195_dptx_hw_params_fixup, 1184094e30efSTrevor Wu SND_SOC_DAILINK_REG(DPTX_BE), 1185094e30efSTrevor Wu }, 1186094e30efSTrevor Wu [DAI_LINK_ETDM1_IN_BE] = { 1187094e30efSTrevor Wu .name = "ETDM1_IN_BE", 1188094e30efSTrevor Wu .no_pcm = 1, 1189094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1190094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1191094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1192094e30efSTrevor Wu .dpcm_capture = 1, 1193094e30efSTrevor Wu SND_SOC_DAILINK_REG(ETDM1_IN_BE), 1194094e30efSTrevor Wu }, 1195094e30efSTrevor Wu [DAI_LINK_ETDM2_IN_BE] = { 1196094e30efSTrevor Wu .name = "ETDM2_IN_BE", 1197094e30efSTrevor Wu .no_pcm = 1, 1198094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1199094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1200094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1201094e30efSTrevor Wu .dpcm_capture = 1, 1202094e30efSTrevor Wu .init = mt8195_rt5682_init, 1203094e30efSTrevor Wu .ops = &mt8195_rt5682_etdm_ops, 1204094e30efSTrevor Wu .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, 1205094e30efSTrevor Wu SND_SOC_DAILINK_REG(ETDM2_IN_BE), 1206094e30efSTrevor Wu }, 1207094e30efSTrevor Wu [DAI_LINK_ETDM1_OUT_BE] = { 1208094e30efSTrevor Wu .name = "ETDM1_OUT_BE", 1209094e30efSTrevor Wu .no_pcm = 1, 1210094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1211094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1212094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1213094e30efSTrevor Wu .dpcm_playback = 1, 1214094e30efSTrevor Wu .ops = &mt8195_rt5682_etdm_ops, 1215094e30efSTrevor Wu .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, 1216094e30efSTrevor Wu SND_SOC_DAILINK_REG(ETDM1_OUT_BE), 1217094e30efSTrevor Wu }, 1218094e30efSTrevor Wu [DAI_LINK_ETDM2_OUT_BE] = { 1219094e30efSTrevor Wu .name = "ETDM2_OUT_BE", 1220094e30efSTrevor Wu .no_pcm = 1, 1221094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1222094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1223094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1224094e30efSTrevor Wu .dpcm_playback = 1, 1225094e30efSTrevor Wu SND_SOC_DAILINK_REG(ETDM2_OUT_BE), 1226094e30efSTrevor Wu }, 1227094e30efSTrevor Wu [DAI_LINK_ETDM3_OUT_BE] = { 1228094e30efSTrevor Wu .name = "ETDM3_OUT_BE", 1229094e30efSTrevor Wu .no_pcm = 1, 1230094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1231094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1232094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1233094e30efSTrevor Wu .dpcm_playback = 1, 1234094e30efSTrevor Wu SND_SOC_DAILINK_REG(ETDM3_OUT_BE), 1235094e30efSTrevor Wu }, 1236094e30efSTrevor Wu [DAI_LINK_PCM1_BE] = { 1237094e30efSTrevor Wu .name = "PCM1_BE", 1238094e30efSTrevor Wu .no_pcm = 1, 1239094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1240094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1241094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1242094e30efSTrevor Wu .dpcm_playback = 1, 1243094e30efSTrevor Wu .dpcm_capture = 1, 1244094e30efSTrevor Wu SND_SOC_DAILINK_REG(PCM1_BE), 1245094e30efSTrevor Wu }, 1246094e30efSTrevor Wu [DAI_LINK_UL_SRC1_BE] = { 1247094e30efSTrevor Wu .name = "UL_SRC1_BE", 1248094e30efSTrevor Wu .no_pcm = 1, 1249094e30efSTrevor Wu .dpcm_capture = 1, 1250094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL_SRC1_BE), 1251094e30efSTrevor Wu }, 1252094e30efSTrevor Wu [DAI_LINK_UL_SRC2_BE] = { 1253094e30efSTrevor Wu .name = "UL_SRC2_BE", 1254094e30efSTrevor Wu .no_pcm = 1, 1255094e30efSTrevor Wu .dpcm_capture = 1, 1256094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL_SRC2_BE), 1257094e30efSTrevor Wu }, 1258094e30efSTrevor Wu /* SOF BE */ 1259094e30efSTrevor Wu [DAI_LINK_SOF_DL2_BE] = { 1260094e30efSTrevor Wu .name = "AFE_SOF_DL2", 1261094e30efSTrevor Wu .no_pcm = 1, 1262094e30efSTrevor Wu .dpcm_playback = 1, 1263094e30efSTrevor Wu SND_SOC_DAILINK_REG(AFE_SOF_DL2), 1264094e30efSTrevor Wu }, 1265094e30efSTrevor Wu [DAI_LINK_SOF_DL3_BE] = { 1266094e30efSTrevor Wu .name = "AFE_SOF_DL3", 1267094e30efSTrevor Wu .no_pcm = 1, 1268094e30efSTrevor Wu .dpcm_playback = 1, 1269094e30efSTrevor Wu SND_SOC_DAILINK_REG(AFE_SOF_DL3), 1270094e30efSTrevor Wu }, 1271094e30efSTrevor Wu [DAI_LINK_SOF_UL4_BE] = { 1272094e30efSTrevor Wu .name = "AFE_SOF_UL4", 1273094e30efSTrevor Wu .no_pcm = 1, 1274094e30efSTrevor Wu .dpcm_capture = 1, 1275094e30efSTrevor Wu SND_SOC_DAILINK_REG(AFE_SOF_UL4), 1276094e30efSTrevor Wu }, 1277094e30efSTrevor Wu [DAI_LINK_SOF_UL5_BE] = { 1278094e30efSTrevor Wu .name = "AFE_SOF_UL5", 1279094e30efSTrevor Wu .no_pcm = 1, 1280094e30efSTrevor Wu .dpcm_capture = 1, 1281094e30efSTrevor Wu SND_SOC_DAILINK_REG(AFE_SOF_UL5), 1282094e30efSTrevor Wu }, 1283094e30efSTrevor Wu }; 1284094e30efSTrevor Wu 1285094e30efSTrevor Wu static struct snd_soc_codec_conf rt1011_codec_conf[] = { 1286094e30efSTrevor Wu { 1287094e30efSTrevor Wu .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME), 1288094e30efSTrevor Wu .name_prefix = "Left", 1289094e30efSTrevor Wu }, 1290094e30efSTrevor Wu { 1291094e30efSTrevor Wu .dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME), 1292094e30efSTrevor Wu .name_prefix = "Right", 1293094e30efSTrevor Wu }, 1294094e30efSTrevor Wu }; 1295094e30efSTrevor Wu 129686a6b9c9STrevor Wu static struct snd_soc_codec_conf max98390_codec_conf[] = { 129786a6b9c9STrevor Wu { 129886a6b9c9STrevor Wu .dlc = COMP_CODEC_CONF(MAX98390_DEV0_NAME), 129986a6b9c9STrevor Wu .name_prefix = "Right", 130086a6b9c9STrevor Wu }, 130186a6b9c9STrevor Wu { 130286a6b9c9STrevor Wu .dlc = COMP_CODEC_CONF(MAX98390_DEV1_NAME), 130386a6b9c9STrevor Wu .name_prefix = "Left", 130486a6b9c9STrevor Wu }, 130586a6b9c9STrevor Wu }; 130686a6b9c9STrevor Wu 1307094e30efSTrevor Wu static struct snd_soc_card mt8195_mt6359_soc_card = { 1308094e30efSTrevor Wu .owner = THIS_MODULE, 1309094e30efSTrevor Wu .dai_link = mt8195_mt6359_dai_links, 1310094e30efSTrevor Wu .num_links = ARRAY_SIZE(mt8195_mt6359_dai_links), 1311094e30efSTrevor Wu .controls = mt8195_mt6359_controls, 1312094e30efSTrevor Wu .num_controls = ARRAY_SIZE(mt8195_mt6359_controls), 1313094e30efSTrevor Wu .dapm_widgets = mt8195_mt6359_widgets, 1314094e30efSTrevor Wu .num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_widgets), 1315094e30efSTrevor Wu .dapm_routes = mt8195_mt6359_routes, 1316094e30efSTrevor Wu .num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_routes), 1317094e30efSTrevor Wu .set_bias_level_post = mt8195_set_bias_level_post, 1318094e30efSTrevor Wu }; 1319094e30efSTrevor Wu 1320094e30efSTrevor Wu /* fixup the BE DAI link to match any values from topology */ 1321094e30efSTrevor Wu static int mt8195_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, 1322094e30efSTrevor Wu struct snd_pcm_hw_params *params) 1323094e30efSTrevor Wu { 1324094e30efSTrevor Wu struct snd_soc_card *card = rtd->card; 1325094e30efSTrevor Wu struct snd_soc_dai_link *sof_dai_link = NULL; 1326094e30efSTrevor Wu struct snd_soc_pcm_runtime *runtime; 1327094e30efSTrevor Wu struct snd_soc_dai *cpu_dai; 1328094e30efSTrevor Wu int i, j, ret = 0; 1329094e30efSTrevor Wu 1330094e30efSTrevor Wu for (i = 0; i < ARRAY_SIZE(g_sof_conn_streams); i++) { 1331094e30efSTrevor Wu const struct sof_conn_stream *conn = &g_sof_conn_streams[i]; 1332094e30efSTrevor Wu 1333094e30efSTrevor Wu if (strcmp(rtd->dai_link->name, conn->normal_link)) 1334094e30efSTrevor Wu continue; 1335094e30efSTrevor Wu 1336094e30efSTrevor Wu for_each_card_rtds(card, runtime) { 1337094e30efSTrevor Wu if (strcmp(runtime->dai_link->name, conn->sof_link)) 1338094e30efSTrevor Wu continue; 1339094e30efSTrevor Wu 1340094e30efSTrevor Wu for_each_rtd_cpu_dais(runtime, j, cpu_dai) { 1341094e30efSTrevor Wu if (cpu_dai->stream_active[conn->stream_dir] > 0) { 1342094e30efSTrevor Wu sof_dai_link = runtime->dai_link; 1343094e30efSTrevor Wu break; 1344094e30efSTrevor Wu } 1345094e30efSTrevor Wu } 1346094e30efSTrevor Wu break; 1347094e30efSTrevor Wu } 1348094e30efSTrevor Wu 1349094e30efSTrevor Wu if (sof_dai_link && sof_dai_link->be_hw_params_fixup) 1350094e30efSTrevor Wu ret = sof_dai_link->be_hw_params_fixup(runtime, params); 1351094e30efSTrevor Wu 1352094e30efSTrevor Wu break; 1353094e30efSTrevor Wu } 1354094e30efSTrevor Wu 1355094e30efSTrevor Wu if (!strcmp(rtd->dai_link->name, "ETDM2_IN_BE") || 1356094e30efSTrevor Wu !strcmp(rtd->dai_link->name, "ETDM1_OUT_BE")) { 1357094e30efSTrevor Wu mt8195_etdm_hw_params_fixup(runtime, params); 1358094e30efSTrevor Wu } 1359094e30efSTrevor Wu 1360094e30efSTrevor Wu return ret; 1361094e30efSTrevor Wu } 1362094e30efSTrevor Wu 1363094e30efSTrevor Wu static int mt8195_mt6359_card_late_probe(struct snd_soc_card *card) 1364094e30efSTrevor Wu { 1365094e30efSTrevor Wu struct snd_soc_pcm_runtime *runtime; 1366094e30efSTrevor Wu struct snd_soc_component *sof_comp = NULL; 1367094e30efSTrevor Wu int i; 1368094e30efSTrevor Wu 1369094e30efSTrevor Wu /* 1. find sof component */ 1370094e30efSTrevor Wu for_each_card_rtds(card, runtime) { 1371094e30efSTrevor Wu for (i = 0; i < runtime->num_components; i++) { 1372094e30efSTrevor Wu if (!runtime->components[i]->driver->name) 1373094e30efSTrevor Wu continue; 1374094e30efSTrevor Wu if (!strcmp(runtime->components[i]->driver->name, "sof-audio-component")) { 1375094e30efSTrevor Wu sof_comp = runtime->components[i]; 1376094e30efSTrevor Wu break; 1377094e30efSTrevor Wu } 1378094e30efSTrevor Wu } 1379094e30efSTrevor Wu } 1380094e30efSTrevor Wu 1381094e30efSTrevor Wu if (!sof_comp) { 1382094e30efSTrevor Wu dev_info(card->dev, " probe without component\n"); 1383094e30efSTrevor Wu return 0; 1384094e30efSTrevor Wu } 1385094e30efSTrevor Wu /* 2. add route path and fixup callback */ 1386094e30efSTrevor Wu for (i = 0; i < ARRAY_SIZE(g_sof_conn_streams); i++) { 1387094e30efSTrevor Wu const struct sof_conn_stream *conn = &g_sof_conn_streams[i]; 1388094e30efSTrevor Wu struct snd_soc_pcm_runtime *sof_rtd = NULL; 1389094e30efSTrevor Wu struct snd_soc_pcm_runtime *normal_rtd = NULL; 1390094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = NULL; 1391094e30efSTrevor Wu 1392094e30efSTrevor Wu for_each_card_rtds(card, rtd) { 1393094e30efSTrevor Wu if (!strcmp(rtd->dai_link->name, conn->sof_link)) { 1394094e30efSTrevor Wu sof_rtd = rtd; 1395094e30efSTrevor Wu continue; 1396094e30efSTrevor Wu } 1397094e30efSTrevor Wu if (!strcmp(rtd->dai_link->name, conn->normal_link)) { 1398094e30efSTrevor Wu normal_rtd = rtd; 1399094e30efSTrevor Wu continue; 1400094e30efSTrevor Wu } 1401094e30efSTrevor Wu if (normal_rtd && sof_rtd) 1402094e30efSTrevor Wu break; 1403094e30efSTrevor Wu } 1404094e30efSTrevor Wu if (normal_rtd && sof_rtd) { 1405094e30efSTrevor Wu int j; 1406094e30efSTrevor Wu struct snd_soc_dai *cpu_dai; 1407094e30efSTrevor Wu 1408094e30efSTrevor Wu for_each_rtd_cpu_dais(sof_rtd, j, cpu_dai) { 1409094e30efSTrevor Wu struct snd_soc_dapm_route route; 1410094e30efSTrevor Wu struct snd_soc_dapm_path *p = NULL; 1411094e30efSTrevor Wu struct snd_soc_dapm_widget *play_widget = 1412094e30efSTrevor Wu cpu_dai->playback_widget; 1413094e30efSTrevor Wu struct snd_soc_dapm_widget *cap_widget = 1414094e30efSTrevor Wu cpu_dai->capture_widget; 1415094e30efSTrevor Wu memset(&route, 0, sizeof(route)); 1416094e30efSTrevor Wu if (conn->stream_dir == SNDRV_PCM_STREAM_CAPTURE && 1417094e30efSTrevor Wu cap_widget) { 1418094e30efSTrevor Wu snd_soc_dapm_widget_for_each_sink_path(cap_widget, p) { 1419094e30efSTrevor Wu route.source = conn->sof_dma; 1420094e30efSTrevor Wu route.sink = p->sink->name; 1421094e30efSTrevor Wu snd_soc_dapm_add_routes(&card->dapm, &route, 1); 1422094e30efSTrevor Wu } 1423094e30efSTrevor Wu } else if (conn->stream_dir == SNDRV_PCM_STREAM_PLAYBACK && 1424094e30efSTrevor Wu play_widget){ 1425094e30efSTrevor Wu snd_soc_dapm_widget_for_each_source_path(play_widget, p) { 1426094e30efSTrevor Wu route.source = p->source->name; 1427094e30efSTrevor Wu route.sink = conn->sof_dma; 1428094e30efSTrevor Wu snd_soc_dapm_add_routes(&card->dapm, &route, 1); 1429094e30efSTrevor Wu } 1430094e30efSTrevor Wu } else { 1431094e30efSTrevor Wu dev_err(cpu_dai->dev, "stream dir and widget not pair\n"); 1432094e30efSTrevor Wu } 1433094e30efSTrevor Wu } 1434094e30efSTrevor Wu normal_rtd->dai_link->be_hw_params_fixup = mt8195_dai_link_fixup; 1435094e30efSTrevor Wu } 1436094e30efSTrevor Wu } 1437094e30efSTrevor Wu 1438094e30efSTrevor Wu return 0; 1439094e30efSTrevor Wu } 1440094e30efSTrevor Wu 1441094e30efSTrevor Wu static int mt8195_dailink_parse_of(struct snd_soc_card *card, struct device_node *np, 1442094e30efSTrevor Wu const char *propname) 1443094e30efSTrevor Wu { 1444094e30efSTrevor Wu struct device *dev = card->dev; 1445094e30efSTrevor Wu struct snd_soc_dai_link *link; 1446094e30efSTrevor Wu const char *dai_name = NULL; 1447094e30efSTrevor Wu int i, j, ret, num_links; 1448094e30efSTrevor Wu 1449094e30efSTrevor Wu num_links = of_property_count_strings(np, "mediatek,dai-link"); 1450094e30efSTrevor Wu 1451094e30efSTrevor Wu if (num_links < 0 || num_links > ARRAY_SIZE(mt8195_mt6359_dai_links)) { 1452094e30efSTrevor Wu dev_dbg(dev, "number of dai-link is invalid\n"); 1453094e30efSTrevor Wu return -EINVAL; 1454094e30efSTrevor Wu } 1455094e30efSTrevor Wu 1456094e30efSTrevor Wu card->dai_link = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL); 1457094e30efSTrevor Wu if (!card->dai_link) 1458094e30efSTrevor Wu return -ENOMEM; 1459094e30efSTrevor Wu 1460094e30efSTrevor Wu card->num_links = 0; 1461094e30efSTrevor Wu link = card->dai_link; 1462094e30efSTrevor Wu 1463094e30efSTrevor Wu for (i = 0; i < num_links; i++) { 1464094e30efSTrevor Wu ret = of_property_read_string_index(np, propname, i, &dai_name); 1465094e30efSTrevor Wu if (ret) { 1466094e30efSTrevor Wu dev_dbg(dev, "ASoC: Property '%s' index %d could not be read: %d\n", 1467094e30efSTrevor Wu propname, i, ret); 1468094e30efSTrevor Wu return -EINVAL; 1469094e30efSTrevor Wu } 1470094e30efSTrevor Wu 1471094e30efSTrevor Wu for (j = 0; j < ARRAY_SIZE(mt8195_mt6359_dai_links); j++) { 1472094e30efSTrevor Wu if (!strcmp(dai_name, mt8195_mt6359_dai_links[j].name)) { 1473094e30efSTrevor Wu memcpy(link, &mt8195_mt6359_dai_links[j], 1474094e30efSTrevor Wu sizeof(struct snd_soc_dai_link)); 1475094e30efSTrevor Wu link++; 1476094e30efSTrevor Wu card->num_links++; 1477094e30efSTrevor Wu break; 1478094e30efSTrevor Wu } 1479094e30efSTrevor Wu } 1480094e30efSTrevor Wu } 1481094e30efSTrevor Wu 1482094e30efSTrevor Wu if (card->num_links != num_links) 1483094e30efSTrevor Wu return -EINVAL; 1484094e30efSTrevor Wu 1485094e30efSTrevor Wu return 0; 1486094e30efSTrevor Wu } 1487094e30efSTrevor Wu 1488094e30efSTrevor Wu static int mt8195_mt6359_dev_probe(struct platform_device *pdev) 1489094e30efSTrevor Wu { 1490094e30efSTrevor Wu struct snd_soc_card *card = &mt8195_mt6359_soc_card; 1491094e30efSTrevor Wu struct snd_soc_dai_link *dai_link; 1492094e30efSTrevor Wu struct mt8195_mt6359_priv *priv; 1493094e30efSTrevor Wu struct device_node *platform_node, *adsp_node, *dp_node, *hdmi_node; 1494094e30efSTrevor Wu struct mt8195_card_data *card_data; 1495094e30efSTrevor Wu int is5682s = 0; 1496094e30efSTrevor Wu int init6359 = 0; 1497094e30efSTrevor Wu int sof_on = 0; 1498094e30efSTrevor Wu int ret, i; 1499094e30efSTrevor Wu 1500094e30efSTrevor Wu card_data = (struct mt8195_card_data *)of_device_get_match_data(&pdev->dev); 1501094e30efSTrevor Wu card->dev = &pdev->dev; 1502094e30efSTrevor Wu 1503094e30efSTrevor Wu ret = snd_soc_of_parse_card_name(card, "model"); 1504094e30efSTrevor Wu if (ret) { 1505094e30efSTrevor Wu dev_err(&pdev->dev, "%s new card name parsing error %d\n", 1506094e30efSTrevor Wu __func__, ret); 1507094e30efSTrevor Wu return ret; 1508094e30efSTrevor Wu } 1509094e30efSTrevor Wu 1510094e30efSTrevor Wu if (!card->name) 1511094e30efSTrevor Wu card->name = card_data->name; 1512094e30efSTrevor Wu 1513094e30efSTrevor Wu if (strstr(card->name, "_5682s")) 1514094e30efSTrevor Wu is5682s = 1; 1515094e30efSTrevor Wu 1516094e30efSTrevor Wu priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 1517094e30efSTrevor Wu if (!priv) 1518094e30efSTrevor Wu return -ENOMEM; 1519094e30efSTrevor Wu 1520094e30efSTrevor Wu if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) { 1521094e30efSTrevor Wu ret = mt8195_dailink_parse_of(card, pdev->dev.of_node, 1522094e30efSTrevor Wu "mediatek,dai-link"); 1523094e30efSTrevor Wu if (ret) { 1524094e30efSTrevor Wu dev_dbg(&pdev->dev, "Parse dai-link fail\n"); 1525094e30efSTrevor Wu return -EINVAL; 1526094e30efSTrevor Wu } 1527094e30efSTrevor Wu } else { 1528094e30efSTrevor Wu if (!sof_on) 1529094e30efSTrevor Wu card->num_links = DAI_LINK_REGULAR_NUM; 1530094e30efSTrevor Wu } 1531094e30efSTrevor Wu 1532094e30efSTrevor Wu platform_node = of_parse_phandle(pdev->dev.of_node, 1533094e30efSTrevor Wu "mediatek,platform", 0); 1534094e30efSTrevor Wu if (!platform_node) { 1535094e30efSTrevor Wu dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n"); 1536094e30efSTrevor Wu return -EINVAL; 1537094e30efSTrevor Wu } 1538094e30efSTrevor Wu 1539094e30efSTrevor Wu adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0); 1540094e30efSTrevor Wu if (adsp_node) 1541094e30efSTrevor Wu sof_on = 1; 1542094e30efSTrevor Wu 1543094e30efSTrevor Wu dp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,dptx-codec", 0); 1544094e30efSTrevor Wu hdmi_node = of_parse_phandle(pdev->dev.of_node, 1545094e30efSTrevor Wu "mediatek,hdmi-codec", 0); 1546094e30efSTrevor Wu 1547094e30efSTrevor Wu for_each_card_prelinks(card, i, dai_link) { 1548094e30efSTrevor Wu if (!dai_link->platforms->name) { 1549094e30efSTrevor Wu if (!strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")) && sof_on) 1550094e30efSTrevor Wu dai_link->platforms->of_node = adsp_node; 1551094e30efSTrevor Wu else 1552094e30efSTrevor Wu dai_link->platforms->of_node = platform_node; 1553094e30efSTrevor Wu } 1554094e30efSTrevor Wu 1555094e30efSTrevor Wu if (strcmp(dai_link->name, "DPTX_BE") == 0) { 1556094e30efSTrevor Wu if (!dp_node) { 1557094e30efSTrevor Wu dev_dbg(&pdev->dev, "No property 'dptx-codec'\n"); 1558094e30efSTrevor Wu } else { 1559094e30efSTrevor Wu dai_link->codecs->of_node = dp_node; 1560094e30efSTrevor Wu dai_link->codecs->name = NULL; 1561094e30efSTrevor Wu dai_link->codecs->dai_name = "i2s-hifi"; 1562094e30efSTrevor Wu dai_link->init = mt8195_dptx_codec_init; 1563094e30efSTrevor Wu } 1564094e30efSTrevor Wu } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { 1565094e30efSTrevor Wu if (!hdmi_node) { 1566094e30efSTrevor Wu dev_dbg(&pdev->dev, "No property 'hdmi-codec'\n"); 1567094e30efSTrevor Wu } else { 1568094e30efSTrevor Wu dai_link->codecs->of_node = hdmi_node; 1569094e30efSTrevor Wu dai_link->codecs->name = NULL; 1570094e30efSTrevor Wu dai_link->codecs->dai_name = "i2s-hifi"; 1571094e30efSTrevor Wu dai_link->init = mt8195_hdmi_codec_init; 1572094e30efSTrevor Wu } 1573094e30efSTrevor Wu } else if (strcmp(dai_link->name, "ETDM1_OUT_BE") == 0 || 1574094e30efSTrevor Wu strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { 1575094e30efSTrevor Wu dai_link->codecs->name = 1576094e30efSTrevor Wu is5682s ? RT5682S_DEV0_NAME : RT5682_DEV0_NAME; 1577094e30efSTrevor Wu dai_link->codecs->dai_name = 1578094e30efSTrevor Wu is5682s ? RT5682S_CODEC_DAI : RT5682_CODEC_DAI; 1579094e30efSTrevor Wu } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || 1580094e30efSTrevor Wu strcmp(dai_link->name, "UL_SRC1_BE") == 0 || 1581094e30efSTrevor Wu strcmp(dai_link->name, "UL_SRC2_BE") == 0) { 1582094e30efSTrevor Wu if (!init6359) { 1583094e30efSTrevor Wu dai_link->init = mt8195_mt6359_init; 1584094e30efSTrevor Wu init6359 = 1; 1585094e30efSTrevor Wu } 1586094e30efSTrevor Wu } else if (strcmp(dai_link->name, "ETDM2_OUT_BE") == 0) { 1587094e30efSTrevor Wu switch (card_data->quirk) { 1588094e30efSTrevor Wu case RT1011_SPEAKER_AMP_PRESENT: 1589094e30efSTrevor Wu dai_link->codecs = rt1011_comps; 1590094e30efSTrevor Wu dai_link->num_codecs = ARRAY_SIZE(rt1011_comps); 1591094e30efSTrevor Wu dai_link->init = mt8195_rt1011_init; 1592094e30efSTrevor Wu dai_link->ops = &mt8195_rt1011_etdm_ops; 1593094e30efSTrevor Wu dai_link->be_hw_params_fixup = mt8195_etdm_hw_params_fixup; 1594094e30efSTrevor Wu card->codec_conf = rt1011_codec_conf; 1595094e30efSTrevor Wu card->num_configs = ARRAY_SIZE(rt1011_codec_conf); 1596094e30efSTrevor Wu break; 1597094e30efSTrevor Wu case RT1019_SPEAKER_AMP_PRESENT: 1598094e30efSTrevor Wu dai_link->codecs = rt1019_comps; 1599094e30efSTrevor Wu dai_link->num_codecs = ARRAY_SIZE(rt1019_comps); 1600094e30efSTrevor Wu dai_link->init = mt8195_rt1019_init; 1601094e30efSTrevor Wu break; 160286a6b9c9STrevor Wu case MAX98390_SPEAKER_AMP_PRESENT: 160386a6b9c9STrevor Wu dai_link->codecs = max98390_comps; 160486a6b9c9STrevor Wu dai_link->num_codecs = ARRAY_SIZE(max98390_comps); 160586a6b9c9STrevor Wu dai_link->init = mt8195_max98390_init; 160686a6b9c9STrevor Wu card->codec_conf = max98390_codec_conf; 160786a6b9c9STrevor Wu card->num_configs = ARRAY_SIZE(max98390_codec_conf); 160886a6b9c9STrevor Wu break; 1609094e30efSTrevor Wu default: 1610094e30efSTrevor Wu break; 1611094e30efSTrevor Wu } 1612094e30efSTrevor Wu } 1613094e30efSTrevor Wu } 1614094e30efSTrevor Wu 1615094e30efSTrevor Wu if (sof_on) 1616094e30efSTrevor Wu card->late_probe = mt8195_mt6359_card_late_probe; 1617094e30efSTrevor Wu 1618094e30efSTrevor Wu snd_soc_card_set_drvdata(card, priv); 1619094e30efSTrevor Wu 1620094e30efSTrevor Wu ret = devm_snd_soc_register_card(&pdev->dev, card); 1621094e30efSTrevor Wu 1622094e30efSTrevor Wu of_node_put(platform_node); 1623094e30efSTrevor Wu of_node_put(adsp_node); 1624094e30efSTrevor Wu of_node_put(dp_node); 1625094e30efSTrevor Wu of_node_put(hdmi_node); 1626094e30efSTrevor Wu return ret; 1627094e30efSTrevor Wu } 1628094e30efSTrevor Wu 1629094e30efSTrevor Wu static struct mt8195_card_data mt8195_mt6359_rt1019_rt5682_card = { 1630094e30efSTrevor Wu .name = "mt8195_r1019_5682", 1631094e30efSTrevor Wu .quirk = RT1019_SPEAKER_AMP_PRESENT, 1632094e30efSTrevor Wu }; 1633094e30efSTrevor Wu 1634094e30efSTrevor Wu static struct mt8195_card_data mt8195_mt6359_rt1011_rt5682_card = { 1635094e30efSTrevor Wu .name = "mt8195_r1011_5682", 1636094e30efSTrevor Wu .quirk = RT1011_SPEAKER_AMP_PRESENT, 1637094e30efSTrevor Wu }; 1638094e30efSTrevor Wu 163986a6b9c9STrevor Wu static struct mt8195_card_data mt8195_mt6359_max98390_rt5682_card = { 164086a6b9c9STrevor Wu .name = "mt8195_m98390_r5682", 164186a6b9c9STrevor Wu .quirk = MAX98390_SPEAKER_AMP_PRESENT, 164286a6b9c9STrevor Wu }; 164386a6b9c9STrevor Wu 1644094e30efSTrevor Wu #ifdef CONFIG_OF 1645094e30efSTrevor Wu static const struct of_device_id mt8195_mt6359_dt_match[] = { 1646094e30efSTrevor Wu { 1647094e30efSTrevor Wu .compatible = "mediatek,mt8195_mt6359_rt1019_rt5682", 1648094e30efSTrevor Wu .data = &mt8195_mt6359_rt1019_rt5682_card, 1649094e30efSTrevor Wu }, 1650094e30efSTrevor Wu { 1651094e30efSTrevor Wu .compatible = "mediatek,mt8195_mt6359_rt1011_rt5682", 1652094e30efSTrevor Wu .data = &mt8195_mt6359_rt1011_rt5682_card, 1653094e30efSTrevor Wu }, 165486a6b9c9STrevor Wu { 165586a6b9c9STrevor Wu .compatible = "mediatek,mt8195_mt6359_max98390_rt5682", 165686a6b9c9STrevor Wu .data = &mt8195_mt6359_max98390_rt5682_card, 165786a6b9c9STrevor Wu }, 1658*a2c11c5bSLv Ruyi {}, 1659094e30efSTrevor Wu }; 1660094e30efSTrevor Wu #endif 1661094e30efSTrevor Wu 1662094e30efSTrevor Wu static const struct dev_pm_ops mt8195_mt6359_pm_ops = { 1663094e30efSTrevor Wu .poweroff = snd_soc_poweroff, 1664094e30efSTrevor Wu .restore = snd_soc_resume, 1665094e30efSTrevor Wu }; 1666094e30efSTrevor Wu 1667094e30efSTrevor Wu static struct platform_driver mt8195_mt6359_driver = { 1668094e30efSTrevor Wu .driver = { 1669094e30efSTrevor Wu .name = "mt8195_mt6359", 1670094e30efSTrevor Wu #ifdef CONFIG_OF 1671094e30efSTrevor Wu .of_match_table = mt8195_mt6359_dt_match, 1672094e30efSTrevor Wu #endif 1673094e30efSTrevor Wu .pm = &mt8195_mt6359_pm_ops, 1674094e30efSTrevor Wu }, 1675094e30efSTrevor Wu .probe = mt8195_mt6359_dev_probe, 1676094e30efSTrevor Wu }; 1677094e30efSTrevor Wu 1678094e30efSTrevor Wu module_platform_driver(mt8195_mt6359_driver); 1679094e30efSTrevor Wu 1680094e30efSTrevor Wu /* Module information */ 1681094e30efSTrevor Wu MODULE_DESCRIPTION("MT8195-MT6359 ALSA SoC machine driver"); 1682094e30efSTrevor Wu MODULE_AUTHOR("Trevor Wu <trevor.wu@mediatek.com>"); 1683094e30efSTrevor Wu MODULE_AUTHOR("YC Hung <yc.hung@mediatek.com>"); 1684094e30efSTrevor Wu MODULE_LICENSE("GPL"); 1685094e30efSTrevor Wu MODULE_ALIAS("mt8195_mt6359 soc card"); 1686