Beispiel #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;
}
Beispiel #2
0
static int pcm_set_fmt(unsigned long *format,int mode)
{
	int ret = 0;
	int data_width = 0;
	struct dsp_pipe *dp_in = NULL;
	struct dsp_pipe *dp_out = NULL;
	dp_in = pcm_priv->endpoint->in_endpoint;
	dp_out = pcm_priv->endpoint->out_endpoint;

	switch (*format) {

	case AFMT_U8:
	case AFMT_S8:
		*format = AFMT_U8;
		data_width = 8;
		if (mode & CODEC_WMODE) {
			__pcm_set_oss_sample_size(0);
			dp_out->dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
			dp_out->dma_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
		} if (mode & CODEC_RMODE) {
			__pcm_set_iss_sample_size(0);
			dp_in->dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
			dp_in->dma_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
		}
		break;
	case AFMT_S16_LE:
	case AFMT_S16_BE:
		data_width = 16;
		*format = AFMT_S16_LE;
		if (mode & CODEC_WMODE) {
			__pcm_set_oss_sample_size(1);
			/*__pcm_set_oss_sample_size(0);*/
			dp_out->dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
			dp_out->dma_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
		}
		if (mode & CODEC_RMODE) {
			__pcm_set_iss_sample_size(1);
			dp_in->dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
			dp_in->dma_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
		}
		break;
	default :
		printk("PCM: there is unknown format 0x%x.\n",(unsigned int)*format);
		return -EINVAL;
	}
	if (mode & CODEC_WMODE) {
		dp_out->dma_config.dst_maxburst = 16 * data_width/8/2;
		dump_dma_config(dp_out);
		if (pcm_priv->replay_format != *format) {
			pcm_priv->replay_format = *format;
			ret |= NEED_RECONF_TRIGGER | NEED_RECONF_FILTER;
			ret |= NEED_RECONF_DMA;
		}
	}

	if (mode & CODEC_RMODE) {
		dp_in->dma_config.src_maxburst = 16 * data_width/8/2;
		dump_dma_config(dp_in);
		if (pcm_priv->record_format != *format) {
			pcm_priv->record_format = *format;
			ret |= NEED_RECONF_TRIGGER | NEED_RECONF_FILTER;
			ret |= NEED_RECONF_DMA;
		}
	}

	return ret;
}