mt8186-dai-i2s.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // MediaTek ALSA SoC Audio DAI I2S Control
  4. //
  5. // Copyright (c) 2022 MediaTek Inc.
  6. // Author: Jiaxin Yu <[email protected]>
  7. #include <linux/bitops.h>
  8. #include <linux/regmap.h>
  9. #include <sound/pcm_params.h>
  10. #include "mt8186-afe-clk.h"
  11. #include "mt8186-afe-common.h"
  12. #include "mt8186-afe-gpio.h"
  13. #include "mt8186-interconnection.h"
  14. enum {
  15. I2S_FMT_EIAJ = 0,
  16. I2S_FMT_I2S = 1,
  17. };
  18. enum {
  19. I2S_WLEN_16_BIT = 0,
  20. I2S_WLEN_32_BIT = 1,
  21. };
  22. enum {
  23. I2S_HD_NORMAL = 0,
  24. I2S_HD_LOW_JITTER = 1,
  25. };
  26. enum {
  27. I2S1_SEL_O28_O29 = 0,
  28. I2S1_SEL_O03_O04 = 1,
  29. };
  30. enum {
  31. I2S_IN_PAD_CONNSYS = 0,
  32. I2S_IN_PAD_IO_MUX = 1,
  33. };
  34. struct mtk_afe_i2s_priv {
  35. int id;
  36. int rate; /* for determine which apll to use */
  37. int low_jitter_en;
  38. int master; /* only i2s0 has slave mode*/
  39. int share_i2s_id;
  40. int mclk_id;
  41. int mclk_rate;
  42. int mclk_apll;
  43. };
  44. static unsigned int get_i2s_wlen(snd_pcm_format_t format)
  45. {
  46. return snd_pcm_format_physical_width(format) <= 16 ?
  47. I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;
  48. }
  49. #define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux"
  50. #define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux"
  51. #define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux"
  52. #define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux"
  53. #define MTK_AFE_I2S0_SRC_KCONTROL_NAME "I2S0_SRC_Mux"
  54. #define I2S0_HD_EN_W_NAME "I2S0_HD_EN"
  55. #define I2S1_HD_EN_W_NAME "I2S1_HD_EN"
  56. #define I2S2_HD_EN_W_NAME "I2S2_HD_EN"
  57. #define I2S3_HD_EN_W_NAME "I2S3_HD_EN"
  58. #define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN"
  59. #define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN"
  60. #define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN"
  61. #define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN"
  62. static int get_i2s_id_by_name(struct mtk_base_afe *afe,
  63. const char *name)
  64. {
  65. if (strncmp(name, "I2S0", 4) == 0)
  66. return MT8186_DAI_I2S_0;
  67. else if (strncmp(name, "I2S1", 4) == 0)
  68. return MT8186_DAI_I2S_1;
  69. else if (strncmp(name, "I2S2", 4) == 0)
  70. return MT8186_DAI_I2S_2;
  71. else if (strncmp(name, "I2S3", 4) == 0)
  72. return MT8186_DAI_I2S_3;
  73. return -EINVAL;
  74. }
  75. static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,
  76. const char *name)
  77. {
  78. struct mt8186_afe_private *afe_priv = afe->platform_priv;
  79. int dai_id = get_i2s_id_by_name(afe, name);
  80. if (dai_id < 0)
  81. return NULL;
  82. return afe_priv->dai_priv[dai_id];
  83. }
  84. /* low jitter control */
  85. static const char * const mt8186_i2s_hd_str[] = {
  86. "Normal", "Low_Jitter"
  87. };
  88. static const struct soc_enum mt8186_i2s_enum[] = {
  89. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_i2s_hd_str),
  90. mt8186_i2s_hd_str),
  91. };
  92. static int mt8186_i2s_hd_get(struct snd_kcontrol *kcontrol,
  93. struct snd_ctl_elem_value *ucontrol)
  94. {
  95. struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
  96. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  97. struct mtk_afe_i2s_priv *i2s_priv;
  98. i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
  99. ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;
  100. return 0;
  101. }
  102. static int mt8186_i2s_hd_set(struct snd_kcontrol *kcontrol,
  103. struct snd_ctl_elem_value *ucontrol)
  104. {
  105. struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
  106. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  107. struct mtk_afe_i2s_priv *i2s_priv;
  108. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  109. int hd_en;
  110. if (ucontrol->value.enumerated.item[0] >= e->items)
  111. return -EINVAL;
  112. hd_en = ucontrol->value.integer.value[0];
  113. dev_dbg(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
  114. __func__, kcontrol->id.name, hd_en);
  115. i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
  116. if (i2s_priv->low_jitter_en == hd_en)
  117. return 0;
  118. i2s_priv->low_jitter_en = hd_en;
  119. return 1;
  120. }
  121. static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {
  122. SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8186_i2s_enum[0],
  123. mt8186_i2s_hd_get, mt8186_i2s_hd_set),
  124. SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8186_i2s_enum[0],
  125. mt8186_i2s_hd_get, mt8186_i2s_hd_set),
  126. SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8186_i2s_enum[0],
  127. mt8186_i2s_hd_get, mt8186_i2s_hd_set),
  128. SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8186_i2s_enum[0],
  129. mt8186_i2s_hd_get, mt8186_i2s_hd_set),
  130. };
  131. /* dai component */
  132. /* i2s virtual mux to output widget */
  133. static const char * const i2s_mux_map[] = {
  134. "Normal", "Dummy_Widget",
  135. };
  136. static int i2s_mux_map_value[] = {
  137. 0, 1,
  138. };
  139. static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s_mux_map_enum,
  140. SND_SOC_NOPM,
  141. 0,
  142. 1,
  143. i2s_mux_map,
  144. i2s_mux_map_value);
  145. static const struct snd_kcontrol_new i2s0_in_mux_control =
  146. SOC_DAPM_ENUM("I2S0 In Select", i2s_mux_map_enum);
  147. static const struct snd_kcontrol_new i2s1_out_mux_control =
  148. SOC_DAPM_ENUM("I2S1 Out Select", i2s_mux_map_enum);
  149. static const struct snd_kcontrol_new i2s2_in_mux_control =
  150. SOC_DAPM_ENUM("I2S2 In Select", i2s_mux_map_enum);
  151. static const struct snd_kcontrol_new i2s3_out_mux_control =
  152. SOC_DAPM_ENUM("I2S3 Out Select", i2s_mux_map_enum);
  153. /* i2s in lpbk */
  154. static const char * const i2s_lpbk_mux_map[] = {
  155. "Normal", "Lpbk",
  156. };
  157. static int i2s_lpbk_mux_map_value[] = {
  158. 0, 1,
  159. };
  160. static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s0_lpbk_mux_map_enum,
  161. AFE_I2S_CON,
  162. I2S_LOOPBACK_SFT,
  163. 1,
  164. i2s_lpbk_mux_map,
  165. i2s_lpbk_mux_map_value);
  166. static const struct snd_kcontrol_new i2s0_lpbk_mux_control =
  167. SOC_DAPM_ENUM("I2S Lpbk Select", i2s0_lpbk_mux_map_enum);
  168. static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s2_lpbk_mux_map_enum,
  169. AFE_I2S_CON2,
  170. I2S3_LOOPBACK_SFT,
  171. 1,
  172. i2s_lpbk_mux_map,
  173. i2s_lpbk_mux_map_value);
  174. static const struct snd_kcontrol_new i2s2_lpbk_mux_control =
  175. SOC_DAPM_ENUM("I2S Lpbk Select", i2s2_lpbk_mux_map_enum);
  176. /* interconnection */
  177. static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = {
  178. SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN0,
  179. I_DL1_CH1, 1, 0),
  180. SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN0,
  181. I_DL2_CH1, 1, 0),
  182. SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN0,
  183. I_DL3_CH1, 1, 0),
  184. SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN0,
  185. I_DL12_CH1, 1, 0),
  186. SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN0,
  187. I_DL12_CH3, 1, 0),
  188. SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN0_1,
  189. I_DL6_CH1, 1, 0),
  190. SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN0_1,
  191. I_DL4_CH1, 1, 0),
  192. SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN0_1,
  193. I_DL5_CH1, 1, 0),
  194. SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN0_1,
  195. I_DL8_CH1, 1, 0),
  196. SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN0,
  197. I_GAIN1_OUT_CH1, 1, 0),
  198. SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN0,
  199. I_ADDA_UL_CH1, 1, 0),
  200. SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN0,
  201. I_ADDA_UL_CH2, 1, 0),
  202. SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN0,
  203. I_ADDA_UL_CH3, 1, 0),
  204. SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN0,
  205. I_PCM_1_CAP_CH1, 1, 0),
  206. SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN0_1,
  207. I_SRC_1_OUT_CH1, 1, 0),
  208. };
  209. static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = {
  210. SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN1,
  211. I_DL1_CH2, 1, 0),
  212. SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN1,
  213. I_DL2_CH2, 1, 0),
  214. SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN1,
  215. I_DL3_CH2, 1, 0),
  216. SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN1,
  217. I_DL12_CH2, 1, 0),
  218. SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN1,
  219. I_DL12_CH4, 1, 0),
  220. SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN1_1,
  221. I_DL6_CH2, 1, 0),
  222. SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN1_1,
  223. I_DL4_CH2, 1, 0),
  224. SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN1_1,
  225. I_DL5_CH2, 1, 0),
  226. SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN1_1,
  227. I_DL8_CH2, 1, 0),
  228. SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN1,
  229. I_GAIN1_OUT_CH2, 1, 0),
  230. SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN1,
  231. I_ADDA_UL_CH1, 1, 0),
  232. SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN1,
  233. I_ADDA_UL_CH2, 1, 0),
  234. SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN1,
  235. I_ADDA_UL_CH3, 1, 0),
  236. SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN1,
  237. I_PCM_1_CAP_CH2, 1, 0),
  238. SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN1,
  239. I_PCM_2_CAP_CH2, 1, 0),
  240. SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN1_1,
  241. I_SRC_1_OUT_CH2, 1, 0),
  242. };
  243. static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = {
  244. SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN28,
  245. I_DL1_CH1, 1, 0),
  246. SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN28,
  247. I_DL2_CH1, 1, 0),
  248. SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN28,
  249. I_DL3_CH1, 1, 0),
  250. SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN28,
  251. I_DL12_CH1, 1, 0),
  252. SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN28,
  253. I_DL12_CH3, 1, 0),
  254. SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN28_1,
  255. I_DL6_CH1, 1, 0),
  256. SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN28_1,
  257. I_DL4_CH1, 1, 0),
  258. SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN28_1,
  259. I_DL5_CH1, 1, 0),
  260. SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN28_1,
  261. I_DL8_CH1, 1, 0),
  262. SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN28,
  263. I_GAIN1_OUT_CH1, 1, 0),
  264. SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN28,
  265. I_ADDA_UL_CH1, 1, 0),
  266. SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN28,
  267. I_PCM_1_CAP_CH1, 1, 0),
  268. SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN28_1,
  269. I_SRC_1_OUT_CH1, 1, 0),
  270. };
  271. static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = {
  272. SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN29,
  273. I_DL1_CH2, 1, 0),
  274. SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN29,
  275. I_DL2_CH2, 1, 0),
  276. SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN29,
  277. I_DL3_CH2, 1, 0),
  278. SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN29,
  279. I_DL12_CH2, 1, 0),
  280. SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN29,
  281. I_DL12_CH4, 1, 0),
  282. SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN29_1,
  283. I_DL6_CH2, 1, 0),
  284. SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN29_1,
  285. I_DL4_CH2, 1, 0),
  286. SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN29_1,
  287. I_DL5_CH2, 1, 0),
  288. SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN29_1,
  289. I_DL8_CH2, 1, 0),
  290. SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN29,
  291. I_GAIN1_OUT_CH2, 1, 0),
  292. SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN29,
  293. I_ADDA_UL_CH2, 1, 0),
  294. SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN29,
  295. I_PCM_1_CAP_CH2, 1, 0),
  296. SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN29,
  297. I_PCM_2_CAP_CH2, 1, 0),
  298. SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN29_1,
  299. I_SRC_1_OUT_CH2, 1, 0),
  300. };
  301. enum {
  302. SUPPLY_SEQ_APLL,
  303. SUPPLY_SEQ_I2S_MCLK_EN,
  304. SUPPLY_SEQ_I2S_HD_EN,
  305. SUPPLY_SEQ_I2S_EN,
  306. };
  307. static int mtk_i2s_en_event(struct snd_soc_dapm_widget *w,
  308. struct snd_kcontrol *kcontrol,
  309. int event)
  310. {
  311. struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
  312. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  313. struct mtk_afe_i2s_priv *i2s_priv;
  314. i2s_priv = get_i2s_priv_by_name(afe, w->name);
  315. dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
  316. __func__, w->name, event);
  317. switch (event) {
  318. case SND_SOC_DAPM_PRE_PMU:
  319. mt8186_afe_gpio_request(afe->dev, true, i2s_priv->id, 0);
  320. break;
  321. case SND_SOC_DAPM_POST_PMD:
  322. mt8186_afe_gpio_request(afe->dev, false, i2s_priv->id, 0);
  323. break;
  324. default:
  325. break;
  326. }
  327. return 0;
  328. }
  329. static int mtk_apll_event(struct snd_soc_dapm_widget *w,
  330. struct snd_kcontrol *kcontrol,
  331. int event)
  332. {
  333. struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
  334. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  335. dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
  336. __func__, w->name, event);
  337. switch (event) {
  338. case SND_SOC_DAPM_PRE_PMU:
  339. if (strcmp(w->name, APLL1_W_NAME) == 0)
  340. mt8186_apll1_enable(afe);
  341. else
  342. mt8186_apll2_enable(afe);
  343. break;
  344. case SND_SOC_DAPM_POST_PMD:
  345. if (strcmp(w->name, APLL1_W_NAME) == 0)
  346. mt8186_apll1_disable(afe);
  347. else
  348. mt8186_apll2_disable(afe);
  349. break;
  350. default:
  351. break;
  352. }
  353. return 0;
  354. }
  355. static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
  356. struct snd_kcontrol *kcontrol,
  357. int event)
  358. {
  359. struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
  360. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  361. struct mtk_afe_i2s_priv *i2s_priv;
  362. dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
  363. __func__, w->name, event);
  364. i2s_priv = get_i2s_priv_by_name(afe, w->name);
  365. switch (event) {
  366. case SND_SOC_DAPM_PRE_PMU:
  367. mt8186_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);
  368. break;
  369. case SND_SOC_DAPM_POST_PMD:
  370. i2s_priv->mclk_rate = 0;
  371. mt8186_mck_disable(afe, i2s_priv->mclk_id);
  372. break;
  373. default:
  374. break;
  375. }
  376. return 0;
  377. }
  378. static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {
  379. SND_SOC_DAPM_INPUT("CONNSYS"),
  380. SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0,
  381. mtk_i2s1_ch1_mix,
  382. ARRAY_SIZE(mtk_i2s1_ch1_mix)),
  383. SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0,
  384. mtk_i2s1_ch2_mix,
  385. ARRAY_SIZE(mtk_i2s1_ch2_mix)),
  386. SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0,
  387. mtk_i2s3_ch1_mix,
  388. ARRAY_SIZE(mtk_i2s3_ch1_mix)),
  389. SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0,
  390. mtk_i2s3_ch2_mix,
  391. ARRAY_SIZE(mtk_i2s3_ch2_mix)),
  392. /* i2s en*/
  393. SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN,
  394. AFE_I2S_CON, I2S_EN_SFT, 0,
  395. mtk_i2s_en_event,
  396. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  397. SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN,
  398. AFE_I2S_CON1, I2S_EN_SFT, 0,
  399. mtk_i2s_en_event,
  400. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  401. SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN,
  402. AFE_I2S_CON2, I2S_EN_SFT, 0,
  403. mtk_i2s_en_event,
  404. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  405. SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN,
  406. AFE_I2S_CON3, I2S_EN_SFT, 0,
  407. mtk_i2s_en_event,
  408. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  409. /* i2s hd en */
  410. SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
  411. AFE_I2S_CON, I2S1_HD_EN_SFT, 0, NULL,
  412. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  413. SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
  414. AFE_I2S_CON1, I2S2_HD_EN_SFT, 0, NULL,
  415. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  416. SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
  417. AFE_I2S_CON2, I2S3_HD_EN_SFT, 0, NULL,
  418. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  419. SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
  420. AFE_I2S_CON3, I2S4_HD_EN_SFT, 0, NULL,
  421. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  422. /* i2s mclk en */
  423. SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
  424. SND_SOC_NOPM, 0, 0,
  425. mtk_mclk_en_event,
  426. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  427. SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
  428. SND_SOC_NOPM, 0, 0,
  429. mtk_mclk_en_event,
  430. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  431. SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
  432. SND_SOC_NOPM, 0, 0,
  433. mtk_mclk_en_event,
  434. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  435. SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
  436. SND_SOC_NOPM, 0, 0,
  437. mtk_mclk_en_event,
  438. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  439. /* apll */
  440. SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
  441. SND_SOC_NOPM, 0, 0,
  442. mtk_apll_event,
  443. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  444. SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
  445. SND_SOC_NOPM, 0, 0,
  446. mtk_apll_event,
  447. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  448. /* allow i2s on without codec on */
  449. SND_SOC_DAPM_OUTPUT("I2S_DUMMY_OUT"),
  450. SND_SOC_DAPM_MUX("I2S1_Out_Mux",
  451. SND_SOC_NOPM, 0, 0, &i2s1_out_mux_control),
  452. SND_SOC_DAPM_MUX("I2S3_Out_Mux",
  453. SND_SOC_NOPM, 0, 0, &i2s3_out_mux_control),
  454. SND_SOC_DAPM_INPUT("I2S_DUMMY_IN"),
  455. SND_SOC_DAPM_MUX("I2S0_In_Mux",
  456. SND_SOC_NOPM, 0, 0, &i2s0_in_mux_control),
  457. SND_SOC_DAPM_MUX("I2S2_In_Mux",
  458. SND_SOC_NOPM, 0, 0, &i2s2_in_mux_control),
  459. /* i2s in lpbk */
  460. SND_SOC_DAPM_MUX("I2S0_Lpbk_Mux",
  461. SND_SOC_NOPM, 0, 0, &i2s0_lpbk_mux_control),
  462. SND_SOC_DAPM_MUX("I2S2_Lpbk_Mux",
  463. SND_SOC_NOPM, 0, 0, &i2s2_lpbk_mux_control),
  464. };
  465. static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,
  466. struct snd_soc_dapm_widget *sink)
  467. {
  468. struct snd_soc_dapm_widget *w = sink;
  469. struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
  470. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  471. struct mtk_afe_i2s_priv *i2s_priv;
  472. i2s_priv = get_i2s_priv_by_name(afe, sink->name);
  473. if (i2s_priv->share_i2s_id < 0)
  474. return 0;
  475. return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);
  476. }
  477. static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,
  478. struct snd_soc_dapm_widget *sink)
  479. {
  480. struct snd_soc_dapm_widget *w = sink;
  481. struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
  482. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  483. struct mtk_afe_i2s_priv *i2s_priv;
  484. i2s_priv = get_i2s_priv_by_name(afe, sink->name);
  485. if (get_i2s_id_by_name(afe, sink->name) ==
  486. get_i2s_id_by_name(afe, source->name))
  487. return i2s_priv->low_jitter_en;
  488. /* check if share i2s need hd en */
  489. if (i2s_priv->share_i2s_id < 0)
  490. return 0;
  491. if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
  492. return i2s_priv->low_jitter_en;
  493. return 0;
  494. }
  495. static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,
  496. struct snd_soc_dapm_widget *sink)
  497. {
  498. struct snd_soc_dapm_widget *w = sink;
  499. struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
  500. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  501. struct mtk_afe_i2s_priv *i2s_priv;
  502. int cur_apll;
  503. int i2s_need_apll;
  504. i2s_priv = get_i2s_priv_by_name(afe, w->name);
  505. /* which apll */
  506. cur_apll = mt8186_get_apll_by_name(afe, source->name);
  507. /* choose APLL from i2s rate */
  508. i2s_need_apll = mt8186_get_apll_by_rate(afe, i2s_priv->rate);
  509. return (i2s_need_apll == cur_apll) ? 1 : 0;
  510. }
  511. static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,
  512. struct snd_soc_dapm_widget *sink)
  513. {
  514. struct snd_soc_dapm_widget *w = sink;
  515. struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
  516. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  517. struct mtk_afe_i2s_priv *i2s_priv;
  518. i2s_priv = get_i2s_priv_by_name(afe, sink->name);
  519. if (get_i2s_id_by_name(afe, sink->name) ==
  520. get_i2s_id_by_name(afe, source->name))
  521. return (i2s_priv->mclk_rate > 0) ? 1 : 0;
  522. /* check if share i2s need mclk */
  523. if (i2s_priv->share_i2s_id < 0)
  524. return 0;
  525. if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
  526. return (i2s_priv->mclk_rate > 0) ? 1 : 0;
  527. return 0;
  528. }
  529. static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
  530. struct snd_soc_dapm_widget *sink)
  531. {
  532. struct snd_soc_dapm_widget *w = sink;
  533. struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
  534. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
  535. struct mtk_afe_i2s_priv *i2s_priv;
  536. int cur_apll;
  537. i2s_priv = get_i2s_priv_by_name(afe, w->name);
  538. /* which apll */
  539. cur_apll = mt8186_get_apll_by_name(afe, source->name);
  540. return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0;
  541. }
  542. static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {
  543. {"Connsys I2S", NULL, "CONNSYS"},
  544. /* i2s0 */
  545. {"I2S0", NULL, "I2S0_EN"},
  546. {"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
  547. {"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
  548. {"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
  549. {"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  550. {"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  551. {"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  552. {"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  553. {I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
  554. {I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
  555. {"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  556. {"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  557. {"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  558. {"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  559. {I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
  560. {I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
  561. /* i2s1 */
  562. {"I2S1_CH1", "DL1_CH1 Switch", "DL1"},
  563. {"I2S1_CH2", "DL1_CH2 Switch", "DL1"},
  564. {"I2S1_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"},
  565. {"I2S1_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"},
  566. {"I2S1_CH1", "DL2_CH1 Switch", "DL2"},
  567. {"I2S1_CH2", "DL2_CH2 Switch", "DL2"},
  568. {"I2S1_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"},
  569. {"I2S1_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"},
  570. {"I2S1_CH1", "DL3_CH1 Switch", "DL3"},
  571. {"I2S1_CH2", "DL3_CH2 Switch", "DL3"},
  572. {"I2S1_CH1", "DL12_CH1 Switch", "DL12"},
  573. {"I2S1_CH2", "DL12_CH2 Switch", "DL12"},
  574. {"I2S1_CH1", "DL12_CH3 Switch", "DL12"},
  575. {"I2S1_CH2", "DL12_CH4 Switch", "DL12"},
  576. {"I2S1_CH1", "DL6_CH1 Switch", "DL6"},
  577. {"I2S1_CH2", "DL6_CH2 Switch", "DL6"},
  578. {"I2S1_CH1", "DL4_CH1 Switch", "DL4"},
  579. {"I2S1_CH2", "DL4_CH2 Switch", "DL4"},
  580. {"I2S1_CH1", "DL5_CH1 Switch", "DL5"},
  581. {"I2S1_CH2", "DL5_CH2 Switch", "DL5"},
  582. {"I2S1_CH1", "DL8_CH1 Switch", "DL8"},
  583. {"I2S1_CH2", "DL8_CH2 Switch", "DL8"},
  584. {"I2S1", NULL, "I2S1_CH1"},
  585. {"I2S1", NULL, "I2S1_CH2"},
  586. {"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
  587. {"I2S1", NULL, "I2S1_EN"},
  588. {"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
  589. {"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
  590. {"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  591. {"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  592. {"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  593. {"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  594. {I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
  595. {I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
  596. {"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  597. {"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  598. {"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  599. {"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  600. {I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
  601. {I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
  602. /* i2s2 */
  603. {"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
  604. {"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
  605. {"I2S2", NULL, "I2S2_EN"},
  606. {"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
  607. {"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  608. {"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  609. {"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  610. {"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  611. {I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
  612. {I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
  613. {"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  614. {"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  615. {"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  616. {"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  617. {I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
  618. {I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
  619. /* i2s3 */
  620. {"I2S3_CH1", "DL1_CH1 Switch", "DL1"},
  621. {"I2S3_CH2", "DL1_CH2 Switch", "DL1"},
  622. {"I2S3_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"},
  623. {"I2S3_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"},
  624. {"I2S3_CH1", "DL2_CH1 Switch", "DL2"},
  625. {"I2S3_CH2", "DL2_CH2 Switch", "DL2"},
  626. {"I2S3_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"},
  627. {"I2S3_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"},
  628. {"I2S3_CH1", "DL3_CH1 Switch", "DL3"},
  629. {"I2S3_CH2", "DL3_CH2 Switch", "DL3"},
  630. {"I2S3_CH1", "DL12_CH1 Switch", "DL12"},
  631. {"I2S3_CH2", "DL12_CH2 Switch", "DL12"},
  632. {"I2S3_CH1", "DL12_CH3 Switch", "DL12"},
  633. {"I2S3_CH2", "DL12_CH4 Switch", "DL12"},
  634. {"I2S3_CH1", "DL6_CH1 Switch", "DL6"},
  635. {"I2S3_CH2", "DL6_CH2 Switch", "DL6"},
  636. {"I2S3_CH1", "DL4_CH1 Switch", "DL4"},
  637. {"I2S3_CH2", "DL4_CH2 Switch", "DL4"},
  638. {"I2S3_CH1", "DL5_CH1 Switch", "DL5"},
  639. {"I2S3_CH2", "DL5_CH2 Switch", "DL5"},
  640. {"I2S3_CH1", "DL8_CH1 Switch", "DL8"},
  641. {"I2S3_CH2", "DL8_CH2 Switch", "DL8"},
  642. {"I2S3", NULL, "I2S3_CH1"},
  643. {"I2S3", NULL, "I2S3_CH2"},
  644. {"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
  645. {"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
  646. {"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
  647. {"I2S3", NULL, "I2S3_EN"},
  648. {"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  649. {"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  650. {"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  651. {"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
  652. {I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
  653. {I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
  654. {"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  655. {"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  656. {"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  657. {"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
  658. {I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
  659. {I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
  660. /* allow i2s on without codec on */
  661. {"I2S0", NULL, "I2S0_In_Mux"},
  662. {"I2S0_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},
  663. {"I2S1_Out_Mux", "Dummy_Widget", "I2S1"},
  664. {"I2S_DUMMY_OUT", NULL, "I2S1_Out_Mux"},
  665. {"I2S2", NULL, "I2S2_In_Mux"},
  666. {"I2S2_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},
  667. {"I2S3_Out_Mux", "Dummy_Widget", "I2S3"},
  668. {"I2S_DUMMY_OUT", NULL, "I2S3_Out_Mux"},
  669. /* i2s in lpbk */
  670. {"I2S0_Lpbk_Mux", "Lpbk", "I2S3"},
  671. {"I2S2_Lpbk_Mux", "Lpbk", "I2S1"},
  672. {"I2S0", NULL, "I2S0_Lpbk_Mux"},
  673. {"I2S2", NULL, "I2S2_Lpbk_Mux"},
  674. };
  675. /* dai ops */
  676. static int mtk_dai_connsys_i2s_hw_params(struct snd_pcm_substream *substream,
  677. struct snd_pcm_hw_params *params,
  678. struct snd_soc_dai *dai)
  679. {
  680. struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
  681. unsigned int rate = params_rate(params);
  682. unsigned int rate_reg = mt8186_rate_transform(afe->dev,
  683. rate, dai->id);
  684. unsigned int i2s_con = 0;
  685. dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
  686. __func__, dai->id, substream->stream, rate);
  687. /* non-inverse, i2s mode, slave, 16bits, from connsys */
  688. i2s_con |= 0 << INV_PAD_CTRL_SFT;
  689. i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
  690. i2s_con |= 1 << I2S_SRC_SFT;
  691. i2s_con |= get_i2s_wlen(SNDRV_PCM_FORMAT_S16_LE) << I2S_WLEN_SFT;
  692. i2s_con |= 0 << I2SIN_PAD_SEL_SFT;
  693. regmap_write(afe->regmap, AFE_CONNSYS_I2S_CON, i2s_con);
  694. /* use asrc */
  695. regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
  696. I2S_BYPSRC_MASK_SFT, 0);
  697. /* slave mode, set i2s for asrc */
  698. regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
  699. I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT);
  700. if (rate == 44100)
  701. regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1b9000);
  702. else if (rate == 32000)
  703. regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x140000);
  704. else
  705. regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1e0000);
  706. /* Calibration setting */
  707. regmap_write(afe->regmap, AFE_ASRC_2CH_CON4, 0x140000);
  708. regmap_write(afe->regmap, AFE_ASRC_2CH_CON9, 0x36000);
  709. regmap_write(afe->regmap, AFE_ASRC_2CH_CON10, 0x2fc00);
  710. regmap_write(afe->regmap, AFE_ASRC_2CH_CON6, 0x7ef4);
  711. regmap_write(afe->regmap, AFE_ASRC_2CH_CON5, 0xff5986);
  712. /* 0:Stereo 1:Mono */
  713. regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2,
  714. CHSET_IS_MONO_MASK_SFT, 0);
  715. return 0;
  716. }
  717. static int mtk_dai_connsys_i2s_trigger(struct snd_pcm_substream *substream,
  718. int cmd, struct snd_soc_dai *dai)
  719. {
  720. struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
  721. struct mt8186_afe_private *afe_priv = afe->platform_priv;
  722. dev_dbg(afe->dev, "%s(), cmd %d, stream %d\n",
  723. __func__, cmd, substream->stream);
  724. switch (cmd) {
  725. case SNDRV_PCM_TRIGGER_START:
  726. case SNDRV_PCM_TRIGGER_RESUME:
  727. /* i2s enable */
  728. regmap_update_bits(afe->regmap,
  729. AFE_CONNSYS_I2S_CON,
  730. I2S_EN_MASK_SFT,
  731. BIT(I2S_EN_SFT));
  732. /* calibrator enable */
  733. regmap_update_bits(afe->regmap,
  734. AFE_ASRC_2CH_CON5,
  735. CALI_EN_MASK_SFT,
  736. BIT(CALI_EN_SFT));
  737. /* asrc enable */
  738. regmap_update_bits(afe->regmap,
  739. AFE_ASRC_2CH_CON0,
  740. CON0_CHSET_STR_CLR_MASK_SFT,
  741. BIT(CON0_CHSET_STR_CLR_SFT));
  742. regmap_update_bits(afe->regmap,
  743. AFE_ASRC_2CH_CON0,
  744. CON0_ASM_ON_MASK_SFT,
  745. BIT(CON0_ASM_ON_SFT));
  746. afe_priv->dai_on[dai->id] = true;
  747. return 0;
  748. case SNDRV_PCM_TRIGGER_STOP:
  749. case SNDRV_PCM_TRIGGER_SUSPEND:
  750. regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,
  751. CON0_ASM_ON_MASK_SFT, 0);
  752. regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5,
  753. CALI_EN_MASK_SFT, 0);
  754. /* i2s disable */
  755. regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
  756. I2S_EN_MASK_SFT, 0);
  757. /* bypass asrc */
  758. regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
  759. I2S_BYPSRC_MASK_SFT, BIT(I2S_BYPSRC_SFT));
  760. afe_priv->dai_on[dai->id] = false;
  761. return 0;
  762. default:
  763. return -EINVAL;
  764. }
  765. return 0;
  766. }
  767. static const struct snd_soc_dai_ops mtk_dai_connsys_i2s_ops = {
  768. .hw_params = mtk_dai_connsys_i2s_hw_params,
  769. .trigger = mtk_dai_connsys_i2s_trigger,
  770. };
  771. /* i2s */
  772. static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
  773. struct snd_pcm_hw_params *params,
  774. int i2s_id)
  775. {
  776. struct mt8186_afe_private *afe_priv = afe->platform_priv;
  777. struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];
  778. unsigned int rate = params_rate(params);
  779. unsigned int rate_reg = mt8186_rate_transform(afe->dev,
  780. rate, i2s_id);
  781. snd_pcm_format_t format = params_format(params);
  782. unsigned int i2s_con = 0;
  783. int ret;
  784. dev_dbg(afe->dev, "%s(), id %d, rate %d, format %d\n",
  785. __func__, i2s_id, rate, format);
  786. i2s_priv->rate = rate;
  787. switch (i2s_id) {
  788. case MT8186_DAI_I2S_0:
  789. i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;
  790. i2s_con |= rate_reg << I2S_OUT_MODE_SFT;
  791. i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
  792. i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;
  793. regmap_update_bits(afe->regmap, AFE_I2S_CON,
  794. 0xffffeffa, i2s_con);
  795. break;
  796. case MT8186_DAI_I2S_1:
  797. i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;
  798. i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;
  799. i2s_con |= I2S_FMT_I2S << I2S2_FMT_SFT;
  800. i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;
  801. regmap_update_bits(afe->regmap, AFE_I2S_CON1,
  802. 0xffffeffa, i2s_con);
  803. break;
  804. case MT8186_DAI_I2S_2:
  805. i2s_con = 8 << I2S3_UPDATE_WORD_SFT;
  806. i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;
  807. i2s_con |= I2S_FMT_I2S << I2S3_FMT_SFT;
  808. i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;
  809. regmap_update_bits(afe->regmap, AFE_I2S_CON2,
  810. 0xffffeffa, i2s_con);
  811. break;
  812. case MT8186_DAI_I2S_3:
  813. i2s_con = rate_reg << I2S4_OUT_MODE_SFT;
  814. i2s_con |= I2S_FMT_I2S << I2S4_FMT_SFT;
  815. i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;
  816. regmap_update_bits(afe->regmap, AFE_I2S_CON3,
  817. 0xffffeffa, i2s_con);
  818. break;
  819. default:
  820. dev_err(afe->dev, "%s(), id %d not support\n",
  821. __func__, i2s_id);
  822. return -EINVAL;
  823. }
  824. /* set share i2s */
  825. if (i2s_priv->share_i2s_id >= 0) {
  826. ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);
  827. if (ret)
  828. return ret;
  829. }
  830. return 0;
  831. }
  832. static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,
  833. struct snd_pcm_hw_params *params,
  834. struct snd_soc_dai *dai)
  835. {
  836. struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
  837. return mtk_dai_i2s_config(afe, params, dai->id);
  838. }
  839. static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
  840. int clk_id, unsigned int freq, int dir)
  841. {
  842. struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
  843. struct mt8186_afe_private *afe_priv = afe->platform_priv;
  844. struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id];
  845. int apll;
  846. int apll_rate;
  847. if (dir != SND_SOC_CLOCK_OUT) {
  848. dev_err(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);
  849. return -EINVAL;
  850. }
  851. dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq);
  852. apll = mt8186_get_apll_by_rate(afe, freq);
  853. apll_rate = mt8186_get_apll_rate(afe, apll);
  854. if (freq > apll_rate) {
  855. dev_err(afe->dev, "%s(), freq > apll rate", __func__);
  856. return -EINVAL;
  857. }
  858. if (apll_rate % freq != 0) {
  859. dev_err(afe->dev, "%s(), APLL cannot generate freq Hz", __func__);
  860. return -EINVAL;
  861. }
  862. i2s_priv->mclk_rate = freq;
  863. i2s_priv->mclk_apll = apll;
  864. if (i2s_priv->share_i2s_id > 0) {
  865. struct mtk_afe_i2s_priv *share_i2s_priv;
  866. share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];
  867. if (!share_i2s_priv) {
  868. dev_err(afe->dev, "%s(), share_i2s_priv == NULL", __func__);
  869. return -EINVAL;
  870. }
  871. share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;
  872. share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;
  873. }
  874. return 0;
  875. }
  876. static const struct snd_soc_dai_ops mtk_dai_i2s_ops = {
  877. .hw_params = mtk_dai_i2s_hw_params,
  878. .set_sysclk = mtk_dai_i2s_set_sysclk,
  879. };
  880. /* dai driver */
  881. #define MTK_CONNSYS_I2S_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
  882. #define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\
  883. SNDRV_PCM_RATE_88200 |\
  884. SNDRV_PCM_RATE_96000 |\
  885. SNDRV_PCM_RATE_176400 |\
  886. SNDRV_PCM_RATE_192000)
  887. #define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
  888. SNDRV_PCM_FMTBIT_S24_LE |\
  889. SNDRV_PCM_FMTBIT_S32_LE)
  890. static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {
  891. {
  892. .name = "CONNSYS_I2S",
  893. .id = MT8186_DAI_CONNSYS_I2S,
  894. .capture = {
  895. .stream_name = "Connsys I2S",
  896. .channels_min = 1,
  897. .channels_max = 2,
  898. .rates = MTK_CONNSYS_I2S_RATES,
  899. .formats = MTK_I2S_FORMATS,
  900. },
  901. .ops = &mtk_dai_connsys_i2s_ops,
  902. },
  903. {
  904. .name = "I2S0",
  905. .id = MT8186_DAI_I2S_0,
  906. .capture = {
  907. .stream_name = "I2S0",
  908. .channels_min = 1,
  909. .channels_max = 2,
  910. .rates = MTK_I2S_RATES,
  911. .formats = MTK_I2S_FORMATS,
  912. },
  913. .ops = &mtk_dai_i2s_ops,
  914. },
  915. {
  916. .name = "I2S1",
  917. .id = MT8186_DAI_I2S_1,
  918. .playback = {
  919. .stream_name = "I2S1",
  920. .channels_min = 1,
  921. .channels_max = 2,
  922. .rates = MTK_I2S_RATES,
  923. .formats = MTK_I2S_FORMATS,
  924. },
  925. .ops = &mtk_dai_i2s_ops,
  926. },
  927. {
  928. .name = "I2S2",
  929. .id = MT8186_DAI_I2S_2,
  930. .capture = {
  931. .stream_name = "I2S2",
  932. .channels_min = 1,
  933. .channels_max = 2,
  934. .rates = MTK_I2S_RATES,
  935. .formats = MTK_I2S_FORMATS,
  936. },
  937. .ops = &mtk_dai_i2s_ops,
  938. },
  939. {
  940. .name = "I2S3",
  941. .id = MT8186_DAI_I2S_3,
  942. .playback = {
  943. .stream_name = "I2S3",
  944. .channels_min = 1,
  945. .channels_max = 2,
  946. .rates = MTK_I2S_RATES,
  947. .formats = MTK_I2S_FORMATS,
  948. },
  949. .ops = &mtk_dai_i2s_ops,
  950. }
  951. };
  952. /* this enum is merely for mtk_afe_i2s_priv declare */
  953. enum {
  954. DAI_I2S0 = 0,
  955. DAI_I2S1,
  956. DAI_I2S2,
  957. DAI_I2S3,
  958. DAI_I2S_NUM,
  959. };
  960. static const struct mtk_afe_i2s_priv mt8186_i2s_priv[DAI_I2S_NUM] = {
  961. [DAI_I2S0] = {
  962. .id = MT8186_DAI_I2S_0,
  963. .mclk_id = MT8186_I2S0_MCK,
  964. .share_i2s_id = -1,
  965. },
  966. [DAI_I2S1] = {
  967. .id = MT8186_DAI_I2S_1,
  968. .mclk_id = MT8186_I2S1_MCK,
  969. .share_i2s_id = -1,
  970. },
  971. [DAI_I2S2] = {
  972. .id = MT8186_DAI_I2S_2,
  973. .mclk_id = MT8186_I2S2_MCK,
  974. .share_i2s_id = -1,
  975. },
  976. [DAI_I2S3] = {
  977. .id = MT8186_DAI_I2S_3,
  978. /* clock gate naming is hf_faud_i2s4_m_ck*/
  979. .mclk_id = MT8186_I2S4_MCK,
  980. .share_i2s_id = -1,
  981. }
  982. };
  983. /**
  984. * mt8186_dai_i2s_set_share() - Set up I2S ports to share a single clock.
  985. * @afe: Pointer to &struct mtk_base_afe
  986. * @main_i2s_name: The name of the I2S port that will provide the clock
  987. * @secondary_i2s_name: The name of the I2S port that will use this clock
  988. */
  989. int mt8186_dai_i2s_set_share(struct mtk_base_afe *afe, const char *main_i2s_name,
  990. const char *secondary_i2s_name)
  991. {
  992. struct mtk_afe_i2s_priv *secondary_i2s_priv;
  993. int main_i2s_id;
  994. secondary_i2s_priv = get_i2s_priv_by_name(afe, secondary_i2s_name);
  995. if (!secondary_i2s_priv)
  996. return -EINVAL;
  997. main_i2s_id = get_i2s_id_by_name(afe, main_i2s_name);
  998. if (main_i2s_id < 0)
  999. return main_i2s_id;
  1000. secondary_i2s_priv->share_i2s_id = main_i2s_id;
  1001. return 0;
  1002. }
  1003. EXPORT_SYMBOL_GPL(mt8186_dai_i2s_set_share);
  1004. static int mt8186_dai_i2s_set_priv(struct mtk_base_afe *afe)
  1005. {
  1006. int i;
  1007. int ret;
  1008. for (i = 0; i < DAI_I2S_NUM; i++) {
  1009. ret = mt8186_dai_set_priv(afe, mt8186_i2s_priv[i].id,
  1010. sizeof(struct mtk_afe_i2s_priv),
  1011. &mt8186_i2s_priv[i]);
  1012. if (ret)
  1013. return ret;
  1014. }
  1015. return 0;
  1016. }
  1017. int mt8186_dai_i2s_register(struct mtk_base_afe *afe)
  1018. {
  1019. struct mtk_base_afe_dai *dai;
  1020. int ret;
  1021. dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
  1022. if (!dai)
  1023. return -ENOMEM;
  1024. list_add(&dai->list, &afe->sub_dais);
  1025. dai->dai_drivers = mtk_dai_i2s_driver;
  1026. dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);
  1027. dai->controls = mtk_dai_i2s_controls;
  1028. dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls);
  1029. dai->dapm_widgets = mtk_dai_i2s_widgets;
  1030. dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);
  1031. dai->dapm_routes = mtk_dai_i2s_routes;
  1032. dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);
  1033. /* set all dai i2s private data */
  1034. ret = mt8186_dai_i2s_set_priv(afe);
  1035. if (ret)
  1036. return ret;
  1037. return 0;
  1038. }