Example #1
0
/* reclaim completed transmit descriptors and packets */
static void BCMFASTPATH
chiptxreclaim(struct bcm4xxx *ch, bool forceall)
{
	ET_TRACE(("et%d: chiptxreclaim\n", ch->etc->unit));
	dma_txreclaim(ch->di, forceall ? HNDDMA_RANGE_ALL : HNDDMA_RANGE_TRANSMITTED);
	ch->intstatus &= ~I_XI;
}
Example #2
0
static int bcm947xx_pcm_close(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	bcm947xx_i2s_info_t *snd_bcm = rtd->dai->cpu_dai->private_data;
	struct bcm947xx_runtime_data *brtd = substream->runtime->private_data;

	DBG("%s %s\n", __FUNCTION__, bcm947xx_direction_str(substream));
	
	DBG("%s: i2s intstatus 0x%x intmask 0x%x\n", __FUNCTION__,
	    R_REG(snd_bcm->osh, &snd_bcm->regs->intstatus),
	    R_REG(snd_bcm->osh, &snd_bcm->regs->intmask));

/* #if required because dma_dump is unavailable in non-debug builds. */
#if BCM947XX_DUMP_RING_BUFFER_ON_PCM_CLOSE_ON
	{
		/* dump dma rings to console */
#if !defined(FIFOERROR_DUMP_SIZE)
#define FIFOERROR_DUMP_SIZE 8192
#endif
		char *tmp;
		struct bcmstrbuf b;
		if (snd_bcm->di[0] && (tmp = MALLOC(snd_bcm->osh, FIFOERROR_DUMP_SIZE))) {
			bcm_binit(&b, tmp, FIFOERROR_DUMP_SIZE);
			dma_dump(snd_bcm->di[0], &b, TRUE);
			printbig(tmp);
			MFREE(snd_bcm->osh, tmp, FIFOERROR_DUMP_SIZE);
		}
	}
#endif /* BCM947XX_DUMP_RING_BUFFER_ON_PCM_CLOSE_ON */

	/* reclaim all descriptors */
	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
		dma_rxreset(snd_bcm->di[0]);
		dma_rxreclaim(snd_bcm->di[0]);
	} else {
		dma_txreset(snd_bcm->di[0]);
		dma_txreclaim(snd_bcm->di[0], HNDDMA_RANGE_ALL);
	}

	if (brtd)
		kfree(brtd);
	else
		DBG("%s: called with brtd == NULL\n", __FUNCTION__);

	return 0;
}
Example #3
0
/* Maybe called from snd_period_elapsed. */
static int bcm947xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	bcm947xx_i2s_info_t *snd_bcm = rtd->dai->cpu_dai->private_data;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct bcm947xx_runtime_data *brtd = runtime->private_data;
	uint32 intmask = R_REG(snd_bcm->osh, &snd_bcm->regs->intmask);
	int ret = 0;
	
	DBG("%s %s w/cmd=%d\n", __FUNCTION__, bcm947xx_direction_str(substream), cmd);

	spin_lock(&brtd->lock);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
	case SNDRV_PCM_TRIGGER_RESUME:
		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
			brtd->bytes_pending = snd_pcm_lib_buffer_bytes(substream);
			bcm947xx_pcm_enqueue(substream);
		} else {
//			dma_txresume(snd_bcm->di[0]);
		}
		break;

	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
//			dma_txsuspend(snd_bcm->di[0]);
			break;
		}
		/* fall-thru */

	case SNDRV_PCM_TRIGGER_STOP:
		/* Reset the disable interrupts, DMA RX/TX channel.
		   Might get here as a result of calling snd_pcm_period_elapsed.
		*/
		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
			intmask &= ~intmask_capture;
			W_REG(snd_bcm->osh, &snd_bcm->regs->intmask, intmask);
			dma_rxreset(snd_bcm->di[0]);
			dma_rxreclaim(snd_bcm->di[0]);
			dma_rxinit(snd_bcm->di[0]);
		} else {
			/* Disable transmit interrupts. */
			intmask &= ~intmask_playback;
			W_REG(snd_bcm->osh, &snd_bcm->regs->intmask, intmask);
			dma_txreset(snd_bcm->di[0]);
			dma_txreclaim(snd_bcm->di[0], HNDDMA_RANGE_ALL);
			dma_txinit(snd_bcm->di[0]);
			if (BCM947XX_DMA_LOOPBACK_ENABLED)
				dma_fifoloopbackenable(snd_bcm->di[0]);
//			dma_txsuspend(snd_bcm->di[0]);
		}
		break;
	default:	
		ret = -EINVAL;
	}

	spin_unlock(&brtd->lock);

	DBG("%s: i2s intstatus 0x%x intmask 0x%x\n", __FUNCTION__,
	    R_REG(snd_bcm->osh, &snd_bcm->regs->intstatus),
	    R_REG(snd_bcm->osh, &snd_bcm->regs->intmask));

	return ret;
}