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

 

  1.   1
  2.   摘要
  3.   商标
  4. 简介
  5. 软件架构
  6. 声卡信息
  7. McASP - 外部信号
  8. MCASP 时钟生成和配置
  9. 虚拟声卡 DTS 更改
  10. 单 DAI 链路或单声卡
  11. 多 DAI 链路 - 单卡但多个子器件
  12. MCASP - 实际示例
  13. 10McASP 作为接收器
    1. 10.1 ADC 或编解码器作为时钟主器件
    2. 10.2 器件树更改 - 编解码器作为主器件,MCASP 作为从器件
  14. 11MCASP 作为发送器
    1. 11.1 器件树更改 - 编解码器作为从器件,MCASP 作为主器件
  15. 12参考资料

器件树更改 - 编解码器作为从器件,MCASP 作为主器件

许多 ADC 无法自行生成时钟,必须作为时钟从器件运行。由于 McASP 从 ADC 接收数据,因此宜将其 Rx 时钟引脚配置为输出,并生成将驱动到 ADC 时钟引脚的时钟。请记住,McASP 具有整数时钟分频器。如果器件的 AUXCLK 运行频率可用于在所需频率下生成所有必要的 McASP Rx 时钟,则 AHCLKR、ACLKR 和 AFSR 都将在内部生成,并全部配置为输出,如下图所示。

 ADC 作为时钟从器件,所有 McASP 时钟均在内部生成图 11-1 ADC 作为时钟从器件,所有 McASP 时钟均在内部生成

需要注意的重要事项:

  • 所有 McASP Rx 时钟都是输出。
  • AHCLKR 由 McASP 驱动。这是因为 ADC 通常需要高频时钟才能运行。如需了解更多信息,请参阅器件特定 ADC 数据手册。

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

在上述情况下,时钟生成如下图所示:

 ADC 作为时钟从器件,Rx 时钟在内部生成图 11-2 ADC 作为时钟从器件,Rx 时钟在内部生成

AUXCLK 馈送 AHCLKRDIV,而 AHCLKRDIV 馈送 ACLKRDIV,ACLKRDIV 馈送 Rx FSG。

参考: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";
};

在许多情况下,AUXCLK 的运行频率不能分频为所需的位时钟和帧同步速率(请记住,McASP 只有整数分频器,有时计算结果无法满足需求)。在这种情况下,必须将某种适当的外部时钟源馈送到 AHCLKR 引脚,然后进行分频以生成位时钟和帧同步。图 7 展示了这一场景。

 ADC 作为时钟从器件,外部主时钟图 11-3 ADC 作为时钟从器件,外部主时钟

外部时钟同时馈送 ADC 的 MCLK 和 AHCLKR 引脚。下图展示了此场景的时钟生成。

 ADC 作为时钟从器件,外部主时钟用于 Rx 时钟生成图 11-4 ADC 作为时钟从器件,外部主时钟用于 Rx 时钟生成

在这种情况下,不使用 AUXCLK;因此不使用 AHCLKRDIV。外部主时钟源用于生成 ACLKR 和 AFSR 信号,然后将这些信号馈送到 ADC 的 BCK 和 LRCK 引脚,以满足 ADC 充当时钟从器件的要求。

假设该外部时钟源向 AUDIO_EXT_REFCLK0 提供时钟并在 AM62x 上使用 MCASP2,则器件树需要添加以下线路:

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