12babb477STrevor Wu // SPDX-License-Identifier: GPL-2.0 22babb477STrevor Wu /* 32babb477STrevor Wu * MediaTek ALSA SoC Audio DAI eTDM Control 42babb477STrevor Wu * 52babb477STrevor Wu * Copyright (c) 2022 MediaTek Inc. 62babb477STrevor Wu * Author: Bicycle Tsai <bicycle.tsai@mediatek.com> 72babb477STrevor Wu * Trevor Wu <trevor.wu@mediatek.com> 82babb477STrevor Wu * Chun-Chia Chiu <chun-chia.chiu@mediatek.com> 92babb477STrevor Wu */ 102babb477STrevor Wu 112babb477STrevor Wu #include <linux/bitfield.h> 122babb477STrevor Wu #include <linux/pm_runtime.h> 132babb477STrevor Wu #include <linux/regmap.h> 142babb477STrevor Wu #include <sound/pcm_params.h> 152babb477STrevor Wu #include "mt8188-afe-clk.h" 162babb477STrevor Wu #include "mt8188-afe-common.h" 172babb477STrevor Wu #include "mt8188-reg.h" 182babb477STrevor Wu 192babb477STrevor Wu #define MT8188_ETDM_MAX_CHANNELS 16 202babb477STrevor Wu #define MT8188_ETDM_NORMAL_MAX_BCK_RATE 24576000 212babb477STrevor Wu #define ETDM_TO_DAI_ID(x) ((x) + MT8188_AFE_IO_ETDM_START) 222babb477STrevor Wu #define ENUM_TO_STR(x) #x 232babb477STrevor Wu 242babb477STrevor Wu enum { 252babb477STrevor Wu MTK_DAI_ETDM_FORMAT_I2S = 0, 262babb477STrevor Wu MTK_DAI_ETDM_FORMAT_LJ, 272babb477STrevor Wu MTK_DAI_ETDM_FORMAT_RJ, 282babb477STrevor Wu MTK_DAI_ETDM_FORMAT_EIAJ, 292babb477STrevor Wu MTK_DAI_ETDM_FORMAT_DSPA, 302babb477STrevor Wu MTK_DAI_ETDM_FORMAT_DSPB, 312babb477STrevor Wu }; 322babb477STrevor Wu 332babb477STrevor Wu enum { 342babb477STrevor Wu MTK_DAI_ETDM_DATA_ONE_PIN = 0, 352babb477STrevor Wu MTK_DAI_ETDM_DATA_MULTI_PIN, 362babb477STrevor Wu }; 372babb477STrevor Wu 382babb477STrevor Wu enum { 392babb477STrevor Wu ETDM_IN, 402babb477STrevor Wu ETDM_OUT, 412babb477STrevor Wu }; 422babb477STrevor Wu 432babb477STrevor Wu enum { 442babb477STrevor Wu COWORK_ETDM_NONE = 0, 452babb477STrevor Wu COWORK_ETDM_IN1_M = 2, 462babb477STrevor Wu COWORK_ETDM_IN1_S = 3, 472babb477STrevor Wu COWORK_ETDM_IN2_M = 4, 482babb477STrevor Wu COWORK_ETDM_IN2_S = 5, 492babb477STrevor Wu COWORK_ETDM_OUT1_M = 10, 502babb477STrevor Wu COWORK_ETDM_OUT1_S = 11, 512babb477STrevor Wu COWORK_ETDM_OUT2_M = 12, 522babb477STrevor Wu COWORK_ETDM_OUT2_S = 13, 532babb477STrevor Wu COWORK_ETDM_OUT3_M = 14, 542babb477STrevor Wu COWORK_ETDM_OUT3_S = 15, 552babb477STrevor Wu }; 562babb477STrevor Wu 572babb477STrevor Wu enum { 582babb477STrevor Wu ETDM_RELATCH_TIMING_A1A2SYS, 592babb477STrevor Wu ETDM_RELATCH_TIMING_A3SYS, 602babb477STrevor Wu ETDM_RELATCH_TIMING_A4SYS, 612babb477STrevor Wu }; 622babb477STrevor Wu 632babb477STrevor Wu enum { 642babb477STrevor Wu ETDM_SYNC_NONE, 652babb477STrevor Wu ETDM_SYNC_FROM_IN1 = 2, 662babb477STrevor Wu ETDM_SYNC_FROM_IN2 = 4, 672babb477STrevor Wu ETDM_SYNC_FROM_OUT1 = 10, 682babb477STrevor Wu ETDM_SYNC_FROM_OUT2 = 12, 692babb477STrevor Wu ETDM_SYNC_FROM_OUT3 = 14, 702babb477STrevor Wu }; 712babb477STrevor Wu 722babb477STrevor Wu struct etdm_con_reg { 732babb477STrevor Wu unsigned int con0; 742babb477STrevor Wu unsigned int con1; 752babb477STrevor Wu unsigned int con2; 762babb477STrevor Wu unsigned int con3; 772babb477STrevor Wu unsigned int con4; 782babb477STrevor Wu unsigned int con5; 792babb477STrevor Wu }; 802babb477STrevor Wu 812babb477STrevor Wu struct mtk_dai_etdm_rate { 822babb477STrevor Wu unsigned int rate; 832babb477STrevor Wu unsigned int reg_value; 842babb477STrevor Wu }; 852babb477STrevor Wu 862babb477STrevor Wu struct mtk_dai_etdm_priv { 872babb477STrevor Wu unsigned int clock_mode; 882babb477STrevor Wu unsigned int data_mode; 892babb477STrevor Wu bool slave_mode; 902babb477STrevor Wu bool lrck_inv; 912babb477STrevor Wu bool bck_inv; 922babb477STrevor Wu unsigned int format; 932babb477STrevor Wu unsigned int slots; 942babb477STrevor Wu unsigned int lrck_width; 952babb477STrevor Wu unsigned int mclk_freq; 962babb477STrevor Wu unsigned int mclk_fixed_apll; 972babb477STrevor Wu unsigned int mclk_apll; 982babb477STrevor Wu unsigned int mclk_dir; 992babb477STrevor Wu int cowork_source_id; //dai id 1002babb477STrevor Wu unsigned int cowork_slv_count; 1012babb477STrevor Wu int cowork_slv_id[MT8188_AFE_IO_ETDM_NUM - 1]; //dai_id 1022babb477STrevor Wu bool in_disable_ch[MT8188_ETDM_MAX_CHANNELS]; 1032babb477STrevor Wu unsigned int en_ref_cnt; 1042babb477STrevor Wu bool is_prepared; 1052babb477STrevor Wu }; 1062babb477STrevor Wu 1072babb477STrevor Wu static const struct mtk_dai_etdm_rate mt8188_etdm_rates[] = { 1082babb477STrevor Wu { .rate = 8000, .reg_value = 0, }, 1092babb477STrevor Wu { .rate = 12000, .reg_value = 1, }, 1102babb477STrevor Wu { .rate = 16000, .reg_value = 2, }, 1112babb477STrevor Wu { .rate = 24000, .reg_value = 3, }, 1122babb477STrevor Wu { .rate = 32000, .reg_value = 4, }, 1132babb477STrevor Wu { .rate = 48000, .reg_value = 5, }, 1142babb477STrevor Wu { .rate = 96000, .reg_value = 7, }, 1152babb477STrevor Wu { .rate = 192000, .reg_value = 9, }, 1162babb477STrevor Wu { .rate = 384000, .reg_value = 11, }, 1172babb477STrevor Wu { .rate = 11025, .reg_value = 16, }, 1182babb477STrevor Wu { .rate = 22050, .reg_value = 17, }, 1192babb477STrevor Wu { .rate = 44100, .reg_value = 18, }, 1202babb477STrevor Wu { .rate = 88200, .reg_value = 19, }, 1212babb477STrevor Wu { .rate = 176400, .reg_value = 20, }, 1222babb477STrevor Wu { .rate = 352800, .reg_value = 21, }, 1232babb477STrevor Wu }; 1242babb477STrevor Wu 1252babb477STrevor Wu static int get_etdm_fs_timing(unsigned int rate) 1262babb477STrevor Wu { 1272babb477STrevor Wu int i; 1282babb477STrevor Wu 1292babb477STrevor Wu for (i = 0; i < ARRAY_SIZE(mt8188_etdm_rates); i++) 1302babb477STrevor Wu if (mt8188_etdm_rates[i].rate == rate) 1312babb477STrevor Wu return mt8188_etdm_rates[i].reg_value; 1322babb477STrevor Wu 1332babb477STrevor Wu return -EINVAL; 1342babb477STrevor Wu } 1352babb477STrevor Wu 1362babb477STrevor Wu static unsigned int get_etdm_ch_fixup(unsigned int channels) 1372babb477STrevor Wu { 1382babb477STrevor Wu if (channels > 16) 1392babb477STrevor Wu return 24; 1402babb477STrevor Wu else if (channels > 8) 1412babb477STrevor Wu return 16; 1422babb477STrevor Wu else if (channels > 4) 1432babb477STrevor Wu return 8; 1442babb477STrevor Wu else if (channels > 2) 1452babb477STrevor Wu return 4; 1462babb477STrevor Wu else 1472babb477STrevor Wu return 2; 1482babb477STrevor Wu } 1492babb477STrevor Wu 1502babb477STrevor Wu static int get_etdm_reg(unsigned int dai_id, struct etdm_con_reg *etdm_reg) 1512babb477STrevor Wu { 1522babb477STrevor Wu switch (dai_id) { 1532babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 1542babb477STrevor Wu etdm_reg->con0 = ETDM_IN1_CON0; 1552babb477STrevor Wu etdm_reg->con1 = ETDM_IN1_CON1; 1562babb477STrevor Wu etdm_reg->con2 = ETDM_IN1_CON2; 1572babb477STrevor Wu etdm_reg->con3 = ETDM_IN1_CON3; 1582babb477STrevor Wu etdm_reg->con4 = ETDM_IN1_CON4; 1592babb477STrevor Wu etdm_reg->con5 = ETDM_IN1_CON5; 1602babb477STrevor Wu break; 1612babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 1622babb477STrevor Wu etdm_reg->con0 = ETDM_IN2_CON0; 1632babb477STrevor Wu etdm_reg->con1 = ETDM_IN2_CON1; 1642babb477STrevor Wu etdm_reg->con2 = ETDM_IN2_CON2; 1652babb477STrevor Wu etdm_reg->con3 = ETDM_IN2_CON3; 1662babb477STrevor Wu etdm_reg->con4 = ETDM_IN2_CON4; 1672babb477STrevor Wu etdm_reg->con5 = ETDM_IN2_CON5; 1682babb477STrevor Wu break; 1692babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 1702babb477STrevor Wu etdm_reg->con0 = ETDM_OUT1_CON0; 1712babb477STrevor Wu etdm_reg->con1 = ETDM_OUT1_CON1; 1722babb477STrevor Wu etdm_reg->con2 = ETDM_OUT1_CON2; 1732babb477STrevor Wu etdm_reg->con3 = ETDM_OUT1_CON3; 1742babb477STrevor Wu etdm_reg->con4 = ETDM_OUT1_CON4; 1752babb477STrevor Wu etdm_reg->con5 = ETDM_OUT1_CON5; 1762babb477STrevor Wu break; 1772babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 1782babb477STrevor Wu etdm_reg->con0 = ETDM_OUT2_CON0; 1792babb477STrevor Wu etdm_reg->con1 = ETDM_OUT2_CON1; 1802babb477STrevor Wu etdm_reg->con2 = ETDM_OUT2_CON2; 1812babb477STrevor Wu etdm_reg->con3 = ETDM_OUT2_CON3; 1822babb477STrevor Wu etdm_reg->con4 = ETDM_OUT2_CON4; 1832babb477STrevor Wu etdm_reg->con5 = ETDM_OUT2_CON5; 1842babb477STrevor Wu break; 1852babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 1862babb477STrevor Wu case MT8188_AFE_IO_DPTX: 1872babb477STrevor Wu etdm_reg->con0 = ETDM_OUT3_CON0; 1882babb477STrevor Wu etdm_reg->con1 = ETDM_OUT3_CON1; 1892babb477STrevor Wu etdm_reg->con2 = ETDM_OUT3_CON2; 1902babb477STrevor Wu etdm_reg->con3 = ETDM_OUT3_CON3; 1912babb477STrevor Wu etdm_reg->con4 = ETDM_OUT3_CON4; 1922babb477STrevor Wu etdm_reg->con5 = ETDM_OUT3_CON5; 1932babb477STrevor Wu break; 1942babb477STrevor Wu default: 1952babb477STrevor Wu return -EINVAL; 1962babb477STrevor Wu } 1972babb477STrevor Wu return 0; 1982babb477STrevor Wu } 1992babb477STrevor Wu 2002babb477STrevor Wu static int get_etdm_dir(unsigned int dai_id) 2012babb477STrevor Wu { 2022babb477STrevor Wu switch (dai_id) { 2032babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 2042babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 2052babb477STrevor Wu return ETDM_IN; 2062babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 2072babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 2082babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 2092babb477STrevor Wu return ETDM_OUT; 2102babb477STrevor Wu default: 2112babb477STrevor Wu return -EINVAL; 2122babb477STrevor Wu } 2132babb477STrevor Wu } 2142babb477STrevor Wu 2152babb477STrevor Wu static int get_etdm_wlen(unsigned int bitwidth) 2162babb477STrevor Wu { 2172babb477STrevor Wu return bitwidth <= 16 ? 16 : 32; 2182babb477STrevor Wu } 2192babb477STrevor Wu 2202babb477STrevor Wu static bool is_valid_etdm_dai(int dai_id) 2212babb477STrevor Wu { 2222babb477STrevor Wu switch (dai_id) { 2232babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 2242babb477STrevor Wu fallthrough; 2252babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 2262babb477STrevor Wu fallthrough; 2272babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 2282babb477STrevor Wu fallthrough; 2292babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 2302babb477STrevor Wu fallthrough; 2312babb477STrevor Wu case MT8188_AFE_IO_DPTX: 2322babb477STrevor Wu fallthrough; 2332babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 2342babb477STrevor Wu return true; 2352babb477STrevor Wu default: 2362babb477STrevor Wu return false; 2372babb477STrevor Wu } 2382babb477STrevor Wu } 2392babb477STrevor Wu 2402babb477STrevor Wu static int is_cowork_mode(struct snd_soc_dai *dai) 2412babb477STrevor Wu { 2422babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 2432babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 2442babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 2452babb477STrevor Wu 2462babb477STrevor Wu if (!is_valid_etdm_dai(dai->id)) 2472babb477STrevor Wu return -EINVAL; 2482babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai->id]; 2492babb477STrevor Wu 2502babb477STrevor Wu return (etdm_data->cowork_slv_count > 0 || 2512babb477STrevor Wu etdm_data->cowork_source_id != COWORK_ETDM_NONE); 2522babb477STrevor Wu } 2532babb477STrevor Wu 2542babb477STrevor Wu static int sync_to_dai_id(int source_sel) 2552babb477STrevor Wu { 2562babb477STrevor Wu switch (source_sel) { 2572babb477STrevor Wu case ETDM_SYNC_FROM_IN1: 2582babb477STrevor Wu return MT8188_AFE_IO_ETDM1_IN; 2592babb477STrevor Wu case ETDM_SYNC_FROM_IN2: 2602babb477STrevor Wu return MT8188_AFE_IO_ETDM2_IN; 2612babb477STrevor Wu case ETDM_SYNC_FROM_OUT1: 2622babb477STrevor Wu return MT8188_AFE_IO_ETDM1_OUT; 2632babb477STrevor Wu case ETDM_SYNC_FROM_OUT2: 2642babb477STrevor Wu return MT8188_AFE_IO_ETDM2_OUT; 2652babb477STrevor Wu case ETDM_SYNC_FROM_OUT3: 2662babb477STrevor Wu return MT8188_AFE_IO_ETDM3_OUT; 2672babb477STrevor Wu default: 2682babb477STrevor Wu return 0; 2692babb477STrevor Wu } 2702babb477STrevor Wu } 2712babb477STrevor Wu 2722babb477STrevor Wu static int get_etdm_cowork_master_id(struct snd_soc_dai *dai) 2732babb477STrevor Wu { 2742babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 2752babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 2762babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 2772babb477STrevor Wu int dai_id; 2782babb477STrevor Wu 2792babb477STrevor Wu if (!is_valid_etdm_dai(dai->id)) 2802babb477STrevor Wu return -EINVAL; 2812babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai->id]; 2822babb477STrevor Wu dai_id = etdm_data->cowork_source_id; 2832babb477STrevor Wu 2842babb477STrevor Wu if (dai_id == COWORK_ETDM_NONE) 2852babb477STrevor Wu dai_id = dai->id; 2862babb477STrevor Wu 2872babb477STrevor Wu return dai_id; 2882babb477STrevor Wu } 2892babb477STrevor Wu 2902babb477STrevor Wu static int mtk_dai_etdm_get_cg_id_by_dai_id(int dai_id) 2912babb477STrevor Wu { 2922babb477STrevor Wu switch (dai_id) { 2932babb477STrevor Wu case MT8188_AFE_IO_DPTX: 2942babb477STrevor Wu return MT8188_CLK_AUD_HDMI_OUT; 2952babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 2962babb477STrevor Wu return MT8188_CLK_AUD_TDM_IN; 2972babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 2982babb477STrevor Wu return MT8188_CLK_AUD_I2SIN; 2992babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 3002babb477STrevor Wu return MT8188_CLK_AUD_TDM_OUT; 3012babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 3022babb477STrevor Wu return MT8188_CLK_AUD_I2S_OUT; 3032babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 3042babb477STrevor Wu return MT8188_CLK_AUD_HDMI_OUT; 3052babb477STrevor Wu default: 3062babb477STrevor Wu return -EINVAL; 3072babb477STrevor Wu } 3082babb477STrevor Wu } 3092babb477STrevor Wu 3102babb477STrevor Wu static int mtk_dai_etdm_get_clk_id_by_dai_id(int dai_id) 3112babb477STrevor Wu { 3122babb477STrevor Wu switch (dai_id) { 3132babb477STrevor Wu case MT8188_AFE_IO_DPTX: 3142babb477STrevor Wu return MT8188_CLK_TOP_DPTX_M_SEL; 3152babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 3162babb477STrevor Wu return MT8188_CLK_TOP_I2SI1_M_SEL; 3172babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 3182babb477STrevor Wu return MT8188_CLK_TOP_I2SI2_M_SEL; 3192babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 3202babb477STrevor Wu return MT8188_CLK_TOP_I2SO1_M_SEL; 3212babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 3222babb477STrevor Wu return MT8188_CLK_TOP_I2SO2_M_SEL; 3232babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 3242babb477STrevor Wu default: 3252babb477STrevor Wu return -EINVAL; 3262babb477STrevor Wu } 3272babb477STrevor Wu } 3282babb477STrevor Wu 3292babb477STrevor Wu static int mtk_dai_etdm_get_clkdiv_id_by_dai_id(int dai_id) 3302babb477STrevor Wu { 3312babb477STrevor Wu switch (dai_id) { 3322babb477STrevor Wu case MT8188_AFE_IO_DPTX: 3332babb477STrevor Wu return MT8188_CLK_TOP_APLL12_DIV9; 3342babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 3352babb477STrevor Wu return MT8188_CLK_TOP_APLL12_DIV0; 3362babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 3372babb477STrevor Wu return MT8188_CLK_TOP_APLL12_DIV1; 3382babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 3392babb477STrevor Wu return MT8188_CLK_TOP_APLL12_DIV2; 3402babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 3412babb477STrevor Wu return MT8188_CLK_TOP_APLL12_DIV3; 3422babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 3432babb477STrevor Wu default: 3442babb477STrevor Wu return -EINVAL; 3452babb477STrevor Wu } 3462babb477STrevor Wu } 3472babb477STrevor Wu 3482babb477STrevor Wu static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id) 3492babb477STrevor Wu { 3502babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 3512babb477STrevor Wu int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id); 3522babb477STrevor Wu 3532babb477STrevor Wu if (clkdiv_id < 0) 3542babb477STrevor Wu return -EINVAL; 3552babb477STrevor Wu 3562babb477STrevor Wu mt8188_afe_enable_clk(afe, afe_priv->clk[clkdiv_id]); 3572babb477STrevor Wu 3582babb477STrevor Wu return 0; 3592babb477STrevor Wu } 3602babb477STrevor Wu 3612babb477STrevor Wu static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id) 3622babb477STrevor Wu { 3632babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 3642babb477STrevor Wu int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id); 3652babb477STrevor Wu 3662babb477STrevor Wu if (clkdiv_id < 0) 3672babb477STrevor Wu return -EINVAL; 3682babb477STrevor Wu 3692babb477STrevor Wu mt8188_afe_disable_clk(afe, afe_priv->clk[clkdiv_id]); 3702babb477STrevor Wu 3712babb477STrevor Wu return 0; 3722babb477STrevor Wu } 3732babb477STrevor Wu 3742babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o048_mix[] = { 3752babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN48, 20, 1, 0), 3762babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN48, 22, 1, 0), 3772babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN48_1, 14, 1, 0), 3782babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN48_2, 6, 1, 0), 3792babb477STrevor Wu }; 3802babb477STrevor Wu 3812babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o049_mix[] = { 3822babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN49, 21, 1, 0), 3832babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN49, 23, 1, 0), 3842babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN49_1, 15, 1, 0), 3852babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN49_2, 7, 1, 0), 3862babb477STrevor Wu }; 3872babb477STrevor Wu 3882babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o050_mix[] = { 3892babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN50, 24, 1, 0), 3902babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN50_1, 16, 1, 0), 3912babb477STrevor Wu }; 3922babb477STrevor Wu 3932babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o051_mix[] = { 3942babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN51, 25, 1, 0), 3952babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN51_1, 17, 1, 0), 3962babb477STrevor Wu }; 3972babb477STrevor Wu 3982babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o052_mix[] = { 3992babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN52, 26, 1, 0), 4002babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN52_1, 18, 1, 0), 4012babb477STrevor Wu }; 4022babb477STrevor Wu 4032babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o053_mix[] = { 4042babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN53, 27, 1, 0), 4052babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN53_1, 19, 1, 0), 4062babb477STrevor Wu }; 4072babb477STrevor Wu 4082babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o054_mix[] = { 4092babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN54, 28, 1, 0), 4102babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN54_1, 20, 1, 0), 4112babb477STrevor Wu }; 4122babb477STrevor Wu 4132babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o055_mix[] = { 4142babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN55, 29, 1, 0), 4152babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN55_1, 21, 1, 0), 4162babb477STrevor Wu }; 4172babb477STrevor Wu 4182babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o056_mix[] = { 4192babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I030 Switch", AFE_CONN56, 30, 1, 0), 4202babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I054 Switch", AFE_CONN56_1, 22, 1, 0), 4212babb477STrevor Wu }; 4222babb477STrevor Wu 4232babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o057_mix[] = { 4242babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I031 Switch", AFE_CONN57, 31, 1, 0), 4252babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I055 Switch", AFE_CONN57_1, 23, 1, 0), 4262babb477STrevor Wu }; 4272babb477STrevor Wu 4282babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o058_mix[] = { 4292babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I032 Switch", AFE_CONN58_1, 0, 1, 0), 4302babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I056 Switch", AFE_CONN58_1, 24, 1, 0), 4312babb477STrevor Wu }; 4322babb477STrevor Wu 4332babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o059_mix[] = { 4342babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I033 Switch", AFE_CONN59_1, 1, 1, 0), 4352babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I057 Switch", AFE_CONN59_1, 25, 1, 0), 4362babb477STrevor Wu }; 4372babb477STrevor Wu 4382babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o060_mix[] = { 4392babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I034 Switch", AFE_CONN60_1, 2, 1, 0), 4402babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I058 Switch", AFE_CONN60_1, 26, 1, 0), 4412babb477STrevor Wu }; 4422babb477STrevor Wu 4432babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o061_mix[] = { 4442babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I035 Switch", AFE_CONN61_1, 3, 1, 0), 4452babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I059 Switch", AFE_CONN61_1, 27, 1, 0), 4462babb477STrevor Wu }; 4472babb477STrevor Wu 4482babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o062_mix[] = { 4492babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I036 Switch", AFE_CONN62_1, 4, 1, 0), 4502babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I060 Switch", AFE_CONN62_1, 28, 1, 0), 4512babb477STrevor Wu }; 4522babb477STrevor Wu 4532babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o063_mix[] = { 4542babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I037 Switch", AFE_CONN63_1, 5, 1, 0), 4552babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I061 Switch", AFE_CONN63_1, 29, 1, 0), 4562babb477STrevor Wu }; 4572babb477STrevor Wu 4582babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o072_mix[] = { 4592babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN72, 20, 1, 0), 4602babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN72, 22, 1, 0), 4612babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN72_1, 14, 1, 0), 4622babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN72_2, 6, 1, 0), 4632babb477STrevor Wu }; 4642babb477STrevor Wu 4652babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o073_mix[] = { 4662babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN73, 21, 1, 0), 4672babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN73, 23, 1, 0), 4682babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN73_1, 15, 1, 0), 4692babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN73_2, 7, 1, 0), 4702babb477STrevor Wu }; 4712babb477STrevor Wu 4722babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o074_mix[] = { 4732babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN74, 24, 1, 0), 4742babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN74_1, 16, 1, 0), 4752babb477STrevor Wu }; 4762babb477STrevor Wu 4772babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o075_mix[] = { 4782babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN75, 25, 1, 0), 4792babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN75_1, 17, 1, 0), 4802babb477STrevor Wu }; 4812babb477STrevor Wu 4822babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o076_mix[] = { 4832babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN76, 26, 1, 0), 4842babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN76_1, 18, 1, 0), 4852babb477STrevor Wu }; 4862babb477STrevor Wu 4872babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o077_mix[] = { 4882babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN77, 27, 1, 0), 4892babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN77_1, 19, 1, 0), 4902babb477STrevor Wu }; 4912babb477STrevor Wu 4922babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o078_mix[] = { 4932babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN78, 28, 1, 0), 4942babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN78_1, 20, 1, 0), 4952babb477STrevor Wu }; 4962babb477STrevor Wu 4972babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o079_mix[] = { 4982babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN79, 29, 1, 0), 4992babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN79_1, 21, 1, 0), 5002babb477STrevor Wu }; 5012babb477STrevor Wu 5022babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o080_mix[] = { 5032babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I030 Switch", AFE_CONN80, 30, 1, 0), 5042babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I054 Switch", AFE_CONN80_1, 22, 1, 0), 5052babb477STrevor Wu }; 5062babb477STrevor Wu 5072babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o081_mix[] = { 5082babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I031 Switch", AFE_CONN81, 31, 1, 0), 5092babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I055 Switch", AFE_CONN81_1, 23, 1, 0), 5102babb477STrevor Wu }; 5112babb477STrevor Wu 5122babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o082_mix[] = { 5132babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I032 Switch", AFE_CONN82_1, 0, 1, 0), 5142babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I056 Switch", AFE_CONN82_1, 24, 1, 0), 5152babb477STrevor Wu }; 5162babb477STrevor Wu 5172babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o083_mix[] = { 5182babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I033 Switch", AFE_CONN83_1, 1, 1, 0), 5192babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I057 Switch", AFE_CONN83_1, 25, 1, 0), 5202babb477STrevor Wu }; 5212babb477STrevor Wu 5222babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o084_mix[] = { 5232babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I034 Switch", AFE_CONN84_1, 2, 1, 0), 5242babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I058 Switch", AFE_CONN84_1, 26, 1, 0), 5252babb477STrevor Wu }; 5262babb477STrevor Wu 5272babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o085_mix[] = { 5282babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I035 Switch", AFE_CONN85_1, 3, 1, 0), 5292babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I059 Switch", AFE_CONN85_1, 27, 1, 0), 5302babb477STrevor Wu }; 5312babb477STrevor Wu 5322babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o086_mix[] = { 5332babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I036 Switch", AFE_CONN86_1, 4, 1, 0), 5342babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I060 Switch", AFE_CONN86_1, 28, 1, 0), 5352babb477STrevor Wu }; 5362babb477STrevor Wu 5372babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_o087_mix[] = { 5382babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I037 Switch", AFE_CONN87_1, 5, 1, 0), 5392babb477STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I061 Switch", AFE_CONN87_1, 29, 1, 0), 5402babb477STrevor Wu }; 5412babb477STrevor Wu 5422babb477STrevor Wu static const char * const mt8188_etdm_clk_src_sel_text[] = { 5432babb477STrevor Wu "26m", 5442babb477STrevor Wu "a1sys_a2sys", 5452babb477STrevor Wu "a3sys", 5462babb477STrevor Wu "a4sys", 5472babb477STrevor Wu }; 5482babb477STrevor Wu 5492babb477STrevor Wu static SOC_ENUM_SINGLE_EXT_DECL(etdmout_clk_src_enum, 5502babb477STrevor Wu mt8188_etdm_clk_src_sel_text); 5512babb477STrevor Wu 5522babb477STrevor Wu static const char * const hdmitx_dptx_mux_map[] = { 5532babb477STrevor Wu "Disconnect", "Connect", 5542babb477STrevor Wu }; 5552babb477STrevor Wu 5562babb477STrevor Wu static int hdmitx_dptx_mux_map_value[] = { 5572babb477STrevor Wu 0, 1, 5582babb477STrevor Wu }; 5592babb477STrevor Wu 5602babb477STrevor Wu /* HDMI_OUT_MUX */ 5612babb477STrevor Wu static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(hdmi_out_mux_map_enum, 5622babb477STrevor Wu SND_SOC_NOPM, 5632babb477STrevor Wu 0, 5642babb477STrevor Wu 1, 5652babb477STrevor Wu hdmitx_dptx_mux_map, 5662babb477STrevor Wu hdmitx_dptx_mux_map_value); 5672babb477STrevor Wu 5682babb477STrevor Wu static const struct snd_kcontrol_new hdmi_out_mux_control = 5692babb477STrevor Wu SOC_DAPM_ENUM("HDMI_OUT_MUX", hdmi_out_mux_map_enum); 5702babb477STrevor Wu 5712babb477STrevor Wu /* DPTX_OUT_MUX */ 5722babb477STrevor Wu static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(dptx_out_mux_map_enum, 5732babb477STrevor Wu SND_SOC_NOPM, 5742babb477STrevor Wu 0, 5752babb477STrevor Wu 1, 5762babb477STrevor Wu hdmitx_dptx_mux_map, 5772babb477STrevor Wu hdmitx_dptx_mux_map_value); 5782babb477STrevor Wu 5792babb477STrevor Wu static const struct snd_kcontrol_new dptx_out_mux_control = 5802babb477STrevor Wu SOC_DAPM_ENUM("DPTX_OUT_MUX", dptx_out_mux_map_enum); 5812babb477STrevor Wu 5822babb477STrevor Wu /* HDMI_CH0_MUX ~ HDMI_CH7_MUX */ 5832babb477STrevor Wu static const char *const afe_conn_hdmi_mux_map[] = { 5842babb477STrevor Wu "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", 5852babb477STrevor Wu }; 5862babb477STrevor Wu 5872babb477STrevor Wu static int afe_conn_hdmi_mux_map_value[] = { 5882babb477STrevor Wu 0, 1, 2, 3, 4, 5, 6, 7, 5892babb477STrevor Wu }; 5902babb477STrevor Wu 5912babb477STrevor Wu static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch0_mux_map_enum, 5922babb477STrevor Wu AFE_TDMOUT_CONN0, 5932babb477STrevor Wu 0, 5942babb477STrevor Wu 0xf, 5952babb477STrevor Wu afe_conn_hdmi_mux_map, 5962babb477STrevor Wu afe_conn_hdmi_mux_map_value); 5972babb477STrevor Wu 5982babb477STrevor Wu static const struct snd_kcontrol_new hdmi_ch0_mux_control = 5992babb477STrevor Wu SOC_DAPM_ENUM("HDMI_CH0_MUX", hdmi_ch0_mux_map_enum); 6002babb477STrevor Wu 6012babb477STrevor Wu static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch1_mux_map_enum, 6022babb477STrevor Wu AFE_TDMOUT_CONN0, 6032babb477STrevor Wu 4, 6042babb477STrevor Wu 0xf, 6052babb477STrevor Wu afe_conn_hdmi_mux_map, 6062babb477STrevor Wu afe_conn_hdmi_mux_map_value); 6072babb477STrevor Wu 6082babb477STrevor Wu static const struct snd_kcontrol_new hdmi_ch1_mux_control = 6092babb477STrevor Wu SOC_DAPM_ENUM("HDMI_CH1_MUX", hdmi_ch1_mux_map_enum); 6102babb477STrevor Wu 6112babb477STrevor Wu static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch2_mux_map_enum, 6122babb477STrevor Wu AFE_TDMOUT_CONN0, 6132babb477STrevor Wu 8, 6142babb477STrevor Wu 0xf, 6152babb477STrevor Wu afe_conn_hdmi_mux_map, 6162babb477STrevor Wu afe_conn_hdmi_mux_map_value); 6172babb477STrevor Wu 6182babb477STrevor Wu static const struct snd_kcontrol_new hdmi_ch2_mux_control = 6192babb477STrevor Wu SOC_DAPM_ENUM("HDMI_CH2_MUX", hdmi_ch2_mux_map_enum); 6202babb477STrevor Wu 6212babb477STrevor Wu static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch3_mux_map_enum, 6222babb477STrevor Wu AFE_TDMOUT_CONN0, 6232babb477STrevor Wu 12, 6242babb477STrevor Wu 0xf, 6252babb477STrevor Wu afe_conn_hdmi_mux_map, 6262babb477STrevor Wu afe_conn_hdmi_mux_map_value); 6272babb477STrevor Wu 6282babb477STrevor Wu static const struct snd_kcontrol_new hdmi_ch3_mux_control = 6292babb477STrevor Wu SOC_DAPM_ENUM("HDMI_CH3_MUX", hdmi_ch3_mux_map_enum); 6302babb477STrevor Wu 6312babb477STrevor Wu static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch4_mux_map_enum, 6322babb477STrevor Wu AFE_TDMOUT_CONN0, 6332babb477STrevor Wu 16, 6342babb477STrevor Wu 0xf, 6352babb477STrevor Wu afe_conn_hdmi_mux_map, 6362babb477STrevor Wu afe_conn_hdmi_mux_map_value); 6372babb477STrevor Wu 6382babb477STrevor Wu static const struct snd_kcontrol_new hdmi_ch4_mux_control = 6392babb477STrevor Wu SOC_DAPM_ENUM("HDMI_CH4_MUX", hdmi_ch4_mux_map_enum); 6402babb477STrevor Wu 6412babb477STrevor Wu static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch5_mux_map_enum, 6422babb477STrevor Wu AFE_TDMOUT_CONN0, 6432babb477STrevor Wu 20, 6442babb477STrevor Wu 0xf, 6452babb477STrevor Wu afe_conn_hdmi_mux_map, 6462babb477STrevor Wu afe_conn_hdmi_mux_map_value); 6472babb477STrevor Wu 6482babb477STrevor Wu static const struct snd_kcontrol_new hdmi_ch5_mux_control = 6492babb477STrevor Wu SOC_DAPM_ENUM("HDMI_CH5_MUX", hdmi_ch5_mux_map_enum); 6502babb477STrevor Wu 6512babb477STrevor Wu static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch6_mux_map_enum, 6522babb477STrevor Wu AFE_TDMOUT_CONN0, 6532babb477STrevor Wu 24, 6542babb477STrevor Wu 0xf, 6552babb477STrevor Wu afe_conn_hdmi_mux_map, 6562babb477STrevor Wu afe_conn_hdmi_mux_map_value); 6572babb477STrevor Wu 6582babb477STrevor Wu static const struct snd_kcontrol_new hdmi_ch6_mux_control = 6592babb477STrevor Wu SOC_DAPM_ENUM("HDMI_CH6_MUX", hdmi_ch6_mux_map_enum); 6602babb477STrevor Wu 6612babb477STrevor Wu static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch7_mux_map_enum, 6622babb477STrevor Wu AFE_TDMOUT_CONN0, 6632babb477STrevor Wu 28, 6642babb477STrevor Wu 0xf, 6652babb477STrevor Wu afe_conn_hdmi_mux_map, 6662babb477STrevor Wu afe_conn_hdmi_mux_map_value); 6672babb477STrevor Wu 6682babb477STrevor Wu static const struct snd_kcontrol_new hdmi_ch7_mux_control = 6692babb477STrevor Wu SOC_DAPM_ENUM("HDMI_CH7_MUX", hdmi_ch7_mux_map_enum); 6702babb477STrevor Wu 6712babb477STrevor Wu static int mt8188_etdm_clk_src_sel_put(struct snd_kcontrol *kcontrol, 6722babb477STrevor Wu struct snd_ctl_elem_value *ucontrol) 6732babb477STrevor Wu { 6742babb477STrevor Wu struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 6752babb477STrevor Wu struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 6762babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); 6772babb477STrevor Wu unsigned int source = ucontrol->value.enumerated.item[0]; 6782babb477STrevor Wu unsigned int val; 6792babb477STrevor Wu unsigned int old_val; 6802babb477STrevor Wu unsigned int mask; 6812babb477STrevor Wu unsigned int reg; 6822babb477STrevor Wu 6832babb477STrevor Wu if (source >= e->items) 6842babb477STrevor Wu return -EINVAL; 6852babb477STrevor Wu 6862babb477STrevor Wu if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) { 6872babb477STrevor Wu reg = ETDM_OUT1_CON4; 6882babb477STrevor Wu mask = ETDM_OUT_CON4_CLOCK_MASK; 6892babb477STrevor Wu val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source); 6902babb477STrevor Wu } else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) { 6912babb477STrevor Wu reg = ETDM_OUT2_CON4; 6922babb477STrevor Wu mask = ETDM_OUT_CON4_CLOCK_MASK; 6932babb477STrevor Wu val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source); 6942babb477STrevor Wu } else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) { 6952babb477STrevor Wu reg = ETDM_OUT3_CON4; 6962babb477STrevor Wu mask = ETDM_OUT_CON4_CLOCK_MASK; 6972babb477STrevor Wu val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source); 6982babb477STrevor Wu } else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) { 6992babb477STrevor Wu reg = ETDM_IN1_CON2; 7002babb477STrevor Wu mask = ETDM_IN_CON2_CLOCK_MASK; 7012babb477STrevor Wu val = FIELD_PREP(ETDM_IN_CON2_CLOCK_MASK, source); 7022babb477STrevor Wu } else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) { 7032babb477STrevor Wu reg = ETDM_IN2_CON2; 7042babb477STrevor Wu mask = ETDM_IN_CON2_CLOCK_MASK; 7052babb477STrevor Wu val = FIELD_PREP(ETDM_IN_CON2_CLOCK_MASK, source); 7062babb477STrevor Wu } else { 7072babb477STrevor Wu return -EINVAL; 7082babb477STrevor Wu } 7092babb477STrevor Wu 7102babb477STrevor Wu regmap_read(afe->regmap, reg, &old_val); 7112babb477STrevor Wu old_val &= mask; 7122babb477STrevor Wu if (old_val == val) 7132babb477STrevor Wu return 0; 7142babb477STrevor Wu 7152babb477STrevor Wu regmap_update_bits(afe->regmap, reg, mask, val); 7162babb477STrevor Wu 7172babb477STrevor Wu return 1; 7182babb477STrevor Wu } 7192babb477STrevor Wu 7202babb477STrevor Wu static int mt8188_etdm_clk_src_sel_get(struct snd_kcontrol *kcontrol, 7212babb477STrevor Wu struct snd_ctl_elem_value *ucontrol) 7222babb477STrevor Wu { 7232babb477STrevor Wu struct snd_soc_component *component = 7242babb477STrevor Wu snd_soc_kcontrol_component(kcontrol); 7252babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); 7262babb477STrevor Wu unsigned int value; 7272babb477STrevor Wu unsigned int reg; 7282babb477STrevor Wu unsigned int mask; 7292babb477STrevor Wu unsigned int shift; 7302babb477STrevor Wu 7312babb477STrevor Wu if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) { 7322babb477STrevor Wu reg = ETDM_OUT1_CON4; 7332babb477STrevor Wu mask = ETDM_OUT_CON4_CLOCK_MASK; 7342babb477STrevor Wu shift = ETDM_OUT_CON4_CLOCK_SHIFT; 7352babb477STrevor Wu } else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) { 7362babb477STrevor Wu reg = ETDM_OUT2_CON4; 7372babb477STrevor Wu mask = ETDM_OUT_CON4_CLOCK_MASK; 7382babb477STrevor Wu shift = ETDM_OUT_CON4_CLOCK_SHIFT; 7392babb477STrevor Wu } else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) { 7402babb477STrevor Wu reg = ETDM_OUT3_CON4; 7412babb477STrevor Wu mask = ETDM_OUT_CON4_CLOCK_MASK; 7422babb477STrevor Wu shift = ETDM_OUT_CON4_CLOCK_SHIFT; 7432babb477STrevor Wu } else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) { 7442babb477STrevor Wu reg = ETDM_IN1_CON2; 7452babb477STrevor Wu mask = ETDM_IN_CON2_CLOCK_MASK; 7462babb477STrevor Wu shift = ETDM_IN_CON2_CLOCK_SHIFT; 7472babb477STrevor Wu } else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) { 7482babb477STrevor Wu reg = ETDM_IN2_CON2; 7492babb477STrevor Wu mask = ETDM_IN_CON2_CLOCK_MASK; 7502babb477STrevor Wu shift = ETDM_IN_CON2_CLOCK_SHIFT; 7512babb477STrevor Wu } else { 7522babb477STrevor Wu return -EINVAL; 7532babb477STrevor Wu } 7542babb477STrevor Wu 7552babb477STrevor Wu regmap_read(afe->regmap, reg, &value); 7562babb477STrevor Wu 7572babb477STrevor Wu value &= mask; 7582babb477STrevor Wu value >>= shift; 7592babb477STrevor Wu ucontrol->value.enumerated.item[0] = value; 7602babb477STrevor Wu return 0; 7612babb477STrevor Wu } 7622babb477STrevor Wu 7632babb477STrevor Wu static const struct snd_kcontrol_new mtk_dai_etdm_controls[] = { 7642babb477STrevor Wu SOC_ENUM_EXT("ETDM_OUT1_Clock_Source", etdmout_clk_src_enum, 7652babb477STrevor Wu mt8188_etdm_clk_src_sel_get, 7662babb477STrevor Wu mt8188_etdm_clk_src_sel_put), 7672babb477STrevor Wu SOC_ENUM_EXT("ETDM_OUT2_Clock_Source", etdmout_clk_src_enum, 7682babb477STrevor Wu mt8188_etdm_clk_src_sel_get, 7692babb477STrevor Wu mt8188_etdm_clk_src_sel_put), 7702babb477STrevor Wu SOC_ENUM_EXT("ETDM_OUT3_Clock_Source", etdmout_clk_src_enum, 7712babb477STrevor Wu mt8188_etdm_clk_src_sel_get, 7722babb477STrevor Wu mt8188_etdm_clk_src_sel_put), 7732babb477STrevor Wu SOC_ENUM_EXT("ETDM_IN1_Clock_Source", etdmout_clk_src_enum, 7742babb477STrevor Wu mt8188_etdm_clk_src_sel_get, 7752babb477STrevor Wu mt8188_etdm_clk_src_sel_put), 7762babb477STrevor Wu SOC_ENUM_EXT("ETDM_IN2_Clock_Source", etdmout_clk_src_enum, 7772babb477STrevor Wu mt8188_etdm_clk_src_sel_get, 7782babb477STrevor Wu mt8188_etdm_clk_src_sel_put), 7792babb477STrevor Wu }; 7802babb477STrevor Wu 7812babb477STrevor Wu static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = { 7822babb477STrevor Wu /* eTDM_IN2 */ 7832babb477STrevor Wu SND_SOC_DAPM_MIXER("I012", SND_SOC_NOPM, 0, 0, NULL, 0), 7842babb477STrevor Wu SND_SOC_DAPM_MIXER("I013", SND_SOC_NOPM, 0, 0, NULL, 0), 7852babb477STrevor Wu SND_SOC_DAPM_MIXER("I014", SND_SOC_NOPM, 0, 0, NULL, 0), 7862babb477STrevor Wu SND_SOC_DAPM_MIXER("I015", SND_SOC_NOPM, 0, 0, NULL, 0), 7872babb477STrevor Wu SND_SOC_DAPM_MIXER("I016", SND_SOC_NOPM, 0, 0, NULL, 0), 7882babb477STrevor Wu SND_SOC_DAPM_MIXER("I017", SND_SOC_NOPM, 0, 0, NULL, 0), 7892babb477STrevor Wu SND_SOC_DAPM_MIXER("I018", SND_SOC_NOPM, 0, 0, NULL, 0), 7902babb477STrevor Wu SND_SOC_DAPM_MIXER("I019", SND_SOC_NOPM, 0, 0, NULL, 0), 7912babb477STrevor Wu SND_SOC_DAPM_MIXER("I188", SND_SOC_NOPM, 0, 0, NULL, 0), 7922babb477STrevor Wu SND_SOC_DAPM_MIXER("I189", SND_SOC_NOPM, 0, 0, NULL, 0), 7932babb477STrevor Wu SND_SOC_DAPM_MIXER("I190", SND_SOC_NOPM, 0, 0, NULL, 0), 7942babb477STrevor Wu SND_SOC_DAPM_MIXER("I191", SND_SOC_NOPM, 0, 0, NULL, 0), 7952babb477STrevor Wu SND_SOC_DAPM_MIXER("I192", SND_SOC_NOPM, 0, 0, NULL, 0), 7962babb477STrevor Wu SND_SOC_DAPM_MIXER("I193", SND_SOC_NOPM, 0, 0, NULL, 0), 7972babb477STrevor Wu SND_SOC_DAPM_MIXER("I194", SND_SOC_NOPM, 0, 0, NULL, 0), 7982babb477STrevor Wu SND_SOC_DAPM_MIXER("I195", SND_SOC_NOPM, 0, 0, NULL, 0), 7992babb477STrevor Wu 8002babb477STrevor Wu /* eTDM_IN1 */ 8012babb477STrevor Wu SND_SOC_DAPM_MIXER("I072", SND_SOC_NOPM, 0, 0, NULL, 0), 8022babb477STrevor Wu SND_SOC_DAPM_MIXER("I073", SND_SOC_NOPM, 0, 0, NULL, 0), 8032babb477STrevor Wu SND_SOC_DAPM_MIXER("I074", SND_SOC_NOPM, 0, 0, NULL, 0), 8042babb477STrevor Wu SND_SOC_DAPM_MIXER("I075", SND_SOC_NOPM, 0, 0, NULL, 0), 8052babb477STrevor Wu SND_SOC_DAPM_MIXER("I076", SND_SOC_NOPM, 0, 0, NULL, 0), 8062babb477STrevor Wu SND_SOC_DAPM_MIXER("I077", SND_SOC_NOPM, 0, 0, NULL, 0), 8072babb477STrevor Wu SND_SOC_DAPM_MIXER("I078", SND_SOC_NOPM, 0, 0, NULL, 0), 8082babb477STrevor Wu SND_SOC_DAPM_MIXER("I079", SND_SOC_NOPM, 0, 0, NULL, 0), 8092babb477STrevor Wu SND_SOC_DAPM_MIXER("I080", SND_SOC_NOPM, 0, 0, NULL, 0), 8102babb477STrevor Wu SND_SOC_DAPM_MIXER("I081", SND_SOC_NOPM, 0, 0, NULL, 0), 8112babb477STrevor Wu SND_SOC_DAPM_MIXER("I082", SND_SOC_NOPM, 0, 0, NULL, 0), 8122babb477STrevor Wu SND_SOC_DAPM_MIXER("I083", SND_SOC_NOPM, 0, 0, NULL, 0), 8132babb477STrevor Wu SND_SOC_DAPM_MIXER("I084", SND_SOC_NOPM, 0, 0, NULL, 0), 8142babb477STrevor Wu SND_SOC_DAPM_MIXER("I085", SND_SOC_NOPM, 0, 0, NULL, 0), 8152babb477STrevor Wu SND_SOC_DAPM_MIXER("I086", SND_SOC_NOPM, 0, 0, NULL, 0), 8162babb477STrevor Wu SND_SOC_DAPM_MIXER("I087", SND_SOC_NOPM, 0, 0, NULL, 0), 8172babb477STrevor Wu 8182babb477STrevor Wu /* eTDM_OUT2 */ 8192babb477STrevor Wu SND_SOC_DAPM_MIXER("O048", SND_SOC_NOPM, 0, 0, 8202babb477STrevor Wu mtk_dai_etdm_o048_mix, ARRAY_SIZE(mtk_dai_etdm_o048_mix)), 8212babb477STrevor Wu SND_SOC_DAPM_MIXER("O049", SND_SOC_NOPM, 0, 0, 8222babb477STrevor Wu mtk_dai_etdm_o049_mix, ARRAY_SIZE(mtk_dai_etdm_o049_mix)), 8232babb477STrevor Wu SND_SOC_DAPM_MIXER("O050", SND_SOC_NOPM, 0, 0, 8242babb477STrevor Wu mtk_dai_etdm_o050_mix, ARRAY_SIZE(mtk_dai_etdm_o050_mix)), 8252babb477STrevor Wu SND_SOC_DAPM_MIXER("O051", SND_SOC_NOPM, 0, 0, 8262babb477STrevor Wu mtk_dai_etdm_o051_mix, ARRAY_SIZE(mtk_dai_etdm_o051_mix)), 8272babb477STrevor Wu SND_SOC_DAPM_MIXER("O052", SND_SOC_NOPM, 0, 0, 8282babb477STrevor Wu mtk_dai_etdm_o052_mix, ARRAY_SIZE(mtk_dai_etdm_o052_mix)), 8292babb477STrevor Wu SND_SOC_DAPM_MIXER("O053", SND_SOC_NOPM, 0, 0, 8302babb477STrevor Wu mtk_dai_etdm_o053_mix, ARRAY_SIZE(mtk_dai_etdm_o053_mix)), 8312babb477STrevor Wu SND_SOC_DAPM_MIXER("O054", SND_SOC_NOPM, 0, 0, 8322babb477STrevor Wu mtk_dai_etdm_o054_mix, ARRAY_SIZE(mtk_dai_etdm_o054_mix)), 8332babb477STrevor Wu SND_SOC_DAPM_MIXER("O055", SND_SOC_NOPM, 0, 0, 8342babb477STrevor Wu mtk_dai_etdm_o055_mix, ARRAY_SIZE(mtk_dai_etdm_o055_mix)), 8352babb477STrevor Wu SND_SOC_DAPM_MIXER("O056", SND_SOC_NOPM, 0, 0, 8362babb477STrevor Wu mtk_dai_etdm_o056_mix, ARRAY_SIZE(mtk_dai_etdm_o056_mix)), 8372babb477STrevor Wu SND_SOC_DAPM_MIXER("O057", SND_SOC_NOPM, 0, 0, 8382babb477STrevor Wu mtk_dai_etdm_o057_mix, ARRAY_SIZE(mtk_dai_etdm_o057_mix)), 8392babb477STrevor Wu SND_SOC_DAPM_MIXER("O058", SND_SOC_NOPM, 0, 0, 8402babb477STrevor Wu mtk_dai_etdm_o058_mix, ARRAY_SIZE(mtk_dai_etdm_o058_mix)), 8412babb477STrevor Wu SND_SOC_DAPM_MIXER("O059", SND_SOC_NOPM, 0, 0, 8422babb477STrevor Wu mtk_dai_etdm_o059_mix, ARRAY_SIZE(mtk_dai_etdm_o059_mix)), 8432babb477STrevor Wu SND_SOC_DAPM_MIXER("O060", SND_SOC_NOPM, 0, 0, 8442babb477STrevor Wu mtk_dai_etdm_o060_mix, ARRAY_SIZE(mtk_dai_etdm_o060_mix)), 8452babb477STrevor Wu SND_SOC_DAPM_MIXER("O061", SND_SOC_NOPM, 0, 0, 8462babb477STrevor Wu mtk_dai_etdm_o061_mix, ARRAY_SIZE(mtk_dai_etdm_o061_mix)), 8472babb477STrevor Wu SND_SOC_DAPM_MIXER("O062", SND_SOC_NOPM, 0, 0, 8482babb477STrevor Wu mtk_dai_etdm_o062_mix, ARRAY_SIZE(mtk_dai_etdm_o062_mix)), 8492babb477STrevor Wu SND_SOC_DAPM_MIXER("O063", SND_SOC_NOPM, 0, 0, 8502babb477STrevor Wu mtk_dai_etdm_o063_mix, ARRAY_SIZE(mtk_dai_etdm_o063_mix)), 8512babb477STrevor Wu 8522babb477STrevor Wu /* eTDM_OUT1 */ 8532babb477STrevor Wu SND_SOC_DAPM_MIXER("O072", SND_SOC_NOPM, 0, 0, 8542babb477STrevor Wu mtk_dai_etdm_o072_mix, ARRAY_SIZE(mtk_dai_etdm_o072_mix)), 8552babb477STrevor Wu SND_SOC_DAPM_MIXER("O073", SND_SOC_NOPM, 0, 0, 8562babb477STrevor Wu mtk_dai_etdm_o073_mix, ARRAY_SIZE(mtk_dai_etdm_o073_mix)), 8572babb477STrevor Wu SND_SOC_DAPM_MIXER("O074", SND_SOC_NOPM, 0, 0, 8582babb477STrevor Wu mtk_dai_etdm_o074_mix, ARRAY_SIZE(mtk_dai_etdm_o074_mix)), 8592babb477STrevor Wu SND_SOC_DAPM_MIXER("O075", SND_SOC_NOPM, 0, 0, 8602babb477STrevor Wu mtk_dai_etdm_o075_mix, ARRAY_SIZE(mtk_dai_etdm_o075_mix)), 8612babb477STrevor Wu SND_SOC_DAPM_MIXER("O076", SND_SOC_NOPM, 0, 0, 8622babb477STrevor Wu mtk_dai_etdm_o076_mix, ARRAY_SIZE(mtk_dai_etdm_o076_mix)), 8632babb477STrevor Wu SND_SOC_DAPM_MIXER("O077", SND_SOC_NOPM, 0, 0, 8642babb477STrevor Wu mtk_dai_etdm_o077_mix, ARRAY_SIZE(mtk_dai_etdm_o077_mix)), 8652babb477STrevor Wu SND_SOC_DAPM_MIXER("O078", SND_SOC_NOPM, 0, 0, 8662babb477STrevor Wu mtk_dai_etdm_o078_mix, ARRAY_SIZE(mtk_dai_etdm_o078_mix)), 8672babb477STrevor Wu SND_SOC_DAPM_MIXER("O079", SND_SOC_NOPM, 0, 0, 8682babb477STrevor Wu mtk_dai_etdm_o079_mix, ARRAY_SIZE(mtk_dai_etdm_o079_mix)), 8692babb477STrevor Wu SND_SOC_DAPM_MIXER("O080", SND_SOC_NOPM, 0, 0, 8702babb477STrevor Wu mtk_dai_etdm_o080_mix, ARRAY_SIZE(mtk_dai_etdm_o080_mix)), 8712babb477STrevor Wu SND_SOC_DAPM_MIXER("O081", SND_SOC_NOPM, 0, 0, 8722babb477STrevor Wu mtk_dai_etdm_o081_mix, ARRAY_SIZE(mtk_dai_etdm_o081_mix)), 8732babb477STrevor Wu SND_SOC_DAPM_MIXER("O082", SND_SOC_NOPM, 0, 0, 8742babb477STrevor Wu mtk_dai_etdm_o082_mix, ARRAY_SIZE(mtk_dai_etdm_o082_mix)), 8752babb477STrevor Wu SND_SOC_DAPM_MIXER("O083", SND_SOC_NOPM, 0, 0, 8762babb477STrevor Wu mtk_dai_etdm_o083_mix, ARRAY_SIZE(mtk_dai_etdm_o083_mix)), 8772babb477STrevor Wu SND_SOC_DAPM_MIXER("O084", SND_SOC_NOPM, 0, 0, 8782babb477STrevor Wu mtk_dai_etdm_o084_mix, ARRAY_SIZE(mtk_dai_etdm_o084_mix)), 8792babb477STrevor Wu SND_SOC_DAPM_MIXER("O085", SND_SOC_NOPM, 0, 0, 8802babb477STrevor Wu mtk_dai_etdm_o085_mix, ARRAY_SIZE(mtk_dai_etdm_o085_mix)), 8812babb477STrevor Wu SND_SOC_DAPM_MIXER("O086", SND_SOC_NOPM, 0, 0, 8822babb477STrevor Wu mtk_dai_etdm_o086_mix, ARRAY_SIZE(mtk_dai_etdm_o086_mix)), 8832babb477STrevor Wu SND_SOC_DAPM_MIXER("O087", SND_SOC_NOPM, 0, 0, 8842babb477STrevor Wu mtk_dai_etdm_o087_mix, ARRAY_SIZE(mtk_dai_etdm_o087_mix)), 8852babb477STrevor Wu 8862babb477STrevor Wu /* eTDM_OUT3 */ 8872babb477STrevor Wu SND_SOC_DAPM_MUX("HDMI_OUT_MUX", SND_SOC_NOPM, 0, 0, 8882babb477STrevor Wu &hdmi_out_mux_control), 8892babb477STrevor Wu SND_SOC_DAPM_MUX("DPTX_OUT_MUX", SND_SOC_NOPM, 0, 0, 8902babb477STrevor Wu &dptx_out_mux_control), 8912babb477STrevor Wu 8922babb477STrevor Wu SND_SOC_DAPM_MUX("HDMI_CH0_MUX", SND_SOC_NOPM, 0, 0, 8932babb477STrevor Wu &hdmi_ch0_mux_control), 8942babb477STrevor Wu SND_SOC_DAPM_MUX("HDMI_CH1_MUX", SND_SOC_NOPM, 0, 0, 8952babb477STrevor Wu &hdmi_ch1_mux_control), 8962babb477STrevor Wu SND_SOC_DAPM_MUX("HDMI_CH2_MUX", SND_SOC_NOPM, 0, 0, 8972babb477STrevor Wu &hdmi_ch2_mux_control), 8982babb477STrevor Wu SND_SOC_DAPM_MUX("HDMI_CH3_MUX", SND_SOC_NOPM, 0, 0, 8992babb477STrevor Wu &hdmi_ch3_mux_control), 9002babb477STrevor Wu SND_SOC_DAPM_MUX("HDMI_CH4_MUX", SND_SOC_NOPM, 0, 0, 9012babb477STrevor Wu &hdmi_ch4_mux_control), 9022babb477STrevor Wu SND_SOC_DAPM_MUX("HDMI_CH5_MUX", SND_SOC_NOPM, 0, 0, 9032babb477STrevor Wu &hdmi_ch5_mux_control), 9042babb477STrevor Wu SND_SOC_DAPM_MUX("HDMI_CH6_MUX", SND_SOC_NOPM, 0, 0, 9052babb477STrevor Wu &hdmi_ch6_mux_control), 9062babb477STrevor Wu SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0, 9072babb477STrevor Wu &hdmi_ch7_mux_control), 9082babb477STrevor Wu 9092babb477STrevor Wu SND_SOC_DAPM_INPUT("ETDM_INPUT"), 9102babb477STrevor Wu SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"), 9112babb477STrevor Wu }; 9122babb477STrevor Wu 9132babb477STrevor Wu static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = { 9142babb477STrevor Wu {"I012", NULL, "ETDM2_IN"}, 9152babb477STrevor Wu {"I013", NULL, "ETDM2_IN"}, 9162babb477STrevor Wu {"I014", NULL, "ETDM2_IN"}, 9172babb477STrevor Wu {"I015", NULL, "ETDM2_IN"}, 9182babb477STrevor Wu {"I016", NULL, "ETDM2_IN"}, 9192babb477STrevor Wu {"I017", NULL, "ETDM2_IN"}, 9202babb477STrevor Wu {"I018", NULL, "ETDM2_IN"}, 9212babb477STrevor Wu {"I019", NULL, "ETDM2_IN"}, 9222babb477STrevor Wu {"I188", NULL, "ETDM2_IN"}, 9232babb477STrevor Wu {"I189", NULL, "ETDM2_IN"}, 9242babb477STrevor Wu {"I190", NULL, "ETDM2_IN"}, 9252babb477STrevor Wu {"I191", NULL, "ETDM2_IN"}, 9262babb477STrevor Wu {"I192", NULL, "ETDM2_IN"}, 9272babb477STrevor Wu {"I193", NULL, "ETDM2_IN"}, 9282babb477STrevor Wu {"I194", NULL, "ETDM2_IN"}, 9292babb477STrevor Wu {"I195", NULL, "ETDM2_IN"}, 9302babb477STrevor Wu 9312babb477STrevor Wu {"I072", NULL, "ETDM1_IN"}, 9322babb477STrevor Wu {"I073", NULL, "ETDM1_IN"}, 9332babb477STrevor Wu {"I074", NULL, "ETDM1_IN"}, 9342babb477STrevor Wu {"I075", NULL, "ETDM1_IN"}, 9352babb477STrevor Wu {"I076", NULL, "ETDM1_IN"}, 9362babb477STrevor Wu {"I077", NULL, "ETDM1_IN"}, 9372babb477STrevor Wu {"I078", NULL, "ETDM1_IN"}, 9382babb477STrevor Wu {"I079", NULL, "ETDM1_IN"}, 9392babb477STrevor Wu {"I080", NULL, "ETDM1_IN"}, 9402babb477STrevor Wu {"I081", NULL, "ETDM1_IN"}, 9412babb477STrevor Wu {"I082", NULL, "ETDM1_IN"}, 9422babb477STrevor Wu {"I083", NULL, "ETDM1_IN"}, 9432babb477STrevor Wu {"I084", NULL, "ETDM1_IN"}, 9442babb477STrevor Wu {"I085", NULL, "ETDM1_IN"}, 9452babb477STrevor Wu {"I086", NULL, "ETDM1_IN"}, 9462babb477STrevor Wu {"I087", NULL, "ETDM1_IN"}, 9472babb477STrevor Wu 9482babb477STrevor Wu {"UL8", NULL, "ETDM1_IN"}, 9492babb477STrevor Wu {"UL3", NULL, "ETDM2_IN"}, 9502babb477STrevor Wu 9512babb477STrevor Wu {"ETDM2_OUT", NULL, "O048"}, 9522babb477STrevor Wu {"ETDM2_OUT", NULL, "O049"}, 9532babb477STrevor Wu {"ETDM2_OUT", NULL, "O050"}, 9542babb477STrevor Wu {"ETDM2_OUT", NULL, "O051"}, 9552babb477STrevor Wu {"ETDM2_OUT", NULL, "O052"}, 9562babb477STrevor Wu {"ETDM2_OUT", NULL, "O053"}, 9572babb477STrevor Wu {"ETDM2_OUT", NULL, "O054"}, 9582babb477STrevor Wu {"ETDM2_OUT", NULL, "O055"}, 9592babb477STrevor Wu {"ETDM2_OUT", NULL, "O056"}, 9602babb477STrevor Wu {"ETDM2_OUT", NULL, "O057"}, 9612babb477STrevor Wu {"ETDM2_OUT", NULL, "O058"}, 9622babb477STrevor Wu {"ETDM2_OUT", NULL, "O059"}, 9632babb477STrevor Wu {"ETDM2_OUT", NULL, "O060"}, 9642babb477STrevor Wu {"ETDM2_OUT", NULL, "O061"}, 9652babb477STrevor Wu {"ETDM2_OUT", NULL, "O062"}, 9662babb477STrevor Wu {"ETDM2_OUT", NULL, "O063"}, 9672babb477STrevor Wu 9682babb477STrevor Wu {"ETDM1_OUT", NULL, "O072"}, 9692babb477STrevor Wu {"ETDM1_OUT", NULL, "O073"}, 9702babb477STrevor Wu {"ETDM1_OUT", NULL, "O074"}, 9712babb477STrevor Wu {"ETDM1_OUT", NULL, "O075"}, 9722babb477STrevor Wu {"ETDM1_OUT", NULL, "O076"}, 9732babb477STrevor Wu {"ETDM1_OUT", NULL, "O077"}, 9742babb477STrevor Wu {"ETDM1_OUT", NULL, "O078"}, 9752babb477STrevor Wu {"ETDM1_OUT", NULL, "O079"}, 9762babb477STrevor Wu {"ETDM1_OUT", NULL, "O080"}, 9772babb477STrevor Wu {"ETDM1_OUT", NULL, "O081"}, 9782babb477STrevor Wu {"ETDM1_OUT", NULL, "O082"}, 9792babb477STrevor Wu {"ETDM1_OUT", NULL, "O083"}, 9802babb477STrevor Wu {"ETDM1_OUT", NULL, "O084"}, 9812babb477STrevor Wu {"ETDM1_OUT", NULL, "O085"}, 9822babb477STrevor Wu {"ETDM1_OUT", NULL, "O086"}, 9832babb477STrevor Wu {"ETDM1_OUT", NULL, "O087"}, 9842babb477STrevor Wu 9852babb477STrevor Wu {"O048", "I020 Switch", "I020"}, 9862babb477STrevor Wu {"O049", "I021 Switch", "I021"}, 9872babb477STrevor Wu 9882babb477STrevor Wu {"O048", "I022 Switch", "I022"}, 9892babb477STrevor Wu {"O049", "I023 Switch", "I023"}, 9902babb477STrevor Wu {"O050", "I024 Switch", "I024"}, 9912babb477STrevor Wu {"O051", "I025 Switch", "I025"}, 9922babb477STrevor Wu {"O052", "I026 Switch", "I026"}, 9932babb477STrevor Wu {"O053", "I027 Switch", "I027"}, 9942babb477STrevor Wu {"O054", "I028 Switch", "I028"}, 9952babb477STrevor Wu {"O055", "I029 Switch", "I029"}, 9962babb477STrevor Wu {"O056", "I030 Switch", "I030"}, 9972babb477STrevor Wu {"O057", "I031 Switch", "I031"}, 9982babb477STrevor Wu {"O058", "I032 Switch", "I032"}, 9992babb477STrevor Wu {"O059", "I033 Switch", "I033"}, 10002babb477STrevor Wu {"O060", "I034 Switch", "I034"}, 10012babb477STrevor Wu {"O061", "I035 Switch", "I035"}, 10022babb477STrevor Wu {"O062", "I036 Switch", "I036"}, 10032babb477STrevor Wu {"O063", "I037 Switch", "I037"}, 10042babb477STrevor Wu 10052babb477STrevor Wu {"O048", "I046 Switch", "I046"}, 10062babb477STrevor Wu {"O049", "I047 Switch", "I047"}, 10072babb477STrevor Wu {"O050", "I048 Switch", "I048"}, 10082babb477STrevor Wu {"O051", "I049 Switch", "I049"}, 10092babb477STrevor Wu {"O052", "I050 Switch", "I050"}, 10102babb477STrevor Wu {"O053", "I051 Switch", "I051"}, 10112babb477STrevor Wu {"O054", "I052 Switch", "I052"}, 10122babb477STrevor Wu {"O055", "I053 Switch", "I053"}, 10132babb477STrevor Wu {"O056", "I054 Switch", "I054"}, 10142babb477STrevor Wu {"O057", "I055 Switch", "I055"}, 10152babb477STrevor Wu {"O058", "I056 Switch", "I056"}, 10162babb477STrevor Wu {"O059", "I057 Switch", "I057"}, 10172babb477STrevor Wu {"O060", "I058 Switch", "I058"}, 10182babb477STrevor Wu {"O061", "I059 Switch", "I059"}, 10192babb477STrevor Wu {"O062", "I060 Switch", "I060"}, 10202babb477STrevor Wu {"O063", "I061 Switch", "I061"}, 10212babb477STrevor Wu 10222babb477STrevor Wu {"O048", "I070 Switch", "I070"}, 10232babb477STrevor Wu {"O049", "I071 Switch", "I071"}, 10242babb477STrevor Wu 10252babb477STrevor Wu {"O072", "I020 Switch", "I020"}, 10262babb477STrevor Wu {"O073", "I021 Switch", "I021"}, 10272babb477STrevor Wu 10282babb477STrevor Wu {"O072", "I022 Switch", "I022"}, 10292babb477STrevor Wu {"O073", "I023 Switch", "I023"}, 10302babb477STrevor Wu {"O074", "I024 Switch", "I024"}, 10312babb477STrevor Wu {"O075", "I025 Switch", "I025"}, 10322babb477STrevor Wu {"O076", "I026 Switch", "I026"}, 10332babb477STrevor Wu {"O077", "I027 Switch", "I027"}, 10342babb477STrevor Wu {"O078", "I028 Switch", "I028"}, 10352babb477STrevor Wu {"O079", "I029 Switch", "I029"}, 10362babb477STrevor Wu {"O080", "I030 Switch", "I030"}, 10372babb477STrevor Wu {"O081", "I031 Switch", "I031"}, 10382babb477STrevor Wu {"O082", "I032 Switch", "I032"}, 10392babb477STrevor Wu {"O083", "I033 Switch", "I033"}, 10402babb477STrevor Wu {"O084", "I034 Switch", "I034"}, 10412babb477STrevor Wu {"O085", "I035 Switch", "I035"}, 10422babb477STrevor Wu {"O086", "I036 Switch", "I036"}, 10432babb477STrevor Wu {"O087", "I037 Switch", "I037"}, 10442babb477STrevor Wu 10452babb477STrevor Wu {"O072", "I046 Switch", "I046"}, 10462babb477STrevor Wu {"O073", "I047 Switch", "I047"}, 10472babb477STrevor Wu {"O074", "I048 Switch", "I048"}, 10482babb477STrevor Wu {"O075", "I049 Switch", "I049"}, 10492babb477STrevor Wu {"O076", "I050 Switch", "I050"}, 10502babb477STrevor Wu {"O077", "I051 Switch", "I051"}, 10512babb477STrevor Wu {"O078", "I052 Switch", "I052"}, 10522babb477STrevor Wu {"O079", "I053 Switch", "I053"}, 10532babb477STrevor Wu {"O080", "I054 Switch", "I054"}, 10542babb477STrevor Wu {"O081", "I055 Switch", "I055"}, 10552babb477STrevor Wu {"O082", "I056 Switch", "I056"}, 10562babb477STrevor Wu {"O083", "I057 Switch", "I057"}, 10572babb477STrevor Wu {"O084", "I058 Switch", "I058"}, 10582babb477STrevor Wu {"O085", "I059 Switch", "I059"}, 10592babb477STrevor Wu {"O086", "I060 Switch", "I060"}, 10602babb477STrevor Wu {"O087", "I061 Switch", "I061"}, 10612babb477STrevor Wu 10622babb477STrevor Wu {"O072", "I070 Switch", "I070"}, 10632babb477STrevor Wu {"O073", "I071 Switch", "I071"}, 10642babb477STrevor Wu 10652babb477STrevor Wu {"HDMI_CH0_MUX", "CH0", "DL10"}, 10662babb477STrevor Wu {"HDMI_CH0_MUX", "CH1", "DL10"}, 10672babb477STrevor Wu {"HDMI_CH0_MUX", "CH2", "DL10"}, 10682babb477STrevor Wu {"HDMI_CH0_MUX", "CH3", "DL10"}, 10692babb477STrevor Wu {"HDMI_CH0_MUX", "CH4", "DL10"}, 10702babb477STrevor Wu {"HDMI_CH0_MUX", "CH5", "DL10"}, 10712babb477STrevor Wu {"HDMI_CH0_MUX", "CH6", "DL10"}, 10722babb477STrevor Wu {"HDMI_CH0_MUX", "CH7", "DL10"}, 10732babb477STrevor Wu 10742babb477STrevor Wu {"HDMI_CH1_MUX", "CH0", "DL10"}, 10752babb477STrevor Wu {"HDMI_CH1_MUX", "CH1", "DL10"}, 10762babb477STrevor Wu {"HDMI_CH1_MUX", "CH2", "DL10"}, 10772babb477STrevor Wu {"HDMI_CH1_MUX", "CH3", "DL10"}, 10782babb477STrevor Wu {"HDMI_CH1_MUX", "CH4", "DL10"}, 10792babb477STrevor Wu {"HDMI_CH1_MUX", "CH5", "DL10"}, 10802babb477STrevor Wu {"HDMI_CH1_MUX", "CH6", "DL10"}, 10812babb477STrevor Wu {"HDMI_CH1_MUX", "CH7", "DL10"}, 10822babb477STrevor Wu 10832babb477STrevor Wu {"HDMI_CH2_MUX", "CH0", "DL10"}, 10842babb477STrevor Wu {"HDMI_CH2_MUX", "CH1", "DL10"}, 10852babb477STrevor Wu {"HDMI_CH2_MUX", "CH2", "DL10"}, 10862babb477STrevor Wu {"HDMI_CH2_MUX", "CH3", "DL10"}, 10872babb477STrevor Wu {"HDMI_CH2_MUX", "CH4", "DL10"}, 10882babb477STrevor Wu {"HDMI_CH2_MUX", "CH5", "DL10"}, 10892babb477STrevor Wu {"HDMI_CH2_MUX", "CH6", "DL10"}, 10902babb477STrevor Wu {"HDMI_CH2_MUX", "CH7", "DL10"}, 10912babb477STrevor Wu 10922babb477STrevor Wu {"HDMI_CH3_MUX", "CH0", "DL10"}, 10932babb477STrevor Wu {"HDMI_CH3_MUX", "CH1", "DL10"}, 10942babb477STrevor Wu {"HDMI_CH3_MUX", "CH2", "DL10"}, 10952babb477STrevor Wu {"HDMI_CH3_MUX", "CH3", "DL10"}, 10962babb477STrevor Wu {"HDMI_CH3_MUX", "CH4", "DL10"}, 10972babb477STrevor Wu {"HDMI_CH3_MUX", "CH5", "DL10"}, 10982babb477STrevor Wu {"HDMI_CH3_MUX", "CH6", "DL10"}, 10992babb477STrevor Wu {"HDMI_CH3_MUX", "CH7", "DL10"}, 11002babb477STrevor Wu 11012babb477STrevor Wu {"HDMI_CH4_MUX", "CH0", "DL10"}, 11022babb477STrevor Wu {"HDMI_CH4_MUX", "CH1", "DL10"}, 11032babb477STrevor Wu {"HDMI_CH4_MUX", "CH2", "DL10"}, 11042babb477STrevor Wu {"HDMI_CH4_MUX", "CH3", "DL10"}, 11052babb477STrevor Wu {"HDMI_CH4_MUX", "CH4", "DL10"}, 11062babb477STrevor Wu {"HDMI_CH4_MUX", "CH5", "DL10"}, 11072babb477STrevor Wu {"HDMI_CH4_MUX", "CH6", "DL10"}, 11082babb477STrevor Wu {"HDMI_CH4_MUX", "CH7", "DL10"}, 11092babb477STrevor Wu 11102babb477STrevor Wu {"HDMI_CH5_MUX", "CH0", "DL10"}, 11112babb477STrevor Wu {"HDMI_CH5_MUX", "CH1", "DL10"}, 11122babb477STrevor Wu {"HDMI_CH5_MUX", "CH2", "DL10"}, 11132babb477STrevor Wu {"HDMI_CH5_MUX", "CH3", "DL10"}, 11142babb477STrevor Wu {"HDMI_CH5_MUX", "CH4", "DL10"}, 11152babb477STrevor Wu {"HDMI_CH5_MUX", "CH5", "DL10"}, 11162babb477STrevor Wu {"HDMI_CH5_MUX", "CH6", "DL10"}, 11172babb477STrevor Wu {"HDMI_CH5_MUX", "CH7", "DL10"}, 11182babb477STrevor Wu 11192babb477STrevor Wu {"HDMI_CH6_MUX", "CH0", "DL10"}, 11202babb477STrevor Wu {"HDMI_CH6_MUX", "CH1", "DL10"}, 11212babb477STrevor Wu {"HDMI_CH6_MUX", "CH2", "DL10"}, 11222babb477STrevor Wu {"HDMI_CH6_MUX", "CH3", "DL10"}, 11232babb477STrevor Wu {"HDMI_CH6_MUX", "CH4", "DL10"}, 11242babb477STrevor Wu {"HDMI_CH6_MUX", "CH5", "DL10"}, 11252babb477STrevor Wu {"HDMI_CH6_MUX", "CH6", "DL10"}, 11262babb477STrevor Wu {"HDMI_CH6_MUX", "CH7", "DL10"}, 11272babb477STrevor Wu 11282babb477STrevor Wu {"HDMI_CH7_MUX", "CH0", "DL10"}, 11292babb477STrevor Wu {"HDMI_CH7_MUX", "CH1", "DL10"}, 11302babb477STrevor Wu {"HDMI_CH7_MUX", "CH2", "DL10"}, 11312babb477STrevor Wu {"HDMI_CH7_MUX", "CH3", "DL10"}, 11322babb477STrevor Wu {"HDMI_CH7_MUX", "CH4", "DL10"}, 11332babb477STrevor Wu {"HDMI_CH7_MUX", "CH5", "DL10"}, 11342babb477STrevor Wu {"HDMI_CH7_MUX", "CH6", "DL10"}, 11352babb477STrevor Wu {"HDMI_CH7_MUX", "CH7", "DL10"}, 11362babb477STrevor Wu 11372babb477STrevor Wu {"HDMI_OUT_MUX", "Connect", "HDMI_CH0_MUX"}, 11382babb477STrevor Wu {"HDMI_OUT_MUX", "Connect", "HDMI_CH1_MUX"}, 11392babb477STrevor Wu {"HDMI_OUT_MUX", "Connect", "HDMI_CH2_MUX"}, 11402babb477STrevor Wu {"HDMI_OUT_MUX", "Connect", "HDMI_CH3_MUX"}, 11412babb477STrevor Wu {"HDMI_OUT_MUX", "Connect", "HDMI_CH4_MUX"}, 11422babb477STrevor Wu {"HDMI_OUT_MUX", "Connect", "HDMI_CH5_MUX"}, 11432babb477STrevor Wu {"HDMI_OUT_MUX", "Connect", "HDMI_CH6_MUX"}, 11442babb477STrevor Wu {"HDMI_OUT_MUX", "Connect", "HDMI_CH7_MUX"}, 11452babb477STrevor Wu 11462babb477STrevor Wu {"DPTX_OUT_MUX", "Connect", "HDMI_CH0_MUX"}, 11472babb477STrevor Wu {"DPTX_OUT_MUX", "Connect", "HDMI_CH1_MUX"}, 11482babb477STrevor Wu {"DPTX_OUT_MUX", "Connect", "HDMI_CH2_MUX"}, 11492babb477STrevor Wu {"DPTX_OUT_MUX", "Connect", "HDMI_CH3_MUX"}, 11502babb477STrevor Wu {"DPTX_OUT_MUX", "Connect", "HDMI_CH4_MUX"}, 11512babb477STrevor Wu {"DPTX_OUT_MUX", "Connect", "HDMI_CH5_MUX"}, 11522babb477STrevor Wu {"DPTX_OUT_MUX", "Connect", "HDMI_CH6_MUX"}, 11532babb477STrevor Wu {"DPTX_OUT_MUX", "Connect", "HDMI_CH7_MUX"}, 11542babb477STrevor Wu 11552babb477STrevor Wu {"ETDM3_OUT", NULL, "HDMI_OUT_MUX"}, 11562babb477STrevor Wu {"DPTX", NULL, "DPTX_OUT_MUX"}, 11572babb477STrevor Wu 11582babb477STrevor Wu {"ETDM_OUTPUT", NULL, "DPTX"}, 11592babb477STrevor Wu {"ETDM_OUTPUT", NULL, "ETDM1_OUT"}, 11602babb477STrevor Wu {"ETDM_OUTPUT", NULL, "ETDM2_OUT"}, 11612babb477STrevor Wu {"ETDM_OUTPUT", NULL, "ETDM3_OUT"}, 11622babb477STrevor Wu {"ETDM1_IN", NULL, "ETDM_INPUT"}, 11632babb477STrevor Wu {"ETDM2_IN", NULL, "ETDM_INPUT"}, 11642babb477STrevor Wu }; 11652babb477STrevor Wu 11662babb477STrevor Wu static int mt8188_afe_enable_etdm(struct mtk_base_afe *afe, int dai_id) 11672babb477STrevor Wu { 11682babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 11692babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 11702babb477STrevor Wu struct etdm_con_reg etdm_reg; 11712babb477STrevor Wu unsigned long flags; 11722babb477STrevor Wu int ret = 0; 11732babb477STrevor Wu 11742babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 11752babb477STrevor Wu return -EINVAL; 11762babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 11772babb477STrevor Wu 11782babb477STrevor Wu dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt); 11792babb477STrevor Wu spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); 11802babb477STrevor Wu etdm_data->en_ref_cnt++; 11812babb477STrevor Wu if (etdm_data->en_ref_cnt == 1) { 11822babb477STrevor Wu ret = get_etdm_reg(dai_id, &etdm_reg); 11832babb477STrevor Wu if (ret < 0) 11842babb477STrevor Wu goto out; 11852babb477STrevor Wu 11862babb477STrevor Wu regmap_set_bits(afe->regmap, etdm_reg.con0, ETDM_CON0_EN); 11872babb477STrevor Wu } 11882babb477STrevor Wu 11892babb477STrevor Wu out: 11902babb477STrevor Wu spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); 11912babb477STrevor Wu return ret; 11922babb477STrevor Wu } 11932babb477STrevor Wu 11942babb477STrevor Wu static int mt8188_afe_disable_etdm(struct mtk_base_afe *afe, int dai_id) 11952babb477STrevor Wu { 11962babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 11972babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 11982babb477STrevor Wu struct etdm_con_reg etdm_reg; 11992babb477STrevor Wu unsigned long flags; 12002babb477STrevor Wu int ret = 0; 12012babb477STrevor Wu 12022babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 12032babb477STrevor Wu return -EINVAL; 12042babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 12052babb477STrevor Wu 12062babb477STrevor Wu dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt); 12072babb477STrevor Wu spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); 12082babb477STrevor Wu if (etdm_data->en_ref_cnt > 0) { 12092babb477STrevor Wu etdm_data->en_ref_cnt--; 12102babb477STrevor Wu if (etdm_data->en_ref_cnt == 0) { 12112babb477STrevor Wu ret = get_etdm_reg(dai_id, &etdm_reg); 12122babb477STrevor Wu if (ret < 0) 12132babb477STrevor Wu goto out; 12142babb477STrevor Wu regmap_clear_bits(afe->regmap, etdm_reg.con0, 12152babb477STrevor Wu ETDM_CON0_EN); 12162babb477STrevor Wu } 12172babb477STrevor Wu } 12182babb477STrevor Wu 12192babb477STrevor Wu out: 12202babb477STrevor Wu spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); 12212babb477STrevor Wu return ret; 12222babb477STrevor Wu } 12232babb477STrevor Wu 12242babb477STrevor Wu static int etdm_cowork_slv_sel(int id, int slave_mode) 12252babb477STrevor Wu { 12262babb477STrevor Wu if (slave_mode) { 12272babb477STrevor Wu switch (id) { 12282babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 12292babb477STrevor Wu return COWORK_ETDM_IN1_S; 12302babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 12312babb477STrevor Wu return COWORK_ETDM_IN2_S; 12322babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 12332babb477STrevor Wu return COWORK_ETDM_OUT1_S; 12342babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 12352babb477STrevor Wu return COWORK_ETDM_OUT2_S; 12362babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 12372babb477STrevor Wu return COWORK_ETDM_OUT3_S; 12382babb477STrevor Wu default: 12392babb477STrevor Wu return -EINVAL; 12402babb477STrevor Wu } 12412babb477STrevor Wu } else { 12422babb477STrevor Wu switch (id) { 12432babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 12442babb477STrevor Wu return COWORK_ETDM_IN1_M; 12452babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 12462babb477STrevor Wu return COWORK_ETDM_IN2_M; 12472babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 12482babb477STrevor Wu return COWORK_ETDM_OUT1_M; 12492babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 12502babb477STrevor Wu return COWORK_ETDM_OUT2_M; 12512babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 12522babb477STrevor Wu return COWORK_ETDM_OUT3_M; 12532babb477STrevor Wu default: 12542babb477STrevor Wu return -EINVAL; 12552babb477STrevor Wu } 12562babb477STrevor Wu } 12572babb477STrevor Wu } 12582babb477STrevor Wu 12592babb477STrevor Wu static int etdm_cowork_sync_sel(int id) 12602babb477STrevor Wu { 12612babb477STrevor Wu switch (id) { 12622babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 12632babb477STrevor Wu return ETDM_SYNC_FROM_IN1; 12642babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 12652babb477STrevor Wu return ETDM_SYNC_FROM_IN2; 12662babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 12672babb477STrevor Wu return ETDM_SYNC_FROM_OUT1; 12682babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 12692babb477STrevor Wu return ETDM_SYNC_FROM_OUT2; 12702babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 12712babb477STrevor Wu return ETDM_SYNC_FROM_OUT3; 12722babb477STrevor Wu default: 12732babb477STrevor Wu return -EINVAL; 12742babb477STrevor Wu } 12752babb477STrevor Wu } 12762babb477STrevor Wu 12772babb477STrevor Wu static int mt8188_etdm_sync_mode_slv(struct mtk_base_afe *afe, int dai_id) 12782babb477STrevor Wu { 12792babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 12802babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 12812babb477STrevor Wu unsigned int reg = 0; 12822babb477STrevor Wu unsigned int mask; 12832babb477STrevor Wu unsigned int val; 12842babb477STrevor Wu int cowork_source_sel; 12852babb477STrevor Wu 12862babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 12872babb477STrevor Wu return -EINVAL; 12882babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 12892babb477STrevor Wu 12902babb477STrevor Wu cowork_source_sel = etdm_cowork_slv_sel(etdm_data->cowork_source_id, 12912babb477STrevor Wu true); 12922babb477STrevor Wu if (cowork_source_sel < 0) 12932babb477STrevor Wu return cowork_source_sel; 12942babb477STrevor Wu 12952babb477STrevor Wu switch (dai_id) { 12962babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 12972babb477STrevor Wu reg = ETDM_COWORK_CON1; 12982babb477STrevor Wu mask = ETDM_IN1_SLAVE_SEL_MASK; 12992babb477STrevor Wu val = FIELD_PREP(ETDM_IN1_SLAVE_SEL_MASK, cowork_source_sel); 13002babb477STrevor Wu break; 13012babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 13022babb477STrevor Wu reg = ETDM_COWORK_CON2; 13032babb477STrevor Wu mask = ETDM_IN2_SLAVE_SEL_MASK; 13042babb477STrevor Wu val = FIELD_PREP(ETDM_IN2_SLAVE_SEL_MASK, cowork_source_sel); 13052babb477STrevor Wu break; 13062babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 13072babb477STrevor Wu reg = ETDM_COWORK_CON0; 13082babb477STrevor Wu mask = ETDM_OUT1_SLAVE_SEL_MASK; 13092babb477STrevor Wu val = FIELD_PREP(ETDM_OUT1_SLAVE_SEL_MASK, cowork_source_sel); 13102babb477STrevor Wu break; 13112babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 13122babb477STrevor Wu reg = ETDM_COWORK_CON2; 13132babb477STrevor Wu mask = ETDM_OUT2_SLAVE_SEL_MASK; 13142babb477STrevor Wu val = FIELD_PREP(ETDM_OUT2_SLAVE_SEL_MASK, cowork_source_sel); 13152babb477STrevor Wu break; 13162babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 13172babb477STrevor Wu reg = ETDM_COWORK_CON2; 13182babb477STrevor Wu mask = ETDM_OUT3_SLAVE_SEL_MASK; 13192babb477STrevor Wu val = FIELD_PREP(ETDM_OUT3_SLAVE_SEL_MASK, cowork_source_sel); 13202babb477STrevor Wu break; 13212babb477STrevor Wu default: 13222babb477STrevor Wu return 0; 13232babb477STrevor Wu } 13242babb477STrevor Wu 13252babb477STrevor Wu regmap_update_bits(afe->regmap, reg, mask, val); 13262babb477STrevor Wu 13272babb477STrevor Wu return 0; 13282babb477STrevor Wu } 13292babb477STrevor Wu 13302babb477STrevor Wu static int mt8188_etdm_sync_mode_mst(struct mtk_base_afe *afe, int dai_id) 13312babb477STrevor Wu { 13322babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 13332babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 13342babb477STrevor Wu struct etdm_con_reg etdm_reg; 13352babb477STrevor Wu unsigned int reg = 0; 13362babb477STrevor Wu unsigned int mask; 13372babb477STrevor Wu unsigned int val; 13382babb477STrevor Wu int cowork_source_sel; 13392babb477STrevor Wu int ret; 13402babb477STrevor Wu 13412babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 13422babb477STrevor Wu return -EINVAL; 13432babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 13442babb477STrevor Wu 13452babb477STrevor Wu cowork_source_sel = etdm_cowork_sync_sel(etdm_data->cowork_source_id); 13462babb477STrevor Wu if (cowork_source_sel < 0) 13472babb477STrevor Wu return cowork_source_sel; 13482babb477STrevor Wu 13492babb477STrevor Wu switch (dai_id) { 13502babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 13512babb477STrevor Wu reg = ETDM_COWORK_CON1; 13522babb477STrevor Wu mask = ETDM_IN1_SYNC_SEL_MASK; 13532babb477STrevor Wu val = FIELD_PREP(ETDM_IN1_SYNC_SEL_MASK, cowork_source_sel); 13542babb477STrevor Wu break; 13552babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 13562babb477STrevor Wu reg = ETDM_COWORK_CON2; 13572babb477STrevor Wu mask = ETDM_IN2_SYNC_SEL_MASK; 13582babb477STrevor Wu val = FIELD_PREP(ETDM_IN2_SYNC_SEL_MASK, cowork_source_sel); 13592babb477STrevor Wu break; 13602babb477STrevor Wu case MT8188_AFE_IO_ETDM1_OUT: 13612babb477STrevor Wu reg = ETDM_COWORK_CON0; 13622babb477STrevor Wu mask = ETDM_OUT1_SYNC_SEL_MASK; 13632babb477STrevor Wu val = FIELD_PREP(ETDM_OUT1_SYNC_SEL_MASK, cowork_source_sel); 13642babb477STrevor Wu break; 13652babb477STrevor Wu case MT8188_AFE_IO_ETDM2_OUT: 13662babb477STrevor Wu reg = ETDM_COWORK_CON2; 13672babb477STrevor Wu mask = ETDM_OUT2_SYNC_SEL_MASK; 13682babb477STrevor Wu val = FIELD_PREP(ETDM_OUT2_SYNC_SEL_MASK, cowork_source_sel); 13692babb477STrevor Wu break; 13702babb477STrevor Wu case MT8188_AFE_IO_ETDM3_OUT: 13712babb477STrevor Wu reg = ETDM_COWORK_CON2; 13722babb477STrevor Wu mask = ETDM_OUT3_SYNC_SEL_MASK; 13732babb477STrevor Wu val = FIELD_PREP(ETDM_OUT3_SYNC_SEL_MASK, cowork_source_sel); 13742babb477STrevor Wu break; 13752babb477STrevor Wu default: 13762babb477STrevor Wu return 0; 13772babb477STrevor Wu } 13782babb477STrevor Wu 13792babb477STrevor Wu ret = get_etdm_reg(dai_id, &etdm_reg); 13802babb477STrevor Wu if (ret < 0) 13812babb477STrevor Wu return ret; 13822babb477STrevor Wu 13832babb477STrevor Wu regmap_update_bits(afe->regmap, reg, mask, val); 13842babb477STrevor Wu 13852babb477STrevor Wu regmap_set_bits(afe->regmap, etdm_reg.con0, ETDM_CON0_SYNC_MODE); 13862babb477STrevor Wu 13872babb477STrevor Wu return 0; 13882babb477STrevor Wu } 13892babb477STrevor Wu 13902babb477STrevor Wu static int mt8188_etdm_sync_mode_configure(struct mtk_base_afe *afe, int dai_id) 13912babb477STrevor Wu { 13922babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 13932babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 13942babb477STrevor Wu 13952babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 13962babb477STrevor Wu return -EINVAL; 13972babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 13982babb477STrevor Wu 13992babb477STrevor Wu if (etdm_data->cowork_source_id == COWORK_ETDM_NONE) 14002babb477STrevor Wu return 0; 14012babb477STrevor Wu 14022babb477STrevor Wu if (etdm_data->slave_mode) 14032babb477STrevor Wu mt8188_etdm_sync_mode_slv(afe, dai_id); 14042babb477STrevor Wu else 14052babb477STrevor Wu mt8188_etdm_sync_mode_mst(afe, dai_id); 14062babb477STrevor Wu 14072babb477STrevor Wu return 0; 14082babb477STrevor Wu } 14092babb477STrevor Wu 14102babb477STrevor Wu /* dai ops */ 14112babb477STrevor Wu static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream, 14122babb477STrevor Wu struct snd_soc_dai *dai) 14132babb477STrevor Wu { 14142babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 14152babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 14162babb477STrevor Wu struct mtk_dai_etdm_priv *mst_etdm_data; 14172babb477STrevor Wu int mst_dai_id; 14182babb477STrevor Wu int slv_dai_id; 14192babb477STrevor Wu int cg_id; 14202babb477STrevor Wu int i; 14212babb477STrevor Wu 14222babb477STrevor Wu if (is_cowork_mode(dai)) { 14232babb477STrevor Wu mst_dai_id = get_etdm_cowork_master_id(dai); 14242babb477STrevor Wu if (!is_valid_etdm_dai(mst_dai_id)) 14252babb477STrevor Wu return -EINVAL; 14262babb477STrevor Wu mtk_dai_etdm_enable_mclk(afe, mst_dai_id); 14272babb477STrevor Wu 14282babb477STrevor Wu cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id); 14292babb477STrevor Wu if (cg_id >= 0) 14302babb477STrevor Wu mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]); 14312babb477STrevor Wu 14322babb477STrevor Wu mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; 14332babb477STrevor Wu 14342babb477STrevor Wu for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) { 14352babb477STrevor Wu slv_dai_id = mst_etdm_data->cowork_slv_id[i]; 14362babb477STrevor Wu cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id); 14372babb477STrevor Wu if (cg_id >= 0) 14382babb477STrevor Wu mt8188_afe_enable_clk(afe, 14392babb477STrevor Wu afe_priv->clk[cg_id]); 14402babb477STrevor Wu } 14412babb477STrevor Wu } else { 14422babb477STrevor Wu mtk_dai_etdm_enable_mclk(afe, dai->id); 14432babb477STrevor Wu 14442babb477STrevor Wu cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id); 14452babb477STrevor Wu if (cg_id >= 0) 14462babb477STrevor Wu mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]); 14472babb477STrevor Wu } 14482babb477STrevor Wu 14492babb477STrevor Wu return 0; 14502babb477STrevor Wu } 14512babb477STrevor Wu 14522babb477STrevor Wu static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream, 14532babb477STrevor Wu struct snd_soc_dai *dai) 14542babb477STrevor Wu { 14552babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 14562babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 14572babb477STrevor Wu struct mtk_dai_etdm_priv *mst_etdm_data; 14582babb477STrevor Wu int mst_dai_id; 14592babb477STrevor Wu int slv_dai_id; 14602babb477STrevor Wu int cg_id; 14612babb477STrevor Wu int ret; 14622babb477STrevor Wu int i; 14632babb477STrevor Wu 14642babb477STrevor Wu if (!is_valid_etdm_dai(dai->id)) 14652babb477STrevor Wu return; 14662babb477STrevor Wu mst_etdm_data = afe_priv->dai_priv[dai->id]; 14672babb477STrevor Wu 14682babb477STrevor Wu dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id, 14692babb477STrevor Wu mst_etdm_data->is_prepared); 14702babb477STrevor Wu 14712babb477STrevor Wu if (mst_etdm_data->is_prepared) { 14722babb477STrevor Wu mst_etdm_data->is_prepared = false; 14732babb477STrevor Wu 14742babb477STrevor Wu if (is_cowork_mode(dai)) { 14752babb477STrevor Wu mst_dai_id = get_etdm_cowork_master_id(dai); 14762babb477STrevor Wu if (!is_valid_etdm_dai(mst_dai_id)) 14772babb477STrevor Wu return; 14782babb477STrevor Wu mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; 14792babb477STrevor Wu 14802babb477STrevor Wu ret = mt8188_afe_disable_etdm(afe, mst_dai_id); 14812babb477STrevor Wu if (ret) 14822babb477STrevor Wu dev_dbg(afe->dev, "%s disable %d failed\n", 14832babb477STrevor Wu __func__, mst_dai_id); 14842babb477STrevor Wu 14852babb477STrevor Wu for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) { 14862babb477STrevor Wu slv_dai_id = mst_etdm_data->cowork_slv_id[i]; 14872babb477STrevor Wu ret = mt8188_afe_disable_etdm(afe, slv_dai_id); 14882babb477STrevor Wu if (ret) 14892babb477STrevor Wu dev_dbg(afe->dev, "%s disable %d failed\n", 14902babb477STrevor Wu __func__, slv_dai_id); 14912babb477STrevor Wu } 14922babb477STrevor Wu } else { 14932babb477STrevor Wu ret = mt8188_afe_disable_etdm(afe, dai->id); 14942babb477STrevor Wu if (ret) 14952babb477STrevor Wu dev_dbg(afe->dev, "%s disable %d failed\n", 14962babb477STrevor Wu __func__, dai->id); 14972babb477STrevor Wu } 14982babb477STrevor Wu } 14992babb477STrevor Wu 15002babb477STrevor Wu if (is_cowork_mode(dai)) { 15012babb477STrevor Wu mst_dai_id = get_etdm_cowork_master_id(dai); 15022babb477STrevor Wu if (!is_valid_etdm_dai(mst_dai_id)) 15032babb477STrevor Wu return; 15042babb477STrevor Wu cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id); 15052babb477STrevor Wu if (cg_id >= 0) 15062babb477STrevor Wu mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]); 15072babb477STrevor Wu 15082babb477STrevor Wu mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; 15092babb477STrevor Wu for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) { 15102babb477STrevor Wu slv_dai_id = mst_etdm_data->cowork_slv_id[i]; 15112babb477STrevor Wu cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id); 15122babb477STrevor Wu if (cg_id >= 0) 15132babb477STrevor Wu mt8188_afe_disable_clk(afe, 15142babb477STrevor Wu afe_priv->clk[cg_id]); 15152babb477STrevor Wu } 15162babb477STrevor Wu mtk_dai_etdm_disable_mclk(afe, mst_dai_id); 15172babb477STrevor Wu } else { 15182babb477STrevor Wu cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id); 15192babb477STrevor Wu if (cg_id >= 0) 15202babb477STrevor Wu mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]); 15212babb477STrevor Wu 15222babb477STrevor Wu mtk_dai_etdm_disable_mclk(afe, dai->id); 15232babb477STrevor Wu } 15242babb477STrevor Wu } 15252babb477STrevor Wu 15262babb477STrevor Wu static int mtk_dai_etdm_fifo_mode(struct mtk_base_afe *afe, 15272babb477STrevor Wu int dai_id, unsigned int rate) 15282babb477STrevor Wu { 15292babb477STrevor Wu unsigned int mode = 0; 15302babb477STrevor Wu unsigned int reg = 0; 15312babb477STrevor Wu unsigned int val = 0; 15322babb477STrevor Wu unsigned int mask = (ETDM_IN_AFIFO_MODE_MASK | ETDM_IN_USE_AFIFO); 15332babb477STrevor Wu 15342babb477STrevor Wu if (rate != 0) 15352babb477STrevor Wu mode = mt8188_afe_fs_timing(rate); 15362babb477STrevor Wu 15372babb477STrevor Wu switch (dai_id) { 15382babb477STrevor Wu case MT8188_AFE_IO_ETDM1_IN: 15392babb477STrevor Wu reg = ETDM_IN1_AFIFO_CON; 15402babb477STrevor Wu if (rate == 0) 15412babb477STrevor Wu mode = MT8188_ETDM_IN1_1X_EN; 15422babb477STrevor Wu break; 15432babb477STrevor Wu case MT8188_AFE_IO_ETDM2_IN: 15442babb477STrevor Wu reg = ETDM_IN2_AFIFO_CON; 15452babb477STrevor Wu if (rate == 0) 15462babb477STrevor Wu mode = MT8188_ETDM_IN2_1X_EN; 15472babb477STrevor Wu break; 15482babb477STrevor Wu default: 15492babb477STrevor Wu return -EINVAL; 15502babb477STrevor Wu } 15512babb477STrevor Wu 15522babb477STrevor Wu val = (mode | ETDM_IN_USE_AFIFO); 15532babb477STrevor Wu 15542babb477STrevor Wu regmap_update_bits(afe->regmap, reg, mask, val); 15552babb477STrevor Wu return 0; 15562babb477STrevor Wu } 15572babb477STrevor Wu 15582babb477STrevor Wu static int mtk_dai_etdm_in_configure(struct mtk_base_afe *afe, 15592babb477STrevor Wu unsigned int rate, 15602babb477STrevor Wu unsigned int channels, 15612babb477STrevor Wu int dai_id) 15622babb477STrevor Wu { 15632babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 15642babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 15652babb477STrevor Wu struct etdm_con_reg etdm_reg; 15662babb477STrevor Wu bool slave_mode; 15672babb477STrevor Wu unsigned int data_mode; 15682babb477STrevor Wu unsigned int lrck_width; 15692babb477STrevor Wu unsigned int val = 0; 15702babb477STrevor Wu unsigned int mask = 0; 15712babb477STrevor Wu int ret; 15722babb477STrevor Wu int i; 15732babb477STrevor Wu 15742babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 15752babb477STrevor Wu return -EINVAL; 15762babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 15772babb477STrevor Wu slave_mode = etdm_data->slave_mode; 15782babb477STrevor Wu data_mode = etdm_data->data_mode; 15792babb477STrevor Wu lrck_width = etdm_data->lrck_width; 15802babb477STrevor Wu 15812babb477STrevor Wu dev_dbg(afe->dev, "%s rate %u channels %u, id %d\n", 15822babb477STrevor Wu __func__, rate, channels, dai_id); 15832babb477STrevor Wu 15842babb477STrevor Wu ret = get_etdm_reg(dai_id, &etdm_reg); 15852babb477STrevor Wu if (ret < 0) 15862babb477STrevor Wu return ret; 15872babb477STrevor Wu 15882babb477STrevor Wu /* afifo */ 15892babb477STrevor Wu if (slave_mode) 15902babb477STrevor Wu mtk_dai_etdm_fifo_mode(afe, dai_id, 0); 15912babb477STrevor Wu else 15922babb477STrevor Wu mtk_dai_etdm_fifo_mode(afe, dai_id, rate); 15932babb477STrevor Wu 15942babb477STrevor Wu /* con1 */ 15952babb477STrevor Wu if (lrck_width > 0) { 15962babb477STrevor Wu mask |= (ETDM_IN_CON1_LRCK_AUTO_MODE | 15972babb477STrevor Wu ETDM_IN_CON1_LRCK_WIDTH_MASK); 15982babb477STrevor Wu val |= FIELD_PREP(ETDM_IN_CON1_LRCK_WIDTH_MASK, lrck_width - 1); 15992babb477STrevor Wu } 16002babb477STrevor Wu regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val); 16012babb477STrevor Wu 16022babb477STrevor Wu mask = 0; 16032babb477STrevor Wu val = 0; 16042babb477STrevor Wu 16052babb477STrevor Wu /* con2 */ 16062babb477STrevor Wu if (!slave_mode) { 16072babb477STrevor Wu mask |= ETDM_IN_CON2_UPDATE_GAP_MASK; 16082babb477STrevor Wu if (rate == 352800 || rate == 384000) 16092babb477STrevor Wu val |= FIELD_PREP(ETDM_IN_CON2_UPDATE_GAP_MASK, 4); 16102babb477STrevor Wu else 16112babb477STrevor Wu val |= FIELD_PREP(ETDM_IN_CON2_UPDATE_GAP_MASK, 3); 16122babb477STrevor Wu } 16132babb477STrevor Wu mask |= (ETDM_IN_CON2_MULTI_IP_2CH_MODE | 16142babb477STrevor Wu ETDM_IN_CON2_MULTI_IP_TOTAL_CH_MASK); 16152babb477STrevor Wu if (data_mode == MTK_DAI_ETDM_DATA_MULTI_PIN) { 16162babb477STrevor Wu val |= ETDM_IN_CON2_MULTI_IP_2CH_MODE | 16172babb477STrevor Wu FIELD_PREP(ETDM_IN_CON2_MULTI_IP_TOTAL_CH_MASK, channels - 1); 16182babb477STrevor Wu } 16192babb477STrevor Wu regmap_update_bits(afe->regmap, etdm_reg.con2, mask, val); 16202babb477STrevor Wu 16212babb477STrevor Wu mask = 0; 16222babb477STrevor Wu val = 0; 16232babb477STrevor Wu 16242babb477STrevor Wu /* con3 */ 16252babb477STrevor Wu mask |= ETDM_IN_CON3_DISABLE_OUT_MASK; 16262babb477STrevor Wu for (i = 0; i < channels; i += 2) { 16272babb477STrevor Wu if (etdm_data->in_disable_ch[i] && 16282babb477STrevor Wu etdm_data->in_disable_ch[i + 1]) 16292babb477STrevor Wu val |= ETDM_IN_CON3_DISABLE_OUT(i >> 1); 16302babb477STrevor Wu } 16312babb477STrevor Wu if (!slave_mode) { 16322babb477STrevor Wu mask |= ETDM_IN_CON3_FS_MASK; 16332babb477STrevor Wu val |= FIELD_PREP(ETDM_IN_CON3_FS_MASK, get_etdm_fs_timing(rate)); 16342babb477STrevor Wu } 16352babb477STrevor Wu regmap_update_bits(afe->regmap, etdm_reg.con3, mask, val); 16362babb477STrevor Wu 16372babb477STrevor Wu mask = 0; 16382babb477STrevor Wu val = 0; 16392babb477STrevor Wu 16402babb477STrevor Wu /* con4 */ 16412babb477STrevor Wu mask |= (ETDM_IN_CON4_MASTER_LRCK_INV | ETDM_IN_CON4_MASTER_BCK_INV | 16422babb477STrevor Wu ETDM_IN_CON4_SLAVE_LRCK_INV | ETDM_IN_CON4_SLAVE_BCK_INV); 16432babb477STrevor Wu if (slave_mode) { 16442babb477STrevor Wu if (etdm_data->lrck_inv) 16452babb477STrevor Wu val |= ETDM_IN_CON4_SLAVE_LRCK_INV; 16462babb477STrevor Wu if (etdm_data->bck_inv) 16472babb477STrevor Wu val |= ETDM_IN_CON4_SLAVE_BCK_INV; 16482babb477STrevor Wu } else { 16492babb477STrevor Wu if (etdm_data->lrck_inv) 16502babb477STrevor Wu val |= ETDM_IN_CON4_MASTER_LRCK_INV; 16512babb477STrevor Wu if (etdm_data->bck_inv) 16522babb477STrevor Wu val |= ETDM_IN_CON4_MASTER_BCK_INV; 16532babb477STrevor Wu } 16542babb477STrevor Wu regmap_update_bits(afe->regmap, etdm_reg.con4, mask, val); 16552babb477STrevor Wu 16562babb477STrevor Wu mask = 0; 16572babb477STrevor Wu val = 0; 16582babb477STrevor Wu 16592babb477STrevor Wu /* con5 */ 16602babb477STrevor Wu mask |= ETDM_IN_CON5_LR_SWAP_MASK; 16612babb477STrevor Wu mask |= ETDM_IN_CON5_ENABLE_ODD_MASK; 16622babb477STrevor Wu for (i = 0; i < channels; i += 2) { 16632babb477STrevor Wu if (etdm_data->in_disable_ch[i] && 16642babb477STrevor Wu !etdm_data->in_disable_ch[i + 1]) { 16652babb477STrevor Wu val |= ETDM_IN_CON5_LR_SWAP(i >> 1); 16662babb477STrevor Wu val |= ETDM_IN_CON5_ENABLE_ODD(i >> 1); 16672babb477STrevor Wu } else if (!etdm_data->in_disable_ch[i] && 16682babb477STrevor Wu etdm_data->in_disable_ch[i + 1]) { 16692babb477STrevor Wu val |= ETDM_IN_CON5_ENABLE_ODD(i >> 1); 16702babb477STrevor Wu } 16712babb477STrevor Wu } 16722babb477STrevor Wu regmap_update_bits(afe->regmap, etdm_reg.con5, mask, val); 16732babb477STrevor Wu return 0; 16742babb477STrevor Wu } 16752babb477STrevor Wu 16762babb477STrevor Wu static int mtk_dai_etdm_out_configure(struct mtk_base_afe *afe, 16772babb477STrevor Wu unsigned int rate, 16782babb477STrevor Wu unsigned int channels, 16792babb477STrevor Wu int dai_id) 16802babb477STrevor Wu { 16812babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 16822babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 16832babb477STrevor Wu struct etdm_con_reg etdm_reg; 16842babb477STrevor Wu bool slave_mode; 16852babb477STrevor Wu unsigned int lrck_width; 16862babb477STrevor Wu unsigned int val = 0; 16872babb477STrevor Wu unsigned int mask = 0; 16882babb477STrevor Wu int fs = 0; 16892babb477STrevor Wu int ret; 16902babb477STrevor Wu 16912babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 16922babb477STrevor Wu return -EINVAL; 16932babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 16942babb477STrevor Wu slave_mode = etdm_data->slave_mode; 16952babb477STrevor Wu lrck_width = etdm_data->lrck_width; 16962babb477STrevor Wu 16972babb477STrevor Wu dev_dbg(afe->dev, "%s rate %u channels %u, id %d\n", 16982babb477STrevor Wu __func__, rate, channels, dai_id); 16992babb477STrevor Wu 17002babb477STrevor Wu ret = get_etdm_reg(dai_id, &etdm_reg); 17012babb477STrevor Wu if (ret < 0) 17022babb477STrevor Wu return ret; 17032babb477STrevor Wu 17042babb477STrevor Wu /* con0 */ 17052babb477STrevor Wu mask = ETDM_OUT_CON0_RELATCH_DOMAIN_MASK; 17062babb477STrevor Wu val = FIELD_PREP(ETDM_OUT_CON0_RELATCH_DOMAIN_MASK, 17072babb477STrevor Wu ETDM_RELATCH_TIMING_A1A2SYS); 17082babb477STrevor Wu regmap_update_bits(afe->regmap, etdm_reg.con0, mask, val); 17092babb477STrevor Wu 17102babb477STrevor Wu mask = 0; 17112babb477STrevor Wu val = 0; 17122babb477STrevor Wu 17132babb477STrevor Wu /* con1 */ 17142babb477STrevor Wu if (lrck_width > 0) { 17152babb477STrevor Wu mask |= (ETDM_OUT_CON1_LRCK_AUTO_MODE | 17162babb477STrevor Wu ETDM_OUT_CON1_LRCK_WIDTH_MASK); 17172babb477STrevor Wu val |= FIELD_PREP(ETDM_OUT_CON1_LRCK_WIDTH_MASK, lrck_width - 1); 17182babb477STrevor Wu } 17192babb477STrevor Wu regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val); 17202babb477STrevor Wu 17212babb477STrevor Wu mask = 0; 17222babb477STrevor Wu val = 0; 17232babb477STrevor Wu 17242babb477STrevor Wu if (!slave_mode) { 17252babb477STrevor Wu /* con4 */ 17262babb477STrevor Wu mask |= ETDM_OUT_CON4_FS_MASK; 17272babb477STrevor Wu val |= FIELD_PREP(ETDM_OUT_CON4_FS_MASK, get_etdm_fs_timing(rate)); 17282babb477STrevor Wu } 17292babb477STrevor Wu 17302babb477STrevor Wu mask |= ETDM_OUT_CON4_RELATCH_EN_MASK; 17312babb477STrevor Wu if (dai_id == MT8188_AFE_IO_ETDM1_OUT) 17322babb477STrevor Wu fs = MT8188_ETDM_OUT1_1X_EN; 17332babb477STrevor Wu else if (dai_id == MT8188_AFE_IO_ETDM2_OUT) 17342babb477STrevor Wu fs = MT8188_ETDM_OUT2_1X_EN; 17352babb477STrevor Wu 17362babb477STrevor Wu val |= FIELD_PREP(ETDM_OUT_CON4_RELATCH_EN_MASK, fs); 17372babb477STrevor Wu 17382babb477STrevor Wu regmap_update_bits(afe->regmap, etdm_reg.con4, mask, val); 17392babb477STrevor Wu 17402babb477STrevor Wu mask = 0; 17412babb477STrevor Wu val = 0; 17422babb477STrevor Wu 17432babb477STrevor Wu /* con5 */ 17442babb477STrevor Wu mask |= (ETDM_OUT_CON5_MASTER_LRCK_INV | ETDM_OUT_CON5_MASTER_BCK_INV | 17452babb477STrevor Wu ETDM_OUT_CON5_SLAVE_LRCK_INV | ETDM_OUT_CON5_SLAVE_BCK_INV); 17462babb477STrevor Wu if (slave_mode) { 17472babb477STrevor Wu if (etdm_data->lrck_inv) 17482babb477STrevor Wu val |= ETDM_OUT_CON5_SLAVE_LRCK_INV; 17492babb477STrevor Wu if (etdm_data->bck_inv) 17502babb477STrevor Wu val |= ETDM_OUT_CON5_SLAVE_BCK_INV; 17512babb477STrevor Wu } else { 17522babb477STrevor Wu if (etdm_data->lrck_inv) 17532babb477STrevor Wu val |= ETDM_OUT_CON5_MASTER_LRCK_INV; 17542babb477STrevor Wu if (etdm_data->bck_inv) 17552babb477STrevor Wu val |= ETDM_OUT_CON5_MASTER_BCK_INV; 17562babb477STrevor Wu } 17572babb477STrevor Wu regmap_update_bits(afe->regmap, etdm_reg.con5, mask, val); 17582babb477STrevor Wu 17592babb477STrevor Wu return 0; 17602babb477STrevor Wu } 17612babb477STrevor Wu 17622babb477STrevor Wu static int mtk_dai_etdm_mclk_configure(struct mtk_base_afe *afe, int dai_id) 17632babb477STrevor Wu { 17642babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 17652babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 17662babb477STrevor Wu struct etdm_con_reg etdm_reg; 17672babb477STrevor Wu int clk_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id); 17682babb477STrevor Wu int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id); 17692babb477STrevor Wu int apll_clk_id; 17702babb477STrevor Wu int apll; 17712babb477STrevor Wu int ret; 17722babb477STrevor Wu 17732babb477STrevor Wu if (clk_id < 0 || clkdiv_id < 0) 17742babb477STrevor Wu return -EINVAL; 17752babb477STrevor Wu 17762babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 17772babb477STrevor Wu return -EINVAL; 17782babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 17792babb477STrevor Wu 17802babb477STrevor Wu ret = get_etdm_reg(dai_id, &etdm_reg); 17812babb477STrevor Wu if (ret < 0) 17822babb477STrevor Wu return ret; 17832babb477STrevor Wu 17842babb477STrevor Wu if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT) 17852babb477STrevor Wu regmap_set_bits(afe->regmap, etdm_reg.con1, 17862babb477STrevor Wu ETDM_CON1_MCLK_OUTPUT); 17872babb477STrevor Wu else 17882babb477STrevor Wu regmap_clear_bits(afe->regmap, etdm_reg.con1, 17892babb477STrevor Wu ETDM_CON1_MCLK_OUTPUT); 17902babb477STrevor Wu 17912babb477STrevor Wu if (etdm_data->mclk_freq) { 17922babb477STrevor Wu apll = etdm_data->mclk_apll; 17932babb477STrevor Wu apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll); 17942babb477STrevor Wu if (apll_clk_id < 0) 17952babb477STrevor Wu return apll_clk_id; 17962babb477STrevor Wu 17972babb477STrevor Wu /* select apll */ 17982babb477STrevor Wu ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clk_id], 17992babb477STrevor Wu afe_priv->clk[apll_clk_id]); 18002babb477STrevor Wu if (ret) 18012babb477STrevor Wu return ret; 18022babb477STrevor Wu 18032babb477STrevor Wu /* set rate */ 18042babb477STrevor Wu ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id], 18052babb477STrevor Wu etdm_data->mclk_freq); 18062babb477STrevor Wu if (ret) 18072babb477STrevor Wu return ret; 18082babb477STrevor Wu } else { 18092babb477STrevor Wu if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT) 18102babb477STrevor Wu dev_dbg(afe->dev, "%s mclk freq = 0\n", __func__); 18112babb477STrevor Wu } 18122babb477STrevor Wu 18132babb477STrevor Wu return 0; 18142babb477STrevor Wu } 18152babb477STrevor Wu 18162babb477STrevor Wu static int mtk_dai_etdm_configure(struct mtk_base_afe *afe, 18172babb477STrevor Wu unsigned int rate, 18182babb477STrevor Wu unsigned int channels, 18192babb477STrevor Wu unsigned int bit_width, 18202babb477STrevor Wu int dai_id) 18212babb477STrevor Wu { 18222babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 18232babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 18242babb477STrevor Wu struct etdm_con_reg etdm_reg; 18252babb477STrevor Wu bool slave_mode; 18262babb477STrevor Wu unsigned int etdm_channels; 18272babb477STrevor Wu unsigned int val = 0; 18282babb477STrevor Wu unsigned int mask = 0; 18292babb477STrevor Wu unsigned int bck; 18302babb477STrevor Wu unsigned int wlen = get_etdm_wlen(bit_width); 18312babb477STrevor Wu int ret; 18322babb477STrevor Wu 18332babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 18342babb477STrevor Wu return -EINVAL; 18352babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 18362babb477STrevor Wu slave_mode = etdm_data->slave_mode; 18372babb477STrevor Wu 18382babb477STrevor Wu ret = get_etdm_reg(dai_id, &etdm_reg); 18392babb477STrevor Wu if (ret < 0) 18402babb477STrevor Wu return ret; 18412babb477STrevor Wu 18422babb477STrevor Wu dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, clock %u slv %u\n", 18432babb477STrevor Wu __func__, etdm_data->format, etdm_data->data_mode, 18442babb477STrevor Wu etdm_data->lrck_inv, etdm_data->lrck_width, etdm_data->bck_inv, 18452babb477STrevor Wu etdm_data->clock_mode, etdm_data->slave_mode); 18462babb477STrevor Wu dev_dbg(afe->dev, "%s rate %u channels %u bitwidth %u, id %d\n", 18472babb477STrevor Wu __func__, rate, channels, bit_width, dai_id); 18482babb477STrevor Wu 18492babb477STrevor Wu etdm_channels = (etdm_data->data_mode == MTK_DAI_ETDM_DATA_ONE_PIN) ? 18502babb477STrevor Wu get_etdm_ch_fixup(channels) : 2; 18512babb477STrevor Wu 18522babb477STrevor Wu bck = rate * etdm_channels * wlen; 18532babb477STrevor Wu if (bck > MT8188_ETDM_NORMAL_MAX_BCK_RATE) { 18542babb477STrevor Wu dev_err(afe->dev, "%s bck rate %u not support\n", 18552babb477STrevor Wu __func__, bck); 18562babb477STrevor Wu return -EINVAL; 18572babb477STrevor Wu } 18582babb477STrevor Wu 18592babb477STrevor Wu /* con0 */ 18602babb477STrevor Wu mask |= ETDM_CON0_BIT_LEN_MASK; 18612babb477STrevor Wu val |= FIELD_PREP(ETDM_CON0_BIT_LEN_MASK, bit_width - 1); 18622babb477STrevor Wu mask |= ETDM_CON0_WORD_LEN_MASK; 18632babb477STrevor Wu val |= FIELD_PREP(ETDM_CON0_WORD_LEN_MASK, wlen - 1); 18642babb477STrevor Wu mask |= ETDM_CON0_FORMAT_MASK; 18652babb477STrevor Wu val |= FIELD_PREP(ETDM_CON0_FORMAT_MASK, etdm_data->format); 18662babb477STrevor Wu mask |= ETDM_CON0_CH_NUM_MASK; 18672babb477STrevor Wu val |= FIELD_PREP(ETDM_CON0_CH_NUM_MASK, etdm_channels - 1); 18682babb477STrevor Wu 18692babb477STrevor Wu mask |= ETDM_CON0_SLAVE_MODE; 18702babb477STrevor Wu if (slave_mode) { 18712babb477STrevor Wu if (dai_id == MT8188_AFE_IO_ETDM1_OUT) { 18722babb477STrevor Wu dev_err(afe->dev, "%s id %d only support master mode\n", 18732babb477STrevor Wu __func__, dai_id); 18742babb477STrevor Wu return -EINVAL; 18752babb477STrevor Wu } 18762babb477STrevor Wu val |= ETDM_CON0_SLAVE_MODE; 18772babb477STrevor Wu } 18782babb477STrevor Wu regmap_update_bits(afe->regmap, etdm_reg.con0, mask, val); 18792babb477STrevor Wu 18802babb477STrevor Wu if (get_etdm_dir(dai_id) == ETDM_IN) 18812babb477STrevor Wu mtk_dai_etdm_in_configure(afe, rate, channels, dai_id); 18822babb477STrevor Wu else 18832babb477STrevor Wu mtk_dai_etdm_out_configure(afe, rate, channels, dai_id); 18842babb477STrevor Wu 18852babb477STrevor Wu return 0; 18862babb477STrevor Wu } 18872babb477STrevor Wu 18882babb477STrevor Wu static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, 18892babb477STrevor Wu struct snd_pcm_hw_params *params, 18902babb477STrevor Wu struct snd_soc_dai *dai) 18912babb477STrevor Wu { 18922babb477STrevor Wu unsigned int rate = params_rate(params); 18932babb477STrevor Wu unsigned int bit_width = params_width(params); 18942babb477STrevor Wu unsigned int channels = params_channels(params); 18952babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 18962babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 18972babb477STrevor Wu struct mtk_dai_etdm_priv *mst_etdm_data; 18982babb477STrevor Wu int mst_dai_id; 18992babb477STrevor Wu int slv_dai_id; 19002babb477STrevor Wu int ret; 19012babb477STrevor Wu int i; 19022babb477STrevor Wu 19032babb477STrevor Wu dev_dbg(afe->dev, "%s '%s' period %u-%u\n", 19042babb477STrevor Wu __func__, snd_pcm_stream_str(substream), 19052babb477STrevor Wu params_period_size(params), params_periods(params)); 19062babb477STrevor Wu 19072babb477STrevor Wu if (is_cowork_mode(dai)) { 19082babb477STrevor Wu mst_dai_id = get_etdm_cowork_master_id(dai); 19092babb477STrevor Wu if (!is_valid_etdm_dai(mst_dai_id)) 19102babb477STrevor Wu return -EINVAL; 19112babb477STrevor Wu 1912*2664c879STrevor Wu mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; 1913*2664c879STrevor Wu if (mst_etdm_data->slots) 1914*2664c879STrevor Wu channels = mst_etdm_data->slots; 1915*2664c879STrevor Wu 19162babb477STrevor Wu ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id); 19172babb477STrevor Wu if (ret) 19182babb477STrevor Wu return ret; 19192babb477STrevor Wu 19202babb477STrevor Wu ret = mtk_dai_etdm_configure(afe, rate, channels, 19212babb477STrevor Wu bit_width, mst_dai_id); 19222babb477STrevor Wu if (ret) 19232babb477STrevor Wu return ret; 19242babb477STrevor Wu 19252babb477STrevor Wu for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) { 19262babb477STrevor Wu slv_dai_id = mst_etdm_data->cowork_slv_id[i]; 19272babb477STrevor Wu ret = mtk_dai_etdm_configure(afe, rate, channels, 19282babb477STrevor Wu bit_width, slv_dai_id); 19292babb477STrevor Wu if (ret) 19302babb477STrevor Wu return ret; 19312babb477STrevor Wu 19322babb477STrevor Wu ret = mt8188_etdm_sync_mode_configure(afe, slv_dai_id); 19332babb477STrevor Wu if (ret) 19342babb477STrevor Wu return ret; 19352babb477STrevor Wu } 19362babb477STrevor Wu } else { 1937*2664c879STrevor Wu if (!is_valid_etdm_dai(dai->id)) 1938*2664c879STrevor Wu return -EINVAL; 1939*2664c879STrevor Wu mst_etdm_data = afe_priv->dai_priv[dai->id]; 1940*2664c879STrevor Wu if (mst_etdm_data->slots) 1941*2664c879STrevor Wu channels = mst_etdm_data->slots; 1942*2664c879STrevor Wu 19432babb477STrevor Wu ret = mtk_dai_etdm_mclk_configure(afe, dai->id); 19442babb477STrevor Wu if (ret) 19452babb477STrevor Wu return ret; 19462babb477STrevor Wu 19472babb477STrevor Wu ret = mtk_dai_etdm_configure(afe, rate, channels, 19482babb477STrevor Wu bit_width, dai->id); 19492babb477STrevor Wu if (ret) 19502babb477STrevor Wu return ret; 19512babb477STrevor Wu } 19522babb477STrevor Wu 19532babb477STrevor Wu return 0; 19542babb477STrevor Wu } 19552babb477STrevor Wu 19562babb477STrevor Wu static int mtk_dai_etdm_prepare(struct snd_pcm_substream *substream, 19572babb477STrevor Wu struct snd_soc_dai *dai) 19582babb477STrevor Wu { 19592babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 19602babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 19612babb477STrevor Wu struct mtk_dai_etdm_priv *mst_etdm_data; 19622babb477STrevor Wu int mst_dai_id; 19632babb477STrevor Wu int slv_dai_id; 19642babb477STrevor Wu int ret; 19652babb477STrevor Wu int i; 19662babb477STrevor Wu 19672babb477STrevor Wu if (!is_valid_etdm_dai(dai->id)) 19682babb477STrevor Wu return -EINVAL; 19692babb477STrevor Wu mst_etdm_data = afe_priv->dai_priv[dai->id]; 19702babb477STrevor Wu 19712babb477STrevor Wu dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id, 19722babb477STrevor Wu mst_etdm_data->is_prepared); 19732babb477STrevor Wu 19742babb477STrevor Wu if (mst_etdm_data->is_prepared) 19752babb477STrevor Wu return 0; 19762babb477STrevor Wu 19772babb477STrevor Wu mst_etdm_data->is_prepared = true; 19782babb477STrevor Wu 19792babb477STrevor Wu if (is_cowork_mode(dai)) { 19802babb477STrevor Wu mst_dai_id = get_etdm_cowork_master_id(dai); 19812babb477STrevor Wu if (!is_valid_etdm_dai(mst_dai_id)) 19822babb477STrevor Wu return -EINVAL; 19832babb477STrevor Wu mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; 19842babb477STrevor Wu 19852babb477STrevor Wu for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) { 19862babb477STrevor Wu slv_dai_id = mst_etdm_data->cowork_slv_id[i]; 19872babb477STrevor Wu ret = mt8188_afe_enable_etdm(afe, slv_dai_id); 19882babb477STrevor Wu if (ret) { 19892babb477STrevor Wu dev_dbg(afe->dev, "%s enable %d failed\n", 19902babb477STrevor Wu __func__, slv_dai_id); 19912babb477STrevor Wu 19922babb477STrevor Wu return ret; 19932babb477STrevor Wu } 19942babb477STrevor Wu } 19952babb477STrevor Wu 19962babb477STrevor Wu ret = mt8188_afe_enable_etdm(afe, mst_dai_id); 19972babb477STrevor Wu if (ret) { 19982babb477STrevor Wu dev_dbg(afe->dev, "%s enable %d failed\n", 19992babb477STrevor Wu __func__, mst_dai_id); 20002babb477STrevor Wu 20012babb477STrevor Wu return ret; 20022babb477STrevor Wu } 20032babb477STrevor Wu } else { 20042babb477STrevor Wu ret = mt8188_afe_enable_etdm(afe, dai->id); 20052babb477STrevor Wu if (ret) { 20062babb477STrevor Wu dev_dbg(afe->dev, "%s enable %d failed\n", 20072babb477STrevor Wu __func__, dai->id); 20082babb477STrevor Wu 20092babb477STrevor Wu return ret; 20102babb477STrevor Wu } 20112babb477STrevor Wu } 20122babb477STrevor Wu 20132babb477STrevor Wu return 0; 20142babb477STrevor Wu } 20152babb477STrevor Wu 20162babb477STrevor Wu static int mtk_dai_etdm_cal_mclk(struct mtk_base_afe *afe, int freq, int dai_id) 20172babb477STrevor Wu { 20182babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 20192babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 20202babb477STrevor Wu int apll_rate; 20212babb477STrevor Wu int apll; 20222babb477STrevor Wu 20232babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 20242babb477STrevor Wu return -EINVAL; 20252babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 20262babb477STrevor Wu 20272babb477STrevor Wu if (freq == 0) { 20282babb477STrevor Wu etdm_data->mclk_freq = freq; 20292babb477STrevor Wu return 0; 20302babb477STrevor Wu } 20312babb477STrevor Wu 20322babb477STrevor Wu if (etdm_data->mclk_fixed_apll == 0) 20332babb477STrevor Wu apll = mt8188_afe_get_default_mclk_source_by_rate(freq); 20342babb477STrevor Wu else 20352babb477STrevor Wu apll = etdm_data->mclk_apll; 20362babb477STrevor Wu 20372babb477STrevor Wu apll_rate = mt8188_afe_get_mclk_source_rate(afe, apll); 20382babb477STrevor Wu 20392babb477STrevor Wu if (freq > apll_rate) { 20402babb477STrevor Wu dev_err(afe->dev, "freq %d > apll rate %d\n", freq, apll_rate); 20412babb477STrevor Wu return -EINVAL; 20422babb477STrevor Wu } 20432babb477STrevor Wu 20442babb477STrevor Wu if (apll_rate % freq != 0) { 20452babb477STrevor Wu dev_err(afe->dev, "APLL%d cannot generate freq Hz\n", apll); 20462babb477STrevor Wu return -EINVAL; 20472babb477STrevor Wu } 20482babb477STrevor Wu 20492babb477STrevor Wu if (etdm_data->mclk_fixed_apll == 0) 20502babb477STrevor Wu etdm_data->mclk_apll = apll; 20512babb477STrevor Wu etdm_data->mclk_freq = freq; 20522babb477STrevor Wu 20532babb477STrevor Wu return 0; 20542babb477STrevor Wu } 20552babb477STrevor Wu 20562babb477STrevor Wu static int mtk_dai_etdm_set_sysclk(struct snd_soc_dai *dai, 20572babb477STrevor Wu int clk_id, unsigned int freq, int dir) 20582babb477STrevor Wu { 20592babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 20602babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 20612babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 20622babb477STrevor Wu int dai_id; 20632babb477STrevor Wu 20642babb477STrevor Wu dev_dbg(dai->dev, "%s id %d freq %u, dir %d\n", 20652babb477STrevor Wu __func__, dai->id, freq, dir); 20662babb477STrevor Wu if (is_cowork_mode(dai)) 20672babb477STrevor Wu dai_id = get_etdm_cowork_master_id(dai); 20682babb477STrevor Wu else 20692babb477STrevor Wu dai_id = dai->id; 20702babb477STrevor Wu 20712babb477STrevor Wu if (!is_valid_etdm_dai(dai_id)) 20722babb477STrevor Wu return -EINVAL; 20732babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 20742babb477STrevor Wu etdm_data->mclk_dir = dir; 20752babb477STrevor Wu return mtk_dai_etdm_cal_mclk(afe, freq, dai_id); 20762babb477STrevor Wu } 20772babb477STrevor Wu 20782babb477STrevor Wu static int mtk_dai_etdm_set_tdm_slot(struct snd_soc_dai *dai, 20792babb477STrevor Wu unsigned int tx_mask, unsigned int rx_mask, 20802babb477STrevor Wu int slots, int slot_width) 20812babb477STrevor Wu { 20822babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 20832babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 20842babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 2085*2664c879STrevor Wu int dai_id; 20862babb477STrevor Wu 2087*2664c879STrevor Wu if (is_cowork_mode(dai)) 2088*2664c879STrevor Wu dai_id = get_etdm_cowork_master_id(dai); 2089*2664c879STrevor Wu else 2090*2664c879STrevor Wu dai_id = dai->id; 2091*2664c879STrevor Wu 2092*2664c879STrevor Wu if (!is_valid_etdm_dai(dai_id)) 20932babb477STrevor Wu return -EINVAL; 2094*2664c879STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 20952babb477STrevor Wu 20962babb477STrevor Wu dev_dbg(dai->dev, "%s id %d slot_width %d\n", 20972babb477STrevor Wu __func__, dai->id, slot_width); 20982babb477STrevor Wu 20992babb477STrevor Wu etdm_data->slots = slots; 21002babb477STrevor Wu etdm_data->lrck_width = slot_width; 21012babb477STrevor Wu return 0; 21022babb477STrevor Wu } 21032babb477STrevor Wu 21042babb477STrevor Wu static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 21052babb477STrevor Wu { 21062babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 21072babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 21082babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 21092babb477STrevor Wu 21102babb477STrevor Wu if (!is_valid_etdm_dai(dai->id)) 21112babb477STrevor Wu return -EINVAL; 21122babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai->id]; 21132babb477STrevor Wu 21142babb477STrevor Wu switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 21152babb477STrevor Wu case SND_SOC_DAIFMT_I2S: 21162babb477STrevor Wu etdm_data->format = MTK_DAI_ETDM_FORMAT_I2S; 21172babb477STrevor Wu break; 21182babb477STrevor Wu case SND_SOC_DAIFMT_LEFT_J: 21192babb477STrevor Wu etdm_data->format = MTK_DAI_ETDM_FORMAT_LJ; 21202babb477STrevor Wu break; 21212babb477STrevor Wu case SND_SOC_DAIFMT_RIGHT_J: 21222babb477STrevor Wu etdm_data->format = MTK_DAI_ETDM_FORMAT_RJ; 21232babb477STrevor Wu break; 21242babb477STrevor Wu case SND_SOC_DAIFMT_DSP_A: 21252babb477STrevor Wu etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPA; 21262babb477STrevor Wu break; 21272babb477STrevor Wu case SND_SOC_DAIFMT_DSP_B: 21282babb477STrevor Wu etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPB; 21292babb477STrevor Wu break; 21302babb477STrevor Wu default: 21312babb477STrevor Wu return -EINVAL; 21322babb477STrevor Wu } 21332babb477STrevor Wu 21342babb477STrevor Wu switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 21352babb477STrevor Wu case SND_SOC_DAIFMT_NB_NF: 21362babb477STrevor Wu etdm_data->bck_inv = false; 21372babb477STrevor Wu etdm_data->lrck_inv = false; 21382babb477STrevor Wu break; 21392babb477STrevor Wu case SND_SOC_DAIFMT_NB_IF: 21402babb477STrevor Wu etdm_data->bck_inv = false; 21412babb477STrevor Wu etdm_data->lrck_inv = true; 21422babb477STrevor Wu break; 21432babb477STrevor Wu case SND_SOC_DAIFMT_IB_NF: 21442babb477STrevor Wu etdm_data->bck_inv = true; 21452babb477STrevor Wu etdm_data->lrck_inv = false; 21462babb477STrevor Wu break; 21472babb477STrevor Wu case SND_SOC_DAIFMT_IB_IF: 21482babb477STrevor Wu etdm_data->bck_inv = true; 21492babb477STrevor Wu etdm_data->lrck_inv = true; 21502babb477STrevor Wu break; 21512babb477STrevor Wu default: 21522babb477STrevor Wu return -EINVAL; 21532babb477STrevor Wu } 21542babb477STrevor Wu 21552babb477STrevor Wu switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 21562babb477STrevor Wu case SND_SOC_DAIFMT_BC_FC: 21572babb477STrevor Wu etdm_data->slave_mode = true; 21582babb477STrevor Wu break; 21592babb477STrevor Wu case SND_SOC_DAIFMT_BP_FP: 21602babb477STrevor Wu etdm_data->slave_mode = false; 21612babb477STrevor Wu break; 21622babb477STrevor Wu default: 21632babb477STrevor Wu return -EINVAL; 21642babb477STrevor Wu } 21652babb477STrevor Wu 21662babb477STrevor Wu return 0; 21672babb477STrevor Wu } 21682babb477STrevor Wu 21692babb477STrevor Wu static int mtk_dai_hdmitx_dptx_startup(struct snd_pcm_substream *substream, 21702babb477STrevor Wu struct snd_soc_dai *dai) 21712babb477STrevor Wu { 21722babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 21732babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 21742babb477STrevor Wu int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id); 21752babb477STrevor Wu 21762babb477STrevor Wu if (cg_id >= 0) 21772babb477STrevor Wu mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]); 21782babb477STrevor Wu 21792babb477STrevor Wu mtk_dai_etdm_enable_mclk(afe, dai->id); 21802babb477STrevor Wu 21812babb477STrevor Wu return 0; 21822babb477STrevor Wu } 21832babb477STrevor Wu 21842babb477STrevor Wu static void mtk_dai_hdmitx_dptx_shutdown(struct snd_pcm_substream *substream, 21852babb477STrevor Wu struct snd_soc_dai *dai) 21862babb477STrevor Wu { 21872babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 21882babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 21892babb477STrevor Wu int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id); 21902babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 21912babb477STrevor Wu int ret; 21922babb477STrevor Wu 21932babb477STrevor Wu if (!is_valid_etdm_dai(dai->id)) 21942babb477STrevor Wu return; 21952babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai->id]; 21962babb477STrevor Wu 21972babb477STrevor Wu if (etdm_data->is_prepared) { 21982babb477STrevor Wu etdm_data->is_prepared = false; 21992babb477STrevor Wu /* disable etdm_out3 */ 22002babb477STrevor Wu ret = mt8188_afe_disable_etdm(afe, dai->id); 22012babb477STrevor Wu if (ret) 22022babb477STrevor Wu dev_dbg(afe->dev, "%s disable failed\n", __func__); 22032babb477STrevor Wu 22042babb477STrevor Wu /* disable dptx interface */ 22052babb477STrevor Wu if (dai->id == MT8188_AFE_IO_DPTX) 22062babb477STrevor Wu regmap_clear_bits(afe->regmap, AFE_DPTX_CON, 22072babb477STrevor Wu AFE_DPTX_CON_ON); 22082babb477STrevor Wu } 22092babb477STrevor Wu 22102babb477STrevor Wu mtk_dai_etdm_disable_mclk(afe, dai->id); 22112babb477STrevor Wu 22122babb477STrevor Wu if (cg_id >= 0) 22132babb477STrevor Wu mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]); 22142babb477STrevor Wu } 22152babb477STrevor Wu 22162babb477STrevor Wu static unsigned int mtk_dai_get_dptx_ch_en(unsigned int channel) 22172babb477STrevor Wu { 22182babb477STrevor Wu switch (channel) { 22192babb477STrevor Wu case 1 ... 2: 22202babb477STrevor Wu return AFE_DPTX_CON_CH_EN_2CH; 22212babb477STrevor Wu case 3 ... 4: 22222babb477STrevor Wu return AFE_DPTX_CON_CH_EN_4CH; 22232babb477STrevor Wu case 5 ... 6: 22242babb477STrevor Wu return AFE_DPTX_CON_CH_EN_6CH; 22252babb477STrevor Wu case 7 ... 8: 22262babb477STrevor Wu return AFE_DPTX_CON_CH_EN_8CH; 22272babb477STrevor Wu default: 22282babb477STrevor Wu return AFE_DPTX_CON_CH_EN_2CH; 22292babb477STrevor Wu } 22302babb477STrevor Wu } 22312babb477STrevor Wu 22322babb477STrevor Wu static unsigned int mtk_dai_get_dptx_ch(unsigned int ch) 22332babb477STrevor Wu { 22342babb477STrevor Wu return (ch > 2) ? 22352babb477STrevor Wu AFE_DPTX_CON_CH_NUM_8CH : AFE_DPTX_CON_CH_NUM_2CH; 22362babb477STrevor Wu } 22372babb477STrevor Wu 22382babb477STrevor Wu static unsigned int mtk_dai_get_dptx_wlen(snd_pcm_format_t format) 22392babb477STrevor Wu { 22402babb477STrevor Wu return snd_pcm_format_physical_width(format) <= 16 ? 22412babb477STrevor Wu AFE_DPTX_CON_16BIT : AFE_DPTX_CON_24BIT; 22422babb477STrevor Wu } 22432babb477STrevor Wu 22442babb477STrevor Wu static int mtk_dai_hdmitx_dptx_hw_params(struct snd_pcm_substream *substream, 22452babb477STrevor Wu struct snd_pcm_hw_params *params, 22462babb477STrevor Wu struct snd_soc_dai *dai) 22472babb477STrevor Wu { 22482babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 22492babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 22502babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 22512babb477STrevor Wu unsigned int rate = params_rate(params); 22522babb477STrevor Wu unsigned int channels = params_channels(params); 22532babb477STrevor Wu snd_pcm_format_t format = params_format(params); 22542babb477STrevor Wu int width = snd_pcm_format_physical_width(format); 22552babb477STrevor Wu int ret; 22562babb477STrevor Wu 22572babb477STrevor Wu if (!is_valid_etdm_dai(dai->id)) 22582babb477STrevor Wu return -EINVAL; 22592babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai->id]; 22602babb477STrevor Wu 22612babb477STrevor Wu /* dptx configure */ 22622babb477STrevor Wu if (dai->id == MT8188_AFE_IO_DPTX) { 22632babb477STrevor Wu regmap_update_bits(afe->regmap, AFE_DPTX_CON, 22642babb477STrevor Wu AFE_DPTX_CON_CH_EN_MASK, 22652babb477STrevor Wu mtk_dai_get_dptx_ch_en(channels)); 22662babb477STrevor Wu regmap_update_bits(afe->regmap, AFE_DPTX_CON, 22672babb477STrevor Wu AFE_DPTX_CON_CH_NUM_MASK, 22682babb477STrevor Wu mtk_dai_get_dptx_ch(channels)); 22692babb477STrevor Wu regmap_update_bits(afe->regmap, AFE_DPTX_CON, 22702babb477STrevor Wu AFE_DPTX_CON_16BIT_MASK, 22712babb477STrevor Wu mtk_dai_get_dptx_wlen(format)); 22722babb477STrevor Wu 22732babb477STrevor Wu if (mtk_dai_get_dptx_ch(channels) == AFE_DPTX_CON_CH_NUM_8CH) { 22742babb477STrevor Wu etdm_data->data_mode = MTK_DAI_ETDM_DATA_ONE_PIN; 22752babb477STrevor Wu channels = 8; 22762babb477STrevor Wu } else { 22772babb477STrevor Wu channels = 2; 22782babb477STrevor Wu } 22792babb477STrevor Wu } else { 22802babb477STrevor Wu etdm_data->data_mode = MTK_DAI_ETDM_DATA_MULTI_PIN; 22812babb477STrevor Wu } 22822babb477STrevor Wu 22832babb477STrevor Wu ret = mtk_dai_etdm_mclk_configure(afe, dai->id); 22842babb477STrevor Wu if (ret) 22852babb477STrevor Wu return ret; 22862babb477STrevor Wu 22872babb477STrevor Wu ret = mtk_dai_etdm_configure(afe, rate, channels, width, dai->id); 22882babb477STrevor Wu 22892babb477STrevor Wu return ret; 22902babb477STrevor Wu } 22912babb477STrevor Wu 22922babb477STrevor Wu static int mtk_dai_hdmitx_dptx_prepare(struct snd_pcm_substream *substream, 22932babb477STrevor Wu struct snd_soc_dai *dai) 22942babb477STrevor Wu { 22952babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 22962babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 22972babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 22982babb477STrevor Wu 22992babb477STrevor Wu if (!is_valid_etdm_dai(dai->id)) 23002babb477STrevor Wu return -EINVAL; 23012babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai->id]; 23022babb477STrevor Wu 23032babb477STrevor Wu dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id, 23042babb477STrevor Wu etdm_data->is_prepared); 23052babb477STrevor Wu 23062babb477STrevor Wu if (etdm_data->is_prepared) 23072babb477STrevor Wu return 0; 23082babb477STrevor Wu 23092babb477STrevor Wu etdm_data->is_prepared = true; 23102babb477STrevor Wu 23112babb477STrevor Wu /* enable dptx interface */ 23122babb477STrevor Wu if (dai->id == MT8188_AFE_IO_DPTX) 23132babb477STrevor Wu regmap_set_bits(afe->regmap, AFE_DPTX_CON, AFE_DPTX_CON_ON); 23142babb477STrevor Wu 23152babb477STrevor Wu /* enable etdm_out3 */ 23162babb477STrevor Wu return mt8188_afe_enable_etdm(afe, dai->id); 23172babb477STrevor Wu } 23182babb477STrevor Wu 23192babb477STrevor Wu static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai, 23202babb477STrevor Wu int clk_id, 23212babb477STrevor Wu unsigned int freq, 23222babb477STrevor Wu int dir) 23232babb477STrevor Wu { 23242babb477STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 23252babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 23262babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 23272babb477STrevor Wu 23282babb477STrevor Wu if (!is_valid_etdm_dai(dai->id)) 23292babb477STrevor Wu return -EINVAL; 23302babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai->id]; 23312babb477STrevor Wu 23322babb477STrevor Wu dev_dbg(dai->dev, "%s id %d freq %u, dir %d\n", 23332babb477STrevor Wu __func__, dai->id, freq, dir); 23342babb477STrevor Wu 23352babb477STrevor Wu etdm_data->mclk_dir = dir; 23362babb477STrevor Wu return mtk_dai_etdm_cal_mclk(afe, freq, dai->id); 23372babb477STrevor Wu } 23382babb477STrevor Wu 23392babb477STrevor Wu static const struct snd_soc_dai_ops mtk_dai_etdm_ops = { 23402babb477STrevor Wu .startup = mtk_dai_etdm_startup, 23412babb477STrevor Wu .shutdown = mtk_dai_etdm_shutdown, 23422babb477STrevor Wu .hw_params = mtk_dai_etdm_hw_params, 23432babb477STrevor Wu .prepare = mtk_dai_etdm_prepare, 23442babb477STrevor Wu .set_sysclk = mtk_dai_etdm_set_sysclk, 23452babb477STrevor Wu .set_fmt = mtk_dai_etdm_set_fmt, 23462babb477STrevor Wu .set_tdm_slot = mtk_dai_etdm_set_tdm_slot, 23472babb477STrevor Wu }; 23482babb477STrevor Wu 23492babb477STrevor Wu static const struct snd_soc_dai_ops mtk_dai_hdmitx_dptx_ops = { 23502babb477STrevor Wu .startup = mtk_dai_hdmitx_dptx_startup, 23512babb477STrevor Wu .shutdown = mtk_dai_hdmitx_dptx_shutdown, 23522babb477STrevor Wu .hw_params = mtk_dai_hdmitx_dptx_hw_params, 23532babb477STrevor Wu .prepare = mtk_dai_hdmitx_dptx_prepare, 23542babb477STrevor Wu .set_sysclk = mtk_dai_hdmitx_dptx_set_sysclk, 23552babb477STrevor Wu .set_fmt = mtk_dai_etdm_set_fmt, 23562babb477STrevor Wu }; 23572babb477STrevor Wu 23582babb477STrevor Wu /* dai driver */ 23592babb477STrevor Wu #define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_192000) 23602babb477STrevor Wu 23612babb477STrevor Wu #define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 23622babb477STrevor Wu SNDRV_PCM_FMTBIT_S24_LE |\ 23632babb477STrevor Wu SNDRV_PCM_FMTBIT_S32_LE) 23642babb477STrevor Wu 23652babb477STrevor Wu static struct snd_soc_dai_driver mtk_dai_etdm_driver[] = { 23662babb477STrevor Wu { 23672babb477STrevor Wu .name = "DPTX", 23682babb477STrevor Wu .id = MT8188_AFE_IO_DPTX, 23692babb477STrevor Wu .playback = { 23702babb477STrevor Wu .stream_name = "DPTX", 23712babb477STrevor Wu .channels_min = 1, 23722babb477STrevor Wu .channels_max = 8, 23732babb477STrevor Wu .rates = MTK_ETDM_RATES, 23742babb477STrevor Wu .formats = MTK_ETDM_FORMATS, 23752babb477STrevor Wu }, 23762babb477STrevor Wu .ops = &mtk_dai_hdmitx_dptx_ops, 23772babb477STrevor Wu }, 23782babb477STrevor Wu { 23792babb477STrevor Wu .name = "ETDM1_IN", 23802babb477STrevor Wu .id = MT8188_AFE_IO_ETDM1_IN, 23812babb477STrevor Wu .capture = { 23822babb477STrevor Wu .stream_name = "ETDM1_IN", 23832babb477STrevor Wu .channels_min = 1, 23842babb477STrevor Wu .channels_max = 16, 23852babb477STrevor Wu .rates = MTK_ETDM_RATES, 23862babb477STrevor Wu .formats = MTK_ETDM_FORMATS, 23872babb477STrevor Wu }, 23882babb477STrevor Wu .ops = &mtk_dai_etdm_ops, 23892babb477STrevor Wu }, 23902babb477STrevor Wu { 23912babb477STrevor Wu .name = "ETDM2_IN", 23922babb477STrevor Wu .id = MT8188_AFE_IO_ETDM2_IN, 23932babb477STrevor Wu .capture = { 23942babb477STrevor Wu .stream_name = "ETDM2_IN", 23952babb477STrevor Wu .channels_min = 1, 23962babb477STrevor Wu .channels_max = 16, 23972babb477STrevor Wu .rates = MTK_ETDM_RATES, 23982babb477STrevor Wu .formats = MTK_ETDM_FORMATS, 23992babb477STrevor Wu }, 24002babb477STrevor Wu .ops = &mtk_dai_etdm_ops, 24012babb477STrevor Wu }, 24022babb477STrevor Wu { 24032babb477STrevor Wu .name = "ETDM1_OUT", 24042babb477STrevor Wu .id = MT8188_AFE_IO_ETDM1_OUT, 24052babb477STrevor Wu .playback = { 24062babb477STrevor Wu .stream_name = "ETDM1_OUT", 24072babb477STrevor Wu .channels_min = 1, 24082babb477STrevor Wu .channels_max = 16, 24092babb477STrevor Wu .rates = MTK_ETDM_RATES, 24102babb477STrevor Wu .formats = MTK_ETDM_FORMATS, 24112babb477STrevor Wu }, 24122babb477STrevor Wu .ops = &mtk_dai_etdm_ops, 24132babb477STrevor Wu }, 24142babb477STrevor Wu { 24152babb477STrevor Wu .name = "ETDM2_OUT", 24162babb477STrevor Wu .id = MT8188_AFE_IO_ETDM2_OUT, 24172babb477STrevor Wu .playback = { 24182babb477STrevor Wu .stream_name = "ETDM2_OUT", 24192babb477STrevor Wu .channels_min = 1, 24202babb477STrevor Wu .channels_max = 16, 24212babb477STrevor Wu .rates = MTK_ETDM_RATES, 24222babb477STrevor Wu .formats = MTK_ETDM_FORMATS, 24232babb477STrevor Wu }, 24242babb477STrevor Wu .ops = &mtk_dai_etdm_ops, 24252babb477STrevor Wu }, 24262babb477STrevor Wu { 24272babb477STrevor Wu .name = "ETDM3_OUT", 24282babb477STrevor Wu .id = MT8188_AFE_IO_ETDM3_OUT, 24292babb477STrevor Wu .playback = { 24302babb477STrevor Wu .stream_name = "ETDM3_OUT", 24312babb477STrevor Wu .channels_min = 1, 24322babb477STrevor Wu .channels_max = 8, 24332babb477STrevor Wu .rates = MTK_ETDM_RATES, 24342babb477STrevor Wu .formats = MTK_ETDM_FORMATS, 24352babb477STrevor Wu }, 24362babb477STrevor Wu .ops = &mtk_dai_hdmitx_dptx_ops, 24372babb477STrevor Wu }, 24382babb477STrevor Wu }; 24392babb477STrevor Wu 24402babb477STrevor Wu static void mt8188_etdm_update_sync_info(struct mtk_base_afe *afe) 24412babb477STrevor Wu { 24422babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 24432babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 24442babb477STrevor Wu struct mtk_dai_etdm_priv *mst_data; 24452babb477STrevor Wu int mst_dai_id; 24462babb477STrevor Wu int i; 24472babb477STrevor Wu 24482babb477STrevor Wu for (i = MT8188_AFE_IO_ETDM_START; i < MT8188_AFE_IO_ETDM_END; i++) { 24492babb477STrevor Wu etdm_data = afe_priv->dai_priv[i]; 24502babb477STrevor Wu if (etdm_data->cowork_source_id != COWORK_ETDM_NONE) { 24512babb477STrevor Wu mst_dai_id = etdm_data->cowork_source_id; 24522babb477STrevor Wu mst_data = afe_priv->dai_priv[mst_dai_id]; 24532babb477STrevor Wu if (mst_data->cowork_source_id != COWORK_ETDM_NONE) 24542babb477STrevor Wu dev_err(afe->dev, "%s [%d] wrong sync source\n", 24552babb477STrevor Wu __func__, i); 24562babb477STrevor Wu mst_data->cowork_slv_id[mst_data->cowork_slv_count] = i; 24572babb477STrevor Wu mst_data->cowork_slv_count++; 24582babb477STrevor Wu } 24592babb477STrevor Wu } 24602babb477STrevor Wu } 24612babb477STrevor Wu 24622babb477STrevor Wu static void mt8188_dai_etdm_parse_of(struct mtk_base_afe *afe) 24632babb477STrevor Wu { 24642babb477STrevor Wu const struct device_node *of_node = afe->dev->of_node; 24652babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 24662babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_data; 24672babb477STrevor Wu char prop[48]; 24682babb477STrevor Wu u8 disable_chn[MT8188_ETDM_MAX_CHANNELS]; 24692babb477STrevor Wu int max_chn = MT8188_ETDM_MAX_CHANNELS; 24702babb477STrevor Wu unsigned int sync_id; 24712babb477STrevor Wu u32 sel; 24722babb477STrevor Wu int ret; 24732babb477STrevor Wu int dai_id; 24742babb477STrevor Wu int i, j; 24752babb477STrevor Wu struct { 24762babb477STrevor Wu const char *name; 24772babb477STrevor Wu const unsigned int sync_id; 24782babb477STrevor Wu } of_afe_etdms[MT8188_AFE_IO_ETDM_NUM] = { 24792babb477STrevor Wu {"etdm-in1", ETDM_SYNC_FROM_IN1}, 24802babb477STrevor Wu {"etdm-in2", ETDM_SYNC_FROM_IN2}, 24812babb477STrevor Wu {"etdm-out1", ETDM_SYNC_FROM_OUT1}, 24822babb477STrevor Wu {"etdm-out2", ETDM_SYNC_FROM_OUT2}, 24832babb477STrevor Wu {"etdm-out3", ETDM_SYNC_FROM_OUT3}, 24842babb477STrevor Wu }; 24852babb477STrevor Wu 24862babb477STrevor Wu for (i = 0; i < MT8188_AFE_IO_ETDM_NUM; i++) { 24872babb477STrevor Wu dai_id = ETDM_TO_DAI_ID(i); 24882babb477STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 24892babb477STrevor Wu 249066b9e94cSTrevor Wu snprintf(prop, sizeof(prop), "mediatek,%s-multi-pin-mode", 24912babb477STrevor Wu of_afe_etdms[i].name); 249266b9e94cSTrevor Wu 24932babb477STrevor Wu etdm_data->data_mode = of_property_read_bool(of_node, prop); 24942babb477STrevor Wu 249566b9e94cSTrevor Wu snprintf(prop, sizeof(prop), "mediatek,%s-cowork-source", 24962babb477STrevor Wu of_afe_etdms[i].name); 249766b9e94cSTrevor Wu 24982babb477STrevor Wu ret = of_property_read_u32(of_node, prop, &sel); 24992babb477STrevor Wu if (ret == 0) { 25002babb477STrevor Wu if (sel >= MT8188_AFE_IO_ETDM_NUM) { 25012babb477STrevor Wu dev_err(afe->dev, "%s invalid id=%d\n", 25022babb477STrevor Wu __func__, sel); 25032babb477STrevor Wu etdm_data->cowork_source_id = COWORK_ETDM_NONE; 25042babb477STrevor Wu } else { 25052babb477STrevor Wu sync_id = of_afe_etdms[sel].sync_id; 25062babb477STrevor Wu etdm_data->cowork_source_id = 25072babb477STrevor Wu sync_to_dai_id(sync_id); 25082babb477STrevor Wu } 25092babb477STrevor Wu } else { 25102babb477STrevor Wu etdm_data->cowork_source_id = COWORK_ETDM_NONE; 25112babb477STrevor Wu } 25122babb477STrevor Wu } 25132babb477STrevor Wu 25142babb477STrevor Wu /* etdm in only */ 25152babb477STrevor Wu for (i = 0; i < 2; i++) { 251623badca4STrevor Wu dai_id = ETDM_TO_DAI_ID(i); 251723badca4STrevor Wu etdm_data = afe_priv->dai_priv[dai_id]; 251823badca4STrevor Wu 251966b9e94cSTrevor Wu snprintf(prop, sizeof(prop), "mediatek,%s-chn-disabled", 25202babb477STrevor Wu of_afe_etdms[i].name); 252166b9e94cSTrevor Wu 25222babb477STrevor Wu ret = of_property_read_variable_u8_array(of_node, prop, 25232babb477STrevor Wu disable_chn, 25242babb477STrevor Wu 1, max_chn); 25252babb477STrevor Wu if (ret < 0) 25262babb477STrevor Wu continue; 25272babb477STrevor Wu 25282babb477STrevor Wu for (j = 0; j < ret; j++) { 25292babb477STrevor Wu if (disable_chn[j] >= MT8188_ETDM_MAX_CHANNELS) 25302babb477STrevor Wu dev_err(afe->dev, "%s [%d] invalid chn %u\n", 25312babb477STrevor Wu __func__, j, disable_chn[j]); 25322babb477STrevor Wu else 25332babb477STrevor Wu etdm_data->in_disable_ch[disable_chn[j]] = true; 25342babb477STrevor Wu } 25352babb477STrevor Wu } 25362babb477STrevor Wu mt8188_etdm_update_sync_info(afe); 25372babb477STrevor Wu } 25382babb477STrevor Wu 25392babb477STrevor Wu static int init_etdm_priv_data(struct mtk_base_afe *afe) 25402babb477STrevor Wu { 25412babb477STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv; 25422babb477STrevor Wu struct mtk_dai_etdm_priv *etdm_priv; 25432babb477STrevor Wu int i; 25442babb477STrevor Wu 25452babb477STrevor Wu for (i = MT8188_AFE_IO_ETDM_START; i < MT8188_AFE_IO_ETDM_END; i++) { 25462babb477STrevor Wu etdm_priv = devm_kzalloc(afe->dev, 25472babb477STrevor Wu sizeof(struct mtk_dai_etdm_priv), 25482babb477STrevor Wu GFP_KERNEL); 25492babb477STrevor Wu if (!etdm_priv) 25502babb477STrevor Wu return -ENOMEM; 25512babb477STrevor Wu 25522babb477STrevor Wu afe_priv->dai_priv[i] = etdm_priv; 25532babb477STrevor Wu } 25542babb477STrevor Wu 25552babb477STrevor Wu afe_priv->dai_priv[MT8188_AFE_IO_DPTX] = 25562babb477STrevor Wu afe_priv->dai_priv[MT8188_AFE_IO_ETDM3_OUT]; 25572babb477STrevor Wu 25582babb477STrevor Wu mt8188_dai_etdm_parse_of(afe); 25592babb477STrevor Wu return 0; 25602babb477STrevor Wu } 25612babb477STrevor Wu 25622babb477STrevor Wu int mt8188_dai_etdm_register(struct mtk_base_afe *afe) 25632babb477STrevor Wu { 25642babb477STrevor Wu struct mtk_base_afe_dai *dai; 25652babb477STrevor Wu 25662babb477STrevor Wu dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 25672babb477STrevor Wu if (!dai) 25682babb477STrevor Wu return -ENOMEM; 25692babb477STrevor Wu 25702babb477STrevor Wu list_add(&dai->list, &afe->sub_dais); 25712babb477STrevor Wu 25722babb477STrevor Wu dai->dai_drivers = mtk_dai_etdm_driver; 25732babb477STrevor Wu dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_etdm_driver); 25742babb477STrevor Wu 25752babb477STrevor Wu dai->dapm_widgets = mtk_dai_etdm_widgets; 25762babb477STrevor Wu dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_etdm_widgets); 25772babb477STrevor Wu dai->dapm_routes = mtk_dai_etdm_routes; 25782babb477STrevor Wu dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_etdm_routes); 25792babb477STrevor Wu dai->controls = mtk_dai_etdm_controls; 25802babb477STrevor Wu dai->num_controls = ARRAY_SIZE(mtk_dai_etdm_controls); 25812babb477STrevor Wu 25822babb477STrevor Wu return init_etdm_priv_data(afe); 25832babb477STrevor Wu } 2584