예제 #1
0
/* S/PDIF */
static void davinci_hw_dit_param(struct davinci_audio_dev *dev)
{
	/* Set the PDIR for Serialiser as output */
	mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AFSX);

	/* TXMASK for 24 bits */
	mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0x00FFFFFF);

	/* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
	   and LSB first */
	mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
						TXROT(6) | TXSSZ(15));

	/* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */
	mcasp_set_reg(dev->base + DAVINCI_MCASP_TXFMCTL_REG,
						AFSXE | FSXMOD(0x180));

	/* Set the TX tdm : for all the slots */
	mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF);

	/* Set the TX clock controls : div = 1 and internal */
	mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
						ACLKXE | TX_ASYNC);

	mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS);

	/* Only 44100 and 48000 are valid, both have the same setting */
	mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3));

	/* Enable the DIT */
	mcasp_set_bits(dev->base + DAVINCI_MCASP_TXDITCTL_REG, DITEN);
}
static int davinci_mcasp_set_dai_clkdiv(struct snd_soc_dai *dai, int div_id,
		int div)
{
	struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai);

	switch (div_id) {
	case DAVINCI_MCASP_CLKXDIV:
		div--;
		if (div < 0) {
			dev_err(dev->dev, "tried to set invalid clkdiv\n");
			return -EINVAL;
		} else if (div/3 > 31) {
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
				AHCLKXDIV(0xfff));
			mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
				AHCLKXDIV(3));
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
				ACLKXDIV(0x1F));
			mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
				ACLKXDIV(div/4));
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
				AHCLKRDIV(0xfff));
			mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
				AHCLKRDIV(3));
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG,
				ACLKRDIV(0x1F));
			mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG,
				ACLKRDIV(div/4));
		} else if (div > 31) {
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
				AHCLKXDIV(0xfff));
			mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
				AHCLKXDIV(2));
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
				ACLKXDIV(0x1F));
			mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
				ACLKXDIV(div/3));
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
				AHCLKRDIV(0xfff));
			mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
				AHCLKRDIV(2));
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG,
				ACLKRDIV(0x1F));
			mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG,
				ACLKRDIV(div/3));
		} else {
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
				AHCLKXDIV(0xfff));
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
				ACLKXDIV(0x1F));
			mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
				ACLKXDIV(div));
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
				AHCLKRDIV(0xfff));
			mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG,
				ACLKRDIV(0x1F));
			mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG,
				ACLKRDIV(div));
		}
		break;
	default:
		dev_err(dev->dev, "tried to set unsupported clkdiv\n");
		return -EINVAL;
	}

	return 0;
}