I am currently working on bringing up two TLV320AIC3204 audio codecs on an i.MX7D running Linux kernel 6.1. Both codecs are physically present on the I2C bus and are detected via i2cdetect, however only one codec at a time is registering as a sound card in ALSA (aplay -l).
Both codecs are on different i2c buses but with same register address.
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "tlv320aic32x4";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&dailink_master_cpu>;
simple-audio-card,frame-master = <&dailink_master_cpu>;
simple-audio-card,widgets =
"Microphone", "Mic Jack",
"Line", "Line In",
"Line", "Line Out",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"IN1_L", "Line In",
"IN1_R", "Line In",
"IN3_R", "Mic Jack",
"CM_L", "Mic Jack",
"CM_R", "Mic Jack",
"Line Out", "LOL",
"Line Out", "LOR",
"Headphone Jack", "HPL",
"Headphone Jack", "HPR";
dailink_master_cpu: simple-audio-card,cpu {
sound-dai = <&sai3>;
//clocks = <&clks IMX7D_SAI3_ROOT_CLK>;
clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
clock-names = "mclk";
};
simple-audio-card,codec {
sound-dai = <&codec_tlv>;
system-clock-frequency= <12288000>;
//clocks = <&clks IMX7D_SAI3_ROOT_CLK>;
};
};
sound1 {
compatible = "simple-audio-card";
simple-audio-card,name = "tlv320aic32x4_1";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&master_sai2>;
simple-audio-card,frame-master = <&master_sai2>;
simple-audio-card,widgets =
"Microphone", "Mic Jack",
"Line", "Line In",
"Line", "Line Out",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"IN1_L", "Line In",
"IN1_R", "Line In",
"IN3_R", "Mic Jack",
"CM_L", "Mic Jack",
"CM_R", "Mic Jack",
"Line Out", "LOL",
"Line Out", "LOR",
"Headphone Jack", "HPL",
"Headphone Jack", "HPR";
master_sai2: simple-audio-card,cpu {
sound-dai = <&sai2>;
clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
clock-names = "mclk";
};
simple-audio-card,codec {
sound-dai = <&codec_tlv2>;
system-clock-frequency= <12288000>;
//clocks = <&clks IMX7D_SAI2_ROOT_CLK>;
};
&clks {
assigned-clocks = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <626688000>;
};
&sai3 {
pinctrl-names = “default”;
pinctrl-0 = <&pinctrl_sai3 &pinctrl_sai3_mclk>;
assigned-clocks = <&clks IMX7D_SAI3_ROOT_SRC>,
<&clks IMX7D_SAI3_ROOT_CLK>;
//<&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <0>, <36864000>;
//assigned-clock-rates = <0>, <12288000>;
fsl,sai-mclk-direction-output;
status = "okay";
};
&sai2 {
pinctrl-names = “default”;
pinctrl-0 = <&pinctrl_sai2 &pinctrl_sai2_mclk>;
assigned-clocks = <&clks IMX7D_SAI2_ROOT_SRC>,
<&clks IMX7D_SAI2_ROOT_CLK>;
//<&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <0>, <36864000>;
fsl,sai-mclk-direction-output;
//assigned-clock-rates = <0>, <12288000>;
status = “okay”;
};
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = “default”, “gpio”;
pinctrl-0 = <&pinctrl_i2c2>;
pinctrl-1 = <&pinctrl_i2c2_recovery>;
scl-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio1 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = “okay”;
codec_tlv: tlv320aic32x4@18 {
compatible = "ti,tlv320aic32x4";
#sound-dai-cells = <0>;
reg = <0x18>;
//clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
clocks = <&clks IMX7D_SAI3_ROOT_CLK>;
clock-names = "mclk";
//clock-names = "mclk";
//pinctrl-names = "default";
status = "okay";
ldoin-supply = <®_module_3v3>;
iov-supply = <®_module_3v3>;
};
};
&i2c3 {
clock-frequency = <100000>;
pinctrl-names = “default”, “gpio”;
//pinctrl-0 = <&pinctrl_i2c4>;
//pinctrl-1 = <&pinctrl_i2c4_recovery>;
//scl-gpios = <&gpio7 8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
//sda-gpios = <&gpio7 9 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
pinctrl-0 = <&pinctrl_i2c3>;
pinctrl-1 = <&pinctrl_i2c3_recovery>;
scl-gpios = <&gpio1 8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio1 9 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = “okay”;
codec_tlv2: tlv320aic32x4@18 {
compatible = "ti,tlv320aic32x4";
#sound-dai-cells = <0>;
reg = <0x18>;
//clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
clocks = <&clks IMX7D_SAI2_ROOT_CLK>;
clock-names = "mclk";
//pinctrl-names = "default";
status = "okay";
//avdd-supply = <®_module_3v3>;
// dvdd-supply = <®_module_3v3>;
iov-supply = <®_module_3v3>;
ldoin-supply = <®_module_3v3>;
};
};