我们正在尝试为具有 NXP 的 i.MX8MP MPU 的定制电路板引入 TLV320AIC3100音频编解码器。 我们针对编解码器的 DT 配置基于此论坛上发布的许多其他内容、如下所示:
/
reg_audio_pwr: regulator-audio-pwr {
compatible = "regulator-fixed";
regulator-name = "audio-pwr";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-high;
regulator-always-on;
};
reg_audio_pwr_1v8: regulator-audio-pwr {
compatible = "regulator-fixed";
regulator-name = "audio-pwr";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
enable-active-high;
regulator-always-on;
};
vdd_input: vdd_input {
compatible = "regulator-fixed";
regulator-name = "vdd_input";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
regulator-always-on;
};
sound-tlv320aic31xx {
compatible = "simple-audio-card";
simple-audio-card,name = "tlv320aic31xx-Codec";
simple-audio-card,format = "i2s";
simple-audio-card,frame-master = <&dailink_master>;//Which one is master
simple-audio-card,bitclock-master = <&dailink_master>;//which one is master
simple-audio-card,mclk-fs = <256>;//Multiplication rate between stream rate and codec mclk
simple-audio-card,widgets =
"Speaker", "External Speaker",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"External Speaker", "SPK",
"Headphone Jack", "HPL",
"Headphone Jack", "HPR";
dailink_master:simple-audio-card,cpu {
sound-dai = <&sai3>;
};
thecodec:simple-audio-card,codec {
sound-dai = <&tlv320aic3100>;
clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK1>;
};
};
&i2c5 {
clock-frequency = <100000>; /* Lower clock speed for external bus. */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c5>;
status = "okay";
tlv320aic3100: tlv320aic31xx@18 {
pinctrl-0 = <&pinctrl_dac_rst>;
pinctrl-names= "default";
compatible = "ti,tlv320aic3100";
#sound-dai-cells =<0>;
reg = <0x18>;
clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK1>;
clock-names = "mclk1";
reset-gpios = <&gpio4 29 GPIO_ACTIVE_LOW>;
HPVDD-supply = <®_audio_pwr>;
SPRVDD-supply = <&vdd_input>;
SPLVDD-supply = <&vdd_input>;
AVDD-supply = <®_audio_pwr>;
IOVDD-supply = <®_audio_pwr>;
DVDD-supply = <®_audio_pwr_1v8>;
};
};
&sai3 {
#sound-dai-cells=<0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
assigned-clock-rates = <12288000>;
clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_IPG>, <&clk IMX8MP_CLK_DUMMY>,
<&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK1>, <&clk IMX8MP_CLK_DUMMY>,
<&clk IMX8MP_CLK_DUMMY>;
clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
fsl,sai-synchronous-rx;
status = "okay";
};
&iomuxc {
pinctrl_dac_rst: dacrstgrp {
fsl,pins = <
MX8MP_IOMUXC_SAI3_RXC__GPIO4_IO29 0x19 //DAC RST TODO
>;
};
pinctrl_sai3: sai3grp {
fsl,pins = <
MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC 0xd6
MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK 0xd6
MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00 0xd6
MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00 0xd6
MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI3_MCLK 0xd6
>;
};
};
这似乎是我们得到某种解析错误的 DAI 链接。 我们收到 simple-card.c 驱动程序的 Di-links 解析错误。 我们已经修补了驱动程序以查看一些日志、似乎问题是基于此部分驱动程序:
static int __simple_for_each_link(struct asoc_simple_priv *priv,
struct link_info *li,
int (*func_noml)(struct asoc_simple_priv *priv,
struct device_node *np,
struct device_node *codec,
struct link_info *li, bool is_top),
int (*func_dpcm)(struct asoc_simple_priv *priv,
struct device_node *np,
struct device_node *codec,
struct link_info *li, bool is_top))
{
struct device *dev = simple_priv_to_dev(priv);
struct device_node *top = dev->of_node;
struct device_node *node;
uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev);
bool is_top = 0;
int ret = 0;
printk("Entering __simple_for_each_link\n");
/* Check if it has dai-link */
node = of_get_child_by_name(top, PREFIX "dai-link");
if (!node) {
node = of_node_get(top);
is_top = 1;
printk("No Dai-Link?\n");
}
/* loop for all dai-link */
do {
struct asoc_simple_data adata;
struct device_node *codec;
struct device_node *plat;
struct device_node *np;
int num = of_get_child_count(node);
printk("Inside do-while loop\n");
/* get codec */
codec = of_get_child_by_name(node, is_top ?
PREFIX "codec" : "codec");
if (!codec) {
ret = -ENODEV;
goto error;
}
/* get platform */
plat = of_get_child_by_name(node, is_top ?
PREFIX "plat" : "plat");
/* get convert-xxx property */
memset(&adata, 0, sizeof(adata));
for_each_child_of_node(node, np)
simple_parse_convert(dev, np, &adata);
/* loop for all CPU/Codec node */
for_each_child_of_node(node, np) {
printk("Inside for_each_child_of_node loop\n");
if (plat == np)
continue;
/*
* It is DPCM
* if it has many CPUs,
* or has convert-xxx property
*/
if (dpcm_selectable &&
(num > 2 || asoc_simple_is_convert_required(&adata))) {
/*
* np
* |1(CPU)|0(Codec) li->cpu
* CPU |Pass |return
* Codec |return|Pass
*/
if (li->cpu != (np == codec))
ret = func_dpcm(priv, np, codec, li, is_top);
/* else normal sound */
} else {
/*
* np
* |1(CPU)|0(Codec) li->cpu
* CPU |Pass |return
* Codec |return|return
*/
if (li->cpu && (np != codec))
ret = func_noml(priv, np, codec, li, is_top);
}
if (ret < 0) {
of_node_put(codec);
of_node_put(plat);
of_node_put(np);
goto error;
}
}
of_node_put(codec);
node = of_get_next_child(top, node);
} while (!is_top && node);
error:
of_node_put(node);
printk("Exiting __simple_for_each_link with ret: %d\n", ret);
return ret;
}
我们已从内核配置中启用了该驱动程序:下面是带补丁驱动程序的引导日志:
imx8mp-lpddr4-evk login: [ 14.563842] probing for the TLV320AIC [ 14.567547] Entering __simple_for_each_link [ 14.571790] No Dai-Link? [ 14.574337] Inside do-while loop [ 14.577629] Inside for_each_child_of_node loop [ 14.582111] Inside for_each_child_of_node loop [ 14.586592] Exiting __simple_for_each_link with ret: 0 [ 14.591763] Entering __simple_for_each_link [ 14.595972] No Dai-Link? [ 14.598509] Inside do-while loop [ 14.601772] Inside for_each_child_of_node loop [ 14.606235] Inside for_each_child_of_node loop [ 14.610715] Exiting __simple_for_each_link with ret: 0 [ 14.615960] Entering __simple_for_each_link [ 14.620193] No Dai-Link? [ 14.622730] Inside do-while loop [ 14.625987] Inside for_each_child_of_node loop [ 14.630481] Exiting __simple_for_each_link with ret: -517 [ 14.635887] li->cpu val:1 ret val:-517 [ 14.639641] parsing error occured on dai links parsing link [ 14.645324] parse error: -517
使用 i2cdetect 命令时、我们可以看到填充了0x18区域、但当我们观察 i2c 总线时使用此命令时、无法看到0x18、我们会看到下面不是0x18的输出:

我们看不到 MCLK 的任何移动、并且我们的 SAI 接口被观察为从控制台延迟:
root@imx8mp-lpddr4-evk:~# cat /sys/kernel/debug/devices_deferred 30c30000.sai sound-bt-sco asoc-simple-card: parse error sound-tlv320aic31xx asoc-simple-card: parse error 30c20000.sai
接口和编解码器这两个节点似乎都是延迟的。 是接口或编解码器配置导致的问题。 我们如何调试该问题? 感谢您的任何想法! 提前感谢您!
此致!
