static int davinci_pcm_prepare(struct snd_pcm_substream *substream) { struct davinci_runtime_data *prtd = substream->runtime->private_data; davinci_pcm_period_reset(substream); if (prtd->ram_channel >= 0) { int ret = ping_pong_dma_setup(substream); if (ret < 0) return ret; edma_write_slot(prtd->ram_channel, &prtd->ram_params); edma_write_slot(prtd->asp_channel, &prtd->asp_params); print_buf_info(prtd->ram_channel, "ram_channel"); print_buf_info(prtd->ram_link, "ram_link"); print_buf_info(prtd->ram_link2, "ram_link2"); print_buf_info(prtd->asp_channel, "asp_channel"); print_buf_info(prtd->asp_link[0], "asp_link[0]"); print_buf_info(prtd->asp_link[1], "asp_link[1]"); /* * There is a phase offset of 2 periods between the position * used by dma setup and the position reported in the pointer * function. * * The phase offset, when not using ping-pong buffers, is due to * the two consecutive calls to davinci_pcm_enqueue_dma() below. * * Whereas here, with ping-pong buffers, the phase is due to * there being an entire buffer transfer complete before the * first dma completion event triggers davinci_pcm_dma_irq(). */ davinci_pcm_period_elapsed(substream); davinci_pcm_period_elapsed(substream); return 0; } davinci_pcm_enqueue_dma(substream); davinci_pcm_period_elapsed(substream); /* Copy self-linked parameter RAM entry into master channel */ edma_read_slot(prtd->asp_link[0], &prtd->asp_params); edma_write_slot(prtd->asp_channel, &prtd->asp_params); davinci_pcm_enqueue_dma(substream); davinci_pcm_period_elapsed(substream); return 0; }
static int davinci_pcm_prepare(struct snd_pcm_substream *substream) { struct davinci_runtime_data *prtd = substream->runtime->private_data; if (prtd->ram_channel >= 0) { int ret = ping_pong_dma_setup(substream); if (ret < 0) return ret; edma_write_slot(prtd->ram_channel, &prtd->ram_params); edma_write_slot(prtd->asp_channel, &prtd->asp_params); print_buf_info(prtd->ram_channel, "ram_channel"); print_buf_info(prtd->ram_link, "ram_link"); print_buf_info(prtd->ram_link2, "ram_link2"); print_buf_info(prtd->asp_channel, "asp_channel"); print_buf_info(prtd->asp_link[0], "asp_link[0]"); print_buf_info(prtd->asp_link[1], "asp_link[1]"); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* copy 1st iram buffer */ edma_start(prtd->ram_channel); } edma_start(prtd->asp_channel); return 0; } prtd->period = 0; davinci_pcm_enqueue_dma(substream); /* Copy self-linked parameter RAM entry into master channel */ edma_read_slot(prtd->asp_link[0], &prtd->asp_params); edma_write_slot(prtd->asp_channel, &prtd->asp_params); davinci_pcm_enqueue_dma(substream); edma_start(prtd->asp_channel); return 0; }