This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

am335x: S/PDIF support in Linux

I'm trying to get S/PDIF on McASP1 working. According to your PSP kernel DIT should be supported (sound/soc/davinci/davinci-mcasp.c). So far all I can hear is noise. I found a checklist (22.3.8.3.2 Transmit DIT Clock and Frame Sync Generation) and there are differences in XFMT settings. According to the documentation rotation should be 0x0 or 0x2 depending on data alignment (left/right), but the driver had 0x6. The mask is also different. The user data registers won't be touched.

What is the proper S/PDIF configuration for am335x? Is there any reference hardware that is working with S/PDIF?

Yegor

  • So far I've made following settings:

    created new struct snd_platform_data for S/PDIF

    static struct snd_platform_data am335x_evm_alekto2_snd_spdif_data1 = {
            .tx_dma_offset  = 0x46400000,   /* McASP1 */
            /*.rx_dma_offset        = 0x46400000,*/
            .op_mode        = DAVINCI_MCASP_DIT_MODE,
            .num_serializer = ARRAY_SIZE(am335x_evm_spdif_serializer_direction1),
            .tdm_slots      = 2,
            .serial_dir     = am335x_evm_spdif_serializer_direction1,
            .asp_chan_q     = EVENTQ_2,
            .version        = MCASP_VERSION_3,
            .txnumevt       = 32,
    };

    Made changes regarding TRM to McASP register settings:

    - clock is derived from 24MHz

    - for 48000Hz divide the clock to get 6MHz (128 * 48000)

    /* 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 16 bits */
            mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0x0000FFFF);

            /* Set the TX format : 0 bit right rotation, 32 bit slot, Pad 0
               and LSB first */
            mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
                                                    TXROT(0) | 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, AHCLKXE | AHCLKXDIV(3));

            /* Enable the DIT */
            mcasp_set_bits(dev->base + DAVINCI_MCASP_TXDITCTL_REG, DITEN);
    }

    What about DIT Channel Status and User Data Register Files (DITCSRA0-5, DITUDRA0-5)? Haven't seen them being configured in the driver source code.

  • We made measurements and it looks like one byte is missing. We send 0x55ff and as you can see from the osci picture only 0xff was really transfered: