2406056_zh-CN

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2406056_zh-CN

2406056_zh-CN

i.mx8M Plus 上的 wm8962 错误
我们正在设计基于 NXP i.MX 8M Plus (i.MX8MP) 处理器和 Wolfson WM8962 音频编解码器的定制电路板。我们目前正在将驱动程序移植到Linux 内核 5.4。以下是错误日志和我们的 DTS(设备树源)配置。
日志:
[    2.097680] imx-wm8962 sound-wm8962: 2111111111111111111111111
[    2.103533] imx-wm8962 sound-wm8962: 22222222222222222222222222
[    2.109467] imx-wm8962 sound-wm8962: 333333333333333333
[    2.114705] imx-wm8962 sound-wm8962: 888888888888888888
[    2.119953] imx-wm8962 sound-wm8962: failed to find codec platform device
[    2.126759] imx-wm8962: probe of sound-wm8962 failed with error -22
[    2.995796] wm8962 2-001a: afrrgrgtrggggggggggggggggggg
[    3.001038] wm8962 2-001a: bbbbbbbbbbbbbbbbbbbbbbbbb
[    3.008259] random: fast init done
[    3.011807] wm8962 2-001a: customer id 0 revision F​

DTS:

 
sound-wm8960-forenex {
		compatible = "fsl,imx-audio-wm8962";
		model = "wm8962-audio";
		audio-codec = <&codec>;
		audio-cpu = <&sai3>;
		audio-routing = "Headphone Jack", "HPOUTL",
			"Headphone Jack", "HPOUTR",
			"Ext Spk", "SPKOUTL",
			"Ext Spk", "SPKOUTR",
			"AMIC", "MICBIAS",
			"IN3R", "AMIC",
			"IN1R", "AMIC";
	};
&i2c3 {
	clock-frequency = <100000>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_i2c3>;
	status = "okay";

	pca6416: gpio@20 {
		compatible = "ti,tca6416";
		reg = <0x20>;
		gpio-controller;
		#gpio-cells = <2>;
	};

	ov5640_1: ov5640_mipi@3c {
		compatible = "ovti,ov5640";
		reg = <0x3c>;
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_csi0_pwn>, <&pinctrl_csi0_rst>, <&pinctrl_csi_mclk>;
		clocks = <&clk IMX8MP_CLK_IPP_DO_CLKO2>;
		clock-names = "xclk";
		assigned-clocks = <&clk IMX8MP_CLK_IPP_DO_CLKO2>;
		assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
		assigned-clock-rates = <24000000>;
		csi_id = <0>;
		powerdown-gpios = <&gpio4 1 GPIO_ACTIVE_HIGH>;
		reset-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
		mclk = <24000000>;
		mclk_source = <0>;
		mipi_csi;
		status = "disabled";

		port {
			ov5640_mipi_1_ep: endpoint {
				remote-endpoint = <&mipi_csi1_ep>;
				data-lanes = <1 2>;
				clock-lanes = <0>;
			};
		};
	};
	
	codec: wm8962@1a {
	  compatible = "wlf,wm8962";
		reg = <0x1a>;
		clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1>;
		clock-names = "mclk";
		wlf,shared-lrclk;
	  AVDD-supply = <&reg_audio_pwr>;
		CPVDD-supply = <&reg_audio_pwr>;
		DBVDD-supply = <&reg_audio_pwr>;
	  DCVDD-supply = <&reg_audio_pwr>;
	  MICVDD-supply = <&reg_audio_pwr>;
	  PLLVDD-supply = <&reg_audio_pwr>;
		SPKVDD1-supply = <&reg_audio_pwr>;
		SPKVDD2-supply = <&reg_audio_pwr>;
	  gpio-cfg = <
					0x0000 /* 0:Default */
					0x0000 /* 1:Default */
					0x0000 /* 2:FN_DMICCLK */
					0x0000 /* 3:Default */
					0x0000 /* 4:FN_DMICCDAT */
					0x0000 /* 5:Default */
				>;
	};
};​

根据我们的分析,当内核尝试初始化 imx-wm8962 机器驱动程序时,I2C 总线上的 WM8962 编解码器尚未完成探测/注册。WM8962 之后才会完成初始化。这种探针顺序不一致会导致驱动程序初始化失败并出现错误。

请问您能否帮忙分析一下这个问题,并提出解决此问题的建议?
AndroidLinuxRe: wm8962 on i.mx8M Plus error
  1. 当编解码器或 SAI 平台设备未准备就绪时,返回 -EPROBE_DEFER

在你的 imx-wm8962.c 中探测路径,区分以下几种情况:

  • 缺少/无效的 DT 句柄 → 实际错误,返回 -EINVAL;
  • 句柄存在,但引用的设备尚未注册 → 依赖项未准备就绪,返回 -EPROBE_DEFER。

例如,从概念上讲:

codec_np = of_parse_phandle(np, "audio-codec", 0);

如果 (!codec_np) {

dev_err(&pdev->dev, "音频编解码器缺失或无效\n");

        返回-EINVAL;

}

codec_dev = of_find_i2c_device_by_node(codec_np);

如果 (!codec_dev) {

dev_info(&pdev->dev, "编解码器设备未就绪,延迟探测\n");

of_node_put(codec_np);

返回 -EPROBE_DEFER;

}

同样适用于 CPU DAI / SAI 节点:

cpu_np = of_parse_phandle(np, "audio-cpu", 0);

如果 (!cpu_np) {

dev_err(&pdev->dev, "audio-cpu 缺失或无效\n");

        返回-EINVAL;

}

cpu_pdev = of_find_device_by_node(cpu_np);

如果 (!cpu_pdev) {

dev_info(&pdev->dev, "SAI 平台设备未就绪,延迟探测\n");

of_node_put(cpu_np);

返回 -EPROBE_DEFER;

}

如果您保留当前的机器驱动程序,这是最直接的解决方法。

  1. 如果可用,请优先选择 Linux 5.4 fsl-asoc-card 路径。

对于 Linux 5.4 时代的 NXP 内核,compatible = "fsl,imx-audio-wm8962" 由 sound/soc/fsl/fsl-asoc-card.c 处理,其中显式地处理了 WM8962,包括编解码器 DAI 名称 "wm8962" 和 WM8962 时钟/FLL ID。还要验证 snd-soc-fsl-asoc-card.ko 是否已加载或已构建。

这意味着您应该避免让旧版/自定义 imx-wm8962 机器驱动程序和 fsl-asoc-card 尝试绑定同一个兼容字符串。推荐方法:

  • 启用/使用 CONFIG_SND_SOC_FSL_ASOC_CARD;
  • 确保您的声音节点使用兼容的 = "fsl,imx-audio-wm8962";  ;
  • 除非您有意保留,否则请移除或禁用该兼容字符串的旧版/自定义 imx-wm8962 绑定。
  1. 确保DTS具有所需的SAI和编解码器DAI属性

您的编解码器节点大致符合预期形状:WM8962 的示例使用 compatible = "wlf,wm8962" 、 reg = <0x1a> 、 clocks、 supply properties 和 gpio-cfg。但是,请确认您的DTS中未显示的部件:

&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>; /* 或板要求的 MCLK */

        status = "okay";

};

此外,编解码器通常还应公开以下内容:

编解码器:wm8962@1a {

兼容 = "wlf,wm8962";

reg =<0x1a> �

#sound-dai-cells = <0>

clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1>;

时钟名称 = "mclk";

……

};

同时确保 reg_audio_pwr 引用的稳压器已定义、已启用,并且具有有效的电压范围。您的编解码器已被检测到,因此电源可能不是造成此特定错误的原因,但不良的电源或 MCLK 设置可能会导致以后的音频故障。

  1. 验证 MCLK 是否使能。

已知有一类 WM8962 启动问题,需要在音频机器驱动程序中启用编解码器 MCLK;据报道,在 imx_wm8962_probe() 中添加 clk_prepare_enable(codec_clk) 可以使 WM8962 音频工作。如果编解码器探测成功,但之后播放/捕获失败,请检查在编解码器初始化和流启动期间,SAI3 MCLK 是否实际存在于编解码器引脚上。

  1. 检查是否存在重复或冲突的声卡节点

确保只有一个活动的声音节点指向此编解码器/SAI 对,并且模型字符串是唯一的。在 NXP 社区调试中,还出现了类似的故障,即找不到编解码器平台设备,这与声卡命名/重复卡冲突有关。您的节点名称显示为 sound-wm8960-forenex,而兼容/型号为 WM8962;节点名称本身通常不起作用,但我建议您将其重命名以使其更清晰,并确认其他地方没有第二个已启用的 sound-wm8962 节点。

推荐的最短路径

  • 如果可能,请使用适用于 Linux 5.4 的 fsl-asoc-card。
  • 如果 WM8962 节点缺少 #sound-dai-cells = <0>;,请添加它。
  • 确认 &sai3 已启用且已配置时钟/引脚控制。
  • 如果保留自定义的 imx-wm8962 驱动程序,请修补失败的编解码器/CPU 查找路径,使其返回 -EPROBE_DEFER 而不是 -EINVAL。
  • 确认 MCLK 已启用且存在。

Tags (1)
No ratings
Version history
Last update:
Wednesday
Updated by: