prtd->dma_data = dma_data;
err = omap_request_dma(dma_data->dma_req, dma_data->name,
omap_pcm_dma_irq, substream, &prtd->dma_ch);
- if (!cpu_is_omap1510()) {
+ if (!err & !cpu_is_omap1510()) {
/*
* Link channel with itself so DMA doesn't need any
* reprogramming while looping the buffer
dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC;
dma_params.src_start = runtime->dma_addr;
dma_params.dst_start = dma_data->port_addr;
+ dma_params.dst_port = OMAP_DMA_PORT_MPUI;
} else {
dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT;
dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
dma_params.src_start = dma_data->port_addr;
dma_params.dst_start = runtime->dma_addr;
+ dma_params.src_port = OMAP_DMA_PORT_MPUI;
}
/*
* Set DMA transfer frame size equal to ALSA period size and frame
omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
+ /*
+ * To handle realtime streaming sources properly, we need to be sure
+ * we have at least 2 periods of size larger than FIFO in the buffer
+ * to start playing without underflowing. This is because DMA is always
+ * ahead of playback by amount close to FIFO size and needs to have
+ * next period ready when previous one finishes transfering to FIFO.
+ */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
+ runtime->periods > 1) {
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ int *mcbsp_bus_id = rtd->dai->cpu_dai->private_data;
+ int fifo_samples = (*mcbsp_bus_id == 1) ? 1024 : 256;
+ int period_samples, period_frames;
+
+ period_samples = bytes_to_samples(runtime,
+ snd_pcm_lib_period_bytes(substream));
+ if (period_samples < fifo_samples + runtime->channels)
+ period_samples = fifo_samples + runtime->channels;
+ period_frames = bytes_to_frames(runtime,
+ samples_to_bytes(runtime, period_samples)) * 2;
+
+ if (runtime->start_threshold < period_frames)
+ runtime->start_threshold = period_frames;
+ }
+
return 0;
}
if (ret < 0)
goto out;
- prtd = kzalloc(sizeof(prtd), GFP_KERNEL);
+ prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
if (prtd == NULL) {
ret = -ENOMEM;
goto out;