Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c009f701 authored by Liam Girdwood's avatar Liam Girdwood Committed by Gerrit - the friendly Code Review server
Browse files

ASoC: core - add hostless DAI support



Allow DAI's to be hostless so that no PCM data is sent between DAI
and CPU. This allows for power savings as there is no DMA or CPU
interaction required.

TODO: we shouldn't need to allocate a PAGE for a dummy DMA buffer.

Change-Id: I8947f1ad2c4a7013e92e21078b35e3cad332cf6f
Signed-off-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: default avatarPatrick Lai <plai@codeaurora.org>
Git-commit: b77e8f4fb684f8afd45d4276e3dba9edd4a0c4e0
Git-repo: https://source.codeaurora.org/quic/la/kernel/msm/log/?h=msm-2.6.38


[bgoswami@codeaurora.org: fix merge conflict by moving
 code to the right source file. Fix checkpatch errors
 for line over 80 character. Fix compilation errors.]
Signed-off-by: default avatarBanajit Goswami <bgoswami@codeaurora.org>
Signed-off-by: default avatarMeng Wang <mwang@codeaurora.org>
parent 563a5071
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -380,6 +380,10 @@
#define SND_SOC_COMP_ORDER_LATE		1
#define SND_SOC_COMP_ORDER_LAST		2

/* DAI Link Host Mode Support */
#define SND_SOC_DAI_LINK_NO_HOST		0x1
#define SND_SOC_DAI_LINK_OPT_HOST		0x2

/*
 * Bias levels
 *
@@ -968,6 +972,12 @@ struct snd_soc_dai_link {
	/* This DAI link can route to other DAI links at runtime (Frontend)*/
	unsigned int dynamic:1;

	/*
	 * This DAI can support no host IO (no pcm data is
	 * copied to from host)
	 */
	unsigned int no_host_mode:2;

	/* DPCM capture and Playback support */
	unsigned int dpcm_capture:1;
	unsigned int dpcm_playback:1;
+50 −0
Original line number Diff line number Diff line
@@ -28,6 +28,25 @@

#define DPCM_MAX_BE_USERS	8

/*
 * 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,
};

/*
 * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
 *
@@ -493,6 +512,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);
@@ -1004,6 +1026,20 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
	ret = soc_pcm_params_symmetry(substream, params);
        if (ret)
		goto component_err;

	/* 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.private_data = NULL;

		ret = snd_pcm_lib_malloc_pages(substream, PAGE_SIZE);
		if (ret < 0)
			goto component_err;
	}
out:
	mutex_unlock(&rtd->pcm_mutex);
	return ret;
@@ -1086,6 +1122,8 @@ 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;
}
@@ -3105,6 +3143,18 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
		goto out;
	}

	/* 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);
	}

	/* ASoC PCM operations */
	if (rtd->dai_link->dynamic) {
		rtd->ops.open		= dpcm_fe_dai_open;