ADAU1977 Linux Driver LRCLK Mode

Hello,

I have a few problems integrating the ADAU1977 with the help of the Linux driver from Analog Devices and I would be happy if someone can help me.

At first a little overview about my system:

Hardware:

     - NXP i.MX 8MN Eval-Board

     - ADAU1977 is connected over the SAI3 Interface of the NXP board

Software:

     - Device-Tree for the codec and sound-card:    

   adau_sound {
        compatible = "simple-audio-card";
        simple-audio-card,name = "adau1977";
        simple-audio-card,format = "i2s";
        simple-audio-card,bitclock-master = <&sai_dai>;
        simple-audio-card,frame-master = <&sai_dai>;
        simple-audio-card,widgets =
            "Line", "Analog In1",
            "Line", "Analog In2",
            "Line", "Analog In3",
            "Line", "Analog In4";
        simple-audio-card,routing =
            "AIN1", "Analog In1",
            "AIN2", "Analog In2",
            "AIN3", "Analog In3",
            "AIN4", "Analog In4";
        satus="okay";

        sai_dai: simple-audio-card,cpu {
            sound-dai = <&sai3>;
        };

        codec_dai: simple-audio-card,codec {
            sound-dai = <&adau1977_i2c>;
            clocks = <&clk IMX8MN_CLK_SAI3_ROOT>;
            clock-names = "mclk";
            mclk-fs = <512>;
        };
    };

{...}

    adau1977_i2c: adau1977@11 {
        compatible = "adi,adau1977";
        reg = <0x11>;
        status = "okay";
        #sound-dai-cells = <0>;

        AVDD-supply = <&codec_supply_AVDD>;
        reset-gpios = <&pca6416 8 GPIO_ACTIVE_HIGH>;
    };

Now the description of my problem:

     - the ADAU1977 is running in LRCLK-Mode

     - Now I have found the code section in the function adau1977_set_sysclk (…) in which the register ADAU1977_REG_PLL is written:

       

    switch (source) {
    case ADAU1977_SYSCLK_SRC_MCLK:
        clk_src = 0;
        break;
    case ADAU1977_SYSCLK_SRC_LRCLK:
        clk_src = ADAU1977_PLL_CLK_S;
        break;
    default:
        return -EINVAL;
    }

         --> However, I don't quite know how to pass the corresponding transfer parameter source to the function. Is there a way to store this setting in the device tree?

     - If I change the function adau1977_set_sysclk () so that source = ADAU1977_SYSCLK_SRC_LRCLK is set in the head, the registers are written correctly via I2C, but when I start a recording via arecord, the PLL is not locked and therefore the ADC does not output a signal. The signals BCLK and LRCLK are at the correct frequency, I have measured them on the oscilloscope.

I was able to fix the problem in the following way:

     - Since I only have to set the ADC setting once in my application, it is sufficient for me to set the required registers once to the required value when booting. So I took the source-code of the driver, commented out all parts where any registers are set and only added the writing of the following registers in the adau1977_probe () function:

    

regmap_write(adau1977->regmap, ADAU1977_REG_PLL, 0x50);     // 0x50 = Clock Source LRCLK && Auto Mute at PLL Unlockeds
regmap_write(adau1977->regmap, ADAU1977_REG_POWER, 0x11);   // 0x11 = Reset + Power On

      --> With these changes the communication with the ADC works without problems, the device tree has remained the same, the PLL locks immediately and the ADC sends the corresponding data with the same BCLK and LRCLK.

Now my questions:

     - Did anyone know this problem?

     - Has the driver been tested for an ADAU1977 in LRCLK mode? 

     - Do you have any idea where could be issues and why the PLL is not locked with the same register settings?

Thank you in advance for your support and I would be very happy to hear from you.

Top Replies

Parents
  • +1
    •  Analog Employees 
    on Jun 10, 2021 7:54 AM

    Hi,

    Unfortunately the simple card platform driver is not flexible enough to allow selection of MCLK source.

    You can see in this line that function snd_soc_dai_set_sysclk is called but if we look at what parameters it pass to the codec driver we can see that source is always set to 0 soc-dai.c - sound/soc/soc-dai.c.

    So either you create your own platform driver (you can start form simple card) or you hardcode the PLL source in ADAU1977 driver as you already did.

    Next can you please share with us the oscilloscope prints with signals BCLK and LRCLK captured? I'm interested which frequencies do they have.

    And also please share a register dump took by reading /sys/kernel/debug/regmap/"adau i2c addr"/registers

  • Hi,

    Thanks for your reply! So at least I can be sure that I haven't overlooked anything. I think I'll stick with my variant to write the registers hard-coded.

    Unfortunately, I currently don't have any recordings from the oscilloscope at hand.

Reply Children
No Data