phy_audio_i2srx.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032
  1. /*
  2. * Copyright (c) 2020 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief Audio I2SRX physical implementation
  9. */
  10. /*
  11. * Features
  12. * - Support master and slave mode
  13. * - Support I2S 2ch format
  14. * - I2SRXFIFO(32 x 24bits level)
  15. * - Support 3 format: left-justified format, right-justified format, I2S format
  16. * - Support 16/20/24 effective data width; BCLK support 32/64fs, and MCLK=4BCLK
  17. * - Support sample rate auto detect in slave mode
  18. * - Sample rate support 8k/12k/11.025k/16k/22.05k/24k/32k/44.1k/48k/88.2k/96k/192k
  19. */
  20. #include <kernel.h>
  21. #include <device.h>
  22. #include <string.h>
  23. #include <errno.h>
  24. #include <soc.h>
  25. #include <board_cfg.h>
  26. #include "../phy_audio_common.h"
  27. #include "../audio_acts_utils.h"
  28. #include <drivers/audio/audio_in.h>
  29. #include <logging/log.h>
  30. LOG_MODULE_REGISTER(i2srx0, LOG_LEVEL_DBG);
  31. /***************************************************************************************************
  32. * I2SRX_CTL
  33. */
  34. #define I2SR0_CTL_PCM_SYNC BIT(26) /* PCM frame select*/
  35. #define I2SR0_CTL_PCM_CHAN_SHIFT (24)
  36. #define I2SR0_CTL_PCM_CHAN_MASK (0x3 << I2SR0_CTL_PCM_CHAN_SHIFT)
  37. #define I2SR0_CTL_PCM_CHAN(x) ((x) << I2SR0_CTL_PCM_CHAN_SHIFT) /* pcm slot select*/
  38. #define I2SR0_CTL_TDMRX_CHAN BIT(16) /* 4 channel or 8 channel */
  39. #define I2SR0_CTL_TDMRX_MODE BIT(15) /* I2S format or left-justified format */
  40. #define I2SR0_CTL_TDMRX_SYNC_SHIFT (13) /* at the beginning of the data frame, the type of LRCLK setting */
  41. #define I2SR0_CTL_TDMRX_SYNC_MASK (0x3 << I2SR0_CTL_TDMRX_SYNC_SHIFT)
  42. #define I2SR0_CTL_TDMRX_SYNC(x) ((x) << I2SR0_CTL_TDMRX_SYNC_SHIFT)
  43. #define I2SR0_CTL_PCMRX0_EN BIT(6) /* PCM TX ENABEL */
  44. #define I2SR0_CTL_RXWIDTH_SHIFT (4) /* effective width */
  45. #define I2SR0_CTL_RXWIDTH_MASK (0x3 << I2SR0_CTL_RXWIDTH_SHIFT)
  46. #define I2SR0_CTL_RXWIDTH(x) ((x) << I2SR0_CTL_RXWIDTH_SHIFT)
  47. #define I2SR0_CTL_RXBCLKSET BIT(3) /* rate of BCLK with LRCLK */
  48. #define I2SR0_CTL_RXMODELSEL_SHIFT (1) /* I2S transfer format select */
  49. #define I2SR0_CTL_RXMODELSEL_MASK (0x3 << I2SR0_CTL_RXMODELSEL_SHIFT)
  50. #define I2SR0_CTL_RXMODELSEL(x) ((x) << I2SR0_CTL_RXMODELSEL_SHIFT)
  51. #define I2SR0_CTL_RXEN BIT(0) /* I2S RX enable */
  52. /***************************************************************************************************
  53. * I2SRX_FIFOCTL
  54. */
  55. #define I2SR0_FIFOCTL_RXFIFO_DMAWIDTH BIT(7) /* DMA transfer width */
  56. #define I2SR0_FIFOCTL_RXFOS_SHIFT (4) /* RX FIFO output select */
  57. #define I2SR0_FIFOCTL_RXFOS_MASK (0x3 << I2SR0_FIFOCTL_RXFOS_SHIFT)
  58. #define I2SR0_FIFOCTL_RXFOS(x) ((x) << I2SR0_FIFOCTL_RXFOS_SHIFT)
  59. #define I2SR0_FIFOCTL_RXFFIE BIT(2) /* RX FIFO half filled irq enable */
  60. #define I2SR0_FIFOCTL_RXFFDE BIT(1) /* RX FIFO half filed drq enable */
  61. #define I2SR0_FIFOCTL_RXFRT BIT(0) /* RX FIFO reset */
  62. /***************************************************************************************************
  63. * I2SRX_STAT
  64. */
  65. #define I2SR0_FIFOSTA_FIFO_ER BIT(8) /* FIFO error */
  66. #define I2SR0_FIFOSTA_RXFEF BIT(7) /* RX FIFO empty flag */
  67. #define I2SR0_FIFOSTA_RXFIP BIT(6) /* RX FIFO half filled irq pending */
  68. #define I2SR0_FIFOSTA_RXFS_SHIFT (0) /* RX FIFO status */
  69. #define I2SR0_FIFOSTA_RXFS_MASK (0x3F << I2SR0_FIFOSTA_RXFS_SHIFT)
  70. /***************************************************************************************************
  71. * I2SRX_DAT
  72. */
  73. #define I2SR0_DAT_RXDAT_SHIFT (8) /* I2S RX FIFO data */
  74. #define I2SR0_DAT_RXDAT_MASK (0xFFFFFF << I2SR0_DAT_RXDAT_SHIFT)
  75. /***************************************************************************************************
  76. * I2SRX_CTL
  77. */
  78. #define I2SR0_SRDCTL_MUTE_EN BIT(12) /* If detect sample rate or channel width changing, mute output */
  79. #define I2SR0_SRDCTL_TO_IE BIT(11)
  80. #define I2SR0_SRDCTL_SRD_IE BIT(10)
  81. #define I2SR0_SRDCTL_CHW_IE BIT(8) /* sample rate detect result change interrupt enable */
  82. #define I2SR0_SRDCTL_CNT_TIM_SHIFT (4) /* slave mode rample rate detect counter period select */
  83. #define I2SR0_SRDCTL_CNT_TIM_MASK (0x3 << I2SR0_SRDCTL_CNT_TIM_SHIFT)
  84. #define I2SR0_SRDCTL_SRD_TH_SHIFT (1) /* the sampling sensitivity */
  85. #define I2SR0_SRDCTL_SRD_TH_MASK (0x7 << I2SR0_SRDCTL_SRD_TH_SHIFT)
  86. #define I2SR0_SRDCTL_SRD_TH(x) ((x) << I2SR0_SRDCTL_SRD_TH_SHIFT)
  87. #define I2SR0_SRDCTL_SRD_EN BIT(0) /* slave mode sample rate detect enable */
  88. /***************************************************************************************************
  89. * I2SRX_SRDSTA
  90. */
  91. #define I2SR0_SRDSTA_CNT_SHIFT (12) /* CNT of LRCLK which sampling by SRC_CLK */
  92. #define I2SR0_SRDSTA_CNT_MASK (0x1FFF << I2SR0_SRDSTA_CNT_SHIFT)
  93. #define I2SR0_SRDSTA_TO_PD BIT(11) /* sample rate changing detection timeout interrupt pending */
  94. #define I2SR0_SRDSTA_SRC_PD BIT(10) /* sample rate changing detection interrupt pending */
  95. #define I2SR0_SRDSTA_CHW_PD BIT(8) /* channel width change interrupt pending */
  96. #define I2SR0_SRDSTA_WL_SHIFT (0) /* channel word length */
  97. #define I2SR0_SRDSTA_WL_MASK (0x7 << I2SR0_SRDSTA_WL_SHIFT)
  98. /***************************************************************************************************
  99. * i2SRX FEATURES CONGIURATION
  100. */
  101. /* The sensitivity of the SRD */
  102. #define I2SRX_SRD_TH_DEFAULT (7)
  103. #define I2SRX_BCLK_DIV_DEFAULT (0) /* BCLK divisor */
  104. #define I2SRX_SRD_CONFIG_TIMEOUT_US (500000)
  105. /*
  106. * enum a_i2srx_mclk_clksrc_e
  107. * @brief The MCLK clock source of i2srx selection
  108. */
  109. typedef enum {
  110. CLK_SRCRX_I2SRX = 0, /* I2SRX clock source from I2SRX clk */
  111. CLK_SRCRX_I2STX, /* I2SRX clock source from I2STX MCLK */
  112. CLK_SRCRX_I2SRX_EXT = 3, /* I2SRX clock source from I2SRX extern MCLK */
  113. } a_i2srx_mclk_clksrc_e;
  114. /*
  115. * @struct acts_audio_i2srx
  116. * @brief I2SRX controller hardware register
  117. */
  118. struct acts_audio_i2srx {
  119. volatile uint32_t rx_ctl; /* I2SRX control */
  120. volatile uint32_t fifoctl; /* I2SRX FIFO control */
  121. volatile uint32_t fifostat; /* I2SRX FIFO state */
  122. volatile uint32_t dat; /* I2SRX FIFO data */
  123. volatile uint32_t srdctl; /* I2S slave mode RX sample rate detect control */
  124. volatile uint32_t srdstat; /* I2S slave mode RX sample rate detect state */
  125. };
  126. /*
  127. * struct phy_i2srx_drv_data
  128. * @brief The software related data that used by physical i2srx driver.
  129. */
  130. struct phy_i2srx_drv_data {
  131. uint8_t mclksrc; /* MCLK clock source selection refer to #a_i2srx_mclk_clksrc_e */
  132. int (*srd_callback)(void *cb_data, uint32_t cmd, void *param);
  133. void *cb_data;
  134. uint8_t srd_wl; /* The width length detected by SRD */
  135. uint8_t sample_rate; /* sample rate */
  136. uint8_t channel_opened : 1; /* flag of channel opened */
  137. };
  138. /**
  139. * union phy_i2srx_features
  140. * @brief The infomation from DTS to control the I2SRX features to enable or nor.
  141. */
  142. typedef union {
  143. uint32_t raw;
  144. struct {
  145. uint32_t srd_en : 1; /* SRD function enable or not */
  146. uint32_t mode: 1; /* master mode or slaver mode; 0: master 1: slaver */
  147. uint32_t channel_num : 4; /* channel number and only support 2/4/8 channels */
  148. uint32_t slave_internal_clk : 1; /* slave mode MCLK to use internal clock */
  149. uint32_t lrclk_proc : 1; /* LRCLK process */
  150. uint32_t mclk_reverse : 1; /* mclk reverse */
  151. uint32_t format : 2; /* I2S transfer format */
  152. uint32_t clk_from_i2stx : 1; /* clock from I2STX(I2SG0) clock */
  153. uint32_t tdm_format : 1; /* TDM format */
  154. uint32_t tdm_frame : 2; /* TDM frame start position */
  155. uint32_t bclk_width : 1; /* bclk width */
  156. uint32_t pcm_en : 1; /* pcm select */
  157. uint32_t pcm_frame : 1; /* pcm frame */
  158. uint32_t pcm_slot : 2; /* pcm slot */
  159. } v;
  160. } phy_i2srx_features;
  161. /**
  162. * struct phy_i2srx_config_data
  163. * @brief The hardware related data that used by physical i2srx driver.
  164. */
  165. struct phy_i2srx_config_data {
  166. uint32_t reg_base; /* I2STX controller register base address */
  167. uint8_t clk_id; /* I2STX devclk id */
  168. uint8_t srd_clk_id; /* I2S SRD clock id */
  169. uint8_t hclk_clk_id; /* I2S HCLK clock id */
  170. uint8_t rst_id; /* I2STX reset id */
  171. struct audio_dma_dt dma_fifo0; /* DMA resource for SPDIFRX */
  172. void (*irq_config)(void); /* IRQ configuration function */
  173. phy_i2srx_features features; /* I2STX features */
  174. };
  175. /* @brief Get the I2SRX controller base address */
  176. static inline struct acts_audio_i2srx *get_i2srx_reg_base(struct device *dev)
  177. {
  178. const struct phy_i2srx_config_data *cfg = dev->config;
  179. return (struct acts_audio_i2srx *)cfg->reg_base;
  180. }
  181. /* @brief Dump the I2SRX relative registers */
  182. static void i2srx_dump_register(struct device *dev)
  183. {
  184. struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
  185. LOG_INF("** i2srx contoller regster **");
  186. LOG_INF(" BASE: %08x", (uint32_t)i2srx_reg);
  187. LOG_INF(" I2SRX_CTL: %08x", i2srx_reg->rx_ctl);
  188. LOG_INF(" I2SRX_FIFOCTL: %08x", i2srx_reg->fifoctl);
  189. LOG_INF(" I2SRX_FIFOSTA: %08x", i2srx_reg->fifostat);
  190. LOG_INF(" I2SRX_DAT: %08x", i2srx_reg->dat);
  191. LOG_INF(" I2SRX_SRDCTL: %08x", i2srx_reg->srdctl);
  192. LOG_INF(" I2SRX_SRDSTA: %08x", i2srx_reg->srdstat);
  193. LOG_INF(" AUDIOPLL0_CTL: %08x", sys_read32(AUDIO_PLL0_CTL));
  194. LOG_INF(" AUDIOPLL1_CTL: %08x", sys_read32(AUDIO_PLL1_CTL));
  195. LOG_INF(" CMU_I2STXCLK: %08x", sys_read32(CMU_I2STXCLK));
  196. LOG_INF(" CMU_I2SRXCLK: %08x", sys_read32(CMU_I2SRXCLK));
  197. LOG_INF(" DMA6_CTL: %08x", sys_read32(0x4001c700));
  198. LOG_INF(" DMA6_START: %08x", sys_read32(0x4001c704));
  199. LOG_INF(" DMA6_sadd0: %08x", sys_read32(0x4001c708));
  200. LOG_INF(" DMA6_sadd1: %08x", sys_read32(0x4001c70c));
  201. LOG_INF(" DMA6_dadd0: %08x", sys_read32(0x4001c710));
  202. LOG_INF(" DMA6_dadd1: %08x", sys_read32(0x4001c714));
  203. LOG_INF(" DMA6_bc: %08x", sys_read32(0x4001c718));
  204. LOG_INF(" DMA6_rc: %08x", sys_read32(0x4001c71c));
  205. }
  206. /* @brief I2SRX sample rate config */
  207. static int i2srx_sample_rate_set(struct device *dev, uint16_t sr_khz,
  208. a_i2srx_mclk_clksrc_e mclk_src)
  209. {
  210. const struct phy_i2srx_config_data *cfg = dev->config;
  211. int ret;
  212. uint8_t clk_div, series, pll_index;
  213. uint32_t reg = 0;
  214. uint32_t lrclk_div;
  215. a_mclk_type_e mclk;
  216. switch (I2SRX_BCLK_DIV_DEFAULT)
  217. {
  218. case 0:
  219. if (!PHY_DEV_FEATURE(bclk_width))
  220. mclk = MCLK_256FS;
  221. else
  222. mclk = MCLK_128FS;
  223. break;
  224. case 1:
  225. if (!PHY_DEV_FEATURE(bclk_width))
  226. mclk = MCLK_384FS;
  227. else
  228. mclk = MCLK_192FS;
  229. break;
  230. case 2:
  231. if (!PHY_DEV_FEATURE(bclk_width))
  232. mclk = MCLK_512FS;
  233. else
  234. mclk = MCLK_256FS;
  235. break;
  236. case 3:
  237. if (!PHY_DEV_FEATURE(bclk_width))
  238. mclk = MCLK_768FS;
  239. else
  240. mclk = MCLK_384FS;
  241. break;
  242. default:
  243. if (!PHY_DEV_FEATURE(bclk_width))
  244. mclk = MCLK_256FS;
  245. else
  246. mclk = MCLK_128FS;
  247. break;
  248. }
  249. if (CLK_SRCRX_I2STX == mclk_src) {
  250. struct device *i2stx_dev = (struct device *)device_get_binding(CONFIG_AUDIO_I2STX_0_NAME);
  251. if (!i2stx_dev) {
  252. LOG_ERR("failed to get i2stx dev %s", CONFIG_AUDIO_I2STX_0_NAME);
  253. return -ENODEV;
  254. }
  255. return phy_audio_control(i2stx_dev, PHY_CMD_I2STX_CLK_SET, &sr_khz);
  256. } else if (CLK_SRCRX_I2SRX == mclk_src) {
  257. /* make external MCLK clock phase reverse */
  258. if (PHY_DEV_FEATURE(mclk_reverse))
  259. reg |= CMU_I2SRXCLK_I2SG1MCLKEXTREV;
  260. /* I2S master mode to enable MCLK output to PAD */
  261. if (!PHY_DEV_FEATURE(mode)) {
  262. reg |= (CMU_I2SG1MCLKOEN | CMU_I2SG1BCLKOEN | CMU_I2SG1LRCLOKEN | CMU_I2SRXCLK_I2SRX0CLKSRC);
  263. } else {
  264. if (PHY_DEV_FEATURE(slave_internal_clk))
  265. sr_khz *= 2; /* slave mode use internal clk condition: MCLK > 6BCLK */
  266. /* BCLK/LRCLK source from external PAD */
  267. reg |= CMU_I2SRXCLK_I2SG1BLRCLKSRC;
  268. }
  269. reg |= CMU_I2SRXCLK_I2SG1LRCLKPROC(PHY_DEV_FEATURE(lrclk_proc));
  270. /* BCLK = FS x channel number x channel bit width */
  271. if (!PHY_DEV_FEATURE(bclk_width))
  272. lrclk_div = PHY_DEV_FEATURE(channel_num) * 32;
  273. else
  274. lrclk_div = PHY_DEV_FEATURE(channel_num) * 16;
  275. /* LRCLK divisor 0:32; 1:64; 2: 128; 3:256 */
  276. if (32 == lrclk_div) {
  277. lrclk_div = 0;
  278. } else if (64 == lrclk_div) {
  279. lrclk_div = 1;
  280. } else if (128 == lrclk_div) {
  281. lrclk_div = 2;
  282. } else if (256 == lrclk_div) {
  283. lrclk_div = 3;
  284. } else {
  285. LOG_ERR("invalid lrclk divisor:%d", lrclk_div);
  286. return -EINVAL;
  287. }
  288. reg |= CMU_I2SRXCLK_I2SG1LRCLKDIV(lrclk_div);
  289. /* MCLK = 4 x BCLK */
  290. reg |= CMU_I2SRXCLK_I2SG1BCLKDIV(I2SRX_BCLK_DIV_DEFAULT);
  291. sr_khz = PHY_DEV_FEATURE(channel_num) / 2 * sr_khz;
  292. /* Get audio PLL setting */
  293. ret = audio_get_pll_setting_i2s(sr_khz, mclk, &clk_div, &series);
  294. if (ret) {
  295. LOG_DBG("get pll setting error:%d", ret);
  296. return ret;
  297. }
  298. ret = audio_pll_check_config(series, &pll_index);
  299. if (ret) {
  300. LOG_DBG("check pll config error:%d", ret);
  301. return ret;
  302. }
  303. /* Select pll0 or pll1 */
  304. // reg |= (pll_index & 0x1) << CMU_I2SRXCLK_I2SG1CLKSRC;
  305. reg |= clk_div << CMU_I2SRXCLK_I2SG1CLKDIV_SHIFT;
  306. } else if (CLK_SRCRX_I2SRX_EXT == mclk_src) {
  307. LOG_INF("I2SRX clock source from external");
  308. /* BCLK/LRCLK source from external PAD */
  309. // reg |= CMU_I2SRXCLK_I2SG1BLRCLKSRC;//RX CLOCK来自G0
  310. reg |= CMU_I2SRXCLK_I2SG1BLRCLKSRC | CMU_I2SRXCLK_I2SRX0CLKSRC;//CLOCK来自G1
  311. } else {
  312. LOG_ERR("Invalid i2srx clk source %d", mclk_src);
  313. return -EINVAL;
  314. }
  315. /* Select the i2srx mclk source */
  316. reg |= CMU_I2SRXCLK_I2SG1MCLKSRC(mclk_src);
  317. sys_write32(reg, CMU_I2SRXCLK);
  318. return 0;
  319. }
  320. /* @brief Get the sample rate from the I2SRX config */
  321. static int i2srx_sample_rate_get(struct device *dev)
  322. {
  323. const struct phy_i2srx_config_data *cfg = dev->config;
  324. uint8_t clk_div, pll_index, mclk_src;
  325. uint32_t reg;
  326. int ret = -1;
  327. a_mclk_type_e mclk;
  328. if (!PHY_DEV_FEATURE(bclk_width))
  329. mclk = MCLK_256FS;
  330. else
  331. mclk = MCLK_128FS;
  332. reg = sys_read32(CMU_I2SRXCLK);
  333. mclk_src = (reg & CMU_I2SRXCLK_I2SG1MCLKSRC_MASK) >> CMU_I2SRXCLK_I2SG1MCLKSRC_SHIFT;
  334. if (CLK_SRCRX_I2SRX == mclk_src) {
  335. clk_div = reg & 0xF;
  336. pll_index = 0;//leopard 只有一个PLL0源
  337. ret = audio_get_pll_sample_rate_i2s(MCLK_256FS, clk_div, pll_index);
  338. } else if (CLK_SRCRX_I2STX == mclk_src) {
  339. reg = sys_read32(CMU_I2STXCLK);
  340. clk_div = reg & 0xF;
  341. pll_index = 0;
  342. ret = audio_get_pll_sample_rate_i2s(mclk, clk_div, pll_index);
  343. } else if (CLK_SRCRX_I2SRX_EXT == mclk_src) {
  344. LOG_INF("I2SRX is using the external clock");
  345. ret = -ENOENT;
  346. }
  347. return ret;
  348. }
  349. /* @brief Get the AUDIO_PLL APS used by I2SRX */
  350. static int i2srx_get_pll_aps(struct device *dev)
  351. {
  352. uint32_t reg;
  353. uint8_t pll_index, mclk_src;
  354. int ret = -1;
  355. reg = sys_read32(CMU_I2SRXCLK);
  356. mclk_src = (reg & CMU_I2SRXCLK_I2SG1MCLKSRC_MASK) >> CMU_I2SRXCLK_I2SG1MCLKSRC_SHIFT;
  357. pll_index = AUDIOPLL_TYPE_0;//leopard 只有一个PLL0源
  358. if (CLK_SRCRX_I2SRX == mclk_src) {
  359. ret = audio_pll_get_aps((a_pll_type_e)pll_index);
  360. } else if (CLK_SRCRX_I2STX == mclk_src) {
  361. reg = sys_read32(CMU_I2STXCLK);
  362. ret = audio_pll_get_aps((a_pll_type_e)pll_index);
  363. }if (CLK_SRCRX_I2SRX_EXT == mclk_src) {
  364. LOG_INF("I2SRX is using the external clock source");
  365. return -ENOENT;
  366. }
  367. return ret;
  368. }
  369. /* @brief Set the AUDIO_PLL APS used by I2SRX */
  370. static int i2srx_set_pll_aps(struct device *dev, audio_aps_level_e level)
  371. {
  372. uint32_t reg;
  373. uint8_t pll_index, mclk_src;
  374. int ret = -1;
  375. reg = sys_read32(CMU_I2SRXCLK);
  376. mclk_src = (reg & CMU_I2SRXCLK_I2SG1MCLKSRC_MASK) >> CMU_I2SRXCLK_I2SG1MCLKSRC_SHIFT;
  377. if (CLK_SRCRX_I2SRX == mclk_src) {
  378. pll_index = AUDIOPLL_TYPE_0;//leopard 只有一个PLL0源
  379. ret = audio_pll_set_aps((a_pll_type_e)pll_index, level);
  380. } else if (CLK_SRCRX_I2STX == mclk_src) {
  381. reg = sys_read32(CMU_I2STXCLK);
  382. pll_index = AUDIOPLL_TYPE_0;
  383. ret = audio_pll_set_aps((a_pll_type_e)pll_index, level);
  384. } else if (CLK_SRCRX_I2SRX_EXT == mclk_src) {
  385. LOG_INF("I2SRX is using the external clock source");
  386. ret = -ENOENT;
  387. }
  388. return ret;
  389. }
  390. /* @brief Disable the I2SRX FIFO */
  391. static void i2srx_fifo_disable(struct device *dev)
  392. {
  393. struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
  394. i2srx_reg->fifoctl &= ~I2SR0_CTL_RXEN;
  395. }
  396. /* @brief Reset the I2SRX FIFO */
  397. static void i2srx_fifo_reset(struct device *dev)
  398. {
  399. struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
  400. i2srx_reg->fifoctl &= ~I2SR0_CTL_RXEN;
  401. i2srx_reg->fifoctl |= I2SR0_CTL_RXEN;
  402. }
  403. /* @brief Enable the I2SRX FIFO */
  404. static void i2srx_fifo_enable(struct device *dev, audio_fifouse_sel_e sel, audio_dma_width_e width)
  405. {
  406. struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
  407. uint32_t reg = 0;
  408. if (DMA_WIDTH_16BITS == width)
  409. reg |= I2SR0_FIFOCTL_RXFIFO_DMAWIDTH;
  410. if (FIFO_SEL_CPU == sel) {
  411. reg |= (I2SR0_FIFOCTL_RXFFIE | I2SR0_FIFOCTL_RXFRT);
  412. } else if (FIFO_SEL_DMA == sel) {
  413. reg |= (I2SR0_FIFOCTL_RXFFDE | I2SR0_FIFOCTL_RXFRT
  414. | I2SR0_FIFOCTL_RXFOS(1));
  415. } else if (FIFO_SEL_DSP == sel) {
  416. reg |= I2SR0_FIFOCTL_RXFOS(3) | I2SR0_FIFOCTL_RXFRT;
  417. } else {
  418. LOG_ERR("invalid fifo sel %d", sel);
  419. }
  420. i2srx_reg->fifoctl = reg;
  421. }
  422. /* @brief I2SRX digital function control */
  423. static void i2srx_digital_enable(struct device *dev, audio_ch_width_e width)
  424. {
  425. const struct phy_i2srx_config_data *cfg = dev->config;
  426. struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
  427. uint32_t reg = 0;
  428. uint8_t rx_width, fmt = PHY_DEV_FEATURE(format);
  429. uint8_t pcm_frame = PHY_DEV_FEATURE(pcm_frame);
  430. uint8_t pcm_slot = PHY_DEV_FEATURE(pcm_slot);
  431. if (CHANNEL_WIDTH_16BITS == width)
  432. rx_width = 0;
  433. else if (CHANNEL_WIDTH_20BITS == width)
  434. rx_width = 1;
  435. else
  436. rx_width = 2;
  437. if (PHY_DEV_FEATURE(channel_num) != 2) {
  438. fmt = 3; /* TDM mode */
  439. reg &= ~ (0xF << I2SR0_CTL_TDMRX_SYNC_SHIFT);
  440. if (PHY_DEV_FEATURE(channel_num) == 8)
  441. reg |= I2SR0_CTL_TDMRX_CHAN;
  442. if (PHY_DEV_FEATURE(tdm_format))
  443. reg |= I2SR0_CTL_TDMRX_MODE;
  444. reg |= I2SR0_CTL_TDMRX_SYNC(PHY_DEV_FEATURE(tdm_frame));
  445. }
  446. reg |= (I2SR0_CTL_RXMODELSEL(fmt) | I2SR0_CTL_RXWIDTH(rx_width));
  447. if (PHY_DEV_FEATURE(bclk_width))
  448. reg |= I2SR0_CTL_RXBCLKSET;
  449. i2srx_reg->rx_ctl = reg;
  450. /* PCM RX enable */
  451. if(PHY_DEV_FEATURE(pcm_en))
  452. {
  453. i2srx_reg->rx_ctl |= I2SR0_CTL_PCM_CHAN(pcm_slot);
  454. i2srx_reg->rx_ctl |= I2SR0_CTL_PCMRX0_EN;
  455. //pcm frame set 1 is long frame
  456. if(pcm_frame)
  457. {
  458. i2srx_reg->rx_ctl |= I2SR0_CTL_PCM_SYNC;
  459. sys_write32(sys_read32(CMU_I2SRXCLK)|
  460. CMU_I2SRXCLK_I2SG1LRCLKPROC(2),
  461. CMU_I2SRXCLK);
  462. }
  463. else
  464. sys_write32(sys_read32(CMU_I2SRXCLK)|
  465. CMU_I2SRXCLK_I2SG1LRCLKPROC(3),
  466. CMU_I2SRXCLK);
  467. }
  468. else
  469. /* I2S RX enable */
  470. i2srx_reg->rx_ctl |= I2SR0_CTL_RXEN;
  471. }
  472. /* @brief Disable I2SRX digital function */
  473. static void i2srx_digital_disable(struct device *dev)
  474. {
  475. struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
  476. i2srx_reg->rx_ctl = 0;
  477. }
  478. /* @brief get the I2SRX sample rate detect counter */
  479. static uint32_t read_i2srx_srd_count(struct device *dev)
  480. {
  481. struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
  482. /* CNT of LRCLK which sampling by SRC_CLK */
  483. return ((i2srx_reg->srdstat & I2SR0_SRDSTA_CNT_MASK) >> I2SR0_SRDSTA_CNT_SHIFT);
  484. }
  485. /* @brief I2SRX in slave mode handle sample rate detect change */
  486. static void i2srx_srd_fs_change(struct device *dev)
  487. {
  488. const struct phy_i2srx_config_data *cfg = dev->config;
  489. struct phy_i2srx_drv_data *data = dev->data;
  490. uint32_t cnt, fs;
  491. audio_sr_sel_e sr;
  492. cnt = read_i2srx_srd_count(dev);
  493. /* CNT = SRD_CLK / LRCLK and SRD_CLK uses HOSC which is a 32MHz clock source*/
  494. fs = 32 *1000 / cnt;
  495. /* Allow a 1% deviation */
  496. if ((fs > 7920) && (fs < 8080)) { /* 8kfs */
  497. sr = SAMPLE_RATE_8KHZ;
  498. } else if ((fs > 10915) && (fs < 11135)) { /* 11.025kfs */
  499. sr = SAMPLE_RATE_11KHZ;
  500. } else if ((fs > 11880) && (fs < 12120)) { /* 12kfs */
  501. sr = SAMPLE_RATE_12KHZ;
  502. } else if ((fs > 15840) && (fs < 16160)) { /* 16kfs */
  503. sr = SAMPLE_RATE_16KHZ;
  504. } else if ((fs > 21830) && (fs < 22270)) { /* 22.05kfs */
  505. sr = SAMPLE_RATE_22KHZ;
  506. } else if ((fs > 23760) && (fs < 24240)) { /* 24kfs */
  507. sr = SAMPLE_RATE_24KHZ;
  508. } else if ((fs > 31680) && (fs < 32320)) { /* 32kfs */
  509. sr = SAMPLE_RATE_32KHZ;
  510. } else if ((fs > 43659) && (fs < 44541)) { /* 44.1kfs */
  511. sr = SAMPLE_RATE_44KHZ;
  512. } else if ((fs > 47520) && (fs < 48480)) { /* 48kfs */
  513. sr = SAMPLE_RATE_48KHZ;
  514. } else if ((fs > 63360) && (fs < 64640)) { /* 64kfs */
  515. sr = SAMPLE_RATE_64KHZ;
  516. } else if ((fs > 87318) && (fs < 89082)) { /* 88.2kfs */
  517. sr = SAMPLE_RATE_88KHZ;
  518. } else if ((fs > 95040) && (fs < 96960)) { /* 96kfs */
  519. sr = SAMPLE_RATE_96KHZ;
  520. } else if ((fs > 174636) && (fs < 178164)) { /* 176.4kfs */
  521. sr = SAMPLE_RATE_176KHZ;
  522. } else if((fs > 190080) && (fs < 193920)) { /* 192kfs */
  523. sr = SAMPLE_RATE_192KHZ;
  524. } else {
  525. LOG_ERR("Invalid sample rate %d", fs);
  526. return ;
  527. }
  528. LOG_INF("Detect new sample rate %d -> %d", fs, sr);
  529. /* FIXME: If not do the fifo reset, the left and right channel will exchange probably. */
  530. i2srx_fifo_reset(dev);
  531. if (data->sample_rate != sr && PHY_DEV_FEATURE(slave_internal_clk)) {
  532. i2srx_sample_rate_set(dev, sr, data->mclksrc);
  533. data->sample_rate = sr;
  534. }
  535. if (data->srd_callback)
  536. data->srd_callback(data->cb_data, I2SRX_SRD_FS_CHANGE, (void *)&sr);
  537. }
  538. /* @brief I2SRX SRD width length change operation */
  539. void i2srx_srd_wl_change(struct device *dev)
  540. {
  541. struct phy_i2srx_drv_data *data = dev->data;
  542. struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
  543. uint8_t width;
  544. width = i2srx_reg->srdstat & I2SR0_SRDSTA_WL_MASK;
  545. LOG_DBG("Detect new width length: %d", width);
  546. if (((data->srd_wl == SRDSTA_WL_64RATE) && (width == SRDSTA_WL_32RATE))
  547. || ((data->srd_wl == SRDSTA_WL_32RATE) && (width == SRDSTA_WL_64RATE))) {
  548. data->srd_wl = width;
  549. if (data->srd_callback)
  550. data->srd_callback(data->cb_data, I2SRX_SRD_WL_CHANGE, (void *)&data->srd_wl);
  551. }
  552. }
  553. /* @brief I2SRX sample rate detect function configuration */
  554. static int i2srx_srd_cfg(struct device *dev, uint8_t srd_th, audio_i2s_srd_period_e period, bool irq_en, bool mute)
  555. {
  556. const struct phy_i2srx_config_data *cfg = dev->config;
  557. struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
  558. uint32_t reg;
  559. uint8_t _wl, wl;
  560. uint32_t start_time, curr_time;
  561. reg = (I2SR0_SRDCTL_SRD_TH(srd_th & 0x7) | I2SR0_SRDCTL_SRD_TH(period));
  562. if (irq_en)
  563. reg |= I2SR0_SRDCTL_CHW_IE | I2SR0_SRDCTL_SRD_IE | I2SR0_SRDCTL_TO_IE;
  564. if (mute)
  565. reg |= I2SR0_SRDCTL_MUTE_EN;
  566. i2srx_reg->srdctl = reg;
  567. /* enable slave mode sample rate detect */
  568. i2srx_reg->srdctl |= I2SR0_SRDCTL_SRD_EN;
  569. if (!PHY_DEV_FEATURE(bclk_width))
  570. wl = SRDSTA_WL_64RATE;
  571. else
  572. wl = SRDSTA_WL_32RATE;
  573. start_time = k_cycle_get_32();
  574. _wl = i2srx_reg->srdstat & I2SR0_SRDSTA_WL_MASK;
  575. while (_wl != wl) {
  576. curr_time = k_cycle_get_32();
  577. if (k_cyc_to_us_floor32(curr_time - start_time) > I2SRX_SRD_CONFIG_TIMEOUT_US) {
  578. LOG_ERR("Wait SRD WL status timeout");
  579. return -ETIMEDOUT;
  580. }
  581. _wl = i2srx_reg->srdstat & I2SR0_SRDSTA_WL_MASK;
  582. k_sleep(K_MSEC(2));
  583. }
  584. i2srx_reg->srdstat |= I2SR0_SRDSTA_CHW_PD;
  585. i2srx_srd_fs_change(dev);
  586. return 0;
  587. }
  588. // static int set_gpio_mfc(int type, int gpio_m_num,int gpio__b_num,int gpio_lr_num,int gpio_io_num)
  589. // {
  590. // if(type==0)
  591. // {
  592. // //i2s tx gpio_mfc_config
  593. // sys_write32(0x0000100c,GPIO_REG_BASE + gpio_m_num * 0x4);
  594. // sys_write32(0x0000100c,GPIO_REG_BASE + gpio__b_num * 0x4);
  595. // sys_write32(0x0000100c,GPIO_REG_BASE + gpio_lr_num * 0x4);
  596. // sys_write32(0x0000100c,GPIO_REG_BASE + gpio_io_num * 0x4);
  597. // printk("%08x\n",(sys_read32(GPIO_REG_BASE + gpio_m_num * 0x4)));
  598. // printk("%08x\n",(sys_read32(GPIO_REG_BASE + gpio__b_num * 0x4)));
  599. // printk("%08x\n",(sys_read32(GPIO_REG_BASE + gpio_lr_num * 0x4)));
  600. // printk("%08x\n",(sys_read32(GPIO_REG_BASE + gpio_io_num * 0x4)));
  601. // }
  602. // else
  603. // {
  604. // //i2s rx gpio_mfc_config
  605. // sys_write32(0x0000100d,GPIO_REG_BASE + gpio_m_num * 0x4);
  606. // sys_write32(0x0000100d,GPIO_REG_BASE + gpio__b_num * 0x4);
  607. // sys_write32(0x0000100d,GPIO_REG_BASE + gpio_lr_num * 0x4);
  608. // sys_write32(0x0000100d,GPIO_REG_BASE + gpio_io_num * 0x4);
  609. // printk("%08x\n",*((volatile unsigned int*)(GPIO_REG_BASE + gpio_m_num * 0x4)));
  610. // printk("%08x\n",*((volatile unsigned int*)(GPIO_REG_BASE + gpio__b_num * 0x4)));
  611. // printk("%08x\n",*((volatile unsigned int*)(GPIO_REG_BASE + gpio_lr_num * 0x4)));
  612. // printk("%08x\n",*((volatile unsigned int*)(GPIO_REG_BASE + gpio_io_num * 0x4)));
  613. // }
  614. // return 0;
  615. // }
  616. /* @brief physical I2SRX device enable */
  617. static int phy_i2srx_enable(struct device *dev, void *param)
  618. {
  619. const struct phy_i2srx_config_data *cfg = dev->config;
  620. struct phy_i2srx_drv_data *data = dev->data;
  621. ain_param_t *in_param = (ain_param_t *)param;
  622. i2srx_setting_t *i2srx_setting = in_param->i2srx_setting;
  623. soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, true);
  624. if ((!in_param) || (!i2srx_setting)
  625. || (!in_param->sample_rate)) {
  626. LOG_ERR("Invalid parameters");
  627. soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, false);
  628. return -EINVAL;
  629. }
  630. if (in_param->channel_type != AUDIO_CHANNEL_I2SRX) {
  631. LOG_ERR("Invalid channel type %d", in_param->channel_type);
  632. soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, false);
  633. return -EINVAL;
  634. }
  635. /* enable adc clock */
  636. acts_clock_peripheral_enable(cfg->clk_id);
  637. acts_clock_peripheral_enable(cfg->hclk_clk_id);
  638. if (PHY_DEV_FEATURE(srd_en))
  639. acts_clock_peripheral_enable(cfg->srd_clk_id);
  640. /* slave mode and clock from external source */
  641. if (PHY_DEV_FEATURE(mode)
  642. && !PHY_DEV_FEATURE(slave_internal_clk)) {
  643. data->mclksrc = CLK_SRCRX_I2SRX_EXT;
  644. } else if (PHY_DEV_FEATURE(clk_from_i2stx)) {
  645. if (PHY_DEV_FEATURE(mode)) {
  646. LOG_ERR("clock source form I2STX shall work in master mode");
  647. soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, false);
  648. return -EPERM;
  649. }
  650. data->mclksrc = CLK_SRCRX_I2STX;
  651. } else {
  652. data->mclksrc = CLK_SRCRX_I2SRX;
  653. }
  654. /* I2SRX sample rate set */
  655. if (i2srx_sample_rate_set(dev, in_param->sample_rate, data->mclksrc)) {
  656. LOG_ERR("Failed to config sample rate %d",
  657. in_param->sample_rate);
  658. soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, false);
  659. return -ESRCH;
  660. }
  661. /*enable txfifo clock*/
  662. sys_write32(sys_read32(CMU_I2SRXCLK) | CMU_I2SRX0_FIFOCLKEN, CMU_I2SRXCLK);
  663. i2srx_fifo_enable(dev, FIFO_SEL_DMA, (in_param->channel_width == CHANNEL_WIDTH_16BITS)
  664. ? DMA_WIDTH_16BITS : DMA_WIDTH_32BITS);
  665. i2srx_digital_enable(dev, in_param->channel_width);
  666. if (PHY_DEV_FEATURE(mode) && PHY_DEV_FEATURE(srd_en)) {
  667. LOG_INF("I2SRX SRD enable");
  668. i2srx_srd_cfg(dev, I2SRX_SRD_TH_DEFAULT, I2S_SRD_2LRCLK, true, false);
  669. data->srd_callback = i2srx_setting->srd_callback;
  670. data->cb_data = i2srx_setting->cb_data;
  671. if (!PHY_DEV_FEATURE(bclk_width))
  672. data->srd_wl = SRDSTA_WL_64RATE;
  673. else
  674. data->srd_wl = SRDSTA_WL_32RATE;
  675. }
  676. data->channel_opened = 1;
  677. // set_gpio_mfc(1,16,17,21,15);//rx
  678. return 0;
  679. }
  680. /* @brief physical I2SRX device disable */
  681. static int phy_i2srx_disable(struct device *dev, void *param)
  682. {
  683. const struct phy_i2srx_config_data *cfg = dev->config;
  684. struct phy_i2srx_drv_data *data = dev->data;
  685. i2srx_fifo_disable(dev);
  686. i2srx_digital_disable(dev);
  687. if (PHY_DEV_FEATURE(srd_en))
  688. acts_clock_peripheral_disable(cfg->srd_clk_id);
  689. data->srd_callback = NULL;
  690. data->cb_data = NULL;
  691. if (!PHY_DEV_FEATURE(bclk_width))
  692. data->srd_wl = SRDSTA_WL_64RATE;
  693. else
  694. data->srd_wl = SRDSTA_WL_32RATE;
  695. data->sample_rate = 0;
  696. data->channel_opened = 0;
  697. acts_clock_peripheral_disable(cfg->clk_id);
  698. soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, false);
  699. return 0;
  700. }
  701. /* @brief physical I2SRX IO commands */
  702. static int phy_i2srx_ioctl(struct device *dev, uint32_t cmd, void *param)
  703. {
  704. const struct phy_i2srx_config_data *cfg = dev->config;
  705. struct phy_i2srx_drv_data *data = dev->data;
  706. int ret = 0;
  707. switch (cmd) {
  708. case PHY_CMD_DUMP_REGS:
  709. {
  710. i2srx_dump_register(dev);
  711. break;
  712. }
  713. case AIN_CMD_I2SRX_QUERY_SAMPLE_RATE:
  714. {
  715. *(audio_sr_sel_e *)param = data->sample_rate;
  716. break;
  717. }
  718. case PHY_CMD_I2SRX_IS_OPENED:
  719. {
  720. *(uint8_t *)param = data->channel_opened;
  721. break;
  722. }
  723. case AIN_CMD_GET_SAMPLERATE:
  724. {
  725. ret = i2srx_sample_rate_get(dev);
  726. if (ret < 0) {
  727. LOG_ERR("Failed to get I2SRX sample rate err=%d", ret);
  728. return ret;
  729. }
  730. *(audio_sr_sel_e *)param = (audio_sr_sel_e)ret;
  731. ret = 0;
  732. break;
  733. }
  734. case AIN_CMD_SET_SAMPLERATE:
  735. {
  736. audio_sr_sel_e val = *(audio_sr_sel_e *)param;
  737. ret = i2srx_sample_rate_set(dev, val, data->mclksrc);
  738. if (ret) {
  739. LOG_ERR("Failed to set I2SRX sample rate err=%d", ret);
  740. return ret;
  741. }
  742. break;
  743. }
  744. case AIN_CMD_GET_APS:
  745. {
  746. ret = i2srx_get_pll_aps(dev);
  747. if (ret < 0) {
  748. LOG_ERR("Failed to get audio pll APS err=%d", ret);
  749. return ret;
  750. }
  751. *(audio_aps_level_e *)param = (audio_aps_level_e)ret;
  752. ret = 0;
  753. break;
  754. }
  755. case AIN_CMD_SET_APS:
  756. {
  757. audio_aps_level_e level = *(audio_aps_level_e *)param;
  758. ret = i2srx_set_pll_aps(dev, level);
  759. if (ret) {
  760. LOG_ERR("Failed to set audio pll APS err=%d", ret);
  761. return ret;
  762. }
  763. LOG_DBG("set new aps level %d", level);
  764. break;
  765. }
  766. case PHY_CMD_GET_AIN_DMA_INFO:
  767. {
  768. struct audio_out_dma_info *info = (struct audio_out_dma_info *)param;
  769. info->dma_info.dma_chan = cfg->dma_fifo0.dma_chan;
  770. info->dma_info.dma_dev_name = cfg->dma_fifo0.dma_dev_name;
  771. info->dma_info.dma_id = cfg->dma_fifo0.dma_id;
  772. break;
  773. }
  774. default:
  775. LOG_ERR("Unsupport command %d", cmd);
  776. return -ENOTSUP;
  777. }
  778. return ret;
  779. }
  780. const struct phy_audio_driver_api phy_i2srx_drv_api = {
  781. .audio_enable = phy_i2srx_enable,
  782. .audio_disable = phy_i2srx_disable,
  783. .audio_ioctl = phy_i2srx_ioctl,
  784. };
  785. /* dump i2srx device tree infomation */
  786. static void __i2srx_dt_dump_info(const struct phy_i2srx_config_data *cfg)
  787. {
  788. #if (PHY_DEV_SHOW_DT_INFO == 1)
  789. LOG_INF("** I2SRX BASIC INFO **");
  790. LOG_INF(" BASE: %08x", cfg->reg_base);
  791. LOG_INF(" CLK-ID: %08x", cfg->clk_id);
  792. LOG_INF("SRDCLK-ID: %08x", cfg->srd_clk_id);
  793. LOG_INF(" RST-ID: %08x", cfg->rst_id);
  794. LOG_INF("DMA0-NAME: %s", cfg->dma_fifo0.dma_dev_name);
  795. LOG_INF(" DMA0-ID: %08x", cfg->dma_fifo0.dma_id);
  796. LOG_INF(" DMA0-CH: %08x", cfg->dma_fifo0.dma_chan);
  797. LOG_INF("** I2SRX FEATURES **");
  798. LOG_INF(" SRD-EN: %d", PHY_DEV_FEATURE(srd_en));
  799. LOG_INF(" MODE: %d", PHY_DEV_FEATURE(mode));
  800. LOG_INF(" BCLK-WIDTH: %d", PHY_DEV_FEATURE(bclk_width));
  801. LOG_INF(" CH-NUM: %d", PHY_DEV_FEATURE(channel_num));
  802. LOG_INF(" EXTERNAL-CLK: %d", PHY_DEV_FEATURE(slave_internal_clk));
  803. LOG_INF(" LRCLK-PROC: %d", PHY_DEV_FEATURE(lrclk_proc));
  804. LOG_INF(" TDM-FORMAT: %d", PHY_DEV_FEATURE(tdm_format));
  805. LOG_INF(" TDM-FRAME: %d", PHY_DEV_FEATURE(tdm_frame));
  806. LOG_INF(" MCLK-REVERSE: %d", PHY_DEV_FEATURE(mclk_reverse));
  807. LOG_INF("CLK-FROM-I2STX: %d", PHY_DEV_FEATURE(clk_from_i2stx));
  808. #endif
  809. }
  810. static int phy_i2srx_init(const struct device *dev)
  811. {
  812. const struct phy_i2srx_config_data *cfg = dev->config;
  813. struct phy_i2srx_drv_data *data = dev->data;
  814. /* clear driver data */
  815. memset(data, 0, sizeof(struct phy_i2srx_drv_data));
  816. __i2srx_dt_dump_info(cfg);
  817. /* reset I2SRX controller */
  818. acts_reset_peripheral(cfg->rst_id);
  819. acts_reset_peripheral(RESET_ID_ADC);//REST ADC
  820. if (cfg->irq_config)
  821. cfg->irq_config();
  822. printk("I2SRX init successfully\n");
  823. return 0;
  824. }
  825. void phy_i2srx_isr(const void *arg)
  826. {
  827. struct device *dev = (struct device *)arg;
  828. struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
  829. struct phy_i2srx_drv_data *data = dev->data;
  830. LOG_DBG("srdstat: 0x%x", i2srx_reg->srdstat);
  831. /* Sample rate detection timeout irq pending */
  832. if (i2srx_reg->srdstat & I2SR0_SRDSTA_TO_PD) {
  833. i2srx_reg->srdstat |= I2SR0_SRDSTA_TO_PD;
  834. if (data->srd_callback)
  835. data->srd_callback(data->cb_data, I2SRX_SRD_TIMEOUT, NULL);
  836. }
  837. /* Sample rate changed detection irq pending */
  838. if (i2srx_reg->srdstat & I2SR0_SRDSTA_SRC_PD) {
  839. i2srx_reg->srdstat |= I2SR0_SRDSTA_SRC_PD;
  840. i2srx_srd_fs_change(dev);
  841. }
  842. /* Channel width change irq pending */
  843. if (i2srx_reg->srdstat & I2SR0_SRDSTA_CHW_PD) {
  844. i2srx_reg->srdstat |= I2SR0_SRDSTA_CHW_PD;
  845. i2srx_srd_wl_change(dev);
  846. }
  847. }
  848. static void phy_i2srx_irq_config(void);
  849. /* physical i2stx driver data */
  850. static struct phy_i2srx_drv_data phy_i2srx_drv_data0;
  851. /* physical i2stx config data */
  852. static const struct phy_i2srx_config_data phy_i2srx_config_data0 = {
  853. .reg_base = AUDIO_I2SRX0_REG_BASE,
  854. .clk_id = CLOCK_ID_I2SRX,
  855. .srd_clk_id = CLOCK_ID_I2SSRDCLK,
  856. .hclk_clk_id = CLOCK_ID_I2SHCLKEN,
  857. .rst_id = RESET_ID_I2SRX,
  858. AUDIO_DMA_FIFO_DEF(I2SRX, 0),
  859. .irq_config = phy_i2srx_irq_config,
  860. PHY_DEV_FEATURE_DEF(srd_en) = CONFIG_AUDIO_I2SRX_0_SRD_EN,
  861. PHY_DEV_FEATURE_DEF(mode) = CONFIG_AUDIO_I2SRX_0_MODE,
  862. PHY_DEV_FEATURE_DEF(bclk_width) = CONFIG_AUDIO_I2SRX_0_BCLK_WIDTH,
  863. PHY_DEV_FEATURE_DEF(channel_num) = CONFIG_AUDIO_I2SRX_0_CHANNEL_NUM,
  864. PHY_DEV_FEATURE_DEF(slave_internal_clk) = CONFIG_AUDIO_I2SRX_0_SLAVE_INTERNAL_CLK,
  865. PHY_DEV_FEATURE_DEF(lrclk_proc) = CONFIG_AUDIO_I2SRX_0_LRCLK_PROC,
  866. PHY_DEV_FEATURE_DEF(tdm_format) = CONFIG_AUDIO_I2SRX_0_TDM_FORMAT,
  867. PHY_DEV_FEATURE_DEF(tdm_frame) = CONFIG_AUDIO_I2SRX_0_TDM_FRAME,
  868. PHY_DEV_FEATURE_DEF(mclk_reverse) = CONFIG_AUDIO_I2SRX_0_MCLK_REVERSE,
  869. PHY_DEV_FEATURE_DEF(clk_from_i2stx) = CONFIG_AUDIO_I2SRX_0_CLK_FROM_I2STX,
  870. PHY_DEV_FEATURE_DEF(pcm_en) = CONFIG_AUDIO_PCMRX_0_EN,
  871. PHY_DEV_FEATURE_DEF(pcm_frame) = CONFIG_AUDIO_PCMRX_0_FORMART,
  872. PHY_DEV_FEATURE_DEF(pcm_slot) = CONFIG_AUDIO_PCMRX_0_SLOT,
  873. };
  874. #if IS_ENABLED(CONFIG_AUDIO_I2SRX_0)
  875. DEVICE_DEFINE(i2srx0, CONFIG_AUDIO_I2SRX_0_NAME, phy_i2srx_init, NULL,
  876. &phy_i2srx_drv_data0, &phy_i2srx_config_data0,
  877. POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS, &phy_i2srx_drv_api);
  878. #endif
  879. /*
  880. * @brief Enable I2SRX IRQ
  881. * @note I2STX IRQ source as shown below:
  882. * - I2STX FIFO Half Filled IRQ
  883. * - I2STX SRDTO IRQ
  884. * - I2STX SRDSR IRQ
  885. * - I2STX SRDCHW IRQ
  886. */
  887. static void phy_i2srx_irq_config(void)
  888. {
  889. IRQ_CONNECT(IRQ_ID_I2S1, CONFIG_AUDIO_I2SRX_0_IRQ_PRI,
  890. phy_i2srx_isr,
  891. DEVICE_GET(i2srx0), 0);
  892. irq_enable(IRQ_ID_I2S1);
  893. }