/* 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; }