Esempio n. 1
0
static int jz_spdif_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	int channels = params_channels(params);
	int fmt_width = snd_pcm_format_width(params_format(params));
	struct jz_spdif *jz_spdif = dev_get_drvdata(dai->dev);
	struct device *aic = jz_spdif->aic;
	struct jz_aic *jz_aic = dev_get_drvdata(aic);
	enum dma_slave_buswidth buswidth;
	int trigger;
	unsigned long sample_rate = params_rate(params);

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

	if (!((1 << params_format(params)) & JZ_SPDIF_FORMATS) || channels > 2) {
		dev_err(dai->dev, "hw params not inval channel %d params %x\n",
				channels, params_format(params));
		return -EINVAL;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		__i2s_channel(aic, channels);
		/* format */
		if (fmt_width == 16){
			buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
			__spdif_set_max_wl(aic,0);
			__spdif_set_sample_size(aic,1);
		}else if(fmt_width == 24){
			buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
			__spdif_set_max_wl(aic,1);
			__spdif_set_sample_size(aic,5);
		}else{
			return -EINVAL;
		}

		jz_spdif->tx_dma_data.buswidth = buswidth;
		jz_spdif->tx_dma_data.max_burst = (SPDIF_TFIFO_DEPTH * buswidth)/2;
		trigger = SPDIF_TFIFO_DEPTH - (jz_spdif->tx_dma_data.max_burst/(int)buswidth);
		__i2s_set_transmit_trigger(aic,trigger/2);
		snd_soc_dai_set_dma_data(dai, substream, (void *)&jz_spdif->tx_dma_data);

	} else {
		printk("spdif is not a capture device!\n");
		return -EINVAL;
	}

	/* sample rate */
	unsigned long tmp_rate = 0;
	tmp_rate = jz_spdif_set_rate(aic,jz_aic,sample_rate);
	if(tmp_rate < 0)
		printk("set spdif clk failed!!\n");
	/* signed transfer */
	if(snd_pcm_format_signed(params_format(params)))
		__spdif_clear_signn(aic);
	else
		__spdif_set_signn(aic);
	return 0;
}
Esempio n. 2
0
static int jz_spdif_probe(struct snd_soc_dai *dai)
{
	struct jz_spdif *jz_spdif = dev_get_drvdata(dai->dev);
	struct device *aic = jz_spdif->aic;
	unsigned int reg_tmp;

	spdif_DEBUG_MSG("enter %s\n", __func__);


	__i2s_disable_transmit_dma(aic);
	__i2s_disable_receive_dma(aic);
	__i2s_disable_replay(aic);
	__i2s_disable_record(aic);
	__i2s_disable_loopback(aic);
	__aic_disable(aic);


	reg_tmp = jz_aic_read_reg(aic, SPCTRL);
	reg_tmp |= (SPCTRL_SPDIF_I2S_MASK | SPCTRL_M_TRIG_MASK |
			SPCTRL_M_FFUR_MASK | SPCTRL_INVALID_MASK);
	jz_aic_write_reg(aic, SPCTRL, reg_tmp);

	__i2s_stop_bitclk(aic);
	__i2s_external_codec(aic);
	__i2s_bclk_output(aic);
	__i2s_sync_output(aic);
	__aic_select_i2s(aic);
	__i2s_send_rfirst(aic);

	__spdif_set_dtype(aic,0);
	__spdif_set_ch1num(aic,0);
	__spdif_set_ch2num(aic,1);
	__spdif_set_srcnum(aic,0);

	__interface_select_spdif(aic);
	__spdif_play_lastsample(aic);
	__spdif_init_set_low(aic);
	__spdif_choose_consumer(aic);
	__spdif_clear_audion(aic);
	__spdif_set_copyn(aic);
	__spdif_clear_pre(aic);
	__spdif_choose_chmd(aic);
	__spdif_set_category_code_normal(aic);
	__spdif_set_clkacu(aic, 0);
	__spdif_set_sample_size(aic, 1);
	__spdif_set_valid(aic);
	__spdif_mask_trig(aic);
	__spdif_disable_underrun_intr(aic);
	/*select spdif trans*/
	printk("spdif cpu dai prob ok\n");

	return 0;
}