phy_audio_spdifrx.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. /*
  2. * Copyright (c) 2020 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief Audio SPDIFTX physical implementation
  9. */
  10. /*
  11. * Features
  12. * - 32 level * 24bits FIFO
  13. * - Support HDMI ARC
  14. * - Support Sample Rate Change & Timeout Detect
  15. * - Sample rate support up to 96KHz
  16. */
  17. #include <kernel.h>
  18. #include <device.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. #include <soc.h>
  22. #include <board.h>
  23. #include <board_cfg.h>
  24. #include "../phy_audio_common.h"
  25. #include "../audio_acts_utils.h"
  26. #include <drivers/audio/audio_in.h>
  27. #include <logging/log.h>
  28. LOG_MODULE_REGISTER(spdifrx0, CONFIG_LOG_DEFAULT_LEVEL);
  29. /***************************************************************************************************
  30. * SPDIFRX_CTL0
  31. */
  32. #define SPDIFR0_CTL0_ANA_RES BIT(29) /* Enable or disable internal 2k ohm registor */
  33. #define SPDIFR0_CTL0_ANA_HYSVOL BIT(28) /* Analog pin Hysteresis Voltage select 0: 110mv 1: 220mv */
  34. #define SPDIFR0_CTL0_FCS BIT(16) /* Filter Pulse Cycle Select */
  35. #define SPDIFR0_CTL0_LOOPBACK_EN BIT(15) /* Enable internal loopback */
  36. #define SPDIFR0_CTL0_VBM BIT(14) /* Validity bit */
  37. #define SPDIFR0_CTL0_DAMS BIT(13) /* Data mask state. If sample rate changed, data will be keep as 0 and set this bit*/
  38. #define SPDIFR0_CTL0_DAMEN BIT(12) /* If sample rate changed, the data mask enable flag*/
  39. #define SPDIFR0_CTL0_DELTAADD_SHIFT (8) /* Delta to add on configured or detected T width */
  40. #define SPDIFR0_CTL0_DELTAADD_MASK (0xF << SPDIFR0_CTL0_DELTAADD_SHIFT)
  41. #define SPDIFR0_CTL0_DELTAADD(x) ((x) << SPDIFR0_CTL0_DELTAADD_SHIFT)
  42. #define SPDIFR0_CTL0_DELTAMIN_SHIFT (4) /* Delta to minus from configured or detected T width */
  43. #define SPDIFR0_CTL0_DELTAMIN_MASK (0xF << SPDIFR0_CTL0_DELTAMIN_SHIFT)
  44. #define SPDIFR0_CTL0_DELTAMIN(x) ((x) << SPDIFR0_CTL0_DELTAMIN_SHIFT)
  45. #define SPDIFR0_CTL0_DELTA_MODE BIT(3) /* T Width delta mode select */
  46. #define SPDIFR0_CTL0_CAL_MODE BIT(2) /* T Width cal mode select */
  47. #define SPDIFR0_CTL0_SPDIF_CKEDG BIT(1) /* Select of SPDIF input signal latch clock edge */
  48. #define SPDIFR0_CTL0_SPDIF_RXEN BIT(0) /* SPDIF RX Enable */
  49. /***************************************************************************************************
  50. * SPDIFRX_CTL1
  51. */
  52. #define SPDIFR0_CTL1_WID2TCFG_SHIFT (16) /* 2T Width Config MAX:512 */
  53. #define SPDIFR0_CTL1_WID2TCFG_MASK (0x1FF << SPDIFR0_CTL1_WID2TCFG_SHIFT)
  54. #define SPDIFR0_CTL1_WID1P5TCFG_SHIFT (8) /* 1.5T Width Config MAX:156*/
  55. #define SPDIFR0_CTL1_WID1P5TCFG_MASK (0xFF << SPDIFR0_CTL1_WID1P5TCFG_SHIFT)
  56. #define SPDIFR0_CTL1_WID1TCFG_SHIFT (0) /* 1T Width Config MAX:156*/
  57. #define SPDIFR0_CTL1_WID1TCFG_MASK (0xFF << SPDIFR0_CTL1_WID1TCFG_SHIFT)
  58. /***************************************************************************************************
  59. * SPDIFRX_CTL2
  60. */
  61. #define SPDIFR0_CTL2_WID4TCFG_SHIFT (18) /* 4T Width Config MAX:1024 */
  62. #define SPDIFR0_CTL2_WID4TCFG_MASK (0x3FF << SPDIFR0_CTL2_WID4TCFG_SHIFT)
  63. #define SPDIFR0_CTL2_WID3TCFG_SHIFT (9) /* 3T Width Config MAX:512 */
  64. #define SPDIFR0_CTL2_WID3TCFG_MASK (0x1FF << SPDIFR0_CTL2_WID3TCFG_SHIFT)
  65. #define SPDIFR0_CTL2_WID2P5TCFG_SHIFT (0) /* 2.5T Width Config MAX:512 */
  66. #define SPDIFR0_CTL2_WID2P5TCFG_MASK (0x1FF << SPDIFR0_CTL2_WID2P5TCFG_SHIFT)
  67. /***************************************************************************************************
  68. * SPDIFRX_PD
  69. */
  70. #define SPDIFR0_PD_SRCIRQDELAY BIT(17) /* SPDIF RX sample rate change IRQ occur timing. 0: right now; 1: after new block head has been detected */
  71. #define SPDIFR0_PD_BL_HEADPD BIT(16) /* Block head detect pending */
  72. #define SPDIFR0_PD_SRTOPD BIT(14) /* Sample rate detect timeout interrupt pending */
  73. #define SPDIFR0_PD_CSSRUPPD BIT(13) /* Channel state sample rate change IRQ pending */
  74. #define SPDIFR0_PD_CSUPPD BIT(12) /* Channel state update irq pending */
  75. #define SPDIFR0_PD_SRCPD BIT(11) /* Sample rate change pending */
  76. #define SPDIFR0_PD_BMCERPD BIT(10) /* BMC Decoder Err pending */
  77. #define SPDIFR0_PD_SUBRCVPD BIT(9) /* Sub Frame Receive Err pending */
  78. #define SPDIFR0_PD_BLKRCVPD BIT(8) /* Block received Err pending */
  79. #define SPDIFR0_PD_SRTOEN BIT(6) /* sample rate detect timeout IRQ enable */
  80. #define SPDIFR0_PD_CSSRCIRQEN BIT(5) /* channel state sample rate change irq enable */
  81. #define SPDIFR0_PD_CSUPIRQEN BIT(4) /* channel state update irq enable */
  82. #define SPDIFR0_PD_SRCIRQEN BIT(3) /* SPDIF RX sample rate change IRQ enable */
  83. #define SPDIFR0_PD_BMCIRQEN BIT(2) /* BMC Decoder Err IRQ enable */
  84. #define SPDIFR0_PD_SUBIRQEN BIT(1) /* Sub Frame receive Err IRQ enable */
  85. #define SPDIFR0_PD_BLKIRQEN BIT(0) /* Block Receive Err IRQ enable */
  86. /***************************************************************************************************
  87. * SPDIFRX_DBG
  88. */
  89. #define SPDIFR0_DBG_DBGSEL_SHIFT (17)
  90. #define SPDIFR0_DBG_DBGSEL_MASK (0xF << SPDIFR0_DBG_DBGSEL_SHIFT)
  91. #define SPDIFR0_DBG_SUBRCVFSM_SHIFT (14)
  92. #define SPDIFR0_DBG_SUBRCVFSM_MASK (0x7 << SPDIFR0_DBG_SUBRCVFSM_SHIFT)
  93. #define SPDIFR0_DBG_BMCRCVFSM_SHIFT (6)
  94. #define SPDIFR0_DBG_BMCRCVFSM_MASK (0xFF << SPDIFR0_DBG_BMCRCVFSM_SHIFT)
  95. #define SPDIFR0_DBG_BMCDECFSM_SHIFT (3)
  96. #define SPDIFR0_DBG_BMCDECFSM_MASK (0x7 << SPDIFR0_DBG_BMCDECFSM_SHIFT)
  97. #define SPDIFR0_DBG_HW_FSM_SHIFT (0)
  98. #define SPDIFR0_DBG_HW_FSM_MASK (0x7 << SPDIFR0_DBG_HW_FSM_SHIFT)
  99. /***************************************************************************************************
  100. * SPDIFRX_CNT
  101. */
  102. #define SPDIFR0_CNT_DIN2_WIDTH_SHIFT (24) /* Din2 Width */
  103. #define SPDIFR0_CNT_DIN2_WIDTH_MASK (0xFF << SPDIFR0_CNT_DIN1_WIDTH_SHIFT)
  104. #define SPDIFR0_CNT_DIN1_WIDTH_SHIFT (16) /* Din1 Width */
  105. #define SPDIFR0_CNT_DIN1_WIDTH_MASK (0xFF << SPDIFR0_CNT_DIN1_WIDTH_SHIFT)
  106. #define SPDIFR0_CNT_DIN0_WIDTH_SHIFT (8) /* Din0 Width */
  107. #define SPDIFR0_CNT_DIN0_WIDTH_MASK (0xFF << SPDIFR0_CNT_DIN0_WIDTH_SHIFT)
  108. #define SPDIFR0_CNT_FRAMECNT_SHIFT (0) /* Audio Frame Counter */
  109. #define SPDIFR0_CNT_FRAMECNT_MASK (0xFF << SPDIFR0_CNT_FRAMECNT_SHIFT)
  110. /***************************************************************************************************
  111. * SPDIFRX_CSL
  112. */
  113. #define SPDIFR0_CSL_SPDCSL_E (31) /* SPDIFRX Channel State Low */
  114. #define SPDIFR0_CSL_SPDCSL_SHIFT (0)
  115. #define SPDIFR0_CSL_SPDCSL_MASK (0xFFFFFFFF << SPDIFR0_CSL_SPDCSL_SHIFT)
  116. /***************************************************************************************************
  117. * SPDIFRX_CSH
  118. */
  119. #define SPDIFR0_CSH_SPDCSH_SHIFT (0) /* SPDIFRX Channel State High */
  120. #define SPDIFR0_CSH_SPDCSH_MASK (0xFFFF << SPDIFR0_CSH_SPDCSH_SHIFT)
  121. /***************************************************************************************************
  122. * SPDIFRX_SAMP - Sample Rate Detect Register
  123. */
  124. #define SPDIFR0_SAMP_SAMP_VALID BIT(28) /* sample rate valid flag */
  125. #define SPDIFR0_SAMP_SAMP_CNT_SHIFT (16) /* SPDIFRX sample rate counter detect by 24M clock */
  126. #define SPDIFR0_SAMP_SAMP_CNT_MASK (0xFFF << SPDIFR0_SAMP_SAMP_CNT_SHIFT)
  127. #define SPDIFR0_SAMP_SAMP_CNT(x) (((x) & SPDIFR0_SAMP_SAMP_CNT_MASK) >> SPDIFR0_SAMP_SAMP_CNT_SHIFT)
  128. #define SPDIFR0_SAMP_SAMP_DELTA_SHIFT (1) /* Delta is used by SAMP_CNT to detect sample rate change or not */
  129. #define SPDIFR0_SAMP_SAMP_DELTA_MASK (0xF << SPDIFR0_SAMP_SAMP_DELTA_SHIFT)
  130. #define SPDIFR0_SAMP_SAMP_DELTA(x) ((x) << SPDIFR0_SAMP_SAMP_DELTA_SHIFT)
  131. #define SPDIFR0_SAMP_SAMP_EN BIT(0) /* Sample rate detect enable */
  132. /***************************************************************************************************
  133. * SPDIFRX_SRTO_THRES
  134. */
  135. #define SPDIFR0_SRTO_THRES_SRTO_THRES_SHIFT (0) /* The threshold to generate sample rate detect timeout signal */
  136. #define SPDIFR0_SRTO_THRES_SRTO_THRES_MASK (0xFFFFFF << 0)
  137. /***************************************************************************************************
  138. * SPDIFRX_FIFOCTL
  139. */
  140. #define SPDIFR0_FIFOCTL_FIFO_DMAWIDTH BIT(7) /* FIFO DMA transfer width configured */
  141. #define SPDIFR0_FIFOCTL_FIFO_OS_SHIFT (4) /* FIFO output select */
  142. #define SPDIFR0_FIFOCTL_FIFO_OS_MASK (0x3 << SPDIFR0_FIFOCTL_FIFO_OS_SHIFT)
  143. #define SPDIFR0_FIFOCTL_FIFO_OS(x) ((x) << SPDIFR0_FIFOCTL_FIFO_OS_SHIFT)
  144. #define SPDIFR0_FIFOCTL_FIFO_OS_CPU SPDIFR0_FIFOCTL_FIFO_OS(0)
  145. #define SPDIFR0_FIFOCTL_FIFO_OS_DMA SPDIFR0_FIFOCTL_FIFO_OS(1)
  146. #define SPDIFR0_FIFOCTL_FIFO_IEN BIT(2) /* FIFO Half filled IRQ enable */
  147. #define SPDIFR0_FIFOCTL_FIFO_DEN BIT(1) /* FIFO Half filled DRQ enable */
  148. #define SPDIFR0_FIFOCTL_FIFO_RST BIT(0) /* FIFO reset */
  149. /***************************************************************************************************
  150. * SPDIFRX_FIFOSTA
  151. */
  152. #define SPDIFR0_FIFOSTA_FIFO_ER BIT(8) /* FIFO error */
  153. #define SPDIFR0_FIFOSTA_FIFO_EMPTY BIT(7) /* FIFO empty flag */
  154. #define SPDIFR0_FIFOSTA_FIFO_IP BIT(6) /* FIFO Half Filled IRQ pending bit */
  155. #define SPDIFR0_FIFOSTA_FIFO_STATUS_SHIFT (0) /* FIFO status */
  156. #define SPDIFR0_FIFOSTA_FIFO_STATUS_MASK (0x3F << SPDIFR0_FIFOSTA_FIFO_STATUS_SHIFT)
  157. /***************************************************************************************************
  158. * SPDIFRX_DAT_FIFO
  159. */
  160. #define SPDIFR0_DAT_FIFO_RXDAT_SHIFT (8) /* SPDIFRX Data */
  161. #define SPDIFR0_DAT_FIFO_RXDAT_MASK (0xFFFFFF << SPDIFR0_DAT_FIFO_RXDAT_SHIFT)
  162. #define SPDIF_RX_INIT_DELTA (4)
  163. #define SPDIF_RX_DEFAULT_SAMPLE_DELTA (8)
  164. #define SPDIF_RX_HIGH_SR_SAMPLE_DELTA (3)
  165. #define SPDIF_RX_SR_DETECT_MS (1)
  166. #define SPDIF_RX_SRD_TIMEOUT_THRES (0xFFFFFF)
  167. /*
  168. * enum a_spdifrx_srd_sts_e
  169. * @brief The SPDIFRX sample rate detect status
  170. */
  171. typedef enum {
  172. RX_SR_STATUS_NOTGET = 0, /* Still not get the sample rate */
  173. RX_SR_STATUS_CHANGE, /* sample rate detect change happened */
  174. RX_SR_STATUS_GET, /* has gotten the sample rate */
  175. } a_spdifrx_srd_sts_e;
  176. /**
  177. * struct phy_spdifrx_drv_data
  178. * @brief The software related data that used by physical spdifrx driver.
  179. */
  180. struct phy_spdifrx_drv_data {
  181. int (*srd_callback)(void *cb_data, uint32_t cmd, void *param); /* sample rate detect callback */
  182. void *cb_data; /* callback user data */
  183. a_spdifrx_srd_sts_e srd_status; /* sample rate detect status */
  184. uint8_t sample_rate; /* channel sample rate */
  185. };
  186. /**
  187. * struct phy_spdifrx_config_data
  188. * @brief The hardware related data that used by physical spdifrx driver.
  189. */
  190. struct phy_spdifrx_config_data {
  191. uint32_t reg_base; /* SPDIFRX controller register base address */
  192. struct audio_dma_dt dma_fifo0; /* DMA resource for SPDIFRX */
  193. uint32_t min_corepll_clock; /* min_corepll_clock >= 8 x 128 x sr */
  194. void (*irq_config)(void); /* IRQ configuration function */
  195. uint8_t clk_id; /* SPDIFRX devclk id */
  196. uint8_t rst_id; /* SPDIFRX reset id */
  197. };
  198. /*
  199. * @struct acts_audio_spdifrx
  200. * @brief SPDIFRX controller hardware register
  201. */
  202. struct acts_audio_spdifrx {
  203. volatile uint32_t ctl0; /* SPDIFRX Control0 */
  204. volatile uint32_t ctl1; /* SPDIFRX Control1 */
  205. volatile uint32_t ctl2; /* SPDIFRX Control2 */
  206. volatile uint32_t pending; /* SPDIFRX IRQ pending */
  207. volatile uint32_t dbg; /* SPDIFRX debug */
  208. volatile uint32_t cnt; /* SPDIFRX counter */
  209. volatile uint32_t csl; /* SPDIFRX Channel State Low */
  210. volatile uint32_t csh; /* SPDIFRX Channel State High */
  211. volatile uint32_t samp; /* SPDIFRX sample rate detect */
  212. volatile uint32_t thres; /* SPDIFRX sample rate detect timeout threshold */
  213. volatile uint32_t fifoctl; /* SPDIFRX FIFO control */
  214. volatile uint32_t fifostat; /* SPDIFRX FIFO state */
  215. volatile uint32_t fifodat; /* SPDIFRX FIFO data */
  216. };
  217. /* @brief get the base address of SPDIFRX register */
  218. static inline struct acts_audio_spdifrx *get_spdifrx_reg_base(struct device *dev)
  219. {
  220. const struct phy_spdifrx_config_data *cfg = dev->config;
  221. return (struct acts_audio_spdifrx *)cfg->reg_base;
  222. }
  223. /* @brief dump spdifrx controller register */
  224. static void spdifrx_dump_register(struct device *dev)
  225. {
  226. struct acts_audio_spdifrx *spdifrx_base = get_spdifrx_reg_base(dev);
  227. LOG_INF("** spdifrx contoller regster **");
  228. LOG_INF(" BASE: %08x", (uint32_t)spdifrx_base);
  229. LOG_INF(" SPDIFRX_CTL0: %08x", spdifrx_base->ctl0);
  230. LOG_INF(" SPDIFRX_CTL1: %08x", spdifrx_base->ctl1);
  231. LOG_INF(" SPDIFRX_CTL2: %08x", spdifrx_base->ctl2);
  232. LOG_INF(" SPDIFRX_PD: %08x", spdifrx_base->pending);
  233. LOG_INF(" SPDIFRX_DBG: %08x", spdifrx_base->dbg);
  234. LOG_INF(" SPDIFRX_CNT: %08x", spdifrx_base->cnt);
  235. LOG_INF(" SPDIFRX_CSL: %08x", spdifrx_base->csl);
  236. LOG_INF(" SPDIFRX_CSH: %08x", spdifrx_base->csh);
  237. LOG_INF(" SPDIFRX_SAMP: %08x", spdifrx_base->samp);
  238. LOG_INF(" SPDIFRX_STRO_THRES: %08x", spdifrx_base->thres);
  239. LOG_INF(" SPDIFRX_FIFOCTL: %08x", spdifrx_base->fifoctl);
  240. LOG_INF(" SPDIFRX_FIFOSTA: %08x", spdifrx_base->fifostat);
  241. LOG_INF(" SPDIFRX_DAT_FIFO: %08x", spdifrx_base->fifodat);
  242. LOG_INF(" CMU_SPDIFRXCLK: %08x", sys_read32(CMU_SPDIFRXCLK));
  243. LOG_INF(" CORE_PLL_CTL: %08x", sys_read32(COREPLL_CTL));
  244. }
  245. /* @brief Prepare the clock and pinmux resources for the SPDIFRX enable */
  246. static int phy_spdifrx_prepare_enable(struct device *dev, uint8_t sr)
  247. {
  248. const struct phy_spdifrx_config_data *cfg = dev->config;
  249. uint32_t core_pll;
  250. struct board_pinmux_info pinmux_info;
  251. board_get_spdiftx0_pinmux_info(&pinmux_info);
  252. /* Config the spdifrx pin state */
  253. acts_pinmux_setup_pins(pinmux_info.pins_config, pinmux_info.pins_num);
  254. /* SPDIFRX RMU normal */
  255. acts_reset_peripheral(cfg->rst_id);
  256. /* clear SPDIFRX clock */
  257. sys_write32((sys_read32(CMU_SPDIFRXCLK) & ~(CMU_SPDIFRXCLK_SPDIFRXCLKSRC_MASK
  258. | CMU_SPDIFRXCLK_SPDIFRXCLKDIV_MASK)), CMU_SPDIFRXCLK);
  259. /* Select SPDIFRX clock source to be corepll */
  260. sys_write32((sys_read32(CMU_SPDIFRXCLK) | CMU_SPDIFRXCLK_SPDIFRXCLKSRC(2)), CMU_SPDIFRXCLK);
  261. if (sr <= SAMPLE_RATE_16KHZ) {
  262. uint8_t pll_index, seires;
  263. if (SAMPLE_RATE_11KHZ == sr) {
  264. seires = AUDIOPLL_44KSR;
  265. } else {
  266. seires = AUDIOPLL_48KSR;
  267. }
  268. if (audio_pll_check_config(seires, &pll_index)) {
  269. LOG_ERR("pll check and config error");
  270. return -EFAULT;
  271. }
  272. sys_write32((sys_read32(CMU_SPDIFRXCLK) & (~0x3FF))
  273. | ((pll_index << 8) | (3 << 0)), CMU_SPDIFRXCLK);
  274. } else {
  275. core_pll = clk_rate_get_corepll();
  276. if (core_pll < cfg->min_corepll_clock) {
  277. LOG_ERR("too low frequency corepll:%d mininum:%d", core_pll, cfg->min_corepll_clock);
  278. return -EACCES;
  279. }
  280. }
  281. /* this will also enable the HOSC clock to detect Audio Sample Rate */
  282. acts_clock_peripheral_enable(cfg->clk_id);
  283. return 0;
  284. }
  285. /* @brief Config the SPDIFRX FIFO source */
  286. static int phy_spdifrx_fifo_config(struct device *dev, audio_fifouse_sel_e sel, audio_dma_width_e width)
  287. {
  288. struct acts_audio_spdifrx *spdifrx_base = get_spdifrx_reg_base(dev);
  289. if (FIFO_SEL_CPU == sel) {
  290. spdifrx_base->fifoctl = (SPDIFR0_FIFOCTL_FIFO_IEN | SPDIFR0_FIFOCTL_FIFO_RST);
  291. } else if (FIFO_SEL_DMA == sel) {
  292. spdifrx_base->fifoctl = (SPDIFR0_FIFOCTL_FIFO_OS_DMA | SPDIFR0_FIFOCTL_FIFO_DEN
  293. | SPDIFR0_FIFOCTL_FIFO_RST);
  294. if (DMA_WIDTH_16BITS == width)
  295. spdifrx_base->fifoctl |= SPDIFR0_FIFOCTL_FIFO_DMAWIDTH;
  296. } else {
  297. LOG_ERR("invalid fifo sel %d", sel);
  298. return -EINVAL;
  299. }
  300. return 0;
  301. }
  302. /* @brief SPDIF control and config */
  303. static void phy_spdifrx_ctl_config(struct device *dev)
  304. {
  305. struct acts_audio_spdifrx *spdifrx_base = get_spdifrx_reg_base(dev);
  306. spdifrx_base->ctl0 = 0;
  307. /* Enable hardware detect T Width */
  308. spdifrx_base->ctl0 |= SPDIFR0_CTL0_CAL_MODE;
  309. /* Enable hardware automatically fill DELTAADD and DELTAMIN T Width */
  310. spdifrx_base->ctl0 |= SPDIFR0_CTL0_DELTA_MODE;
  311. /* Delta to minus from configured or detected T width */
  312. spdifrx_base->ctl0 |= SPDIFR0_CTL0_DELTAMIN(SPDIF_RX_INIT_DELTA);
  313. /* Delta to add on configured or detected T width */
  314. spdifrx_base->ctl0 |= SPDIFR0_CTL0_DELTAADD(SPDIF_RX_INIT_DELTA);
  315. /* DAMEN */
  316. spdifrx_base->ctl0 |= SPDIFR0_CTL0_DAMEN;
  317. /* spdif rx enable */
  318. spdifrx_base->ctl0 |= SPDIFR0_CTL0_SPDIF_RXEN;
  319. /* sample rate detect enable */
  320. spdifrx_base->samp &= (~SPDIFR0_SAMP_SAMP_DELTA_MASK);
  321. spdifrx_base->samp |= SPDIFR0_SAMP_SAMP_DELTA(SPDIF_RX_DEFAULT_SAMPLE_DELTA);
  322. spdifrx_base->samp |= SPDIFR0_SAMP_SAMP_EN;
  323. }
  324. /* @brief Get the SPDIFRX channel status */
  325. static void phy_spdifrx_channel_status_get(struct device *dev, audio_spdif_ch_status_t *sts)
  326. {
  327. struct acts_audio_spdifrx *spdifrx_base = get_spdifrx_reg_base(dev);
  328. if (sts) {
  329. sts->csl = spdifrx_base->csl;
  330. sts->csh = (uint16_t)spdifrx_base->csh;
  331. }
  332. }
  333. /* @brief Check if the stream is the PCM format stream */
  334. static bool phy_spdifrx_check_is_pcm(struct device *dev)
  335. {
  336. struct acts_audio_spdifrx *spdifrx_base = get_spdifrx_reg_base(dev);
  337. /* The channel status bit1 indicats the stream is a linear PCM samples */
  338. if (spdifrx_base->csl & (1 << 1))
  339. return false;
  340. return true;
  341. }
  342. /* @brief Check if decode error happened */
  343. static bool phy_spdifrx_check_decode_err(struct device *dev)
  344. {
  345. struct acts_audio_spdifrx *spdifrx_base = get_spdifrx_reg_base(dev);
  346. bool ret = false;
  347. if (spdifrx_base->pending & SPDIFR0_PD_BLKRCVPD) {
  348. spdifrx_base->pending |= SPDIFR0_PD_BLKRCVPD;
  349. ret = true;
  350. }
  351. if (spdifrx_base->pending & SPDIFR0_PD_SUBRCVPD) {
  352. spdifrx_base->pending |= SPDIFR0_PD_SUBRCVPD;
  353. ret = true;
  354. }
  355. if (spdifrx_base->pending & SPDIFR0_PD_BMCERPD) {
  356. spdifrx_base->pending |= SPDIFR0_PD_BMCERPD;
  357. ret = true;
  358. }
  359. return ret;
  360. }
  361. /* @brief Enable spdifrx irq events */
  362. static void phy_spdifrx_irq_en(struct device *dev)
  363. {
  364. struct acts_audio_spdifrx *spdifrx_base = get_spdifrx_reg_base(dev);
  365. spdifrx_base->thres = SPDIF_RX_SRD_TIMEOUT_THRES;
  366. /* SPDIF RX sample rate change IRQ happened when new block head has been detected */
  367. spdifrx_base->pending |= SPDIFR0_PD_SRCIRQDELAY;
  368. /* SPDIFRX sample rate detect IRQ enable */
  369. spdifrx_base->pending |= (SPDIFR0_PD_SRCIRQEN | SPDIFR0_PD_SRTOEN);
  370. /* clear all IRQ pendings */
  371. spdifrx_base->pending |= (SPDIFR0_PD_BLKRCVPD | SPDIFR0_PD_SUBRCVPD
  372. | SPDIFR0_PD_BMCERPD | SPDIFR0_PD_SRCPD
  373. | SPDIFR0_PD_CSUPPD | SPDIFR0_PD_CSSRUPPD
  374. | SPDIFR0_PD_SRTOPD | SPDIFR0_PD_BL_HEADPD);
  375. }
  376. static int phy_spdifrx_enable(struct device *dev, void *param)
  377. {
  378. struct phy_spdifrx_drv_data *data = dev->data;
  379. ain_param_t *in_param = (ain_param_t *)param;
  380. spdifrx_setting_t *spdifrx_setting = in_param->spdifrx_setting;
  381. int ret;
  382. uint8_t width;
  383. if (!in_param) {
  384. LOG_ERR("Invalid parameters");
  385. return -EINVAL;
  386. }
  387. if (in_param->sample_rate)
  388. data->sample_rate = in_param->sample_rate;
  389. if (spdifrx_setting && spdifrx_setting->srd_callback) {
  390. data->srd_callback = spdifrx_setting->srd_callback;
  391. data->cb_data = spdifrx_setting->cb_data;
  392. } else {
  393. data->srd_callback = NULL;
  394. data->cb_data = NULL;
  395. }
  396. /* Prepare the spdifrx clock and pinmux etc. */
  397. ret = phy_spdifrx_prepare_enable(dev, data->sample_rate);
  398. if (ret)
  399. return ret;
  400. /* Config the SPDIFRX FIFO */
  401. width = (in_param->channel_width == CHANNEL_WIDTH_16BITS)
  402. ? DMA_WIDTH_16BITS : DMA_WIDTH_32BITS;
  403. ret = phy_spdifrx_fifo_config(dev, FIFO_SEL_DMA, width);
  404. if (ret) {
  405. LOG_ERR("Config SPDIFRX FIFO error %d", ret);
  406. return ret;
  407. }
  408. /* Control spdifrx and enable sample rate detect function */
  409. phy_spdifrx_ctl_config(dev);
  410. /* Enable SPDIFRX IRQs */
  411. phy_spdifrx_irq_en(dev);
  412. return 0;
  413. }
  414. static int phy_spdifrx_disable(struct device *dev, void *param)
  415. {
  416. const struct phy_spdifrx_config_data *cfg = dev->config;
  417. struct acts_audio_spdifrx *spdifrx_base = get_spdifrx_reg_base(dev);
  418. struct phy_spdifrx_drv_data *data = dev->data;
  419. uint8_t i;
  420. struct board_pinmux_info pinmux_info;
  421. board_get_spdiftx0_pinmux_info(&pinmux_info);
  422. /* Set the spdiftx pins to be GPIO state for the power consume */
  423. for (i = 0; i < pinmux_info.pins_num; i++)
  424. acts_pinmux_set(pinmux_info.pins_config[i].pin_num, 0);
  425. /* SPDIFRX FIFO reset */
  426. spdifrx_base->fifoctl &= ~SPDIFR0_FIFOCTL_FIFO_RST;
  427. /* SPDIF RX disable */
  428. spdifrx_base->ctl0 &= ~SPDIFR0_CTL0_SPDIF_RXEN;
  429. /* Disable sample rate change IRQ */
  430. spdifrx_base->pending &= ~(SPDIFR0_PD_SRCIRQEN | SPDIFR0_PD_SRTOEN);
  431. /* SPDIF RX clock gating disable */
  432. acts_clock_peripheral_disable(cfg->clk_id);
  433. data->srd_callback = NULL;
  434. data->cb_data = NULL;
  435. data->sample_rate = 0;
  436. return 0;
  437. }
  438. int phy_spdifrx_samplerate_detect(struct device *dev, int wait_time_ms)
  439. {
  440. struct acts_audio_spdifrx *spdifrx_base = get_spdifrx_reg_base(dev);
  441. struct phy_spdifrx_drv_data *data = dev->data;
  442. uint32_t time_stamp_begin, time_stamp_delta;
  443. int result = -1;
  444. uint8_t index;
  445. uint32_t sample_cnt;
  446. static const uint16_t sample_cnt_tbl[14][2] = {
  447. {120, 130}, // 192k, 24M/192K = 125
  448. {131, 141}, // 176.4k, 24M/176K = 136
  449. {245, 255}, // 96k, 24M/96K = 250
  450. {267, 277}, // 88.2k, 24M/88K = 272
  451. {369, 381}, // 64k, 24M/64K = 375
  452. {489, 510}, // 48k, 24M/48K = 500
  453. {532, 726}, // 44.1k, 24M/44K = 544
  454. {727, 774}, // 32k, 24M/32K = 750
  455. {960, 1043}, // 24k, 24M/24K = 1000
  456. {1041,1140}, // 22.05k, 24M/22.05K = 1088
  457. {1411, 1600}, // 16k, 24M/16K = 1500
  458. {1846, 2170}, // 12k, 24M/12K = 2000
  459. {2171, 2394}, // 11.025k, 24M/11.025K = 2176
  460. {2666, 3428}, // 8k, 24M/8K = 3000
  461. };
  462. const uint8_t sample_rate_tbl[] = {
  463. SAMPLE_RATE_192KHZ, SAMPLE_RATE_176KHZ, SAMPLE_RATE_96KHZ, SAMPLE_RATE_88KHZ,
  464. SAMPLE_RATE_64KHZ, SAMPLE_RATE_48KHZ, SAMPLE_RATE_44KHZ, SAMPLE_RATE_32KHZ,
  465. SAMPLE_RATE_24KHZ, SAMPLE_RATE_22KHZ, SAMPLE_RATE_16KHZ, SAMPLE_RATE_12KHZ,
  466. SAMPLE_RATE_11KHZ, SAMPLE_RATE_8KHZ
  467. };
  468. if(data->srd_status >= RX_SR_STATUS_GET) {
  469. LOG_INF("Already got sample rate %d", data->sample_rate);
  470. return 0;
  471. }
  472. if (wait_time_ms != -1)
  473. time_stamp_begin = k_cycle_get_32();
  474. do {
  475. /* get the sample rate detect counter */
  476. sample_cnt = SPDIFR0_SAMP_SAMP_CNT(spdifrx_base->samp);
  477. if (wait_time_ms != -1) {
  478. time_stamp_delta = k_cyc_to_ns_floor64(k_cycle_get_32() - time_stamp_begin);
  479. time_stamp_delta /= 1000000;
  480. if(time_stamp_delta > wait_time_ms) {
  481. LOG_INF("timeout samp:%d\n", sample_cnt);
  482. result = -ETIMEDOUT;
  483. break;
  484. }
  485. }
  486. /* check sample valid */
  487. if ((spdifrx_base->samp & SPDIFR0_SAMP_SAMP_VALID) == 0) {
  488. /* Occur when BMC_ERR or SAMP_CNT overflow */
  489. LOG_DBG("sample rate invalid");
  490. } else {
  491. /* sample rate valid */
  492. for(index = 0; index < sizeof(sample_rate_tbl); index++) {
  493. if((sample_cnt >= sample_cnt_tbl[index][0]) && (sample_cnt <= sample_cnt_tbl[index][1])) {
  494. data->sample_rate = sample_rate_tbl[index];
  495. result = 0;
  496. break;
  497. }
  498. }
  499. if (result == 0) {
  500. LOG_INF("NEW SAMPLE RATE => %d!\n", data->sample_rate);
  501. break;
  502. }
  503. }
  504. }while(1);
  505. return result;
  506. }
  507. static int phy_spdifrx_ioctl(struct device *dev, uint32_t cmd, void *param)
  508. {
  509. const struct phy_spdifrx_config_data *cfg = dev->config;
  510. switch (cmd) {
  511. case PHY_CMD_DUMP_REGS:
  512. {
  513. spdifrx_dump_register(dev);
  514. break;
  515. }
  516. case AIN_CMD_SPDIF_GET_CHANNEL_STATUS:
  517. {
  518. audio_spdif_ch_status_t *sts = (audio_spdif_ch_status_t *)param;
  519. if (!sts) {
  520. LOG_ERR("Invalid parameters");
  521. return -EINVAL;
  522. }
  523. phy_spdifrx_channel_status_get(dev, sts);
  524. break;
  525. }
  526. case AIN_CMD_SPDIF_IS_PCM_STREAM:
  527. {
  528. if (phy_spdifrx_check_is_pcm(dev))
  529. *(bool *)param = true;
  530. else
  531. *(bool *)param = false;
  532. break;
  533. }
  534. case AIN_CMD_SPDIF_CHECK_DECODE_ERR:
  535. {
  536. if (phy_spdifrx_check_decode_err(dev))
  537. *(bool *)param = true;
  538. else
  539. *(bool *)param = false;
  540. break;
  541. }
  542. case PHY_CMD_GET_AIN_DMA_INFO:
  543. {
  544. struct audio_out_dma_info *info = (struct audio_out_dma_info *)param;
  545. info->dma_info.dma_chan = cfg->dma_fifo0.dma_chan;
  546. info->dma_info.dma_dev_name = cfg->dma_fifo0.dma_dev_name;
  547. info->dma_info.dma_id = cfg->dma_fifo0.dma_id;
  548. break;
  549. }
  550. default:
  551. LOG_ERR("Unsupport command %d", cmd);
  552. return -ENOTSUP;
  553. }
  554. return 0;
  555. }
  556. const struct phy_audio_driver_api phy_spdifrx_drv_api = {
  557. .audio_enable = phy_spdifrx_enable,
  558. .audio_disable = phy_spdifrx_disable,
  559. .audio_ioctl = phy_spdifrx_ioctl,
  560. };
  561. /* dump spdifrx device tree infomation */
  562. static void __spdifrx_dt_dump_info(const struct phy_spdifrx_config_data *cfg)
  563. {
  564. #if (PHY_DEV_SHOW_DT_INFO == 1)
  565. LOG_INF("** SPDIFRX BASIC INFO **");
  566. LOG_INF(" BASE: %08x", cfg->reg_base);
  567. LOG_INF(" CLK-ID: %08x", cfg->clk_id);
  568. LOG_INF(" RST-ID: %08x", cfg->rst_id);
  569. LOG_INF(" DMA0-NAME: %s", cfg->dma_fifo0.dma_dev_name);
  570. LOG_INF(" DMA0-ID: %08x", cfg->dma_fifo0.dma_id);
  571. LOG_INF(" DMA0-CH: %08x", cfg->dma_fifo0.dma_chan);
  572. LOG_INF("MIN-COREPLL-CLOCK: %08x", cfg->min_corepll_clock);
  573. #endif
  574. }
  575. static void phy_spdifrx_isr(const void *arg)
  576. {
  577. struct device *dev = (struct device *)arg;
  578. struct acts_audio_spdifrx *spdifrx_base = get_spdifrx_reg_base(dev);
  579. struct phy_spdifrx_drv_data *data = dev->data;
  580. int result;
  581. uint32_t pending;
  582. LOG_DBG("irq pending 0x%x", spdifrx_base->pending);
  583. pending = spdifrx_base->pending & (~0x7F);
  584. /* deal for spdifrx sample rate change irq */
  585. if (spdifrx_base->pending & SPDIFR0_PD_SRCPD) {
  586. /* sample rate change happened */
  587. data->srd_status = RX_SR_STATUS_CHANGE;
  588. result = phy_spdifrx_samplerate_detect(dev, SPDIF_RX_SR_DETECT_MS);
  589. if(result != 0) {
  590. LOG_ERR("sample rate detect error:%d", result);
  591. if (data->srd_callback != NULL)
  592. data->srd_callback(data->cb_data, SPDIFRX_SRD_TIMEOUT, NULL);
  593. } else {
  594. /* got new sample rate */
  595. data->srd_status = RX_SR_STATUS_GET;
  596. }
  597. spdifrx_base->ctl0 |= SPDIFR0_CTL0_DAMS;
  598. if (result == 0) {
  599. /* notify the sample rate event to user */
  600. if (data->srd_callback)
  601. data->srd_callback(data->cb_data, SPDIFRX_SRD_FS_CHANGE, (void *)&data->sample_rate);
  602. }
  603. }
  604. /* sample rate detect timeout pending */
  605. if ((spdifrx_base->pending & SPDIFR0_PD_SRTOPD)
  606. && (data->srd_status == RX_SR_STATUS_GET)) {
  607. if (data->srd_callback)
  608. data->srd_callback(data->cb_data, SPDIFRX_SRD_TIMEOUT, NULL);
  609. data->srd_status = RX_SR_STATUS_NOTGET;
  610. }
  611. /* clear pending */
  612. spdifrx_base->pending |= pending;
  613. }
  614. static int phy_spdifrx_init(const struct device *dev)
  615. {
  616. const struct phy_spdifrx_config_data *cfg = dev->config;
  617. struct phy_spdiftx_drv_data *data = dev->data;
  618. /* clear driver data */
  619. memset(data, 0, sizeof(struct phy_spdifrx_drv_data));
  620. __spdifrx_dt_dump_info(cfg);
  621. /* reset SPDIFRX controller */
  622. acts_reset_peripheral(cfg->rst_id);
  623. if (cfg->irq_config)
  624. cfg->irq_config();
  625. printk("SPDIFRX init successfully\n");
  626. return 0;
  627. }
  628. static void phy_spdifrx_irq_config(void);
  629. /* physical spdifrx driver data */
  630. static struct phy_spdifrx_drv_data phy_spdifrx_drv_data0;
  631. /* physical spdifrx config data */
  632. static const struct phy_spdifrx_config_data phy_spdifrx_config_data0 = {
  633. .reg_base = AUDIO_SPDIFRX_REG_BASE,
  634. AUDIO_DMA_FIFO_DEF(SPDIFRX, 0),
  635. .clk_id = CLOCK_ID_SPDIFRX,
  636. .rst_id = RESET_ID_SPDIFRX,
  637. .min_corepll_clock = CONFIG_AUDIO_SPDIFRX_0_MIN_COREPLL_CLOCK,
  638. .irq_config = phy_spdifrx_irq_config,
  639. };
  640. #if IS_ENABLED(CONFIG_AUDIO_SPDIFRX_0)
  641. DEVICE_DEFINE(spdifrx0, CONFIG_AUDIO_SPDIFRX_0_NAME, phy_spdifrx_init, NULL,
  642. &phy_spdifrx_drv_data0, &phy_spdifrx_config_data0,
  643. POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS, &phy_spdifrx_drv_api);
  644. #endif
  645. static void phy_spdifrx_irq_config(void)
  646. {
  647. IRQ_CONNECT(IRQ_ID_SPIDFRX, CONFIG_AUDIO_SPDIFRX_0_IRQ_PRI,
  648. phy_spdifrx_isr,
  649. DEVICE_GET(spdifrx0), 0);
  650. irq_enable(IRQ_ID_SPIDFRX);
  651. }