diff options
author | Misael Lopez Cruz <misael.lopez@ti.com> | 2011-12-15 23:13:38 -0600 |
---|---|---|
committer | Simon Wilson <simonwilson@google.com> | 2012-01-17 13:46:37 -0800 |
commit | 30e477c93956e988f26deaea841a77e998acad09 (patch) | |
tree | 1803ad007eaa33ca60836ea48082b53b7b93d2fc /sound/soc/soc-dsp.c | |
parent | 9eac901ff48b70e54c7c437c1376ed06f2bef918 (diff) | |
download | kernel_samsung_tuna-30e477c93956e988f26deaea841a77e998acad09.zip kernel_samsung_tuna-30e477c93956e988f26deaea841a77e998acad09.tar.gz kernel_samsung_tuna-30e477c93956e988f26deaea841a77e998acad09.tar.bz2 |
ASoC: DSP: Split runtime startup/shutdown updates
A FE->BE-1 link can transition to FE->BE-2 in a single widget/kcontrol
change (e.g. Muxes). Currently, DSP framework searches for new and old
paths of the FE, and then perform the startup/shutdown runtime updates.
The single-step FE->BE-1 to FE->BE-2 transition has both: new and old
paths to be updated, hence BE-1 and BE-2 will be marked for runtime
update. However, startup and shutdown updates will both be performed
on BE-1 and BE-2, which is incorect as it would be expected to run
startup update on BE-2 and shutdown update on BE-1.
In order to handle these scenarios, the path search (new and old) is
performed along with its runtime update (startup and shutdown).
Change-Id: I5a687d6fcc51a968d9b0ae52d749935a92f00ef7
Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
Signed-off-by: Liam Girdwood <lrg@ti.com>
Diffstat (limited to 'sound/soc/soc-dsp.c')
-rw-r--r-- | sound/soc/soc-dsp.c | 78 |
1 files changed, 37 insertions, 41 deletions
diff --git a/sound/soc/soc-dsp.c b/sound/soc/soc-dsp.c index ab36c55..c04b24a 100644 --- a/sound/soc/soc-dsp.c +++ b/sound/soc/soc-dsp.c @@ -1107,27 +1107,27 @@ disconnect: return ret; } -static int dsp_run_update(struct snd_soc_pcm_runtime *fe, int stream, - int start, int stop) +static int dsp_run_new_update(struct snd_soc_pcm_runtime *fe, int stream) { - int ret = 0; + int ret; fe->dsp[stream].runtime_update = SND_SOC_DSP_UPDATE_BE; + ret = dsp_run_update_startup(fe, stream); + if (ret < 0) + dev_err(&fe->dev, "failed to startup some BEs\n"); + fe->dsp[stream].runtime_update = SND_SOC_DSP_UPDATE_NO; - /* startup any new BEs */ - if (start) { - ret = dsp_run_update_startup(fe, stream); - if (ret < 0) - dev_err(&fe->dev, "failed to startup BEs\n"); - } + return ret; +} - /* close down old BEs */ - if (stop) { - ret = dsp_run_update_shutdown(fe, stream); - if (ret < 0) - dev_err(&fe->dev, "failed to shutdown BEs\n"); - } +static int dsp_run_old_update(struct snd_soc_pcm_runtime *fe, int stream) +{ + int ret; + fe->dsp[stream].runtime_update = SND_SOC_DSP_UPDATE_BE; + ret = dsp_run_update_shutdown(fe, stream); + if (ret < 0) + dev_err(&fe->dev, "failed to shutdown some BEs\n"); fe->dsp[stream].runtime_update = SND_SOC_DSP_UPDATE_NO; return ret; @@ -1167,44 +1167,40 @@ int soc_dsp_runtime_update(struct snd_soc_dapm_widget *widget) if (!fe->cpu_dai->driver->playback.channels_min) goto capture; - /* update any playback paths */ + /* update new playback paths */ start = dsp_add_new_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, 1); - stop = dsp_prune_old_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, 1); - if (!(start || stop)) - goto capture; - - /* run PCM ops on new/old playback paths */ - ret = dsp_run_update(fe, SNDRV_PCM_STREAM_PLAYBACK, start, stop); - if (ret < 0) { - dev_err(&fe->dev, "failed to update playback FE stream %s\n", - fe->dai_link->stream_name); + if (start) { + dsp_run_new_update(fe, SNDRV_PCM_STREAM_PLAYBACK); + fe_clear_pending(fe, SNDRV_PCM_STREAM_PLAYBACK); } - /* free old playback links */ - fe_clear_pending(fe, SNDRV_PCM_STREAM_PLAYBACK); - be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK); + /* update old playback paths */ + stop = dsp_prune_old_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, 1); + if (stop) { + dsp_run_old_update(fe, SNDRV_PCM_STREAM_PLAYBACK); + fe_clear_pending(fe, SNDRV_PCM_STREAM_PLAYBACK); + be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK); + } capture: /* skip if FE doesn't have capture capability */ if (!fe->cpu_dai->driver->capture.channels_min) continue; - /* update any capture paths */ + /* update new capture paths */ start = dsp_add_new_paths(fe, SNDRV_PCM_STREAM_CAPTURE, 1); - stop = dsp_prune_old_paths(fe, SNDRV_PCM_STREAM_CAPTURE, 1); - if (!(start || stop)) - continue; - - /* run PCM ops on new/old capture paths */ - ret = dsp_run_update(fe, SNDRV_PCM_STREAM_CAPTURE, start, stop); - if (ret < 0) { - dev_err(&fe->dev, "failed to update capture FE stream %s\n", - fe->dai_link->stream_name); + if (start) { + dsp_run_new_update(fe, SNDRV_PCM_STREAM_CAPTURE); + fe_clear_pending(fe, SNDRV_PCM_STREAM_CAPTURE); } - /* free old capture links */ - fe_clear_pending(fe, SNDRV_PCM_STREAM_CAPTURE); - be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE); + /* update old capture paths */ + stop = dsp_prune_old_paths(fe, SNDRV_PCM_STREAM_CAPTURE, 1); + if (stop) { + dsp_run_old_update(fe, SNDRV_PCM_STREAM_CAPTURE); + fe_clear_pending(fe, SNDRV_PCM_STREAM_CAPTURE); + be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE); + } } mutex_unlock(&widget->dapm->card->dsp_mutex); |