Example #1
0
static int jz_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	struct device *dev = dai->dev;
	struct jz_pcm *jz_pcm = dev_get_drvdata(dai->dev);
	int fmt_width = snd_pcm_format_width(params_format(params));
	enum dma_slave_buswidth buswidth;
	int trigger;

	PCM_DEBUG_MSG("enter %s, substream = %s\n",
			__func__,
			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "playback" : "capture");

	if (!((1 << params_format(params)) & JZ_PCM_FORMATS) ||
			params_channels(params) != 1 ||
			params_rate(params) != 8000) {
		dev_err(dai->dev, "hw params not inval channel %d params %x\n",
				params_channels(params), params_format(params));
		return -EINVAL;
	}

	/* format 8 bit or 16 bit*/
	if (fmt_width == 8)
		buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
	else
		buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		jz_pcm->tx_dma_data.buswidth = buswidth;
		jz_pcm->tx_dma_data.max_burst = (PCM_TFIFO_DEPTH * buswidth)/2;
		trigger = PCM_TFIFO_DEPTH - (jz_pcm->tx_dma_data.max_burst/(int)buswidth);
		__pcm_set_oss_sample_size(dev, fmt_width == 8 ? 0 : 1);
		__pcm_set_transmit_trigger(dev, trigger);
		snd_soc_dai_set_dma_data(dai, substream, (void *)&jz_pcm->tx_dma_data);
	} else {
		jz_pcm->rx_dma_data.buswidth = buswidth;
		jz_pcm->rx_dma_data.max_burst = (PCM_RFIFO_DEPTH * buswidth)/2;
		trigger = jz_pcm->rx_dma_data.max_burst/(int)buswidth;
		__pcm_set_iss_sample_size(dev, fmt_width == 8 ? 0 : 1);
		__pcm_set_receive_trigger(dev, trigger);
		snd_soc_dai_set_dma_data(dai, substream, (void *)&jz_pcm->rx_dma_data);
	}
	return 0;
}
Example #2
0
static void pcm_set_trigger(int mode)
{
	int data_width = 0;
	struct dsp_pipe *dp = NULL;
	int burst_length = 0;

	if (!pcm_priv)
		return;

	if (mode & CODEC_WMODE) {
		switch(pcm_priv->replay_format) {
		case AFMT_U8:
			data_width = 8;
			break;
		case AFMT_S16_LE:
			data_width = 16;
			break;
		}
		dp = pcm_priv->endpoint->out_endpoint;
		burst_length = get_burst_length((int)dp->paddr|(int)dp->fragsize|dp->dma_config.dst_maxburst);
		__pcm_set_transmit_trigger((PCM_FIFO_DEPTH - burst_length/data_width) - 1);
		printk("PCM_FIFO_DEPTH - burst_length/data_width - 1 = %d\n",(PCM_FIFO_DEPTH - burst_length/data_width) - 1);
}
	if (mode &CODEC_RMODE) {
		switch(pcm_priv->record_format) {
		case AFMT_U8:
			data_width = 8;
			break;
		case AFMT_S16_LE:
			data_width = 16;
			break;
		}
		dp = pcm_priv->endpoint->in_endpoint;
		burst_length = get_burst_length((int)dp->paddr|(int)dp->fragsize|dp->dma_config.src_maxburst);
		__pcm_set_receive_trigger((burst_length/data_width) - 1);
	}

	return;
}
Example #3
0
static int pcm_init(struct platform_device *pdev)
{
	int ret = 0;
	struct resource *pcm_resource = NULL;
	struct dsp_pipe *pcm_pipe_out = NULL;
	struct dsp_pipe *pcm_pipe_in = NULL;

	/* map io address */
	pcm_resource = platform_get_resource(pdev,IORESOURCE_MEM,0);
	if (pcm_resource == NULL) {
		printk("pcm: platform_get_resource fail.\n");
		return -1;
	}
	if (!request_mem_region(pcm_resource->start, resource_size(pcm_resource), pdev->name)) {
		printk("pcm: mem region fail busy .\n");
		return -EBUSY;
	}

	pcm_iomem = ioremap(pcm_resource->start, resource_size(pcm_resource));
	if (!pcm_iomem) {
		printk ("pcm: ioremap fail.\n");
		ret =  -ENOMEM;
		goto __err_ioremap;
	}

	/*init pipe*/
	ret = pcm_init_pipe(&pcm_pipe_out,DMA_TO_DEVICE,pcm_resource->start);
	if (ret < 0)
		goto __err_init_pipeout;
	ret = pcm_init_pipe(&pcm_pipe_in,DMA_FROM_DEVICE,pcm_resource->start);
	if (ret < 0)
		goto __err_init_pipein;
	pcm_endpoints.out_endpoint = pcm_pipe_out;
	pcm_endpoints.in_endpoint = pcm_pipe_in;

	/*spin lock init*/
	spin_lock_init(&pcm_irq_lock);

	/* request irq */
	pcm_resource = platform_get_resource(pdev,IORESOURCE_IRQ,0);
	if (pcm_resource == NULL) {
		ret = -1;
		printk("pcm there is not irq resource\n");
		goto __err_irq;
	}
	pcm_priv->irq = pcm_resource->start;
	ret = request_irq(pcm_resource->start, pcm_irq_handler,
			IRQF_DISABLED, "pcm_irq", NULL);
	if (ret < 0) {
		printk("pcm:request irq fail\n");
		goto __err_irq;
	}

	ret = pcm_clk_init(pdev);
	if (ret < 0)
		goto __err_clk_init;

	__pcm_disable_receive_dma();
	__pcm_disable_transmit_dma();
	__pcm_disable_record();
	__pcm_disable_replay();
	__pcm_flush_fifo();
	__pcm_clear_ror();
	__pcm_clear_tur();
	__pcm_set_receive_trigger(7);
	__pcm_set_transmit_trigger(8);
	__pcm_disable_overrun_intr();
	__pcm_disable_underrun_intr();
	__pcm_disable_transmit_intr();
	__pcm_disable_receive_intr();
	/* play zero or last sample when underflow */
	__pcm_play_lastsample();
	//__pcm_enable();

	return 0;

__err_clk_init:
	free_irq(pcm_priv->irq,NULL);
__err_irq:
	vfree(pcm_pipe_in);
__err_init_pipein:
	vfree(pcm_pipe_out);
__err_init_pipeout:
	iounmap(pcm_iomem);
__err_ioremap:
	release_mem_region(pcm_resource->start,resource_size(pcm_resource));
	return ret;
}