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.

Linux/TLV320AIC3104: driver don't call to codec

Part Number: TLV320AIC3104


Tool/software: Linux

Hello !

I'm trying to run the tlv320aic3104 codec on my own board with imx6ul processor. In DTS I make the description:

&i2c2 {
        clock_frequency = <100000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";

        codec: tlv320aic3x@18 {
                compatible = "ti,tlv320aic3x";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_gpio_key>;
                reg = <0x18>;
                gpio-reset = <&gpio5 0 GPIO_ACTIVE_LOW>;
/*
                clocks = <&clks IMX6UL_CLK_SAI2>;
                clock-names = "mclk";
*/
                status = "okay";
        };
};
Kernel ver 4.1.15.

The driver reports successful registration:
Dec 25 09:44:35 myd-y6ul14x14 user.debug kernel: of_get_named_gpiod_flags: parsed 'gpio-reset' property of node '/ soc / aips-bus @ 02100000 / i2c @ 021a4000
/ tlv320aic3x @ 18 [0] '- status (0)
Dec 25 09:44:35 myd-y6ul14x14 user.warn kernel: 1-0018 supply IOVDD not found, using dummy regulator
Dec 25 09:44:35 myd-y6ul14x14 user.warn kernel: 1-0018 supply DVDD not found, using dummy regulator
Dec 25 09:44:35 myd-y6ul14x14 user.warn kernel: 1-0018 supply AVDD not found, using dummy regulator
Dec 25 09:44:35 myd-y6ul14x14 user.warn kernel: 1-0018 supply DRVDD not found, using dummy regulator
Dec 25 09:44:35 myd-y6ul14x14 user.debug kernel: i2c-core: driver [tlv320aic3x-codec] registered
Dec 25 09:44:35 myd-y6ul14x14 user.info kernel: fsl-asrc 2034000.asrc: driver registered

But no more action on the i2c bus.
I don't see any attempts access to IC (CONFIG_I2C_DEBUG* = y in kernel config).
ALSA reports:
Dec 25 09:44:35 myd-y6ul14x14 user.info kernel: ALSA device list:
Dec 25 09:44:35 myd-y6ul14x14 user.info kernel: No soundcards found.
The i2c bus used successfully by other devices (ds1307, for example).
i2cdetect also defines response at address 0x18, if remove codec description from DTS.


I tried to debug the tlv320aic3x.c driver:
aic3x_i2c_probe() procedure is successfully executed (return = 0), but the aic3x_probe() procedure is not called.

I tried to describe the sound node in DTS in different ways, but I get the same result:

variant1:
        sound {
                compatible = "simple-audio-card";
                simple-audio-card,name = "OnboardTLV320";
                simple-audio-card,format = "i2s";
                simple-audio-card,bitclock-master = <&dailink_master>;
                simple-audio-card,frame-master = <&dailink_master>;

                simple-audio-card, widgets =
                        "Microphone", "Mic Jack",
                        "Line", "Line In",
                        "Line", "Line Out",
                        "Speaker", "Speaker",
                        "Headphone", "Headphone Jack";
                simple-audio-card, routing =
                        "Line Out", "LLOUT",
                        "Line Out", "RLOUT",
                        "Speaker", "SPOP",
                        "Speaker", "SPOM",
                        "Headphone Jack", "HPLOUT",
                        "Headphone Jack", "HPROUT",
                        "MIC3L", "Mic Jack",
                        "MIC3R", "Mic Jack",
                        "Mic Jack", "Mic Bias",
                        "LINE1L", "Line In",
                        "LINE1R", "Line In";

                simple-audio-card, cpu {
                        sound-dai = <&sai2>;
                };

                dailink_master: simple-audio-card, codec {
                        sound-dai = <&codec>;
                        clocks = <&tlv320_mclk>;
                };

variant2:
        sound {
                compatible = "ti,tlv320aic3x";
                cpu-dai = <&sai2>;
                gpr = <&gpr>;

                ti,audio-codec = <&codec>;
                ti,asrc-controller = <&asrc>;
                ti,codec-clock-rate = <12000000>;
                ti,audio-routing =
                    "Headphone Jack", "HPLOUT",
                    "Headphone Jack", "HPROUT",
                    "LINE1L", "Line In",
                    "LINE1R", "Line In";
        };

SAI descritption:

& sai2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_sai2>;

        assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
                          <&clks IMX6UL_CLK_SAI2>;
        assigned-clock-parents = <& clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
        assigned-clock-rates = <0>, <12288000>;

        status = "okay";
};
kernel config:
$ grep -i snd .config |grep -v ^#
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
CONFIG_SND_DMAENGINE_PCM=y
CONFIG_SND_HWDEP=y
CONFIG_SND_RAWMIDI=y
CONFIG_SND_COMPRESS_OFFLOAD=y
CONFIG_SND_JACK=y
CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_DEBUG=y
CONFIG_SND_DEBUG_VERBOSE=y
CONFIG_SND_ARM=y
CONFIG_SND_SPI=y
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
CONFIG_SND_SOC_FSL_ASRC=y
CONFIG_SND_SOC_FSL_SAI=y
CONFIG_SND_SOC_FSL_SSI=y
CONFIG_SND_SOC_IMX_PCM_DMA=y
CONFIG_SND_SOC_IMX_AUDMUX=y
CONFIG_SND_IMX_SOC=y
CONFIG_SND_SOC_IMX_PCM_FIQ=y
CONFIG_SND_SOC_I2C_AND_SPI=y
CONFIG_SND_SOC_TLV320AIC3X=y

What can I check or change?
  • Hello Vladimir,

    The TLV320AIC3x driver was made for Kernal 2.7 as I recall. Its very old and we do not actively support the driver at this time. We are hoping to update the driver soon.

    best regards,
    -Steve wilson
  • Thank you!

    I slightly advancе solution: need too Machine driver imx-tlv320aic3x.c. It not a part of kernel source tree, but I found in Inet some examples.  But it don't resolve my problem: ALSA show codec in list, but aplay do hang up.

    At fact, sound/soc/codecs/tlv320aic3x.c do call snd_soc_write() procedure for init codec, but i2c driver do not receive it task, and so no pulses on i2c wires.

  • Vladimir,

    I'm sorry to hear that the driver is not functioning for you.  We do hope to update the driver soon, but I cannot say when you could expect a new driver from our end.

    If you would like to work on the driver and try to up date it, you may find the below document helpful.  it shows all of the audio routing and associated registers.

    1374.TLV320AIC3104_Functional_block_Diagram_With_Registers.pdf

    Best regards,

    -Steve Wilson

  • I managed resolve the issue.

    1) I used the imx-tlv320aic3x.c version from Variscite, Ltd, 2014. This should be placed in sound/soc/fsl/ and in Makefile should be inserted lines causing compilation imx-tlv320aic3x.c. Find lines for "eukrea-tlv320" and add some, change "eukrea-tlv320" with "imx-tlv320aic3x".
    Also need to add in file Kconfig:
    config SND_SOC_IMX_TLV320AIC3X
            tristate "SoC Audio support for i.MX6 boards with tlv320aic3x audio codec"
            depends on OF && I2C
            select SND_SOC_TLV320AIC3X
            select SND_SOC_IMX_PCM_DMA
            select SND_SOC_IMX_AUDMUX
            select SND_SOC_FSL_SSI
            help
              SoC audio for i.MX6 boards with codec TLV320AIC3x attached over
              SSI interface.
              Say Y if you want to add support for SoC audio on phyFLEX-i.MX6
              boards.

    2) It is also required to set the parameter CONFIG_SND_SOC*TLV320AIC3X = y in the kernel configuration.
    CONFIG_SND_SOC_IMX_TLV320AIC3X=y
    CONFIG_SND_SOC_TLV320AIC3X=y
    3) A kernel patch is also required (already in recent releases, but I am work with 4.1.15), which allow configures the MCLK line for output.
    Apply patch and build kernel.

    4) In the device tree, you need to set the mclk direction parameter "fsl,sai-mclk-direction-output". Since the tlv320 driver does not support slave mode, so the CPU needs to synthesize the MCLK signal, so codec will be synthesizes WCLK and BCLK signal.
    In total, DTS:
    ...
            sound {
                    compatible = "fsl,imx-audio-tlv320aic3x";
                    model = "tlv320-audio-U";
                    ssi-controller = <&sai2>;
                    cpu-dai = <&sai2>;
                    audio-codec = <&codec>;
                    mux-int-port = <2>;  /* 1, 2, 7 - SSI */
                    mux-ext-port = <5>;  /* 3-6, IOMUX */
                    audio-routing =
                        "LINE1L", "Mic Jack",
                        "Headphone Jack", "HPLOUT",
                        "Headphone Jack", "HPROUT",
                        "Line Out Jack", "LLOUT",
                        "Line Out Jack", "RLOUT",
                        "Mic Jack", "Mic Bias";
            };
    ...
    
    &sai2 {
            pinctrl-names = "default";
            pinctrl-0 = <&pinctrl_sai2>;
    
            assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
                              <&clks IMX6UL_CLK_SAI2>;
            assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
            assigned-clock-rates = <0>, <19200000>;  /* tlv320aic3104 */
            fsl,sai-mclk-direction-output;
            status = "okay";
    };
    ...
    
    &i2c2 {
            clock_frequency = <100000>;
            pinctrl-names = "default";
            pinctrl-0 = <&pinctrl_i2c2>;
            status = "okay";
    
            codec: tlv320aic3x@18 {
                    /*   ai3x-micbias-vg = <2>; */
                    compatible = "ti,tlv320aic3104";
                    reg = <0x18>;
                    gpio-reset = <&gpio5 0 GPIO_ACTIVE_LOW>;
    
                    clocks = <&clks IMX6UL_CLK_SAI2>;
                    status = "okay";
            };
    };