From 34822909bd95327a6903fd4a466a30ea38683fb0 Mon Sep 17 00:00:00 2001 From: Sumit Bhattacharya Date: Mon, 20 Feb 2012 18:53:23 +0530 Subject: ASOC: Tegra: Fix Tegra20 BT SCO playback/record Set I2s FIFO attention level based on sample size and channel count. Also set playback DMA destination bus width and capture DMA source bus width based on sample size. These changes are needed to have proper BT SCO playback and record which uses 16bit-mono format. Bug 934101 Bug 874428 Bug 927978 Signed-off-by: Sumit Bhattacharya Reviewed-on: http://git-master/r/84817 (cherry picked from commit 3ca2eb665af450d7e8f3bf6f2471e31203052641) Change-Id: I95c10716eaa990adb8b6ae535ce6acfca122a609 Reviewed-on: http://git-master/r/87192 Tested-by: Sumit Bhattacharya Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra20_i2s.c | 16 +++++++++++++--- sound/soc/tegra/tegra_pcm.c | 20 ++++++++++++-------- 2 files changed, 25 insertions(+), 11 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index c8682302b4aa..9ebe36795b07 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -249,9 +249,14 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg); - tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, - TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | - TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); + if (sample_size * params_channels(params) >= 32) + tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, + TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | + TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); + else + tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, + TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS | + TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS); i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK; reg = tegra20_i2s_read(i2s, TEGRA20_I2S_PCM_CTRL); @@ -263,12 +268,17 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, else i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO_FORMAT_32; + i2s->capture_dma_data.width = sample_size; + i2s->playback_dma_data.width = sample_size; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) reg |= TEGRA20_I2S_PCM_CTRL_TRM_MODE_EN; else reg |= TEGRA20_I2S_PCM_CTRL_RCV_MODE_EN; } else { i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED; + i2s->capture_dma_data.width = 32; + i2s->playback_dma_data.width = 32; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) reg &= ~TEGRA20_I2S_PCM_CTRL_TRM_MODE_EN; else diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 3eab18cfe864..f277d282fbd4 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -150,14 +150,6 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); if (dmap) { - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - setup_dma_tx_request(&prtd->dma_req[0], dmap); - setup_dma_tx_request(&prtd->dma_req[1], dmap); - } else { - setup_dma_rx_request(&prtd->dma_req[0], dmap); - setup_dma_rx_request(&prtd->dma_req[1], dmap); - } - prtd->dma_req[0].dev = prtd; prtd->dma_req[1].dev = prtd; @@ -215,9 +207,21 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; struct tegra_runtime_data *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct tegra_pcm_dma_params * dmap; snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + if (dmap) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + setup_dma_tx_request(&prtd->dma_req[0], dmap); + setup_dma_tx_request(&prtd->dma_req[1], dmap); + } else { + setup_dma_rx_request(&prtd->dma_req[0], dmap); + setup_dma_rx_request(&prtd->dma_req[1], dmap); + } + } prtd->dma_req[0].size = params_period_bytes(params); prtd->dma_req[1].size = prtd->dma_req[0].size; -- cgit v1.2.3