diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index 2d8e27b60ca6..efaa378dc36b 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -85,6 +85,8 @@ struct txrx_config { u32 rxonly; }; +struct rk_i2s_tdm_dev; + struct rk_i2s_soc_data { u32 softrst_offset; u32 grf_reg_offset; @@ -92,6 +94,7 @@ struct rk_i2s_soc_data { int config_count; const struct txrx_config *configs; int (*init)(struct device *dev, u32 addr); + void (*src_clk_ctrl)(struct rk_i2s_tdm_dev *i2s_tdm, bool en); }; struct rk_i2s_tdm_dev { @@ -126,9 +129,8 @@ struct rk_i2s_tdm_dev { struct pinctrl_state *clk_state; const struct rk_i2s_soc_data *soc_data; #ifdef HAVE_SYNC_RESET + int id; void __iomem *cru_base; - int tx_reset_id; - int rx_reset_id; #endif bool is_master_mode; bool io_multiplex; @@ -229,148 +231,146 @@ static inline bool is_dma_active(struct rk_i2s_tdm_dev *i2s_tdm, int stream) } #ifdef HAVE_SYNC_RESET -#if defined(CONFIG_ARM) && !defined(writeq) -static inline void __raw_writeq(u64 val, volatile void __iomem *addr) +static void rockchip_i2s_tdm_src_clk_ctrl(struct rk_i2s_tdm_dev *i2s_tdm, bool en, + unsigned int gate_reg, unsigned int gate_val, + unsigned int sel_reg) { - asm volatile("strd %0, %H0, [%1]" : : "r" (val), "r" (addr)); + int val = readl(i2s_tdm->cru_base + sel_reg); + + if (!gate_reg || !sel_reg) + return; + + if (IS_I2S_CLK_SRC_MCLKIN(val) && en) + writel(I2S_CLK_SRC_MCLKIN, i2s_tdm->cru_base + sel_reg); + + writel(gate_val, i2s_tdm->cru_base + gate_reg); + + if (IS_I2S_CLK_SRC_MCLKIN(val) && !en) + writel(I2S_CLK_SRC_PLL, i2s_tdm->cru_base + sel_reg); +} + +static void rockchip_i2s_tdm_px30_src_clk_ctrl(struct rk_i2s_tdm_dev *i2s_tdm, bool en) +{ + unsigned int gate_reg = 0, gate_val = 0, sel_reg = 0; + + switch (i2s_tdm->clk_trcm) { + case I2S_CKR_TRCM_TXONLY: + sel_reg = PX30_CLKSEL_CON28_I2S0_TX; + gate_reg = PX30_CLKGATE_CON9; + gate_val = en ? PX30_CLKGATE_CON9_I2S0_TX_PLL_EN : + PX30_CLKGATE_CON9_I2S0_TX_PLL_DIS; + break; + case I2S_CKR_TRCM_RXONLY: + sel_reg = PX30_CLKSEL_CON58_I2S0_RX; + gate_reg = PX30_CLKGATE_CON17; + gate_val = en ? PX30_CLKGATE_CON17_I2S0_RX_PLL_EN : + PX30_CLKGATE_CON17_I2S0_RX_PLL_DIS; + break; + } + + rockchip_i2s_tdm_src_clk_ctrl(i2s_tdm, en, gate_reg, gate_val, sel_reg); +} + +static void rockchip_i2s_tdm_rk1808_src_clk_ctrl(struct rk_i2s_tdm_dev *i2s_tdm, bool en) +{ + unsigned int gate_reg = 0, gate_val = 0, sel_reg = 0; + + switch (i2s_tdm->clk_trcm) { + case I2S_CKR_TRCM_TXONLY: + sel_reg = RK1808_CLKSEL_CON32_I2S0_TX; + gate_reg = RK1808_CLKGATE_CON17; + gate_val = en ? RK1808_CLKGATE_CON17_I2S0_TX_PLL_EN : + RK1808_CLKGATE_CON17_I2S0_TX_PLL_DIS; + break; + case I2S_CKR_TRCM_RXONLY: + sel_reg = RK1808_CLKSEL_CON34_I2S0_RX; + gate_reg = RK1808_CLKGATE_CON18; + gate_val = en ? RK1808_CLKGATE_CON18_I2S0_RX_PLL_EN : + RK1808_CLKGATE_CON18_I2S0_RX_PLL_DIS; + break; + } + + rockchip_i2s_tdm_src_clk_ctrl(i2s_tdm, en, gate_reg, gate_val, sel_reg); +} + +static void rockchip_i2s_tdm_rk3308_src_clk_ctrl(struct rk_i2s_tdm_dev *i2s_tdm, bool en) +{ + unsigned int gate_reg = 0, gate_val = 0, sel_reg = 0; + + /* I2S_8CH_2 used for internal and TRCM-none mode default */ + switch (i2s_tdm->id) { + case 0: + switch (i2s_tdm->clk_trcm) { + case I2S_CKR_TRCM_TXONLY: + sel_reg = RK3308_CLKSEL_CON52_I2S0_TX; + gate_reg = RK3308_CLKGATE_CON10; + gate_val = en ? RK3308_CLKGATE_CON10_I2S0_TX_PLL_EN : + RK3308_CLKGATE_CON10_I2S0_TX_PLL_DIS; + break; + case I2S_CKR_TRCM_RXONLY: + sel_reg = RK3308_CLKSEL_CON54_I2S0_RX; + gate_reg = RK3308_CLKGATE_CON11; + gate_val = en ? RK3308_CLKGATE_CON11_I2S0_RX_PLL_EN : + RK3308_CLKGATE_CON11_I2S0_RX_PLL_DIS; + break; + } + break; + case 1: + switch (i2s_tdm->clk_trcm) { + case I2S_CKR_TRCM_TXONLY: + sel_reg = RK3308_CLKSEL_CON56_I2S1_TX; + gate_reg = RK3308_CLKGATE_CON11; + gate_val = en ? RK3308_CLKGATE_CON11_I2S1_TX_PLL_EN : + RK3308_CLKGATE_CON11_I2S1_TX_PLL_DIS; + break; + case I2S_CKR_TRCM_RXONLY: + sel_reg = RK3308_CLKSEL_CON58_I2S1_RX; + gate_reg = RK3308_CLKGATE_CON11; + gate_val = en ? RK3308_CLKGATE_CON11_I2S1_RX_PLL_EN : + RK3308_CLKGATE_CON11_I2S1_RX_PLL_DIS; + break; + } + break; + } + + rockchip_i2s_tdm_src_clk_ctrl(i2s_tdm, en, gate_reg, gate_val, sel_reg); } -#define writeq(v,c) ({ __iowmb(); __raw_writeq((__force u64) cpu_to_le64(v), c); }) -#endif static void rockchip_i2s_tdm_reset_assert(struct rk_i2s_tdm_dev *i2s_tdm) { - int tx_bank, rx_bank, tx_offset, rx_offset, tx_id, rx_id; - void __iomem *cru_reset, *addr; - unsigned long flags; - u64 val; - if (!i2s_tdm->cru_base || !i2s_tdm->soc_data || !i2s_tdm->is_master_mode) return; - tx_id = i2s_tdm->tx_reset_id; - rx_id = i2s_tdm->rx_reset_id; - if (tx_id < 0 || rx_id < 0) + if (IS_ERR_OR_NULL(i2s_tdm->tx_reset) || IS_ERR_OR_NULL(i2s_tdm->rx_reset)) return; - tx_bank = tx_id / 16; - tx_offset = tx_id % 16; - rx_bank = rx_id / 16; - rx_offset = rx_id % 16; + reset_control_assert(i2s_tdm->tx_reset); + reset_control_assert(i2s_tdm->rx_reset); - dev_dbg(i2s_tdm->dev, - "tx_bank: %d, rx_bank: %d,tx_offset: %d, rx_offset: %d\n", - tx_bank, rx_bank, tx_offset, rx_offset); - - cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset; - - switch (abs(tx_bank - rx_bank)) { - case 0: - writel(BIT(tx_offset) | BIT(rx_offset) | - (BIT(tx_offset) << 16) | (BIT(rx_offset) << 16), - cru_reset + (tx_bank * 4)); - break; - case 1: - if (tx_bank < rx_bank) { - val = BIT(rx_offset) | (BIT(rx_offset) << 16); - val <<= 32; - val |= BIT(tx_offset) | (BIT(tx_offset) << 16); - addr = cru_reset + (tx_bank * 4); - } else { - val = BIT(tx_offset) | (BIT(tx_offset) << 16); - val <<= 32; - val |= BIT(rx_offset) | (BIT(rx_offset) << 16); - addr = cru_reset + (rx_bank * 4); - } - - if (IS_ALIGNED((uintptr_t)addr, 8)) { - writeq(val, addr); - break; - } - fallthrough; - default: - local_irq_save(flags); - writel(BIT(tx_offset) | (BIT(tx_offset) << 16), - cru_reset + (tx_bank * 4)); - writel(BIT(rx_offset) | (BIT(rx_offset) << 16), - cru_reset + (rx_bank * 4)); - local_irq_restore(flags); - break; - } /* delay for reset assert done */ udelay(10); } static void rockchip_i2s_tdm_reset_deassert(struct rk_i2s_tdm_dev *i2s_tdm) { - int tx_bank, rx_bank, tx_offset, rx_offset, tx_id, rx_id; - void __iomem *cru_reset, *addr; - unsigned long flags; - u64 val; - if (!i2s_tdm->cru_base || !i2s_tdm->soc_data || !i2s_tdm->is_master_mode) return; - tx_id = i2s_tdm->tx_reset_id; - rx_id = i2s_tdm->rx_reset_id; - if (tx_id < 0 || rx_id < 0) + if (IS_ERR_OR_NULL(i2s_tdm->tx_reset) || IS_ERR_OR_NULL(i2s_tdm->rx_reset)) return; - tx_bank = tx_id / 16; - tx_offset = tx_id % 16; - rx_bank = rx_id / 16; - rx_offset = rx_id % 16; + if (i2s_tdm->soc_data && i2s_tdm->soc_data->src_clk_ctrl) + i2s_tdm->soc_data->src_clk_ctrl(i2s_tdm, 0); - dev_dbg(i2s_tdm->dev, - "tx_bank: %d, rx_bank: %d,tx_offset: %d, rx_offset: %d\n", - tx_bank, rx_bank, tx_offset, rx_offset); + reset_control_deassert(i2s_tdm->tx_reset); + reset_control_deassert(i2s_tdm->rx_reset); - cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset; + if (i2s_tdm->soc_data && i2s_tdm->soc_data->src_clk_ctrl) + i2s_tdm->soc_data->src_clk_ctrl(i2s_tdm, 1); - switch (abs(tx_bank - rx_bank)) { - case 0: - writel((BIT(tx_offset) << 16) | (BIT(rx_offset) << 16), - cru_reset + (tx_bank * 4)); - break; - case 1: - if (tx_bank < rx_bank) { - val = (BIT(rx_offset) << 16); - val <<= 32; - val |= (BIT(tx_offset) << 16); - addr = cru_reset + (tx_bank * 4); - } else { - val = (BIT(tx_offset) << 16); - val <<= 32; - val |= (BIT(rx_offset) << 16); - addr = cru_reset + (rx_bank * 4); - } - - if (IS_ALIGNED((uintptr_t)addr, 8)) { - writeq(val, addr); - break; - } - fallthrough; - default: - local_irq_save(flags); - writel((BIT(tx_offset) << 16), - cru_reset + (tx_bank * 4)); - writel((BIT(rx_offset) << 16), - cru_reset + (rx_bank * 4)); - local_irq_restore(flags); - break; - } /* delay for reset deassert done */ udelay(10); } - -/* - * make sure both tx and rx are reset at the same time for sync lrck - * when clk_trcm > 0 - */ -static void rockchip_i2s_tdm_sync_reset(struct rk_i2s_tdm_dev *i2s_tdm) -{ - rockchip_i2s_tdm_reset_assert(i2s_tdm); - rockchip_i2s_tdm_reset_deassert(i2s_tdm); -} #else static inline void rockchip_i2s_tdm_reset_assert(struct rk_i2s_tdm_dev *i2s_tdm) { @@ -378,44 +378,35 @@ static inline void rockchip_i2s_tdm_reset_assert(struct rk_i2s_tdm_dev *i2s_tdm) static inline void rockchip_i2s_tdm_reset_deassert(struct rk_i2s_tdm_dev *i2s_tdm) { } -static inline void rockchip_i2s_tdm_sync_reset(struct rk_i2s_tdm_dev *i2s_tdm) -{ -} #endif -static void rockchip_i2s_tdm_reset(struct reset_control *rc) +static void rockchip_i2s_tdm_reset(struct rk_i2s_tdm_dev *i2s_tdm, unsigned int clr) { - if (IS_ERR_OR_NULL(rc)) - return; + if ((clr & I2S_CLR_TXC) && !IS_ERR_OR_NULL(i2s_tdm->tx_reset)) { + reset_control_assert(i2s_tdm->tx_reset); + /* delay for reset assert done */ + udelay(10); + reset_control_deassert(i2s_tdm->tx_reset); + /* delay for reset deassert done */ + udelay(10); + } - reset_control_assert(rc); - /* delay for reset assert done */ - udelay(10); - reset_control_deassert(rc); - /* delay for reset deassert done */ - udelay(10); + if ((clr & I2S_CLR_RXC) && !IS_ERR_OR_NULL(i2s_tdm->rx_reset)) { + reset_control_assert(i2s_tdm->rx_reset); + /* delay for reset assert done */ + udelay(10); + reset_control_deassert(i2s_tdm->rx_reset); + /* delay for reset deassert done */ + udelay(10); + } } static int rockchip_i2s_tdm_clear(struct rk_i2s_tdm_dev *i2s_tdm, unsigned int clr) { - struct reset_control *rst = NULL; unsigned int val = 0; int ret = 0; - switch (clr) { - case I2S_CLR_TXC: - rst = i2s_tdm->tx_reset; - break; - case I2S_CLR_RXC: - rst = i2s_tdm->rx_reset; - break; - case I2S_CLR_TXC | I2S_CLR_RXC: - break; - default: - return -EINVAL; - } - regmap_update_bits(i2s_tdm->regmap, I2S_CLR, clr, clr); ret = regmap_read_poll_timeout_atomic(i2s_tdm->regmap, I2S_CLR, val, !(val & clr), 10, 100); @@ -453,10 +444,7 @@ static int rockchip_i2s_tdm_clear(struct rk_i2s_tdm_dev *i2s_tdm, return 0; reset: - if (i2s_tdm->clk_trcm) - rockchip_i2s_tdm_sync_reset(i2s_tdm); - else - rockchip_i2s_tdm_reset(rst); + rockchip_i2s_tdm_reset(i2s_tdm, clr); return 0; } @@ -2282,6 +2270,9 @@ static const struct rk_i2s_soc_data px30_i2s_soc_data = { .configs = px30_txrx_config, .config_count = ARRAY_SIZE(px30_txrx_config), .init = common_soc_init, +#ifdef HAVE_SYNC_RESET + .src_clk_ctrl = rockchip_i2s_tdm_px30_src_clk_ctrl, +#endif }; static const struct rk_i2s_soc_data rk1808_i2s_soc_data = { @@ -2289,6 +2280,9 @@ static const struct rk_i2s_soc_data rk1808_i2s_soc_data = { .configs = rk1808_txrx_config, .config_count = ARRAY_SIZE(rk1808_txrx_config), .init = common_soc_init, +#ifdef HAVE_SYNC_RESET + .src_clk_ctrl = rockchip_i2s_tdm_rk1808_src_clk_ctrl, +#endif }; static const struct rk_i2s_soc_data rk3308_i2s_soc_data = { @@ -2298,6 +2292,9 @@ static const struct rk_i2s_soc_data rk3308_i2s_soc_data = { .configs = rk3308_txrx_config, .config_count = ARRAY_SIZE(rk3308_txrx_config), .init = common_soc_init, +#ifdef HAVE_SYNC_RESET + .src_clk_ctrl = rockchip_i2s_tdm_rk3308_src_clk_ctrl, +#endif }; static const struct rk_i2s_soc_data rk3568_i2s_soc_data = { @@ -2339,26 +2336,6 @@ static const struct of_device_id rockchip_i2s_tdm_match[] = { {}, }; -#ifdef HAVE_SYNC_RESET -static int of_i2s_resetid_get(struct device_node *node, - const char *id) -{ - struct of_phandle_args args; - int index = 0; - int ret; - - if (id) - index = of_property_match_string(node, - "reset-names", id); - ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", - index, &args); - if (ret) - return ret; - - return args.args[0]; -} -#endif - static int rockchip_i2s_tdm_dai_prepare(struct platform_device *pdev, struct snd_soc_dai_driver **soc_dai) { @@ -2878,24 +2855,6 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev) } } -#ifdef HAVE_SYNC_RESET - sync = of_device_is_compatible(node, "rockchip,px30-i2s-tdm") || - of_device_is_compatible(node, "rockchip,rk1808-i2s-tdm") || - of_device_is_compatible(node, "rockchip,rk3308-i2s-tdm"); - - if (i2s_tdm->clk_trcm && sync) { - struct device_node *cru_node; - - cru_node = of_parse_phandle(node, "rockchip,cru", 0); - i2s_tdm->cru_base = of_iomap(cru_node, 0); - if (!i2s_tdm->cru_base) - return -ENOENT; - - i2s_tdm->tx_reset_id = of_i2s_resetid_get(node, "tx-m"); - i2s_tdm->rx_reset_id = of_i2s_resetid_get(node, "rx-m"); - } -#endif - i2s_tdm->tx_reset = devm_reset_control_get(&pdev->dev, "tx-m"); if (IS_ERR(i2s_tdm->tx_reset)) { ret = PTR_ERR(i2s_tdm->tx_reset); @@ -3017,6 +2976,23 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev) return ret; } +#ifdef HAVE_SYNC_RESET + sync = of_device_is_compatible(node, "rockchip,px30-i2s-tdm") || + of_device_is_compatible(node, "rockchip,rk1808-i2s-tdm") || + of_device_is_compatible(node, "rockchip,rk3308-i2s-tdm"); + + if (i2s_tdm->clk_trcm && sync) { + struct device_node *cru_node; + + cru_node = of_parse_phandle(node, "rockchip,cru", 0); + i2s_tdm->cru_base = of_iomap(cru_node, 0); + if (!i2s_tdm->cru_base) + return -ENOENT; + + i2s_tdm->id = (res->start >> 16) & GENMASK(3, 0); + } +#endif + /* * MUST: after pm_runtime_enable step, any register R/W * should be wrapped with pm_runtime_get_sync/put. diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.h b/sound/soc/rockchip/rockchip_i2s_tdm.h index 904afe035fbd..f625cdf0ffaf 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.h +++ b/sound/soc/rockchip/rockchip_i2s_tdm.h @@ -324,7 +324,25 @@ enum { #define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16)) -/* PX30 GRF CONFIGS*/ +/* I2Sx CLK SRC Mux Common Define */ +#define I2S_CLK_SRC(v) (((v) & GENMASK(11, 10)) >> 10) +#define I2S_CLK_SRC_MCLKIN HIWORD_UPDATE(2, 11, 10) +#define I2S_CLK_SRC_PLL HIWORD_UPDATE(0, 11, 10) +#define IS_I2S_CLK_SRC_MCLKIN(v) (I2S_CLK_SRC(v) == 2) + +/* PX30 CRU CONFIGS */ +#define PX30_CLKSEL_CON28_I2S0_TX 0x170 +#define PX30_CLKSEL_CON58_I2S0_RX 0x1e8 + +#define PX30_CLKGATE_CON9 0x224 +#define PX30_CLKGATE_CON9_I2S0_TX_PLL_DIS HIWORD_UPDATE(1, 12, 12) +#define PX30_CLKGATE_CON9_I2S0_TX_PLL_EN HIWORD_UPDATE(0, 12, 12) + +#define PX30_CLKGATE_CON17 0x244 +#define PX30_CLKGATE_CON17_I2S0_RX_PLL_DIS HIWORD_UPDATE(1, 0, 0) +#define PX30_CLKGATE_CON17_I2S0_RX_PLL_EN HIWORD_UPDATE(0, 0, 0) + +/* PX30 GRF CONFIGS */ #define PX30_I2S0_CLK_IN_SRC_FROM_TX HIWORD_UPDATE(1, 13, 12) #define PX30_I2S0_CLK_IN_SRC_FROM_RX HIWORD_UPDATE(2, 13, 12) #define PX30_I2S0_MCLK_OUT_SRC_FROM_TX HIWORD_UPDATE(1, 5, 5) @@ -336,7 +354,19 @@ enum { #define PX30_I2S0_CLK_RXONLY \ (PX30_I2S0_MCLK_OUT_SRC_FROM_RX | PX30_I2S0_CLK_IN_SRC_FROM_RX) -/* RK1808 GRF CONFIGS*/ +/* RK1808 CRU CONFIGS */ +#define RK1808_CLKSEL_CON32_I2S0_TX 0x180 +#define RK1808_CLKSEL_CON34_I2S0_RX 0x188 + +#define RK1808_CLKGATE_CON17 0x274 +#define RK1808_CLKGATE_CON17_I2S0_TX_PLL_DIS HIWORD_UPDATE(1, 12, 12) +#define RK1808_CLKGATE_CON17_I2S0_TX_PLL_EN HIWORD_UPDATE(0, 12, 12) + +#define RK1808_CLKGATE_CON18 0x278 +#define RK1808_CLKGATE_CON18_I2S0_RX_PLL_DIS HIWORD_UPDATE(1, 0, 0) +#define RK1808_CLKGATE_CON18_I2S0_RX_PLL_EN HIWORD_UPDATE(0, 0, 0) + +/* RK1808 GRF CONFIGS */ #define RK1808_I2S0_MCLK_OUT_SRC_FROM_RX HIWORD_UPDATE(1, 2, 2) #define RK1808_I2S0_MCLK_OUT_SRC_FROM_TX HIWORD_UPDATE(0, 2, 2) #define RK1808_I2S0_CLK_IN_SRC_FROM_TX HIWORD_UPDATE(1, 1, 0) @@ -348,7 +378,27 @@ enum { #define RK1808_I2S0_CLK_RXONLY \ (RK1808_I2S0_MCLK_OUT_SRC_FROM_RX | RK1808_I2S0_CLK_IN_SRC_FROM_RX) -/* RK3308 GRF CONFIGS*/ +/* RK3308 CRU CONFIGS */ +#define RK3308_CLKSEL_CON52_I2S0_TX 0x1d0 +#define RK3308_CLKSEL_CON54_I2S0_RX 0x1d8 +#define RK3308_CLKSEL_CON56_I2S1_TX 0x1e0 +#define RK3308_CLKSEL_CON58_I2S1_RX 0x1e8 + +#define RK3308_CLKGATE_CON10 0x328 +#define RK3308_CLKGATE_CON10_I2S0_TX_PLL_DIS HIWORD_UPDATE(1, 12, 12) +#define RK3308_CLKGATE_CON10_I2S0_TX_PLL_EN HIWORD_UPDATE(0, 12, 12) + +#define RK3308_CLKGATE_CON11 0x32c +#define RK3308_CLKGATE_CON11_I2S0_RX_PLL_DIS HIWORD_UPDATE(1, 0, 0) +#define RK3308_CLKGATE_CON11_I2S0_RX_PLL_EN HIWORD_UPDATE(0, 0, 0) + +#define RK3308_CLKGATE_CON11_I2S1_TX_PLL_DIS HIWORD_UPDATE(1, 4, 4) +#define RK3308_CLKGATE_CON11_I2S1_TX_PLL_EN HIWORD_UPDATE(0, 4, 4) + +#define RK3308_CLKGATE_CON11_I2S1_RX_PLL_DIS HIWORD_UPDATE(1, 8, 8) +#define RK3308_CLKGATE_CON11_I2S1_RX_PLL_EN HIWORD_UPDATE(0, 8, 8) + +/* RK3308 GRF CONFIGS */ #define RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_RX HIWORD_UPDATE(1, 10, 10) #define RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_TX HIWORD_UPDATE(0, 10, 10) #define RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_TX HIWORD_UPDATE(1, 9, 9)