summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorManjula Gupta <magupta@nvidia.com>2010-12-28 15:41:58 +0530
committerBharat Nihalani <bnihalani@nvidia.com>2011-01-04 04:00:41 -0800
commit8acb4af010106dc63c41feac52d40441edb4d4f8 (patch)
tree556dee9c40a2e2ce0dab4a9a2cbe914b28702d2a /sound
parentb949927cfd131f65ef416c3c75623f63df4bb770 (diff)
[tegra ALSA] Fix Playback crash after Record
Set DAP Pinmux pins to tristate only when no dai is active. For bug: 773232 Change-Id: Icc1e6734208e6d59454e27986240d09cf19c2c7b Reviewed-on: http://git-master/r/14457 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/tegra_pcm.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 6aef41853ceb..760518b2feba 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -215,6 +215,11 @@ static int tegra_pcm_hw_free(struct snd_pcm_substream *substream)
static int tegra_pcm_prepare(struct snd_pcm_substream *substream)
{
+ struct tegra_runtime_data *prtd = substream->runtime->private_data;
+
+ prtd->dma_pos = 0;
+ prtd->period_index = 0;
+
return 0;
}
@@ -246,7 +251,8 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
prtd->state = STATE_ABORT;
- prtd->dma_state = prtd->dma_state = STATE_ABORT;
+ prtd->dma_state = STATE_ABORT;
+ tegra_dma_cancel(prtd->dma_chan);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (prtd->dma_chan) {
stop_i2s_playback();
@@ -283,6 +289,9 @@ static snd_pcm_uframes_t tegra_pcm_pointer(struct snd_pcm_substream *substream)
static int tegra_pcm_open(struct snd_pcm_substream *substream)
{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai_link *machine = rtd->dai;
+ struct snd_soc_dai *cpu_dai = machine->cpu_dai;
struct snd_pcm_runtime *runtime = substream->runtime;
struct tegra_runtime_data *prtd;
int ret=0;
@@ -363,10 +372,12 @@ fail:
tegra_dma_flush(prtd->dma_chan);
tegra_dma_free_channel(prtd->dma_chan);
}
- /* Tristate the DAP pinmux */
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_DAP1,TEGRA_TRI_TRISTATE);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_CDEV1,TEGRA_TRI_TRISTATE);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_CDEV2,TEGRA_TRI_TRISTATE);
+
+ if (cpu_dai->active == 0) {
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_DAP1,TEGRA_TRI_TRISTATE);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_CDEV1,TEGRA_TRI_TRISTATE);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_CDEV2,TEGRA_TRI_TRISTATE);
+ }
kfree(prtd);
@@ -376,6 +387,9 @@ end:
static int tegra_pcm_close(struct snd_pcm_substream *substream)
{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai_link *machine = rtd->dai;
+ struct snd_soc_dai *cpu_dai = machine->cpu_dai;
struct snd_pcm_runtime *runtime = substream->runtime;
struct tegra_runtime_data *prtd = runtime->private_data;
@@ -390,16 +404,22 @@ static int tegra_pcm_close(struct snd_pcm_substream *substream)
prtd->dma_state = STATE_EXIT;
tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req1);
tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req2);
- stop_i2s_playback();
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ stop_i2s_playback();
+ else
+ stop_i2s_capture();
tegra_dma_flush(prtd->dma_chan);
tegra_dma_free_channel(prtd->dma_chan);
prtd->dma_chan = NULL;
}
kfree(prtd);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_DAP1,TEGRA_TRI_TRISTATE);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_CDEV1,TEGRA_TRI_TRISTATE);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_CDEV2,TEGRA_TRI_TRISTATE);
+
+ if (cpu_dai->active == 0) {
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_DAP1,TEGRA_TRI_TRISTATE);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_CDEV1,TEGRA_TRI_TRISTATE);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_CDEV2,TEGRA_TRI_TRISTATE);
+ }
return 0;
}