ASoC: Tegra: Acquire wake_lock during playback capture
Sumit Bhattacharya [Wed, 7 Dec 2011 12:28:14 +0000 (17:28 +0530)]
Acquire wake_lock from alsa kernel when pcm playback/capture
starts and hold it until playack/capture ends. It is needed
to prevent device from going into suspend state in middle
of audio playback.

Change-Id: I71e5fae0268f73a3e57f8d886c1b228d46899ea4
Signed-off-by: Sumit Bhattacharya <sumitb@nvidia.com>
Reviewed-on: http://git-master/r/68671
Reviewed-by: Nikesh Oswal <noswal@nvidia.com>
Reviewed-by: Scott Peterson <speterson@nvidia.com>

Rebase-Id: R6fea7e61615ca45f612e462c5aa58ec40f6eb979

sound/soc/tegra/tegra_pcm.c
sound/soc/tegra/tegra_pcm.h

index 3730d44..f9b9529 100644 (file)
@@ -177,6 +177,15 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
        if (ret < 0)
                goto err;
 
+#ifdef CONFIG_HAS_WAKELOCK
+       snprintf(prtd->tegra_wake_lock_name, sizeof(prtd->tegra_wake_lock_name),
+               "tegra-pcm-%s-%d",
+               (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "out" : "in",
+               substream->pcm->device);
+       wake_lock_init(&prtd->tegra_wake_lock, WAKE_LOCK_SUSPEND,
+               prtd->tegra_wake_lock_name);
+#endif
+
        return 0;
 
 err:
@@ -194,6 +203,10 @@ static int tegra_pcm_close(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct tegra_runtime_data *prtd = runtime->private_data;
 
+#ifdef CONFIG_HAS_WAKELOCK
+       wake_lock_destroy(&prtd->tegra_wake_lock);
+#endif
+
        if (prtd->dma_chan)
                tegra_dma_free_channel(prtd->dma_chan);
 
@@ -250,6 +263,9 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
                /* Fall-through */
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+#ifdef CONFIG_HAS_WAKELOCK
+       wake_lock(&prtd->tegra_wake_lock);
+#endif
                spin_lock_irqsave(&prtd->lock, flags);
                prtd->running = 1;
                spin_unlock_irqrestore(&prtd->lock, flags);
@@ -264,6 +280,10 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
                spin_unlock_irqrestore(&prtd->lock, flags);
                tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[0]);
                tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[1]);
+
+#ifdef CONFIG_HAS_WAKELOCK
+               wake_unlock(&prtd->tegra_wake_lock);
+#endif
                break;
        default:
                return -EINVAL;
index dbb9033..883c979 100644 (file)
 
 #include <mach/dma.h>
 
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#endif
+
 struct tegra_pcm_dma_params {
        unsigned long addr;
        unsigned long wrap;
@@ -50,6 +54,10 @@ struct tegra_runtime_data {
        int dma_req_idx;
        struct tegra_dma_req dma_req[2];
        struct tegra_dma_channel *dma_chan;
+#ifdef CONFIG_HAS_WAKELOCK
+       struct wake_lock tegra_wake_lock;
+       char tegra_wake_lock_name[32];
+#endif
 };
 
 #endif