diff options
Diffstat (limited to 'sound/soc/omap/omap-mcpdm.c')
-rw-r--r-- | sound/soc/omap/omap-mcpdm.c | 65 |
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); |