Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // MediaTek ALSA SoC Audio DAI TDM Control
0004 //
0005 // Copyright (c) 2018 MediaTek Inc.
0006 // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
0007 
0008 #include <linux/regmap.h>
0009 #include <sound/pcm_params.h>
0010 #include "mt8183-afe-clk.h"
0011 #include "mt8183-afe-common.h"
0012 #include "mt8183-interconnection.h"
0013 #include "mt8183-reg.h"
0014 
0015 struct mtk_afe_tdm_priv {
0016     int bck_id;
0017     int bck_rate;
0018     int tdm_out_mode;
0019     int bck_invert;
0020     int lck_invert;
0021     int mclk_id;
0022     int mclk_multiple; /* according to sample rate */
0023     int mclk_rate;
0024     int mclk_apll;
0025 };
0026 
0027 enum {
0028     TDM_OUT_I2S = 0,
0029     TDM_OUT_TDM = 1,
0030 };
0031 
0032 enum {
0033     TDM_BCK_NON_INV = 0,
0034     TDM_BCK_INV = 1,
0035 };
0036 
0037 enum {
0038     TDM_LCK_NON_INV = 0,
0039     TDM_LCK_INV = 1,
0040 };
0041 
0042 enum {
0043     TDM_WLEN_16_BIT = 1,
0044     TDM_WLEN_32_BIT = 2,
0045 };
0046 
0047 enum {
0048     TDM_CHANNEL_BCK_16 = 0,
0049     TDM_CHANNEL_BCK_24 = 1,
0050     TDM_CHANNEL_BCK_32 = 2,
0051 };
0052 
0053 enum {
0054     TDM_CHANNEL_NUM_2 = 0,
0055     TDM_CHANNEL_NUM_4 = 1,
0056     TDM_CHANNEL_NUM_8 = 2,
0057 };
0058 
0059 enum  {
0060     TDM_CH_START_O30_O31 = 0,
0061     TDM_CH_START_O32_O33,
0062     TDM_CH_START_O34_O35,
0063     TDM_CH_START_O36_O37,
0064     TDM_CH_ZERO,
0065 };
0066 
0067 enum {
0068     HDMI_BIT_WIDTH_16_BIT = 0,
0069     HDMI_BIT_WIDTH_32_BIT = 1,
0070 };
0071 
0072 static unsigned int get_hdmi_wlen(snd_pcm_format_t format)
0073 {
0074     return snd_pcm_format_physical_width(format) <= 16 ?
0075            HDMI_BIT_WIDTH_16_BIT : HDMI_BIT_WIDTH_32_BIT;
0076 }
0077 
0078 static unsigned int get_tdm_wlen(snd_pcm_format_t format)
0079 {
0080     return snd_pcm_format_physical_width(format) <= 16 ?
0081            TDM_WLEN_16_BIT : TDM_WLEN_32_BIT;
0082 }
0083 
0084 static unsigned int get_tdm_channel_bck(snd_pcm_format_t format)
0085 {
0086     return snd_pcm_format_physical_width(format) <= 16 ?
0087            TDM_CHANNEL_BCK_16 : TDM_CHANNEL_BCK_32;
0088 }
0089 
0090 static unsigned int get_tdm_lrck_width(snd_pcm_format_t format)
0091 {
0092     return snd_pcm_format_physical_width(format) - 1;
0093 }
0094 
0095 static unsigned int get_tdm_ch(unsigned int ch)
0096 {
0097     switch (ch) {
0098     case 1:
0099     case 2:
0100         return TDM_CHANNEL_NUM_2;
0101     case 3:
0102     case 4:
0103         return TDM_CHANNEL_NUM_4;
0104     case 5:
0105     case 6:
0106     case 7:
0107     case 8:
0108     default:
0109         return TDM_CHANNEL_NUM_8;
0110     }
0111 }
0112 
0113 static unsigned int get_tdm_ch_fixup(unsigned int channels)
0114 {
0115     if (channels > 4)
0116         return 8;
0117     else if (channels > 2)
0118         return 4;
0119     else
0120         return 2;
0121 }
0122 
0123 static unsigned int get_tdm_ch_per_sdata(unsigned int mode,
0124                      unsigned int channels)
0125 {
0126     if (mode == TDM_OUT_TDM)
0127         return get_tdm_ch_fixup(channels);
0128     else
0129         return 2;
0130 }
0131 
0132 /* interconnection */
0133 enum {
0134     HDMI_CONN_CH0 = 0,
0135     HDMI_CONN_CH1,
0136     HDMI_CONN_CH2,
0137     HDMI_CONN_CH3,
0138     HDMI_CONN_CH4,
0139     HDMI_CONN_CH5,
0140     HDMI_CONN_CH6,
0141     HDMI_CONN_CH7,
0142 };
0143 
0144 static const char *const hdmi_conn_mux_map[] = {
0145     "CH0", "CH1", "CH2", "CH3",
0146     "CH4", "CH5", "CH6", "CH7",
0147 };
0148 
0149 static int hdmi_conn_mux_map_value[] = {
0150     HDMI_CONN_CH0,
0151     HDMI_CONN_CH1,
0152     HDMI_CONN_CH2,
0153     HDMI_CONN_CH3,
0154     HDMI_CONN_CH4,
0155     HDMI_CONN_CH5,
0156     HDMI_CONN_CH6,
0157     HDMI_CONN_CH7,
0158 };
0159 
0160 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch0_mux_map_enum,
0161                   AFE_HDMI_CONN0,
0162                   HDMI_O_0_SFT,
0163                   HDMI_O_0_MASK,
0164                   hdmi_conn_mux_map,
0165                   hdmi_conn_mux_map_value);
0166 
0167 static const struct snd_kcontrol_new hdmi_ch0_mux_control =
0168     SOC_DAPM_ENUM("HDMI_CH0_MUX", hdmi_ch0_mux_map_enum);
0169 
0170 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch1_mux_map_enum,
0171                   AFE_HDMI_CONN0,
0172                   HDMI_O_1_SFT,
0173                   HDMI_O_1_MASK,
0174                   hdmi_conn_mux_map,
0175                   hdmi_conn_mux_map_value);
0176 
0177 static const struct snd_kcontrol_new hdmi_ch1_mux_control =
0178     SOC_DAPM_ENUM("HDMI_CH1_MUX", hdmi_ch1_mux_map_enum);
0179 
0180 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch2_mux_map_enum,
0181                   AFE_HDMI_CONN0,
0182                   HDMI_O_2_SFT,
0183                   HDMI_O_2_MASK,
0184                   hdmi_conn_mux_map,
0185                   hdmi_conn_mux_map_value);
0186 
0187 static const struct snd_kcontrol_new hdmi_ch2_mux_control =
0188     SOC_DAPM_ENUM("HDMI_CH2_MUX", hdmi_ch2_mux_map_enum);
0189 
0190 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch3_mux_map_enum,
0191                   AFE_HDMI_CONN0,
0192                   HDMI_O_3_SFT,
0193                   HDMI_O_3_MASK,
0194                   hdmi_conn_mux_map,
0195                   hdmi_conn_mux_map_value);
0196 
0197 static const struct snd_kcontrol_new hdmi_ch3_mux_control =
0198     SOC_DAPM_ENUM("HDMI_CH3_MUX", hdmi_ch3_mux_map_enum);
0199 
0200 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch4_mux_map_enum,
0201                   AFE_HDMI_CONN0,
0202                   HDMI_O_4_SFT,
0203                   HDMI_O_4_MASK,
0204                   hdmi_conn_mux_map,
0205                   hdmi_conn_mux_map_value);
0206 
0207 static const struct snd_kcontrol_new hdmi_ch4_mux_control =
0208     SOC_DAPM_ENUM("HDMI_CH4_MUX", hdmi_ch4_mux_map_enum);
0209 
0210 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch5_mux_map_enum,
0211                   AFE_HDMI_CONN0,
0212                   HDMI_O_5_SFT,
0213                   HDMI_O_5_MASK,
0214                   hdmi_conn_mux_map,
0215                   hdmi_conn_mux_map_value);
0216 
0217 static const struct snd_kcontrol_new hdmi_ch5_mux_control =
0218     SOC_DAPM_ENUM("HDMI_CH5_MUX", hdmi_ch5_mux_map_enum);
0219 
0220 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch6_mux_map_enum,
0221                   AFE_HDMI_CONN0,
0222                   HDMI_O_6_SFT,
0223                   HDMI_O_6_MASK,
0224                   hdmi_conn_mux_map,
0225                   hdmi_conn_mux_map_value);
0226 
0227 static const struct snd_kcontrol_new hdmi_ch6_mux_control =
0228     SOC_DAPM_ENUM("HDMI_CH6_MUX", hdmi_ch6_mux_map_enum);
0229 
0230 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch7_mux_map_enum,
0231                   AFE_HDMI_CONN0,
0232                   HDMI_O_7_SFT,
0233                   HDMI_O_7_MASK,
0234                   hdmi_conn_mux_map,
0235                   hdmi_conn_mux_map_value);
0236 
0237 static const struct snd_kcontrol_new hdmi_ch7_mux_control =
0238     SOC_DAPM_ENUM("HDMI_CH7_MUX", hdmi_ch7_mux_map_enum);
0239 
0240 enum {
0241     SUPPLY_SEQ_APLL,
0242     SUPPLY_SEQ_TDM_MCK_EN,
0243     SUPPLY_SEQ_TDM_BCK_EN,
0244 };
0245 
0246 static int mtk_tdm_bck_en_event(struct snd_soc_dapm_widget *w,
0247                 struct snd_kcontrol *kcontrol,
0248                 int event)
0249 {
0250     struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0251     struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0252     struct mt8183_afe_private *afe_priv = afe->platform_priv;
0253     struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[MT8183_DAI_TDM];
0254 
0255     dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
0256          __func__, w->name, event);
0257 
0258     switch (event) {
0259     case SND_SOC_DAPM_PRE_PMU:
0260         mt8183_mck_enable(afe, tdm_priv->bck_id, tdm_priv->bck_rate);
0261         break;
0262     case SND_SOC_DAPM_POST_PMD:
0263         mt8183_mck_disable(afe, tdm_priv->bck_id);
0264         break;
0265     default:
0266         break;
0267     }
0268 
0269     return 0;
0270 }
0271 
0272 static int mtk_tdm_mck_en_event(struct snd_soc_dapm_widget *w,
0273                 struct snd_kcontrol *kcontrol,
0274                 int event)
0275 {
0276     struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0277     struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0278     struct mt8183_afe_private *afe_priv = afe->platform_priv;
0279     struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[MT8183_DAI_TDM];
0280 
0281     dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
0282          __func__, w->name, event);
0283 
0284     switch (event) {
0285     case SND_SOC_DAPM_PRE_PMU:
0286         mt8183_mck_enable(afe, tdm_priv->mclk_id, tdm_priv->mclk_rate);
0287         break;
0288     case SND_SOC_DAPM_POST_PMD:
0289         tdm_priv->mclk_rate = 0;
0290         mt8183_mck_disable(afe, tdm_priv->mclk_id);
0291         break;
0292     default:
0293         break;
0294     }
0295 
0296     return 0;
0297 }
0298 
0299 static const struct snd_soc_dapm_widget mtk_dai_tdm_widgets[] = {
0300     SND_SOC_DAPM_MUX("HDMI_CH0_MUX", SND_SOC_NOPM, 0, 0,
0301              &hdmi_ch0_mux_control),
0302     SND_SOC_DAPM_MUX("HDMI_CH1_MUX", SND_SOC_NOPM, 0, 0,
0303              &hdmi_ch1_mux_control),
0304     SND_SOC_DAPM_MUX("HDMI_CH2_MUX", SND_SOC_NOPM, 0, 0,
0305              &hdmi_ch2_mux_control),
0306     SND_SOC_DAPM_MUX("HDMI_CH3_MUX", SND_SOC_NOPM, 0, 0,
0307              &hdmi_ch3_mux_control),
0308     SND_SOC_DAPM_MUX("HDMI_CH4_MUX", SND_SOC_NOPM, 0, 0,
0309              &hdmi_ch4_mux_control),
0310     SND_SOC_DAPM_MUX("HDMI_CH5_MUX", SND_SOC_NOPM, 0, 0,
0311              &hdmi_ch5_mux_control),
0312     SND_SOC_DAPM_MUX("HDMI_CH6_MUX", SND_SOC_NOPM, 0, 0,
0313              &hdmi_ch6_mux_control),
0314     SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0,
0315              &hdmi_ch7_mux_control),
0316 
0317     SND_SOC_DAPM_CLOCK_SUPPLY("aud_tdm_clk"),
0318 
0319     SND_SOC_DAPM_SUPPLY_S("TDM_BCK", SUPPLY_SEQ_TDM_BCK_EN,
0320                   SND_SOC_NOPM, 0, 0,
0321                   mtk_tdm_bck_en_event,
0322                   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
0323 
0324     SND_SOC_DAPM_SUPPLY_S("TDM_MCK", SUPPLY_SEQ_TDM_MCK_EN,
0325                   SND_SOC_NOPM, 0, 0,
0326                   mtk_tdm_mck_en_event,
0327                   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
0328 };
0329 
0330 static int mtk_afe_tdm_apll_connect(struct snd_soc_dapm_widget *source,
0331                     struct snd_soc_dapm_widget *sink)
0332 {
0333     struct snd_soc_dapm_widget *w = sink;
0334     struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0335     struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0336     struct mt8183_afe_private *afe_priv = afe->platform_priv;
0337     struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[MT8183_DAI_TDM];
0338     int cur_apll;
0339 
0340     /* which apll */
0341     cur_apll = mt8183_get_apll_by_name(afe, source->name);
0342 
0343     return (tdm_priv->mclk_apll == cur_apll) ? 1 : 0;
0344 }
0345 
0346 static const struct snd_soc_dapm_route mtk_dai_tdm_routes[] = {
0347     {"HDMI_CH0_MUX", "CH0", "HDMI"},
0348     {"HDMI_CH0_MUX", "CH1", "HDMI"},
0349     {"HDMI_CH0_MUX", "CH2", "HDMI"},
0350     {"HDMI_CH0_MUX", "CH3", "HDMI"},
0351     {"HDMI_CH0_MUX", "CH4", "HDMI"},
0352     {"HDMI_CH0_MUX", "CH5", "HDMI"},
0353     {"HDMI_CH0_MUX", "CH6", "HDMI"},
0354     {"HDMI_CH0_MUX", "CH7", "HDMI"},
0355 
0356     {"HDMI_CH1_MUX", "CH0", "HDMI"},
0357     {"HDMI_CH1_MUX", "CH1", "HDMI"},
0358     {"HDMI_CH1_MUX", "CH2", "HDMI"},
0359     {"HDMI_CH1_MUX", "CH3", "HDMI"},
0360     {"HDMI_CH1_MUX", "CH4", "HDMI"},
0361     {"HDMI_CH1_MUX", "CH5", "HDMI"},
0362     {"HDMI_CH1_MUX", "CH6", "HDMI"},
0363     {"HDMI_CH1_MUX", "CH7", "HDMI"},
0364 
0365     {"HDMI_CH2_MUX", "CH0", "HDMI"},
0366     {"HDMI_CH2_MUX", "CH1", "HDMI"},
0367     {"HDMI_CH2_MUX", "CH2", "HDMI"},
0368     {"HDMI_CH2_MUX", "CH3", "HDMI"},
0369     {"HDMI_CH2_MUX", "CH4", "HDMI"},
0370     {"HDMI_CH2_MUX", "CH5", "HDMI"},
0371     {"HDMI_CH2_MUX", "CH6", "HDMI"},
0372     {"HDMI_CH2_MUX", "CH7", "HDMI"},
0373 
0374     {"HDMI_CH3_MUX", "CH0", "HDMI"},
0375     {"HDMI_CH3_MUX", "CH1", "HDMI"},
0376     {"HDMI_CH3_MUX", "CH2", "HDMI"},
0377     {"HDMI_CH3_MUX", "CH3", "HDMI"},
0378     {"HDMI_CH3_MUX", "CH4", "HDMI"},
0379     {"HDMI_CH3_MUX", "CH5", "HDMI"},
0380     {"HDMI_CH3_MUX", "CH6", "HDMI"},
0381     {"HDMI_CH3_MUX", "CH7", "HDMI"},
0382 
0383     {"HDMI_CH4_MUX", "CH0", "HDMI"},
0384     {"HDMI_CH4_MUX", "CH1", "HDMI"},
0385     {"HDMI_CH4_MUX", "CH2", "HDMI"},
0386     {"HDMI_CH4_MUX", "CH3", "HDMI"},
0387     {"HDMI_CH4_MUX", "CH4", "HDMI"},
0388     {"HDMI_CH4_MUX", "CH5", "HDMI"},
0389     {"HDMI_CH4_MUX", "CH6", "HDMI"},
0390     {"HDMI_CH4_MUX", "CH7", "HDMI"},
0391 
0392     {"HDMI_CH5_MUX", "CH0", "HDMI"},
0393     {"HDMI_CH5_MUX", "CH1", "HDMI"},
0394     {"HDMI_CH5_MUX", "CH2", "HDMI"},
0395     {"HDMI_CH5_MUX", "CH3", "HDMI"},
0396     {"HDMI_CH5_MUX", "CH4", "HDMI"},
0397     {"HDMI_CH5_MUX", "CH5", "HDMI"},
0398     {"HDMI_CH5_MUX", "CH6", "HDMI"},
0399     {"HDMI_CH5_MUX", "CH7", "HDMI"},
0400 
0401     {"HDMI_CH6_MUX", "CH0", "HDMI"},
0402     {"HDMI_CH6_MUX", "CH1", "HDMI"},
0403     {"HDMI_CH6_MUX", "CH2", "HDMI"},
0404     {"HDMI_CH6_MUX", "CH3", "HDMI"},
0405     {"HDMI_CH6_MUX", "CH4", "HDMI"},
0406     {"HDMI_CH6_MUX", "CH5", "HDMI"},
0407     {"HDMI_CH6_MUX", "CH6", "HDMI"},
0408     {"HDMI_CH6_MUX", "CH7", "HDMI"},
0409 
0410     {"HDMI_CH7_MUX", "CH0", "HDMI"},
0411     {"HDMI_CH7_MUX", "CH1", "HDMI"},
0412     {"HDMI_CH7_MUX", "CH2", "HDMI"},
0413     {"HDMI_CH7_MUX", "CH3", "HDMI"},
0414     {"HDMI_CH7_MUX", "CH4", "HDMI"},
0415     {"HDMI_CH7_MUX", "CH5", "HDMI"},
0416     {"HDMI_CH7_MUX", "CH6", "HDMI"},
0417     {"HDMI_CH7_MUX", "CH7", "HDMI"},
0418 
0419     {"TDM", NULL, "HDMI_CH0_MUX"},
0420     {"TDM", NULL, "HDMI_CH1_MUX"},
0421     {"TDM", NULL, "HDMI_CH2_MUX"},
0422     {"TDM", NULL, "HDMI_CH3_MUX"},
0423     {"TDM", NULL, "HDMI_CH4_MUX"},
0424     {"TDM", NULL, "HDMI_CH5_MUX"},
0425     {"TDM", NULL, "HDMI_CH6_MUX"},
0426     {"TDM", NULL, "HDMI_CH7_MUX"},
0427 
0428     {"TDM", NULL, "aud_tdm_clk"},
0429     {"TDM", NULL, "TDM_BCK"},
0430     {"TDM_BCK", NULL, "TDM_MCK"},
0431     {"TDM_MCK", NULL, APLL1_W_NAME, mtk_afe_tdm_apll_connect},
0432     {"TDM_MCK", NULL, APLL2_W_NAME, mtk_afe_tdm_apll_connect},
0433 };
0434 
0435 /* dai ops */
0436 static int mtk_dai_tdm_cal_mclk(struct mtk_base_afe *afe,
0437                 struct mtk_afe_tdm_priv *tdm_priv,
0438                 int freq)
0439 {
0440     int apll;
0441     int apll_rate;
0442 
0443     apll = mt8183_get_apll_by_rate(afe, freq);
0444     apll_rate = mt8183_get_apll_rate(afe, apll);
0445 
0446     if (!freq || freq > apll_rate) {
0447         dev_warn(afe->dev,
0448              "%s(), freq(%d Hz) invalid\n", __func__, freq);
0449         return -EINVAL;
0450     }
0451 
0452     if (apll_rate % freq != 0) {
0453         dev_warn(afe->dev,
0454              "%s(), APLL cannot generate %d Hz", __func__, freq);
0455         return -EINVAL;
0456     }
0457 
0458     tdm_priv->mclk_rate = freq;
0459     tdm_priv->mclk_apll = apll;
0460 
0461     return 0;
0462 }
0463 
0464 static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream,
0465                  struct snd_pcm_hw_params *params,
0466                  struct snd_soc_dai *dai)
0467 {
0468     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0469     struct mt8183_afe_private *afe_priv = afe->platform_priv;
0470     int tdm_id = dai->id;
0471     struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id];
0472     unsigned int tdm_out_mode = tdm_priv->tdm_out_mode;
0473     unsigned int rate = params_rate(params);
0474     unsigned int channels = params_channels(params);
0475     unsigned int out_channels_per_sdata =
0476         get_tdm_ch_per_sdata(tdm_out_mode, channels);
0477     snd_pcm_format_t format = params_format(params);
0478     unsigned int tdm_con = 0;
0479 
0480     /* calculate mclk_rate, if not set explicitly */
0481     if (!tdm_priv->mclk_rate) {
0482         tdm_priv->mclk_rate = rate * tdm_priv->mclk_multiple;
0483         mtk_dai_tdm_cal_mclk(afe,
0484                      tdm_priv,
0485                      tdm_priv->mclk_rate);
0486     }
0487 
0488     /* calculate bck */
0489     tdm_priv->bck_rate = rate *
0490                  out_channels_per_sdata *
0491                  snd_pcm_format_physical_width(format);
0492 
0493     if (tdm_priv->bck_rate > tdm_priv->mclk_rate)
0494         dev_warn(afe->dev, "%s(), bck_rate > mclk_rate rate", __func__);
0495 
0496     if (tdm_priv->mclk_rate % tdm_priv->bck_rate != 0)
0497         dev_warn(afe->dev, "%s(), bck cannot generate", __func__);
0498 
0499     dev_info(afe->dev, "%s(), id %d, rate %d, channels %d, format %d, mclk_rate %d, bck_rate %d\n",
0500          __func__,
0501          tdm_id, rate, channels, format,
0502          tdm_priv->mclk_rate, tdm_priv->bck_rate);
0503     dev_info(afe->dev, "%s(), out_channels_per_sdata = %d\n",
0504          __func__, out_channels_per_sdata);
0505 
0506     /* set tdm */
0507     if (tdm_priv->bck_invert)
0508         regmap_update_bits(afe->regmap, AUDIO_TOP_CON3,
0509                    BCK_INVERSE_MASK_SFT,
0510                    0x1 << BCK_INVERSE_SFT);
0511 
0512     if (tdm_priv->lck_invert)
0513         tdm_con |= 1 << LRCK_INVERSE_SFT;
0514 
0515     if (tdm_priv->tdm_out_mode == TDM_OUT_I2S) {
0516         tdm_con |= 1 << DELAY_DATA_SFT;
0517         tdm_con |= get_tdm_lrck_width(format) << LRCK_TDM_WIDTH_SFT;
0518     } else if (tdm_priv->tdm_out_mode == TDM_OUT_TDM) {
0519         tdm_con |= 0 << DELAY_DATA_SFT;
0520         tdm_con |= 0 << LRCK_TDM_WIDTH_SFT;
0521     }
0522 
0523     tdm_con |= 1 << LEFT_ALIGN_SFT;
0524     tdm_con |= get_tdm_wlen(format) << WLEN_SFT;
0525     tdm_con |= get_tdm_ch(out_channels_per_sdata) << CHANNEL_NUM_SFT;
0526     tdm_con |= get_tdm_channel_bck(format) << CHANNEL_BCK_CYCLES_SFT;
0527     regmap_write(afe->regmap, AFE_TDM_CON1, tdm_con);
0528 
0529     if (out_channels_per_sdata == 2) {
0530         switch (channels) {
0531         case 1:
0532         case 2:
0533             tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
0534             tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT;
0535             tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT;
0536             tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
0537             break;
0538         case 3:
0539         case 4:
0540             tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
0541             tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
0542             tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT;
0543             tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
0544             break;
0545         case 5:
0546         case 6:
0547             tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
0548             tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
0549             tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT;
0550             tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
0551             break;
0552         case 7:
0553         case 8:
0554             tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
0555             tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
0556             tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT;
0557             tdm_con |= TDM_CH_START_O36_O37 << ST_CH_PAIR_SOUT3_SFT;
0558             break;
0559         default:
0560             tdm_con = 0;
0561         }
0562     } else {
0563         tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
0564         tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT;
0565         tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT;
0566         tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
0567     }
0568 
0569     regmap_write(afe->regmap, AFE_TDM_CON2, tdm_con);
0570 
0571     regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
0572                AFE_HDMI_OUT_CH_NUM_MASK_SFT,
0573                channels << AFE_HDMI_OUT_CH_NUM_SFT);
0574 
0575     regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
0576                AFE_HDMI_OUT_BIT_WIDTH_MASK_SFT,
0577                get_hdmi_wlen(format) << AFE_HDMI_OUT_BIT_WIDTH_SFT);
0578     return 0;
0579 }
0580 
0581 static int mtk_dai_tdm_trigger(struct snd_pcm_substream *substream,
0582                    int cmd,
0583                    struct snd_soc_dai *dai)
0584 {
0585     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0586 
0587     switch (cmd) {
0588     case SNDRV_PCM_TRIGGER_START:
0589     case SNDRV_PCM_TRIGGER_RESUME:
0590         /* enable Out control */
0591         regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
0592                    AFE_HDMI_OUT_ON_MASK_SFT,
0593                    0x1 << AFE_HDMI_OUT_ON_SFT);
0594         /* enable tdm */
0595         regmap_update_bits(afe->regmap, AFE_TDM_CON1,
0596                    TDM_EN_MASK_SFT, 0x1 << TDM_EN_SFT);
0597         break;
0598     case SNDRV_PCM_TRIGGER_STOP:
0599     case SNDRV_PCM_TRIGGER_SUSPEND:
0600         /* disable tdm */
0601         regmap_update_bits(afe->regmap, AFE_TDM_CON1,
0602                    TDM_EN_MASK_SFT, 0);
0603         /* disable Out control */
0604         regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
0605                    AFE_HDMI_OUT_ON_MASK_SFT,
0606                    0);
0607         break;
0608     default:
0609         return -EINVAL;
0610     }
0611 
0612     return 0;
0613 }
0614 
0615 static int mtk_dai_tdm_set_sysclk(struct snd_soc_dai *dai,
0616                   int clk_id, unsigned int freq, int dir)
0617 {
0618     struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
0619     struct mt8183_afe_private *afe_priv = afe->platform_priv;
0620     struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id];
0621 
0622     if (!tdm_priv) {
0623         dev_warn(afe->dev, "%s(), tdm_priv == NULL", __func__);
0624         return -EINVAL;
0625     }
0626 
0627     if (dir != SND_SOC_CLOCK_OUT) {
0628         dev_warn(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);
0629         return -EINVAL;
0630     }
0631 
0632     dev_info(afe->dev, "%s(), freq %d\n", __func__, freq);
0633 
0634     return mtk_dai_tdm_cal_mclk(afe, tdm_priv, freq);
0635 }
0636 
0637 static int mtk_dai_tdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0638 {
0639     struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
0640     struct mt8183_afe_private *afe_priv = afe->platform_priv;
0641     struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id];
0642 
0643     if (!tdm_priv) {
0644         dev_warn(afe->dev, "%s(), tdm_priv == NULL", __func__);
0645         return -EINVAL;
0646     }
0647 
0648     /* DAI mode*/
0649     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0650     case SND_SOC_DAIFMT_I2S:
0651         tdm_priv->tdm_out_mode = TDM_OUT_I2S;
0652         break;
0653     case SND_SOC_DAIFMT_DSP_A:
0654         tdm_priv->tdm_out_mode = TDM_OUT_TDM;
0655         break;
0656     default:
0657         tdm_priv->tdm_out_mode = TDM_OUT_I2S;
0658     }
0659 
0660     /* DAI clock inversion*/
0661     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0662     case SND_SOC_DAIFMT_NB_NF:
0663         tdm_priv->bck_invert = TDM_BCK_NON_INV;
0664         tdm_priv->lck_invert = TDM_LCK_NON_INV;
0665         break;
0666     case SND_SOC_DAIFMT_NB_IF:
0667         tdm_priv->bck_invert = TDM_BCK_NON_INV;
0668         tdm_priv->lck_invert = TDM_LCK_INV;
0669         break;
0670     case SND_SOC_DAIFMT_IB_NF:
0671         tdm_priv->bck_invert = TDM_BCK_INV;
0672         tdm_priv->lck_invert = TDM_LCK_NON_INV;
0673         break;
0674     case SND_SOC_DAIFMT_IB_IF:
0675     default:
0676         tdm_priv->bck_invert = TDM_BCK_INV;
0677         tdm_priv->lck_invert = TDM_LCK_INV;
0678         break;
0679     }
0680 
0681     return 0;
0682 }
0683 
0684 static const struct snd_soc_dai_ops mtk_dai_tdm_ops = {
0685     .hw_params = mtk_dai_tdm_hw_params,
0686     .trigger = mtk_dai_tdm_trigger,
0687     .set_sysclk = mtk_dai_tdm_set_sysclk,
0688     .set_fmt = mtk_dai_tdm_set_fmt,
0689 };
0690 
0691 /* dai driver */
0692 #define MTK_TDM_RATES (SNDRV_PCM_RATE_8000_48000 |\
0693                SNDRV_PCM_RATE_88200 |\
0694                SNDRV_PCM_RATE_96000 |\
0695                SNDRV_PCM_RATE_176400 |\
0696                SNDRV_PCM_RATE_192000)
0697 
0698 #define MTK_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
0699              SNDRV_PCM_FMTBIT_S24_LE |\
0700              SNDRV_PCM_FMTBIT_S32_LE)
0701 
0702 static struct snd_soc_dai_driver mtk_dai_tdm_driver[] = {
0703     {
0704         .name = "TDM",
0705         .id = MT8183_DAI_TDM,
0706         .playback = {
0707             .stream_name = "TDM",
0708             .channels_min = 2,
0709             .channels_max = 8,
0710             .rates = MTK_TDM_RATES,
0711             .formats = MTK_TDM_FORMATS,
0712         },
0713         .ops = &mtk_dai_tdm_ops,
0714     },
0715 };
0716 
0717 int mt8183_dai_tdm_register(struct mtk_base_afe *afe)
0718 {
0719     struct mt8183_afe_private *afe_priv = afe->platform_priv;
0720     struct mtk_afe_tdm_priv *tdm_priv;
0721     struct mtk_base_afe_dai *dai;
0722 
0723     dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
0724     if (!dai)
0725         return -ENOMEM;
0726 
0727     list_add(&dai->list, &afe->sub_dais);
0728 
0729     dai->dai_drivers = mtk_dai_tdm_driver;
0730     dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_tdm_driver);
0731 
0732     dai->dapm_widgets = mtk_dai_tdm_widgets;
0733     dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_tdm_widgets);
0734     dai->dapm_routes = mtk_dai_tdm_routes;
0735     dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_tdm_routes);
0736 
0737     tdm_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_afe_tdm_priv),
0738                 GFP_KERNEL);
0739     if (!tdm_priv)
0740         return -ENOMEM;
0741 
0742     tdm_priv->mclk_multiple = 128;
0743     tdm_priv->bck_id = MT8183_I2S4_BCK;
0744     tdm_priv->mclk_id = MT8183_I2S4_MCK;
0745 
0746     afe_priv->dai_priv[MT8183_DAI_TDM] = tdm_priv;
0747     return 0;
0748 }