ASoC: msm: Add support for flexible period size and count

Add support for flexible period size and count for audio playback path.

Change-Id: Ide5b504054e9eee5c1ffee60b889446919aeb7f4
Signed-off-by: Honghao Liu <honghaol@codeaurora.org>
This commit is contained in:
Honghao Liu 2015-07-17 11:31:24 -04:00 committed by Artem Borisov
parent eb02886309
commit ed3e1345c9
1 changed files with 34 additions and 31 deletions

View File

@ -39,12 +39,14 @@ struct snd_msm {
struct snd_pcm *pcm;
};
#define PLAYBACK_NUM_PERIODS 8
#define PLAYBACK_PERIOD_SIZE 2048
#define CAPTURE_MIN_NUM_PERIODS 2
#define CAPTURE_MAX_NUM_PERIODS 16
#define CAPTURE_MAX_PERIOD_SIZE 4096
#define CAPTURE_MIN_PERIOD_SIZE 320
#define PLAYBACK_MIN_NUM_PERIODS 2
#define PLAYBACK_MAX_NUM_PERIODS 8
#define PLAYBACK_MIN_PERIOD_SIZE 128
#define PLAYBACK_MAX_PERIOD_SIZE 12288
#define CAPTURE_MIN_NUM_PERIODS 2
#define CAPTURE_MAX_NUM_PERIODS 16
#define CAPTURE_MAX_PERIOD_SIZE 4096
#define CAPTURE_MIN_PERIOD_SIZE 320
static struct snd_pcm_hardware msm_pcm_hardware_capture = {
.info = (SNDRV_PCM_INFO_MMAP |
@ -79,11 +81,12 @@ static struct snd_pcm_hardware msm_pcm_hardware_playback = {
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = PLAYBACK_NUM_PERIODS * PLAYBACK_PERIOD_SIZE,
.period_bytes_min = PLAYBACK_PERIOD_SIZE,
.period_bytes_max = PLAYBACK_PERIOD_SIZE,
.periods_min = PLAYBACK_NUM_PERIODS,
.periods_max = PLAYBACK_NUM_PERIODS,
.buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS *
PLAYBACK_MAX_PERIOD_SIZE,
.period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
.period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
.periods_min = PLAYBACK_MIN_NUM_PERIODS,
.periods_max = PLAYBACK_MAX_NUM_PERIODS,
.fifo_size = 0,
};
@ -397,6 +400,16 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
if (ret < 0)
pr_err("snd_pcm_hw_constraint_integer failed\n");
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = snd_pcm_hw_constraint_minmax(runtime,
SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE,
PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE);
if (ret < 0) {
pr_err("constraint for buffer bytes min max ret = %d\n",
ret);
}
}
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
ret = snd_pcm_hw_constraint_minmax(runtime,
@ -711,21 +724,15 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
substream->stream, event);
}
if (dir == OUT) {
ret = q6asm_audio_client_buf_alloc_contiguous(dir,
prtd->audio_client,
(params_buffer_bytes(params) / params_periods(params)),
params_periods(params));
pr_debug("buff bytes = %d, period size = %d,\
period count = %d\n", params_buffer_bytes(params),
params_periods(params),
params_buffer_bytes(params) / params_periods(params));
} else {
ret = q6asm_audio_client_buf_alloc_contiguous(dir,
prtd->audio_client,
runtime->hw.period_bytes_min,
runtime->hw.periods_max);
}
ret = q6asm_audio_client_buf_alloc_contiguous(dir,
prtd->audio_client,
(params_buffer_bytes(params) / params_periods(params)),
params_periods(params));
pr_debug("buff bytes = %d, period count = %d, period size = %d\n",
params_buffer_bytes(params),
params_periods(params),
params_buffer_bytes(params) / params_periods(params));
if (ret < 0) {
pr_err("Audio Start: Buffer Allocation failed \
@ -742,11 +749,7 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
dma_buf->private_data = NULL;
dma_buf->area = buf[0].data;
dma_buf->addr = buf[0].phys;
dma_buf->bytes = runtime->hw.buffer_bytes_max;
if (dir == IN)
dma_buf->bytes = runtime->hw.buffer_bytes_max;
else
dma_buf->bytes = params_buffer_bytes(params);
dma_buf->bytes = params_buffer_bytes(params);
if (!dma_buf->area)
return -ENOMEM;