瑞芯微Rockchip开发者社区
直播中

zhongnian

8年用户 1315经验值
擅长:MEMS/传感技术
私信 关注
[问答]

RK3288的HDMI和Codec怎样实现同时输出音频呢

怎样判断hdmi对应的是哪个pcm设备呢?RK3288的HDMI和Codec怎样实现同时输出音频呢?

回帖(1)

邢钊楚

2022-3-4 09:42:46
说明:本文适用于 RK3288 kernel4.4 SDK 版本。

RK3288 的 HDMI 和 codec 共用一组 i2s 。如果需要 HDMI 和 Codec 同时输出音频,直接使用 SDK 自带的 hdmi_analog_sound 节点配置。如果需要 HDMI 和 codec 可以单独输出,需要将 HDMI 单独注册成一个 PCM 设备。
注:hdmi_analog_sound 和 simple-audio-card 这两种注册方式只能二选一。

HDMI 和 Codec 同时输出

方案一:直接使用 hdmi_analog_sound 默认节点配置( 以 RT5640 为例 )

//RK3288 kernel4.4
/ {
    hdmi_analog_sound: hdmi-analog-sound {
        status = "okay";
                compatible = "rockchip,rk3288-hdmi-analog",
                                "rockchip,rk3368-hdmi-analog";
                rockchip,model = "rockchip,rt5640-codec";
                rockchip,cpu = <&i2s>;
                rockchip,codec = <&rt5640>, <&hdmi>;
                rockchip,widgets =
                        "Microphone", "Microphone Jack",
                        "Headphone", "Headphone Jack";
                rockchip,routing =
                        "MIC1", "Microphone Jack",
                        "MIC2", "Microphone Jack",
                        "Microphone Jack", "micbias1",
                        "Headphone Jack", "HPOL",
                        "Headphone Jack", "HPOR";
        };
};

&i2s {
    status = "okay";
};

&hdmi{
    status = "okay";
};

&i2c2 {
        status = "okay";
        rt5640: rt5640@1c {
                #sound-dai-cells = <0>;
                compatible = "realtek,rt5640";
                reg = <0x1c>;
                clocks = <&cru SCLK_I2S0_OUT>;
                clock-names = "mclk";
                interrupt-parent = <&gpio6>;
                interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2s0_mclk>;
        };
};

方案二:关闭上层 HDMI 设备插入检测,DTS 用 simple-audio-card 注册 Codec 声卡。
1、上层注释掉 hdmi 设备插入的检测:

diff --git a/services/java/com/android/server/WiredAccessoryManager.java b/services/java/com/android/server/WiredAccessoryManager.java
index c8d3510..2fb231e 100644
--- a/services/java/com/android/server/WiredAccessoryManager.java
+++ b/services/java/com/android/server/WiredAccessoryManager.java
@@ -374,7 +374,7 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
             //
             // If the kernel does not have an "hdmi_audio" switch, just fall back on the older
             // "hdmi" switch instead.
-            uei = new UEventInfo(NAME_HDMI_AUDIO, BIT_HDMI_AUDIO, 0);
+/*            uei = new UEventInfo(NAME_HDMI_AUDIO, BIT_HDMI_AUDIO, 0);
             if (uei.checkSwitchExists()) {
                 retVal.add(uei);
             } else {
@@ -385,7 +385,7 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
                     Slog.w(TAG, "This kernel does not have HDMI audio support");
                 }
             }
-
+*/
             return retVal;
         }

2、simple-audio-card 注册 Codec 声卡

//RK3288 kernel4.4
/{
    rt5640_codec: rt5640-codec{
                status = "okay";
                compatible = "simple-audio-card";
                simple-audio-card,format = "i2s";
                simple-audio-card,name = "rockchip,rt5640-codec";
                simple-audio-card,mclk-fs = <512>;
                simple-audio-card,widgets =
                        "Microphone", "Microphone Jack",
                        "Headphone", "Headphone Jack";
                simple-audio-card,routing =
                        "MIC1", "Microphone Jack",
                        "MIC2", "Microphone Jack",
                        "Microphone Jack", "micbias1",
                        "Headphone Jack", "HPOL",
                        "Headphone Jack", "HPOR";

                simple-audio-card,dai-link@0 {
                        format = "i2s";
                        cpu {
                                sound-dai = <&i2s>;
                        };
                        codec {
                                sound-dai = <&rt5640>;
                        };
                };
};

&i2s {
    status = "okay";
};

&i2c2 {
        status = "okay";
        rt5640: rt5640@1c {
                #sound-dai-cells = <0>;
                compatible = "realtek,rt5640";
                reg = <0x1c>;
                clocks = <&cru SCLK_I2S0_OUT>;
                clock-names = "mclk";
                interrupt-parent = <&gpio6>;
                interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2s0_mclk>;
        };
};

HDMI 和 codec 单独输出


实现 HDMI 和 codec 音频单独输出需要将 hdmi 单独注册成一个 PCM 设备,HDMI 设备插入后上层会切换输出设备为 AUDIO_DEVICE_OUT_HDMI ,然后在 HAL 层打开对应的 PCM 设备即可。

DTS配置如下:

//RK3288 kernel4.4
/{
    rt5640_codec: rt5640-codec{
        status = "okay";
        compatible = "simple-audio-card";
        simple-audio-card,format = "i2s";
        simple-audio-card,name = "rockchip,rt5640-codec";
        simple-audio-card,mclk-fs = <512>;
        simple-audio-card,widgets =
            "Microphone", "Microphone Jack",
            "Headphone", "Headphone Jack";
        simple-audio-card,routing =
            "MIC1", "Microphone Jack",
            "MIC2", "Microphone Jack",
            "Microphone Jack", "micbias1",
            "Headphone Jack", "HPOL",
            "Headphone Jack", "HPOR";

        simple-audio-card,dai-link@0 {
            format = "i2s";
            cpu {
                sound-dai = <&i2s>;
            };
            codec {
                sound-dai = <&rt5640>;
            };
        };
        simple-audio-card,dai-link@1 {
            format = "i2s";
            cpu {
                sound-dai = <&i2s>;
            };
            codec {
                sound-dai = <&hdmi>;
            };
        };
    };
};

&hdmi_analog_sound {
    status = "disabled";
};

&i2s {
    status = "okay";
};

&i2c2 {
        status = "okay";
        rt5640: rt5640@1c {
                #sound-dai-cells = <0>;
                compatible = "realtek,rt5640";
                reg = <0x1c>;
                clocks = <&cru SCLK_I2S0_OUT>;
                clock-names = "mclk";
                interrupt-parent = <&gpio6>;
                interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2s0_mclk>;
        };
};

注册成功后,可以通过 adb 查看注册上的 pcm设备。

rk3228:/ # ls dev/snd
ls dev/snd
. .. controlC0 pcmC0D0c pcmC0D0p pcmC0D1p timer

其中 pcmC0D1p 对应的就是 HDMI pcm 设备,然后在 hal 层调用 pcmC0D1p ,修改如下:

hardware/rockchip/audio/tinyalsa_hal$ git diff .
diff --git a/tinyalsa_hal/audio_hw.c b/tinyalsa_hal/audio_hw.c
index 13dd42e..fd7c664 100755
--- a/tinyalsa_hal/audio_hw.c
+++ b/tinyalsa_hal/audio_hw.c
@@ -615,7 +615,7 @@ static int start_output_stream(struct stream_out *out)
             }
#endif
#endif
-            out->pcm[PCM_CARD_HDMI] = pcm_open(PCM_CARD_HDMI, out->pcm_device,
+            out->pcm[PCM_CARD_HDMI] = pcm_open(0, 1,
                                                 PCM_OUT | PCM_MONOTONIC, &out->config);
             if (out->pcm[PCM_CARD_HDMI] &&
                     !pcm_is_ready(out->pcm[PCM_CARD_HDMI])) {
              
注:具体 hdmi 对应的是哪个 pcm 设备需要根据实际情况来定,如果不清楚怎么确认,底层可以先通过 tinyalsa 来确定 hdmi 的 pcm 设备,然后参照上述 hal 层的代码修改成对应的 hdmi pcm 设备 即可。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分