1*094e30efSTrevor Wu // SPDX-License-Identifier: GPL-2.0 2*094e30efSTrevor Wu /* 3*094e30efSTrevor Wu * mt8195-mt6359.c -- 4*094e30efSTrevor Wu * MT8195-MT6359 ALSA SoC machine driver code 5*094e30efSTrevor Wu * 6*094e30efSTrevor Wu * Copyright (c) 2022 MediaTek Inc. 7*094e30efSTrevor Wu * Author: Trevor Wu <trevor.wu@mediatek.com> 8*094e30efSTrevor Wu * YC Hung <yc.hung@mediatek.com> 9*094e30efSTrevor Wu */ 10*094e30efSTrevor Wu 11*094e30efSTrevor Wu #include <linux/input.h> 12*094e30efSTrevor Wu #include <linux/module.h> 13*094e30efSTrevor Wu #include <linux/of_device.h> 14*094e30efSTrevor Wu #include <linux/pm_runtime.h> 15*094e30efSTrevor Wu #include <sound/jack.h> 16*094e30efSTrevor Wu #include <sound/pcm_params.h> 17*094e30efSTrevor Wu #include <sound/rt5682.h> 18*094e30efSTrevor Wu #include <sound/soc.h> 19*094e30efSTrevor Wu #include "../../codecs/mt6359.h" 20*094e30efSTrevor Wu #include "../../codecs/rt1011.h" 21*094e30efSTrevor Wu #include "../../codecs/rt5682.h" 22*094e30efSTrevor Wu #include "../common/mtk-afe-platform-driver.h" 23*094e30efSTrevor Wu #include "mt8195-afe-clk.h" 24*094e30efSTrevor Wu #include "mt8195-afe-common.h" 25*094e30efSTrevor Wu 26*094e30efSTrevor Wu #define RT1011_SPEAKER_AMP_PRESENT BIT(0) 27*094e30efSTrevor Wu #define RT1019_SPEAKER_AMP_PRESENT BIT(1) 28*094e30efSTrevor Wu 29*094e30efSTrevor Wu #define RT1011_CODEC_DAI "rt1011-aif" 30*094e30efSTrevor Wu #define RT1011_DEV0_NAME "rt1011.2-0038" 31*094e30efSTrevor Wu #define RT1011_DEV1_NAME "rt1011.2-0039" 32*094e30efSTrevor Wu 33*094e30efSTrevor Wu #define RT1019_CODEC_DAI "HiFi" 34*094e30efSTrevor Wu #define RT1019_DEV0_NAME "rt1019p" 35*094e30efSTrevor Wu 36*094e30efSTrevor Wu #define RT5682_CODEC_DAI "rt5682-aif1" 37*094e30efSTrevor Wu #define RT5682_DEV0_NAME "rt5682.2-001a" 38*094e30efSTrevor Wu 39*094e30efSTrevor Wu #define RT5682S_CODEC_DAI "rt5682s-aif1" 40*094e30efSTrevor Wu #define RT5682S_DEV0_NAME "rt5682s.2-001a" 41*094e30efSTrevor Wu 42*094e30efSTrevor Wu #define SOF_DMA_DL2 "SOF_DMA_DL2" 43*094e30efSTrevor Wu #define SOF_DMA_DL3 "SOF_DMA_DL3" 44*094e30efSTrevor Wu #define SOF_DMA_UL4 "SOF_DMA_UL4" 45*094e30efSTrevor Wu #define SOF_DMA_UL5 "SOF_DMA_UL5" 46*094e30efSTrevor Wu 47*094e30efSTrevor Wu struct mt8195_card_data { 48*094e30efSTrevor Wu const char *name; 49*094e30efSTrevor Wu unsigned long quirk; 50*094e30efSTrevor Wu }; 51*094e30efSTrevor Wu 52*094e30efSTrevor Wu struct sof_conn_stream { 53*094e30efSTrevor Wu const char *normal_link; 54*094e30efSTrevor Wu const char *sof_link; 55*094e30efSTrevor Wu const char *sof_dma; 56*094e30efSTrevor Wu int stream_dir; 57*094e30efSTrevor Wu }; 58*094e30efSTrevor Wu 59*094e30efSTrevor Wu struct mt8195_mt6359_priv { 60*094e30efSTrevor Wu struct snd_soc_jack headset_jack; 61*094e30efSTrevor Wu struct snd_soc_jack dp_jack; 62*094e30efSTrevor Wu struct snd_soc_jack hdmi_jack; 63*094e30efSTrevor Wu struct clk *i2so1_mclk; 64*094e30efSTrevor Wu }; 65*094e30efSTrevor Wu 66*094e30efSTrevor Wu static const struct snd_soc_dapm_widget mt8195_mt6359_widgets[] = { 67*094e30efSTrevor Wu SND_SOC_DAPM_HP("Headphone Jack", NULL), 68*094e30efSTrevor Wu SND_SOC_DAPM_MIC("Headset Mic", NULL), 69*094e30efSTrevor Wu SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0), 70*094e30efSTrevor Wu SND_SOC_DAPM_MIXER(SOF_DMA_DL3, SND_SOC_NOPM, 0, 0, NULL, 0), 71*094e30efSTrevor Wu SND_SOC_DAPM_MIXER(SOF_DMA_UL4, SND_SOC_NOPM, 0, 0, NULL, 0), 72*094e30efSTrevor Wu SND_SOC_DAPM_MIXER(SOF_DMA_UL5, SND_SOC_NOPM, 0, 0, NULL, 0), 73*094e30efSTrevor Wu }; 74*094e30efSTrevor Wu 75*094e30efSTrevor Wu static const struct snd_soc_dapm_route mt8195_mt6359_routes[] = { 76*094e30efSTrevor Wu /* headset */ 77*094e30efSTrevor Wu { "Headphone Jack", NULL, "HPOL" }, 78*094e30efSTrevor Wu { "Headphone Jack", NULL, "HPOR" }, 79*094e30efSTrevor Wu { "IN1P", NULL, "Headset Mic" }, 80*094e30efSTrevor Wu /* SOF Uplink */ 81*094e30efSTrevor Wu {SOF_DMA_UL4, NULL, "O034"}, 82*094e30efSTrevor Wu {SOF_DMA_UL4, NULL, "O035"}, 83*094e30efSTrevor Wu {SOF_DMA_UL5, NULL, "O036"}, 84*094e30efSTrevor Wu {SOF_DMA_UL5, NULL, "O037"}, 85*094e30efSTrevor Wu /* SOF Downlink */ 86*094e30efSTrevor Wu {"I070", NULL, SOF_DMA_DL2}, 87*094e30efSTrevor Wu {"I071", NULL, SOF_DMA_DL2}, 88*094e30efSTrevor Wu {"I020", NULL, SOF_DMA_DL3}, 89*094e30efSTrevor Wu {"I021", NULL, SOF_DMA_DL3}, 90*094e30efSTrevor Wu }; 91*094e30efSTrevor Wu 92*094e30efSTrevor Wu static const struct snd_kcontrol_new mt8195_mt6359_controls[] = { 93*094e30efSTrevor Wu SOC_DAPM_PIN_SWITCH("Headphone Jack"), 94*094e30efSTrevor Wu SOC_DAPM_PIN_SWITCH("Headset Mic"), 95*094e30efSTrevor Wu }; 96*094e30efSTrevor Wu 97*094e30efSTrevor Wu static const struct snd_soc_dapm_widget mt8195_dual_speaker_widgets[] = { 98*094e30efSTrevor Wu SND_SOC_DAPM_SPK("Left Speaker", NULL), 99*094e30efSTrevor Wu SND_SOC_DAPM_SPK("Right Speaker", NULL), 100*094e30efSTrevor Wu }; 101*094e30efSTrevor Wu 102*094e30efSTrevor Wu static const struct snd_kcontrol_new mt8195_dual_speaker_controls[] = { 103*094e30efSTrevor Wu SOC_DAPM_PIN_SWITCH("Left Speaker"), 104*094e30efSTrevor Wu SOC_DAPM_PIN_SWITCH("Right Speaker"), 105*094e30efSTrevor Wu }; 106*094e30efSTrevor Wu 107*094e30efSTrevor Wu static const struct snd_soc_dapm_widget mt8195_speaker_widgets[] = { 108*094e30efSTrevor Wu SND_SOC_DAPM_SPK("Speakers", NULL), 109*094e30efSTrevor Wu }; 110*094e30efSTrevor Wu 111*094e30efSTrevor Wu static const struct snd_kcontrol_new mt8195_speaker_controls[] = { 112*094e30efSTrevor Wu SOC_DAPM_PIN_SWITCH("Speakers"), 113*094e30efSTrevor Wu }; 114*094e30efSTrevor Wu 115*094e30efSTrevor Wu static const struct snd_soc_dapm_route mt8195_rt1011_routes[] = { 116*094e30efSTrevor Wu { "Left Speaker", NULL, "Left SPO" }, 117*094e30efSTrevor Wu { "Right Speaker", NULL, "Right SPO" }, 118*094e30efSTrevor Wu }; 119*094e30efSTrevor Wu 120*094e30efSTrevor Wu static const struct snd_soc_dapm_route mt8195_rt1019_routes[] = { 121*094e30efSTrevor Wu { "Speakers", NULL, "Speaker" }, 122*094e30efSTrevor Wu }; 123*094e30efSTrevor Wu 124*094e30efSTrevor Wu #define CKSYS_AUD_TOP_CFG 0x032c 125*094e30efSTrevor Wu #define CKSYS_AUD_TOP_MON 0x0330 126*094e30efSTrevor Wu 127*094e30efSTrevor Wu static int mt8195_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) 128*094e30efSTrevor Wu { 129*094e30efSTrevor Wu struct snd_soc_component *cmpnt_afe = 130*094e30efSTrevor Wu snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 131*094e30efSTrevor Wu struct snd_soc_component *cmpnt_codec = 132*094e30efSTrevor Wu asoc_rtd_to_codec(rtd, 0)->component; 133*094e30efSTrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 134*094e30efSTrevor Wu struct mt8195_afe_private *afe_priv = afe->platform_priv; 135*094e30efSTrevor Wu struct mtkaif_param *param = &afe_priv->mtkaif_params; 136*094e30efSTrevor Wu int chosen_phase_1, chosen_phase_2, chosen_phase_3; 137*094e30efSTrevor Wu int prev_cycle_1, prev_cycle_2, prev_cycle_3; 138*094e30efSTrevor Wu int test_done_1, test_done_2, test_done_3; 139*094e30efSTrevor Wu int cycle_1, cycle_2, cycle_3; 140*094e30efSTrevor Wu int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM]; 141*094e30efSTrevor Wu int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM]; 142*094e30efSTrevor Wu int mtkaif_calibration_num_phase; 143*094e30efSTrevor Wu bool mtkaif_calibration_ok; 144*094e30efSTrevor Wu unsigned int monitor; 145*094e30efSTrevor Wu int counter; 146*094e30efSTrevor Wu int phase; 147*094e30efSTrevor Wu int i; 148*094e30efSTrevor Wu 149*094e30efSTrevor Wu dev_dbg(afe->dev, "%s(), start\n", __func__); 150*094e30efSTrevor Wu 151*094e30efSTrevor Wu param->mtkaif_calibration_ok = false; 152*094e30efSTrevor Wu for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) { 153*094e30efSTrevor Wu param->mtkaif_chosen_phase[i] = -1; 154*094e30efSTrevor Wu param->mtkaif_phase_cycle[i] = 0; 155*094e30efSTrevor Wu mtkaif_chosen_phase[i] = -1; 156*094e30efSTrevor Wu mtkaif_phase_cycle[i] = 0; 157*094e30efSTrevor Wu } 158*094e30efSTrevor Wu 159*094e30efSTrevor Wu if (IS_ERR(afe_priv->topckgen)) { 160*094e30efSTrevor Wu dev_info(afe->dev, "%s() Cannot find topckgen controller\n", 161*094e30efSTrevor Wu __func__); 162*094e30efSTrevor Wu return 0; 163*094e30efSTrevor Wu } 164*094e30efSTrevor Wu 165*094e30efSTrevor Wu pm_runtime_get_sync(afe->dev); 166*094e30efSTrevor Wu mt6359_mtkaif_calibration_enable(cmpnt_codec); 167*094e30efSTrevor Wu 168*094e30efSTrevor Wu /* set test type to synchronizer pulse */ 169*094e30efSTrevor Wu regmap_update_bits(afe_priv->topckgen, 170*094e30efSTrevor Wu CKSYS_AUD_TOP_CFG, 0xffff, 0x4); 171*094e30efSTrevor Wu mtkaif_calibration_num_phase = 42; /* mt6359: 0 ~ 42 */ 172*094e30efSTrevor Wu mtkaif_calibration_ok = true; 173*094e30efSTrevor Wu 174*094e30efSTrevor Wu for (phase = 0; 175*094e30efSTrevor Wu phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok; 176*094e30efSTrevor Wu phase++) { 177*094e30efSTrevor Wu mt6359_set_mtkaif_calibration_phase(cmpnt_codec, 178*094e30efSTrevor Wu phase, phase, phase); 179*094e30efSTrevor Wu 180*094e30efSTrevor Wu regmap_update_bits(afe_priv->topckgen, 181*094e30efSTrevor Wu CKSYS_AUD_TOP_CFG, 0x1, 0x1); 182*094e30efSTrevor Wu 183*094e30efSTrevor Wu test_done_1 = 0; 184*094e30efSTrevor Wu test_done_2 = 0; 185*094e30efSTrevor Wu test_done_3 = 0; 186*094e30efSTrevor Wu cycle_1 = -1; 187*094e30efSTrevor Wu cycle_2 = -1; 188*094e30efSTrevor Wu cycle_3 = -1; 189*094e30efSTrevor Wu counter = 0; 190*094e30efSTrevor Wu while (!(test_done_1 & test_done_2 & test_done_3)) { 191*094e30efSTrevor Wu regmap_read(afe_priv->topckgen, 192*094e30efSTrevor Wu CKSYS_AUD_TOP_MON, &monitor); 193*094e30efSTrevor Wu test_done_1 = (monitor >> 28) & 0x1; 194*094e30efSTrevor Wu test_done_2 = (monitor >> 29) & 0x1; 195*094e30efSTrevor Wu test_done_3 = (monitor >> 30) & 0x1; 196*094e30efSTrevor Wu if (test_done_1 == 1) 197*094e30efSTrevor Wu cycle_1 = monitor & 0xf; 198*094e30efSTrevor Wu 199*094e30efSTrevor Wu if (test_done_2 == 1) 200*094e30efSTrevor Wu cycle_2 = (monitor >> 4) & 0xf; 201*094e30efSTrevor Wu 202*094e30efSTrevor Wu if (test_done_3 == 1) 203*094e30efSTrevor Wu cycle_3 = (monitor >> 8) & 0xf; 204*094e30efSTrevor Wu 205*094e30efSTrevor Wu /* handle if never test done */ 206*094e30efSTrevor Wu if (++counter > 10000) { 207*094e30efSTrevor Wu dev_info(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, cycle_3 %d, monitor 0x%x\n", 208*094e30efSTrevor Wu __func__, 209*094e30efSTrevor Wu cycle_1, cycle_2, cycle_3, monitor); 210*094e30efSTrevor Wu mtkaif_calibration_ok = false; 211*094e30efSTrevor Wu break; 212*094e30efSTrevor Wu } 213*094e30efSTrevor Wu } 214*094e30efSTrevor Wu 215*094e30efSTrevor Wu if (phase == 0) { 216*094e30efSTrevor Wu prev_cycle_1 = cycle_1; 217*094e30efSTrevor Wu prev_cycle_2 = cycle_2; 218*094e30efSTrevor Wu prev_cycle_3 = cycle_3; 219*094e30efSTrevor Wu } 220*094e30efSTrevor Wu 221*094e30efSTrevor Wu if (cycle_1 != prev_cycle_1 && 222*094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) { 223*094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = phase - 1; 224*094e30efSTrevor Wu mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] = prev_cycle_1; 225*094e30efSTrevor Wu } 226*094e30efSTrevor Wu 227*094e30efSTrevor Wu if (cycle_2 != prev_cycle_2 && 228*094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) { 229*094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = phase - 1; 230*094e30efSTrevor Wu mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] = prev_cycle_2; 231*094e30efSTrevor Wu } 232*094e30efSTrevor Wu 233*094e30efSTrevor Wu if (cycle_3 != prev_cycle_3 && 234*094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) { 235*094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = phase - 1; 236*094e30efSTrevor Wu mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] = prev_cycle_3; 237*094e30efSTrevor Wu } 238*094e30efSTrevor Wu 239*094e30efSTrevor Wu regmap_update_bits(afe_priv->topckgen, 240*094e30efSTrevor Wu CKSYS_AUD_TOP_CFG, 0x1, 0x0); 241*094e30efSTrevor Wu 242*094e30efSTrevor Wu if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] >= 0 && 243*094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] >= 0 && 244*094e30efSTrevor Wu mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] >= 0) 245*094e30efSTrevor Wu break; 246*094e30efSTrevor Wu } 247*094e30efSTrevor Wu 248*094e30efSTrevor Wu if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) { 249*094e30efSTrevor Wu mtkaif_calibration_ok = false; 250*094e30efSTrevor Wu chosen_phase_1 = 0; 251*094e30efSTrevor Wu } else { 252*094e30efSTrevor Wu chosen_phase_1 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0]; 253*094e30efSTrevor Wu } 254*094e30efSTrevor Wu 255*094e30efSTrevor Wu if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) { 256*094e30efSTrevor Wu mtkaif_calibration_ok = false; 257*094e30efSTrevor Wu chosen_phase_2 = 0; 258*094e30efSTrevor Wu } else { 259*094e30efSTrevor Wu chosen_phase_2 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1]; 260*094e30efSTrevor Wu } 261*094e30efSTrevor Wu 262*094e30efSTrevor Wu if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) { 263*094e30efSTrevor Wu mtkaif_calibration_ok = false; 264*094e30efSTrevor Wu chosen_phase_3 = 0; 265*094e30efSTrevor Wu } else { 266*094e30efSTrevor Wu chosen_phase_3 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2]; 267*094e30efSTrevor Wu } 268*094e30efSTrevor Wu 269*094e30efSTrevor Wu mt6359_set_mtkaif_calibration_phase(cmpnt_codec, 270*094e30efSTrevor Wu chosen_phase_1, 271*094e30efSTrevor Wu chosen_phase_2, 272*094e30efSTrevor Wu chosen_phase_3); 273*094e30efSTrevor Wu 274*094e30efSTrevor Wu mt6359_mtkaif_calibration_disable(cmpnt_codec); 275*094e30efSTrevor Wu pm_runtime_put(afe->dev); 276*094e30efSTrevor Wu 277*094e30efSTrevor Wu param->mtkaif_calibration_ok = mtkaif_calibration_ok; 278*094e30efSTrevor Wu param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = chosen_phase_1; 279*094e30efSTrevor Wu param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = chosen_phase_2; 280*094e30efSTrevor Wu param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = chosen_phase_3; 281*094e30efSTrevor Wu for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) 282*094e30efSTrevor Wu param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i]; 283*094e30efSTrevor Wu 284*094e30efSTrevor Wu dev_info(afe->dev, "%s(), end, calibration ok %d\n", 285*094e30efSTrevor Wu __func__, param->mtkaif_calibration_ok); 286*094e30efSTrevor Wu 287*094e30efSTrevor Wu return 0; 288*094e30efSTrevor Wu } 289*094e30efSTrevor Wu 290*094e30efSTrevor Wu static int mt8195_mt6359_init(struct snd_soc_pcm_runtime *rtd) 291*094e30efSTrevor Wu { 292*094e30efSTrevor Wu struct snd_soc_component *cmpnt_codec = 293*094e30efSTrevor Wu asoc_rtd_to_codec(rtd, 0)->component; 294*094e30efSTrevor Wu 295*094e30efSTrevor Wu /* set mtkaif protocol */ 296*094e30efSTrevor Wu mt6359_set_mtkaif_protocol(cmpnt_codec, 297*094e30efSTrevor Wu MT6359_MTKAIF_PROTOCOL_2_CLK_P2); 298*094e30efSTrevor Wu 299*094e30efSTrevor Wu /* mtkaif calibration */ 300*094e30efSTrevor Wu mt8195_mt6359_mtkaif_calibration(rtd); 301*094e30efSTrevor Wu 302*094e30efSTrevor Wu return 0; 303*094e30efSTrevor Wu } 304*094e30efSTrevor Wu 305*094e30efSTrevor Wu static int mt8195_hdmitx_dptx_startup(struct snd_pcm_substream *substream) 306*094e30efSTrevor Wu { 307*094e30efSTrevor Wu static const unsigned int rates[] = { 308*094e30efSTrevor Wu 48000 309*094e30efSTrevor Wu }; 310*094e30efSTrevor Wu static const unsigned int channels[] = { 311*094e30efSTrevor Wu 2, 4, 6, 8 312*094e30efSTrevor Wu }; 313*094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_rates = { 314*094e30efSTrevor Wu .count = ARRAY_SIZE(rates), 315*094e30efSTrevor Wu .list = rates, 316*094e30efSTrevor Wu .mask = 0, 317*094e30efSTrevor Wu }; 318*094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_channels = { 319*094e30efSTrevor Wu .count = ARRAY_SIZE(channels), 320*094e30efSTrevor Wu .list = channels, 321*094e30efSTrevor Wu .mask = 0, 322*094e30efSTrevor Wu }; 323*094e30efSTrevor Wu 324*094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 325*094e30efSTrevor Wu struct snd_pcm_runtime *runtime = substream->runtime; 326*094e30efSTrevor Wu int ret; 327*094e30efSTrevor Wu 328*094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 329*094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_RATE, 330*094e30efSTrevor Wu &constraints_rates); 331*094e30efSTrevor Wu if (ret < 0) { 332*094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list rate failed\n"); 333*094e30efSTrevor Wu return ret; 334*094e30efSTrevor Wu } 335*094e30efSTrevor Wu 336*094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 337*094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_CHANNELS, 338*094e30efSTrevor Wu &constraints_channels); 339*094e30efSTrevor Wu if (ret < 0) { 340*094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list channel failed\n"); 341*094e30efSTrevor Wu return ret; 342*094e30efSTrevor Wu } 343*094e30efSTrevor Wu 344*094e30efSTrevor Wu return 0; 345*094e30efSTrevor Wu } 346*094e30efSTrevor Wu 347*094e30efSTrevor Wu static const struct snd_soc_ops mt8195_hdmitx_dptx_playback_ops = { 348*094e30efSTrevor Wu .startup = mt8195_hdmitx_dptx_startup, 349*094e30efSTrevor Wu }; 350*094e30efSTrevor Wu 351*094e30efSTrevor Wu static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream, 352*094e30efSTrevor Wu struct snd_pcm_hw_params *params) 353*094e30efSTrevor Wu { 354*094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = substream->private_data; 355*094e30efSTrevor Wu struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 356*094e30efSTrevor Wu 357*094e30efSTrevor Wu return snd_soc_dai_set_sysclk(cpu_dai, 0, params_rate(params) * 256, 358*094e30efSTrevor Wu SND_SOC_CLOCK_OUT); 359*094e30efSTrevor Wu } 360*094e30efSTrevor Wu 361*094e30efSTrevor Wu static const struct snd_soc_ops mt8195_dptx_ops = { 362*094e30efSTrevor Wu .hw_params = mt8195_dptx_hw_params, 363*094e30efSTrevor Wu }; 364*094e30efSTrevor Wu 365*094e30efSTrevor Wu static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) 366*094e30efSTrevor Wu { 367*094e30efSTrevor Wu struct mt8195_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); 368*094e30efSTrevor Wu struct snd_soc_component *cmpnt_codec = 369*094e30efSTrevor Wu asoc_rtd_to_codec(rtd, 0)->component; 370*094e30efSTrevor Wu int ret; 371*094e30efSTrevor Wu 372*094e30efSTrevor Wu ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_LINEOUT, 373*094e30efSTrevor Wu &priv->dp_jack, NULL, 0); 374*094e30efSTrevor Wu if (ret) 375*094e30efSTrevor Wu return ret; 376*094e30efSTrevor Wu 377*094e30efSTrevor Wu return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL); 378*094e30efSTrevor Wu } 379*094e30efSTrevor Wu 380*094e30efSTrevor Wu static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd) 381*094e30efSTrevor Wu { 382*094e30efSTrevor Wu struct mt8195_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); 383*094e30efSTrevor Wu struct snd_soc_component *cmpnt_codec = 384*094e30efSTrevor Wu asoc_rtd_to_codec(rtd, 0)->component; 385*094e30efSTrevor Wu int ret; 386*094e30efSTrevor Wu 387*094e30efSTrevor Wu ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, 388*094e30efSTrevor Wu &priv->hdmi_jack, NULL, 0); 389*094e30efSTrevor Wu if (ret) 390*094e30efSTrevor Wu return ret; 391*094e30efSTrevor Wu 392*094e30efSTrevor Wu return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL); 393*094e30efSTrevor Wu } 394*094e30efSTrevor Wu 395*094e30efSTrevor Wu static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 396*094e30efSTrevor Wu struct snd_pcm_hw_params *params) 397*094e30efSTrevor Wu { 398*094e30efSTrevor Wu /* fix BE i2s format to S24_LE, clean param mask first */ 399*094e30efSTrevor Wu snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 400*094e30efSTrevor Wu 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); 401*094e30efSTrevor Wu 402*094e30efSTrevor Wu params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 403*094e30efSTrevor Wu 404*094e30efSTrevor Wu return 0; 405*094e30efSTrevor Wu } 406*094e30efSTrevor Wu 407*094e30efSTrevor Wu static int mt8195_playback_startup(struct snd_pcm_substream *substream) 408*094e30efSTrevor Wu { 409*094e30efSTrevor Wu static const unsigned int rates[] = { 410*094e30efSTrevor Wu 48000 411*094e30efSTrevor Wu }; 412*094e30efSTrevor Wu static const unsigned int channels[] = { 413*094e30efSTrevor Wu 2 414*094e30efSTrevor Wu }; 415*094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_rates = { 416*094e30efSTrevor Wu .count = ARRAY_SIZE(rates), 417*094e30efSTrevor Wu .list = rates, 418*094e30efSTrevor Wu .mask = 0, 419*094e30efSTrevor Wu }; 420*094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_channels = { 421*094e30efSTrevor Wu .count = ARRAY_SIZE(channels), 422*094e30efSTrevor Wu .list = channels, 423*094e30efSTrevor Wu .mask = 0, 424*094e30efSTrevor Wu }; 425*094e30efSTrevor Wu 426*094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 427*094e30efSTrevor Wu struct snd_pcm_runtime *runtime = substream->runtime; 428*094e30efSTrevor Wu int ret; 429*094e30efSTrevor Wu 430*094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 431*094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_RATE, 432*094e30efSTrevor Wu &constraints_rates); 433*094e30efSTrevor Wu if (ret < 0) { 434*094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list rate failed\n"); 435*094e30efSTrevor Wu return ret; 436*094e30efSTrevor Wu } 437*094e30efSTrevor Wu 438*094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 439*094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_CHANNELS, 440*094e30efSTrevor Wu &constraints_channels); 441*094e30efSTrevor Wu if (ret < 0) { 442*094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list channel failed\n"); 443*094e30efSTrevor Wu return ret; 444*094e30efSTrevor Wu } 445*094e30efSTrevor Wu 446*094e30efSTrevor Wu return 0; 447*094e30efSTrevor Wu } 448*094e30efSTrevor Wu 449*094e30efSTrevor Wu static const struct snd_soc_ops mt8195_playback_ops = { 450*094e30efSTrevor Wu .startup = mt8195_playback_startup, 451*094e30efSTrevor Wu }; 452*094e30efSTrevor Wu 453*094e30efSTrevor Wu static int mt8195_capture_startup(struct snd_pcm_substream *substream) 454*094e30efSTrevor Wu { 455*094e30efSTrevor Wu static const unsigned int rates[] = { 456*094e30efSTrevor Wu 48000 457*094e30efSTrevor Wu }; 458*094e30efSTrevor Wu static const unsigned int channels[] = { 459*094e30efSTrevor Wu 1, 2 460*094e30efSTrevor Wu }; 461*094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_rates = { 462*094e30efSTrevor Wu .count = ARRAY_SIZE(rates), 463*094e30efSTrevor Wu .list = rates, 464*094e30efSTrevor Wu .mask = 0, 465*094e30efSTrevor Wu }; 466*094e30efSTrevor Wu static const struct snd_pcm_hw_constraint_list constraints_channels = { 467*094e30efSTrevor Wu .count = ARRAY_SIZE(channels), 468*094e30efSTrevor Wu .list = channels, 469*094e30efSTrevor Wu .mask = 0, 470*094e30efSTrevor Wu }; 471*094e30efSTrevor Wu 472*094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 473*094e30efSTrevor Wu struct snd_pcm_runtime *runtime = substream->runtime; 474*094e30efSTrevor Wu int ret; 475*094e30efSTrevor Wu 476*094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 477*094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_RATE, 478*094e30efSTrevor Wu &constraints_rates); 479*094e30efSTrevor Wu if (ret < 0) { 480*094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list rate failed\n"); 481*094e30efSTrevor Wu return ret; 482*094e30efSTrevor Wu } 483*094e30efSTrevor Wu 484*094e30efSTrevor Wu ret = snd_pcm_hw_constraint_list(runtime, 0, 485*094e30efSTrevor Wu SNDRV_PCM_HW_PARAM_CHANNELS, 486*094e30efSTrevor Wu &constraints_channels); 487*094e30efSTrevor Wu if (ret < 0) { 488*094e30efSTrevor Wu dev_err(rtd->dev, "hw_constraint_list channel failed\n"); 489*094e30efSTrevor Wu return ret; 490*094e30efSTrevor Wu } 491*094e30efSTrevor Wu 492*094e30efSTrevor Wu return 0; 493*094e30efSTrevor Wu } 494*094e30efSTrevor Wu 495*094e30efSTrevor Wu static const struct snd_soc_ops mt8195_capture_ops = { 496*094e30efSTrevor Wu .startup = mt8195_capture_startup, 497*094e30efSTrevor Wu }; 498*094e30efSTrevor Wu 499*094e30efSTrevor Wu static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream, 500*094e30efSTrevor Wu struct snd_pcm_hw_params *params) 501*094e30efSTrevor Wu { 502*094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = substream->private_data; 503*094e30efSTrevor Wu struct snd_soc_card *card = rtd->card; 504*094e30efSTrevor Wu struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 505*094e30efSTrevor Wu struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 506*094e30efSTrevor Wu unsigned int rate = params_rate(params); 507*094e30efSTrevor Wu int bitwidth; 508*094e30efSTrevor Wu int ret; 509*094e30efSTrevor Wu 510*094e30efSTrevor Wu bitwidth = snd_pcm_format_width(params_format(params)); 511*094e30efSTrevor Wu if (bitwidth < 0) { 512*094e30efSTrevor Wu dev_err(card->dev, "invalid bit width: %d\n", bitwidth); 513*094e30efSTrevor Wu return bitwidth; 514*094e30efSTrevor Wu } 515*094e30efSTrevor Wu 516*094e30efSTrevor Wu ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth); 517*094e30efSTrevor Wu if (ret) { 518*094e30efSTrevor Wu dev_err(card->dev, "failed to set tdm slot\n"); 519*094e30efSTrevor Wu return ret; 520*094e30efSTrevor Wu } 521*094e30efSTrevor Wu 522*094e30efSTrevor Wu ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, RT5682_PLL1_S_MCLK, 523*094e30efSTrevor Wu rate * 256, rate * 512); 524*094e30efSTrevor Wu if (ret) { 525*094e30efSTrevor Wu dev_err(card->dev, "failed to set pll\n"); 526*094e30efSTrevor Wu return ret; 527*094e30efSTrevor Wu } 528*094e30efSTrevor Wu 529*094e30efSTrevor Wu ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1, 530*094e30efSTrevor Wu rate * 512, SND_SOC_CLOCK_IN); 531*094e30efSTrevor Wu if (ret) { 532*094e30efSTrevor Wu dev_err(card->dev, "failed to set sysclk\n"); 533*094e30efSTrevor Wu return ret; 534*094e30efSTrevor Wu } 535*094e30efSTrevor Wu 536*094e30efSTrevor Wu return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 256, 537*094e30efSTrevor Wu SND_SOC_CLOCK_OUT); 538*094e30efSTrevor Wu } 539*094e30efSTrevor Wu 540*094e30efSTrevor Wu static const struct snd_soc_ops mt8195_rt5682_etdm_ops = { 541*094e30efSTrevor Wu .hw_params = mt8195_rt5682_etdm_hw_params, 542*094e30efSTrevor Wu }; 543*094e30efSTrevor Wu 544*094e30efSTrevor Wu static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd) 545*094e30efSTrevor Wu { 546*094e30efSTrevor Wu struct snd_soc_component *cmpnt_codec = 547*094e30efSTrevor Wu asoc_rtd_to_codec(rtd, 0)->component; 548*094e30efSTrevor Wu struct mt8195_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); 549*094e30efSTrevor Wu struct snd_soc_jack *jack = &priv->headset_jack; 550*094e30efSTrevor Wu struct snd_soc_component *cmpnt_afe = 551*094e30efSTrevor Wu snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 552*094e30efSTrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 553*094e30efSTrevor Wu struct mt8195_afe_private *afe_priv = afe->platform_priv; 554*094e30efSTrevor Wu int ret; 555*094e30efSTrevor Wu 556*094e30efSTrevor Wu priv->i2so1_mclk = afe_priv->clk[MT8195_CLK_TOP_APLL12_DIV2]; 557*094e30efSTrevor Wu 558*094e30efSTrevor Wu ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", 559*094e30efSTrevor Wu SND_JACK_HEADSET | SND_JACK_BTN_0 | 560*094e30efSTrevor Wu SND_JACK_BTN_1 | SND_JACK_BTN_2 | 561*094e30efSTrevor Wu SND_JACK_BTN_3, 562*094e30efSTrevor Wu jack, NULL, 0); 563*094e30efSTrevor Wu if (ret) { 564*094e30efSTrevor Wu dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); 565*094e30efSTrevor Wu return ret; 566*094e30efSTrevor Wu } 567*094e30efSTrevor Wu 568*094e30efSTrevor Wu snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 569*094e30efSTrevor Wu snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 570*094e30efSTrevor Wu snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 571*094e30efSTrevor Wu snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 572*094e30efSTrevor Wu 573*094e30efSTrevor Wu ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL); 574*094e30efSTrevor Wu if (ret) { 575*094e30efSTrevor Wu dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret); 576*094e30efSTrevor Wu return ret; 577*094e30efSTrevor Wu } 578*094e30efSTrevor Wu 579*094e30efSTrevor Wu return 0; 580*094e30efSTrevor Wu }; 581*094e30efSTrevor Wu 582*094e30efSTrevor Wu static int mt8195_rt1011_etdm_hw_params(struct snd_pcm_substream *substream, 583*094e30efSTrevor Wu struct snd_pcm_hw_params *params) 584*094e30efSTrevor Wu { 585*094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 586*094e30efSTrevor Wu struct snd_soc_dai *codec_dai; 587*094e30efSTrevor Wu struct snd_soc_card *card = rtd->card; 588*094e30efSTrevor Wu int srate, i, ret; 589*094e30efSTrevor Wu 590*094e30efSTrevor Wu srate = params_rate(params); 591*094e30efSTrevor Wu 592*094e30efSTrevor Wu for_each_rtd_codec_dais(rtd, i, codec_dai) { 593*094e30efSTrevor Wu ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK, 594*094e30efSTrevor Wu 64 * srate, 256 * srate); 595*094e30efSTrevor Wu if (ret < 0) { 596*094e30efSTrevor Wu dev_err(card->dev, "codec_dai clock not set\n"); 597*094e30efSTrevor Wu return ret; 598*094e30efSTrevor Wu } 599*094e30efSTrevor Wu 600*094e30efSTrevor Wu ret = snd_soc_dai_set_sysclk(codec_dai, 601*094e30efSTrevor Wu RT1011_FS_SYS_PRE_S_PLL1, 602*094e30efSTrevor Wu 256 * srate, SND_SOC_CLOCK_IN); 603*094e30efSTrevor Wu if (ret < 0) { 604*094e30efSTrevor Wu dev_err(card->dev, "codec_dai clock not set\n"); 605*094e30efSTrevor Wu return ret; 606*094e30efSTrevor Wu } 607*094e30efSTrevor Wu } 608*094e30efSTrevor Wu return 0; 609*094e30efSTrevor Wu } 610*094e30efSTrevor Wu 611*094e30efSTrevor Wu static const struct snd_soc_ops mt8195_rt1011_etdm_ops = { 612*094e30efSTrevor Wu .hw_params = mt8195_rt1011_etdm_hw_params, 613*094e30efSTrevor Wu }; 614*094e30efSTrevor Wu 615*094e30efSTrevor Wu static int mt8195_rt1011_init(struct snd_soc_pcm_runtime *rtd) 616*094e30efSTrevor Wu { 617*094e30efSTrevor Wu struct snd_soc_card *card = rtd->card; 618*094e30efSTrevor Wu int ret; 619*094e30efSTrevor Wu 620*094e30efSTrevor Wu ret = snd_soc_dapm_new_controls(&card->dapm, mt8195_dual_speaker_widgets, 621*094e30efSTrevor Wu ARRAY_SIZE(mt8195_dual_speaker_widgets)); 622*094e30efSTrevor Wu if (ret) { 623*094e30efSTrevor Wu dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); 624*094e30efSTrevor Wu /* Don't need to add routes if widget addition failed */ 625*094e30efSTrevor Wu return ret; 626*094e30efSTrevor Wu } 627*094e30efSTrevor Wu 628*094e30efSTrevor Wu ret = snd_soc_add_card_controls(card, mt8195_dual_speaker_controls, 629*094e30efSTrevor Wu ARRAY_SIZE(mt8195_dual_speaker_controls)); 630*094e30efSTrevor Wu if (ret) { 631*094e30efSTrevor Wu dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 632*094e30efSTrevor Wu return ret; 633*094e30efSTrevor Wu } 634*094e30efSTrevor Wu 635*094e30efSTrevor Wu ret = snd_soc_dapm_add_routes(&card->dapm, mt8195_rt1011_routes, 636*094e30efSTrevor Wu ARRAY_SIZE(mt8195_rt1011_routes)); 637*094e30efSTrevor Wu if (ret) 638*094e30efSTrevor Wu dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); 639*094e30efSTrevor Wu 640*094e30efSTrevor Wu return ret; 641*094e30efSTrevor Wu } 642*094e30efSTrevor Wu 643*094e30efSTrevor Wu static int mt8195_rt1019_init(struct snd_soc_pcm_runtime *rtd) 644*094e30efSTrevor Wu { 645*094e30efSTrevor Wu struct snd_soc_card *card = rtd->card; 646*094e30efSTrevor Wu int ret; 647*094e30efSTrevor Wu 648*094e30efSTrevor Wu ret = snd_soc_dapm_new_controls(&card->dapm, mt8195_speaker_widgets, 649*094e30efSTrevor Wu ARRAY_SIZE(mt8195_speaker_widgets)); 650*094e30efSTrevor Wu if (ret) { 651*094e30efSTrevor Wu dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); 652*094e30efSTrevor Wu /* Don't need to add routes if widget addition failed */ 653*094e30efSTrevor Wu return ret; 654*094e30efSTrevor Wu } 655*094e30efSTrevor Wu 656*094e30efSTrevor Wu ret = snd_soc_add_card_controls(card, mt8195_speaker_controls, 657*094e30efSTrevor Wu ARRAY_SIZE(mt8195_speaker_controls)); 658*094e30efSTrevor Wu if (ret) { 659*094e30efSTrevor Wu dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 660*094e30efSTrevor Wu return ret; 661*094e30efSTrevor Wu } 662*094e30efSTrevor Wu 663*094e30efSTrevor Wu ret = snd_soc_dapm_add_routes(&card->dapm, mt8195_rt1019_routes, 664*094e30efSTrevor Wu ARRAY_SIZE(mt8195_rt1019_routes)); 665*094e30efSTrevor Wu if (ret) 666*094e30efSTrevor Wu dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); 667*094e30efSTrevor Wu 668*094e30efSTrevor Wu return ret; 669*094e30efSTrevor Wu } 670*094e30efSTrevor Wu 671*094e30efSTrevor Wu static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 672*094e30efSTrevor Wu struct snd_pcm_hw_params *params) 673*094e30efSTrevor Wu { 674*094e30efSTrevor Wu /* fix BE i2s format to S24_LE, clean param mask first */ 675*094e30efSTrevor Wu snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 676*094e30efSTrevor Wu 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); 677*094e30efSTrevor Wu 678*094e30efSTrevor Wu params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 679*094e30efSTrevor Wu 680*094e30efSTrevor Wu return 0; 681*094e30efSTrevor Wu } 682*094e30efSTrevor Wu 683*094e30efSTrevor Wu static int mt8195_set_bias_level_post(struct snd_soc_card *card, 684*094e30efSTrevor Wu struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) 685*094e30efSTrevor Wu { 686*094e30efSTrevor Wu struct snd_soc_component *component = dapm->component; 687*094e30efSTrevor Wu struct mt8195_mt6359_priv *priv = snd_soc_card_get_drvdata(card); 688*094e30efSTrevor Wu int ret; 689*094e30efSTrevor Wu 690*094e30efSTrevor Wu /* 691*094e30efSTrevor Wu * It's required to control mclk directly in the set_bias_level_post 692*094e30efSTrevor Wu * function for rt5682 and rt5682s codec, or the unexpected pop happens 693*094e30efSTrevor Wu * at the end of playback. 694*094e30efSTrevor Wu */ 695*094e30efSTrevor Wu if (!component || 696*094e30efSTrevor Wu (strcmp(component->name, RT5682_DEV0_NAME) && 697*094e30efSTrevor Wu strcmp(component->name, RT5682S_DEV0_NAME))) 698*094e30efSTrevor Wu return 0; 699*094e30efSTrevor Wu 700*094e30efSTrevor Wu switch (level) { 701*094e30efSTrevor Wu case SND_SOC_BIAS_OFF: 702*094e30efSTrevor Wu if (!__clk_is_enabled(priv->i2so1_mclk)) 703*094e30efSTrevor Wu return 0; 704*094e30efSTrevor Wu 705*094e30efSTrevor Wu clk_disable_unprepare(priv->i2so1_mclk); 706*094e30efSTrevor Wu dev_dbg(card->dev, "Disable i2so1 mclk\n"); 707*094e30efSTrevor Wu break; 708*094e30efSTrevor Wu case SND_SOC_BIAS_ON: 709*094e30efSTrevor Wu ret = clk_prepare_enable(priv->i2so1_mclk); 710*094e30efSTrevor Wu if (ret) { 711*094e30efSTrevor Wu dev_err(card->dev, "Can't enable i2so1 mclk: %d\n", ret); 712*094e30efSTrevor Wu return ret; 713*094e30efSTrevor Wu } 714*094e30efSTrevor Wu dev_dbg(card->dev, "Enable i2so1 mclk\n"); 715*094e30efSTrevor Wu break; 716*094e30efSTrevor Wu default: 717*094e30efSTrevor Wu break; 718*094e30efSTrevor Wu } 719*094e30efSTrevor Wu 720*094e30efSTrevor Wu return 0; 721*094e30efSTrevor Wu } 722*094e30efSTrevor Wu 723*094e30efSTrevor Wu enum { 724*094e30efSTrevor Wu DAI_LINK_DL2_FE, 725*094e30efSTrevor Wu DAI_LINK_DL3_FE, 726*094e30efSTrevor Wu DAI_LINK_DL6_FE, 727*094e30efSTrevor Wu DAI_LINK_DL7_FE, 728*094e30efSTrevor Wu DAI_LINK_DL8_FE, 729*094e30efSTrevor Wu DAI_LINK_DL10_FE, 730*094e30efSTrevor Wu DAI_LINK_DL11_FE, 731*094e30efSTrevor Wu DAI_LINK_UL1_FE, 732*094e30efSTrevor Wu DAI_LINK_UL2_FE, 733*094e30efSTrevor Wu DAI_LINK_UL3_FE, 734*094e30efSTrevor Wu DAI_LINK_UL4_FE, 735*094e30efSTrevor Wu DAI_LINK_UL5_FE, 736*094e30efSTrevor Wu DAI_LINK_UL6_FE, 737*094e30efSTrevor Wu DAI_LINK_UL8_FE, 738*094e30efSTrevor Wu DAI_LINK_UL9_FE, 739*094e30efSTrevor Wu DAI_LINK_UL10_FE, 740*094e30efSTrevor Wu DAI_LINK_DL_SRC_BE, 741*094e30efSTrevor Wu DAI_LINK_DPTX_BE, 742*094e30efSTrevor Wu DAI_LINK_ETDM1_IN_BE, 743*094e30efSTrevor Wu DAI_LINK_ETDM2_IN_BE, 744*094e30efSTrevor Wu DAI_LINK_ETDM1_OUT_BE, 745*094e30efSTrevor Wu DAI_LINK_ETDM2_OUT_BE, 746*094e30efSTrevor Wu DAI_LINK_ETDM3_OUT_BE, 747*094e30efSTrevor Wu DAI_LINK_PCM1_BE, 748*094e30efSTrevor Wu DAI_LINK_UL_SRC1_BE, 749*094e30efSTrevor Wu DAI_LINK_UL_SRC2_BE, 750*094e30efSTrevor Wu DAI_LINK_REGULAR_LAST = DAI_LINK_UL_SRC2_BE, 751*094e30efSTrevor Wu DAI_LINK_SOF_START, 752*094e30efSTrevor Wu DAI_LINK_SOF_DL2_BE = DAI_LINK_SOF_START, 753*094e30efSTrevor Wu DAI_LINK_SOF_DL3_BE, 754*094e30efSTrevor Wu DAI_LINK_SOF_UL4_BE, 755*094e30efSTrevor Wu DAI_LINK_SOF_UL5_BE, 756*094e30efSTrevor Wu DAI_LINK_SOF_END = DAI_LINK_SOF_UL5_BE, 757*094e30efSTrevor Wu }; 758*094e30efSTrevor Wu 759*094e30efSTrevor Wu #define DAI_LINK_REGULAR_NUM (DAI_LINK_REGULAR_LAST + 1) 760*094e30efSTrevor Wu 761*094e30efSTrevor Wu /* FE */ 762*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL2_FE, 763*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 764*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 765*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 766*094e30efSTrevor Wu 767*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL3_FE, 768*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 769*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 770*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 771*094e30efSTrevor Wu 772*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL6_FE, 773*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL6")), 774*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 775*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 776*094e30efSTrevor Wu 777*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL7_FE, 778*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL7")), 779*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 780*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 781*094e30efSTrevor Wu 782*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL8_FE, 783*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL8")), 784*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 785*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 786*094e30efSTrevor Wu 787*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL10_FE, 788*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL10")), 789*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 790*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 791*094e30efSTrevor Wu 792*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL11_FE, 793*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL11")), 794*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 795*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 796*094e30efSTrevor Wu 797*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL1_FE, 798*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 799*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 800*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 801*094e30efSTrevor Wu 802*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL2_FE, 803*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 804*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 805*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 806*094e30efSTrevor Wu 807*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL3_FE, 808*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 809*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 810*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 811*094e30efSTrevor Wu 812*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL4_FE, 813*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL4")), 814*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 815*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 816*094e30efSTrevor Wu 817*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL5_FE, 818*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL5")), 819*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 820*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 821*094e30efSTrevor Wu 822*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL6_FE, 823*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL6")), 824*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 825*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 826*094e30efSTrevor Wu 827*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL8_FE, 828*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL8")), 829*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 830*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 831*094e30efSTrevor Wu 832*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL9_FE, 833*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL9")), 834*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 835*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 836*094e30efSTrevor Wu 837*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL10_FE, 838*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL10")), 839*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 840*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 841*094e30efSTrevor Wu 842*094e30efSTrevor Wu /* BE */ 843*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DL_SRC_BE, 844*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")), 845*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", 846*094e30efSTrevor Wu "mt6359-snd-codec-aif1")), 847*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 848*094e30efSTrevor Wu 849*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(DPTX_BE, 850*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("DPTX")), 851*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 852*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 853*094e30efSTrevor Wu 854*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(ETDM1_IN_BE, 855*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")), 856*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 857*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 858*094e30efSTrevor Wu 859*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(ETDM2_IN_BE, 860*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")), 861*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 862*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 863*094e30efSTrevor Wu 864*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE, 865*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")), 866*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 867*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 868*094e30efSTrevor Wu 869*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE, 870*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")), 871*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 872*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 873*094e30efSTrevor Wu 874*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(ETDM3_OUT_BE, 875*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")), 876*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 877*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 878*094e30efSTrevor Wu 879*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(PCM1_BE, 880*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("PCM1")), 881*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 882*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 883*094e30efSTrevor Wu 884*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL_SRC1_BE, 885*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC1")), 886*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", 887*094e30efSTrevor Wu "mt6359-snd-codec-aif1"), 888*094e30efSTrevor Wu COMP_CODEC("dmic-codec", 889*094e30efSTrevor Wu "dmic-hifi")), 890*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 891*094e30efSTrevor Wu 892*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(UL_SRC2_BE, 893*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC2")), 894*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", 895*094e30efSTrevor Wu "mt6359-snd-codec-aif2")), 896*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 897*094e30efSTrevor Wu 898*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(AFE_SOF_DL2, 899*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")), 900*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 901*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 902*094e30efSTrevor Wu 903*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(AFE_SOF_DL3, 904*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL3")), 905*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 906*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 907*094e30efSTrevor Wu 908*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(AFE_SOF_UL4, 909*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL4")), 910*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 911*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 912*094e30efSTrevor Wu 913*094e30efSTrevor Wu SND_SOC_DAILINK_DEFS(AFE_SOF_UL5, 914*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL5")), 915*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_DUMMY()), 916*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_EMPTY())); 917*094e30efSTrevor Wu 918*094e30efSTrevor Wu /* codec */ 919*094e30efSTrevor Wu SND_SOC_DAILINK_DEF(rt1019_comps, 920*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC(RT1019_DEV0_NAME, 921*094e30efSTrevor Wu RT1019_CODEC_DAI))); 922*094e30efSTrevor Wu 923*094e30efSTrevor Wu SND_SOC_DAILINK_DEF(rt1011_comps, 924*094e30efSTrevor Wu DAILINK_COMP_ARRAY(COMP_CODEC(RT1011_DEV0_NAME, 925*094e30efSTrevor Wu RT1011_CODEC_DAI), 926*094e30efSTrevor Wu COMP_CODEC(RT1011_DEV1_NAME, 927*094e30efSTrevor Wu RT1011_CODEC_DAI))); 928*094e30efSTrevor Wu 929*094e30efSTrevor Wu static const struct sof_conn_stream g_sof_conn_streams[] = { 930*094e30efSTrevor Wu { "ETDM2_OUT_BE", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK}, 931*094e30efSTrevor Wu { "ETDM1_OUT_BE", "AFE_SOF_DL3", SOF_DMA_DL3, SNDRV_PCM_STREAM_PLAYBACK}, 932*094e30efSTrevor Wu { "UL_SRC1_BE", "AFE_SOF_UL4", SOF_DMA_UL4, SNDRV_PCM_STREAM_CAPTURE}, 933*094e30efSTrevor Wu { "ETDM2_IN_BE", "AFE_SOF_UL5", SOF_DMA_UL5, SNDRV_PCM_STREAM_CAPTURE}, 934*094e30efSTrevor Wu }; 935*094e30efSTrevor Wu 936*094e30efSTrevor Wu static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { 937*094e30efSTrevor Wu /* FE */ 938*094e30efSTrevor Wu [DAI_LINK_DL2_FE] = { 939*094e30efSTrevor Wu .name = "DL2_FE", 940*094e30efSTrevor Wu .stream_name = "DL2 Playback", 941*094e30efSTrevor Wu .trigger = { 942*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 943*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 944*094e30efSTrevor Wu }, 945*094e30efSTrevor Wu .dynamic = 1, 946*094e30efSTrevor Wu .dpcm_playback = 1, 947*094e30efSTrevor Wu .ops = &mt8195_playback_ops, 948*094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL2_FE), 949*094e30efSTrevor Wu }, 950*094e30efSTrevor Wu [DAI_LINK_DL3_FE] = { 951*094e30efSTrevor Wu .name = "DL3_FE", 952*094e30efSTrevor Wu .stream_name = "DL3 Playback", 953*094e30efSTrevor Wu .trigger = { 954*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 955*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 956*094e30efSTrevor Wu }, 957*094e30efSTrevor Wu .dynamic = 1, 958*094e30efSTrevor Wu .dpcm_playback = 1, 959*094e30efSTrevor Wu .ops = &mt8195_playback_ops, 960*094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL3_FE), 961*094e30efSTrevor Wu }, 962*094e30efSTrevor Wu [DAI_LINK_DL6_FE] = { 963*094e30efSTrevor Wu .name = "DL6_FE", 964*094e30efSTrevor Wu .stream_name = "DL6 Playback", 965*094e30efSTrevor Wu .trigger = { 966*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 967*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 968*094e30efSTrevor Wu }, 969*094e30efSTrevor Wu .dynamic = 1, 970*094e30efSTrevor Wu .dpcm_playback = 1, 971*094e30efSTrevor Wu .ops = &mt8195_playback_ops, 972*094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL6_FE), 973*094e30efSTrevor Wu }, 974*094e30efSTrevor Wu [DAI_LINK_DL7_FE] = { 975*094e30efSTrevor Wu .name = "DL7_FE", 976*094e30efSTrevor Wu .stream_name = "DL7 Playback", 977*094e30efSTrevor Wu .trigger = { 978*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 979*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 980*094e30efSTrevor Wu }, 981*094e30efSTrevor Wu .dynamic = 1, 982*094e30efSTrevor Wu .dpcm_playback = 1, 983*094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL7_FE), 984*094e30efSTrevor Wu }, 985*094e30efSTrevor Wu [DAI_LINK_DL8_FE] = { 986*094e30efSTrevor Wu .name = "DL8_FE", 987*094e30efSTrevor Wu .stream_name = "DL8 Playback", 988*094e30efSTrevor Wu .trigger = { 989*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 990*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 991*094e30efSTrevor Wu }, 992*094e30efSTrevor Wu .dynamic = 1, 993*094e30efSTrevor Wu .dpcm_playback = 1, 994*094e30efSTrevor Wu .ops = &mt8195_playback_ops, 995*094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL8_FE), 996*094e30efSTrevor Wu }, 997*094e30efSTrevor Wu [DAI_LINK_DL10_FE] = { 998*094e30efSTrevor Wu .name = "DL10_FE", 999*094e30efSTrevor Wu .stream_name = "DL10 Playback", 1000*094e30efSTrevor Wu .trigger = { 1001*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1002*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1003*094e30efSTrevor Wu }, 1004*094e30efSTrevor Wu .dynamic = 1, 1005*094e30efSTrevor Wu .dpcm_playback = 1, 1006*094e30efSTrevor Wu .ops = &mt8195_hdmitx_dptx_playback_ops, 1007*094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL10_FE), 1008*094e30efSTrevor Wu }, 1009*094e30efSTrevor Wu [DAI_LINK_DL11_FE] = { 1010*094e30efSTrevor Wu .name = "DL11_FE", 1011*094e30efSTrevor Wu .stream_name = "DL11 Playback", 1012*094e30efSTrevor Wu .trigger = { 1013*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1014*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1015*094e30efSTrevor Wu }, 1016*094e30efSTrevor Wu .dynamic = 1, 1017*094e30efSTrevor Wu .dpcm_playback = 1, 1018*094e30efSTrevor Wu .ops = &mt8195_playback_ops, 1019*094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL11_FE), 1020*094e30efSTrevor Wu }, 1021*094e30efSTrevor Wu [DAI_LINK_UL1_FE] = { 1022*094e30efSTrevor Wu .name = "UL1_FE", 1023*094e30efSTrevor Wu .stream_name = "UL1 Capture", 1024*094e30efSTrevor Wu .trigger = { 1025*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 1026*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 1027*094e30efSTrevor Wu }, 1028*094e30efSTrevor Wu .dynamic = 1, 1029*094e30efSTrevor Wu .dpcm_capture = 1, 1030*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL1_FE), 1031*094e30efSTrevor Wu }, 1032*094e30efSTrevor Wu [DAI_LINK_UL2_FE] = { 1033*094e30efSTrevor Wu .name = "UL2_FE", 1034*094e30efSTrevor Wu .stream_name = "UL2 Capture", 1035*094e30efSTrevor Wu .trigger = { 1036*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1037*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1038*094e30efSTrevor Wu }, 1039*094e30efSTrevor Wu .dynamic = 1, 1040*094e30efSTrevor Wu .dpcm_capture = 1, 1041*094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1042*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL2_FE), 1043*094e30efSTrevor Wu }, 1044*094e30efSTrevor Wu [DAI_LINK_UL3_FE] = { 1045*094e30efSTrevor Wu .name = "UL3_FE", 1046*094e30efSTrevor Wu .stream_name = "UL3 Capture", 1047*094e30efSTrevor Wu .trigger = { 1048*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1049*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1050*094e30efSTrevor Wu }, 1051*094e30efSTrevor Wu .dynamic = 1, 1052*094e30efSTrevor Wu .dpcm_capture = 1, 1053*094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1054*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL3_FE), 1055*094e30efSTrevor Wu }, 1056*094e30efSTrevor Wu [DAI_LINK_UL4_FE] = { 1057*094e30efSTrevor Wu .name = "UL4_FE", 1058*094e30efSTrevor Wu .stream_name = "UL4 Capture", 1059*094e30efSTrevor Wu .trigger = { 1060*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1061*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1062*094e30efSTrevor Wu }, 1063*094e30efSTrevor Wu .dynamic = 1, 1064*094e30efSTrevor Wu .dpcm_capture = 1, 1065*094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1066*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL4_FE), 1067*094e30efSTrevor Wu }, 1068*094e30efSTrevor Wu [DAI_LINK_UL5_FE] = { 1069*094e30efSTrevor Wu .name = "UL5_FE", 1070*094e30efSTrevor Wu .stream_name = "UL5 Capture", 1071*094e30efSTrevor Wu .trigger = { 1072*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1073*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1074*094e30efSTrevor Wu }, 1075*094e30efSTrevor Wu .dynamic = 1, 1076*094e30efSTrevor Wu .dpcm_capture = 1, 1077*094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1078*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL5_FE), 1079*094e30efSTrevor Wu }, 1080*094e30efSTrevor Wu [DAI_LINK_UL6_FE] = { 1081*094e30efSTrevor Wu .name = "UL6_FE", 1082*094e30efSTrevor Wu .stream_name = "UL6 Capture", 1083*094e30efSTrevor Wu .trigger = { 1084*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 1085*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_PRE, 1086*094e30efSTrevor Wu }, 1087*094e30efSTrevor Wu .dynamic = 1, 1088*094e30efSTrevor Wu .dpcm_capture = 1, 1089*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL6_FE), 1090*094e30efSTrevor Wu }, 1091*094e30efSTrevor Wu [DAI_LINK_UL8_FE] = { 1092*094e30efSTrevor Wu .name = "UL8_FE", 1093*094e30efSTrevor Wu .stream_name = "UL8 Capture", 1094*094e30efSTrevor Wu .trigger = { 1095*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1096*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1097*094e30efSTrevor Wu }, 1098*094e30efSTrevor Wu .dynamic = 1, 1099*094e30efSTrevor Wu .dpcm_capture = 1, 1100*094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1101*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL8_FE), 1102*094e30efSTrevor Wu }, 1103*094e30efSTrevor Wu [DAI_LINK_UL9_FE] = { 1104*094e30efSTrevor Wu .name = "UL9_FE", 1105*094e30efSTrevor Wu .stream_name = "UL9 Capture", 1106*094e30efSTrevor Wu .trigger = { 1107*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1108*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1109*094e30efSTrevor Wu }, 1110*094e30efSTrevor Wu .dynamic = 1, 1111*094e30efSTrevor Wu .dpcm_capture = 1, 1112*094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1113*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL9_FE), 1114*094e30efSTrevor Wu }, 1115*094e30efSTrevor Wu [DAI_LINK_UL10_FE] = { 1116*094e30efSTrevor Wu .name = "UL10_FE", 1117*094e30efSTrevor Wu .stream_name = "UL10 Capture", 1118*094e30efSTrevor Wu .trigger = { 1119*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1120*094e30efSTrevor Wu SND_SOC_DPCM_TRIGGER_POST, 1121*094e30efSTrevor Wu }, 1122*094e30efSTrevor Wu .dynamic = 1, 1123*094e30efSTrevor Wu .dpcm_capture = 1, 1124*094e30efSTrevor Wu .ops = &mt8195_capture_ops, 1125*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL10_FE), 1126*094e30efSTrevor Wu }, 1127*094e30efSTrevor Wu /* BE */ 1128*094e30efSTrevor Wu [DAI_LINK_DL_SRC_BE] = { 1129*094e30efSTrevor Wu .name = "DL_SRC_BE", 1130*094e30efSTrevor Wu .no_pcm = 1, 1131*094e30efSTrevor Wu .dpcm_playback = 1, 1132*094e30efSTrevor Wu SND_SOC_DAILINK_REG(DL_SRC_BE), 1133*094e30efSTrevor Wu }, 1134*094e30efSTrevor Wu [DAI_LINK_DPTX_BE] = { 1135*094e30efSTrevor Wu .name = "DPTX_BE", 1136*094e30efSTrevor Wu .no_pcm = 1, 1137*094e30efSTrevor Wu .dpcm_playback = 1, 1138*094e30efSTrevor Wu .ops = &mt8195_dptx_ops, 1139*094e30efSTrevor Wu .be_hw_params_fixup = mt8195_dptx_hw_params_fixup, 1140*094e30efSTrevor Wu SND_SOC_DAILINK_REG(DPTX_BE), 1141*094e30efSTrevor Wu }, 1142*094e30efSTrevor Wu [DAI_LINK_ETDM1_IN_BE] = { 1143*094e30efSTrevor Wu .name = "ETDM1_IN_BE", 1144*094e30efSTrevor Wu .no_pcm = 1, 1145*094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1146*094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1147*094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1148*094e30efSTrevor Wu .dpcm_capture = 1, 1149*094e30efSTrevor Wu SND_SOC_DAILINK_REG(ETDM1_IN_BE), 1150*094e30efSTrevor Wu }, 1151*094e30efSTrevor Wu [DAI_LINK_ETDM2_IN_BE] = { 1152*094e30efSTrevor Wu .name = "ETDM2_IN_BE", 1153*094e30efSTrevor Wu .no_pcm = 1, 1154*094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1155*094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1156*094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1157*094e30efSTrevor Wu .dpcm_capture = 1, 1158*094e30efSTrevor Wu .init = mt8195_rt5682_init, 1159*094e30efSTrevor Wu .ops = &mt8195_rt5682_etdm_ops, 1160*094e30efSTrevor Wu .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, 1161*094e30efSTrevor Wu SND_SOC_DAILINK_REG(ETDM2_IN_BE), 1162*094e30efSTrevor Wu }, 1163*094e30efSTrevor Wu [DAI_LINK_ETDM1_OUT_BE] = { 1164*094e30efSTrevor Wu .name = "ETDM1_OUT_BE", 1165*094e30efSTrevor Wu .no_pcm = 1, 1166*094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1167*094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1168*094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1169*094e30efSTrevor Wu .dpcm_playback = 1, 1170*094e30efSTrevor Wu .ops = &mt8195_rt5682_etdm_ops, 1171*094e30efSTrevor Wu .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, 1172*094e30efSTrevor Wu SND_SOC_DAILINK_REG(ETDM1_OUT_BE), 1173*094e30efSTrevor Wu }, 1174*094e30efSTrevor Wu [DAI_LINK_ETDM2_OUT_BE] = { 1175*094e30efSTrevor Wu .name = "ETDM2_OUT_BE", 1176*094e30efSTrevor Wu .no_pcm = 1, 1177*094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1178*094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1179*094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1180*094e30efSTrevor Wu .dpcm_playback = 1, 1181*094e30efSTrevor Wu SND_SOC_DAILINK_REG(ETDM2_OUT_BE), 1182*094e30efSTrevor Wu }, 1183*094e30efSTrevor Wu [DAI_LINK_ETDM3_OUT_BE] = { 1184*094e30efSTrevor Wu .name = "ETDM3_OUT_BE", 1185*094e30efSTrevor Wu .no_pcm = 1, 1186*094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1187*094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1188*094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1189*094e30efSTrevor Wu .dpcm_playback = 1, 1190*094e30efSTrevor Wu SND_SOC_DAILINK_REG(ETDM3_OUT_BE), 1191*094e30efSTrevor Wu }, 1192*094e30efSTrevor Wu [DAI_LINK_PCM1_BE] = { 1193*094e30efSTrevor Wu .name = "PCM1_BE", 1194*094e30efSTrevor Wu .no_pcm = 1, 1195*094e30efSTrevor Wu .dai_fmt = SND_SOC_DAIFMT_I2S | 1196*094e30efSTrevor Wu SND_SOC_DAIFMT_NB_NF | 1197*094e30efSTrevor Wu SND_SOC_DAIFMT_CBS_CFS, 1198*094e30efSTrevor Wu .dpcm_playback = 1, 1199*094e30efSTrevor Wu .dpcm_capture = 1, 1200*094e30efSTrevor Wu SND_SOC_DAILINK_REG(PCM1_BE), 1201*094e30efSTrevor Wu }, 1202*094e30efSTrevor Wu [DAI_LINK_UL_SRC1_BE] = { 1203*094e30efSTrevor Wu .name = "UL_SRC1_BE", 1204*094e30efSTrevor Wu .no_pcm = 1, 1205*094e30efSTrevor Wu .dpcm_capture = 1, 1206*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL_SRC1_BE), 1207*094e30efSTrevor Wu }, 1208*094e30efSTrevor Wu [DAI_LINK_UL_SRC2_BE] = { 1209*094e30efSTrevor Wu .name = "UL_SRC2_BE", 1210*094e30efSTrevor Wu .no_pcm = 1, 1211*094e30efSTrevor Wu .dpcm_capture = 1, 1212*094e30efSTrevor Wu SND_SOC_DAILINK_REG(UL_SRC2_BE), 1213*094e30efSTrevor Wu }, 1214*094e30efSTrevor Wu /* SOF BE */ 1215*094e30efSTrevor Wu [DAI_LINK_SOF_DL2_BE] = { 1216*094e30efSTrevor Wu .name = "AFE_SOF_DL2", 1217*094e30efSTrevor Wu .no_pcm = 1, 1218*094e30efSTrevor Wu .dpcm_playback = 1, 1219*094e30efSTrevor Wu SND_SOC_DAILINK_REG(AFE_SOF_DL2), 1220*094e30efSTrevor Wu }, 1221*094e30efSTrevor Wu [DAI_LINK_SOF_DL3_BE] = { 1222*094e30efSTrevor Wu .name = "AFE_SOF_DL3", 1223*094e30efSTrevor Wu .no_pcm = 1, 1224*094e30efSTrevor Wu .dpcm_playback = 1, 1225*094e30efSTrevor Wu SND_SOC_DAILINK_REG(AFE_SOF_DL3), 1226*094e30efSTrevor Wu }, 1227*094e30efSTrevor Wu [DAI_LINK_SOF_UL4_BE] = { 1228*094e30efSTrevor Wu .name = "AFE_SOF_UL4", 1229*094e30efSTrevor Wu .no_pcm = 1, 1230*094e30efSTrevor Wu .dpcm_capture = 1, 1231*094e30efSTrevor Wu SND_SOC_DAILINK_REG(AFE_SOF_UL4), 1232*094e30efSTrevor Wu }, 1233*094e30efSTrevor Wu [DAI_LINK_SOF_UL5_BE] = { 1234*094e30efSTrevor Wu .name = "AFE_SOF_UL5", 1235*094e30efSTrevor Wu .no_pcm = 1, 1236*094e30efSTrevor Wu .dpcm_capture = 1, 1237*094e30efSTrevor Wu SND_SOC_DAILINK_REG(AFE_SOF_UL5), 1238*094e30efSTrevor Wu }, 1239*094e30efSTrevor Wu }; 1240*094e30efSTrevor Wu 1241*094e30efSTrevor Wu static struct snd_soc_codec_conf rt1011_codec_conf[] = { 1242*094e30efSTrevor Wu { 1243*094e30efSTrevor Wu .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME), 1244*094e30efSTrevor Wu .name_prefix = "Left", 1245*094e30efSTrevor Wu }, 1246*094e30efSTrevor Wu { 1247*094e30efSTrevor Wu .dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME), 1248*094e30efSTrevor Wu .name_prefix = "Right", 1249*094e30efSTrevor Wu }, 1250*094e30efSTrevor Wu }; 1251*094e30efSTrevor Wu 1252*094e30efSTrevor Wu static struct snd_soc_card mt8195_mt6359_soc_card = { 1253*094e30efSTrevor Wu .owner = THIS_MODULE, 1254*094e30efSTrevor Wu .dai_link = mt8195_mt6359_dai_links, 1255*094e30efSTrevor Wu .num_links = ARRAY_SIZE(mt8195_mt6359_dai_links), 1256*094e30efSTrevor Wu .controls = mt8195_mt6359_controls, 1257*094e30efSTrevor Wu .num_controls = ARRAY_SIZE(mt8195_mt6359_controls), 1258*094e30efSTrevor Wu .dapm_widgets = mt8195_mt6359_widgets, 1259*094e30efSTrevor Wu .num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_widgets), 1260*094e30efSTrevor Wu .dapm_routes = mt8195_mt6359_routes, 1261*094e30efSTrevor Wu .num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_routes), 1262*094e30efSTrevor Wu .set_bias_level_post = mt8195_set_bias_level_post, 1263*094e30efSTrevor Wu }; 1264*094e30efSTrevor Wu 1265*094e30efSTrevor Wu /* fixup the BE DAI link to match any values from topology */ 1266*094e30efSTrevor Wu static int mt8195_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, 1267*094e30efSTrevor Wu struct snd_pcm_hw_params *params) 1268*094e30efSTrevor Wu { 1269*094e30efSTrevor Wu struct snd_soc_card *card = rtd->card; 1270*094e30efSTrevor Wu struct snd_soc_dai_link *sof_dai_link = NULL; 1271*094e30efSTrevor Wu struct snd_soc_pcm_runtime *runtime; 1272*094e30efSTrevor Wu struct snd_soc_dai *cpu_dai; 1273*094e30efSTrevor Wu int i, j, ret = 0; 1274*094e30efSTrevor Wu 1275*094e30efSTrevor Wu for (i = 0; i < ARRAY_SIZE(g_sof_conn_streams); i++) { 1276*094e30efSTrevor Wu const struct sof_conn_stream *conn = &g_sof_conn_streams[i]; 1277*094e30efSTrevor Wu 1278*094e30efSTrevor Wu if (strcmp(rtd->dai_link->name, conn->normal_link)) 1279*094e30efSTrevor Wu continue; 1280*094e30efSTrevor Wu 1281*094e30efSTrevor Wu for_each_card_rtds(card, runtime) { 1282*094e30efSTrevor Wu if (strcmp(runtime->dai_link->name, conn->sof_link)) 1283*094e30efSTrevor Wu continue; 1284*094e30efSTrevor Wu 1285*094e30efSTrevor Wu for_each_rtd_cpu_dais(runtime, j, cpu_dai) { 1286*094e30efSTrevor Wu if (cpu_dai->stream_active[conn->stream_dir] > 0) { 1287*094e30efSTrevor Wu sof_dai_link = runtime->dai_link; 1288*094e30efSTrevor Wu break; 1289*094e30efSTrevor Wu } 1290*094e30efSTrevor Wu } 1291*094e30efSTrevor Wu break; 1292*094e30efSTrevor Wu } 1293*094e30efSTrevor Wu 1294*094e30efSTrevor Wu if (sof_dai_link && sof_dai_link->be_hw_params_fixup) 1295*094e30efSTrevor Wu ret = sof_dai_link->be_hw_params_fixup(runtime, params); 1296*094e30efSTrevor Wu 1297*094e30efSTrevor Wu break; 1298*094e30efSTrevor Wu } 1299*094e30efSTrevor Wu 1300*094e30efSTrevor Wu if (!strcmp(rtd->dai_link->name, "ETDM2_IN_BE") || 1301*094e30efSTrevor Wu !strcmp(rtd->dai_link->name, "ETDM1_OUT_BE")) { 1302*094e30efSTrevor Wu mt8195_etdm_hw_params_fixup(runtime, params); 1303*094e30efSTrevor Wu } 1304*094e30efSTrevor Wu 1305*094e30efSTrevor Wu return ret; 1306*094e30efSTrevor Wu } 1307*094e30efSTrevor Wu 1308*094e30efSTrevor Wu static int mt8195_mt6359_card_late_probe(struct snd_soc_card *card) 1309*094e30efSTrevor Wu { 1310*094e30efSTrevor Wu struct snd_soc_pcm_runtime *runtime; 1311*094e30efSTrevor Wu struct snd_soc_component *sof_comp = NULL; 1312*094e30efSTrevor Wu int i; 1313*094e30efSTrevor Wu 1314*094e30efSTrevor Wu /* 1. find sof component */ 1315*094e30efSTrevor Wu for_each_card_rtds(card, runtime) { 1316*094e30efSTrevor Wu for (i = 0; i < runtime->num_components; i++) { 1317*094e30efSTrevor Wu if (!runtime->components[i]->driver->name) 1318*094e30efSTrevor Wu continue; 1319*094e30efSTrevor Wu if (!strcmp(runtime->components[i]->driver->name, "sof-audio-component")) { 1320*094e30efSTrevor Wu sof_comp = runtime->components[i]; 1321*094e30efSTrevor Wu break; 1322*094e30efSTrevor Wu } 1323*094e30efSTrevor Wu } 1324*094e30efSTrevor Wu } 1325*094e30efSTrevor Wu 1326*094e30efSTrevor Wu if (!sof_comp) { 1327*094e30efSTrevor Wu dev_info(card->dev, " probe without component\n"); 1328*094e30efSTrevor Wu return 0; 1329*094e30efSTrevor Wu } 1330*094e30efSTrevor Wu /* 2. add route path and fixup callback */ 1331*094e30efSTrevor Wu for (i = 0; i < ARRAY_SIZE(g_sof_conn_streams); i++) { 1332*094e30efSTrevor Wu const struct sof_conn_stream *conn = &g_sof_conn_streams[i]; 1333*094e30efSTrevor Wu struct snd_soc_pcm_runtime *sof_rtd = NULL; 1334*094e30efSTrevor Wu struct snd_soc_pcm_runtime *normal_rtd = NULL; 1335*094e30efSTrevor Wu struct snd_soc_pcm_runtime *rtd = NULL; 1336*094e30efSTrevor Wu 1337*094e30efSTrevor Wu for_each_card_rtds(card, rtd) { 1338*094e30efSTrevor Wu if (!strcmp(rtd->dai_link->name, conn->sof_link)) { 1339*094e30efSTrevor Wu sof_rtd = rtd; 1340*094e30efSTrevor Wu continue; 1341*094e30efSTrevor Wu } 1342*094e30efSTrevor Wu if (!strcmp(rtd->dai_link->name, conn->normal_link)) { 1343*094e30efSTrevor Wu normal_rtd = rtd; 1344*094e30efSTrevor Wu continue; 1345*094e30efSTrevor Wu } 1346*094e30efSTrevor Wu if (normal_rtd && sof_rtd) 1347*094e30efSTrevor Wu break; 1348*094e30efSTrevor Wu } 1349*094e30efSTrevor Wu if (normal_rtd && sof_rtd) { 1350*094e30efSTrevor Wu int j; 1351*094e30efSTrevor Wu struct snd_soc_dai *cpu_dai; 1352*094e30efSTrevor Wu 1353*094e30efSTrevor Wu for_each_rtd_cpu_dais(sof_rtd, j, cpu_dai) { 1354*094e30efSTrevor Wu struct snd_soc_dapm_route route; 1355*094e30efSTrevor Wu struct snd_soc_dapm_path *p = NULL; 1356*094e30efSTrevor Wu struct snd_soc_dapm_widget *play_widget = 1357*094e30efSTrevor Wu cpu_dai->playback_widget; 1358*094e30efSTrevor Wu struct snd_soc_dapm_widget *cap_widget = 1359*094e30efSTrevor Wu cpu_dai->capture_widget; 1360*094e30efSTrevor Wu memset(&route, 0, sizeof(route)); 1361*094e30efSTrevor Wu if (conn->stream_dir == SNDRV_PCM_STREAM_CAPTURE && 1362*094e30efSTrevor Wu cap_widget) { 1363*094e30efSTrevor Wu snd_soc_dapm_widget_for_each_sink_path(cap_widget, p) { 1364*094e30efSTrevor Wu route.source = conn->sof_dma; 1365*094e30efSTrevor Wu route.sink = p->sink->name; 1366*094e30efSTrevor Wu snd_soc_dapm_add_routes(&card->dapm, &route, 1); 1367*094e30efSTrevor Wu } 1368*094e30efSTrevor Wu } else if (conn->stream_dir == SNDRV_PCM_STREAM_PLAYBACK && 1369*094e30efSTrevor Wu play_widget){ 1370*094e30efSTrevor Wu snd_soc_dapm_widget_for_each_source_path(play_widget, p) { 1371*094e30efSTrevor Wu route.source = p->source->name; 1372*094e30efSTrevor Wu route.sink = conn->sof_dma; 1373*094e30efSTrevor Wu snd_soc_dapm_add_routes(&card->dapm, &route, 1); 1374*094e30efSTrevor Wu } 1375*094e30efSTrevor Wu } else { 1376*094e30efSTrevor Wu dev_err(cpu_dai->dev, "stream dir and widget not pair\n"); 1377*094e30efSTrevor Wu } 1378*094e30efSTrevor Wu } 1379*094e30efSTrevor Wu normal_rtd->dai_link->be_hw_params_fixup = mt8195_dai_link_fixup; 1380*094e30efSTrevor Wu } 1381*094e30efSTrevor Wu } 1382*094e30efSTrevor Wu 1383*094e30efSTrevor Wu return 0; 1384*094e30efSTrevor Wu } 1385*094e30efSTrevor Wu 1386*094e30efSTrevor Wu static int mt8195_dailink_parse_of(struct snd_soc_card *card, struct device_node *np, 1387*094e30efSTrevor Wu const char *propname) 1388*094e30efSTrevor Wu { 1389*094e30efSTrevor Wu struct device *dev = card->dev; 1390*094e30efSTrevor Wu struct snd_soc_dai_link *link; 1391*094e30efSTrevor Wu const char *dai_name = NULL; 1392*094e30efSTrevor Wu int i, j, ret, num_links; 1393*094e30efSTrevor Wu 1394*094e30efSTrevor Wu num_links = of_property_count_strings(np, "mediatek,dai-link"); 1395*094e30efSTrevor Wu 1396*094e30efSTrevor Wu if (num_links < 0 || num_links > ARRAY_SIZE(mt8195_mt6359_dai_links)) { 1397*094e30efSTrevor Wu dev_dbg(dev, "number of dai-link is invalid\n"); 1398*094e30efSTrevor Wu return -EINVAL; 1399*094e30efSTrevor Wu } 1400*094e30efSTrevor Wu 1401*094e30efSTrevor Wu card->dai_link = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL); 1402*094e30efSTrevor Wu if (!card->dai_link) 1403*094e30efSTrevor Wu return -ENOMEM; 1404*094e30efSTrevor Wu 1405*094e30efSTrevor Wu card->num_links = 0; 1406*094e30efSTrevor Wu link = card->dai_link; 1407*094e30efSTrevor Wu 1408*094e30efSTrevor Wu for (i = 0; i < num_links; i++) { 1409*094e30efSTrevor Wu ret = of_property_read_string_index(np, propname, i, &dai_name); 1410*094e30efSTrevor Wu if (ret) { 1411*094e30efSTrevor Wu dev_dbg(dev, "ASoC: Property '%s' index %d could not be read: %d\n", 1412*094e30efSTrevor Wu propname, i, ret); 1413*094e30efSTrevor Wu return -EINVAL; 1414*094e30efSTrevor Wu } 1415*094e30efSTrevor Wu 1416*094e30efSTrevor Wu for (j = 0; j < ARRAY_SIZE(mt8195_mt6359_dai_links); j++) { 1417*094e30efSTrevor Wu if (!strcmp(dai_name, mt8195_mt6359_dai_links[j].name)) { 1418*094e30efSTrevor Wu memcpy(link, &mt8195_mt6359_dai_links[j], 1419*094e30efSTrevor Wu sizeof(struct snd_soc_dai_link)); 1420*094e30efSTrevor Wu link++; 1421*094e30efSTrevor Wu card->num_links++; 1422*094e30efSTrevor Wu break; 1423*094e30efSTrevor Wu } 1424*094e30efSTrevor Wu } 1425*094e30efSTrevor Wu } 1426*094e30efSTrevor Wu 1427*094e30efSTrevor Wu if (card->num_links != num_links) 1428*094e30efSTrevor Wu return -EINVAL; 1429*094e30efSTrevor Wu 1430*094e30efSTrevor Wu return 0; 1431*094e30efSTrevor Wu } 1432*094e30efSTrevor Wu 1433*094e30efSTrevor Wu static int mt8195_mt6359_dev_probe(struct platform_device *pdev) 1434*094e30efSTrevor Wu { 1435*094e30efSTrevor Wu struct snd_soc_card *card = &mt8195_mt6359_soc_card; 1436*094e30efSTrevor Wu struct snd_soc_dai_link *dai_link; 1437*094e30efSTrevor Wu struct mt8195_mt6359_priv *priv; 1438*094e30efSTrevor Wu struct device_node *platform_node, *adsp_node, *dp_node, *hdmi_node; 1439*094e30efSTrevor Wu struct mt8195_card_data *card_data; 1440*094e30efSTrevor Wu int is5682s = 0; 1441*094e30efSTrevor Wu int init6359 = 0; 1442*094e30efSTrevor Wu int sof_on = 0; 1443*094e30efSTrevor Wu int ret, i; 1444*094e30efSTrevor Wu 1445*094e30efSTrevor Wu card_data = (struct mt8195_card_data *)of_device_get_match_data(&pdev->dev); 1446*094e30efSTrevor Wu card->dev = &pdev->dev; 1447*094e30efSTrevor Wu 1448*094e30efSTrevor Wu ret = snd_soc_of_parse_card_name(card, "model"); 1449*094e30efSTrevor Wu if (ret) { 1450*094e30efSTrevor Wu dev_err(&pdev->dev, "%s new card name parsing error %d\n", 1451*094e30efSTrevor Wu __func__, ret); 1452*094e30efSTrevor Wu return ret; 1453*094e30efSTrevor Wu } 1454*094e30efSTrevor Wu 1455*094e30efSTrevor Wu if (!card->name) 1456*094e30efSTrevor Wu card->name = card_data->name; 1457*094e30efSTrevor Wu 1458*094e30efSTrevor Wu if (strstr(card->name, "_5682s")) 1459*094e30efSTrevor Wu is5682s = 1; 1460*094e30efSTrevor Wu 1461*094e30efSTrevor Wu priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 1462*094e30efSTrevor Wu if (!priv) 1463*094e30efSTrevor Wu return -ENOMEM; 1464*094e30efSTrevor Wu 1465*094e30efSTrevor Wu if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) { 1466*094e30efSTrevor Wu ret = mt8195_dailink_parse_of(card, pdev->dev.of_node, 1467*094e30efSTrevor Wu "mediatek,dai-link"); 1468*094e30efSTrevor Wu if (ret) { 1469*094e30efSTrevor Wu dev_dbg(&pdev->dev, "Parse dai-link fail\n"); 1470*094e30efSTrevor Wu return -EINVAL; 1471*094e30efSTrevor Wu } 1472*094e30efSTrevor Wu } else { 1473*094e30efSTrevor Wu if (!sof_on) 1474*094e30efSTrevor Wu card->num_links = DAI_LINK_REGULAR_NUM; 1475*094e30efSTrevor Wu } 1476*094e30efSTrevor Wu 1477*094e30efSTrevor Wu platform_node = of_parse_phandle(pdev->dev.of_node, 1478*094e30efSTrevor Wu "mediatek,platform", 0); 1479*094e30efSTrevor Wu if (!platform_node) { 1480*094e30efSTrevor Wu dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n"); 1481*094e30efSTrevor Wu return -EINVAL; 1482*094e30efSTrevor Wu } 1483*094e30efSTrevor Wu 1484*094e30efSTrevor Wu adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0); 1485*094e30efSTrevor Wu if (adsp_node) 1486*094e30efSTrevor Wu sof_on = 1; 1487*094e30efSTrevor Wu 1488*094e30efSTrevor Wu dp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,dptx-codec", 0); 1489*094e30efSTrevor Wu hdmi_node = of_parse_phandle(pdev->dev.of_node, 1490*094e30efSTrevor Wu "mediatek,hdmi-codec", 0); 1491*094e30efSTrevor Wu 1492*094e30efSTrevor Wu for_each_card_prelinks(card, i, dai_link) { 1493*094e30efSTrevor Wu if (!dai_link->platforms->name) { 1494*094e30efSTrevor Wu if (!strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")) && sof_on) 1495*094e30efSTrevor Wu dai_link->platforms->of_node = adsp_node; 1496*094e30efSTrevor Wu else 1497*094e30efSTrevor Wu dai_link->platforms->of_node = platform_node; 1498*094e30efSTrevor Wu } 1499*094e30efSTrevor Wu 1500*094e30efSTrevor Wu if (strcmp(dai_link->name, "DPTX_BE") == 0) { 1501*094e30efSTrevor Wu if (!dp_node) { 1502*094e30efSTrevor Wu dev_dbg(&pdev->dev, "No property 'dptx-codec'\n"); 1503*094e30efSTrevor Wu } else { 1504*094e30efSTrevor Wu dai_link->codecs->of_node = dp_node; 1505*094e30efSTrevor Wu dai_link->codecs->name = NULL; 1506*094e30efSTrevor Wu dai_link->codecs->dai_name = "i2s-hifi"; 1507*094e30efSTrevor Wu dai_link->init = mt8195_dptx_codec_init; 1508*094e30efSTrevor Wu } 1509*094e30efSTrevor Wu } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { 1510*094e30efSTrevor Wu if (!hdmi_node) { 1511*094e30efSTrevor Wu dev_dbg(&pdev->dev, "No property 'hdmi-codec'\n"); 1512*094e30efSTrevor Wu } else { 1513*094e30efSTrevor Wu dai_link->codecs->of_node = hdmi_node; 1514*094e30efSTrevor Wu dai_link->codecs->name = NULL; 1515*094e30efSTrevor Wu dai_link->codecs->dai_name = "i2s-hifi"; 1516*094e30efSTrevor Wu dai_link->init = mt8195_hdmi_codec_init; 1517*094e30efSTrevor Wu } 1518*094e30efSTrevor Wu } else if (strcmp(dai_link->name, "ETDM1_OUT_BE") == 0 || 1519*094e30efSTrevor Wu strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { 1520*094e30efSTrevor Wu dai_link->codecs->name = 1521*094e30efSTrevor Wu is5682s ? RT5682S_DEV0_NAME : RT5682_DEV0_NAME; 1522*094e30efSTrevor Wu dai_link->codecs->dai_name = 1523*094e30efSTrevor Wu is5682s ? RT5682S_CODEC_DAI : RT5682_CODEC_DAI; 1524*094e30efSTrevor Wu } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || 1525*094e30efSTrevor Wu strcmp(dai_link->name, "UL_SRC1_BE") == 0 || 1526*094e30efSTrevor Wu strcmp(dai_link->name, "UL_SRC2_BE") == 0) { 1527*094e30efSTrevor Wu if (!init6359) { 1528*094e30efSTrevor Wu dai_link->init = mt8195_mt6359_init; 1529*094e30efSTrevor Wu init6359 = 1; 1530*094e30efSTrevor Wu } 1531*094e30efSTrevor Wu } else if (strcmp(dai_link->name, "ETDM2_OUT_BE") == 0) { 1532*094e30efSTrevor Wu switch (card_data->quirk) { 1533*094e30efSTrevor Wu case RT1011_SPEAKER_AMP_PRESENT: 1534*094e30efSTrevor Wu dai_link->codecs = rt1011_comps; 1535*094e30efSTrevor Wu dai_link->num_codecs = ARRAY_SIZE(rt1011_comps); 1536*094e30efSTrevor Wu dai_link->init = mt8195_rt1011_init; 1537*094e30efSTrevor Wu dai_link->ops = &mt8195_rt1011_etdm_ops; 1538*094e30efSTrevor Wu dai_link->be_hw_params_fixup = mt8195_etdm_hw_params_fixup; 1539*094e30efSTrevor Wu card->codec_conf = rt1011_codec_conf; 1540*094e30efSTrevor Wu card->num_configs = ARRAY_SIZE(rt1011_codec_conf); 1541*094e30efSTrevor Wu break; 1542*094e30efSTrevor Wu case RT1019_SPEAKER_AMP_PRESENT: 1543*094e30efSTrevor Wu dai_link->codecs = rt1019_comps; 1544*094e30efSTrevor Wu dai_link->num_codecs = ARRAY_SIZE(rt1019_comps); 1545*094e30efSTrevor Wu dai_link->init = mt8195_rt1019_init; 1546*094e30efSTrevor Wu break; 1547*094e30efSTrevor Wu default: 1548*094e30efSTrevor Wu break; 1549*094e30efSTrevor Wu } 1550*094e30efSTrevor Wu } 1551*094e30efSTrevor Wu } 1552*094e30efSTrevor Wu 1553*094e30efSTrevor Wu if (sof_on) 1554*094e30efSTrevor Wu card->late_probe = mt8195_mt6359_card_late_probe; 1555*094e30efSTrevor Wu 1556*094e30efSTrevor Wu snd_soc_card_set_drvdata(card, priv); 1557*094e30efSTrevor Wu 1558*094e30efSTrevor Wu ret = devm_snd_soc_register_card(&pdev->dev, card); 1559*094e30efSTrevor Wu 1560*094e30efSTrevor Wu of_node_put(platform_node); 1561*094e30efSTrevor Wu of_node_put(adsp_node); 1562*094e30efSTrevor Wu of_node_put(dp_node); 1563*094e30efSTrevor Wu of_node_put(hdmi_node); 1564*094e30efSTrevor Wu return ret; 1565*094e30efSTrevor Wu } 1566*094e30efSTrevor Wu 1567*094e30efSTrevor Wu static struct mt8195_card_data mt8195_mt6359_rt1019_rt5682_card = { 1568*094e30efSTrevor Wu .name = "mt8195_r1019_5682", 1569*094e30efSTrevor Wu .quirk = RT1019_SPEAKER_AMP_PRESENT, 1570*094e30efSTrevor Wu }; 1571*094e30efSTrevor Wu 1572*094e30efSTrevor Wu static struct mt8195_card_data mt8195_mt6359_rt1011_rt5682_card = { 1573*094e30efSTrevor Wu .name = "mt8195_r1011_5682", 1574*094e30efSTrevor Wu .quirk = RT1011_SPEAKER_AMP_PRESENT, 1575*094e30efSTrevor Wu }; 1576*094e30efSTrevor Wu 1577*094e30efSTrevor Wu #ifdef CONFIG_OF 1578*094e30efSTrevor Wu static const struct of_device_id mt8195_mt6359_dt_match[] = { 1579*094e30efSTrevor Wu { 1580*094e30efSTrevor Wu .compatible = "mediatek,mt8195_mt6359_rt1019_rt5682", 1581*094e30efSTrevor Wu .data = &mt8195_mt6359_rt1019_rt5682_card, 1582*094e30efSTrevor Wu }, 1583*094e30efSTrevor Wu { 1584*094e30efSTrevor Wu .compatible = "mediatek,mt8195_mt6359_rt1011_rt5682", 1585*094e30efSTrevor Wu .data = &mt8195_mt6359_rt1011_rt5682_card, 1586*094e30efSTrevor Wu }, 1587*094e30efSTrevor Wu }; 1588*094e30efSTrevor Wu #endif 1589*094e30efSTrevor Wu 1590*094e30efSTrevor Wu static const struct dev_pm_ops mt8195_mt6359_pm_ops = { 1591*094e30efSTrevor Wu .poweroff = snd_soc_poweroff, 1592*094e30efSTrevor Wu .restore = snd_soc_resume, 1593*094e30efSTrevor Wu }; 1594*094e30efSTrevor Wu 1595*094e30efSTrevor Wu static struct platform_driver mt8195_mt6359_driver = { 1596*094e30efSTrevor Wu .driver = { 1597*094e30efSTrevor Wu .name = "mt8195_mt6359", 1598*094e30efSTrevor Wu #ifdef CONFIG_OF 1599*094e30efSTrevor Wu .of_match_table = mt8195_mt6359_dt_match, 1600*094e30efSTrevor Wu #endif 1601*094e30efSTrevor Wu .pm = &mt8195_mt6359_pm_ops, 1602*094e30efSTrevor Wu }, 1603*094e30efSTrevor Wu .probe = mt8195_mt6359_dev_probe, 1604*094e30efSTrevor Wu }; 1605*094e30efSTrevor Wu 1606*094e30efSTrevor Wu module_platform_driver(mt8195_mt6359_driver); 1607*094e30efSTrevor Wu 1608*094e30efSTrevor Wu /* Module information */ 1609*094e30efSTrevor Wu MODULE_DESCRIPTION("MT8195-MT6359 ALSA SoC machine driver"); 1610*094e30efSTrevor Wu MODULE_AUTHOR("Trevor Wu <trevor.wu@mediatek.com>"); 1611*094e30efSTrevor Wu MODULE_AUTHOR("YC Hung <yc.hung@mediatek.com>"); 1612*094e30efSTrevor Wu MODULE_LICENSE("GPL"); 1613*094e30efSTrevor Wu MODULE_ALIAS("mt8195_mt6359 soc card"); 1614