mt8186-dai-tdm.c 18 KB

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