aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dsp.c
diff options
context:
space:
mode:
authorMisael Lopez Cruz <misael.lopez@ti.com>2011-12-15 23:13:38 -0600
committerSimon Wilson <simonwilson@google.com>2012-01-17 13:46:37 -0800
commit30e477c93956e988f26deaea841a77e998acad09 (patch)
tree1803ad007eaa33ca60836ea48082b53b7b93d2fc /sound/soc/soc-dsp.c
parent9eac901ff48b70e54c7c437c1376ed06f2bef918 (diff)
downloadkernel_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.c78
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);