mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
ASoC: pcm: Add support for Hostless pcm
Hostless PCM nodes will not exchange data with the userspace clients.Control paths will be setup by userspace clients. Signed-off-by: Gopikrishnaiah Anandan <agopik@codeaurora.org>
This commit is contained in:
parent
1f42244c54
commit
0de64fbea0
3 changed files with 59 additions and 9 deletions
|
@ -413,6 +413,7 @@ struct snd_pcm_substream {
|
|||
#endif
|
||||
/* misc flags */
|
||||
unsigned int hw_opened: 1;
|
||||
unsigned int hw_no_buffer: 1; /* substream may not have a buffer */
|
||||
};
|
||||
|
||||
#define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0)
|
||||
|
|
|
@ -567,7 +567,8 @@ int snd_soc_suspend(struct device *dev)
|
|||
struct snd_soc_dai *dai = card->rtd[i].codec_dai;
|
||||
struct snd_soc_dai_driver *drv = dai->driver;
|
||||
|
||||
if (card->rtd[i].dai_link->ignore_suspend)
|
||||
if (card->rtd[i].dai_link->ignore_suspend ||
|
||||
card->rtd[i].dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
if (card->rtd[i].dai_link->dynamic)
|
||||
|
@ -580,7 +581,8 @@ int snd_soc_suspend(struct device *dev)
|
|||
|
||||
/* suspend all pcms */
|
||||
for (i = 0; i < card->num_rtd; i++) {
|
||||
if (card->rtd[i].dai_link->ignore_suspend)
|
||||
if (card->rtd[i].dai_link->ignore_suspend ||
|
||||
card->rtd[i].dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
snd_pcm_suspend_all(card->rtd[i].pcm);
|
||||
|
@ -593,7 +595,8 @@ int snd_soc_suspend(struct device *dev)
|
|||
struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
|
||||
struct snd_soc_platform *platform = card->rtd[i].platform;
|
||||
|
||||
if (card->rtd[i].dai_link->ignore_suspend)
|
||||
if (card->rtd[i].dai_link->ignore_suspend ||
|
||||
card->rtd[i].dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
if (card->rtd[i].dai_link->dynamic) {
|
||||
|
@ -618,7 +621,8 @@ int snd_soc_suspend(struct device *dev)
|
|||
for (i = 0; i < card->num_rtd; i++) {
|
||||
struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver;
|
||||
|
||||
if (card->rtd[i].dai_link->ignore_suspend)
|
||||
if (card->rtd[i].dai_link->ignore_suspend ||
|
||||
card->rtd[i].dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
if (driver->playback.stream_name != NULL)
|
||||
|
@ -652,7 +656,8 @@ int snd_soc_suspend(struct device *dev)
|
|||
for (i = 0; i < card->num_rtd; i++) {
|
||||
struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
|
||||
|
||||
if (card->rtd[i].dai_link->ignore_suspend)
|
||||
if (card->rtd[i].dai_link->ignore_suspend ||
|
||||
card->rtd[i].dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
if (card->rtd[i].dai_link->dynamic)
|
||||
|
@ -695,7 +700,8 @@ static void soc_resume_deferred(struct work_struct *work)
|
|||
for (i = 0; i < card->num_rtd; i++) {
|
||||
struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
|
||||
|
||||
if (card->rtd[i].dai_link->ignore_suspend)
|
||||
if (card->rtd[i].dai_link->ignore_suspend ||
|
||||
card->rtd[i].dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
if (card->rtd[i].dai_link->dynamic)
|
||||
|
@ -727,7 +733,8 @@ static void soc_resume_deferred(struct work_struct *work)
|
|||
for (i = 0; i < card->num_rtd; i++) {
|
||||
struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver;
|
||||
|
||||
if (card->rtd[i].dai_link->ignore_suspend)
|
||||
if (card->rtd[i].dai_link->ignore_suspend ||
|
||||
card->rtd[i].dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
if (driver->playback.stream_name != NULL)
|
||||
|
@ -744,7 +751,8 @@ static void soc_resume_deferred(struct work_struct *work)
|
|||
struct snd_soc_dai *dai = card->rtd[i].codec_dai;
|
||||
struct snd_soc_dai_driver *drv = dai->driver;
|
||||
|
||||
if (card->rtd[i].dai_link->ignore_suspend)
|
||||
if (card->rtd[i].dai_link->ignore_suspend ||
|
||||
card->rtd[i].dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
if (card->rtd[i].dai_link->dynamic)
|
||||
|
@ -759,7 +767,8 @@ static void soc_resume_deferred(struct work_struct *work)
|
|||
struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
|
||||
struct snd_soc_platform *platform = card->rtd[i].platform;
|
||||
|
||||
if (card->rtd[i].dai_link->ignore_suspend)
|
||||
if (card->rtd[i].dai_link->ignore_suspend ||
|
||||
card->rtd[i].dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
if (card->rtd[i].dai_link->dynamic) {
|
||||
|
|
|
@ -31,9 +31,29 @@
|
|||
#include <sound/soc.h>
|
||||
#include <sound/soc-dpcm.h>
|
||||
#include <sound/initval.h>
|
||||
|
||||
#define MAX_BE_USERS 8 /* adjust if too low for everday use */
|
||||
|
||||
static int soc_dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream);
|
||||
|
||||
/* ASoC no host IO hardware.
|
||||
* TODO: fine tune these values for all host less transfers.
|
||||
*/
|
||||
static const struct snd_pcm_hardware no_host_hardware = {
|
||||
.info = SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_PAUSE |
|
||||
SNDRV_PCM_INFO_RESUME,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.period_bytes_min = PAGE_SIZE >> 2,
|
||||
.period_bytes_max = PAGE_SIZE >> 1,
|
||||
.periods_min = 2,
|
||||
.periods_max = 4,
|
||||
.buffer_bytes_max = PAGE_SIZE,
|
||||
};
|
||||
|
||||
/*
|
||||
* We can only hw_free, stop, pause or suspend a BE DAI if any of it's FE
|
||||
* are not running, paused or suspended for the specified stream direction.
|
||||
|
@ -194,6 +214,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
|
|||
|
||||
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
|
||||
|
||||
if (rtd->dai_link->no_host_mode == SND_SOC_DAI_LINK_NO_HOST)
|
||||
snd_soc_set_runtime_hwparams(substream, &no_host_hardware);
|
||||
|
||||
/* startup the audio subsystem */
|
||||
if (cpu_dai->driver->ops->startup) {
|
||||
ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
|
||||
|
@ -606,6 +629,20 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
cpu_dai->rate = params_rate(params);
|
||||
codec_dai->rate = params_rate(params);
|
||||
|
||||
/* malloc a page for hostless IO.
|
||||
* FIXME: rework with alsa-lib changes so that this malloc is not required.
|
||||
*/
|
||||
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(32);
|
||||
substream->dma_buffer.private_data = NULL;
|
||||
|
||||
ret = snd_pcm_lib_malloc_pages(substream, PAGE_SIZE);
|
||||
if (ret < 0)
|
||||
goto platform_err;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&rtd->pcm_mutex);
|
||||
return ret;
|
||||
|
@ -658,6 +695,9 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
|
|||
if (cpu_dai->driver->ops->hw_free)
|
||||
cpu_dai->driver->ops->hw_free(substream, cpu_dai);
|
||||
|
||||
if (rtd->dai_link->no_host_mode == SND_SOC_DAI_LINK_NO_HOST)
|
||||
snd_pcm_lib_free_pages(substream);
|
||||
|
||||
mutex_unlock(&rtd->pcm_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue