static void musb_sysdma_completion(int lch, u16 ch_status, void *data) { u32 addr; unsigned long flags; struct dma_channel *channel; struct musb_dma_channel *musb_channel = (struct musb_dma_channel *) data; struct musb_dma_controller *controller = musb_channel->controller; struct musb *musb = controller->private_data; void __iomem *mbase = controller->base; channel = &musb_channel->channel; DBG(2, "lch = 0x%d, ch_status = 0x%x\n", lch, ch_status); spin_lock_irqsave(&musb->lock, flags); if (musb_channel->transmit) addr = (u32) omap_get_dma_src_pos(musb_channel->sysdma_channel); else addr = (u32) omap_get_dma_dst_pos(musb_channel->sysdma_channel); if (musb_channel->len == 0) channel->actual_len = 0; else channel->actual_len = addr - musb_channel->start_addr; DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n", channel, musb_channel->start_addr, addr, channel->actual_len, musb_channel->len, (channel->actual_len < musb_channel->len) ? "=> reconfig 0 " : " => complete"); channel->status = MUSB_DMA_STATUS_FREE; /* completed */ if ((musb_channel->transmit) && (channel->desired_mode == 0) && (channel->actual_len == musb_channel->max_packet_sz)) { u8 epnum = musb_channel->epnum; int offset = MUSB_EP_OFFSET(musb, epnum, MUSB_TXCSR); u16 txcsr; /* * The programming guide says that we * must clear DMAENAB before DMAMODE. */ musb_ep_select(musb, mbase, epnum); txcsr = musb_readw(mbase, offset); txcsr |= MUSB_TXCSR_TXPKTRDY; musb_writew(mbase, offset, txcsr); } musb_dma_completion(musb, musb_channel->epnum, musb_channel->transmit); spin_unlock_irqrestore(&musb->lock, flags); return; }
static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct omap_runtime_data *prtd = runtime->private_data; dma_addr_t ptr; snd_pcm_uframes_t offset; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ptr = omap_get_dma_src_pos(prtd->dma_ch); else ptr = omap_get_dma_dst_pos(prtd->dma_ch); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); if (offset >= runtime->buffer_size) offset = 0; return offset; }
/*************************************************************************************** * * Get the dma posn * **************************************************************************************/ u_int audio_get_dma_pos(audio_stream_t * s) { audio_buf_t *b = &s->buffers[s->dma_tail]; u_int offset; FN_IN; if (b->dma_ref) { offset = omap_get_dma_src_pos(s->lch[s->dma_q_head]) - b->dma_addr; if (offset >= s->fragsize) offset = s->fragsize - 4; } else if (s->pending_frags) { offset = b->offset; } else { offset = 0; } FN_OUT(offset); return offset; }
static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct omap_runtime_data *prtd = runtime->private_data; dma_addr_t ptr; snd_pcm_uframes_t offset; if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { ptr = omap_get_dma_dst_pos(prtd->dma_ch); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); } else if (!(cpu_is_omap1510())) { ptr = omap_get_dma_src_pos(prtd->dma_ch); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); } else offset = prtd->period_index * runtime->period_size; if (offset >= runtime->buffer_size) offset = 0; return offset; }