rk3568 Android12音频问题
前言
在调试客户的项目的时候,发现外置的音频功放在打开和关闭音频的时候会出现pop音,严重影响使用体验,好在最后解决了这个问题,遂记录一下解决过程。
tiny-alsa命令的使用
在调试ubuntu等一些纯linux系统的时候,可以使用alsa-utils工具进行调试,由于其过于庞大,安卓中精简了一部分功能,在安卓中叫alsa-utils工具。
shell
#查看本机的声卡
cat /proc/asound/cards
#查询声卡的采样率,格式等信息
tinypcminfo -D 0
#播放音频
tinyplay xxx.wav -D 0
#录制音频
tinycap -D 0
#控制codec通路
tinymix "name" "value"
#查看所有的value
tinymix -a
#例如将"Playback Path"修改成"SPK" 通路
tinymix "Playback Path" SPK
问题原因
通过查看原理图发现客户的外置SPK连接一颗功放ic,并且音频是从耳机通路中引出,并且是单通道功放。
客户的这个项目中并没有耳机接口,但是SPK走的是耳机的音频通路,一开始想的是,只要让系统检查到耳机的存在就能一直输出音频,所以在rk_headset中把耳机检测gpio配置进去,并且按照其ACTIVE的方向配置gpio状态(内部上下拉),所以就能一直检测到耳机是插入状态,本来正常的情况下,gpio状态要和耳机插入检测gpio ACTIVE的方向相反。
shell
#headset配置
rk_headset: rk-headset {
compatible = "rockchip_headset";
headset_gpio = <&gpio3 RK_PC2 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hp_det>;
};
#pinctrl配置
&pinctrl {
headphone {
hp_det: hp-det {
/* 配置成上拉,这样系统就能检测耳机一直保持插入状态,
如果headset_gpio ACTIVE配置为LOW那么需要拉低才能实现让系统一直检测到插入状态的效果 */
rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
上述配置完,要想让SPK能成功输出声音,还需要配置codec的相关设备树,其中需要把,spk-ctl-gpio配置成反向,正常情况下要想使能spk,那么spk-ctl-gpio是需要拉高的,但是现在不能拉高,目前系统检测到的是耳机插入,所以会把SPK给禁用掉,那么肯定按照配置的SPK的ACTIVE反向拉gpio,所以配置ACTIVE LOW之后就会拉高spk-ctl-gpio,这样SPK就出声了,但是带来的一个问题就是配置成这种方式(强制检测耳机插入),codec打开和关闭的时候会迅速拉一下SPK的控制引脚,这就导致了pop音的产生。而且状态栏一直有耳机图标显示,本来没插耳机但是会显示耳机,看起来很不舒服。
shell
rk809_codec: codec {
#sound-dai-cells = <0>;
compatible = "rockchip,rk809-codec", "rockchip,rk817-codec";
clocks = <&cru I2S1_MCLKOUT>;
clock-names = "mclk";
assigned-clocks = <&cru I2S1_MCLKOUT>, <&cru I2S1_MCLK_TX_IOE>;
assigned-clock-rates = <12288000>;
assigned-clock-parents = <&cru I2S1_MCLKOUT_TX>, <&cru I2S1_MCLKOUT_TX>;
pinctrl-names = "default";
pinctrl-0 = <&i2s1m0_mclk>;
hp-volume = <20>;
use-ext-amlifier;
spk-ctl-gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_LOW>;
spk-volume = <3>;
mic-in-differential;
status = "okay";
};
解决方法
上述方式肯定是不能满足调试需求的,但是如果把耳机和SPK的配置都按照正常的设置进行配置,又无法出声音(因为走的是SPK通路,客户功放并没有走SPK通路),尝试adb中使用tinymix指令切换播放通路到耳机通路后就能成功出声,但是音频播放结束再次播放又会走SPK通路,那么我把SPK通路和HP通路互换一下不就可以了!打开驱动修改之后,成功解决这个问题,下面是我的patch。
shell
--- a/kernel-4.19/sound/soc/codecs/rk817_codec.c
+++ b/kernel-4.19/sound/soc/codecs/rk817_codec.c
@@ -998,8 +1004,8 @@ static int rk817_digital_mute(struct snd_soc_dai *dai, int mute)
snd_soc_component_write(component, RK817_CODEC_ADAC_CFG1,
PWD_DACBIAS_ON | PWD_DACD_DOWN |
PWD_DACL_ON | PWD_DACR_ON);
- rk817_codec_ctl_gpio(rk817, CODEC_SET_SPK, 0);
- rk817_codec_ctl_gpio(rk817, CODEC_SET_HP, 1);
+ rk817_codec_ctl_gpio(rk817, CODEC_SET_SPK, 1);
+ rk817_codec_ctl_gpio(rk817, CODEC_SET_HP, 0);
--- a/kernel-4.19/sound/soc/codecs/rk817_codec.h
+++ b/kernel-4.19/sound/soc/codecs/rk817_codec.h
@@ -185,9 +185,11 @@ enum {
enum {
OFF,
RCV,
- SPK_PATH,
+ HP_NO_MIC,
HP_PATH,
- HP_NO_MIC,
+ SPK_PATH,
BT,
SPK_HP,
RING_SPK,