aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/omap-mcpdm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/omap/omap-mcpdm.c')
-rw-r--r--sound/soc/omap/omap-mcpdm.c65
1 files changed, 16 insertions, 49 deletions
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index c56f38a..ea2081f 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -64,7 +64,6 @@ struct omap_mcpdm {
unsigned long phys_base;
void __iomem *io_base;
int irq;
- struct delayed_work delayed_work;
struct mutex mutex;
struct omap_mcpdm_platform_data *pdata;
@@ -77,7 +76,6 @@ struct omap_mcpdm {
u32 dn_channels;
u32 up_channels;
int active;
- int powered;
int abe_mode;
/* DC offset */
@@ -364,27 +362,19 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
dev_dbg(dai->dev, "%s: active %d\n", __func__, dai->active);
- /* make sure we stop any pre-existing shutdown */
- cancel_delayed_work_sync(&mcpdm->delayed_work);
-
mutex_lock(&mcpdm->mutex);
+ /* nothing to do if already active */
+ if (mcpdm->active++)
+ goto out;
+
if (dai->id >= MCPDM_ABE_DAI_DL1)
mcpdm->abe_mode = 1;
else
mcpdm->abe_mode = 0;
- /* nothing to do if already active */
- if (mcpdm->active++ || mcpdm->powered)
- goto out;
-
pm_runtime_get_sync(mcpdm->dev);
- if (mcpdm->abe_mode)
- abe_dsp_pm_get();
-
- mcpdm->powered = 1;
-
/* Enable McPDM watch dog for ES above ES 1.0 to avoid saturation */
if (omap_rev() != OMAP4430_REV_ES1_0) {
ctrl = omap_mcpdm_read(mcpdm, MCPDM_CTRL);
@@ -399,60 +389,38 @@ out:
return err;
}
-/* work to delay McPDM shutdown */
-static void playback_work(struct work_struct *work)
+static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
{
- struct omap_mcpdm *mcpdm =
- container_of(work, struct omap_mcpdm, delayed_work.work);
+ struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
+
+ dev_dbg(dai->dev, "%s: active %d\n", __func__, dai->active);
mutex_lock(&mcpdm->mutex);
- /*
- * still active or another stream started while
- * delayed work was waiting for execution
- */
- if (!mcpdm->powered || mcpdm->active)
+ if (--mcpdm->active)
goto out;
- /* ABE playback stop handled by delayed work */
if (mcpdm->abe_mode) {
if (omap_mcpdm_active(mcpdm)) {
omap_abe_port_disable(mcpdm->abe, mcpdm->dl_port);
omap_abe_port_disable(mcpdm->abe, mcpdm->ul_port);
udelay(250);
+ abe_remove_opp_req(mcpdm->dev);
omap_mcpdm_stop(mcpdm);
}
- omap_mcpdm_close(mcpdm);
- abe_dsp_shutdown();
- abe_dsp_pm_put();
} else {
omap_mcpdm_stop(mcpdm);
- omap_mcpdm_close(mcpdm);
}
+ omap_mcpdm_close(mcpdm);
+
pm_runtime_put_sync(mcpdm->dev);
- mcpdm->powered = 0;
out:
mutex_unlock(&mcpdm->mutex);
}
-static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
-
- dev_dbg(dai->dev, "%s: active %d\n", __func__, dai->active);
-
- mutex_lock(&mcpdm->mutex);
-
- if (!--mcpdm->active)
- schedule_delayed_work(&mcpdm->delayed_work,
- msecs_to_jiffies(1000)); /* TODO: pdata ? */
-
- mutex_unlock(&mcpdm->mutex);
-}
-
static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -519,6 +487,9 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
omap_abe_port_is_enabled(mcpdm->abe, mcpdm->dl_port))
goto out;
+ /* PDM tasks require ABE OPP 50 */
+ abe_add_opp_req(mcpdm->dev, ABE_OPP_50);
+
/* start ATC before McPDM IP */
omap_abe_port_enable(mcpdm->abe, mcpdm->dl_port);
omap_abe_port_enable(mcpdm->abe, mcpdm->ul_port);
@@ -728,8 +699,6 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
if (err < 0)
dev_err(mcpdm->dev,"failed to DL2 DC offset sysfs: %d\n", err);
- INIT_DELAYED_WORK(&mcpdm->delayed_work, playback_work);
-
#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP) ||\
defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
@@ -776,8 +745,6 @@ static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev);
struct resource *res;
- flush_delayed_work_sync(&mcpdm->delayed_work);
-
snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(omap_mcpdm_dai));
device_remove_file(&pdev->dev, &dev_attr_dl1);