860-v6.6-03-ASoC-mediatek-mt7986-add-platform-driver.patch 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. From fc7776dee86bc07d22820a904760a95f49a2f12e Mon Sep 17 00:00:00 2001
  2. From: Maso Huang <[email protected]>
  3. Date: Thu, 17 Aug 2023 18:13:35 +0800
  4. Subject: [PATCH 3/9] ASoC: mediatek: mt7986: add platform driver
  5. Add mt7986 platform driver.
  6. Signed-off-by: Maso Huang <[email protected]>
  7. Reviewed-by: AngeloGioacchino Del Regno <[email protected]>
  8. Link: https://lore.kernel.org/r/[email protected]
  9. Signed-off-by: Mark Brown <[email protected]>
  10. ---
  11. sound/soc/mediatek/Kconfig | 10 +
  12. sound/soc/mediatek/Makefile | 1 +
  13. sound/soc/mediatek/mt7986/Makefile | 8 +
  14. sound/soc/mediatek/mt7986/mt7986-afe-pcm.c | 622 +++++++++++++++++++++
  15. 4 files changed, 641 insertions(+)
  16. create mode 100644 sound/soc/mediatek/mt7986/Makefile
  17. create mode 100644 sound/soc/mediatek/mt7986/mt7986-afe-pcm.c
  18. --- a/sound/soc/mediatek/Kconfig
  19. +++ b/sound/soc/mediatek/Kconfig
  20. @@ -54,6 +54,16 @@ config SND_SOC_MT6797_MT6351
  21. Select Y if you have such device.
  22. If unsure select "N".
  23. +config SND_SOC_MT7986
  24. + tristate "ASoC support for Mediatek MT7986 chip"
  25. + depends on ARCH_MEDIATEK
  26. + select SND_SOC_MEDIATEK
  27. + help
  28. + This adds ASoC platform driver support for MediaTek MT7986 chip
  29. + that can be used with other codecs.
  30. + Select Y if you have such device.
  31. + If unsure select "N".
  32. +
  33. config SND_SOC_MT8173
  34. tristate "ASoC support for Mediatek MT8173 chip"
  35. depends on ARCH_MEDIATEK
  36. --- a/sound/soc/mediatek/Makefile
  37. +++ b/sound/soc/mediatek/Makefile
  38. @@ -2,6 +2,7 @@
  39. obj-$(CONFIG_SND_SOC_MEDIATEK) += common/
  40. obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
  41. obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
  42. +obj-$(CONFIG_SND_SOC_MT7986) += mt7986/
  43. obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
  44. obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
  45. obj-$(CONFIG_SND_SOC_MT8186) += mt8186/
  46. --- /dev/null
  47. +++ b/sound/soc/mediatek/mt7986/Makefile
  48. @@ -0,0 +1,8 @@
  49. +# SPDX-License-Identifier: GPL-2.0
  50. +
  51. +# platform driver
  52. +snd-soc-mt7986-afe-objs := \
  53. + mt7986-afe-pcm.o \
  54. + mt7986-dai-etdm.o
  55. +
  56. +obj-$(CONFIG_SND_SOC_MT7986) += snd-soc-mt7986-afe.o
  57. --- /dev/null
  58. +++ b/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c
  59. @@ -0,0 +1,622 @@
  60. +// SPDX-License-Identifier: GPL-2.0
  61. +/*
  62. + * MediaTek ALSA SoC AFE platform driver for MT7986
  63. + *
  64. + * Copyright (c) 2023 MediaTek Inc.
  65. + * Authors: Vic Wu <[email protected]>
  66. + * Maso Huang <[email protected]>
  67. + */
  68. +
  69. +#include <linux/clk.h>
  70. +#include <linux/delay.h>
  71. +#include <linux/module.h>
  72. +#include <linux/of.h>
  73. +#include <linux/of_address.h>
  74. +#include <linux/pm_runtime.h>
  75. +
  76. +#include "mt7986-afe-common.h"
  77. +#include "mt7986-reg.h"
  78. +#include "../common/mtk-afe-platform-driver.h"
  79. +#include "../common/mtk-afe-fe-dai.h"
  80. +
  81. +enum {
  82. + MTK_AFE_RATE_8K = 0,
  83. + MTK_AFE_RATE_11K = 1,
  84. + MTK_AFE_RATE_12K = 2,
  85. + MTK_AFE_RATE_16K = 4,
  86. + MTK_AFE_RATE_22K = 5,
  87. + MTK_AFE_RATE_24K = 6,
  88. + MTK_AFE_RATE_32K = 8,
  89. + MTK_AFE_RATE_44K = 9,
  90. + MTK_AFE_RATE_48K = 10,
  91. + MTK_AFE_RATE_88K = 13,
  92. + MTK_AFE_RATE_96K = 14,
  93. + MTK_AFE_RATE_176K = 17,
  94. + MTK_AFE_RATE_192K = 18,
  95. +};
  96. +
  97. +enum {
  98. + CLK_INFRA_AUD_BUS_CK = 0,
  99. + CLK_INFRA_AUD_26M_CK,
  100. + CLK_INFRA_AUD_L_CK,
  101. + CLK_INFRA_AUD_AUD_CK,
  102. + CLK_INFRA_AUD_EG2_CK,
  103. + CLK_NUM
  104. +};
  105. +
  106. +static const char *aud_clks[CLK_NUM] = {
  107. + [CLK_INFRA_AUD_BUS_CK] = "aud_bus_ck",
  108. + [CLK_INFRA_AUD_26M_CK] = "aud_26m_ck",
  109. + [CLK_INFRA_AUD_L_CK] = "aud_l_ck",
  110. + [CLK_INFRA_AUD_AUD_CK] = "aud_aud_ck",
  111. + [CLK_INFRA_AUD_EG2_CK] = "aud_eg2_ck",
  112. +};
  113. +
  114. +unsigned int mt7986_afe_rate_transform(struct device *dev, unsigned int rate)
  115. +{
  116. + switch (rate) {
  117. + case 8000:
  118. + return MTK_AFE_RATE_8K;
  119. + case 11025:
  120. + return MTK_AFE_RATE_11K;
  121. + case 12000:
  122. + return MTK_AFE_RATE_12K;
  123. + case 16000:
  124. + return MTK_AFE_RATE_16K;
  125. + case 22050:
  126. + return MTK_AFE_RATE_22K;
  127. + case 24000:
  128. + return MTK_AFE_RATE_24K;
  129. + case 32000:
  130. + return MTK_AFE_RATE_32K;
  131. + case 44100:
  132. + return MTK_AFE_RATE_44K;
  133. + case 48000:
  134. + return MTK_AFE_RATE_48K;
  135. + case 88200:
  136. + return MTK_AFE_RATE_88K;
  137. + case 96000:
  138. + return MTK_AFE_RATE_96K;
  139. + case 176400:
  140. + return MTK_AFE_RATE_176K;
  141. + case 192000:
  142. + return MTK_AFE_RATE_192K;
  143. + default:
  144. + dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n",
  145. + __func__, rate, MTK_AFE_RATE_48K);
  146. + return MTK_AFE_RATE_48K;
  147. + }
  148. +}
  149. +
  150. +static const struct snd_pcm_hardware mt7986_afe_hardware = {
  151. + .info = SNDRV_PCM_INFO_MMAP |
  152. + SNDRV_PCM_INFO_INTERLEAVED |
  153. + SNDRV_PCM_INFO_MMAP_VALID,
  154. + .formats = SNDRV_PCM_FMTBIT_S16_LE |
  155. + SNDRV_PCM_FMTBIT_S24_LE |
  156. + SNDRV_PCM_FMTBIT_S32_LE,
  157. + .period_bytes_min = 256,
  158. + .period_bytes_max = 4 * 48 * 1024,
  159. + .periods_min = 2,
  160. + .periods_max = 256,
  161. + .buffer_bytes_max = 8 * 48 * 1024,
  162. + .fifo_size = 0,
  163. +};
  164. +
  165. +static int mt7986_memif_fs(struct snd_pcm_substream *substream,
  166. + unsigned int rate)
  167. +{
  168. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  169. + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
  170. + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
  171. +
  172. + return mt7986_afe_rate_transform(afe->dev, rate);
  173. +}
  174. +
  175. +static int mt7986_irq_fs(struct snd_pcm_substream *substream,
  176. + unsigned int rate)
  177. +{
  178. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  179. + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
  180. + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
  181. +
  182. + return mt7986_afe_rate_transform(afe->dev, rate);
  183. +}
  184. +
  185. +#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000 |\
  186. + SNDRV_PCM_RATE_88200 |\
  187. + SNDRV_PCM_RATE_96000 |\
  188. + SNDRV_PCM_RATE_176400 |\
  189. + SNDRV_PCM_RATE_192000)
  190. +
  191. +#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
  192. + SNDRV_PCM_FMTBIT_S24_LE |\
  193. + SNDRV_PCM_FMTBIT_S32_LE)
  194. +
  195. +static struct snd_soc_dai_driver mt7986_memif_dai_driver[] = {
  196. + /* FE DAIs: memory intefaces to CPU */
  197. + {
  198. + .name = "DL1",
  199. + .id = MT7986_MEMIF_DL1,
  200. + .playback = {
  201. + .stream_name = "DL1",
  202. + .channels_min = 1,
  203. + .channels_max = 2,
  204. + .rates = MTK_PCM_RATES,
  205. + .formats = MTK_PCM_FORMATS,
  206. + },
  207. + .ops = &mtk_afe_fe_ops,
  208. + },
  209. + {
  210. + .name = "UL1",
  211. + .id = MT7986_MEMIF_VUL12,
  212. + .capture = {
  213. + .stream_name = "UL1",
  214. + .channels_min = 1,
  215. + .channels_max = 2,
  216. + .rates = MTK_PCM_RATES,
  217. + .formats = MTK_PCM_FORMATS,
  218. + },
  219. + .ops = &mtk_afe_fe_ops,
  220. + },
  221. +};
  222. +
  223. +static const struct snd_kcontrol_new o018_mix[] = {
  224. + SOC_DAPM_SINGLE_AUTODISABLE("I150_Switch", AFE_CONN018_4, 22, 1, 0),
  225. +};
  226. +
  227. +static const struct snd_kcontrol_new o019_mix[] = {
  228. + SOC_DAPM_SINGLE_AUTODISABLE("I151_Switch", AFE_CONN019_4, 23, 1, 0),
  229. +};
  230. +
  231. +static const struct snd_soc_dapm_widget mt7986_memif_widgets[] = {
  232. + /* DL */
  233. + SND_SOC_DAPM_MIXER("I032", SND_SOC_NOPM, 0, 0, NULL, 0),
  234. + SND_SOC_DAPM_MIXER("I033", SND_SOC_NOPM, 0, 0, NULL, 0),
  235. +
  236. + /* UL */
  237. + SND_SOC_DAPM_MIXER("O018", SND_SOC_NOPM, 0, 0,
  238. + o018_mix, ARRAY_SIZE(o018_mix)),
  239. + SND_SOC_DAPM_MIXER("O019", SND_SOC_NOPM, 0, 0,
  240. + o019_mix, ARRAY_SIZE(o019_mix)),
  241. +};
  242. +
  243. +static const struct snd_soc_dapm_route mt7986_memif_routes[] = {
  244. + {"I032", NULL, "DL1"},
  245. + {"I033", NULL, "DL1"},
  246. + {"UL1", NULL, "O018"},
  247. + {"UL1", NULL, "O019"},
  248. + {"O018", "I150_Switch", "I150"},
  249. + {"O019", "I151_Switch", "I151"},
  250. +};
  251. +
  252. +static const struct snd_soc_component_driver mt7986_afe_pcm_dai_component = {
  253. + .name = "mt7986-afe-pcm-dai",
  254. +};
  255. +
  256. +static const struct mtk_base_memif_data memif_data[MT7986_MEMIF_NUM] = {
  257. + [MT7986_MEMIF_DL1] = {
  258. + .name = "DL1",
  259. + .id = MT7986_MEMIF_DL1,
  260. + .reg_ofs_base = AFE_DL0_BASE,
  261. + .reg_ofs_cur = AFE_DL0_CUR,
  262. + .reg_ofs_end = AFE_DL0_END,
  263. + .reg_ofs_base_msb = AFE_DL0_BASE_MSB,
  264. + .reg_ofs_cur_msb = AFE_DL0_CUR_MSB,
  265. + .reg_ofs_end_msb = AFE_DL0_END_MSB,
  266. + .fs_reg = AFE_DL0_CON0,
  267. + .fs_shift = DL0_MODE_SFT,
  268. + .fs_maskbit = DL0_MODE_MASK,
  269. + .mono_reg = AFE_DL0_CON0,
  270. + .mono_shift = DL0_MONO_SFT,
  271. + .enable_reg = AFE_DL0_CON0,
  272. + .enable_shift = DL0_ON_SFT,
  273. + .hd_reg = AFE_DL0_CON0,
  274. + .hd_shift = DL0_HD_MODE_SFT,
  275. + .hd_align_reg = AFE_DL0_CON0,
  276. + .hd_align_mshift = DL0_HALIGN_SFT,
  277. + .pbuf_reg = AFE_DL0_CON0,
  278. + .pbuf_shift = DL0_PBUF_SIZE_SFT,
  279. + .minlen_reg = AFE_DL0_CON0,
  280. + .minlen_shift = DL0_MINLEN_SFT,
  281. + },
  282. + [MT7986_MEMIF_VUL12] = {
  283. + .name = "VUL12",
  284. + .id = MT7986_MEMIF_VUL12,
  285. + .reg_ofs_base = AFE_VUL0_BASE,
  286. + .reg_ofs_cur = AFE_VUL0_CUR,
  287. + .reg_ofs_end = AFE_VUL0_END,
  288. + .reg_ofs_base_msb = AFE_VUL0_BASE_MSB,
  289. + .reg_ofs_cur_msb = AFE_VUL0_CUR_MSB,
  290. + .reg_ofs_end_msb = AFE_VUL0_END_MSB,
  291. + .fs_reg = AFE_VUL0_CON0,
  292. + .fs_shift = VUL0_MODE_SFT,
  293. + .fs_maskbit = VUL0_MODE_MASK,
  294. + .mono_reg = AFE_VUL0_CON0,
  295. + .mono_shift = VUL0_MONO_SFT,
  296. + .enable_reg = AFE_VUL0_CON0,
  297. + .enable_shift = VUL0_ON_SFT,
  298. + .hd_reg = AFE_VUL0_CON0,
  299. + .hd_shift = VUL0_HD_MODE_SFT,
  300. + .hd_align_reg = AFE_VUL0_CON0,
  301. + .hd_align_mshift = VUL0_HALIGN_SFT,
  302. + },
  303. +};
  304. +
  305. +static const struct mtk_base_irq_data irq_data[MT7986_IRQ_NUM] = {
  306. + [MT7986_IRQ_0] = {
  307. + .id = MT7986_IRQ_0,
  308. + .irq_cnt_reg = AFE_IRQ0_MCU_CFG1,
  309. + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT,
  310. + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK,
  311. + .irq_fs_reg = AFE_IRQ0_MCU_CFG0,
  312. + .irq_fs_shift = IRQ_MCU_MODE_SFT,
  313. + .irq_fs_maskbit = IRQ_MCU_MODE_MASK,
  314. + .irq_en_reg = AFE_IRQ0_MCU_CFG0,
  315. + .irq_en_shift = IRQ_MCU_ON_SFT,
  316. + .irq_clr_reg = AFE_IRQ_MCU_CLR,
  317. + .irq_clr_shift = IRQ0_MCU_CLR_SFT,
  318. + },
  319. + [MT7986_IRQ_1] = {
  320. + .id = MT7986_IRQ_1,
  321. + .irq_cnt_reg = AFE_IRQ1_MCU_CFG1,
  322. + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT,
  323. + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK,
  324. + .irq_fs_reg = AFE_IRQ1_MCU_CFG0,
  325. + .irq_fs_shift = IRQ_MCU_MODE_SFT,
  326. + .irq_fs_maskbit = IRQ_MCU_MODE_MASK,
  327. + .irq_en_reg = AFE_IRQ1_MCU_CFG0,
  328. + .irq_en_shift = IRQ_MCU_ON_SFT,
  329. + .irq_clr_reg = AFE_IRQ_MCU_CLR,
  330. + .irq_clr_shift = IRQ1_MCU_CLR_SFT,
  331. + },
  332. + [MT7986_IRQ_2] = {
  333. + .id = MT7986_IRQ_2,
  334. + .irq_cnt_reg = AFE_IRQ2_MCU_CFG1,
  335. + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT,
  336. + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK,
  337. + .irq_fs_reg = AFE_IRQ2_MCU_CFG0,
  338. + .irq_fs_shift = IRQ_MCU_MODE_SFT,
  339. + .irq_fs_maskbit = IRQ_MCU_MODE_MASK,
  340. + .irq_en_reg = AFE_IRQ2_MCU_CFG0,
  341. + .irq_en_shift = IRQ_MCU_ON_SFT,
  342. + .irq_clr_reg = AFE_IRQ_MCU_CLR,
  343. + .irq_clr_shift = IRQ2_MCU_CLR_SFT,
  344. + },
  345. +};
  346. +
  347. +static bool mt7986_is_volatile_reg(struct device *dev, unsigned int reg)
  348. +{
  349. + /*
  350. + * Those auto-gen regs are read-only, so put it as volatile because
  351. + * volatile registers cannot be cached, which means that they cannot
  352. + * be set when power is off
  353. + */
  354. +
  355. + switch (reg) {
  356. + case AFE_DL0_CUR_MSB:
  357. + case AFE_DL0_CUR:
  358. + case AFE_DL0_RCH_MON:
  359. + case AFE_DL0_LCH_MON:
  360. + case AFE_VUL0_CUR_MSB:
  361. + case AFE_VUL0_CUR:
  362. + case AFE_IRQ_MCU_STATUS:
  363. + case AFE_MEMIF_RD_MON:
  364. + case AFE_MEMIF_WR_MON:
  365. + return true;
  366. + default:
  367. + return false;
  368. + };
  369. +}
  370. +
  371. +static const struct regmap_config mt7986_afe_regmap_config = {
  372. + .reg_bits = 32,
  373. + .reg_stride = 4,
  374. + .val_bits = 32,
  375. + .volatile_reg = mt7986_is_volatile_reg,
  376. + .max_register = AFE_MAX_REGISTER,
  377. + .num_reg_defaults_raw = ((AFE_MAX_REGISTER / 4) + 1),
  378. +};
  379. +
  380. +static int mt7986_init_clock(struct mtk_base_afe *afe)
  381. +{
  382. + struct mt7986_afe_private *afe_priv = afe->platform_priv;
  383. + int ret, i;
  384. +
  385. + afe_priv->clks = devm_kcalloc(afe->dev, CLK_NUM,
  386. + sizeof(*afe_priv->clks), GFP_KERNEL);
  387. + if (!afe_priv->clks)
  388. + return -ENOMEM;
  389. + afe_priv->num_clks = CLK_NUM;
  390. +
  391. + for (i = 0; i < afe_priv->num_clks; i++)
  392. + afe_priv->clks[i].id = aud_clks[i];
  393. +
  394. + ret = devm_clk_bulk_get(afe->dev, afe_priv->num_clks, afe_priv->clks);
  395. + if (ret)
  396. + return dev_err_probe(afe->dev, ret, "Failed to get clocks\n");
  397. +
  398. + return 0;
  399. +}
  400. +
  401. +static irqreturn_t mt7986_afe_irq_handler(int irq_id, void *dev)
  402. +{
  403. + struct mtk_base_afe *afe = dev;
  404. + struct mtk_base_afe_irq *irq;
  405. + u32 mcu_en, status, status_mcu;
  406. + int i, ret;
  407. + irqreturn_t irq_ret = IRQ_HANDLED;
  408. +
  409. + /* get irq that is sent to MCU */
  410. + regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_en);
  411. +
  412. + ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &status);
  413. + /* only care IRQ which is sent to MCU */
  414. + status_mcu = status & mcu_en & AFE_IRQ_STATUS_BITS;
  415. +
  416. + if (ret || status_mcu == 0) {
  417. + dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x, mcu_en 0x%x\n",
  418. + __func__, ret, status, mcu_en);
  419. +
  420. + irq_ret = IRQ_NONE;
  421. + goto err_irq;
  422. + }
  423. +
  424. + for (i = 0; i < MT7986_MEMIF_NUM; i++) {
  425. + struct mtk_base_afe_memif *memif = &afe->memif[i];
  426. +
  427. + if (!memif->substream)
  428. + continue;
  429. +
  430. + if (memif->irq_usage < 0)
  431. + continue;
  432. +
  433. + irq = &afe->irqs[memif->irq_usage];
  434. +
  435. + if (status_mcu & (1 << irq->irq_data->irq_en_shift))
  436. + snd_pcm_period_elapsed(memif->substream);
  437. + }
  438. +
  439. +err_irq:
  440. + /* clear irq */
  441. + regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, status_mcu);
  442. +
  443. + return irq_ret;
  444. +}
  445. +
  446. +static int mt7986_afe_runtime_suspend(struct device *dev)
  447. +{
  448. + struct mtk_base_afe *afe = dev_get_drvdata(dev);
  449. + struct mt7986_afe_private *afe_priv = afe->platform_priv;
  450. +
  451. + if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
  452. + goto skip_regmap;
  453. +
  454. + /* disable clk*/
  455. + regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 0x3fff, 0x3fff);
  456. + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_APLL2_EN_MASK, 0);
  457. + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_26M_EN_MASK, 0);
  458. +
  459. + /* make sure all irq status are cleared, twice intended */
  460. + regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CLR, 0xffff, 0xffff);
  461. +
  462. +skip_regmap:
  463. + clk_bulk_disable_unprepare(afe_priv->num_clks, afe_priv->clks);
  464. +
  465. + return 0;
  466. +}
  467. +
  468. +static int mt7986_afe_runtime_resume(struct device *dev)
  469. +{
  470. + struct mtk_base_afe *afe = dev_get_drvdata(dev);
  471. + struct mt7986_afe_private *afe_priv = afe->platform_priv;
  472. + int ret;
  473. +
  474. + ret = clk_bulk_prepare_enable(afe_priv->num_clks, afe_priv->clks);
  475. + if (ret)
  476. + return dev_err_probe(afe->dev, ret, "Failed to enable clocks\n");
  477. +
  478. + if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
  479. + return 0;
  480. +
  481. + /* enable clk*/
  482. + regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 0x3fff, 0);
  483. + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_APLL2_EN_MASK,
  484. + AUD_APLL2_EN);
  485. + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_26M_EN_MASK,
  486. + AUD_26M_EN);
  487. +
  488. + return 0;
  489. +}
  490. +
  491. +static int mt7986_afe_component_probe(struct snd_soc_component *component)
  492. +{
  493. + return mtk_afe_add_sub_dai_control(component);
  494. +}
  495. +
  496. +static const struct snd_soc_component_driver mt7986_afe_component = {
  497. + .name = AFE_PCM_NAME,
  498. + .probe = mt7986_afe_component_probe,
  499. + .pointer = mtk_afe_pcm_pointer,
  500. + .pcm_construct = mtk_afe_pcm_new,
  501. +};
  502. +
  503. +static int mt7986_dai_memif_register(struct mtk_base_afe *afe)
  504. +{
  505. + struct mtk_base_afe_dai *dai;
  506. +
  507. + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
  508. + if (!dai)
  509. + return -ENOMEM;
  510. +
  511. + list_add(&dai->list, &afe->sub_dais);
  512. +
  513. + dai->dai_drivers = mt7986_memif_dai_driver;
  514. + dai->num_dai_drivers = ARRAY_SIZE(mt7986_memif_dai_driver);
  515. +
  516. + dai->dapm_widgets = mt7986_memif_widgets;
  517. + dai->num_dapm_widgets = ARRAY_SIZE(mt7986_memif_widgets);
  518. + dai->dapm_routes = mt7986_memif_routes;
  519. + dai->num_dapm_routes = ARRAY_SIZE(mt7986_memif_routes);
  520. +
  521. + return 0;
  522. +}
  523. +
  524. +typedef int (*dai_register_cb)(struct mtk_base_afe *);
  525. +static const dai_register_cb dai_register_cbs[] = {
  526. + mt7986_dai_etdm_register,
  527. + mt7986_dai_memif_register,
  528. +};
  529. +
  530. +static int mt7986_afe_pcm_dev_probe(struct platform_device *pdev)
  531. +{
  532. + struct mtk_base_afe *afe;
  533. + struct mt7986_afe_private *afe_priv;
  534. + struct device *dev;
  535. + int i, irq_id, ret;
  536. +
  537. + afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
  538. + if (!afe)
  539. + return -ENOMEM;
  540. + platform_set_drvdata(pdev, afe);
  541. +
  542. + afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
  543. + GFP_KERNEL);
  544. + if (!afe->platform_priv)
  545. + return -ENOMEM;
  546. +
  547. + afe_priv = afe->platform_priv;
  548. + afe->dev = &pdev->dev;
  549. + dev = afe->dev;
  550. +
  551. + afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
  552. + if (IS_ERR(afe->base_addr))
  553. + return PTR_ERR(afe->base_addr);
  554. +
  555. + /* initial audio related clock */
  556. + ret = mt7986_init_clock(afe);
  557. + if (ret)
  558. + return dev_err_probe(dev, ret, "Cannot initialize clocks\n");
  559. +
  560. + ret = devm_pm_runtime_enable(dev);
  561. + if (ret)
  562. + return ret;
  563. +
  564. + /* enable clock for regcache get default value from hw */
  565. + afe_priv->pm_runtime_bypass_reg_ctl = true;
  566. + pm_runtime_get_sync(&pdev->dev);
  567. +
  568. + afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
  569. + &mt7986_afe_regmap_config);
  570. +
  571. + pm_runtime_put_sync(&pdev->dev);
  572. + if (IS_ERR(afe->regmap))
  573. + return PTR_ERR(afe->regmap);
  574. +
  575. + afe_priv->pm_runtime_bypass_reg_ctl = false;
  576. +
  577. + /* init memif */
  578. + afe->memif_size = MT7986_MEMIF_NUM;
  579. + afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
  580. + GFP_KERNEL);
  581. + if (!afe->memif)
  582. + return -ENOMEM;
  583. +
  584. + for (i = 0; i < afe->memif_size; i++) {
  585. + afe->memif[i].data = &memif_data[i];
  586. + afe->memif[i].irq_usage = -1;
  587. + }
  588. +
  589. + mutex_init(&afe->irq_alloc_lock);
  590. +
  591. + /* irq initialize */
  592. + afe->irqs_size = MT7986_IRQ_NUM;
  593. + afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
  594. + GFP_KERNEL);
  595. + if (!afe->irqs)
  596. + return -ENOMEM;
  597. +
  598. + for (i = 0; i < afe->irqs_size; i++)
  599. + afe->irqs[i].irq_data = &irq_data[i];
  600. +
  601. + /* request irq */
  602. + irq_id = platform_get_irq(pdev, 0);
  603. + if (irq_id < 0) {
  604. + ret = irq_id;
  605. + return dev_err_probe(dev, ret, "No irq found\n");
  606. + }
  607. + ret = devm_request_irq(dev, irq_id, mt7986_afe_irq_handler,
  608. + IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
  609. + if (ret)
  610. + return dev_err_probe(dev, ret, "Failed to request irq for asys-isr\n");
  611. +
  612. + /* init sub_dais */
  613. + INIT_LIST_HEAD(&afe->sub_dais);
  614. +
  615. + for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) {
  616. + ret = dai_register_cbs[i](afe);
  617. + if (ret)
  618. + return dev_err_probe(dev, ret, "DAI register failed, i: %d\n", i);
  619. + }
  620. +
  621. + /* init dai_driver and component_driver */
  622. + ret = mtk_afe_combine_sub_dai(afe);
  623. + if (ret)
  624. + return dev_err_probe(dev, ret, "mtk_afe_combine_sub_dai fail\n");
  625. +
  626. + afe->mtk_afe_hardware = &mt7986_afe_hardware;
  627. + afe->memif_fs = mt7986_memif_fs;
  628. + afe->irq_fs = mt7986_irq_fs;
  629. +
  630. + afe->runtime_resume = mt7986_afe_runtime_resume;
  631. + afe->runtime_suspend = mt7986_afe_runtime_suspend;
  632. +
  633. + /* register component */
  634. + ret = devm_snd_soc_register_component(&pdev->dev,
  635. + &mt7986_afe_component,
  636. + NULL, 0);
  637. + if (ret)
  638. + return dev_err_probe(dev, ret, "Cannot register AFE component\n");
  639. +
  640. + ret = devm_snd_soc_register_component(afe->dev,
  641. + &mt7986_afe_pcm_dai_component,
  642. + afe->dai_drivers,
  643. + afe->num_dai_drivers);
  644. + if (ret)
  645. + return dev_err_probe(dev, ret, "Cannot register PCM DAI component\n");
  646. +
  647. + return 0;
  648. +}
  649. +
  650. +static void mt7986_afe_pcm_dev_remove(struct platform_device *pdev)
  651. +{
  652. + pm_runtime_disable(&pdev->dev);
  653. + if (!pm_runtime_status_suspended(&pdev->dev))
  654. + mt7986_afe_runtime_suspend(&pdev->dev);
  655. +}
  656. +
  657. +static const struct of_device_id mt7986_afe_pcm_dt_match[] = {
  658. + { .compatible = "mediatek,mt7986-afe" },
  659. + { /* sentinel */ }
  660. +};
  661. +MODULE_DEVICE_TABLE(of, mt7986_afe_pcm_dt_match);
  662. +
  663. +static const struct dev_pm_ops mt7986_afe_pm_ops = {
  664. + SET_RUNTIME_PM_OPS(mt7986_afe_runtime_suspend,
  665. + mt7986_afe_runtime_resume, NULL)
  666. +};
  667. +
  668. +static struct platform_driver mt7986_afe_pcm_driver = {
  669. + .driver = {
  670. + .name = "mt7986-audio",
  671. + .of_match_table = mt7986_afe_pcm_dt_match,
  672. + .pm = &mt7986_afe_pm_ops,
  673. + },
  674. + .probe = mt7986_afe_pcm_dev_probe,
  675. + .remove_new = mt7986_afe_pcm_dev_remove,
  676. +};
  677. +module_platform_driver(mt7986_afe_pcm_driver);
  678. +
  679. +MODULE_DESCRIPTION("MediaTek SoC AFE platform driver for ALSA MT7986");
  680. +MODULE_AUTHOR("Vic Wu <[email protected]>");
  681. +MODULE_LICENSE("GPL");