aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/omap-abe-dsp.c
diff options
context:
space:
mode:
authorSebastien Guiriec <s-guiriec@ti.com>2011-07-04 14:36:34 +0200
committerSimon Wilson <simonwilson@google.com>2011-07-10 15:44:43 -0700
commita3cbab0222616b727df2b26a9c8f985279953302 (patch)
treef4d5fe11ca0e34720cc9f2f667af0a9c076b9d64 /sound/soc/omap/omap-abe-dsp.c
parentd713edc13aa034f5f154765e5183a05b408745a2 (diff)
downloadkernel_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.c179
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;