Múltiples codecs de audio en un i.MX6Q

2

Actualmente estamos tratando de abrir una placa personalizada basada en i.MX6Q con Linux 3.10.17, dos códecs TI TLV320AIC3106 y una interfaz S / PDIF.

Los dos códecs son esclavos I2S y están conectados al i.MX6 a través de

codec1 <-> AUDMUX3 <-> SSI1

y

codec2 <-> AUDMUX4 <-> SSI2

He escrito un controlador de máquina ASoC para los códecs y hasta ahora todo se ve bien desde el punto de vista de ALSA:

aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: imxspdif [imx-spdif], device 0: S/PDIF PCM Playback dit-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: CODEC1 [CODEC1], device 0: HiFi tlv320aic3x-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: CODEC2 [CODEC2], device 0: HiFi tlv320aic3x-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: imxspdif [imx-spdif], device 1: S/PDIF PCM Capture dir-hifi-1 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: CODEC1 [CODEC1], device 0: HiFi tlv320aic3x-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: CODEC2 [CODEC2], device 0: HiFi tlv320aic3x-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Mi problema ahora es que solo puedo interactuar con los dispositivos de audio codec (tarjeta 2 en el ejemplo anterior). Intentar reproducir en / capturar desde la tarjeta 1 resultará en:

aplay -D "plughw:1,0" /home/1000_loud.wav
ALSA sound/core/pcm_lib.c:1944 playback write error (DMA or IRQ trouble?)
aplay: pcm_write:1603: write error: Input/output error

Noté que no tengo ninguna actividad en las líneas I2S para la tarjeta 1 (sin reloj ni datos).
Sin embargo, ambos dispositivos funcionan si desactivo el otro dispositivo en el DT. Así que creo que debo estar bloqueando algo en algún lugar, pero no tengo idea de dónde / por qué / cómo.

Puedo hablar con los códecs a través de I2C, por lo que al menos el bus I2C no parece ser el problema.

Aquí está (la parte relevante de) mi DT:

/ {

    clocks {
        osc {
            compatible = "fsl,imx-osc", "fixed-clock";
            clock-frequency = <25000000>;
        };
    };

    regulators {
        compatible = "simple-bus";

        reg_audio: tlv320aic3x_supply {
            compatible = "regulator-fixed";
            regulator-name = "tlv320aic3x-supply";
            regulator-boot-on;
            regulator-always-on;
        };
    };

    sound1 {
        compatible = "fsl,imx-audio-tlv320aic3x";
        model = "CODEC1";
        ssi-controller = <&ssi1>;
        audio-codec = <&codec1>;
        audio-routing =
            "Microphone 1",      "LINE1L",
            "Microphone 1",      "LINE1R",
            "Microphone 2",      "LINE2L",
            "Microphone 2",      "LINE2R",
            "Piezo Loudspeaker", "LLOUT";
        mux-int-port = <1>;
        mux-ext-port = <3>;
    };

    sound2 {
        compatible = "fsl,imx-audio-tlv320aic3x";
        model = "CODEC2";
        ssi-controller = <&ssi2>;
        audio-codec = <&codec2>;
        audio-routing =
            "Microphone 1", "LINE1L",
            "Microphone 1", "LINE1R",
            "Microphone 2", "LINE2L",
            "Microphone 2", "LINE2R",
            "Loudspeaker",  "LLOUT",
            "Loudspeaker",  "RLOUT";
        mux-int-port = <2>;
        mux-ext-port = <4>;
    };

    sound-spdif {
        compatible = "fsl,imx-audio-spdif";
        model = "imx-spdif";
        spdif-controller = <&spdif>;
        spdif-in;
        spdif-out;
    };
};

&audmux {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_audmux_4>;
    status = "okay";
};

&i2c1 {
    clock-frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c1_2>;
    status = "okay";

    codec1: tlv320aic3x@01b {
        compatible = "ti,tlv320aic3x";
        reg = <0x01b>;
        gpio-reset = <&gpio5 18 GPIO_ACTIVE_LOW>;
        status = "okay";

        clocks = <&clks 201>;
        clock-names = "cko";
        clock-frequency = <25000000>;

        AVDD-supply = <&reg_audio>;
        IOVDD-supply = <&reg_audio>;
        DRVDD-supply = <&reg_audio>;
        DVDD-supply = <&reg_audio>;
        HPVDD-supply = <&reg_audio>;
        SPRVDD-supply = <&reg_audio>;
        SPLVDD-supply = <&reg_audio>;
    };

    codec2: tlv320aic3x@018 {
        compatible = "ti,tlv320aic3x";
        reg = <0x018>;
        gpio-reset = <&gpio5 18 GPIO_ACTIVE_LOW>;
        status = "okay";

        clocks = <&clks 201>;
        clock-names = "cko";
        clock-frequency = <25000000>;

        AVDD-supply = <&reg_audio>;
        IOVDD-supply = <&reg_audio>;
        DRVDD-supply = <&reg_audio>;
        DVDD-supply = <&reg_audio>;
        HPVDD-supply = <&reg_audio>;
        SPRVDD-supply = <&reg_audio>;
        SPLVDD-supply = <&reg_audio>;
    };
};

&iomuxc {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_audmux_4>;

    audmux {
        pinctrl_audmux_4: audmux-4 {
            fsl,pins = <
                MX6QDL_PAD_SD2_DAT0__AUD4_RXD  0x130b0
                MX6QDL_PAD_SD2_DAT3__AUD4_TXC  0x130b0
                MX6QDL_PAD_SD2_DAT2__AUD4_TXD  0x110b0
                MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
                MX6QDL_PAD_CSI0_DAT7__AUD3_RXD  0x130b0
                MX6QDL_PAD_CSI0_DAT4__AUD3_TXC  0x130b0
                MX6QDL_PAD_CSI0_DAT5__AUD3_TXD  0x110b0
                MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
            >;
        };
    };

    spdif {
        pinctrl_spdif_3: spdifgrp-3 {
            fsl,pins = <
                MX6QDL_PAD_EIM_D21__SPDIF_IN  0x1b0b0
                MX6QDL_PAD_EIM_D22__SPDIF_OUT 0x1b0b0
            >;
        };
    };
};

&ssi1 {
    fsl,mode = "i2s-master";
    status = "okay";
};

&ssi2 {
    fsl,mode = "i2s-master";
    status = "okay";
};

&spdif {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_spdif_3>;
    status = "okay";
};

¿Alguien tiene una idea de lo que podría faltar o hacer mal?

¡Muchas gracias por cualquier ayuda por adelantado!

    
pregunta Chris

1 respuesta

3

Pude resolverlo.

Era un problema de dos partes:

a) El controlador de la máquina que utilicé como plantilla para mí no manejó muy bien la carga varias veces. Lo reescribí, lo que resolvió el problema de bloqueo.

Sin embargo, después de eso, todavía no podía reproducir el audio de ambos códecs. Tan pronto como empecé a interactuar con el segundo códec, la reproducción del primero se detendría. Esto fue causado por

b) Por el diseño de hardware, ambos códecs en nuestro tablero comparten el mismo reinicio de GPIO. El controlador del códec realizó un restablecimiento de hardware en cada evento de inicio de reproducción / captura restableciendo el otro códec

    
respondido por el Chris

Lea otras preguntas en las etiquetas