msm-pcm-q6: Add support for flexible recording period size

- Current implementation supports only fixed buffer size
  of 320 bytes only for audio recording. This results in
  performance overhead for recording at higher sample rate.
- Added support for flexible period size so that user can
  use larger buffers for recording at higher sample rates.

Signed-off-by: SathishKumar Mani<smani@codeaurora.org>
Signed-off-by: Iliyan Malchev <malchev@google.com>
This commit is contained in:
SathishKumar Mani 2012-09-21 20:41:23 -07:00 committed by Iliyan Malchev
parent 3aa5b914d3
commit d44697e328

View file

@ -41,8 +41,9 @@ struct snd_msm {
#define PLAYBACK_NUM_PERIODS 8
#define PLAYBACK_PERIOD_SIZE 4096
#define CAPTURE_NUM_PERIODS 16
#define CAPTURE_PERIOD_SIZE 320
#define CAPTURE_NUM_PERIODS 2
#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 |
@ -56,9 +57,9 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = {
.rate_max = 48000,
.channels_min = 1,
.channels_max = 4,
.buffer_bytes_max = CAPTURE_NUM_PERIODS * CAPTURE_PERIOD_SIZE,
.period_bytes_min = CAPTURE_PERIOD_SIZE,
.period_bytes_max = CAPTURE_PERIOD_SIZE,
.buffer_bytes_max = CAPTURE_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
.period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
.period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
.periods_min = CAPTURE_NUM_PERIODS,
.periods_max = CAPTURE_NUM_PERIODS,
.fifo_size = 0,
@ -353,12 +354,24 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
SNDRV_PCM_HW_PARAM_RATE,
&constraints_sample_rates);
if (ret < 0)
pr_info("snd_pcm_hw_constraint_list failed\n");
pr_err("snd_pcm_hw_constraint_list failed\n");
/* Ensure that buffer size is a multiple of period size */
ret = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0)
pr_info("snd_pcm_hw_constraint_integer failed\n");
pr_err("snd_pcm_hw_constraint_integer failed\n");
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
ret = snd_pcm_hw_constraint_minmax(runtime,
SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
CAPTURE_NUM_PERIODS * CAPTURE_MIN_PERIOD_SIZE,
CAPTURE_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE);
if (ret < 0) {
pr_err("constraint for buffer bytes min max ret = %d\n",
ret);
}
}
prtd->dsp_cnt = 0;
runtime->private_data = prtd;
@ -655,10 +668,18 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
prtd->session_id, substream->stream);
}
ret = q6asm_audio_client_buf_alloc_contiguous(dir,
if (dir == OUT) {
ret = q6asm_audio_client_buf_alloc_contiguous(dir,
prtd->audio_client,
(params_buffer_bytes(params) / params_periods(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);
}
if (ret < 0) {
pr_err("Audio Start: Buffer Allocation failed \
rc = %d\n", ret);
@ -675,6 +696,11 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
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);
if (!dma_buf->area)
return -ENOMEM;