static inline snd_pcm_uframes_t
snd_em8300_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream,
					 snd_em8300_pcm_indirect_t *rec, unsigned int ptr)
{
	int bytes = ptr - rec->hw_io;
	if (bytes < 0)
		bytes += rec->hw_buffer_size;
	rec->hw_io = ptr;
	rec->hw_ready -= bytes;
	rec->sw_io += bytes;
	if (rec->sw_io >= rec->sw_buffer_size)
		rec->sw_io -= rec->sw_buffer_size;
	if (substream->ops->ack)
		substream->ops->ack(substream);
	return bytes_to_frames(substream->runtime, rec->sw_io);
}
Exemple #2
0
static snd_pcm_uframes_t at91_pcm_pointer(
	struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct at91_runtime_data *prtd = runtime->private_data;
	struct at91_pcm_dma_params *params = prtd->params;
	dma_addr_t ptr;
	snd_pcm_uframes_t x;

	ptr = (dma_addr_t) at91_ssc_read(params->ssc_base + params->pdc->xpr);
	x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);

	if (x == runtime->buffer_size)
		x = 0;
	return x;
}
/* pointer callback */
static snd_pcm_uframes_t
snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;

	audio_info(" .. IN\n");

	audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0,
		      frames_to_bytes(runtime, runtime->status->hw_ptr),
		      frames_to_bytes(runtime, runtime->control->appl_ptr),
		      alsa_stream->pos);

	audio_info(" .. OUT\n");
	return bytes_to_frames(runtime, alsa_stream->pos);
}
static snd_pcm_uframes_t
pxa3xx_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct pxa3xx_runtime_data *prtd = runtime->private_data;
	dma_addr_t ptr;
	snd_pcm_uframes_t x;

	ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
			 DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
	x = bytes_to_frames(runtime, ptr - runtime->dma_addr);

	if (x == runtime->buffer_size)
		x = 0;
	return x;
}
Exemple #5
0
/* Called in atomic context with IRQ disabled */
static snd_pcm_uframes_t
snd_ad1889_playback_pointer(struct snd_pcm_substream *ss)
{
	size_t ptr = 0;
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);

	if (unlikely(!(chip->wave.reg & AD_DS_WSMC_WAEN)))
		return 0;

	ptr = ad1889_readl(chip, AD_DMA_WAVCA);
	ptr -= chip->wave.addr;
	
	snd_assert((ptr >= 0) && (ptr < chip->wave.size), return 0);
	
	return bytes_to_frames(ss->runtime, ptr);
}
Exemple #6
0
/* Called in atomic context with IRQ disabled */
static snd_pcm_uframes_t
snd_ad1889_capture_pointer(struct snd_pcm_substream *ss)
{
	size_t ptr = 0;
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);

	if (unlikely(!(chip->ramc.reg & AD_DS_RAMC_ADEN)))
		return 0;

	ptr = ad1889_readl(chip, AD_DMA_ADCCA);
	ptr -= chip->ramc.addr;

	snd_assert((ptr >= 0) && (ptr < chip->ramc.size), return 0);
	
	return bytes_to_frames(ss->runtime, ptr);
}
Exemple #7
0
static snd_pcm_uframes_t ath79_pcm_pointer(struct snd_pcm_substream *ss)
{
	struct snd_pcm_runtime *runtime = ss->runtime;
	struct ath79_pcm_rt_priv *rtpriv;
	snd_pcm_uframes_t ret = 0;

	rtpriv = runtime->private_data;

	if(rtpriv->last_played == NULL)
		ret = 0;
	else
		ret = rtpriv->last_played->BufPtr - runtime->dma_addr;

	ret = bytes_to_frames(runtime, ret);
	return ret;
}
Exemple #8
0
static snd_pcm_uframes_t
s3c_dma_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s3c24xx_runtime_data *prtd = runtime->private_data;
	unsigned long res;
	dma_addr_t src, dst;

	pr_debug("Entered %s\n", __func__);

	spin_lock(&prtd->lock);
	s3c2410_dma_getposition(prtd->params->channel, &src, &dst);

	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
		res = dst - prtd->dma_start;
	else
		res = src - prtd->dma_start;

	spin_unlock(&prtd->lock);

	pr_debug("Pointer %x %x\n", src, dst);

	/* we seem to be getting the odd error from the pcm library due
	 * to out-of-bounds pointers. this is maybe due to the dma engine
	 * not having loaded the new values for the channel before being
	 * callled... (todo - fix )
	 */

/* To fix the pcm buffer underrun in case of high busy state ( ex. Starting broswer ) 2010.06.22*/
	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 
	{
		if (res >= snd_pcm_lib_buffer_bytes(substream) * ANDROID_BUF_NUM) {
			if (res == snd_pcm_lib_buffer_bytes(substream) * ANDROID_BUF_NUM)
				res = 0;
		}
	} 
	else 
	{
		if (res >= snd_pcm_lib_buffer_bytes(substream)) {
			if (res == snd_pcm_lib_buffer_bytes(substream))
				res = 0;
		}
	}

	return bytes_to_frames(substream->runtime, res);
}
Exemple #9
0
static snd_pcm_uframes_t
atmel_abdac_pointer(struct snd_pcm_substream *substream)
{
	struct atmel_abdac	*dac = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime	*runtime = substream->runtime;
	snd_pcm_uframes_t	frames;
	unsigned long		bytes;

	bytes = dw_dma_get_src_addr(dac->dma.chan);
	bytes -= runtime->dma_addr;

	frames = bytes_to_frames(runtime, bytes);
	if (frames >= runtime->buffer_size)
		frames -= runtime->buffer_size;

	return frames;
}
Exemple #10
0
static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct hsw_priv_data *pdata =
		snd_soc_platform_get_drvdata(rtd->platform);
	struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
	struct sst_hsw *hsw = pdata->hsw;
	snd_pcm_uframes_t offset;

	offset = bytes_to_frames(runtime,
		sst_hsw_get_dsp_position(hsw, pcm_data->stream));

	dev_dbg(rtd->dev, "PCM: DMA pointer %zu bytes\n",
		frames_to_bytes(runtime, (u32)offset));
	return offset;
}
static snd_pcm_uframes_t
idma_pointer(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    struct idma_ctrl *prtd = runtime->private_data;
    dma_addr_t src;
    unsigned long res;

    spin_lock(&prtd->lock);

    idma_getpos(&src);
    res = src - prtd->start;

    spin_unlock(&prtd->lock);

    return bytes_to_frames(substream->runtime, res);
}
/**
 * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation
 * @substream: PCM substream
 *
 * This function can be used as the PCM pointer callback for dmaengine based PCM
 * driver implementations.
 */
snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
	struct dma_tx_state state;
	enum dma_status status;
	unsigned int buf_size;
	unsigned int pos = 0;

	status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
	if (status == DMA_IN_PROGRESS || status == DMA_PAUSED) {
		buf_size = snd_pcm_lib_buffer_bytes(substream);
		if (state.residue > 0 && state.residue <= buf_size)
			pos = buf_size - state.residue;
	}

	return bytes_to_frames(substream->runtime, pos);
}
Exemple #13
0
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;
}
/* pointer callback */
static snd_pcm_uframes_t snd_vortex_pcm_pointer(snd_pcm_substream_t * substream)
{
	vortex_t *chip = snd_pcm_substream_chip(substream);
	stream_t *stream = (stream_t *) substream->runtime->private_data;
	int dma = stream->dma;
	snd_pcm_uframes_t current_ptr = 0;

	spin_lock(&chip->lock);
	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
		current_ptr = vortex_adbdma_getlinearpos(chip, dma);
#ifndef CHIP_AU8810
	else
		current_ptr = vortex_wtdma_getlinearpos(chip, dma);
#endif
	//printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr);
	spin_unlock(&chip->lock);
	return (bytes_to_frames(substream->runtime, current_ptr));
}
Exemple #15
0
/*
 * report current pointer
 */
static snd_pcm_uframes_t snd_ps3_pcm_pointer(
	struct snd_pcm_substream *substream)
{
	struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
	size_t bytes;
	snd_pcm_uframes_t ret;

	spin_lock(&card->dma_lock);
	{
		bytes = (size_t)(card->dma_last_transfer_vaddr[SND_PS3_CH_L] -
				 card->dma_start_vaddr[SND_PS3_CH_L]);
	}
	spin_unlock(&card->dma_lock);

	ret = bytes_to_frames(substream->runtime, bytes * 2);

	return ret;
};
static snd_pcm_uframes_t
cns3xxx_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct cns3xxx_runtime_data *prtd = runtime->private_data;

	dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
			            DMAC_READ_CHREGS (prtd->dma_ch, PL330_SA) : 
                        DMAC_READ_CHREGS (prtd->dma_ch, PL330_DA) ;
	snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);

#ifdef __DEBUG_PATH
//	printk("%s=>%d\n", __FUNCTION__, __LINE__);
#endif
//	static int dumponce = 1;
//
//    if(dumponce)
//		{
//    	int counter = 0;
//    	unsigned char *pBuf = (unsigned char *)__bus_to_virt(runtime->dma_addr);
//    	
//    	if(*pBuf) {
//    	printk("\n>>>>>>>>>> Dump Sound Buffer 11 <<<<<<<<<<<<\n");
//    	for(counter=0; counter<128; counter++) {
//    		if((counter%16 == 0) && counter)
//    			printk("\n");
//    		printk("%02X  ", *(pBuf+counter));
//    	}
// 			printk("\n");
//    	dumponce = 0;
//    	}
//    }

    //printk ("%s:Transmitted %d frame [sa:%x;da:%x]\n",__FUNCTION__,(int)x,DMAC_READ_CHREGS(prtd->dma_ch,PL330_SA),DMAC_READ_CHREGS(prtd->dma_ch,PL330_DA));

	if (x >= runtime->buffer_size)
    {
//#ifdef CNS3XXX_AUDIO_DEBUG
        //printk ("Transmitted all the frames [%d in total]\n",(int)x);
//#endif
		x = 0;
    }
	return x;
}
static snd_pcm_uframes_t hi3630_srcup_normal_pointer(struct snd_pcm_substream *substream)
{
	snd_pcm_uframes_t offset = 0;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct hi3630_srcup_runtime_data *prtd = substream->runtime->private_data;
	unsigned int period_cur = 0;
	unsigned int period_size = 0;

	spin_lock(&prtd->lock);
	period_cur = prtd->period_cur;
	period_size = prtd->period_size;
	spin_unlock(&prtd->lock);

	offset = bytes_to_frames(runtime, period_cur * period_size);
	if (offset >= runtime->buffer_size)
		offset = 0;

	return offset;
}
Exemple #18
0
static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct sst_byt_priv_data *pdata =
		snd_soc_platform_get_drvdata(rtd->platform);
	struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
	struct sst_byt *byt = pdata->byt;
	snd_pcm_uframes_t offset;
	int pos;

	pos = sst_byt_get_dsp_position(byt, pcm_data->stream,
				       snd_pcm_lib_buffer_bytes(substream));
	offset = bytes_to_frames(runtime, pos);

	dev_dbg(rtd->dev, "PCM: DMA pointer %zu bytes\n",
		frames_to_bytes(runtime, (u32)offset));
	return offset;
}
Exemple #19
0
static snd_pcm_uframes_t
mxs_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct mxs_runtime_data *prtd = runtime->private_data;
	struct mxs_dma_info dma_info;
	unsigned int offset;
	dma_addr_t pos;

	mxs_dma_get_info(prtd->params->dma_ch, &dma_info);
	pos = dma_info.buf_addr;

	offset = bytes_to_frames(runtime, pos - runtime->dma_addr);

	if (offset >= runtime->buffer_size)
		offset = 0;

	return offset;
}
Exemple #20
0
static snd_pcm_uframes_t
atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
{
	struct atmel_ac97c	*chip = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime	*runtime = substream->runtime;
	snd_pcm_uframes_t	frames;
	unsigned long		bytes;

	if (cpu_is_at32ap7000())
		bytes = dw_dma_get_dst_addr(chip->dma.rx_chan);
	else
		bytes = readl(chip->regs + ATMEL_PDC_RPR);
	bytes -= runtime->dma_addr;

	frames = bytes_to_frames(runtime, bytes);
	if (frames >= runtime->buffer_size)
		frames -= runtime->buffer_size;
	return frames;
}
static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct sport_device *sport = runtime->private_data;
	unsigned int diff;
	snd_pcm_uframes_t frames;
	pr_debug("%s enter\n", __func__);
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		diff = sport_curr_offset_tx(sport);
	} else {
		diff = sport_curr_offset_rx(sport);
	}

	if (diff == snd_pcm_lib_buffer_bytes(substream))
		diff = 0;

	frames = bytes_to_frames(substream->runtime, diff);

	return frames;
}
static snd_pcm_uframes_t 
	s5p_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s5p_runtime_data *prtd = runtime->private_data;
	unsigned long res;
	dma_addr_t src, dst;

	spin_lock(&prtd->lock);

	if(s3c_pcm_pdat.lp_mode)
	   s3ci2s_func->dma_getpos(&src, &dst);
	
	/* By Jung */
	res = prtd->dma_pos - prtd->dma_start;

	spin_unlock(&prtd->lock);

	s3cdbg("Pointer %x %x\n", src, dst);

	/* we seem to be getting the odd error from the pcm library due
	 * to out-of-bounds pointers. this is maybe due to the dma engine
	 * not having loaded the new values for the channel before being
	 * callled... (todo - fix )
	 */
	
	/* By Jung */
	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		if (res >= snd_pcm_lib_buffer_bytes(substream) * ANDROID_BUF_NUM) {
			if (res == snd_pcm_lib_buffer_bytes(substream) * ANDROID_BUF_NUM)
				res = 0;
		}
	} else {
		if (res >= snd_pcm_lib_buffer_bytes(substream)) {
			if (res == snd_pcm_lib_buffer_bytes(substream))
				res = 0;
		}
	}

	return bytes_to_frames(substream->runtime, res);
}
Exemple #23
0
/*
 * pointer callback simplly reads XXX_DMA_DT_CUR register as the current
 * position.  when SG-buffer is implemented, the offset must be calculated
 * correctly...
 */
static snd_pcm_uframes_t snd_atiixp_pcm_pointer(snd_pcm_substream_t *substream)
{
    atiixp_t *chip = snd_pcm_substream_chip(substream);
    snd_pcm_runtime_t *runtime = substream->runtime;
    atiixp_dma_t *dma = (atiixp_dma_t *)runtime->private_data;
    unsigned int curptr;
    int timeout = 1000;

    while (timeout--) {
        curptr = readl(chip->remap_addr + dma->ops->dt_cur);
        if (curptr < dma->buf_addr)
            continue;
        curptr -= dma->buf_addr;
        if (curptr >= dma->buf_bytes)
            continue;
        return bytes_to_frames(runtime, curptr);
    }
    snd_printd("atiixp: invalid DMA pointer read 0x%x (buf=%x)\n",
               readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
    return 0;
}
Exemple #24
0
/*
 * return the current pointer
 */
inline
static snd_pcm_uframes_t snd_pmac_pcm_pointer(struct snd_pmac *chip,
					      struct pmac_stream *rec,
					      struct snd_pcm_substream *subs)
{
	int count = 0;

#if 1 /* hmm.. how can we get the current dma pointer?? */
	int stat;
	volatile struct dbdma_cmd __iomem *cp = &rec->cmd.cmds[rec->cur_period];
	stat = le16_to_cpu(cp->xfer_status);
	if (stat & (ACTIVE|DEAD)) {
		count = in_le16(&cp->res_count);
		if (count)
			count = rec->period_size - count;
	}
#endif
	count += rec->cur_period * rec->period_size;
	/*printk(KERN_DEBUG "pointer=%d\n", count);*/
	return bytes_to_frames(subs->runtime, count);
}
static snd_pcm_uframes_t sun7i_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct sun7i_runtime_data *prtd = runtime->private_data;
	unsigned long res = 0;
	snd_pcm_uframes_t offset = 0;
	
	spin_lock(&prtd->lock);
	sw_dma_getposition(prtd->dma_hdl, (dma_addr_t*)&dmasrc, (dma_addr_t*)&dmadst);

	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE){
		res = dmadst - prtd->dma_start;
	} else {
		offset = bytes_to_frames(runtime, dmasrc + prtd->dma_period - runtime->dma_addr);
	}
	spin_unlock(&prtd->lock);

	if(offset >= runtime->buffer_size)
		offset = 0;
		return offset;
}
Exemple #26
0
/*
 * pointer callback simplly reads XXX_DMA_DT_CUR register as the current
 * position.  when SG-buffer is implemented, the offset must be calculated
 * correctly...
 */
static snd_pcm_uframes_t snd_atiixp_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct atiixp *chip = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct atiixp_dma *dma = runtime->private_data;
	unsigned int curptr;
	int timeout = 1000;

	while (timeout--) {
		curptr = readl(chip->remap_addr + dma->ops->dt_cur);
		if (curptr < dma->buf_addr)
			continue;
		curptr -= dma->buf_addr;
		if (curptr >= dma->buf_bytes)
			continue;
		return bytes_to_frames(runtime, curptr);
	}
	dev_dbg(chip->card->dev, "invalid DMA pointer read 0x%x (buf=%x)\n",
		   readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
	return 0;
}
Exemple #27
0
static snd_pcm_uframes_t
dma_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct runtime_data *prtd = runtime->private_data;
	unsigned long res;

	pr_debug("Entered %s\n", __func__);

	res = prtd->dma_pos - prtd->dma_start;

	pr_debug("Pointer offset: %lu\n", res);


	if (res >= snd_pcm_lib_buffer_bytes(substream)) {
		if (res == snd_pcm_lib_buffer_bytes(substream))
			res = 0;
	}

	return bytes_to_frames(substream->runtime, res);
}
Exemple #28
0
static inline int queue_next_buffer(void *arg, int cur_offset)
{
	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)arg;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct pcm_runtime_data *prtd = substream->runtime->private_data;
	struct snd_pcm *pcm = substream->pcm;
	struct tegra_audio_data *ptscx = tegra_snd_cx[pcm->device];
	int offset = cur_offset;
	int size, rtbuffersize;
	NvAudioFxBufferDescriptor abd;

	rtbuffersize = frames_to_bytes(runtime, runtime->buffer_size);
	memset(&abd, 0, sizeof(NvAudioFxBufferDescriptor));
	size = TEGRA_DEFAULT_BUFFER_SIZE;
	if ((offset + size) > rtbuffersize) {
		size = rtbuffersize - offset;
	}

	abd.hMixBuffer = prtd->mixer_buffer;
	abd.Offset = offset;
	abd.Size = size;
	abd.Format.FormatTag = 1;
	abd.Format.SampleRate = runtime->rate;
	abd.Format.BitsPerSample = runtime->sample_bits;
	abd.Format.Channels = runtime->channels;
	abd.Format.ChannelMask = 0;
	abd.Format.ValidBitsPerSample = 0;

	ptscx->xrt_fxn.StreamAddBuffer(
		(NvAudioFxStreamHandle)prtd->stdoutpath->Stream,
		&abd);

	offset += size;
	if (offset >= rtbuffersize)
		offset =0;

	prtd->audiofx_frames += bytes_to_frames(runtime, size);

	return offset;
}
Exemple #29
0
static snd_pcm_uframes_t snd_cs5535audio_pcm_pointer(struct snd_pcm_substream
							*substream)
{
	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
	u32 curdma;
	struct cs5535audio_dma *dma;

	dma = substream->runtime->private_data;
	curdma = dma->ops->read_dma_pntr(cs5535au);
	if (curdma < dma->buf_addr) {
		snd_printk(KERN_ERR "curdma=%x < %x bufaddr.\n",
					curdma, dma->buf_addr);
		return 0;
	}
	curdma -= dma->buf_addr;
	if (curdma >= dma->buf_bytes) {
		snd_printk(KERN_ERR "diff=%x >= %x buf_bytes.\n",
					curdma, dma->buf_bytes);
		return 0;
	}
	return bytes_to_frames(substream->runtime, curdma);
}
Exemple #30
0
static snd_pcm_uframes_t
	idma_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct idma_ctrl *prtd = runtime->private_data;
	dma_addr_t src;
	unsigned long res, flags;

	spin_lock_irqsave(&prtd->lock, flags);

	idma_getpos(&src, substream);
	res = src - prtd->start;

	spin_unlock_irqrestore(&prtd->lock, flags);

	if (res >= snd_pcm_lib_buffer_bytes(substream)) {
		if (res == snd_pcm_lib_buffer_bytes(substream))
			res = 0;
	}

	return bytes_to_frames(substream->runtime, res);
}