整个嵌入式项目由Buildroot构建,现有项目增加音频TAS5754驱动,详细步骤如下
Kernel -> Defconfig name -> 内核配置文件名称
Kernel -> Device Tree Source file name -> dts名称
内核中主要涉及DTS的配置,路径arch/arm64/boot/dts/厂商/xxx.dts
#include "mesonaxg.dtsi"
/ {
model = "Amlogic";
amlogic-dt-id = "xxxx"; // 这个配置很重要,要和buildroot中Device Tree Source file name名称一致
sugr-case-id = "xxx";
sugr-hw-id = "11";
compatible = "xxx, xxx";
interrupt-parent = <&gic>;
#size-cells = <2>;
/* for spk board */
&i2c2 {
status = "okay";
pinctrl-names="default";
pinctrl-0=<&c_i2c_master>;
npcp215x_e6: npcp215x_e6@e6 {
compatible = "nuvoton,npcp215x";
#sound-dai-cells = <0>;
reg = <0x73>;
status = "disable"; // 禁止
reset_pin = <&gpio_ao GPIOAO_4 0>;
mute_pin = <&gpio_ao GPIOAO_3 0>;
amp_power = <&gpio_ao GPIOAO_7 0>;
};
tas575x_37: tas575x_37@37 {
compatible = "ti,tas575x"; //匹配名称
#sound-dai-cells = <0>;
reg = <0x4e>; //IIC从机设备地址
status = "okay"; //使能
mute_pin = <&gpio_ao GPIOAO_3 0>; //引脚配置
amp_power = <&gpio_ao GPIOAO_7 0>;
};
};
kernel/sound/soc/codecs/厂商/tas575x.c
//DTS 设备匹配
static const struct of_device_id tas575x_of_match[] = {
{ .compatible = "ti, tas5754", 0 },
{ .compatible = "ti, tas5756", 0 },
{ .compatible = "ti, tas575x", 0 },
{ }
};
//i2c id 匹配
static const struct i2c_device_id tas575x_i2c_id[] = {
{ "tas5754", (kernel_ulong_t) 0 },
{ "tas5756", (kernel_ulong_t) 0 },
{ "tas575x", (kernel_ulong_t) 0 },
{ }
};
//DTS中配置的引脚通过该接口来操作
amp_power = of_get_named_gpio(node,"amp_power",0);
if (amp_power < 0){
pr_err("%s fail to get mute pin from dts!\n", __func__);
}
gpio_direction_output(amp_power,GPIOF_OUT_INIT_HIGH);
aml-audio-card,dai-link@2 {
format = "i2s";
mclk-fs = <256>;
continuous-clock;
/* tdmb clk using tdmc so no bclk-inv */
//bitclock-inversion;
//frame-inversion;
bitclock-master = <&aml_tdmc>;
frame-master = <&aml_tdmc>;
cpu {
sound-dai = <&aml_tdmc>;
dai-tdm-slot-tx-mask = <1 1>;
dai-tdm-slot-rx-mask = <1 1>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
system-clock-frequency = <12288000>;
};
codec {
//sound-dai = <&npcp215x_e6>;
sound-dai = <&tas575x_37>; //ALSA dai配置
};
};
IIS这里的配置并没有深入研究,后续需要会跟进
static int tas575x_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
//const struct of_device_id *of_id;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
i2c_set_clientdata(client, priv);
priv->regmap = devm_regmap_init_i2c(client, &tas575x_regmap);
...
return snd_soc_register_codec(dev, &soc_codec_dev_tas575x,
&tas575x_dai, 1);
}
需要注意一点:软件中tas575x_i2c_probe匹配成功,IIC不一定通讯成功,需要实际验证
查看功放TAS5754数据手册,MUTE需要拉高功放才能出声,否则会处于静音状态
后续跟进
aplay -Dhw:0,2 xxx.wav
-D : select PCM by name
0 : 代表 card0 2: 代表 deveice 2
调试IIC过程中需要用到逻辑分析仪,这里用Saleae logic,软件下载地址,软件全平台覆盖,非常方便,相关软件资料见
链接: https://pan.baidu.com/s/1KbFhnSIsWD4bFwJoIk1yzw 提取码: xav9
看波形主要看是否有ACK回应,低电平代表有ACK,高电平代表NACK。
1. 测试音频驱动,用应用程序aplay播放wav文件: aplay -Dhw:0,2 xxx.wav
aplay: main:788: audio open error: Device or resource busy
主要由于其他进程占用card 0 设备
2. TAS5754 IIC一直通讯不成功
首先排查硬件,确认线路没有问题。 这个时候发现Pin40 电压为1.2v,显然处于异常情况 硬件排查有线路错误,问题解决