123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032 |
- /*
- * Copyright (c) 2020 Actions Semiconductor Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file
- * @brief Audio I2SRX physical implementation
- */
- /*
- * Features
- * - Support master and slave mode
- * - Support I2S 2ch format
- * - I2SRXFIFO(32 x 24bits level)
- * - Support 3 format: left-justified format, right-justified format, I2S format
- * - Support 16/20/24 effective data width; BCLK support 32/64fs, and MCLK=4BCLK
- * - Support sample rate auto detect in slave mode
- * - Sample rate support 8k/12k/11.025k/16k/22.05k/24k/32k/44.1k/48k/88.2k/96k/192k
- */
- #include <kernel.h>
- #include <device.h>
- #include <string.h>
- #include <errno.h>
- #include <soc.h>
- #include <board_cfg.h>
- #include "../phy_audio_common.h"
- #include "../audio_acts_utils.h"
- #include <drivers/audio/audio_in.h>
- #include <logging/log.h>
- LOG_MODULE_REGISTER(i2srx0, LOG_LEVEL_DBG);
- /***************************************************************************************************
- * I2SRX_CTL
- */
- #define I2SR0_CTL_PCM_SYNC BIT(26) /* PCM frame select*/
- #define I2SR0_CTL_PCM_CHAN_SHIFT (24)
- #define I2SR0_CTL_PCM_CHAN_MASK (0x3 << I2SR0_CTL_PCM_CHAN_SHIFT)
- #define I2SR0_CTL_PCM_CHAN(x) ((x) << I2SR0_CTL_PCM_CHAN_SHIFT) /* pcm slot select*/
- #define I2SR0_CTL_TDMRX_CHAN BIT(16) /* 4 channel or 8 channel */
- #define I2SR0_CTL_TDMRX_MODE BIT(15) /* I2S format or left-justified format */
- #define I2SR0_CTL_TDMRX_SYNC_SHIFT (13) /* at the beginning of the data frame, the type of LRCLK setting */
- #define I2SR0_CTL_TDMRX_SYNC_MASK (0x3 << I2SR0_CTL_TDMRX_SYNC_SHIFT)
- #define I2SR0_CTL_TDMRX_SYNC(x) ((x) << I2SR0_CTL_TDMRX_SYNC_SHIFT)
- #define I2SR0_CTL_PCMRX0_EN BIT(6) /* PCM TX ENABEL */
- #define I2SR0_CTL_RXWIDTH_SHIFT (4) /* effective width */
- #define I2SR0_CTL_RXWIDTH_MASK (0x3 << I2SR0_CTL_RXWIDTH_SHIFT)
- #define I2SR0_CTL_RXWIDTH(x) ((x) << I2SR0_CTL_RXWIDTH_SHIFT)
- #define I2SR0_CTL_RXBCLKSET BIT(3) /* rate of BCLK with LRCLK */
- #define I2SR0_CTL_RXMODELSEL_SHIFT (1) /* I2S transfer format select */
- #define I2SR0_CTL_RXMODELSEL_MASK (0x3 << I2SR0_CTL_RXMODELSEL_SHIFT)
- #define I2SR0_CTL_RXMODELSEL(x) ((x) << I2SR0_CTL_RXMODELSEL_SHIFT)
- #define I2SR0_CTL_RXEN BIT(0) /* I2S RX enable */
- /***************************************************************************************************
- * I2SRX_FIFOCTL
- */
- #define I2SR0_FIFOCTL_RXFIFO_DMAWIDTH BIT(7) /* DMA transfer width */
- #define I2SR0_FIFOCTL_RXFOS_SHIFT (4) /* RX FIFO output select */
- #define I2SR0_FIFOCTL_RXFOS_MASK (0x3 << I2SR0_FIFOCTL_RXFOS_SHIFT)
- #define I2SR0_FIFOCTL_RXFOS(x) ((x) << I2SR0_FIFOCTL_RXFOS_SHIFT)
- #define I2SR0_FIFOCTL_RXFFIE BIT(2) /* RX FIFO half filled irq enable */
- #define I2SR0_FIFOCTL_RXFFDE BIT(1) /* RX FIFO half filed drq enable */
- #define I2SR0_FIFOCTL_RXFRT BIT(0) /* RX FIFO reset */
- /***************************************************************************************************
- * I2SRX_STAT
- */
- #define I2SR0_FIFOSTA_FIFO_ER BIT(8) /* FIFO error */
- #define I2SR0_FIFOSTA_RXFEF BIT(7) /* RX FIFO empty flag */
- #define I2SR0_FIFOSTA_RXFIP BIT(6) /* RX FIFO half filled irq pending */
- #define I2SR0_FIFOSTA_RXFS_SHIFT (0) /* RX FIFO status */
- #define I2SR0_FIFOSTA_RXFS_MASK (0x3F << I2SR0_FIFOSTA_RXFS_SHIFT)
- /***************************************************************************************************
- * I2SRX_DAT
- */
- #define I2SR0_DAT_RXDAT_SHIFT (8) /* I2S RX FIFO data */
- #define I2SR0_DAT_RXDAT_MASK (0xFFFFFF << I2SR0_DAT_RXDAT_SHIFT)
- /***************************************************************************************************
- * I2SRX_CTL
- */
- #define I2SR0_SRDCTL_MUTE_EN BIT(12) /* If detect sample rate or channel width changing, mute output */
- #define I2SR0_SRDCTL_TO_IE BIT(11)
- #define I2SR0_SRDCTL_SRD_IE BIT(10)
- #define I2SR0_SRDCTL_CHW_IE BIT(8) /* sample rate detect result change interrupt enable */
- #define I2SR0_SRDCTL_CNT_TIM_SHIFT (4) /* slave mode rample rate detect counter period select */
- #define I2SR0_SRDCTL_CNT_TIM_MASK (0x3 << I2SR0_SRDCTL_CNT_TIM_SHIFT)
- #define I2SR0_SRDCTL_SRD_TH_SHIFT (1) /* the sampling sensitivity */
- #define I2SR0_SRDCTL_SRD_TH_MASK (0x7 << I2SR0_SRDCTL_SRD_TH_SHIFT)
- #define I2SR0_SRDCTL_SRD_TH(x) ((x) << I2SR0_SRDCTL_SRD_TH_SHIFT)
- #define I2SR0_SRDCTL_SRD_EN BIT(0) /* slave mode sample rate detect enable */
- /***************************************************************************************************
- * I2SRX_SRDSTA
- */
- #define I2SR0_SRDSTA_CNT_SHIFT (12) /* CNT of LRCLK which sampling by SRC_CLK */
- #define I2SR0_SRDSTA_CNT_MASK (0x1FFF << I2SR0_SRDSTA_CNT_SHIFT)
- #define I2SR0_SRDSTA_TO_PD BIT(11) /* sample rate changing detection timeout interrupt pending */
- #define I2SR0_SRDSTA_SRC_PD BIT(10) /* sample rate changing detection interrupt pending */
- #define I2SR0_SRDSTA_CHW_PD BIT(8) /* channel width change interrupt pending */
- #define I2SR0_SRDSTA_WL_SHIFT (0) /* channel word length */
- #define I2SR0_SRDSTA_WL_MASK (0x7 << I2SR0_SRDSTA_WL_SHIFT)
- /***************************************************************************************************
- * i2SRX FEATURES CONGIURATION
- */
- /* The sensitivity of the SRD */
- #define I2SRX_SRD_TH_DEFAULT (7)
- #define I2SRX_BCLK_DIV_DEFAULT (0) /* BCLK divisor */
- #define I2SRX_SRD_CONFIG_TIMEOUT_US (500000)
- /*
- * enum a_i2srx_mclk_clksrc_e
- * @brief The MCLK clock source of i2srx selection
- */
- typedef enum {
- CLK_SRCRX_I2SRX = 0, /* I2SRX clock source from I2SRX clk */
- CLK_SRCRX_I2STX, /* I2SRX clock source from I2STX MCLK */
- CLK_SRCRX_I2SRX_EXT = 3, /* I2SRX clock source from I2SRX extern MCLK */
- } a_i2srx_mclk_clksrc_e;
- /*
- * @struct acts_audio_i2srx
- * @brief I2SRX controller hardware register
- */
- struct acts_audio_i2srx {
- volatile uint32_t rx_ctl; /* I2SRX control */
- volatile uint32_t fifoctl; /* I2SRX FIFO control */
- volatile uint32_t fifostat; /* I2SRX FIFO state */
- volatile uint32_t dat; /* I2SRX FIFO data */
- volatile uint32_t srdctl; /* I2S slave mode RX sample rate detect control */
- volatile uint32_t srdstat; /* I2S slave mode RX sample rate detect state */
- };
- /*
- * struct phy_i2srx_drv_data
- * @brief The software related data that used by physical i2srx driver.
- */
- struct phy_i2srx_drv_data {
- uint8_t mclksrc; /* MCLK clock source selection refer to #a_i2srx_mclk_clksrc_e */
- int (*srd_callback)(void *cb_data, uint32_t cmd, void *param);
- void *cb_data;
- uint8_t srd_wl; /* The width length detected by SRD */
- uint8_t sample_rate; /* sample rate */
- uint8_t channel_opened : 1; /* flag of channel opened */
- };
- /**
- * union phy_i2srx_features
- * @brief The infomation from DTS to control the I2SRX features to enable or nor.
- */
- typedef union {
- uint32_t raw;
- struct {
- uint32_t srd_en : 1; /* SRD function enable or not */
- uint32_t mode: 1; /* master mode or slaver mode; 0: master 1: slaver */
- uint32_t channel_num : 4; /* channel number and only support 2/4/8 channels */
- uint32_t slave_internal_clk : 1; /* slave mode MCLK to use internal clock */
- uint32_t lrclk_proc : 1; /* LRCLK process */
- uint32_t mclk_reverse : 1; /* mclk reverse */
- uint32_t format : 2; /* I2S transfer format */
- uint32_t clk_from_i2stx : 1; /* clock from I2STX(I2SG0) clock */
- uint32_t tdm_format : 1; /* TDM format */
- uint32_t tdm_frame : 2; /* TDM frame start position */
- uint32_t bclk_width : 1; /* bclk width */
- uint32_t pcm_en : 1; /* pcm select */
- uint32_t pcm_frame : 1; /* pcm frame */
- uint32_t pcm_slot : 2; /* pcm slot */
- } v;
- } phy_i2srx_features;
- /**
- * struct phy_i2srx_config_data
- * @brief The hardware related data that used by physical i2srx driver.
- */
- struct phy_i2srx_config_data {
- uint32_t reg_base; /* I2STX controller register base address */
- uint8_t clk_id; /* I2STX devclk id */
- uint8_t srd_clk_id; /* I2S SRD clock id */
- uint8_t hclk_clk_id; /* I2S HCLK clock id */
- uint8_t rst_id; /* I2STX reset id */
- struct audio_dma_dt dma_fifo0; /* DMA resource for SPDIFRX */
- void (*irq_config)(void); /* IRQ configuration function */
- phy_i2srx_features features; /* I2STX features */
- };
- /* @brief Get the I2SRX controller base address */
- static inline struct acts_audio_i2srx *get_i2srx_reg_base(struct device *dev)
- {
- const struct phy_i2srx_config_data *cfg = dev->config;
- return (struct acts_audio_i2srx *)cfg->reg_base;
- }
- /* @brief Dump the I2SRX relative registers */
- static void i2srx_dump_register(struct device *dev)
- {
- struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
- LOG_INF("** i2srx contoller regster **");
- LOG_INF(" BASE: %08x", (uint32_t)i2srx_reg);
- LOG_INF(" I2SRX_CTL: %08x", i2srx_reg->rx_ctl);
- LOG_INF(" I2SRX_FIFOCTL: %08x", i2srx_reg->fifoctl);
- LOG_INF(" I2SRX_FIFOSTA: %08x", i2srx_reg->fifostat);
- LOG_INF(" I2SRX_DAT: %08x", i2srx_reg->dat);
- LOG_INF(" I2SRX_SRDCTL: %08x", i2srx_reg->srdctl);
- LOG_INF(" I2SRX_SRDSTA: %08x", i2srx_reg->srdstat);
- LOG_INF(" AUDIOPLL0_CTL: %08x", sys_read32(AUDIO_PLL0_CTL));
- LOG_INF(" AUDIOPLL1_CTL: %08x", sys_read32(AUDIO_PLL1_CTL));
- LOG_INF(" CMU_I2STXCLK: %08x", sys_read32(CMU_I2STXCLK));
- LOG_INF(" CMU_I2SRXCLK: %08x", sys_read32(CMU_I2SRXCLK));
- LOG_INF(" DMA6_CTL: %08x", sys_read32(0x4001c700));
- LOG_INF(" DMA6_START: %08x", sys_read32(0x4001c704));
- LOG_INF(" DMA6_sadd0: %08x", sys_read32(0x4001c708));
- LOG_INF(" DMA6_sadd1: %08x", sys_read32(0x4001c70c));
- LOG_INF(" DMA6_dadd0: %08x", sys_read32(0x4001c710));
- LOG_INF(" DMA6_dadd1: %08x", sys_read32(0x4001c714));
- LOG_INF(" DMA6_bc: %08x", sys_read32(0x4001c718));
- LOG_INF(" DMA6_rc: %08x", sys_read32(0x4001c71c));
- }
- /* @brief I2SRX sample rate config */
- static int i2srx_sample_rate_set(struct device *dev, uint16_t sr_khz,
- a_i2srx_mclk_clksrc_e mclk_src)
- {
- const struct phy_i2srx_config_data *cfg = dev->config;
- int ret;
- uint8_t clk_div, series, pll_index;
- uint32_t reg = 0;
- uint32_t lrclk_div;
- a_mclk_type_e mclk;
- switch (I2SRX_BCLK_DIV_DEFAULT)
- {
- case 0:
- if (!PHY_DEV_FEATURE(bclk_width))
- mclk = MCLK_256FS;
- else
- mclk = MCLK_128FS;
- break;
- case 1:
- if (!PHY_DEV_FEATURE(bclk_width))
- mclk = MCLK_384FS;
- else
- mclk = MCLK_192FS;
- break;
- case 2:
- if (!PHY_DEV_FEATURE(bclk_width))
- mclk = MCLK_512FS;
- else
- mclk = MCLK_256FS;
- break;
- case 3:
- if (!PHY_DEV_FEATURE(bclk_width))
- mclk = MCLK_768FS;
- else
- mclk = MCLK_384FS;
- break;
- default:
- if (!PHY_DEV_FEATURE(bclk_width))
- mclk = MCLK_256FS;
- else
- mclk = MCLK_128FS;
- break;
- }
- if (CLK_SRCRX_I2STX == mclk_src) {
- struct device *i2stx_dev = (struct device *)device_get_binding(CONFIG_AUDIO_I2STX_0_NAME);
- if (!i2stx_dev) {
- LOG_ERR("failed to get i2stx dev %s", CONFIG_AUDIO_I2STX_0_NAME);
- return -ENODEV;
- }
- return phy_audio_control(i2stx_dev, PHY_CMD_I2STX_CLK_SET, &sr_khz);
- } else if (CLK_SRCRX_I2SRX == mclk_src) {
- /* make external MCLK clock phase reverse */
- if (PHY_DEV_FEATURE(mclk_reverse))
- reg |= CMU_I2SRXCLK_I2SG1MCLKEXTREV;
- /* I2S master mode to enable MCLK output to PAD */
- if (!PHY_DEV_FEATURE(mode)) {
- reg |= (CMU_I2SG1MCLKOEN | CMU_I2SG1BCLKOEN | CMU_I2SG1LRCLOKEN | CMU_I2SRXCLK_I2SRX0CLKSRC);
- } else {
- if (PHY_DEV_FEATURE(slave_internal_clk))
- sr_khz *= 2; /* slave mode use internal clk condition: MCLK > 6BCLK */
- /* BCLK/LRCLK source from external PAD */
- reg |= CMU_I2SRXCLK_I2SG1BLRCLKSRC;
- }
- reg |= CMU_I2SRXCLK_I2SG1LRCLKPROC(PHY_DEV_FEATURE(lrclk_proc));
- /* BCLK = FS x channel number x channel bit width */
- if (!PHY_DEV_FEATURE(bclk_width))
- lrclk_div = PHY_DEV_FEATURE(channel_num) * 32;
- else
- lrclk_div = PHY_DEV_FEATURE(channel_num) * 16;
- /* LRCLK divisor 0:32; 1:64; 2: 128; 3:256 */
- if (32 == lrclk_div) {
- lrclk_div = 0;
- } else if (64 == lrclk_div) {
- lrclk_div = 1;
- } else if (128 == lrclk_div) {
- lrclk_div = 2;
- } else if (256 == lrclk_div) {
- lrclk_div = 3;
- } else {
- LOG_ERR("invalid lrclk divisor:%d", lrclk_div);
- return -EINVAL;
- }
- reg |= CMU_I2SRXCLK_I2SG1LRCLKDIV(lrclk_div);
- /* MCLK = 4 x BCLK */
- reg |= CMU_I2SRXCLK_I2SG1BCLKDIV(I2SRX_BCLK_DIV_DEFAULT);
- sr_khz = PHY_DEV_FEATURE(channel_num) / 2 * sr_khz;
- /* Get audio PLL setting */
- ret = audio_get_pll_setting_i2s(sr_khz, mclk, &clk_div, &series);
- if (ret) {
- LOG_DBG("get pll setting error:%d", ret);
- return ret;
- }
- ret = audio_pll_check_config(series, &pll_index);
- if (ret) {
- LOG_DBG("check pll config error:%d", ret);
- return ret;
- }
- /* Select pll0 or pll1 */
- // reg |= (pll_index & 0x1) << CMU_I2SRXCLK_I2SG1CLKSRC;
- reg |= clk_div << CMU_I2SRXCLK_I2SG1CLKDIV_SHIFT;
- } else if (CLK_SRCRX_I2SRX_EXT == mclk_src) {
- LOG_INF("I2SRX clock source from external");
- /* BCLK/LRCLK source from external PAD */
- // reg |= CMU_I2SRXCLK_I2SG1BLRCLKSRC;//RX CLOCK来自G0
- reg |= CMU_I2SRXCLK_I2SG1BLRCLKSRC | CMU_I2SRXCLK_I2SRX0CLKSRC;//CLOCK来自G1
- } else {
- LOG_ERR("Invalid i2srx clk source %d", mclk_src);
- return -EINVAL;
- }
- /* Select the i2srx mclk source */
- reg |= CMU_I2SRXCLK_I2SG1MCLKSRC(mclk_src);
- sys_write32(reg, CMU_I2SRXCLK);
- return 0;
- }
- /* @brief Get the sample rate from the I2SRX config */
- static int i2srx_sample_rate_get(struct device *dev)
- {
- const struct phy_i2srx_config_data *cfg = dev->config;
- uint8_t clk_div, pll_index, mclk_src;
- uint32_t reg;
- int ret = -1;
- a_mclk_type_e mclk;
- if (!PHY_DEV_FEATURE(bclk_width))
- mclk = MCLK_256FS;
- else
- mclk = MCLK_128FS;
- reg = sys_read32(CMU_I2SRXCLK);
- mclk_src = (reg & CMU_I2SRXCLK_I2SG1MCLKSRC_MASK) >> CMU_I2SRXCLK_I2SG1MCLKSRC_SHIFT;
- if (CLK_SRCRX_I2SRX == mclk_src) {
- clk_div = reg & 0xF;
- pll_index = 0;//leopard 只有一个PLL0源
- ret = audio_get_pll_sample_rate_i2s(MCLK_256FS, clk_div, pll_index);
- } else if (CLK_SRCRX_I2STX == mclk_src) {
- reg = sys_read32(CMU_I2STXCLK);
- clk_div = reg & 0xF;
- pll_index = 0;
- ret = audio_get_pll_sample_rate_i2s(mclk, clk_div, pll_index);
- } else if (CLK_SRCRX_I2SRX_EXT == mclk_src) {
- LOG_INF("I2SRX is using the external clock");
- ret = -ENOENT;
- }
- return ret;
- }
- /* @brief Get the AUDIO_PLL APS used by I2SRX */
- static int i2srx_get_pll_aps(struct device *dev)
- {
- uint32_t reg;
- uint8_t pll_index, mclk_src;
- int ret = -1;
- reg = sys_read32(CMU_I2SRXCLK);
- mclk_src = (reg & CMU_I2SRXCLK_I2SG1MCLKSRC_MASK) >> CMU_I2SRXCLK_I2SG1MCLKSRC_SHIFT;
- pll_index = AUDIOPLL_TYPE_0;//leopard 只有一个PLL0源
- if (CLK_SRCRX_I2SRX == mclk_src) {
- ret = audio_pll_get_aps((a_pll_type_e)pll_index);
- } else if (CLK_SRCRX_I2STX == mclk_src) {
- reg = sys_read32(CMU_I2STXCLK);
- ret = audio_pll_get_aps((a_pll_type_e)pll_index);
- }if (CLK_SRCRX_I2SRX_EXT == mclk_src) {
- LOG_INF("I2SRX is using the external clock source");
- return -ENOENT;
- }
- return ret;
- }
- /* @brief Set the AUDIO_PLL APS used by I2SRX */
- static int i2srx_set_pll_aps(struct device *dev, audio_aps_level_e level)
- {
- uint32_t reg;
- uint8_t pll_index, mclk_src;
- int ret = -1;
- reg = sys_read32(CMU_I2SRXCLK);
- mclk_src = (reg & CMU_I2SRXCLK_I2SG1MCLKSRC_MASK) >> CMU_I2SRXCLK_I2SG1MCLKSRC_SHIFT;
- if (CLK_SRCRX_I2SRX == mclk_src) {
- pll_index = AUDIOPLL_TYPE_0;//leopard 只有一个PLL0源
- ret = audio_pll_set_aps((a_pll_type_e)pll_index, level);
- } else if (CLK_SRCRX_I2STX == mclk_src) {
- reg = sys_read32(CMU_I2STXCLK);
- pll_index = AUDIOPLL_TYPE_0;
- ret = audio_pll_set_aps((a_pll_type_e)pll_index, level);
- } else if (CLK_SRCRX_I2SRX_EXT == mclk_src) {
- LOG_INF("I2SRX is using the external clock source");
- ret = -ENOENT;
- }
- return ret;
- }
- /* @brief Disable the I2SRX FIFO */
- static void i2srx_fifo_disable(struct device *dev)
- {
- struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
- i2srx_reg->fifoctl &= ~I2SR0_CTL_RXEN;
- }
- /* @brief Reset the I2SRX FIFO */
- static void i2srx_fifo_reset(struct device *dev)
- {
- struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
- i2srx_reg->fifoctl &= ~I2SR0_CTL_RXEN;
- i2srx_reg->fifoctl |= I2SR0_CTL_RXEN;
- }
- /* @brief Enable the I2SRX FIFO */
- static void i2srx_fifo_enable(struct device *dev, audio_fifouse_sel_e sel, audio_dma_width_e width)
- {
- struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
- uint32_t reg = 0;
- if (DMA_WIDTH_16BITS == width)
- reg |= I2SR0_FIFOCTL_RXFIFO_DMAWIDTH;
- if (FIFO_SEL_CPU == sel) {
- reg |= (I2SR0_FIFOCTL_RXFFIE | I2SR0_FIFOCTL_RXFRT);
- } else if (FIFO_SEL_DMA == sel) {
- reg |= (I2SR0_FIFOCTL_RXFFDE | I2SR0_FIFOCTL_RXFRT
- | I2SR0_FIFOCTL_RXFOS(1));
- } else if (FIFO_SEL_DSP == sel) {
- reg |= I2SR0_FIFOCTL_RXFOS(3) | I2SR0_FIFOCTL_RXFRT;
- } else {
- LOG_ERR("invalid fifo sel %d", sel);
- }
- i2srx_reg->fifoctl = reg;
- }
- /* @brief I2SRX digital function control */
- static void i2srx_digital_enable(struct device *dev, audio_ch_width_e width)
- {
- const struct phy_i2srx_config_data *cfg = dev->config;
- struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
- uint32_t reg = 0;
- uint8_t rx_width, fmt = PHY_DEV_FEATURE(format);
- uint8_t pcm_frame = PHY_DEV_FEATURE(pcm_frame);
- uint8_t pcm_slot = PHY_DEV_FEATURE(pcm_slot);
- if (CHANNEL_WIDTH_16BITS == width)
- rx_width = 0;
- else if (CHANNEL_WIDTH_20BITS == width)
- rx_width = 1;
- else
- rx_width = 2;
- if (PHY_DEV_FEATURE(channel_num) != 2) {
- fmt = 3; /* TDM mode */
- reg &= ~ (0xF << I2SR0_CTL_TDMRX_SYNC_SHIFT);
- if (PHY_DEV_FEATURE(channel_num) == 8)
- reg |= I2SR0_CTL_TDMRX_CHAN;
- if (PHY_DEV_FEATURE(tdm_format))
- reg |= I2SR0_CTL_TDMRX_MODE;
- reg |= I2SR0_CTL_TDMRX_SYNC(PHY_DEV_FEATURE(tdm_frame));
- }
- reg |= (I2SR0_CTL_RXMODELSEL(fmt) | I2SR0_CTL_RXWIDTH(rx_width));
- if (PHY_DEV_FEATURE(bclk_width))
- reg |= I2SR0_CTL_RXBCLKSET;
- i2srx_reg->rx_ctl = reg;
- /* PCM RX enable */
- if(PHY_DEV_FEATURE(pcm_en))
- {
- i2srx_reg->rx_ctl |= I2SR0_CTL_PCM_CHAN(pcm_slot);
- i2srx_reg->rx_ctl |= I2SR0_CTL_PCMRX0_EN;
- //pcm frame set 1 is long frame
- if(pcm_frame)
- {
- i2srx_reg->rx_ctl |= I2SR0_CTL_PCM_SYNC;
- sys_write32(sys_read32(CMU_I2SRXCLK)|
- CMU_I2SRXCLK_I2SG1LRCLKPROC(2),
- CMU_I2SRXCLK);
- }
- else
- sys_write32(sys_read32(CMU_I2SRXCLK)|
- CMU_I2SRXCLK_I2SG1LRCLKPROC(3),
- CMU_I2SRXCLK);
- }
- else
- /* I2S RX enable */
- i2srx_reg->rx_ctl |= I2SR0_CTL_RXEN;
- }
- /* @brief Disable I2SRX digital function */
- static void i2srx_digital_disable(struct device *dev)
- {
- struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
- i2srx_reg->rx_ctl = 0;
- }
- /* @brief get the I2SRX sample rate detect counter */
- static uint32_t read_i2srx_srd_count(struct device *dev)
- {
- struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
- /* CNT of LRCLK which sampling by SRC_CLK */
- return ((i2srx_reg->srdstat & I2SR0_SRDSTA_CNT_MASK) >> I2SR0_SRDSTA_CNT_SHIFT);
- }
- /* @brief I2SRX in slave mode handle sample rate detect change */
- static void i2srx_srd_fs_change(struct device *dev)
- {
- const struct phy_i2srx_config_data *cfg = dev->config;
- struct phy_i2srx_drv_data *data = dev->data;
- uint32_t cnt, fs;
- audio_sr_sel_e sr;
- cnt = read_i2srx_srd_count(dev);
- /* CNT = SRD_CLK / LRCLK and SRD_CLK uses HOSC which is a 32MHz clock source*/
- fs = 32 *1000 / cnt;
- /* Allow a 1% deviation */
- if ((fs > 7920) && (fs < 8080)) { /* 8kfs */
- sr = SAMPLE_RATE_8KHZ;
- } else if ((fs > 10915) && (fs < 11135)) { /* 11.025kfs */
- sr = SAMPLE_RATE_11KHZ;
- } else if ((fs > 11880) && (fs < 12120)) { /* 12kfs */
- sr = SAMPLE_RATE_12KHZ;
- } else if ((fs > 15840) && (fs < 16160)) { /* 16kfs */
- sr = SAMPLE_RATE_16KHZ;
- } else if ((fs > 21830) && (fs < 22270)) { /* 22.05kfs */
- sr = SAMPLE_RATE_22KHZ;
- } else if ((fs > 23760) && (fs < 24240)) { /* 24kfs */
- sr = SAMPLE_RATE_24KHZ;
- } else if ((fs > 31680) && (fs < 32320)) { /* 32kfs */
- sr = SAMPLE_RATE_32KHZ;
- } else if ((fs > 43659) && (fs < 44541)) { /* 44.1kfs */
- sr = SAMPLE_RATE_44KHZ;
- } else if ((fs > 47520) && (fs < 48480)) { /* 48kfs */
- sr = SAMPLE_RATE_48KHZ;
- } else if ((fs > 63360) && (fs < 64640)) { /* 64kfs */
- sr = SAMPLE_RATE_64KHZ;
- } else if ((fs > 87318) && (fs < 89082)) { /* 88.2kfs */
- sr = SAMPLE_RATE_88KHZ;
- } else if ((fs > 95040) && (fs < 96960)) { /* 96kfs */
- sr = SAMPLE_RATE_96KHZ;
- } else if ((fs > 174636) && (fs < 178164)) { /* 176.4kfs */
- sr = SAMPLE_RATE_176KHZ;
- } else if((fs > 190080) && (fs < 193920)) { /* 192kfs */
- sr = SAMPLE_RATE_192KHZ;
- } else {
- LOG_ERR("Invalid sample rate %d", fs);
- return ;
- }
- LOG_INF("Detect new sample rate %d -> %d", fs, sr);
- /* FIXME: If not do the fifo reset, the left and right channel will exchange probably. */
- i2srx_fifo_reset(dev);
- if (data->sample_rate != sr && PHY_DEV_FEATURE(slave_internal_clk)) {
- i2srx_sample_rate_set(dev, sr, data->mclksrc);
- data->sample_rate = sr;
- }
- if (data->srd_callback)
- data->srd_callback(data->cb_data, I2SRX_SRD_FS_CHANGE, (void *)&sr);
- }
- /* @brief I2SRX SRD width length change operation */
- void i2srx_srd_wl_change(struct device *dev)
- {
- struct phy_i2srx_drv_data *data = dev->data;
- struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
- uint8_t width;
- width = i2srx_reg->srdstat & I2SR0_SRDSTA_WL_MASK;
- LOG_DBG("Detect new width length: %d", width);
- if (((data->srd_wl == SRDSTA_WL_64RATE) && (width == SRDSTA_WL_32RATE))
- || ((data->srd_wl == SRDSTA_WL_32RATE) && (width == SRDSTA_WL_64RATE))) {
- data->srd_wl = width;
- if (data->srd_callback)
- data->srd_callback(data->cb_data, I2SRX_SRD_WL_CHANGE, (void *)&data->srd_wl);
- }
- }
- /* @brief I2SRX sample rate detect function configuration */
- static int i2srx_srd_cfg(struct device *dev, uint8_t srd_th, audio_i2s_srd_period_e period, bool irq_en, bool mute)
- {
- const struct phy_i2srx_config_data *cfg = dev->config;
- struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
- uint32_t reg;
- uint8_t _wl, wl;
- uint32_t start_time, curr_time;
- reg = (I2SR0_SRDCTL_SRD_TH(srd_th & 0x7) | I2SR0_SRDCTL_SRD_TH(period));
- if (irq_en)
- reg |= I2SR0_SRDCTL_CHW_IE | I2SR0_SRDCTL_SRD_IE | I2SR0_SRDCTL_TO_IE;
- if (mute)
- reg |= I2SR0_SRDCTL_MUTE_EN;
- i2srx_reg->srdctl = reg;
- /* enable slave mode sample rate detect */
- i2srx_reg->srdctl |= I2SR0_SRDCTL_SRD_EN;
- if (!PHY_DEV_FEATURE(bclk_width))
- wl = SRDSTA_WL_64RATE;
- else
- wl = SRDSTA_WL_32RATE;
- start_time = k_cycle_get_32();
- _wl = i2srx_reg->srdstat & I2SR0_SRDSTA_WL_MASK;
- while (_wl != wl) {
- curr_time = k_cycle_get_32();
- if (k_cyc_to_us_floor32(curr_time - start_time) > I2SRX_SRD_CONFIG_TIMEOUT_US) {
- LOG_ERR("Wait SRD WL status timeout");
- return -ETIMEDOUT;
- }
- _wl = i2srx_reg->srdstat & I2SR0_SRDSTA_WL_MASK;
- k_sleep(K_MSEC(2));
- }
- i2srx_reg->srdstat |= I2SR0_SRDSTA_CHW_PD;
- i2srx_srd_fs_change(dev);
- return 0;
- }
- // static int set_gpio_mfc(int type, int gpio_m_num,int gpio__b_num,int gpio_lr_num,int gpio_io_num)
- // {
- // if(type==0)
- // {
- // //i2s tx gpio_mfc_config
- // sys_write32(0x0000100c,GPIO_REG_BASE + gpio_m_num * 0x4);
- // sys_write32(0x0000100c,GPIO_REG_BASE + gpio__b_num * 0x4);
- // sys_write32(0x0000100c,GPIO_REG_BASE + gpio_lr_num * 0x4);
- // sys_write32(0x0000100c,GPIO_REG_BASE + gpio_io_num * 0x4);
- // printk("%08x\n",(sys_read32(GPIO_REG_BASE + gpio_m_num * 0x4)));
- // printk("%08x\n",(sys_read32(GPIO_REG_BASE + gpio__b_num * 0x4)));
- // printk("%08x\n",(sys_read32(GPIO_REG_BASE + gpio_lr_num * 0x4)));
- // printk("%08x\n",(sys_read32(GPIO_REG_BASE + gpio_io_num * 0x4)));
- // }
- // else
- // {
- // //i2s rx gpio_mfc_config
- // sys_write32(0x0000100d,GPIO_REG_BASE + gpio_m_num * 0x4);
- // sys_write32(0x0000100d,GPIO_REG_BASE + gpio__b_num * 0x4);
- // sys_write32(0x0000100d,GPIO_REG_BASE + gpio_lr_num * 0x4);
- // sys_write32(0x0000100d,GPIO_REG_BASE + gpio_io_num * 0x4);
- // printk("%08x\n",*((volatile unsigned int*)(GPIO_REG_BASE + gpio_m_num * 0x4)));
- // printk("%08x\n",*((volatile unsigned int*)(GPIO_REG_BASE + gpio__b_num * 0x4)));
- // printk("%08x\n",*((volatile unsigned int*)(GPIO_REG_BASE + gpio_lr_num * 0x4)));
- // printk("%08x\n",*((volatile unsigned int*)(GPIO_REG_BASE + gpio_io_num * 0x4)));
- // }
- // return 0;
- // }
- /* @brief physical I2SRX device enable */
- static int phy_i2srx_enable(struct device *dev, void *param)
- {
- const struct phy_i2srx_config_data *cfg = dev->config;
- struct phy_i2srx_drv_data *data = dev->data;
- ain_param_t *in_param = (ain_param_t *)param;
- i2srx_setting_t *i2srx_setting = in_param->i2srx_setting;
- soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, true);
- if ((!in_param) || (!i2srx_setting)
- || (!in_param->sample_rate)) {
- LOG_ERR("Invalid parameters");
- soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, false);
- return -EINVAL;
- }
- if (in_param->channel_type != AUDIO_CHANNEL_I2SRX) {
- LOG_ERR("Invalid channel type %d", in_param->channel_type);
- soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, false);
- return -EINVAL;
- }
- /* enable adc clock */
- acts_clock_peripheral_enable(cfg->clk_id);
- acts_clock_peripheral_enable(cfg->hclk_clk_id);
- if (PHY_DEV_FEATURE(srd_en))
- acts_clock_peripheral_enable(cfg->srd_clk_id);
- /* slave mode and clock from external source */
- if (PHY_DEV_FEATURE(mode)
- && !PHY_DEV_FEATURE(slave_internal_clk)) {
- data->mclksrc = CLK_SRCRX_I2SRX_EXT;
- } else if (PHY_DEV_FEATURE(clk_from_i2stx)) {
- if (PHY_DEV_FEATURE(mode)) {
- LOG_ERR("clock source form I2STX shall work in master mode");
- soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, false);
- return -EPERM;
- }
- data->mclksrc = CLK_SRCRX_I2STX;
- } else {
- data->mclksrc = CLK_SRCRX_I2SRX;
- }
- /* I2SRX sample rate set */
- if (i2srx_sample_rate_set(dev, in_param->sample_rate, data->mclksrc)) {
- LOG_ERR("Failed to config sample rate %d",
- in_param->sample_rate);
- soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, false);
- return -ESRCH;
- }
- /*enable txfifo clock*/
- sys_write32(sys_read32(CMU_I2SRXCLK) | CMU_I2SRX0_FIFOCLKEN, CMU_I2SRXCLK);
- i2srx_fifo_enable(dev, FIFO_SEL_DMA, (in_param->channel_width == CHANNEL_WIDTH_16BITS)
- ? DMA_WIDTH_16BITS : DMA_WIDTH_32BITS);
- i2srx_digital_enable(dev, in_param->channel_width);
- if (PHY_DEV_FEATURE(mode) && PHY_DEV_FEATURE(srd_en)) {
- LOG_INF("I2SRX SRD enable");
- i2srx_srd_cfg(dev, I2SRX_SRD_TH_DEFAULT, I2S_SRD_2LRCLK, true, false);
- data->srd_callback = i2srx_setting->srd_callback;
- data->cb_data = i2srx_setting->cb_data;
- if (!PHY_DEV_FEATURE(bclk_width))
- data->srd_wl = SRDSTA_WL_64RATE;
- else
- data->srd_wl = SRDSTA_WL_32RATE;
- }
- data->channel_opened = 1;
- // set_gpio_mfc(1,16,17,21,15);//rx
- return 0;
- }
- /* @brief physical I2SRX device disable */
- static int phy_i2srx_disable(struct device *dev, void *param)
- {
- const struct phy_i2srx_config_data *cfg = dev->config;
- struct phy_i2srx_drv_data *data = dev->data;
- i2srx_fifo_disable(dev);
- i2srx_digital_disable(dev);
- if (PHY_DEV_FEATURE(srd_en))
- acts_clock_peripheral_disable(cfg->srd_clk_id);
- data->srd_callback = NULL;
- data->cb_data = NULL;
- if (!PHY_DEV_FEATURE(bclk_width))
- data->srd_wl = SRDSTA_WL_64RATE;
- else
- data->srd_wl = SRDSTA_WL_32RATE;
- data->sample_rate = 0;
- data->channel_opened = 0;
- acts_clock_peripheral_disable(cfg->clk_id);
- soc_powergate_set(POWERGATE_DSP_AU_PG_DEV, false);
- return 0;
- }
- /* @brief physical I2SRX IO commands */
- static int phy_i2srx_ioctl(struct device *dev, uint32_t cmd, void *param)
- {
- const struct phy_i2srx_config_data *cfg = dev->config;
- struct phy_i2srx_drv_data *data = dev->data;
- int ret = 0;
- switch (cmd) {
- case PHY_CMD_DUMP_REGS:
- {
- i2srx_dump_register(dev);
- break;
- }
- case AIN_CMD_I2SRX_QUERY_SAMPLE_RATE:
- {
- *(audio_sr_sel_e *)param = data->sample_rate;
- break;
- }
- case PHY_CMD_I2SRX_IS_OPENED:
- {
- *(uint8_t *)param = data->channel_opened;
- break;
- }
- case AIN_CMD_GET_SAMPLERATE:
- {
- ret = i2srx_sample_rate_get(dev);
- if (ret < 0) {
- LOG_ERR("Failed to get I2SRX sample rate err=%d", ret);
- return ret;
- }
- *(audio_sr_sel_e *)param = (audio_sr_sel_e)ret;
- ret = 0;
- break;
- }
- case AIN_CMD_SET_SAMPLERATE:
- {
- audio_sr_sel_e val = *(audio_sr_sel_e *)param;
- ret = i2srx_sample_rate_set(dev, val, data->mclksrc);
- if (ret) {
- LOG_ERR("Failed to set I2SRX sample rate err=%d", ret);
- return ret;
- }
- break;
- }
- case AIN_CMD_GET_APS:
- {
- ret = i2srx_get_pll_aps(dev);
- if (ret < 0) {
- LOG_ERR("Failed to get audio pll APS err=%d", ret);
- return ret;
- }
- *(audio_aps_level_e *)param = (audio_aps_level_e)ret;
- ret = 0;
- break;
- }
- case AIN_CMD_SET_APS:
- {
- audio_aps_level_e level = *(audio_aps_level_e *)param;
- ret = i2srx_set_pll_aps(dev, level);
- if (ret) {
- LOG_ERR("Failed to set audio pll APS err=%d", ret);
- return ret;
- }
- LOG_DBG("set new aps level %d", level);
- break;
- }
- case PHY_CMD_GET_AIN_DMA_INFO:
- {
- struct audio_out_dma_info *info = (struct audio_out_dma_info *)param;
- info->dma_info.dma_chan = cfg->dma_fifo0.dma_chan;
- info->dma_info.dma_dev_name = cfg->dma_fifo0.dma_dev_name;
- info->dma_info.dma_id = cfg->dma_fifo0.dma_id;
- break;
- }
- default:
- LOG_ERR("Unsupport command %d", cmd);
- return -ENOTSUP;
- }
- return ret;
- }
- const struct phy_audio_driver_api phy_i2srx_drv_api = {
- .audio_enable = phy_i2srx_enable,
- .audio_disable = phy_i2srx_disable,
- .audio_ioctl = phy_i2srx_ioctl,
- };
- /* dump i2srx device tree infomation */
- static void __i2srx_dt_dump_info(const struct phy_i2srx_config_data *cfg)
- {
- #if (PHY_DEV_SHOW_DT_INFO == 1)
- LOG_INF("** I2SRX BASIC INFO **");
- LOG_INF(" BASE: %08x", cfg->reg_base);
- LOG_INF(" CLK-ID: %08x", cfg->clk_id);
- LOG_INF("SRDCLK-ID: %08x", cfg->srd_clk_id);
- LOG_INF(" RST-ID: %08x", cfg->rst_id);
- LOG_INF("DMA0-NAME: %s", cfg->dma_fifo0.dma_dev_name);
- LOG_INF(" DMA0-ID: %08x", cfg->dma_fifo0.dma_id);
- LOG_INF(" DMA0-CH: %08x", cfg->dma_fifo0.dma_chan);
- LOG_INF("** I2SRX FEATURES **");
- LOG_INF(" SRD-EN: %d", PHY_DEV_FEATURE(srd_en));
- LOG_INF(" MODE: %d", PHY_DEV_FEATURE(mode));
- LOG_INF(" BCLK-WIDTH: %d", PHY_DEV_FEATURE(bclk_width));
- LOG_INF(" CH-NUM: %d", PHY_DEV_FEATURE(channel_num));
- LOG_INF(" EXTERNAL-CLK: %d", PHY_DEV_FEATURE(slave_internal_clk));
- LOG_INF(" LRCLK-PROC: %d", PHY_DEV_FEATURE(lrclk_proc));
- LOG_INF(" TDM-FORMAT: %d", PHY_DEV_FEATURE(tdm_format));
- LOG_INF(" TDM-FRAME: %d", PHY_DEV_FEATURE(tdm_frame));
- LOG_INF(" MCLK-REVERSE: %d", PHY_DEV_FEATURE(mclk_reverse));
- LOG_INF("CLK-FROM-I2STX: %d", PHY_DEV_FEATURE(clk_from_i2stx));
- #endif
- }
- static int phy_i2srx_init(const struct device *dev)
- {
- const struct phy_i2srx_config_data *cfg = dev->config;
- struct phy_i2srx_drv_data *data = dev->data;
- /* clear driver data */
- memset(data, 0, sizeof(struct phy_i2srx_drv_data));
- __i2srx_dt_dump_info(cfg);
- /* reset I2SRX controller */
- acts_reset_peripheral(cfg->rst_id);
- acts_reset_peripheral(RESET_ID_ADC);//REST ADC
- if (cfg->irq_config)
- cfg->irq_config();
- printk("I2SRX init successfully\n");
- return 0;
- }
- void phy_i2srx_isr(const void *arg)
- {
- struct device *dev = (struct device *)arg;
- struct acts_audio_i2srx *i2srx_reg = get_i2srx_reg_base(dev);
- struct phy_i2srx_drv_data *data = dev->data;
- LOG_DBG("srdstat: 0x%x", i2srx_reg->srdstat);
- /* Sample rate detection timeout irq pending */
- if (i2srx_reg->srdstat & I2SR0_SRDSTA_TO_PD) {
- i2srx_reg->srdstat |= I2SR0_SRDSTA_TO_PD;
- if (data->srd_callback)
- data->srd_callback(data->cb_data, I2SRX_SRD_TIMEOUT, NULL);
- }
- /* Sample rate changed detection irq pending */
- if (i2srx_reg->srdstat & I2SR0_SRDSTA_SRC_PD) {
- i2srx_reg->srdstat |= I2SR0_SRDSTA_SRC_PD;
- i2srx_srd_fs_change(dev);
- }
- /* Channel width change irq pending */
- if (i2srx_reg->srdstat & I2SR0_SRDSTA_CHW_PD) {
- i2srx_reg->srdstat |= I2SR0_SRDSTA_CHW_PD;
- i2srx_srd_wl_change(dev);
- }
- }
- static void phy_i2srx_irq_config(void);
- /* physical i2stx driver data */
- static struct phy_i2srx_drv_data phy_i2srx_drv_data0;
- /* physical i2stx config data */
- static const struct phy_i2srx_config_data phy_i2srx_config_data0 = {
- .reg_base = AUDIO_I2SRX0_REG_BASE,
- .clk_id = CLOCK_ID_I2SRX,
- .srd_clk_id = CLOCK_ID_I2SSRDCLK,
- .hclk_clk_id = CLOCK_ID_I2SHCLKEN,
- .rst_id = RESET_ID_I2SRX,
- AUDIO_DMA_FIFO_DEF(I2SRX, 0),
- .irq_config = phy_i2srx_irq_config,
- PHY_DEV_FEATURE_DEF(srd_en) = CONFIG_AUDIO_I2SRX_0_SRD_EN,
- PHY_DEV_FEATURE_DEF(mode) = CONFIG_AUDIO_I2SRX_0_MODE,
- PHY_DEV_FEATURE_DEF(bclk_width) = CONFIG_AUDIO_I2SRX_0_BCLK_WIDTH,
- PHY_DEV_FEATURE_DEF(channel_num) = CONFIG_AUDIO_I2SRX_0_CHANNEL_NUM,
- PHY_DEV_FEATURE_DEF(slave_internal_clk) = CONFIG_AUDIO_I2SRX_0_SLAVE_INTERNAL_CLK,
- PHY_DEV_FEATURE_DEF(lrclk_proc) = CONFIG_AUDIO_I2SRX_0_LRCLK_PROC,
- PHY_DEV_FEATURE_DEF(tdm_format) = CONFIG_AUDIO_I2SRX_0_TDM_FORMAT,
- PHY_DEV_FEATURE_DEF(tdm_frame) = CONFIG_AUDIO_I2SRX_0_TDM_FRAME,
- PHY_DEV_FEATURE_DEF(mclk_reverse) = CONFIG_AUDIO_I2SRX_0_MCLK_REVERSE,
- PHY_DEV_FEATURE_DEF(clk_from_i2stx) = CONFIG_AUDIO_I2SRX_0_CLK_FROM_I2STX,
- PHY_DEV_FEATURE_DEF(pcm_en) = CONFIG_AUDIO_PCMRX_0_EN,
- PHY_DEV_FEATURE_DEF(pcm_frame) = CONFIG_AUDIO_PCMRX_0_FORMART,
- PHY_DEV_FEATURE_DEF(pcm_slot) = CONFIG_AUDIO_PCMRX_0_SLOT,
- };
- #if IS_ENABLED(CONFIG_AUDIO_I2SRX_0)
- DEVICE_DEFINE(i2srx0, CONFIG_AUDIO_I2SRX_0_NAME, phy_i2srx_init, NULL,
- &phy_i2srx_drv_data0, &phy_i2srx_config_data0,
- POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS, &phy_i2srx_drv_api);
- #endif
- /*
- * @brief Enable I2SRX IRQ
- * @note I2STX IRQ source as shown below:
- * - I2STX FIFO Half Filled IRQ
- * - I2STX SRDTO IRQ
- * - I2STX SRDSR IRQ
- * - I2STX SRDCHW IRQ
- */
- static void phy_i2srx_irq_config(void)
- {
- IRQ_CONNECT(IRQ_ID_I2S1, CONFIG_AUDIO_I2SRX_0_IRQ_PRI,
- phy_i2srx_isr,
- DEVICE_GET(i2srx0), 0);
- irq_enable(IRQ_ID_I2S1);
- }
|