diff options
author | Sebastien Guiriec <s-guiriec@ti.com> | 2011-07-04 14:36:34 +0200 |
---|---|---|
committer | Simon Wilson <simonwilson@google.com> | 2011-07-10 15:44:43 -0700 |
commit | a3cbab0222616b727df2b26a9c8f985279953302 (patch) | |
tree | f4d5fe11ca0e34720cc9f2f667af0a9c076b9d64 /sound/soc/omap/omap-abe-dsp.c | |
parent | d713edc13aa034f5f154765e5183a05b408745a2 (diff) | |
download | kernel_samsung_tuna-a3cbab0222616b727df2b26a9c8f985279953302.zip kernel_samsung_tuna-a3cbab0222616b727df2b26a9c8f985279953302.tar.gz kernel_samsung_tuna-a3cbab0222616b727df2b26a9c8f985279953302.tar.bz2 |
ASoC: OMAP ABE: Add context save/restore
Add context save/restore to ABE DSP driver.
Signed-off-by: Sebastien Guiriec <s-guiriec@ti.com>
Signed-off-by: PankajJindal <pankajjindal@ti.com>
Diffstat (limited to 'sound/soc/omap/omap-abe-dsp.c')
-rw-r--r-- | sound/soc/omap/omap-abe-dsp.c | 179 |
1 files changed, 110 insertions, 69 deletions
diff --git a/sound/soc/omap/omap-abe-dsp.c b/sound/soc/omap/omap-abe-dsp.c index d2112ca..b5c7e8a 100644 --- a/sound/soc/omap/omap-abe-dsp.c +++ b/sound/soc/omap/omap-abe-dsp.c @@ -1728,14 +1728,11 @@ static const struct snd_pcm_hardware omap_abe_hardware = { .buffer_bytes_max = 24 * 1024 * 2, }; -static int aess_set_runtime_opp_level(struct abe_data *abe) + +static int abe_set_opp_mode(struct abe_data *abe) { int i, opp = 0; - mutex_lock(&abe->opp_mutex); - - pm_runtime_get_sync(abe->dev); - /* now calculate OPP level based upon DAPM widget status */ for (i = 0; i < ABE_NUM_WIDGETS; i++) { if (abe->widget_opp[ABE_WIDGET(i)]) { @@ -1782,6 +1779,15 @@ static int aess_set_runtime_opp_level(struct abe_data *abe) abe->opp = opp; dev_dbg(abe->dev, "new OPP level is %d\n", opp); + return 0; +} + +static int aess_set_runtime_opp_level(struct abe_data *abe) +{ + mutex_lock(&abe->opp_mutex); + + pm_runtime_get_sync(abe->dev); + abe_set_opp_mode(abe); pm_runtime_put_sync(abe->dev); mutex_unlock(&abe->opp_mutex); @@ -1789,6 +1795,95 @@ static int aess_set_runtime_opp_level(struct abe_data *abe) return 0; } +static int aess_save_context(struct abe_data *abe) +{ + struct omap4_abe_dsp_pdata *pdata = abe->abe_pdata; + + /* TODO: Find a better way to save/retore gains after OFF mode */ + + abe_mute_gain(MIXSDT, MIX_SDT_INPUT_UP_MIXER); + abe_mute_gain(MIXSDT, MIX_SDT_INPUT_DL1_MIXER); + abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_MM_DL); + abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_TONES); + abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_UPLINK); + abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_VX_DL); + abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_TONES); + abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_DL); + abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_MM_DL); + abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_UL); + abe_mute_gain(MIXDL1, MIX_DL1_INPUT_MM_DL); + abe_mute_gain(MIXDL1, MIX_DL1_INPUT_MM_UL2); + abe_mute_gain(MIXDL1, MIX_DL1_INPUT_VX_DL); + abe_mute_gain(MIXDL1, MIX_DL1_INPUT_TONES); + abe_mute_gain(MIXDL2, MIX_DL2_INPUT_TONES); + abe_mute_gain(MIXDL2, MIX_DL2_INPUT_VX_DL); + abe_mute_gain(MIXDL2, MIX_DL2_INPUT_MM_DL); + abe_mute_gain(MIXDL2, MIX_DL2_INPUT_MM_UL2); + abe_mute_gain(MIXECHO, MIX_ECHO_DL1); + abe_mute_gain(MIXECHO, MIX_ECHO_DL2); + abe_mute_gain(GAINS_DMIC1, GAIN_LEFT_OFFSET); + abe_mute_gain(GAINS_DMIC1, GAIN_RIGHT_OFFSET); + abe_mute_gain(GAINS_DMIC2, GAIN_LEFT_OFFSET); + abe_mute_gain(GAINS_DMIC2, GAIN_RIGHT_OFFSET); + abe_mute_gain(GAINS_DMIC3, GAIN_LEFT_OFFSET); + abe_mute_gain(GAINS_DMIC3, GAIN_RIGHT_OFFSET); + abe_mute_gain(GAINS_AMIC, GAIN_LEFT_OFFSET); + abe_mute_gain(GAINS_AMIC, GAIN_RIGHT_OFFSET); + + if (pdata->get_context_loss_count) + abe->loss_count = pdata->get_context_loss_count(abe->dev); + + return 0; +} + +static int aess_restore_context(struct abe_data *abe) +{ + struct omap4_abe_dsp_pdata *pdata = abe->abe_pdata; + int loss_count = 0; + + omap_device_set_rate(&abe->dev, &abe->dev, 98000000); + + if (pdata->get_context_loss_count) + loss_count = pdata->get_context_loss_count(abe->dev); + + if (loss_count != the_abe->loss_count) + abe_reload_fw(); + + /* TODO: Find a better way to save/retore gains after dor OFF mode */ + abe_unmute_gain(MIXSDT, MIX_SDT_INPUT_UP_MIXER); + abe_unmute_gain(MIXSDT, MIX_SDT_INPUT_DL1_MIXER); + abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_MM_DL); + abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_TONES); + abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_UPLINK); + abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_VX_DL); + abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_TONES); + abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_DL); + abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_MM_DL); + abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_UL); + abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_MM_DL); + abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_MM_UL2); + abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_VX_DL); + abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_TONES); + abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_TONES); + abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_VX_DL); + abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_MM_DL); + abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_MM_UL2); + abe_unmute_gain(MIXECHO, MIX_ECHO_DL1); + abe_unmute_gain(MIXECHO, MIX_ECHO_DL2); + abe_unmute_gain(GAINS_DMIC1, GAIN_LEFT_OFFSET); + abe_unmute_gain(GAINS_DMIC1, GAIN_RIGHT_OFFSET); + abe_unmute_gain(GAINS_DMIC2, GAIN_LEFT_OFFSET); + abe_unmute_gain(GAINS_DMIC2, GAIN_RIGHT_OFFSET); + abe_unmute_gain(GAINS_DMIC3, GAIN_LEFT_OFFSET); + abe_unmute_gain(GAINS_DMIC3, GAIN_RIGHT_OFFSET); + abe_unmute_gain(GAINS_AMIC, GAIN_LEFT_OFFSET); + abe_unmute_gain(GAINS_AMIC, GAIN_RIGHT_OFFSET); + + abe_set_router_configuration(UPROUTE, 0, (u32 *)abe->router); + + return 0; +} + static int aess_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -1803,8 +1898,12 @@ static int aess_open(struct snd_pcm_substream *substream) pm_runtime_get_sync(abe->dev); - if (!abe->active++) + if (!abe->active++) { + abe->opp = 0; + aess_restore_context(abe); + abe_set_opp_mode(abe); abe_wakeup(); + } switch (dai->id) { case ABE_FRONTEND_DAI_MODEM: @@ -1904,10 +2003,12 @@ static int aess_close(struct snd_pcm_substream *substream) if (!--abe->active) { abe_disable_irq(); + aess_save_context(abe); abe_dsp_shutdown(); - pm_runtime_put_sync(abe->dev); } + pm_runtime_put_sync(abe->dev); + mutex_unlock(&abe->mutex); return 0; } @@ -1962,84 +2063,24 @@ static struct snd_pcm_ops omap_aess_pcm_ops = { static int aess_suspend(struct device *dev) { struct abe_data *abe = dev_get_drvdata(dev); - struct omap4_abe_dsp_pdata *pdata = abe->abe_pdata; pm_runtime_get_sync(abe->dev); - if (abe->active && abe_check_activity()) { - dev_dbg(abe->dev, "Suspend in a middle of ABE activity!\n"); - goto no_suspend; - } + aess_save_context(abe); - /* TODO: Find a better way to save/retore gains after dor OFF mode */ - abe_mute_gain(MIXSDT, MIX_SDT_INPUT_UP_MIXER); - abe_mute_gain(MIXSDT, MIX_SDT_INPUT_DL1_MIXER); - abe_mute_gain(MIXECHO, MIX_ECHO_DL1); - abe_mute_gain(MIXECHO, MIX_ECHO_DL2); - abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_MM_DL); - abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_TONES); - abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_UPLINK); - abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_VX_DL); - abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_TONES); - abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_DL); - abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_MM_DL); - abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_UL); - -no_suspend: pm_runtime_put_sync(abe->dev); - /* - * force setting OPP after suspend/resume to ensure - * ABE freq/volt are set to proper values - */ - abe->opp = 0; - - if (pdata->get_context_loss_count) - abe->loss_count = pdata->get_context_loss_count(dev); - return 0; } static int aess_resume(struct device *dev) { struct abe_data *abe = dev_get_drvdata(dev); - struct omap4_abe_dsp_pdata *pdata = abe->abe_pdata; - int loss_count = 0; - - if (pdata->get_context_loss_count) - loss_count = pdata->get_context_loss_count(dev); pm_runtime_get_sync(abe->dev); - if (abe->active && abe_check_activity()) { - dev_dbg(abe->dev, "Resume in a middle of ABE activity!\n"); - goto no_resume; - } - - if (loss_count != abe->loss_count) - abe_reload_fw(); + aess_restore_context(abe); - /* TODO: Find a better way to save/retore gains after dor OFF mode */ - abe_unmute_gain(MIXSDT, MIX_SDT_INPUT_UP_MIXER); - abe_unmute_gain(MIXSDT, MIX_SDT_INPUT_DL1_MIXER); - abe_unmute_gain(MIXECHO, MIX_ECHO_DL1); - abe_unmute_gain(MIXECHO, MIX_ECHO_DL2); - abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_MM_DL); - abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_TONES); - abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_UPLINK); - abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_VX_DL); - abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_TONES); - abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_DL); - abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_MM_DL); - abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_UL); -// abe_dsp_set_equalizer(EQ1, abe->dl1_equ_profile); -// abe_dsp_set_equalizer(EQ2L, abe->dl20_equ_profile); -// abe_dsp_set_equalizer(EQ2R, abe->dl21_equ_profile); -// abe_dsp_set_equalizer(EQAMIC, abe->amic_equ_profile); -// abe_dsp_set_equalizer(EQDMIC, abe->dmic_equ_profile); -// abe_dsp_set_equalizer(EQSDT, abe->sdt_equ_profile); - -no_resume: pm_runtime_put_sync(abe->dev); return 0; |