mt8186-dai-src.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // MediaTek ALSA SoC Audio DAI SRC Control
  4. //
  5. // Copyright (c) 2022 MediaTek Inc.
  6. // Author: Jiaxin Yu <[email protected]>
  7. #include <linux/regmap.h>
  8. #include "mt8186-afe-common.h"
  9. #include "mt8186-interconnection.h"
  10. struct mtk_afe_src_priv {
  11. int dl_rate;
  12. int ul_rate;
  13. };
  14. static const unsigned int src_iir_coeff_32_to_16[] = {
  15. 0x0dbae6, 0xff9b0a, 0x0dbae6, 0x05e488, 0xe072b9, 0x000002,
  16. 0x0dbae6, 0x000f3b, 0x0dbae6, 0x06a537, 0xe17d79, 0x000002,
  17. 0x0dbae6, 0x01246a, 0x0dbae6, 0x087261, 0xe306be, 0x000002,
  18. 0x0dbae6, 0x03437d, 0x0dbae6, 0x0bc16f, 0xe57c87, 0x000002,
  19. 0x0dbae6, 0x072981, 0x0dbae6, 0x111dd3, 0xe94f2a, 0x000002,
  20. 0x0dbae6, 0x0dc4a6, 0x0dbae6, 0x188611, 0xee85a0, 0x000002,
  21. 0x0dbae6, 0x168b9a, 0x0dbae6, 0x200e8f, 0xf3ccf1, 0x000002,
  22. 0x000000, 0x1b75cb, 0x1b75cb, 0x2374a2, 0x000000, 0x000001
  23. };
  24. static const unsigned int src_iir_coeff_44_to_16[] = {
  25. 0x09ae28, 0xf7d97d, 0x09ae28, 0x212a3d, 0xe0ac3a, 0x000002,
  26. 0x09ae28, 0xf8525a, 0x09ae28, 0x216d72, 0xe234be, 0x000002,
  27. 0x09ae28, 0xf980f5, 0x09ae28, 0x22a057, 0xe45a81, 0x000002,
  28. 0x09ae28, 0xfc0a08, 0x09ae28, 0x24d3bd, 0xe7752d, 0x000002,
  29. 0x09ae28, 0x016162, 0x09ae28, 0x27da01, 0xeb6ea8, 0x000002,
  30. 0x09ae28, 0x0b67df, 0x09ae28, 0x2aca4a, 0xef34c4, 0x000002,
  31. 0x000000, 0x135c50, 0x135c50, 0x2c1079, 0x000000, 0x000001
  32. };
  33. static const unsigned int src_iir_coeff_44_to_32[] = {
  34. 0x096966, 0x0c4d35, 0x096966, 0xedee81, 0xf05070, 0x000003,
  35. 0x12d2cc, 0x193910, 0x12d2cc, 0xddbf4f, 0xe21e1d, 0x000002,
  36. 0x12d2cc, 0x1a9e60, 0x12d2cc, 0xe18916, 0xe470fd, 0x000002,
  37. 0x12d2cc, 0x1d06e0, 0x12d2cc, 0xe8a4a6, 0xe87b24, 0x000002,
  38. 0x12d2cc, 0x207578, 0x12d2cc, 0xf4fe62, 0xef5917, 0x000002,
  39. 0x12d2cc, 0x24055f, 0x12d2cc, 0x05ee2b, 0xf8b502, 0x000002,
  40. 0x000000, 0x25a599, 0x25a599, 0x0fabe2, 0x000000, 0x000001
  41. };
  42. static const unsigned int src_iir_coeff_48_to_16[] = {
  43. 0x0296a4, 0xfd69dd, 0x0296a4, 0x209439, 0xe01ff9, 0x000002,
  44. 0x0f4ff3, 0xf0d6d4, 0x0f4ff3, 0x209bc9, 0xe076c3, 0x000002,
  45. 0x0e8490, 0xf1fe63, 0x0e8490, 0x20cfd6, 0xe12124, 0x000002,
  46. 0x14852f, 0xed794a, 0x14852f, 0x21503d, 0xe28b32, 0x000002,
  47. 0x136222, 0xf17677, 0x136222, 0x225be1, 0xe56964, 0x000002,
  48. 0x0a8d85, 0xfc4a97, 0x0a8d85, 0x24310c, 0xea6952, 0x000002,
  49. 0x05eff5, 0x043455, 0x05eff5, 0x4ced8f, 0xe134d6, 0x000001,
  50. 0x000000, 0x3aebe6, 0x3aebe6, 0x04f3b0, 0x000000, 0x000004
  51. };
  52. static const unsigned int src_iir_coeff_48_to_32[] = {
  53. 0x10c1b8, 0x10a7df, 0x10c1b8, 0xe7514e, 0xe0b41f, 0x000002,
  54. 0x10c1b8, 0x116257, 0x10c1b8, 0xe9402f, 0xe25aaa, 0x000002,
  55. 0x10c1b8, 0x130c89, 0x10c1b8, 0xed3cc3, 0xe4dddb, 0x000002,
  56. 0x10c1b8, 0x1600dd, 0x10c1b8, 0xf48000, 0xe90c55, 0x000002,
  57. 0x10c1b8, 0x1a672e, 0x10c1b8, 0x00494c, 0xefa807, 0x000002,
  58. 0x10c1b8, 0x1f38e6, 0x10c1b8, 0x0ee076, 0xf7c5f3, 0x000002,
  59. 0x000000, 0x218370, 0x218370, 0x168b40, 0x000000, 0x000001
  60. };
  61. static const unsigned int src_iir_coeff_48_to_44[] = {
  62. 0x0bf71c, 0x170f3f, 0x0bf71c, 0xe3a4c8, 0xf096cb, 0x000003,
  63. 0x0bf71c, 0x17395e, 0x0bf71c, 0xe58085, 0xf210c8, 0x000003,
  64. 0x0bf71c, 0x1782bd, 0x0bf71c, 0xe95ef6, 0xf4c899, 0x000003,
  65. 0x0bf71c, 0x17cd97, 0x0bf71c, 0xf1608a, 0xfa3b18, 0x000003,
  66. 0x000000, 0x2fdc6f, 0x2fdc6f, 0xf15663, 0x000000, 0x000001
  67. };
  68. static const unsigned int src_iir_coeff_96_to_16[] = {
  69. 0x0805a1, 0xf21ae3, 0x0805a1, 0x3840bb, 0xe02a2e, 0x000002,
  70. 0x0d5dd8, 0xe8f259, 0x0d5dd8, 0x1c0af6, 0xf04700, 0x000003,
  71. 0x0bb422, 0xec08d9, 0x0bb422, 0x1bfccc, 0xf09216, 0x000003,
  72. 0x08fde6, 0xf108be, 0x08fde6, 0x1bf096, 0xf10ae0, 0x000003,
  73. 0x0ae311, 0xeeeda3, 0x0ae311, 0x37c646, 0xe385f5, 0x000002,
  74. 0x044089, 0xfa7242, 0x044089, 0x37a785, 0xe56526, 0x000002,
  75. 0x00c75c, 0xffb947, 0x00c75c, 0x378ba3, 0xe72c5f, 0x000002,
  76. 0x000000, 0x0ef76e, 0x0ef76e, 0x377fda, 0x000000, 0x000001,
  77. };
  78. static const unsigned int src_iir_coeff_96_to_44[] = {
  79. 0x08b543, 0xfd80f4, 0x08b543, 0x0e2332, 0xe06ed0, 0x000002,
  80. 0x1b6038, 0xf90e7e, 0x1b6038, 0x0ec1ac, 0xe16f66, 0x000002,
  81. 0x188478, 0xfbb921, 0x188478, 0x105859, 0xe2e596, 0x000002,
  82. 0x13eff3, 0xffa707, 0x13eff3, 0x13455c, 0xe533b7, 0x000002,
  83. 0x0dc239, 0x03d458, 0x0dc239, 0x17f120, 0xe8b617, 0x000002,
  84. 0x0745f1, 0x05d790, 0x0745f1, 0x1e3d75, 0xed5f18, 0x000002,
  85. 0x05641f, 0x085e2b, 0x05641f, 0x48efd0, 0xe3e9c8, 0x000001,
  86. 0x000000, 0x28f632, 0x28f632, 0x273905, 0x000000, 0x000001,
  87. };
  88. static unsigned int mtk_get_src_freq_mode(struct mtk_base_afe *afe, int rate)
  89. {
  90. switch (rate) {
  91. case 8000:
  92. return 0x50000;
  93. case 11025:
  94. return 0x6e400;
  95. case 12000:
  96. return 0x78000;
  97. case 16000:
  98. return 0xa0000;
  99. case 22050:
  100. return 0xdc800;
  101. case 24000:
  102. return 0xf0000;
  103. case 32000:
  104. return 0x140000;
  105. case 44100:
  106. return 0x1b9000;
  107. case 48000:
  108. return 0x1e0000;
  109. case 88200:
  110. return 0x372000;
  111. case 96000:
  112. return 0x3c0000;
  113. case 176400:
  114. return 0x6e4000;
  115. case 192000:
  116. return 0x780000;
  117. default:
  118. dev_err(afe->dev, "%s(), rate %d invalid!!!\n",
  119. __func__, rate);
  120. return 0;
  121. }
  122. }
  123. static const unsigned int *get_iir_coeff(unsigned int rate_in,
  124. unsigned int rate_out,
  125. unsigned int *param_num)
  126. {
  127. if (rate_in == 32000 && rate_out == 16000) {
  128. *param_num = ARRAY_SIZE(src_iir_coeff_32_to_16);
  129. return src_iir_coeff_32_to_16;
  130. } else if (rate_in == 44100 && rate_out == 16000) {
  131. *param_num = ARRAY_SIZE(src_iir_coeff_44_to_16);
  132. return src_iir_coeff_44_to_16;
  133. } else if (rate_in == 44100 && rate_out == 32000) {
  134. *param_num = ARRAY_SIZE(src_iir_coeff_44_to_32);
  135. return src_iir_coeff_44_to_32;
  136. } else if ((rate_in == 48000 && rate_out == 16000) ||
  137. (rate_in == 96000 && rate_out == 32000)) {
  138. *param_num = ARRAY_SIZE(src_iir_coeff_48_to_16);
  139. return src_iir_coeff_48_to_16;
  140. } else if (rate_in == 48000 && rate_out == 32000) {
  141. *param_num = ARRAY_SIZE(src_iir_coeff_48_to_32);
  142. return src_iir_coeff_48_to_32;
  143. } else if (rate_in == 48000 && rate_out == 44100) {
  144. *param_num = ARRAY_SIZE(src_iir_coeff_48_to_44);
  145. return src_iir_coeff_48_to_44;
  146. } else if (rate_in == 96000 && rate_out == 16000) {
  147. *param_num = ARRAY_SIZE(src_iir_coeff_96_to_16);
  148. return src_iir_coeff_96_to_16;
  149. } else if ((rate_in == 96000 && rate_out == 44100) ||
  150. (rate_in == 48000 && rate_out == 22050)) {
  151. *param_num = ARRAY_SIZE(src_iir_coeff_96_to_44);
  152. return src_iir_coeff_96_to_44;
  153. }
  154. *param_num = 0;
  155. return NULL;
  156. }
  157. static int mtk_set_src_1_param(struct mtk_base_afe *afe, int id)
  158. {
  159. struct mt8186_afe_private *afe_priv = afe->platform_priv;
  160. struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
  161. unsigned int iir_coeff_num;
  162. unsigned int iir_stage;
  163. int rate_in = src_priv->dl_rate;
  164. int rate_out = src_priv->ul_rate;
  165. unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out);
  166. unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in);
  167. /* set out freq mode */
  168. regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON3,
  169. G_SRC_ASM_FREQ_4_MASK_SFT,
  170. out_freq_mode << G_SRC_ASM_FREQ_4_SFT);
  171. /* set in freq mode */
  172. regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON4,
  173. G_SRC_ASM_FREQ_5_MASK_SFT,
  174. in_freq_mode << G_SRC_ASM_FREQ_5_SFT);
  175. regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5986);
  176. regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5987);
  177. regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON6, 0x1fbd);
  178. regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, 0);
  179. /* set iir if in_rate > out_rate */
  180. if (rate_in > rate_out) {
  181. int i;
  182. const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out,
  183. &iir_coeff_num);
  184. if (iir_coeff_num == 0 || !iir_coeff) {
  185. dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n",
  186. __func__, iir_coeff_num, iir_coeff);
  187. return -EINVAL;
  188. }
  189. /* COEFF_SRAM_CTRL */
  190. regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0,
  191. G_SRC_COEFF_SRAM_CTRL_MASK_SFT,
  192. BIT(G_SRC_COEFF_SRAM_CTRL_SFT));
  193. /* Clear coeff history to r/w coeff from the first position */
  194. regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON13,
  195. G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0);
  196. /* Write SRC coeff, should not read the reg during write */
  197. for (i = 0; i < iir_coeff_num; i++)
  198. regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON12,
  199. iir_coeff[i]);
  200. /* disable sram access */
  201. regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0,
  202. G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0);
  203. /* CHSET_IIR_STAGE */
  204. iir_stage = (iir_coeff_num / 6) - 1;
  205. regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
  206. G_SRC_CHSET_IIR_STAGE_MASK_SFT,
  207. iir_stage << G_SRC_CHSET_IIR_STAGE_SFT);
  208. /* CHSET_IIR_EN */
  209. regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
  210. G_SRC_CHSET_IIR_EN_MASK_SFT,
  211. BIT(G_SRC_CHSET_IIR_EN_SFT));
  212. } else {
  213. /* CHSET_IIR_EN off */
  214. regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
  215. G_SRC_CHSET_IIR_EN_MASK_SFT, 0);
  216. }
  217. return 0;
  218. }
  219. static int mtk_set_src_2_param(struct mtk_base_afe *afe, int id)
  220. {
  221. struct mt8186_afe_private *afe_priv = afe->platform_priv;
  222. struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
  223. unsigned int iir_coeff_num;
  224. unsigned int iir_stage;
  225. int rate_in = src_priv->dl_rate;
  226. int rate_out = src_priv->ul_rate;
  227. unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out);
  228. unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in);
  229. /* set out freq mode */
  230. regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON3,
  231. G_SRC_ASM_FREQ_4_MASK_SFT,
  232. out_freq_mode << G_SRC_ASM_FREQ_4_SFT);
  233. /* set in freq mode */
  234. regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON4,
  235. G_SRC_ASM_FREQ_5_MASK_SFT,
  236. in_freq_mode << G_SRC_ASM_FREQ_5_SFT);
  237. regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5986);
  238. regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5987);
  239. regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON6, 0x1fbd);
  240. regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, 0);
  241. /* set iir if in_rate > out_rate */
  242. if (rate_in > rate_out) {
  243. int i;
  244. const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out,
  245. &iir_coeff_num);
  246. if (iir_coeff_num == 0 || !iir_coeff) {
  247. dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n",
  248. __func__, iir_coeff_num, iir_coeff);
  249. return -EINVAL;
  250. }
  251. /* COEFF_SRAM_CTRL */
  252. regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0,
  253. G_SRC_COEFF_SRAM_CTRL_MASK_SFT,
  254. BIT(G_SRC_COEFF_SRAM_CTRL_SFT));
  255. /* Clear coeff history to r/w coeff from the first position */
  256. regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON13,
  257. G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0);
  258. /* Write SRC coeff, should not read the reg during write */
  259. for (i = 0; i < iir_coeff_num; i++)
  260. regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON12,
  261. iir_coeff[i]);
  262. /* disable sram access */
  263. regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0,
  264. G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0);
  265. /* CHSET_IIR_STAGE */
  266. iir_stage = (iir_coeff_num / 6) - 1;
  267. regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
  268. G_SRC_CHSET_IIR_STAGE_MASK_SFT,
  269. iir_stage << G_SRC_CHSET_IIR_STAGE_SFT);
  270. /* CHSET_IIR_EN */
  271. regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
  272. G_SRC_CHSET_IIR_EN_MASK_SFT,
  273. BIT(G_SRC_CHSET_IIR_EN_SFT));
  274. } else {
  275. /* CHSET_IIR_EN off */
  276. regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
  277. G_SRC_CHSET_IIR_EN_MASK_SFT, 0);
  278. }
  279. return 0;
  280. }
  281. #define HW_SRC_1_EN_W_NAME "HW_SRC_1_Enable"
  282. #define HW_SRC_2_EN_W_NAME "HW_SRC_2_Enable"
  283. static int mtk_hw_src_event(struct snd_soc_dapm_widget *w,
  284. struct snd_kcontrol *kcontrol,
  285. int event)
  286. {
  287. struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
  288. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  289. struct mt8186_afe_private *afe_priv = afe->platform_priv;
  290. int id;
  291. struct mtk_afe_src_priv *src_priv;
  292. unsigned int reg;
  293. if (strcmp(w->name, HW_SRC_1_EN_W_NAME) == 0)
  294. id = MT8186_DAI_SRC_1;
  295. else
  296. id = MT8186_DAI_SRC_2;
  297. src_priv = afe_priv->dai_priv[id];
  298. dev_dbg(afe->dev,
  299. "%s(), name %s, event 0x%x, id %d, src_priv %p, dl_rate %d, ul_rate %d\n",
  300. __func__, w->name, event, id, src_priv,
  301. src_priv->dl_rate, src_priv->ul_rate);
  302. switch (event) {
  303. case SND_SOC_DAPM_PRE_PMU:
  304. if (id == MT8186_DAI_SRC_1)
  305. mtk_set_src_1_param(afe, id);
  306. else
  307. mtk_set_src_2_param(afe, id);
  308. break;
  309. case SND_SOC_DAPM_POST_PMU:
  310. reg = (id == MT8186_DAI_SRC_1) ?
  311. AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0;
  312. /* ASM_ON */
  313. regmap_update_bits(afe->regmap, reg,
  314. G_SRC_ASM_ON_MASK_SFT,
  315. BIT(G_SRC_ASM_ON_SFT));
  316. /* CHSET_ON */
  317. regmap_update_bits(afe->regmap, reg,
  318. G_SRC_CHSET_ON_MASK_SFT,
  319. BIT(G_SRC_CHSET_ON_SFT));
  320. /* CHSET_STR_CLR */
  321. regmap_update_bits(afe->regmap, reg,
  322. G_SRC_CHSET_STR_CLR_MASK_SFT,
  323. BIT(G_SRC_CHSET_STR_CLR_SFT));
  324. break;
  325. case SND_SOC_DAPM_PRE_PMD:
  326. reg = (id == MT8186_DAI_SRC_1) ?
  327. AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0;
  328. /* ASM_OFF */
  329. regmap_update_bits(afe->regmap, reg, G_SRC_ASM_ON_MASK_SFT, 0);
  330. /* CHSET_OFF */
  331. regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_ON_MASK_SFT, 0);
  332. /* CHSET_STR_CLR */
  333. regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_STR_CLR_MASK_SFT, 0);
  334. break;
  335. default:
  336. break;
  337. }
  338. return 0;
  339. }
  340. /* dai component */
  341. static const struct snd_kcontrol_new mtk_hw_src_1_in_ch1_mix[] = {
  342. SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN40,
  343. I_DL1_CH1, 1, 0),
  344. SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN40,
  345. I_DL2_CH1, 1, 0),
  346. SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN40,
  347. I_DL3_CH1, 1, 0),
  348. SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN40_1,
  349. I_DL4_CH1, 1, 0),
  350. SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN40_1,
  351. I_DL6_CH1, 1, 0),
  352. SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH1 Switch", AFE_CONN40,
  353. I_I2S0_CH1, 1, 0),
  354. SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN40_1,
  355. I_DL5_CH1, 1, 0),
  356. };
  357. static const struct snd_kcontrol_new mtk_hw_src_1_in_ch2_mix[] = {
  358. SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN41,
  359. I_DL1_CH2, 1, 0),
  360. SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN41,
  361. I_DL2_CH2, 1, 0),
  362. SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN41,
  363. I_DL3_CH2, 1, 0),
  364. SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN41_1,
  365. I_DL4_CH2, 1, 0),
  366. SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN41_1,
  367. I_DL6_CH2, 1, 0),
  368. SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH2 Switch", AFE_CONN41,
  369. I_I2S0_CH2, 1, 0),
  370. SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN41_1,
  371. I_DL5_CH2, 1, 0),
  372. };
  373. static const struct snd_kcontrol_new mtk_hw_src_2_in_ch1_mix[] = {
  374. SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN42,
  375. I_DL1_CH1, 1, 0),
  376. SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN42,
  377. I_DL2_CH1, 1, 0),
  378. SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN42,
  379. I_DL3_CH1, 1, 0),
  380. SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN42,
  381. I_DL4_CH1, 1, 0),
  382. SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN42_1,
  383. I_DL5_CH1, 1, 0),
  384. SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN42_1,
  385. I_DL6_CH1, 1, 0),
  386. SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH1 Switch", AFE_CONN42,
  387. I_GAIN2_OUT_CH1, 1, 0),
  388. };
  389. static const struct snd_kcontrol_new mtk_hw_src_2_in_ch2_mix[] = {
  390. SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN43,
  391. I_DL1_CH2, 1, 0),
  392. SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN43,
  393. I_DL2_CH2, 1, 0),
  394. SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN43,
  395. I_DL3_CH2, 1, 0),
  396. SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN43,
  397. I_DL4_CH2, 1, 0),
  398. SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN43_1,
  399. I_DL5_CH2, 1, 0),
  400. SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN43_1,
  401. I_DL6_CH2, 1, 0),
  402. SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH2 Switch", AFE_CONN43,
  403. I_GAIN2_OUT_CH2, 1, 0),
  404. };
  405. static const struct snd_soc_dapm_widget mtk_dai_src_widgets[] = {
  406. /* inter-connections */
  407. SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH1", SND_SOC_NOPM, 0, 0,
  408. mtk_hw_src_1_in_ch1_mix,
  409. ARRAY_SIZE(mtk_hw_src_1_in_ch1_mix)),
  410. SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH2", SND_SOC_NOPM, 0, 0,
  411. mtk_hw_src_1_in_ch2_mix,
  412. ARRAY_SIZE(mtk_hw_src_1_in_ch2_mix)),
  413. SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH1", SND_SOC_NOPM, 0, 0,
  414. mtk_hw_src_2_in_ch1_mix,
  415. ARRAY_SIZE(mtk_hw_src_2_in_ch1_mix)),
  416. SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH2", SND_SOC_NOPM, 0, 0,
  417. mtk_hw_src_2_in_ch2_mix,
  418. ARRAY_SIZE(mtk_hw_src_2_in_ch2_mix)),
  419. SND_SOC_DAPM_SUPPLY(HW_SRC_1_EN_W_NAME,
  420. GENERAL_ASRC_EN_ON, GENERAL1_ASRC_EN_ON_SFT, 0,
  421. mtk_hw_src_event,
  422. SND_SOC_DAPM_PRE_PMU |
  423. SND_SOC_DAPM_POST_PMU |
  424. SND_SOC_DAPM_PRE_PMD),
  425. SND_SOC_DAPM_SUPPLY(HW_SRC_2_EN_W_NAME,
  426. GENERAL_ASRC_EN_ON, GENERAL2_ASRC_EN_ON_SFT, 0,
  427. mtk_hw_src_event,
  428. SND_SOC_DAPM_PRE_PMU |
  429. SND_SOC_DAPM_POST_PMU |
  430. SND_SOC_DAPM_PRE_PMD),
  431. SND_SOC_DAPM_INPUT("HW SRC 1 Out Endpoint"),
  432. SND_SOC_DAPM_INPUT("HW SRC 2 Out Endpoint"),
  433. SND_SOC_DAPM_OUTPUT("HW SRC 1 In Endpoint"),
  434. SND_SOC_DAPM_OUTPUT("HW SRC 2 In Endpoint"),
  435. };
  436. static int mtk_afe_src_en_connect(struct snd_soc_dapm_widget *source,
  437. struct snd_soc_dapm_widget *sink)
  438. {
  439. struct snd_soc_dapm_widget *w = source;
  440. struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
  441. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  442. struct mt8186_afe_private *afe_priv = afe->platform_priv;
  443. struct mtk_afe_src_priv *src_priv;
  444. if (strcmp(w->name, HW_SRC_1_EN_W_NAME) == 0)
  445. src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_1];
  446. else
  447. src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_2];
  448. dev_dbg(afe->dev,
  449. "%s(), source %s, sink %s, dl_rate %d, ul_rate %d\n",
  450. __func__, source->name, sink->name,
  451. src_priv->dl_rate, src_priv->ul_rate);
  452. return (src_priv->dl_rate > 0 && src_priv->ul_rate > 0) ? 1 : 0;
  453. }
  454. static const struct snd_soc_dapm_route mtk_dai_src_routes[] = {
  455. {"HW_SRC_1_IN_CH1", "DL1_CH1 Switch", "DL1"},
  456. {"HW_SRC_1_IN_CH2", "DL1_CH2 Switch", "DL1"},
  457. {"HW_SRC_2_IN_CH1", "DL1_CH1 Switch", "DL1"},
  458. {"HW_SRC_2_IN_CH2", "DL1_CH2 Switch", "DL1"},
  459. {"HW_SRC_1_IN_CH1", "DL2_CH1 Switch", "DL2"},
  460. {"HW_SRC_1_IN_CH2", "DL2_CH2 Switch", "DL2"},
  461. {"HW_SRC_2_IN_CH1", "DL2_CH1 Switch", "DL2"},
  462. {"HW_SRC_2_IN_CH2", "DL2_CH2 Switch", "DL2"},
  463. {"HW_SRC_1_IN_CH1", "DL3_CH1 Switch", "DL3"},
  464. {"HW_SRC_1_IN_CH2", "DL3_CH2 Switch", "DL3"},
  465. {"HW_SRC_2_IN_CH1", "DL3_CH1 Switch", "DL3"},
  466. {"HW_SRC_2_IN_CH2", "DL3_CH2 Switch", "DL3"},
  467. {"HW_SRC_1_IN_CH1", "DL6_CH1 Switch", "DL6"},
  468. {"HW_SRC_1_IN_CH2", "DL6_CH2 Switch", "DL6"},
  469. {"HW_SRC_2_IN_CH1", "DL6_CH1 Switch", "DL6"},
  470. {"HW_SRC_2_IN_CH2", "DL6_CH2 Switch", "DL6"},
  471. {"HW_SRC_1_IN_CH1", "DL5_CH1 Switch", "DL5"},
  472. {"HW_SRC_1_IN_CH2", "DL5_CH2 Switch", "DL5"},
  473. {"HW_SRC_2_IN_CH1", "DL5_CH1 Switch", "DL5"},
  474. {"HW_SRC_2_IN_CH2", "DL5_CH2 Switch", "DL5"},
  475. {"HW_SRC_1_IN_CH1", "DL4_CH1 Switch", "DL4"},
  476. {"HW_SRC_1_IN_CH2", "DL4_CH2 Switch", "DL4"},
  477. {"HW_SRC_2_IN_CH1", "DL4_CH1 Switch", "DL4"},
  478. {"HW_SRC_2_IN_CH2", "DL4_CH2 Switch", "DL4"},
  479. {"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH1"},
  480. {"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH2"},
  481. {"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH1"},
  482. {"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH2"},
  483. {"HW_SRC_1_In", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect},
  484. {"HW_SRC_1_Out", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect},
  485. {"HW_SRC_2_In", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect},
  486. {"HW_SRC_2_Out", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect},
  487. {"HW SRC 1 In Endpoint", NULL, "HW_SRC_1_In"},
  488. {"HW SRC 2 In Endpoint", NULL, "HW_SRC_2_In"},
  489. {"HW_SRC_1_Out", NULL, "HW SRC 1 Out Endpoint"},
  490. {"HW_SRC_2_Out", NULL, "HW SRC 2 Out Endpoint"},
  491. };
  492. /* dai ops */
  493. static int mtk_dai_src_hw_params(struct snd_pcm_substream *substream,
  494. struct snd_pcm_hw_params *params,
  495. struct snd_soc_dai *dai)
  496. {
  497. struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
  498. struct mt8186_afe_private *afe_priv = afe->platform_priv;
  499. int id = dai->id;
  500. struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
  501. unsigned int sft, mask;
  502. unsigned int rate = params_rate(params);
  503. unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, id);
  504. dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
  505. __func__, id, substream->stream, rate);
  506. /* rate */
  507. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  508. src_priv->dl_rate = rate;
  509. if (id == MT8186_DAI_SRC_1) {
  510. sft = GENERAL1_ASRCIN_MODE_SFT;
  511. mask = GENERAL1_ASRCIN_MODE_MASK;
  512. } else {
  513. sft = GENERAL2_ASRCIN_MODE_SFT;
  514. mask = GENERAL2_ASRCIN_MODE_MASK;
  515. }
  516. } else {
  517. src_priv->ul_rate = rate;
  518. if (id == MT8186_DAI_SRC_1) {
  519. sft = GENERAL1_ASRCOUT_MODE_SFT;
  520. mask = GENERAL1_ASRCOUT_MODE_MASK;
  521. } else {
  522. sft = GENERAL2_ASRCOUT_MODE_SFT;
  523. mask = GENERAL2_ASRCOUT_MODE_MASK;
  524. }
  525. }
  526. regmap_update_bits(afe->regmap, GENERAL_ASRC_MODE, mask << sft, rate_reg << sft);
  527. return 0;
  528. }
  529. static int mtk_dai_src_hw_free(struct snd_pcm_substream *substream,
  530. struct snd_soc_dai *dai)
  531. {
  532. struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
  533. struct mt8186_afe_private *afe_priv = afe->platform_priv;
  534. int id = dai->id;
  535. struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
  536. dev_dbg(afe->dev, "%s(), id %d, stream %d\n",
  537. __func__, id, substream->stream);
  538. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  539. src_priv->dl_rate = 0;
  540. else
  541. src_priv->ul_rate = 0;
  542. return 0;
  543. }
  544. static const struct snd_soc_dai_ops mtk_dai_src_ops = {
  545. .hw_params = mtk_dai_src_hw_params,
  546. .hw_free = mtk_dai_src_hw_free,
  547. };
  548. /* dai driver */
  549. #define MTK_SRC_RATES (SNDRV_PCM_RATE_8000_48000 |\
  550. SNDRV_PCM_RATE_88200 |\
  551. SNDRV_PCM_RATE_96000 |\
  552. SNDRV_PCM_RATE_176400 |\
  553. SNDRV_PCM_RATE_192000)
  554. #define MTK_SRC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
  555. SNDRV_PCM_FMTBIT_S24_LE |\
  556. SNDRV_PCM_FMTBIT_S32_LE)
  557. static struct snd_soc_dai_driver mtk_dai_src_driver[] = {
  558. {
  559. .name = "HW_SRC_1",
  560. .id = MT8186_DAI_SRC_1,
  561. .playback = {
  562. .stream_name = "HW_SRC_1_In",
  563. .channels_min = 1,
  564. .channels_max = 2,
  565. .rates = MTK_SRC_RATES,
  566. .formats = MTK_SRC_FORMATS,
  567. },
  568. .capture = {
  569. .stream_name = "HW_SRC_1_Out",
  570. .channels_min = 1,
  571. .channels_max = 2,
  572. .rates = MTK_SRC_RATES,
  573. .formats = MTK_SRC_FORMATS,
  574. },
  575. .ops = &mtk_dai_src_ops,
  576. },
  577. {
  578. .name = "HW_SRC_2",
  579. .id = MT8186_DAI_SRC_2,
  580. .playback = {
  581. .stream_name = "HW_SRC_2_In",
  582. .channels_min = 1,
  583. .channels_max = 2,
  584. .rates = MTK_SRC_RATES,
  585. .formats = MTK_SRC_FORMATS,
  586. },
  587. .capture = {
  588. .stream_name = "HW_SRC_2_Out",
  589. .channels_min = 1,
  590. .channels_max = 2,
  591. .rates = MTK_SRC_RATES,
  592. .formats = MTK_SRC_FORMATS,
  593. },
  594. .ops = &mtk_dai_src_ops,
  595. },
  596. };
  597. int mt8186_dai_src_register(struct mtk_base_afe *afe)
  598. {
  599. struct mtk_base_afe_dai *dai;
  600. int ret;
  601. dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
  602. if (!dai)
  603. return -ENOMEM;
  604. list_add(&dai->list, &afe->sub_dais);
  605. dai->dai_drivers = mtk_dai_src_driver;
  606. dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_src_driver);
  607. dai->dapm_widgets = mtk_dai_src_widgets;
  608. dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_src_widgets);
  609. dai->dapm_routes = mtk_dai_src_routes;
  610. dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_src_routes);
  611. /* set dai priv */
  612. ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_1,
  613. sizeof(struct mtk_afe_src_priv), NULL);
  614. if (ret)
  615. return ret;
  616. ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_2,
  617. sizeof(struct mtk_afe_src_priv), NULL);
  618. if (ret)
  619. return ret;
  620. return 0;
  621. }