示例#1
0
static int jz_spdif_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
{
#ifndef CONFIG_JZ_ASOC_DMA_HRTIMER_MODE
	struct jz_pcm_runtime_data *prtd = substream->runtime->private_data;
#endif
	spdif_DEBUG_MSG("enter %s, substream = %s cmd = %d\n",
		      __func__,
		      (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "playback" : "capture",
		      cmd);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
#ifndef CONFIG_JZ_ASOC_DMA_HRTIMER_MODE
		if (atomic_read(&prtd->stopped_pending))
			return -EPIPE;
#endif
		if(jz_spdif_start_substream(substream, dai))
			return -EINVAL;
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
#ifndef CONFIG_JZ_ASOC_DMA_HRTIMER_MODE
		if (atomic_read(&prtd->stopped_pending))
			return 0;
#endif
		jz_spdif_stop_substream(substream, dai);
		break;
	}
	/*dump_registers(aic);*/
	return 0;
}
示例#2
0
static int jz_spdif_stop_substream(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
	struct jz_spdif *jz_spdif = dev_get_drvdata(dai->dev);
	struct device *aic = jz_spdif->aic;
	spdif_DEBUG_MSG("enter %s, substream = %s\n",
			__func__,
			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "playback" : "capture");

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		if (jz_spdif_debug) __aic_dis_tur_int(aic);
		if (__spdif_is_enable_transmit_dma(aic)) {
			__spdif_disable_transmit_dma(aic);
			__spdif_clear_underrun(aic);
#ifdef CONFIG_JZ_ASOC_DMA_HRTIMER_MODE
			/*hrtime mode: stop will be happen in any where, make sure there is
			 *	no data transfer on ahb bus before stop dma
			 */
			while(!__spdif_test_underrun(aic));
#endif
		}
		__spdif_disable(aic);
		__spdif_clear_underrun(aic);
	} else {
		printk("spdif is not a capture device!\n");
		return -EINVAL;
	}

	return 0;
}
示例#3
0
static int jz_spdif_start_substream(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
	struct jz_spdif *jz_spdif = dev_get_drvdata(dai->dev);
	struct device *aic = jz_spdif->aic;
	int rst_test = 0xfff;
	spdif_DEBUG_MSG("enter %s, substream = %s\n",
			__func__,
			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "playback" : "capture");

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		__spdif_reset(aic);
		while(__spdif_get_reset(aic)) {
			if (rst_test-- <= 0){
				printk("spdif rst err\n");
				return -EINVAL;
			}
		}
		__spdif_enable_transmit_dma(aic);
		__spdif_clear_underrun(aic);
		__spdif_enable(aic);
		__aic_enable(aic);
	} else {
		printk("spdif is not a capture device!\n");
		return -EINVAL;
	}
	return 0;
}
示例#4
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;
}
示例#5
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;
}
示例#6
0
static void jz_spdif_shutdown(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai) {
	struct jz_spdif *jz_spdif = dev_get_drvdata(dai->dev);
	struct device *aic = jz_spdif->aic;
	enum aic_mode work_mode = AIC_SPDIF_MODE;

	spdif_DEBUG_MSG("enter %s, substream = %s\n",
			__func__,(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "playback" : "capture");
	work_mode = aic_set_work_mode(jz_spdif->aic, work_mode, false);
	BUG_ON((work_mode != AIC_NO_MODE));
	jz_spdif_stop_substream(substream, dai);
	__aic_disable(aic);
	return;
}
示例#7
0
static int jz_spdif_startup(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
	struct jz_spdif *jz_spdif = dev_get_drvdata(dai->dev);
	struct device *aic = jz_spdif->aic;
	enum aic_mode work_mode = AIC_SPDIF_MODE;

	spdif_DEBUG_MSG("enter %s, substream = %s\n",
			__func__,
			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "playback" : "capture");
	work_mode = aic_set_work_mode(aic, work_mode, true);
	if (work_mode != AIC_SPDIF_MODE) {
		dev_warn(jz_spdif->aic, "Aic now is working on %s mode, open spdif mode failed\n",
				aic_work_mode_str(work_mode));
		return -EPERM;
	}
	printk("start set AIC register....\n");
	return 0;
}