summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2016-05-18 09:46:35 -0400
committerMark Brown <broonie@kernel.org>2016-05-30 11:19:17 -0400
commit4a5c83744feb7608422e6c23fa4cce85569b678c (patch)
tree2ea89ba8b6eda2086d3459986cb75b1831b0dd4b
parent0efecc086caa1fa12b941ca55cf24e1b4d4e59b8 (diff)
ASoC: omap-mcpdm: Support for suspend resume
Implement ASoC's suspend and resume callbacks. Since McPDM does not use pcm_trigger for start and stop of the stream due to strict sequencing needs with the twl6040, the callbacks will stop and restart the McPDM in case the board suspended during audio activity. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/omap/omap-mcpdm.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 11bd07cdce22..74d6e6fdcfd0 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -66,6 +66,9 @@ struct omap_mcpdm {
66 /* McPDM needs to be restarted due to runtime reconfiguration */ 66 /* McPDM needs to be restarted due to runtime reconfiguration */
67 bool restart; 67 bool restart;
68 68
69 /* pm state for suspend/resume handling */
70 int pm_active_count;
71
69 struct snd_dmaengine_dai_dma_data dma_data[2]; 72 struct snd_dmaengine_dai_dma_data dma_data[2];
70}; 73};
71 74
@@ -422,12 +425,55 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
422 return 0; 425 return 0;
423} 426}
424 427
428#ifdef CONFIG_PM_SLEEP
429static int omap_mcpdm_suspend(struct snd_soc_dai *dai)
430{
431 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
432
433 if (dai->active) {
434 omap_mcpdm_stop(mcpdm);
435 omap_mcpdm_close_streams(mcpdm);
436 }
437
438 mcpdm->pm_active_count = 0;
439 while (pm_runtime_active(mcpdm->dev)) {
440 pm_runtime_put_sync(mcpdm->dev);
441 mcpdm->pm_active_count++;
442 }
443
444 return 0;
445}
446
447static int omap_mcpdm_resume(struct snd_soc_dai *dai)
448{
449 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
450
451 if (mcpdm->pm_active_count) {
452 while (mcpdm->pm_active_count--)
453 pm_runtime_get_sync(mcpdm->dev);
454
455 if (dai->active) {
456 omap_mcpdm_open_streams(mcpdm);
457 omap_mcpdm_start(mcpdm);
458 }
459 }
460
461
462 return 0;
463}
464#else
465#define omap_mcpdm_suspend NULL
466#define omap_mcpdm_resume NULL
467#endif
468
425#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 469#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
426#define OMAP_MCPDM_FORMATS SNDRV_PCM_FMTBIT_S32_LE 470#define OMAP_MCPDM_FORMATS SNDRV_PCM_FMTBIT_S32_LE
427 471
428static struct snd_soc_dai_driver omap_mcpdm_dai = { 472static struct snd_soc_dai_driver omap_mcpdm_dai = {
429 .probe = omap_mcpdm_probe, 473 .probe = omap_mcpdm_probe,
430 .remove = omap_mcpdm_remove, 474 .remove = omap_mcpdm_remove,
475 .suspend = omap_mcpdm_suspend,
476 .resume = omap_mcpdm_resume,
431 .probe_order = SND_SOC_COMP_ORDER_LATE, 477 .probe_order = SND_SOC_COMP_ORDER_LATE,
432 .remove_order = SND_SOC_COMP_ORDER_EARLY, 478 .remove_order = SND_SOC_COMP_ORDER_EARLY,
433 .playback = { 479 .playback = {