Exemple #1
0
unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai)
{
	struct s3c_i2sv2_info *i2s = to_info(dai);

	return clk_get_rate(i2s->iis_cclk);
}
Exemple #2
0
static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
				 struct snd_pcm_hw_params *params,
				 struct snd_soc_dai *socdai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai_link *dai = rtd->dai;
	struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
	struct s3c_dma_params *dma_data;
	void __iomem *regs = pcm->regs;
	struct clk *clk;
	int sclk_div, sync_div;
	unsigned long flags;
	u32 clkctl;
	u32 dma_tsfr_size = 0;
	/* added by LiXueZhong on 2013.09.25 */
	unsigned long  srcrate;
	unsigned long  rate;

	dev_dbg(pcm->dev, "Entered %s\n", __func__);

	switch (params_channels(params)) {
	case 1:
		dma_tsfr_size = 2;
		break;
	case 2:
		dma_tsfr_size = 4;
		break;
	case 4:
		break;
	case 6:
		break;
	default:
		break;
	}
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		pcm->dma_playback->dma_size = dma_tsfr_size;
		dma_data = pcm->dma_playback;
	} else {
		pcm->dma_capture->dma_size = dma_tsfr_size;
		dma_data = pcm->dma_capture;
	}
	snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);

	/* Strictly check for sample size */
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		break;
	default:
		return -EINVAL;
	}

	spin_lock_irqsave(&pcm->lock, flags);

	/* Get hold of the PCMSOURCE_CLK */
	clkctl = readl(regs + S3C_PCM_CLKCTL);
	if (clkctl & S3C_PCM_CLKCTL_SERCLKSEL_PCLK)
		clk = pcm->pclk;
	else
		clk = pcm->cclk;

	/* Set the SCLK divider */
	//////////////////////////////////////////
	/* modified by LiXueZhong on 2013.09.25 */
	srcrate = clk_get_rate(clk);
	DBG("--- CLK = %u ---\n", srcrate);
	rate = pcm->sclk_per_fs * params_rate(params) * 2;
	sclk_div = srcrate / rate;
	if (srcrate % rate)
		sclk_div++;
	--sclk_div;
	///////////////////////////////////////////

	clkctl &= ~(S3C_PCM_CLKCTL_SCLKDIV_MASK
			<< S3C_PCM_CLKCTL_SCLKDIV_SHIFT);
	clkctl |= ((sclk_div & S3C_PCM_CLKCTL_SCLKDIV_MASK)
			<< S3C_PCM_CLKCTL_SCLKDIV_SHIFT);

	/* Set the SYNC divider */
	sync_div = pcm->sclk_per_fs - 1;

	clkctl &= ~(S3C_PCM_CLKCTL_SYNCDIV_MASK
				<< S3C_PCM_CLKCTL_SYNCDIV_SHIFT);
	clkctl |= ((sync_div & S3C_PCM_CLKCTL_SYNCDIV_MASK)
				<< S3C_PCM_CLKCTL_SYNCDIV_SHIFT);

	writel(clkctl, regs + S3C_PCM_CLKCTL);

	spin_unlock_irqrestore(&pcm->lock, flags);
/*
	dev_dbg(pcm->dev, "SOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n",
				clk_get_rate(clk), pcm->sclk_per_fs,
				sclk_div, sync_div);
*/
	DBG("--- SOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d ---\n",
				clk_get_rate(clk), pcm->sclk_per_fs,
				sclk_div, sync_div);

	return 0;
}
Exemple #3
0
/*
 * Set S3C2412 I2S DAI format
 */
static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
			       unsigned int fmt)
{
	struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
	u32 iismod;

	pr_debug("Entered %s\n", __func__);

	iismod = readl(i2s->regs + S3C2412_IISMOD);
	pr_debug("hw_params r: IISMOD: %x \n", iismod);

#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
#define IISMOD_MASTER_MASK S3C2412_IISMOD_MASTER_MASK
#define IISMOD_SLAVE S3C2412_IISMOD_SLAVE
#define IISMOD_MASTER S3C2412_IISMOD_MASTER_INTERNAL
#endif

#if defined(CONFIG_PLAT_S3C64XX) || defined(CONFIG_PLAT_S5PC1XX) \
		|| defined(CONFIG_PLAT_S5PC11X) || defined(CONFIG_PLAT_S5P64XX)
/* From Rev1.1 datasheet, we have two master and two slave modes:
 * IMS[11:10]:
 *	00 = master mode, fed from PCLK
 *	01 = master mode, fed from CLKAUDIO
 *	10 = slave mode, using PCLK
 *	11 = slave mode, using I2SCLK
 */
#define IISMOD_MASTER_MASK (1 << 11)
#define IISMOD_SLAVE (1 << 11)
#define IISMOD_MASTER (0 << 11)
#endif

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		i2s->master = 0;
		iismod &= ~IISMOD_MASTER_MASK;
		iismod |= IISMOD_SLAVE;
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		i2s->master = 1;
		iismod &= ~IISMOD_MASTER_MASK;
		iismod |= IISMOD_MASTER;
		break;
	default:
		pr_err("unknwon master/slave format\n");
		return -EINVAL;
	}

	iismod &= ~S3C2412_IISMOD_SDF_MASK;

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_RIGHT_J:
		iismod |= S3C2412_IISMOD_LR_RLOW;
		iismod |= S3C2412_IISMOD_SDF_MSB;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		iismod |= S3C2412_IISMOD_LR_RLOW;
		iismod |= S3C2412_IISMOD_SDF_LSB;
		break;
	case SND_SOC_DAIFMT_I2S:
		iismod &= ~S3C2412_IISMOD_LR_RLOW;
		iismod |= S3C2412_IISMOD_SDF_IIS;
		break;
	default:
		pr_err("Unknown data format\n");
		return -EINVAL;
	}

	writel(iismod, i2s->regs + S3C2412_IISMOD);
	pr_debug("hw_params w: IISMOD: %x \n", iismod);
	return 0;
}
Exemple #4
0
/*
 * Set S3C2412 Clock dividers
 */
static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
				  int div_id, int div)
{
	struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
	u32 reg;

	pr_debug("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div);

	switch (div_id) {
	case S3C_I2SV2_DIV_BCLK:
		if (div > 3) {
			/* convert value to bit field */

			switch (div) {
			case 16:
				div = S3C2412_IISMOD_BCLK_16FS;
				break;

			case 32:
				div = S3C2412_IISMOD_BCLK_32FS;
				break;

			case 24:
				div = S3C2412_IISMOD_BCLK_24FS;
				break;

			case 48:
				div = S3C2412_IISMOD_BCLK_48FS;
				break;

			default:
				return -EINVAL;
			}
		}

		reg = readl(i2s->regs + S3C2412_IISMOD);
		reg &= ~S3C2412_IISMOD_BCLK_MASK;
		writel(reg | div, i2s->regs + S3C2412_IISMOD);

		pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD));
		break;

	case S3C_I2SV2_DIV_RCLK:
		if (div > 3) {
			/* convert value to bit field */

			switch (div) {
			case 256:
				div = S3C2412_IISMOD_RCLK_256FS;
				break;

			case 384:
				div = S3C2412_IISMOD_RCLK_384FS;
				break;

			case 512:
				div = S3C2412_IISMOD_RCLK_512FS;
				break;

			case 768:
				div = S3C2412_IISMOD_RCLK_768FS;
				break;

			default:
				return -EINVAL;
			}
		}

		reg = readl(i2s->regs + S3C2412_IISMOD);
		reg &= ~S3C2412_IISMOD_RCLK_MASK;
		writel(reg | div, i2s->regs + S3C2412_IISMOD);
		pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD));
		break;

	case S3C_I2SV2_DIV_PRESCALER:
		if (div >= 0) {
			writel((div << 8) | S3C2412_IISPSR_PSREN,
			       i2s->regs + S3C2412_IISPSR);
		} else {
			writel(0x0, i2s->regs + S3C2412_IISPSR);
		}
		pr_debug("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR));
		break;

	default:
		return -EINVAL;
	}

	return 0;
}
Exemple #5
0
static int spdif_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params,
				struct snd_soc_dai *socdai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai);
	void __iomem *regs = spdif->regs;
	struct s3c_dma_params *dma_data;
	u32 con, clkcon, cstas;
	unsigned long flags;
	int i, ratio;

	dev_dbg(spdif->dev, "Entered %s\n", __func__);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dma_data = spdif->dma_playback;
	else {
		dev_err(spdif->dev, "Capture is not supported\n");
		return -EINVAL;
	}

	snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);

	spin_lock_irqsave(&spdif->lock, flags);

	con = readl(regs + CON) & CON_MASK;
	cstas = readl(regs + CSTAS) & CSTAS_MASK;
	clkcon = readl(regs + CLKCON) & CLKCTL_MASK;

	con &= ~CON_FIFO_TH_MASK;
	con |= (0x7 << CON_FIFO_TH_SHIFT);
	con |= CON_USERDATA_23RDBIT;
	con |= CON_PCM_DATA;

	con &= ~CON_PCM_MASK;
	switch (params_width(params)) {
	case 16:
		con |= CON_PCM_16BIT;
		break;
	default:
		dev_err(spdif->dev, "Unsupported data size.\n");
		goto err;
	}

	ratio = spdif->clk_rate / params_rate(params);
	for (i = 0; i < ARRAY_SIZE(spdif_sysclk_ratios); i++)
		if (ratio == spdif_sysclk_ratios[i])
			break;
	if (i == ARRAY_SIZE(spdif_sysclk_ratios)) {
		dev_err(spdif->dev, "Invalid clock ratio %ld/%d\n",
				spdif->clk_rate, params_rate(params));
		goto err;
	}

	con &= ~CON_MCLKDIV_MASK;
	switch (ratio) {
	case 256:
		con |= CON_MCLKDIV_256FS;
		break;
	case 384:
		con |= CON_MCLKDIV_384FS;
		break;
	case 512:
		con |= CON_MCLKDIV_512FS;
		break;
	}

	cstas &= ~CSTAS_SAMP_FREQ_MASK;
	switch (params_rate(params)) {
	case 44100:
		cstas |= CSTAS_SAMP_FREQ_44;
		break;
	case 48000:
		cstas |= CSTAS_SAMP_FREQ_48;
		break;
	case 32000:
		cstas |= CSTAS_SAMP_FREQ_32;
		break;
	case 96000:
		cstas |= CSTAS_SAMP_FREQ_96;
		break;
	default:
		dev_err(spdif->dev, "Invalid sampling rate %d\n",
				params_rate(params));
		goto err;
	}

	cstas &= ~CSTAS_CATEGORY_MASK;
	cstas |= CSTAS_CATEGORY_CODE_CDP;
	cstas |= CSTAS_NO_COPYRIGHT;

	writel(con, regs + CON);
	writel(cstas, regs + CSTAS);
	writel(clkcon, regs + CLKCON);

	spin_unlock_irqrestore(&spdif->lock, flags);

	return 0;
err:
	spin_unlock_irqrestore(&spdif->lock, flags);
	return -EINVAL;
}
static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
			       struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct s3c_i2sv2_info *i2s = to_info(rtd->dai->cpu_dai);
	int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
	unsigned long irqs;
	int ret = 0;
	struct s3c_dma_params *dma_data =
		snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);

	pr_debug("Entered %s\n", __func__);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		/* On start, ensure that the FIFOs are cleared and reset. */

		writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH,
		       i2s->regs + S3C2412_IISFIC);

		/* clear again, just in case */
		writel(0x0, i2s->regs + S3C2412_IISFIC);

	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (!i2s->master) {
			ret = s3c2412_snd_lrsync(i2s);
			if (ret)
				goto exit_err;
		}

		local_irq_save(irqs);

		if (capture)
			s3c2412_snd_rxctrl(i2s, 1);
		else
			s3c2412_snd_txctrl(i2s, 1);

		local_irq_restore(irqs);

		/*
		 * Load the next buffer to DMA to meet the reqirement
		 * of the auto reload mechanism of S3C24XX.
		 * This call won't bother S3C64XX.
		 */
		s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);

		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		local_irq_save(irqs);

		if (capture)
			s3c2412_snd_rxctrl(i2s, 0);
		else
			s3c2412_snd_txctrl(i2s, 0);

		local_irq_restore(irqs);
		break;
	default:
		ret = -EINVAL;
		break;
	}

exit_err:
	return ret;
}
Exemple #7
0
static int s5p_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
		int clk_id, unsigned int freq, int dir)
{
	struct clk *clk;
	struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
	u32 iismod = readl(i2s->regs + S3C2412_IISMOD);

	switch (clk_id) {
	case S3C64XX_CLKSRC_PCLK:
		iismod &= ~S3C64XX_IISMOD_IMS_SYSMUX;
		break;
	case S3C64XX_CLKSRC_MUX:
		iismod |= S3C64XX_IISMOD_IMS_SYSMUX;
		break;

	case S3C64XX_CLKSRC_CDCLK:
		switch (dir) {
		case SND_SOC_CLOCK_IN:
			iismod |= S3C64XX_IISMOD_CDCLKCON;
			break;
		case SND_SOC_CLOCK_OUT:
			iismod &= ~S3C64XX_IISMOD_CDCLKCON;
			break;
		default:
			return -EINVAL;
		}
		break;
#ifdef USE_CLKAUDIO
		/* IIS-IP is Master and derives its clocks from I2SCLKD2 */
	case S3C_CLKSRC_CLKAUDIO:
		if (!i2s->master)
			return -EINVAL;
		iismod &= ~S3C_IISMOD_IMSMASK;
		iismod |= clk_id;
		clk = clk_get(NULL, "fout_epll");
		if (IS_ERR(clk)) {
			pr_err("failed to get %s\n", "fout_epll");
			return -EBUSY;
		}
		clk_disable(clk);
		switch (freq) {
		case 8000:
		case 16000:
		case 32000:
		case 48000:
		case 64000:
		case 96000:
			clk_set_rate(clk, 49152000);
			break;
		case 11025:
		case 22050:
		case 44100:
		case 88200:
		default:
			clk_set_rate(clk, 67738000);
			break;
		}
		clk_enable(clk);
		clk_put(clk);
		break;
#endif
		/* IIS-IP is Slave and derives its clocks from the Codec Chip */
	case S3C64XX_CLKSRC_I2SEXT:
		iismod &= ~S3C64XX_IISMOD_IMSMASK;
		iismod |= clk_id;
		/* Operation clock for I2S logic selected as Audio Bus Clock */
		iismod |= S3C64XX_IISMOD_OPPCLK;

		clk = clk_get(NULL, "fout_epll");
		if (IS_ERR(clk)) {
			pr_err("failed to get %s\n", "fout_epll");
				return -EBUSY;
		}
		clk_disable(clk);
		clk_set_rate(clk, 67738000);
		clk_enable(clk);
		clk_put(clk);
		break;

	case S3C64XX_CDCLKSRC_EXT:
		iismod |= S3C64XX_IISMOD_CDCLKCON;
		break;

	default:
		return -EINVAL;
	}

	writel(iismod, i2s->regs + S3C2412_IISMOD);

	return 0;
}
Exemple #8
0
int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
				 struct snd_pcm_hw_params *params,
				 struct snd_soc_dai *socdai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai_link *dai = rtd->dai;
	struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai);
	u32 dma_tsfr_size = 0;
	u32 iismod;

	pr_debug("Entered %s\n", __func__);

	/* TODO */
	switch (params_channels(params)) {
		case 1:
			dma_tsfr_size = 2;
			break;
		case 2:
			dma_tsfr_size = 4;
			break;
		case 4:
			break;
		case 6:
			break;
		default:
			break;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		i2s->dma_playback->dma_size = dma_tsfr_size;
		dai->cpu_dai->dma_data = i2s->dma_playback;
	} else {
		i2s->dma_capture->dma_size = dma_tsfr_size;
		dai->cpu_dai->dma_data = i2s->dma_capture;
	}

	/* Working copies of register */
	iismod = readl(i2s->regs + S3C2412_IISMOD);
	pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);

#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S3C2412_IISMOD_8BIT;
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		iismod &= ~S3C2412_IISMOD_8BIT;
		break;
	}
#endif

#if defined(CONFIG_PLAT_S3C64XX) || defined(CONFIG_PLAT_S5P)
	iismod &= ~(S3C64XX_IISMOD_BLC_MASK | S3C2412_IISMOD_BCLK_MASK);
	/* Sample size */
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		/* 8 bit sample, 16fs BCLK */
		iismod |= (S3C64XX_IISMOD_BLC_8BIT | S3C2412_IISMOD_BCLK_16FS);
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		/* 16 bit sample, 32fs BCLK */
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		/* 24 bit sample, 48fs BCLK */
		iismod |= (S3C64XX_IISMOD_BLC_24BIT | S3C2412_IISMOD_BCLK_48FS);
		break;
	}

	/* Set the IISMOD[25:24](BLC_P) to same value */
	iismod &= ~(S5P_IISMOD_BLCPMASK);
	iismod |= ((iismod & S3C64XX_IISMOD_BLC_MASK) << 11);
#endif

	writel(iismod, i2s->regs + S3C2412_IISMOD);
	pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
	return 0;
}
static int spdif_hw_params(struct snd_pcm_substream *
		substream, struct snd_pcm_hw_params *params,
		struct snd_soc_dai *dai)
{
	struct rockchip_spdif_info *spdif = to_info(dai);
	void __iomem *regs = spdif->regs;
	unsigned long flags;
	int cfgr, dmac, intcr, chnsr_byte[5] = {0};
	int data_type, err_flag, data_len, data_info;
	int bs_num, repetition, burst_info;

	RK_SPDIF_DBG("Entered %s\n", __func__);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		dai->playback_dma_data = &spdif->dma_playback;
	} else {
		pr_err("spdif:Capture is not supported\n");
		return -EINVAL;
	}

	spin_lock_irqsave(&spdif->lock, flags);

	cfgr = readl(regs + CFGR) & CFGR_VALID_DATA_MASK;

	cfgr &= ~CFGR_VALID_DATA_MASK;
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		cfgr |= CFGR_VALID_DATA_16bit;
		break;
	case SNDRV_PCM_FORMAT_S20_3LE:
		cfgr |= CFGR_VALID_DATA_20bit;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		cfgr |= CFGR_VALID_DATA_24bit;
		break;
	default:
		goto err;
	}

	cfgr &= ~CFGR_HALFWORD_TX_MASK;
	cfgr |= CFGR_HALFWORD_TX_ENABLE;

	/* set most MCLK:192kHz */
	cfgr &= ~CFGR_CLK_RATE_MASK;
	cfgr |= (1<<16);

	cfgr &= ~CFGR_JUSTIFIED_MASK;
	cfgr |= CFGR_JUSTIFIED_RIGHT;

	cfgr &= ~CFGR_CSE_MASK;
	cfgr |= CFGR_CSE_DISABLE;

	cfgr &= ~CFGR_LINEAR_MASK;
	cfgr |= CFGR_LINEAR_PCM;

	/* stream type*/
	if (!snd_pcm_format_linear(params_format(params)))
		cfgr |= CFGR_NON_LINEAR_PCM;

	cfgr &= ~CFGR_PRE_CHANGE_MASK;
	cfgr |= CFGR_PRE_CHANGE_ENALBLE;

	writel(cfgr, regs + CFGR);

	intcr = readl(regs + INTCR) & INTCR_SDBEIE_MASK;
	intcr |= INTCR_SDBEIE_ENABLE;
	writel(intcr, regs + INTCR);

	dmac = readl(regs + DMACR) & DMACR_TRAN_DMA_MASK &
		(~DMACR_TRAN_DATA_LEVEL_MASK);
	dmac |= 0x10;
	writel(dmac, regs + DMACR);

	/*
	* channel byte 0:
	* Bit 1
	* 1 Main data field represents linear PCM samples.
	* 0 Main data field used for purposes other purposes.
	*/
	chnsr_byte[0] = (0x0) | (0x0 << 1) |
		(0x0 << 2) | (0x0 << 3) |
		(0x00 << 6);
	chnsr_byte[1] = (0x0);
	chnsr_byte[2] = (0x0) | (0x0 << 4) | (0x0 << 6);
	chnsr_byte[3] = (0x00) | (0x00);
	chnsr_byte[4] = (0x0 << 4) | (0x01 << 1 | 0x0);

	/* set stream type */
	if (!snd_pcm_format_linear(params_format(params))) {
		chnsr_byte[0] |= (0x1<<1);
		chnsr_byte[4] = (0x0<<4)|(0x00<<1|0x0);
	}
	writel((chnsr_byte[4] << 16)
			| (chnsr_byte[4]),
			regs + SPDIF_CHNSR02_ADDR);
	writel((chnsr_byte[3] << 24) | (chnsr_byte[2] << 16) |
		(chnsr_byte[3] << 8) | (chnsr_byte[2]),
		regs + SPDIF_CHNSR01_ADDR);
	writel((chnsr_byte[1] << 24) | (chnsr_byte[0] << 16) |
		(chnsr_byte[1] << 8) | (chnsr_byte[0]),
		regs + SPDIF_CHNSR00_ADDR);

	/* set non-linear params */
	if (!snd_pcm_format_linear(params_format(params))) {
		switch (params_format(params)) {
		case SNDRV_NON_LINEAR_PCM_FORMAT_AC3:
			/* bit0:6 AC-3:0x01, DTS-I -II -III:11,12,13 */
			data_type = burst_info_DATA_TYPE_AC3;
			/*
			* repetition:AC-3:1536
			* DTS-I -II -III:512,1024,2048 EAC3:6144
			*/
			repetition = 1536;
			break;
		case SNDRV_NON_LINEAR_PCM_FORMAT_DTS_I:
			data_type = BURST_INFO_DATA_TYPE_DTS_I;
			repetition = 512;
			break;
		case SNDRV_NON_LINEAR_PCM_FORMAT_EAC3:
			data_type = burst_info_DATA_TYPE_EAC3;
			repetition = 6144;
			break;
		default:
			return -EINVAL;
		}
		err_flag = 0x0;
		data_len = params_period_size(params) * 2 * 16;
		data_info = 0;
		bs_num = 0x0;
		burst_info = (data_len << 16) | (bs_num << 13) |
			(data_info << 8) | (err_flag << 7) | data_type;
		writel(burst_info, regs + SPDIF_BURST_INFO);
		writel(repetition, regs + SPDIF_REPETTION);
	}
	spin_unlock_irqrestore(&spdif->lock, flags);

	return 0;
err:
	spin_unlock_irqrestore(&spdif->lock, flags);
	return -EINVAL;
}