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.

[参考译文] TLV320AIC3110:在我的生命周期内、我可以##39;t 使音频芯片 DTBO 加载或 ALSA 在 Raspberry Pi 中运行5

Guru**** 2379440 points
Other Parts Discussed in Thread: TLV320AIC3110
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/audio-group/audio/f/audio-forum/1456663/tlv320aic3110-for-the-life-of-me-i-can-t-make-audio-chip-dtbo-loaded-or-alsa-working-in-raspberry-pi-5

器件型号:TLV320AIC3110

工具与软件:

我在上个月一直在尝试获取我设计的 HAT、它包含 TI TLV320AIC3110音频代码芯片、可在启动时识别、甚至可通过使用 modprobe 加载驱动程序。 我无法让 ALSA 看到芯片。 这是在 RPI5上

我确实尝试在网上搜索解决方案、但似乎什么都不起作用。

我正在使用 Ubuntu 24.04服务器、因为我需要 Ubuntu 帧和 wpe-mir kiosk 用于没有 HDMI 连接的专用物联网。 此设置不提供 VCdbg 我似乎无法获取任何调试信息。

如果有人能指出问题所在、我会将我的.dts 文件发布在这里。


/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2712"; 
    /* "brcm,bcm2712", "brcm,bcm2711", "brcm,bcm2835"; */

    /* 
     * Fragment@0: Enable the I2S (PCM) interface 
     */
    fragment@0 {
        target = <&i2s>;
        __overlay__ {
            status = "okay";
            pinctrl-names = "default";
            pinctrl-0 = <&tlv320aic3110_pins>;
            
            #sound-dai-cells = <0>;
            brcm,enable-mclk = <1>;           // Enable MCLK output
            brcm,mclk-rate = <12288000>;      // 12.288MHz MCLK rate
            clock-frequency = <12288000>;      // Master clock frequency
            brcm,tx-channels = <2>;           // Stereo output
            brcm,rx-channels = <2>;           // Stereo input
        };
    };

    fragment@1 {
            target-path = "/";
            __overlay__ {
                    codec_1v8_reg: codec-1v8-reg {
                        compatible = "regulator-fixed";
                        regulator-name = "tlv320aic3104_1v8";
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1800000>;
                        regulator-always-on;
                    };
            };
    };

    fragment@2 {
            target = <&gpio>;
            __overlay__ {
                    codec_rst: codec-rst {
                            brcm,pins = <13>;
                            brcm,function = <0>;
                    };
            };
    };

    fragment@3 {
        target = <&i2c1>;
        __overlay__ {
            #address-cells = <1>; /* Single cell for I2C address */
            #size-cells = <0>;    /* No size cells for I2C devices */
            status = "okay";

            tlv320aic3110: tlv320aic3110@18 {
                compatible = "ti,tlv320aic3110", "ti,tlv320aic311x", "ti,tlv320aic3x";
                reg = <0x18>;
                #sound-dai-cells = <0>;
                status = "okay";
                /* DRVDD-supply = <&vdd_3v3_reg>; */
                AVDD-supply = <&vdd_3v3_reg>;
                DVDD-supply = <&codec_1v8_reg>;
                HPVDD-supply = <&vdd_3v3_reg>;
                IOVDD-supply = <&vdd_3v3_reg>;
                SPRVDD-supply = <&vdd_5v0_reg>;
                SPLVDD-supply = <&vdd_5v0_reg>;
                clocks = <&mclk_external>;
                mclk-frequency = <12288000>;
                gpio-controller;
                resets = <&gpio_reset>; /* active-high GPIO4_13 */
                reset-gpios = <&gpio 13 0>; /* GPIO 13 as active high */

                // Debug properties
                debug;
                linux,debug;
            };
        };
    };

    fragment@4 {
        target-path = "/";
        __overlay__ {
            gpio_reset: gpio-reset {
                compatible = "gpio-reset";
                reset-gpios = <&gpio 13 0>; /* GPIO 13 active high */
                #reset-cells = <0>;
                reset-delay-us = <10000>;
                status = "okay";
            };
        };
    };

    fragment@5 {
        target = <&sound>;
        __overlay__ {
            compatible = "simple-audio-card";
            simple-audio-card,name = "TLV320AIC3110";
            simple-audio-card,widgets =
                "Microphone", "Mic Jack",
                "Speaker", "Speaker Left",
                "Speaker", "Speaker Right";
            simple-audio-card,routing =
                "Speaker Left", "SPL",
                "Speaker Right", "SPR",
                "MIC1LP", "Mic Jack",
                "MIC1LM", "Mic Jack";
            status = "okay";

            simple-audio-card,dai-link {
                /* I2S format settings */
                format = "i2s";
                bitclock-master = <&codec_dai>;
                frame-master = <&codec_dai>;
                
                /* DAI link format */
                dai-tdm-slot-num = <2>;      // Stereo
                dai-tdm-slot-width = <32>;   // 32 bits per sample

                cpu_dai: cpu {
                    sound-dai = <&bcm2835_i2s>;
                    dai-tdm-slot-num = <2>;
                    dai-tdm-slot-width = <32>;
                };

                codec_dai: codec {
                    sound-dai = <&tlv320aic3110>;
                    
                    /* Clock settings */
                    system-clock-frequency = <12288000>;  // 12.288MHz MCLK
                    system-clock-direction-out;           // MCLK is input to codec
                    
                    /* Format settings */
                    frame-inversion;                      // Frame sync polarity
                    bitclock-inversion;                   // Clock polarity
                };
            };
        };
    };

    fragment@6 {
        target-path = "/";
        __overlay__ {
            mclk_external: mclk_external {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency = <12288000>; // 12.288 MHz
            };
        };
    };

    fragment@7 {
        target = <&gpio>;
        __overlay__ {
            tlv320aic3110_pins: tlv320aic3110_pins {
                brcm,pins = <18 19 20 21>;     // PCM_CLK, PCM_FS, PCM_DIN, PCM_DOUT
                brcm,function = <4>;           // ALT0 for I2S function
                brcm,pull = <0>;               // No pull-up/down
            };
        };
    };

};

如有任何帮助、将不胜感激。 我还可以提供 PCB 原理图

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    只是添加一点、我可以将 i2cdetect -y 1的器件视为0x18、并可以向其发送命令

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    最后、我成功加载了器件树重叠文件、并且器件驱动程序与 ALSA 一起工作。

    但是、我无法确定要具有的确切命令:

    1. 导向放大器和扬声器的输出
    2. 控制扬声器的音量
    3. 收听任何输出。

    我有一个48kHz 文件、该文件应通过 ALSA 和 PulseAudio 播放

    以下示例是使用外部振荡器、1.8V 数字和正确复位的器件树覆盖文件(.dts)的最佳工作示例、以供参考:

    /dts-v1/;
    /plugin/;
    
    / {
        compatible = "brcm,bcm2712", "brcm,bcm2711", "brcm,bcm2835";
    
        fragment@0 {
            target = <&i2s>;  // For RPi4
            __overlay__ {
                status = "okay";
                #sound-dai-cells = <0>;
                brcm,tx-channels = <2>;
                brcm,rx-channels = <2>;
            };
        };
    
        /* 
         * Fragment@1: Enable the I2S (PCM) interface 
         * Additional for RPi5
         */
        /*
        fragment@1 {
            target = <&i2s_clk_consumer>;
            __overlay__ {
                status = "okay";
                
                #sound-dai-cells = <0>;
                compatible = "snps,designware-i2s";
                clock-names = "i2sclk";
                tx-channels = <2>;
                rx-channels = <2>;
                
                // brcm,enable-mclk = <1>;           // Enable MCLK output
                // brcm,mclk-rate = <12288000>;      // 12.288MHz MCLK rate
                // clock-frequency = <12288000>;      // Master clock frequency
                // brcm,tx-channels = <2>;           // Stereo output
                // brcm,rx-channels = <2>;           // Stereo input
                // brcm,slave = <1>;                 // I2S controller as slave
                
            };
        };
         */
    
        fragment@2 {
                target-path = "/";
                __overlay__ {
                        codec_1v8_reg: codec-1v8-reg {
                            compatible = "regulator-fixed";
                            regulator-name = "tlv320aic3104_1v8";
                            regulator-min-microvolt = <1800000>;
                            regulator-max-microvolt = <1800000>;
                            regulator-always-on;
                        };
                };
        };
     
        fragment@3 {
            target = <&i2c1>;
            __overlay__ {
                #address-cells = <1>; /* Single cell for I2C address */
                #size-cells = <0>;    /* No size cells for I2C devices */
                status = "okay";
    
                tlv320aic3110: tlv320aic3110@18 {
                    compatible = "ti,tlv320aic3110", "ti,tlv320aic311x"; 
                    reg = <0x18>;
                    #sound-dai-cells = <0>;
                    // system-clock-frequency = <12288000>;  // Codec clock config
                    // system-clock-direction-out;           // Codec as master
                    status = "okay";
    
                    HPVDD-supply = <&vdd_3v3_reg>;
                    SPRVDD-supply = <&vdd_5v0_reg>;
                    SPLVDD-supply = <&vdd_5v0_reg>;
                    AVDD-supply = <&vdd_3v3_reg>;
                    IOVDD-supply = <&vdd_3v3_reg>;
                    DVDD-supply = <&codec_1v8_reg>;
    
                    clocks = <&mclk_external>;
                    clock-names = "mclk";
                    // system-clk-frequency = <12288000>;
                    mclk-frequency = <12288000>;
                    // gpio-controller;
    
                    /* PLL configuration for 48kHz with 12.288MHz MCLK */
                    pll-p = <1>;
                    pll-r = <1>;
                    pll-j = <7>;
                    pll-d = <1680>;
    
                    reset-gpios = <&gpio 13 0>; // GPIO 13 as active high 
                    reset-delay-us = <10000>;     /* 10ms delay */
    
                    // Debug properties
                    debug;
                    linux,debug;
                };
            };
        };
        /*
        fragment@4 {
            target-path = "/";
            __overlay__ {
                gpio_reset: gpio-reset {
                    compatible = "gpio-reset";
                    reset-gpios = <&gpio 13 0>; // GPIO 13 active high 
                    #reset-cells = <0>;
                    reset-delay-us = <10000>;
                    status = "okay";
                };
            };
        };
         */
    
        fragment@5 {
            target = <&sound>;
            __overlay__ {
                compatible = "simple-audio-card";
                simple-audio-card,name = "TLV320AIC3110";
                simple-audio-card,format = "i2s";
                // simple-audio-card,bitclock-master = <&dailink0_master>;
                // simple-audio-card,frame-master = <&dailink0_master>;
    
                simple-audio-card,widgets =
                    "Microphone", "Mic Jack",
                    "Speaker", "Speaker Left",
                    "Speaker", "Speaker Right";
                simple-audio-card,routing =
                    "Speaker Left", "SPL",
                    "Speaker Right", "SPR",
                    "MIC1LP", "Mic Jack",
                    "MIC1LM", "Mic Jack";
                status = "okay";
    
                simple-audio-card,cpu {
                    sound-dai = <&i2s>;
                };
    
                dailink0_master: simple-audio-card,codec {
                    sound-dai = <&tlv320aic3110>;
                    clocks = <&mclk_external>;
                };
    
            };
        };
    
        fragment@6 {
            target-path = "/";
            __overlay__ {
                mclk_external: mclk_external {
                    compatible = "fixed-clock";
                    #clock-cells = <0>;
                    clock-frequency = <12288000>; // 12.288 MHz
                    clock-output-names = "mclk";
                };
            };
        };
    
    };
    

    希望这对其他人和人有所帮助、使 PLL 和放大器正常工作

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    感谢您附加 DTS 文件。 要将音频路由到输出、您可以使用此设备驱动程序中"snd_soc_dapm_route"结构中指定的措辞(https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sound/320codecs/tlv320aic31xx.c soc)。  

    在 DTS 文件中、我看到有一个小工具/路由部分、但您需要使用特定于驱动程序的语言对其进行更新。 查看驱动程序代码的"common31xx_audio_map"部分以找到起点。  

    您当前用于通过编解码器播放音频的命令是什么? 运行 alsamixer 时会发生什么情况?

    此致!
    MIR

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Mir、

    我也是 RTFM 的坚定支持者! 我当时查看了 simple-audio 和 tlv320aic31xx 驱动程序文档。 由于缺乏设备树方面的经验、无法确定正确的语法或设备驱动程序如何与设备树叠加进行交互。

    源代码相当大、如果您能将我送到相应的部分、我将不胜感激。 我仍然不知道启用 D 类放大器并向其发送输出的确切语法。 如果你有一个例子*任何地方*我会感激它。

    至于 alsamixer,它似乎知道更好的是什么被安装,并给了我一整套控制。 无法输出右/左扬声器。

    我已经尝试过了  

    aplay /web/config/sounds/news-ting-48k.wav
    speaker-test -t sine -f 800

    我添加了一个12.288Mhz 振荡器作为 MCLK (用于48kHz 播放)、结果是愚蠢的、因为我的所有声音都是44.1kHz。 我将在验证这个设计后立即改为11.2896Mhz、并从放大器/扬声器发出一些声音。
    BTW、这要求我创建/etc/asound.conf (它可以像在/etc/alsa/conf.d 中一样进行电子链接)

    pcm.!default {
        type plug
        slave {
            pcm "hw:TLV320AIC3110,0"
            rate 48000
        }
    }
    
    ctl.!default {
        type hw
        card "TLV320AIC3110"
    }

    再次感谢您的帮助、欢迎您选择样片

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    雅克、您好!

    Amixer 显示其控件是什么? 我发现这个旧的 e2e 线程、其中他们具有 AIC3100的 D 类扬声器输出、并且使用相同的驱动程序: https://e2e.ti.com/support/audio-group/audio/f/audio-forum/1209106/tlv320aic3100-class-d-speaker-wave-and-sound-quality

    您可能需要将扬声器设置为"打开"、如其帖子中所示。 对不起,我不是编写 DTS 文件或 Linux 音频系统的专家,只是为了帮助我们在正确的方向微调我们的调试。 您还有关于 PLL 的问题吗? 此外、您是否确定要为 SPLVDD 和 SPRVDD 电源供电? 您能否将原理图发送出去?

    此致!
    MIR

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我花了一些时间熟悉 Linux 源代码中的音频驱动程序和设备树(有适用于 Raspberry 的特殊版本!) 我已经"有点"找到驱动程序如何与设备树通信。 但不确定。 我会将相关部分发布在这里。

    同时、这里是我的原理图-如果你可以看到我遗漏的东西(非常可能)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是我试图理解的源代码部分:

    static const struct snd_soc_dapm_route
    common31xx_audio_map[] = {
    	/* DAC Input Routing */
    	{"DAC Left Input", "Left Data", "AIF IN"},
    	{"DAC Left Input", "Right Data", "AIF IN"},
    	{"DAC Left Input", "Mono", "AIF IN"},
    	{"DAC Right Input", "Left Data", "AIF IN"},
    	{"DAC Right Input", "Right Data", "AIF IN"},
    	{"DAC Right Input", "Mono", "AIF IN"},
    	{"DAC Left", NULL, "DAC Left Input"},
    	{"DAC Right", NULL, "DAC Right Input"},
    
    	/* HPL path */
    	{"HP Left", "Switch", "Output Left"},
    	{"HPL Driver", NULL, "HP Left"},
    	{"HPL", NULL, "HPL Driver"},
    
    	/* HPR path */
    	{"HP Right", "Switch", "Output Right"},
    	{"HPR Driver", NULL, "HP Right"},
    	{"HPR", NULL, "HPR Driver"},
    };
    
    static const struct snd_soc_dapm_route
    dac31xx_audio_map[] = {
    	/* Left Output */
    	{"Output Left", "From Left DAC", "DAC Left"},
    	{"Output Left", "From AIN1", "AIN1"},
    	{"Output Left", "From AIN2", "AIN2"},
    
    	/* Right Output */
    	{"Output Right", "From Right DAC", "DAC Right"},
    	{"Output Right", "From AIN2", "AIN2"},
    };
    
    static const struct snd_soc_dapm_route
    aic31xx_audio_map[] = {
    	/* Mic input */
    	{"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"},
    	{"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"},
    	{"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"},
    	{"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"},
    	{"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"},
    	{"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"},
    	{"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"},
    	{"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"},
    	{"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"},
    
    	{"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"},
    	{"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"},
    	{"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"},
    
    	{"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"},
    	{"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"},
    	{"MIC_GAIN_CTL", NULL, "MIC1LM P-Terminal"},
    	{"MIC_GAIN_CTL", NULL, "MIC1LM M-Terminal"},
    
    	{"ADC", NULL, "MIC_GAIN_CTL"},
    
    	{"AIF OUT", NULL, "ADC"},
    
    	/* Left Output */
    	{"Output Left", "From Left DAC", "DAC Left"},
    	{"Output Left", "From MIC1LP", "MIC1LP"},
    	{"Output Left", "From MIC1RP", "MIC1RP"},
    
    	/* Right Output */
    	{"Output Right", "From Right DAC", "DAC Right"},
    	{"Output Right", "From MIC1RP", "MIC1RP"},
    };
    
    static const struct snd_soc_dapm_route
    aic311x_audio_map[] = {
    	/* SP L path */
    	{"Speaker Left", "Switch", "Output Left"},
    	{"SPL ClassD", NULL, "Speaker Left"},
    	{"SPL", NULL, "SPL ClassD"},
    
    	/* SP R path */
    	{"Speaker Right", "Switch", "Output Right"},
    	{"SPR ClassD", NULL, "Speaker Right"},
    	{"SPR", NULL, "SPR ClassD"},
    };
    
    static const struct snd_soc_dapm_route
    aic310x_audio_map[] = {
    	/* SP L path */
    	{"Speaker", "Switch", "Output Left"},
    	{"SPK ClassD", NULL, "Speaker"},
    	{"SPK", NULL, "SPK ClassD"},
    };
    
    /*
     * Always connected DAPM routes for codec clock master modes.
     * If the codec is the master on the I2S bus, we need to power up components
     * to have valid DAC_CLK.
     *
     * In order to have the I2S clocks on the bus either the DACs/ADC need to be
     * enabled, or the P0/R29/D2 (Keep bclk/wclk in power down) need to be set.
     *
     * Otherwise the codec will not generate clocks on the bus.
     */
    static const struct snd_soc_dapm_route
    common31xx_cm_audio_map[] = {
    	{"HPL", NULL, "AIF IN"},
    	{"HPR", NULL, "AIF IN"},
    
    	{"AIF IN", NULL, "Activate I2S clocks"},
    };
    
    static const struct snd_soc_dapm_route
    aic31xx_cm_audio_map[] = {
    	{"AIF OUT", NULL, "MIC1LP"},
    	{"AIF OUT", NULL, "MIC1RP"},
    	{"AIF OUT", NULL, "MIC1LM"},
    
    	{"AIF OUT", NULL, "Activate I2S clocks"},
    };

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jaques:

    我认为 dapm_route 是驱动程序与器件进行连接的方式、其中输出对应于 Linux dts 文件中的"受电方"和输入作为"源"、并映射到.h 文件中与驱动程序文件对应的相应 i2c 命令。 我不知道为什么一个扬声器有3个路径、但我认为您确实需要将"Output Left (左输出)"连接到"Speaker Left (左扬声器)"、然后将"Speaker Left (左扬声器)"连接到"SPL ClassD"、再将"SPL ClassD"连接到"SPR"、与 SPL 类似。 也许在 DTS 文件中添加一个或所有这些连接会有所帮助。

    此致!
    MIR

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这来自示例 EVM 以及该论坛上的相应讨论: https://forum.beagleboard.org/t/custom-beaglebone-black-audio-cape-with-tlv320aic3110/21319/2

    ti,audio-routing =
    /* Source Sink /
    / output in driver*/
    /* Speaker connections /
    “Headphone Jack”, “HPL”,
    “Headphone Jack”, “HPR”,
    “Speaker”, “SPL”,
    “Speaker”, “SPR”,

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢。 MIR
    已经具有这些值。

    I * JUST NOW *注意到编解码器上的引脚11。 它有双重功能
    VOL 11 I 音量控制或麦克风检测

    如果是音量控制、那么我可能不应该将它接地。 我会尝试阅读 PDF 的更多内容、看看这意味着什么。 但是、是否有人以不同的方式接线引脚? 如何在 RPi 上进行音量控制? 是否仅适用于耳机?

    (还将尝试为 I2C 信号添加上拉电阻器)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我实际上阅读了更多关于 i2cdetect、i2cdump、i2cget 和 i2cset 的信息。 事实上、一旦加载了设备驱动程序、它便可控制 i2c 地址、但不能再与之进行实际交互。 除非您使用 危险 i2c<cmd>-f xxxx to force it.

    I used this and I get:

    i2cdump -y -f 1 0x18
    No size specified (using byte-data access)
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
    00: 00 00 01 56 03 91 04 00 00 00 00 81 81 00 80 80    ..?V???....??.??
    10: 08 00 81 81 80 80 04 00 00 00 01 0c 00 00 81 00    ?.?????...??..?.
    20: 00 00 00 00 80 11 00 00 00 00 00 00 00 00 00 00    ....??..........
    30: 00 00 00 02 32 12 03 02 02 11 10 00 01 04 00 3d    ...?2??????.??.=
    40: 0c 1c 1c 00 6f 38 00 00 00 00 00 ee 10 d8 7e e3    ???.o8.....???~?
    50: 00 00 a0 0e 00 00 00 00 7f 00 00 00 00 00 00 00    ..??....?.......
    60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    70: 00 00 00 00 00 44 00 00 00 00 00 00 00 00 00 00    .....D..........
    80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................


    现在我所要做的就是确定正确的寄存器设置、然后强制他们手动查看这是否可以解决我的问题。

    我知道我现在必须充分理解数据表  如果有人知道放大器/扬声器输出的正确设置、我全听

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    雅克、您好!

    仅供参考、米尔已长期离职。 我将通过邮件回复您、但该线程将保持正常、以防其他人有添加的内容。

    此致、
    Jeff McPherson

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jeff:

    我正在为驱动程序读取源代码(真的在尝试!) 我注意到频带中出现了这种情况:


    /* ADC dividers can be disabled by configuring them to 0 */
    static const struct aic31xx_rate_divs aic31xx_divs[] = {
    	/* mclk/p    rate  pll: r  j     d     dosr ndac mdac  aors nadc madc */
    	/* 8k rate */
    	{  512000,   8000,	4, 48,   0,	128,  48,  2,   128,  48,  2},
    	{12000000,   8000,	1, 8, 1920,	128,  48,  2,	128,  48,  2},
    	{12000000,   8000,	1, 8, 1920,	128,  32,  3,	128,  32,  3},
    	{12500000,   8000,	1, 7, 8643,	128,  48,  2,	128,  48,  2},
    	/* 11.025k rate */
    	{  705600,  11025,	3, 48,   0,	128,  24,  3,	128,  24,  3},
    	{12000000,  11025,	1, 7, 5264,	128,  32,  2,	128,  32,  2},
    	{12000000,  11025,	1, 8, 4672,	128,  24,  3,	128,  24,  3},
    	{12500000,  11025,	1, 7, 2253,	128,  32,  2,	128,  32,  2},
    	/* 16k rate */
    	{  512000,  16000,	4, 48,   0,	128,  16,  3,	128,  16,  3},
    	{ 1024000,  16000,	2, 48,   0,	128,  16,  3,	128,  16,  3},
    	{12000000,  16000,	1, 8, 1920,	128,  24,  2,	128,  24,  2},
    	{12000000,  16000,	1, 8, 1920,	128,  16,  3,	128,  16,  3},
    	{12500000,  16000,	1, 7, 8643,	128,  24,  2,	128,  24,  2},
    	/* 22.05k rate */
    	{  705600,  22050,	4, 36,   0,	128,  12,  3,	128,  12,  3},
    	{ 1411200,  22050,	2, 36,   0,	128,  12,  3,	128,  12,  3},
    	{12000000,  22050,	1, 7, 5264,	128,  16,  2,	128,  16,  2},
    	{12000000,  22050,	1, 8, 4672,	128,  12,  3,	128,  12,  3},
    	{12500000,  22050,	1, 7, 2253,	128,  16,  2,	128,  16,  2},
    	/* 32k rate */
    	{ 1024000,  32000,      2, 48,   0,	128,  12,  2,	128,  12,  2},
    	{ 2048000,  32000,      1, 48,   0,	128,  12,  2,	128,  12,  2},
    	{12000000,  32000,	1, 8, 1920,	128,  12,  2,	128,  12,  2},
    	{12000000,  32000,	1, 8, 1920,	128,   8,  3,	128,   8,  3},
    	{12500000,  32000,	1, 7, 8643,	128,  12,  2,	128,  12,  2},
    	/* 44.1k rate */
    	{ 1411200,  44100,	2, 32,   0,	128,   8,  2,	128,   8,  2},
    	{ 2822400,  44100,	1, 32,   0,	128,   8,  2,	128,   8,  2},
    	{12000000,  44100,	1, 7, 5264,	128,   8,  2,	128,   8,  2},
    	{12000000,  44100,	1, 8, 4672,	128,   6,  3,	128,   6,  3},
    	{12500000,  44100,	1, 7, 2253,	128,   8,  2,	128,   8,  2},
    	/* 48k rate */
    	{ 1536000,  48000,	2, 32,   0,	128,   8,  2,	128,   8,  2},
    	{ 3072000,  48000,	1, 32,   0,	128,   8,  2,	128,   8,  2},
    	{12000000,  48000,	1, 8, 1920,	128,   8,  2,	128,   8,  2},
    	{12000000,  48000,	1, 7, 6800,	 96,   5,  4,	 96,   5,  4},
    	{12500000,  48000,	1, 7, 8643,	128,   8,  2,	128,   8,  2},
    	/* 88.2k rate */
    	{ 2822400,  88200,	2, 16,   0,	 64,   8,  2,	 64,   8,  2},
    	{ 5644800,  88200,	1, 16,   0,	 64,   8,  2,	 64,   8,  2},
    	{12000000,  88200,	1, 7, 5264,	 64,   8,  2,	 64,   8,  2},
    	{12000000,  88200,	1, 8, 4672,	 64,   6,  3,	 64,   6,  3},
    	{12500000,  88200,	1, 7, 2253,	 64,   8,  2,	 64,   8,  2},
    	/* 96k rate */
    	{ 3072000,  96000,	2, 16,   0,	 64,   8,  2,	 64,   8,  2},
    	{ 6144000,  96000,	1, 16,   0,	 64,   8,  2,	 64,   8,  2},
    	{12000000,  96000,	1, 8, 1920,	 64,   8,  2,	 64,   8,  2},
    	{12000000,  96000,	1, 7, 6800,	 48,   5,  4,	 48,   5,  4},
    	{12500000,  96000,	1, 7, 8643,	 64,   8,  2,	 64,   8,  2},
    	/* 176.4k rate */
    	{ 5644800, 176400,	2, 8,    0,	 32,   8,  2,	 32,   8,  2},
    	{11289600, 176400,	1, 8,    0,	 32,   8,  2,	 32,   8,  2},
    	{12000000, 176400,	1, 7, 5264,	 32,   8,  2,	 32,   8,  2},
    	{12000000, 176400,	1, 8, 4672,	 32,   6,  3,	 32,   6,  3},
    	{12500000, 176400,	1, 7, 2253,	 32,   8,  2,	 32,   8,  2},
    	/* 192k rate */
    	{ 6144000, 192000,	2, 8,	 0,	 32,   8,  2,	 32,   8,  2},
    	{12288000, 192000,	1, 8,	 0,	 32,   8,  2,	 32,   8,  2},
    	{12000000, 192000,	1, 8, 1920,	 32,   8,  2,	 32,   8,  2},
    	{12000000, 192000,	1, 7, 6800,	 24,   5,  4,	 24,   5,  4},
    	{12500000, 192000,	1, 7, 8643,	 32,   8,  2,	 32,   8,  2},
    };

    我注意到我的确切振荡器频率(12.288Mhz )*12288000*不存在。 事实上,我要尝试的下一个(11.2896Mhz )也不存在。 现在、这些频率除以256后、将得到48kHz 和41.1kHz。

    因此、当我不需要 PLL 时、我可以提供这些频率、或者驱动器确切地说是12 MHz。

    ===此外还===

    代码中的此部分:

    	if (match == -1) {
    		dev_err(component->dev,
    			"%s: Sample rate (%u) and format not supported\n",
    			__func__, params_rate(params));
    		/* See below for details on how to fix this. */
    		return -EINVAL;
    	}
    	if (bclk_score != 0) {
    		dev_warn(component->dev, "Can not produce exact bitclock");
    		/* This is fine if using dsp format, but if using i2s
    		   there may be trouble. To fix the issue edit the
    		   aic31xx_divs table for your mclk and sample
    		   rate. Details can be found from:
    		   www.ti.com/.../tlv320aic3100.pdf
    		   Section: 5.6 CLOCK Generation and PLL
    		*/
    	}

    看起来很相关、因为我现在在 dmesg 中遇到了这个错误

    tlv320aic31xx-codec 1-0018:aic31xx_setup_PLL:采样率(44100)和格式不受支持 


    有什么想法吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    仔细阅读源代码后、我终于发现问题的罪魁祸首。 即使数据表建议我可以对 MCLK 使用适当的频率(我选择了12.288Mhz 和11.2896Mhz、再除以256得到48kHz 和41.1Khz)、器件驱动程序也不支持任何任意频率! 它们有一堆用于时钟速率和回放的查找表、如果您的选择不存在、驱动程序将失败。

    我修改了源代码并为我的自定义频率添加了适当的查找

    /* ADC dividers can be disabled by configuring them to 0 */
    static const struct aic31xx_rate_divs aic31xx_divs[] = {
        ...
        /* 11.2896 MHz (11289600 Hz) */
        { 11289600, 44100,  1, 7, 6800, 128,   8,  2,   128,   8,  2},
        /* 12.288 MHz (12288000 Hz) */
        { 12288000, 44100,  1, 7, 5264, 128,   8,  2,   128,   8,  2},
        	/* 11.2896 MHz (11289600 Hz) */
        { 11289600, 48000,  1, 7, 6800, 128,   8,  2,   128,   8,  2},
        /* 12.288 MHz (12288000 Hz) */
        { 12288000, 48000,  1, 8, 1920, 128,   8,  2,   128,   8,  2},
        ...
    };

    在一个有趣的战斗与 Ubuntu 编译这个,看,一切播放!

    现在、对于我涉及物联网器件的项目、我不想包含无符号的器件驱动程序、每次内核更新时都需要 DKMS 进行安装、我将重做 PCB 硬件振荡器以使用本机支持的频率。 为了练习使用、我会给 TI 的人员写一个函数、该函数可以动态地为随机频率 MCLK 和播放组合创建查找条目!

    我仍然把我的器件树文件放在这里、供其他寻找类似信息的人进一步参考。 请注意、麦克风输入未经过测试(我只能正常工作!) 如果我有问题、我们将打开另一个问题!

    感谢所有的支持。

    /dts-v1/;
    /plugin/;
    
    / {
        compatible = "brcm,bcm2712", "brcm,bcm2711", "brcm,bcm2835";
        // compatible = "brcm,bcm2835";
    
        fragment@0 {
            target = <&i2s_clk_consumer>;
            __overlay__ {
                status = "okay";
                #sound-dai-cells = <0>;
                brcm,tx-channels = <2>;
                brcm,rx-channels = <1>;
            };
        };
    
        fragment@1 {
            target-path = "/";
            __overlay__ {
                status = "okay";
    
                codec_1v8_reg: codec-1v8-reg {
                    compatible = "regulator-fixed";
                    regulator-name = "tlv320aic3104_1v8";
                    regulator-min-microvolt = <1800000>;
                    regulator-max-microvolt = <1800000>;
                    regulator-always-on;
                    status = "okay";
                };
            };
        };
     
        fragment@2 {
            target = <&i2c1>;
            __overlay__ {
                #address-cells = <1>; /* Single cell for I2C address */
                #size-cells = <0>;    /* No size cells for I2C devices */
                status = "okay";
    
                tlv320aic3110: tlv320aic3110@18 {
                    compatible = "ti-pg,tlv320aic3110", "ti,tlv320aic3110", "ti,tlv320aic311x"; 
                    reg = <0x18>;
                    #sound-dai-cells = <0>;
                    // system-clock-frequency = <12288000>;  // Codec clock config
                    // system-clock-direction-out;           // Codec as master
                    status = "okay";
    
                    HPVDD-supply = <&vdd_3v3_reg>;
                    SPRVDD-supply = <&vdd_5v0_reg>;
                    SPLVDD-supply = <&vdd_5v0_reg>;
                    AVDD-supply = <&vdd_3v3_reg>;
                    IOVDD-supply = <&vdd_3v3_reg>;
                    DVDD-supply = <&codec_1v8_reg>;
    
                    clocks = <&mclk_external>;
                    clock-names = "mclk";
                    // system-clk-frequency = <12288000>;
                    mclk-frequency = <12288000>;
                    // gpio-controller;
    
                    reset-gpios = <&gpio 13 1>; // GPIO 13 as active low reset
                    reset-delay-us = <10000>;     /* 10ms delay */
    
                    // Debug properties (must precede subnodes)
                    debug;
                    linux,debug;
    
                };
            };
        };
    
        fragment@3 {
            target = <&sound>;
            __overlay__ {
                compatible = "simple-audio-card";
                i2s-controller = <&i2s_clk_consumer>;
                simple-audio-card,name = "TLV320AIC3110";
                simple-audio-card,format = "i2s";
                simple-audio-card,convert-rate = <48000>;
                simple-audio-card,mclk-fs = <256>;
    
                simple-audio-card,bitclock-master = <&snd_codec>;
                simple-audio-card,frame-master = <&snd_codec>;
    
                simple-audio-card,widgets =
                    "Microphone", "Mic Jack",
                    "Speaker", "External Speaker";
                simple-audio-card,routing =
                    "External Speaker", "SPL",
                    "External Speaker", "SPR",
                    "MIC1LP", "Mic Jack",
                    "MIC1LM", "Mic Jack";
    
                status = "okay";
    
                dailink0_master: simple-audio-card,cpu {
                    sound-dai = <&i2s_clk_consumer>;
                    dai-tdm-slot-num = <2>;
                    dai-tdm-slot-width = <32>;
                };
    
                snd_codec: simple-audio-card,codec {
                    sound-dai = <&tlv320aic3110>;
                    clocks = <&mclk_external>;
                    system-clock-direction-out = "out";
                    system-clock-frequency = <12288000>; //*** added LAX
                    mclk-fs = <256>; //*** added LAX
                };
            };
        };
    
        fragment@4 {
            target-path = "/";
            __overlay__ {
                mclk_external: mclk_external {
                    compatible = "fixed-clock";
                    #clock-cells = <0>;
                    clock-frequency = <12288000>; // 12.288 MHz
                    clock-output-names = "mclk";
                };
            };
        };
    };