1// SPDX-License-Identifier: GPL-2.0 2// 3// MediaTek ALSA SoC Audio DAI TDM Control 4// 5// Copyright (c) 2022 MediaTek Inc. 6// Author: Jiaxin Yu <jiaxin.yu@mediatek.com> 7 8#include <linux/regmap.h> 9#include <sound/pcm_params.h> 10 11#include "mt8186-afe-clk.h" 12#include "mt8186-afe-common.h" 13#include "mt8186-afe-gpio.h" 14#include "mt8186-interconnection.h" 15 16#define TDM_HD_EN_W_NAME "TDM_HD_EN" 17#define TDM_MCLK_EN_W_NAME "TDM_MCLK_EN" 18#define MTK_AFE_TDM_KCONTROL_NAME "TDM_HD_Mux" 19 20struct mtk_afe_tdm_priv { 21 unsigned int id; 22 unsigned int rate; /* for determine which apll to use */ 23 unsigned int bck_invert; 24 unsigned int lck_invert; 25 unsigned int lrck_width; 26 unsigned int mclk_id; 27 unsigned int mclk_multiple; /* according to sample rate */ 28 unsigned int mclk_rate; 29 unsigned int mclk_apll; 30 unsigned int tdm_mode; 31 unsigned int data_mode; 32 unsigned int slave_mode; 33 unsigned int low_jitter_en; 34}; 35 36enum { 37 TDM_IN_I2S = 0, 38 TDM_IN_LJ = 1, 39 TDM_IN_RJ = 2, 40 TDM_IN_DSP_A = 4, 41 TDM_IN_DSP_B = 5, 42}; 43 44enum { 45 TDM_DATA_ONE_PIN = 0, 46 TDM_DATA_MULTI_PIN, 47}; 48 49enum { 50 TDM_BCK_NON_INV = 0, 51 TDM_BCK_INV = 1, 52}; 53 54enum { 55 TDM_LCK_NON_INV = 0, 56 TDM_LCK_INV = 1, 57}; 58 59static unsigned int get_tdm_lrck_width(snd_pcm_format_t format, 60 unsigned int mode) 61{ 62 if (mode == TDM_IN_DSP_A || mode == TDM_IN_DSP_B) 63 return 0; 64 65 return snd_pcm_format_physical_width(format) - 1; 66} 67 68static unsigned int get_tdm_ch_fixup(unsigned int channels) 69{ 70 if (channels > 4) 71 return 8; 72 else if (channels > 2) 73 return 4; 74 75 return 2; 76} 77 78static unsigned int get_tdm_ch_per_sdata(unsigned int mode, 79 unsigned int channels) 80{ 81 if (mode == TDM_IN_DSP_A || mode == TDM_IN_DSP_B) 82 return get_tdm_ch_fixup(channels); 83 84 return 2; 85} 86 87enum { 88 SUPPLY_SEQ_APLL, 89 SUPPLY_SEQ_TDM_MCK_EN, 90 SUPPLY_SEQ_TDM_HD_EN, 91 SUPPLY_SEQ_TDM_EN, 92}; 93 94static int get_tdm_id_by_name(const char *name) 95{ 96 return MT8186_DAI_TDM_IN; 97} 98 99static int mtk_tdm_en_event(struct snd_soc_dapm_widget *w, 100 struct snd_kcontrol *kcontrol, 101 int event) 102{ 103 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 104 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 105 struct mt8186_afe_private *afe_priv = afe->platform_priv; 106 int dai_id = get_tdm_id_by_name(w->name); 107 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; 108 109 dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", 110 __func__, w->name, event); 111 112 switch (event) { 113 case SND_SOC_DAPM_PRE_PMU: 114 mt8186_afe_gpio_request(afe->dev, true, tdm_priv->id, 0); 115 break; 116 case SND_SOC_DAPM_POST_PMD: 117 mt8186_afe_gpio_request(afe->dev, false, tdm_priv->id, 0); 118 break; 119 default: 120 break; 121 } 122 123 return 0; 124} 125 126static int mtk_tdm_mck_en_event(struct snd_soc_dapm_widget *w, 127 struct snd_kcontrol *kcontrol, 128 int event) 129{ 130 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 131 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 132 struct mt8186_afe_private *afe_priv = afe->platform_priv; 133 int dai_id = get_tdm_id_by_name(w->name); 134 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; 135 136 dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x, dai_id %d\n", 137 __func__, w->name, event, dai_id); 138 139 switch (event) { 140 case SND_SOC_DAPM_PRE_PMU: 141 mt8186_mck_enable(afe, tdm_priv->mclk_id, tdm_priv->mclk_rate); 142 break; 143 case SND_SOC_DAPM_POST_PMD: 144 tdm_priv->mclk_rate = 0; 145 mt8186_mck_disable(afe, tdm_priv->mclk_id); 146 break; 147 default: 148 break; 149 } 150 151 return 0; 152} 153 154/* dai component */ 155/* tdm virtual mux to output widget */ 156static const char * const tdm_mux_map[] = { 157 "Normal", "Dummy_Widget", 158}; 159 160static int tdm_mux_map_value[] = { 161 0, 1, 162}; 163 164static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(tdm_mux_map_enum, 165 SND_SOC_NOPM, 166 0, 167 1, 168 tdm_mux_map, 169 tdm_mux_map_value); 170 171static const struct snd_kcontrol_new tdm_in_mux_control = 172 SOC_DAPM_ENUM("TDM In Select", tdm_mux_map_enum); 173 174static const struct snd_soc_dapm_widget mtk_dai_tdm_widgets[] = { 175 SND_SOC_DAPM_CLOCK_SUPPLY("aud_tdm_clk"), 176 177 SND_SOC_DAPM_SUPPLY_S("TDM_EN", SUPPLY_SEQ_TDM_EN, 178 ETDM_IN1_CON0, ETDM_IN1_CON0_REG_ETDM_IN_EN_SFT, 179 0, mtk_tdm_en_event, 180 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 181 /* tdm hd en */ 182 SND_SOC_DAPM_SUPPLY_S(TDM_HD_EN_W_NAME, SUPPLY_SEQ_TDM_HD_EN, 183 ETDM_IN1_CON2, ETDM_IN1_CON2_REG_CLOCK_SOURCE_SEL_SFT, 184 0, NULL, 185 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 186 187 SND_SOC_DAPM_SUPPLY_S(TDM_MCLK_EN_W_NAME, SUPPLY_SEQ_TDM_MCK_EN, 188 SND_SOC_NOPM, 0, 0, 189 mtk_tdm_mck_en_event, 190 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 191 192 SND_SOC_DAPM_INPUT("TDM_DUMMY_IN"), 193 194 SND_SOC_DAPM_MUX("TDM_In_Mux", 195 SND_SOC_NOPM, 0, 0, &tdm_in_mux_control), 196}; 197 198static int mtk_afe_tdm_mclk_connect(struct snd_soc_dapm_widget *source, 199 struct snd_soc_dapm_widget *sink) 200{ 201 struct snd_soc_dapm_widget *w = sink; 202 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 203 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 204 struct mt8186_afe_private *afe_priv = afe->platform_priv; 205 int dai_id = get_tdm_id_by_name(w->name); 206 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; 207 208 return (tdm_priv->mclk_rate > 0) ? 1 : 0; 209} 210 211static int mtk_afe_tdm_mclk_apll_connect(struct snd_soc_dapm_widget *source, 212 struct snd_soc_dapm_widget *sink) 213{ 214 struct snd_soc_dapm_widget *w = sink; 215 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 216 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 217 struct mt8186_afe_private *afe_priv = afe->platform_priv; 218 int dai_id = get_tdm_id_by_name(w->name); 219 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; 220 int cur_apll; 221 222 /* which apll */ 223 cur_apll = mt8186_get_apll_by_name(afe, source->name); 224 225 return (tdm_priv->mclk_apll == cur_apll) ? 1 : 0; 226} 227 228static int mtk_afe_tdm_hd_connect(struct snd_soc_dapm_widget *source, 229 struct snd_soc_dapm_widget *sink) 230{ 231 struct snd_soc_dapm_widget *w = sink; 232 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 233 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 234 struct mt8186_afe_private *afe_priv = afe->platform_priv; 235 int dai_id = get_tdm_id_by_name(w->name); 236 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; 237 238 return tdm_priv->low_jitter_en; 239} 240 241static int mtk_afe_tdm_apll_connect(struct snd_soc_dapm_widget *source, 242 struct snd_soc_dapm_widget *sink) 243{ 244 struct snd_soc_dapm_widget *w = sink; 245 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 246 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 247 struct mt8186_afe_private *afe_priv = afe->platform_priv; 248 int dai_id = get_tdm_id_by_name(w->name); 249 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; 250 int cur_apll; 251 int tdm_need_apll; 252 253 /* which apll */ 254 cur_apll = mt8186_get_apll_by_name(afe, source->name); 255 256 /* choose APLL from tdm rate */ 257 tdm_need_apll = mt8186_get_apll_by_rate(afe, tdm_priv->rate); 258 259 return (tdm_need_apll == cur_apll) ? 1 : 0; 260} 261 262/* low jitter control */ 263static const char * const mt8186_tdm_hd_str[] = { 264 "Normal", "Low_Jitter" 265}; 266 267static const struct soc_enum mt8186_tdm_enum[] = { 268 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_tdm_hd_str), 269 mt8186_tdm_hd_str), 270}; 271 272static int mt8186_tdm_hd_get(struct snd_kcontrol *kcontrol, 273 struct snd_ctl_elem_value *ucontrol) 274{ 275 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 276 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 277 struct mt8186_afe_private *afe_priv = afe->platform_priv; 278 int dai_id = get_tdm_id_by_name(kcontrol->id.name); 279 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; 280 281 ucontrol->value.integer.value[0] = tdm_priv->low_jitter_en; 282 283 return 0; 284} 285 286static int mt8186_tdm_hd_set(struct snd_kcontrol *kcontrol, 287 struct snd_ctl_elem_value *ucontrol) 288{ 289 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 290 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 291 struct mt8186_afe_private *afe_priv = afe->platform_priv; 292 int dai_id = get_tdm_id_by_name(kcontrol->id.name); 293 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; 294 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 295 int hd_en; 296 297 if (ucontrol->value.enumerated.item[0] >= e->items) 298 return -EINVAL; 299 300 hd_en = ucontrol->value.integer.value[0]; 301 302 dev_dbg(afe->dev, "%s(), kcontrol name %s, hd_en %d\n", 303 __func__, kcontrol->id.name, hd_en); 304 305 if (tdm_priv->low_jitter_en == hd_en) 306 return 0; 307 308 tdm_priv->low_jitter_en = hd_en; 309 310 return 1; 311} 312 313static const struct snd_kcontrol_new mtk_dai_tdm_controls[] = { 314 SOC_ENUM_EXT(MTK_AFE_TDM_KCONTROL_NAME, mt8186_tdm_enum[0], 315 mt8186_tdm_hd_get, mt8186_tdm_hd_set), 316}; 317 318static const struct snd_soc_dapm_route mtk_dai_tdm_routes[] = { 319 {"TDM IN", NULL, "aud_tdm_clk"}, 320 {"TDM IN", NULL, "TDM_EN"}, 321 {"TDM IN", NULL, TDM_HD_EN_W_NAME, mtk_afe_tdm_hd_connect}, 322 {TDM_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_tdm_apll_connect}, 323 {TDM_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_tdm_apll_connect}, 324 325 {"TDM IN", NULL, TDM_MCLK_EN_W_NAME, mtk_afe_tdm_mclk_connect}, 326 {TDM_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_tdm_mclk_apll_connect}, 327 {TDM_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_tdm_mclk_apll_connect}, 328 329 /* allow tdm on without codec on */ 330 {"TDM IN", NULL, "TDM_In_Mux"}, 331 {"TDM_In_Mux", "Dummy_Widget", "TDM_DUMMY_IN"}, 332}; 333 334/* dai ops */ 335static int mtk_dai_tdm_cal_mclk(struct mtk_base_afe *afe, 336 struct mtk_afe_tdm_priv *tdm_priv, 337 int freq) 338{ 339 int apll; 340 int apll_rate; 341 342 apll = mt8186_get_apll_by_rate(afe, freq); 343 apll_rate = mt8186_get_apll_rate(afe, apll); 344 345 if (!freq || freq > apll_rate) { 346 dev_err(afe->dev, 347 "%s(), freq(%d Hz) invalid\n", __func__, freq); 348 return -EINVAL; 349 } 350 351 if (apll_rate % freq != 0) { 352 dev_err(afe->dev, 353 "%s(), APLL cannot generate %d Hz", __func__, freq); 354 return -EINVAL; 355 } 356 357 tdm_priv->mclk_rate = freq; 358 tdm_priv->mclk_apll = apll; 359 360 return 0; 361} 362 363static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream, 364 struct snd_pcm_hw_params *params, 365 struct snd_soc_dai *dai) 366{ 367 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 368 struct mt8186_afe_private *afe_priv = afe->platform_priv; 369 int tdm_id = dai->id; 370 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id]; 371 unsigned int tdm_mode = tdm_priv->tdm_mode; 372 unsigned int data_mode = tdm_priv->data_mode; 373 unsigned int rate = params_rate(params); 374 unsigned int channels = params_channels(params); 375 snd_pcm_format_t format = params_format(params); 376 unsigned int bit_width = 377 snd_pcm_format_physical_width(format); 378 unsigned int tdm_channels = (data_mode == TDM_DATA_ONE_PIN) ? 379 get_tdm_ch_per_sdata(tdm_mode, channels) : 2; 380 unsigned int lrck_width = 381 get_tdm_lrck_width(format, tdm_mode); 382 unsigned int tdm_con = 0; 383 bool slave_mode = tdm_priv->slave_mode; 384 bool lrck_inv = tdm_priv->lck_invert; 385 bool bck_inv = tdm_priv->bck_invert; 386 unsigned int tran_rate; 387 unsigned int tran_relatch_rate; 388 389 tdm_priv->rate = rate; 390 tran_rate = mt8186_rate_transform(afe->dev, rate, dai->id); 391 tran_relatch_rate = mt8186_tdm_relatch_rate_transform(afe->dev, rate); 392 393 /* calculate mclk_rate, if not set explicitly */ 394 if (!tdm_priv->mclk_rate) { 395 tdm_priv->mclk_rate = rate * tdm_priv->mclk_multiple; 396 mtk_dai_tdm_cal_mclk(afe, tdm_priv, tdm_priv->mclk_rate); 397 } 398 399 /* ETDM_IN1_CON0 */ 400 tdm_con |= slave_mode << ETDM_IN1_CON0_REG_SLAVE_MODE_SFT; 401 tdm_con |= tdm_mode << ETDM_IN1_CON0_REG_FMT_SFT; 402 tdm_con |= (bit_width - 1) << ETDM_IN1_CON0_REG_BIT_LENGTH_SFT; 403 tdm_con |= (bit_width - 1) << ETDM_IN1_CON0_REG_WORD_LENGTH_SFT; 404 tdm_con |= (tdm_channels - 1) << ETDM_IN1_CON0_REG_CH_NUM_SFT; 405 /* need to disable sync mode otherwise this may cause latch data error */ 406 tdm_con |= 0 << ETDM_IN1_CON0_REG_SYNC_MODE_SFT; 407 /* relatch 1x en clock fix to h26m */ 408 tdm_con |= 0 << ETDM_IN1_CON0_REG_RELATCH_1X_EN_SEL_DOMAIN_SFT; 409 regmap_update_bits(afe->regmap, ETDM_IN1_CON0, ETDM_IN_CON0_CTRL_MASK, tdm_con); 410 411 /* ETDM_IN1_CON1 */ 412 tdm_con = 0; 413 tdm_con |= 0 << ETDM_IN1_CON1_REG_LRCK_AUTO_MODE_SFT; 414 tdm_con |= 1 << ETDM_IN1_CON1_PINMUX_MCLK_CTRL_OE_SFT; 415 tdm_con |= (lrck_width - 1) << ETDM_IN1_CON1_REG_LRCK_WIDTH_SFT; 416 regmap_update_bits(afe->regmap, ETDM_IN1_CON1, ETDM_IN_CON1_CTRL_MASK, tdm_con); 417 418 /* ETDM_IN1_CON3 */ 419 tdm_con = 0; 420 tdm_con = ETDM_IN_CON3_FS(tran_rate); 421 regmap_update_bits(afe->regmap, ETDM_IN1_CON3, ETDM_IN_CON3_CTRL_MASK, tdm_con); 422 423 /* ETDM_IN1_CON4 */ 424 tdm_con = 0; 425 tdm_con = ETDM_IN_CON4_FS(tran_relatch_rate); 426 if (slave_mode) { 427 if (lrck_inv) 428 tdm_con |= ETDM_IN_CON4_CON0_SLAVE_LRCK_INV; 429 if (bck_inv) 430 tdm_con |= ETDM_IN_CON4_CON0_SLAVE_BCK_INV; 431 } else { 432 if (lrck_inv) 433 tdm_con |= ETDM_IN_CON4_CON0_MASTER_LRCK_INV; 434 if (bck_inv) 435 tdm_con |= ETDM_IN_CON4_CON0_MASTER_BCK_INV; 436 } 437 regmap_update_bits(afe->regmap, ETDM_IN1_CON4, ETDM_IN_CON4_CTRL_MASK, tdm_con); 438 439 /* ETDM_IN1_CON2 */ 440 tdm_con = 0; 441 if (data_mode == TDM_DATA_MULTI_PIN) { 442 tdm_con |= ETDM_IN_CON2_MULTI_IP_2CH_MODE; 443 tdm_con |= ETDM_IN_CON2_MULTI_IP_CH(channels); 444 } 445 regmap_update_bits(afe->regmap, ETDM_IN1_CON2, ETDM_IN_CON2_CTRL_MASK, tdm_con); 446 447 /* ETDM_IN1_CON8 */ 448 tdm_con = 0; 449 if (slave_mode) { 450 tdm_con |= 1 << ETDM_IN1_CON8_REG_ETDM_USE_AFIFO_SFT; 451 tdm_con |= 0 << ETDM_IN1_CON8_REG_AFIFO_CLOCK_DOMAIN_SEL_SFT; 452 tdm_con |= ETDM_IN_CON8_FS(tran_relatch_rate); 453 } else { 454 tdm_con |= 0 << ETDM_IN1_CON8_REG_ETDM_USE_AFIFO_SFT; 455 } 456 regmap_update_bits(afe->regmap, ETDM_IN1_CON8, ETDM_IN_CON8_CTRL_MASK, tdm_con); 457 458 return 0; 459} 460 461static int mtk_dai_tdm_set_sysclk(struct snd_soc_dai *dai, 462 int clk_id, unsigned int freq, int dir) 463{ 464 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); 465 struct mt8186_afe_private *afe_priv = afe->platform_priv; 466 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id]; 467 468 if (dir != SND_SOC_CLOCK_IN) { 469 dev_err(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__); 470 return -EINVAL; 471 } 472 473 dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq); 474 475 return mtk_dai_tdm_cal_mclk(afe, tdm_priv, freq); 476} 477 478static int mtk_dai_tdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 479{ 480 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); 481 struct mt8186_afe_private *afe_priv = afe->platform_priv; 482 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id]; 483 484 /* DAI mode*/ 485 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 486 case SND_SOC_DAIFMT_I2S: 487 tdm_priv->tdm_mode = TDM_IN_I2S; 488 tdm_priv->data_mode = TDM_DATA_MULTI_PIN; 489 break; 490 case SND_SOC_DAIFMT_LEFT_J: 491 tdm_priv->tdm_mode = TDM_IN_LJ; 492 tdm_priv->data_mode = TDM_DATA_MULTI_PIN; 493 break; 494 case SND_SOC_DAIFMT_RIGHT_J: 495 tdm_priv->tdm_mode = TDM_IN_RJ; 496 tdm_priv->data_mode = TDM_DATA_MULTI_PIN; 497 break; 498 case SND_SOC_DAIFMT_DSP_A: 499 tdm_priv->tdm_mode = TDM_IN_DSP_A; 500 tdm_priv->data_mode = TDM_DATA_ONE_PIN; 501 break; 502 case SND_SOC_DAIFMT_DSP_B: 503 tdm_priv->tdm_mode = TDM_IN_DSP_B; 504 tdm_priv->data_mode = TDM_DATA_ONE_PIN; 505 break; 506 default: 507 dev_err(afe->dev, "%s(), invalid DAIFMT_FORMAT_MASK", __func__); 508 return -EINVAL; 509 } 510 511 /* DAI clock inversion*/ 512 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 513 case SND_SOC_DAIFMT_NB_NF: 514 tdm_priv->bck_invert = TDM_BCK_NON_INV; 515 tdm_priv->lck_invert = TDM_LCK_NON_INV; 516 break; 517 case SND_SOC_DAIFMT_NB_IF: 518 tdm_priv->bck_invert = TDM_BCK_NON_INV; 519 tdm_priv->lck_invert = TDM_LCK_INV; 520 break; 521 case SND_SOC_DAIFMT_IB_NF: 522 tdm_priv->bck_invert = TDM_BCK_INV; 523 tdm_priv->lck_invert = TDM_LCK_NON_INV; 524 break; 525 case SND_SOC_DAIFMT_IB_IF: 526 tdm_priv->bck_invert = TDM_BCK_INV; 527 tdm_priv->lck_invert = TDM_LCK_INV; 528 break; 529 default: 530 dev_err(afe->dev, "%s(), invalid DAIFMT_INV_MASK", __func__); 531 return -EINVAL; 532 } 533 534 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 535 case SND_SOC_DAIFMT_BP_FP: 536 tdm_priv->slave_mode = false; 537 break; 538 case SND_SOC_DAIFMT_BC_FC: 539 tdm_priv->slave_mode = true; 540 break; 541 default: 542 dev_err(afe->dev, "%s(), invalid DAIFMT_CLOCK_PROVIDER_MASK", 543 __func__); 544 return -EINVAL; 545 } 546 547 return 0; 548} 549 550static int mtk_dai_tdm_set_tdm_slot(struct snd_soc_dai *dai, 551 unsigned int tx_mask, 552 unsigned int rx_mask, 553 int slots, 554 int slot_width) 555{ 556 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); 557 struct mt8186_afe_private *afe_priv = afe->platform_priv; 558 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id]; 559 560 dev_dbg(dai->dev, "%s %d slot_width %d\n", __func__, dai->id, slot_width); 561 562 tdm_priv->lrck_width = slot_width; 563 564 return 0; 565} 566 567static const struct snd_soc_dai_ops mtk_dai_tdm_ops = { 568 .hw_params = mtk_dai_tdm_hw_params, 569 .set_sysclk = mtk_dai_tdm_set_sysclk, 570 .set_fmt = mtk_dai_tdm_set_fmt, 571 .set_tdm_slot = mtk_dai_tdm_set_tdm_slot, 572}; 573 574/* dai driver */ 575#define MTK_TDM_RATES (SNDRV_PCM_RATE_8000_48000 |\ 576 SNDRV_PCM_RATE_88200 |\ 577 SNDRV_PCM_RATE_96000 |\ 578 SNDRV_PCM_RATE_176400 |\ 579 SNDRV_PCM_RATE_192000) 580 581#define MTK_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 582 SNDRV_PCM_FMTBIT_S24_LE |\ 583 SNDRV_PCM_FMTBIT_S32_LE) 584 585static struct snd_soc_dai_driver mtk_dai_tdm_driver[] = { 586 { 587 .name = "TDM IN", 588 .id = MT8186_DAI_TDM_IN, 589 .capture = { 590 .stream_name = "TDM IN", 591 .channels_min = 2, 592 .channels_max = 8, 593 .rates = MTK_TDM_RATES, 594 .formats = MTK_TDM_FORMATS, 595 }, 596 .ops = &mtk_dai_tdm_ops, 597 }, 598}; 599 600static struct mtk_afe_tdm_priv *init_tdm_priv_data(struct mtk_base_afe *afe) 601{ 602 struct mtk_afe_tdm_priv *tdm_priv; 603 604 tdm_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_afe_tdm_priv), 605 GFP_KERNEL); 606 if (!tdm_priv) 607 return NULL; 608 609 tdm_priv->mclk_multiple = 512; 610 tdm_priv->mclk_id = MT8186_TDM_MCK; 611 tdm_priv->id = MT8186_DAI_TDM_IN; 612 613 return tdm_priv; 614} 615 616int mt8186_dai_tdm_register(struct mtk_base_afe *afe) 617{ 618 struct mt8186_afe_private *afe_priv = afe->platform_priv; 619 struct mtk_afe_tdm_priv *tdm_priv; 620 struct mtk_base_afe_dai *dai; 621 622 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 623 if (!dai) 624 return -ENOMEM; 625 626 list_add(&dai->list, &afe->sub_dais); 627 628 dai->dai_drivers = mtk_dai_tdm_driver; 629 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_tdm_driver); 630 631 dai->controls = mtk_dai_tdm_controls; 632 dai->num_controls = ARRAY_SIZE(mtk_dai_tdm_controls); 633 dai->dapm_widgets = mtk_dai_tdm_widgets; 634 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_tdm_widgets); 635 dai->dapm_routes = mtk_dai_tdm_routes; 636 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_tdm_routes); 637 638 tdm_priv = init_tdm_priv_data(afe); 639 if (!tdm_priv) 640 return -ENOMEM; 641 642 afe_priv->dai_priv[MT8186_DAI_TDM_IN] = tdm_priv; 643 644 return 0; 645} 646