0001
0002
0003
0004
0005
0006
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;
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
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
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
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
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
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
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
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
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
0601 regmap_update_bits(afe->regmap, AFE_TDM_CON1,
0602 TDM_EN_MASK_SFT, 0);
0603
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
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
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
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 }