From b2bcc108d0c7fdb229a3853269527f0f95ef396e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E8=94=A1=E6=9E=AB?= Date: Fri, 5 Aug 2011 11:28:25 +0800 Subject: [PATCH] reset tx and rx when stop tx or rx --- sound/soc/rk29/rk29_i2s.c | 138 +++++++++++++++++++++----------------- 1 file changed, 76 insertions(+), 62 deletions(-) diff --git a/sound/soc/rk29/rk29_i2s.c b/sound/soc/rk29/rk29_i2s.c index 358eb57b89db..c94cd0568ed0 100755 --- a/sound/soc/rk29/rk29_i2s.c +++ b/sound/soc/rk29/rk29_i2s.c @@ -128,87 +128,101 @@ static int flag_i2s_tx = 0; static int flag_i2s_rx = 0; static void rockchip_snd_txctrl(struct rk29_i2s_info *i2s, int on) { - u32 opr,xfer,fifosts; - - opr = readl(&(pheadi2s->I2S_DMACR)); - xfer = readl(&(pheadi2s->I2S_XFER)); - - opr &= ~I2S_TRAN_DMA_ENABLE; - xfer &= ~I2S_RX_TRAN_START; - xfer &= ~I2S_TX_TRAN_START; - - if (on) - { - I2S_DBG("rockchip_snd_txctrl: on\n"); - - //stop tx - if ((flag_i2s_rx == 0) && (flag_i2s_tx == 0)) - writel(xfer, &(pheadi2s->I2S_XFER)); - writel(opr, &(pheadi2s->I2S_DMACR)); - - //start tx - opr |= I2S_TRAN_DMA_ENABLE; - xfer |= I2S_TX_TRAN_START; - xfer |= I2S_RX_TRAN_START; - writel(opr, &(pheadi2s->I2S_DMACR)); - writel(xfer, &(pheadi2s->I2S_XFER)); - - flag_i2s_tx = 1; - } - else - { - //stop tx - flag_i2s_tx = 0; - - if ((flag_i2s_rx == 0) && (flag_i2s_tx == 0)) - writel(xfer, &(pheadi2s->I2S_XFER)); - udelay(5); - writel(opr, &(pheadi2s->I2S_DMACR)); + u32 opr,xfer; + + opr = readl(&(pheadi2s->I2S_DMACR)); + xfer = readl(&(pheadi2s->I2S_XFER)); + + if (on) + { + I2S_DBG("rockchip_snd_txctrl: on\n"); + + //start tx + if ((flag_i2s_tx == 0) && (flag_i2s_rx == 0)) + { + //if start tx & rx clk, need reset i2s + xfer |= I2S_TX_TRAN_START; + xfer |= I2S_RX_TRAN_START; + writel(xfer, &(pheadi2s->I2S_XFER)); + } + + if ((opr & I2S_TRAN_DMA_ENABLE) == 0) + { + opr |= I2S_TRAN_DMA_ENABLE; + writel(opr, &(pheadi2s->I2S_DMACR)); + } + + flag_i2s_tx = 1; + } + else + { + //stop tx + + flag_i2s_tx = 0; + if ((flag_i2s_rx == 0) && (flag_i2s_tx == 0)) + { + opr &= ~I2S_TRAN_DMA_ENABLE; + writel(opr, &(pheadi2s->I2S_DMACR)); + + xfer &= ~I2S_RX_TRAN_START; + xfer &= ~I2S_TX_TRAN_START; + writel(xfer, &(pheadi2s->I2S_XFER)); - I2S_DBG("rockchip_snd_txctrl: off\n"); - } + //after stop rx & tx clk, reset i2s + writel(0x001,&(pheadi2s->I2S_TXRST)); + writel(0x001,&(pheadi2s->I2S_RXRST)); + } + + I2S_DBG("rockchip_snd_txctrl: off\n"); + } } static void rockchip_snd_rxctrl(struct rk29_i2s_info *i2s, int on) { - u32 opr,xfer,fifosts; - + u32 opr,xfer; opr = readl(&(pheadi2s->I2S_DMACR)); xfer = readl(&(pheadi2s->I2S_XFER)); - opr &= ~I2S_RECE_DMA_ENABLE; - xfer &= ~I2S_RX_TRAN_START; - xfer &= ~I2S_TX_TRAN_START; if (on) { I2S_DBG("rockchip_snd_rxctrl: on\n"); - //stop rx - if ((flag_i2s_rx == 0) && (flag_i2s_tx == 0)) - writel(xfer, &(pheadi2s->I2S_XFER)); - writel(opr, &(pheadi2s->I2S_DMACR)); - //start rx - opr |= I2S_RECE_DMA_ENABLE; - xfer |= I2S_TX_TRAN_START; - xfer |= I2S_RX_TRAN_START; - writel(opr, &(pheadi2s->I2S_DMACR)); - writel(xfer, &(pheadi2s->I2S_XFER)); + if ((flag_i2s_tx == 0) && (flag_i2s_rx == 0)) + { + xfer |= I2S_TX_TRAN_START; + xfer |= I2S_RX_TRAN_START; + writel(xfer, &(pheadi2s->I2S_XFER)); + } + + if ((opr & I2S_RECE_DMA_ENABLE) == 0) + { + opr |= I2S_RECE_DMA_ENABLE; + writel(opr, &(pheadi2s->I2S_DMACR)); + } - flag_i2s_rx = 1; + flag_i2s_rx = 1; } else { //stop rx - flag_i2s_rx = 0; - - if ((flag_i2s_rx == 0) && (flag_i2s_tx == 0)) - writel(xfer, &(pheadi2s->I2S_XFER)); - udelay(5); - writel(opr, &(pheadi2s->I2S_DMACR)); - - I2S_DBG("rockchip_snd_rxctrl: off\n"); + flag_i2s_rx = 0; + if ((flag_i2s_rx == 0) && (flag_i2s_tx == 0)) + { + opr &= ~I2S_RECE_DMA_ENABLE; + writel(opr, &(pheadi2s->I2S_DMACR)); + + xfer &= ~I2S_RX_TRAN_START; + xfer &= ~I2S_TX_TRAN_START; + writel(xfer, &(pheadi2s->I2S_XFER)); + + //after stop rx & tx clk, reset i2s + writel(0x001,&(pheadi2s->I2S_TXRST)); + writel(0x001,&(pheadi2s->I2S_RXRST)); + } + + I2S_DBG("rockchip_snd_rxctrl: off\n"); } } -- 2.34.1