音频调试———FM
一、确认硬件接口
根据硬件原理图设计情况获取对应信息:
项目 | vaule |
接在哪个I2C | I2C4 |
接在哪个I2S | I2S2 |
I2S2_DOUT, I2S2_DIN | PH11, PE9 |
I2S2-BCLK,I2S2-LRCK,I2S2-DIN0 | PE6,PE7,PE9 |
二、设备树
1、设备节点
&i2s2_plat {
tdm-num = <2>;
tx-pin = <0>;
rx-pin = <0>;
pinctrl-used;
pinctrl-names= "default","sleep";
pinctrl-0 = <&i2s2_pins_a &i2s2_pins_c >;
pinctrl-1 = <&i2s2_pins_b>;
tx-hub-en;
rx-sync-en;
status = "okay";
};
&i2s2_mach {
soundcard-mach,name = "sndi2s2";
soundcard-mach,format = "i2s";
soundcard-mach,frame-master = <&i2s2_codec>;
soundcard-mach,bitclock-master = <&i2s2_codec>;
/* soundcard-mach,frame-inversion; */
/* soundcard-mach,bitclock-inversion; */
soundcard-mach,slot-num = <2>;
soundcard-mach,slot-width = <32>;
soundcard-mach,capture-only;
status = "okay";
i2s2_cpu: soundcard-mach,cpu {
sound-dai = <&i2s2_plat>;
soundcard-mach,pll-fs = <1>;
/* edp mclk: 512fs */^M
soundcard-mach,mclk-fs = <0>;
};
i2s2_codec: soundcard-mach,codec {
sound-dai = <&tef668x>;
};
};
&twi4 {
clock-frequency = <400000>;
pinctrl-0 = <&twi4_pins_default>;
pinctrl-1 = <&twi4_pins_sleep>;
pinctrl-names = "default", "sleep";
/* For stability and backwards compatibility, we recommend setting ‘twi_drv_used’ to 1 */
twi_drv_used = <1>;
twi-supply = <®_dcdc4>;
status = "okay";
tef668x: tef668x@64 {
#sound-dai-cells = <0>;
compatible = "tef668x_codec_0";
device_type = "tef668x_codec_0";
reg = <0x64>;
status = "okay";
};
};
2、pinctr信息
三、驱动移植
1、Kconfig
2、Makefile
3、驱动
bsp/drivers/sound/codecs/tef668x
声卡注册 snd_soc_register_codec
混杂设备注册 tef668x_probe(i2c, i2c_id);
static int tef668x_codec_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *i2c_id)
{
struct tef668x_codec_priv *tef668x_codec;
int ret = 0;
printk("tef668x_codec_i2c_probe 20241218 17:41\n");
tef668x_probe(i2c, i2c_id);
tef668x_codec = devm_kzalloc(&i2c->dev, sizeof(struct tef668x_codec_priv), GFP_KERNEL);
if (tef668x_codec == NULL) {
dev_err(&i2c->dev, "Unable to allocate tef668x_codec private data\n");
return -ENOMEM;
}
gTef668xCodec = tef668x_codec;
tef668x_codec->i2c = i2c;
dev_set_drvdata(&i2c->dev, tef668x_codec);
tef668x_codec->fm_switch_on = false;
if (i2c_id->driver_data < TEF668X_CODEC_CHIP_NUMS) {
i2c_ctrl[i2c_id->driver_data] = i2c;
ret = snd_soc_register_codec(&i2c->dev, &tef668x_codec_soc_codec_driver,
tef668x_codec_dai[i2c_id->driver_data], 1);
if (ret < 0) {
dev_err(&i2c->dev,
"Failed to register tef668x_codec codec: %d\n", ret);
}
} else {
pr_err("The wrong i2c_id number :%d\n",
(int)(i2c_id->driver_data));
}
if (ret < 0) {
dev_err(&i2c->dev,
"Failed to register tef668x_codec codec: %d\n", ret);
}
return ret;
}
混杂设备, 用于 fm 控制调频,搜台
bsp/drivers/sound/codecs/tef668x/misc_drv/tef668x.c
四、FM测试
移植对应APP测试程序后。执行APP,IIC报错
排查后定位,IIC未接上拉电阻,上拉4.7K,到VDD_3V3
上拉后,正常
音频设备:
五、录音播放测试
1、FM 录音
arecord -r 44100 -f S16_LE -D hw:1,0 -c2 /mnt/UDISK/fmrecord.wav
#查看录制状态
cat /proc/asound/sndi2s2/pcm0c/sub0/status
state: RUNNING
owner_pid : 1565
trigger_time: 1434.845529224
tstamp : 0.000000000
delay : 1287
avail : 1287
avail_max : 5513
hw_ptr : 2189948
appl_ptr : 2188661
2、FM 录制回放
tinymix -D 0 29 1
aplay /mnt/UDISK/fmrecord.wav
3、问题合集
问题1: 录制数据全0
引脚复用异常
原因: PE9 复用成了 IO Disable
root@Longan:~$ devmem 0x20000C4 32
0xF0033FFF
root@Longan:~$ devmem 0x20000C0 32
0x44F00002
#设置PE9 I2S
devmem 0x20000C4 32 0xF0033F44
解决办法:function 是 i2s2 i2s2_din
i2s2_pins_c: i2s2@2 {
pins = "PE9";//I2S2-DIN0
function = "i2s2"; //"i2s2_din";
drive-strength = <20>;
bias-disable;
};
调试完成!!!!