SDAA199 December   2025 AM620-Q1 , AM625 , AM625-Q1 , AM62A3 , AM62A3-Q1 , AM62A7 , AM62A7-Q1 , AM62P , AM62P-Q1

 

  1.   1
  2.   Abstract
  3.   Trademarks
  4. Introduction
  5. Software Architecture
  6. Sound Card Information
  7. McASP - External Signals
  8. MCASP Clock Generation and Configurations
  9. Dummy Sound Card DTS Changes
  10. Single DAI Link or a Single Sound Card
  11. Multiple DAI Links - Single Card but Multiple Sub-Devices
  12. MCASP - Practical Examples
  13. 10McASP as a Receiver
    1. 10.1 ADC or Codec as Clock Master
    2. 10.2 Device Tree Changes - Codec as Master and MCASP as Slave
  14. 11MCASP as Transmitter
    1. 11.1 Device Tree Changes - With Codec as Slave and MCASP as Master
  15. 12References

Device Tree Changes - With Codec as Slave and MCASP as Master

Many ADCs do not have the ability to generate clocks themselves and must be operated as clock slaves. Since McASP receives data from the ADC, it is appropriate to configure its Rx clock pins as outputs, and generate clocks that will be driven into the ADC’s clock pins. Recall that McASP has integer clock dividers. If the device’s AUXCLK runs at a frequency that can be used to generate all of the necessary McASP Rx clocks at the desired frequencies, then AHCLKR, ACLKR, and AFSR will all be generated internally and all configured as outputs, as shown in the following figure.

 ADC as Clock Slave, All McASP Clocks Generated Internally Figure 11-1 ADC as Clock Slave, All McASP Clocks Generated Internally

Important things to note:

  • All McASP Rx clocks are outputs.
  • AHCLKR is driven out of McASP. This is because ADCs usually require a high-frequency clock for operation. For more information, see the device-specific ADC data manual.

clocks {
                /* 25MHz reference crystal */
                ref25: oscillator {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
                        clock-frequency = <24576000>;
            clock-output-names = "mclk_24m576";
                };
        };
 
        dep_audio: sound-tac5112 {
                compatible = "simple-audio-card";
                simple-audio-card,name = "AM62x-TAC5112-DEP";
                simple-audio-card,format = "i2s";
                simple-audio-card,bitclock-master = <&master>;
                simple-audio-card,frame-master  = <&master>;
        simple-audio-card,bitclock-inversion;
 
        simple-audio-card,widgets =
            "Line", "Line In",
            "Line", "Line Out";
        simple-audio-card,routing =
            "AIN1", "Line In",
            "Line Out", "OUT1";
 
                master: simple-audio-card,cpu {
                        sound-dai = <&mcasp0>;
            system-clock-direction-out;
                };
 
            master1: simple-audio-card,codec {
                        sound-dai = <&dep_codec>;
                };
        };
};
 
    main_mcasp0_pins_default: main-mcasp0-pins-default {
        pinctrl-single,pins = <
            /* Currently unused on the daughtercard */
             AM62X_IOPAD(0x01A8, PIN_OUTPUT, 0)  /* (D20) MCASP0_AFSR */
             AM62X_IOPAD(0x01A4, PIN_OUTPUT, 0)  /* (B20) MCASP0_ACLKR */
             AM62X_IOPAD(0x01A0, PIN_OUTPUT, 0)  /* (E18) MCASP0_AXR0 */
             AM62X_IOPAD(0x019C, PIN_INPUT, 0)  /* (B18) MCASP0_AXR1 */
        >;
    };
 
&mcasp0 {
    status = "okay";
    #sound-dai-cells = <0>;
 
    pinctrl-names = "default";
    pinctrl-0 = <&main_mcasp0_pins_default>;
 
    op-mode = <0>;          /* MCASP_IIS_MODE */
    tdm-slots = <2>;
 
    auxclk-fs-ratio = <2177>;
 
    serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
           1 2 0 0
           0 0 0 0
           0 0 0 0
           0 0 0 0
    >;
};

In the above case, the clock generation is shown in the following figure:

 ADC as Clock Slave, Rx Clocks Generated Internally Figure 11-2 ADC as Clock Slave, Rx Clocks Generated Internally

The AUXCLK feeds the AHCLKRDIV, which feeds ACLKRDIV, which feeds the Rx FSG.

Ref: k3-am62-main.dtsi

mcasp0: audio-controller@2b00000 {
        compatible = "ti,am33xx-mcasp-audio";
        reg = <0x00 0x02b00000 0x00 0x2000>,
              <0x00 0x02b08000 0x00 0x400>;
        reg-names = "mpu", "dat";
        interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>,
                     <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
        interrupt-names = "tx", "rx";
 
        dmas = <&main_bcdma 0 0xc500 0>, <&main_bcdma 0 0x4500 0>;
        dma-names = "tx", "rx";
 
        clocks = <&k3_clks 190 0>;
        clock-names = "fck";
        assigned-clocks = <&k3_clks 190 0>;
        assigned-clock-parents = <&k3_clks 190 2>;
        power-domains = <&k3_pds 190 TI_SCI_PD_EXCLUSIVE>;
        status = "disabled";
};
 
mcasp1: audio-controller@2b10000 {
        compatible = "ti,am33xx-mcasp-audio";
        reg = <0x00 0x02b10000 0x00 0x2000>,
              <0x00 0x02b18000 0x00 0x400>;
        reg-names = "mpu", "dat";
        interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
                     <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
        interrupt-names = "tx", "rx";
 
        dmas = <&main_bcdma 0 0xc501 0>, <&main_bcdma 0 0x4501 0>;
        dma-names = "tx", "rx";
 
        clocks = <&k3_clks 191 0>;
        clock-names = "fck";
        assigned-clocks = <&k3_clks 191 0>;
        assigned-clock-parents = <&k3_clks 191 2>;
        power-domains = <&k3_pds 191 TI_SCI_PD_EXCLUSIVE>;
        status = "disabled";
};
 
mcasp2: audio-controller@2b20000 {
        compatible = "ti,am33xx-mcasp-audio";
        reg = <0x00 0x02b20000 0x00 0x2000>,
              <0x00 0x02b28000 0x00 0x400>;
        reg-names = "mpu", "dat";
        interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
                     <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
        interrupt-names = "tx", "rx";
 
        dmas = <&main_bcdma 0 0xc502 0>, <&main_bcdma 0 0x4502 0>;
        dma-names = "tx", "rx";
 
        clocks = <&k3_clks 192 0>;
        clock-names = "fck";
        assigned-clocks = <&k3_clks 192 0>;
        assigned-clock-parents = <&k3_clks 192 2>;
        power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
        status = "disabled";
};

In many cases, the AUXCLK is running at a frequency that cannot be divided down to the desired bit clock and frame sync rates (recall that McASP only has integer dividers - sometimes the math does not workout). In that case, an appropriate external clock source of some kind must be fed to the AHCLKR pin and then divided down to generate bit clock and frame sync. Figure 7 illustrates this scenario.

 ADC as Clock Slave, External Master Clock Figure 11-3 ADC as Clock Slave, External Master Clock

The external clock feeds both the ADC’s MCLK and the AHCLKR pin. Clock generation for this scenario is illustrated in the following figure.

 ADC as Clock Slave, External Master Clock Used for Rx Clock
                    Generation Figure 11-4 ADC as Clock Slave, External Master Clock Used for Rx Clock Generation

In this case, AUXCLK is not used; therefore, AHCLKRDIV is not used. The external master clock source is used to generate the ACLKR and AFSR signals, which are then fed to the ADC’s BCK and LRCK pins, satisfying the ADC’s requirement to act as a clock slave.

Assuming that this external clock source is providing the clocks to AUDIO_EXT_REFCLK0 and using MCASP2 on AM62x then the Device tree needs to add the following lines:

    fixed_audio_refclk: clk-0 {
        status = "okay";
 
        #clock-cells = <0>;
        compatible = "fixed-clock";
        clock-frequency = <24576000>;
    };
 
    pinctrl-0 = <&board_pins_refclk>;
 
    board_pins_mcasp2: board-pins-mcasp2 {
        pinctrl-single,pins = <
            AM62X_IOPAD(0xf41d0, PIN_OUTPUT, 8) /* [Speaker_Audio_FSYNC] (A15) UART0_CTSn.MCASP2_AFSX */
            AM62X_IOPAD(0xf41d4, PIN_OUTPUT, 8) /* [Speaker_Audio_CLK] (B15) UART0_RTSn.MCASP2_ACLKX */
            AM62X_IOPAD(0xf41d8, PIN_OUTPUT, 8) /* [Speaker_Audio_OUT] (C15) MCAN0_TX.MCASP2_AXR0 */
        >;
    };
 
    board_pins_refclk: board-pins-refclk {
        pinctrl-single,pins = <
            AM62X_IOPAD(0xf4190, PIN_INPUT, 2) /* [Audio_EXT_Refclk0] (AE22) RGMII2_RD3.AUDIO_EXT_REFCLK0 */
            AM62X_IOPAD(0xf41f0, PIN_INPUT, 0) /* [Ext_Refclk1] (A18) EXT_REFCLK1.EXT_REFCLK1 */
            AM62X_IOPAD(0xf413c, PIN_OUTPUT, 7) /* [Audio_Refclk_Enable] (AE18) RGMII1_TD2.GPIO0_77 */
        >;
    };
     
&mcasp2 {
    status = "okay";
    #sound-dai-cells = <0>;
 
    /* CLOCKS:
     * BOARD_AUDIO_EXT_REFCLK0 <192 12> --> AHCLKR IN <192 9>
     * BOARD_AUDIO_EXT_REFCLK0 <192 18> --> AHCLKX IN <192 15>
     * REFCLK runs at 24,576 MHz
     */
    assigned-clocks        = <&k3_clks 192 9>, <&k3_clks 192 15>;
    assigned-clock-parents = <&k3_clks 192 12>, <&k3_clks 192 18>;
    assigned-clock-rates   = <24576000>, <24576000>;
 
    pinctrl-names = "default";
    pinctrl-0 = <&board_pins_mcasp2>;
 
    op-mode = <0>;          /* MCASP_IIS_MODE */
    tdm-slots = <2>;
 
    serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
           1 0 0 0
           0 0 0 0
           0 0 0 0
           0 0 0 0
    >;
    tx-num-evt = <0>;
    rx-num-evt = <0>;
};