From 645bb4d43978ab2bb3a8abd6721e45223c224eb0 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Tue, 10 Jan 2017 17:28:14 -0800 Subject: [PATCH] ANDROID: GKI: ASoC: pcm: Add support for hostless playback/capture For playback/capture usecases in which host doesn't exchange PCM data, audio driver creates hostless pcm devices. This change squashes the below changes added to support hostless pcm usecases- ASoC: core: Add support for no host mode ASoC: core: Update DMA mask for hostless pcm devices ASoC: pcm: increase the hostless buffer size soc: pcm: add arch_setup_dma_ops call Test: build Bug: 151372815 Change-Id: I82574c88847bcb9aa1a495c3690bba7f4e461979 Signed-off-by: Gopikrishnaiah Anandan Signed-off-by: Neema Shetty Signed-off-by: Vidyakumar Athota Signed-off-by: Anish Kumar Signed-off-by: Shiv Maliyappanahalli Signed-off-by: Sudheer Papothi Signed-off-by: Banajit Goswami Signed-off-by: Meng Wang (cherry picked from commit f156bb58247dfbfb91a6f5579f41b07e3c5e5b8b) Signed-off-by: Hridya Valsaraju --- include/sound/soc.h | 1 + sound/soc/soc-pcm.c | 46 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index f213d39d7c3c..b62ca5e46cff 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -743,6 +743,7 @@ struct snd_soc_pcm_stream { unsigned int channels_min; /* min channels */ unsigned int channels_max; /* max channels */ unsigned int sig_bits; /* number of bits of content */ + const char *aif_name; /* DAPM AIF widget name */ }; /* SoC audio ops */ diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index d07d323d8dcb..028157522aa6 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,12 @@ static const struct snd_pcm_hardware no_host_hardware = { .period_bytes_max = PAGE_SIZE >> 1, .periods_min = 2, .periods_max = 4, - .buffer_bytes_max = PAGE_SIZE, + /* + * Increase the max buffer bytes as PAGE_SIZE bytes is + * not enough to encompass all the scenarios sent by + * userspapce. + */ + .buffer_bytes_max = PAGE_SIZE * 4, }; /* @@ -173,6 +179,8 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, const struct snd_pcm_hardware *hw) { struct snd_pcm_runtime *runtime = substream->runtime; + if (!runtime) + return 0; runtime->hw.info = hw->info; runtime->hw.formats = hw->formats; runtime->hw.period_bytes_min = hw->period_bytes_min; @@ -945,6 +953,17 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, int i, ret = 0; mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); + + /* perform any hw_params fixups */ + if ((rtd->dai_link->no_host_mode == SND_SOC_DAI_LINK_NO_HOST) && + rtd->dai_link->be_hw_params_fixup) { + ret = rtd->dai_link->be_hw_params_fixup(rtd, + params); + if (ret < 0) + dev_err(rtd->card->dev, "ASoC: fixup failed for %s\n", + rtd->dai_link->name); + } + if (rtd->dai_link->ops->hw_params) { ret = rtd->dai_link->ops->hw_params(substream, params); if (ret < 0) { @@ -1037,8 +1056,12 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, if (rtd->dai_link->no_host_mode == SND_SOC_DAI_LINK_NO_HOST) { substream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV; substream->dma_buffer.dev.dev = rtd->dev; + substream->dma_buffer.dev.dev->coherent_dma_mask = + DMA_BIT_MASK(sizeof(dma_addr_t) * 8); substream->dma_buffer.private_data = NULL; + arch_setup_dma_ops(substream->dma_buffer.dev.dev, + 0, 0, NULL, 0); ret = snd_pcm_lib_malloc_pages(substream, PAGE_SIZE); if (ret < 0) goto component_err; @@ -3116,6 +3139,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) struct snd_soc_component *component; struct snd_soc_rtdcom_list *rtdcom; struct snd_pcm *pcm; + struct snd_pcm_str *stream; char new_name[64]; int ret = 0, playback = 0, capture = 0; int i; @@ -3190,14 +3214,18 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) /* setup any hostless PCMs - i.e. no host IO is performed */ if (rtd->dai_link->no_host_mode) { - pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->hw_no_buffer = 1; - pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->hw_no_buffer = 1; - snd_soc_set_runtime_hwparams( - pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, - &no_host_hardware); - snd_soc_set_runtime_hwparams( - pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, - &no_host_hardware); + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { + stream = &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]; + stream->substream->hw_no_buffer = 1; + snd_soc_set_runtime_hwparams(stream->substream, + &no_host_hardware); + } + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { + stream = &pcm->streams[SNDRV_PCM_STREAM_CAPTURE]; + stream->substream->hw_no_buffer = 1; + snd_soc_set_runtime_hwparams(stream->substream, + &no_host_hardware); + } } /* ASoC PCM operations */