ASoC: msm: Flexible period size for pcm playback
PCM driver was configured for fixed buffer size on the playback path. With this, varying the buffer sizes on the playback path was not possible. To fix this, support for flexible period sizes is added by setting different values for min and max buffer sizes Signed-off-by: Alexy Joseph <alexyj@codeaurora.org> Signed-off-by: Mekala Natarajan <mekalan@codeaurora.org>
This commit is contained in:
@@ -39,11 +39,12 @@ struct snd_msm {
|
||||
struct snd_pcm *pcm;
|
||||
};
|
||||
|
||||
#define PLAYBACK_NUM_PERIODS 8
|
||||
#define PLAYBACK_PERIOD_SIZE 2048
|
||||
#define CAPTURE_NUM_PERIODS 2
|
||||
#define CAPTURE_MAX_PERIOD_SIZE 4096
|
||||
#define CAPTURE_MIN_PERIOD_SIZE 320
|
||||
#define PLAYBACK_NUM_PERIODS 8
|
||||
#define PLAYBACK_MAX_PERIOD_SIZE 4096
|
||||
#define PLAYBACK_MIN_PERIOD_SIZE 1024
|
||||
#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 |
|
||||
@@ -77,9 +78,9 @@ 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,
|
||||
.buffer_bytes_max = PLAYBACK_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
|
||||
.period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
|
||||
.period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
|
||||
.periods_min = PLAYBACK_NUM_PERIODS,
|
||||
.periods_max = PLAYBACK_NUM_PERIODS,
|
||||
.fifo_size = 0,
|
||||
@@ -362,6 +363,17 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
|
||||
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_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE,
|
||||
PLAYBACK_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,
|
||||
SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
|
||||
@@ -668,18 +680,10 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
prtd->session_id, substream->stream);
|
||||
}
|
||||
|
||||
if (dir == OUT) {
|
||||
ret = q6asm_audio_client_buf_alloc_contiguous(dir,
|
||||
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);
|
||||
}
|
||||
|
||||
params_periods(params));
|
||||
if (ret < 0) {
|
||||
pr_err("Audio Start: Buffer Allocation failed \
|
||||
rc = %d\n", ret);
|
||||
@@ -696,10 +700,7 @@ 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);
|
||||
dma_buf->bytes = params_buffer_bytes(params);
|
||||
|
||||
if (!dma_buf->area)
|
||||
return -ENOMEM;
|
||||
|
||||
Reference in New Issue
Block a user