ALC5651休眠唤醒音频失效问题
问题描述:用的是ALC5651的codec,测试偶发主板休眠唤醒之后,录音和喇叭播放声音都失效了。再重启,发现就能恢复正常。
问题分析:涉及到休眠唤醒后之类出现的问题,一般都是往休眠过程供电掉电、寄存器复位等方面去排查。
问题原因:codec供电接的是vcc_1v8_s0和vcc_3v3_s0,深度睡眠会掉电,唤醒后需要对寄存器做初始化动作。

出问题的时候,i2s时钟和数据是有的,LOUT/ROUT没有信号输出。

对比正常音频时候,0x13d的这个寄存器的值有问题。
经跟瑞昱原厂工程师沟通,这种休眠后断电的情况,可以通过驱动唤醒过程写寄存器去修复。
static const struct reg_sequence init_list[] = { {RT5651_PR_BASE + 0x3d, 0x3e00}, };
+static int rt5651_index_sync(struct snd_soc_component *component) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(init_list); i++) { + if (RT5651_PR_BASE & init_list[i].reg) { + snd_soc_component_write(component, init_list[i].reg, init_list[i].def); + printk("%s, reg=0x%x, val=0x%x\n", __func__, init_list[i].reg, init_list[i].def); + } + } + return 0; +} static int rt5651_resume(struct snd_soc_component *component) { struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); regcache_cache_only(rt5651->regmap, false); snd_soc_component_cache_sync(component); + rt5651_index_sync(component); return 0; }
但经过测试验证,好像有的时候休眠唤醒走rt5651_resume这个流程有点问题,有时候会走SET_SYSTEM_SLEEP_PM_OPS这个流程:
@@ -2281,6 +2294,32 @@ static const struct i2c_device_id rt5651_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt5651_i2c_id); +#ifdef CONFIG_PM_SLEEP +static int rt5651_sys_suspend(struct device *dev) +{ + struct rt5651_priv *rt5651 = dev_get_drvdata(dev); + + regcache_cache_only(rt5651->regmap, true); + regcache_mark_dirty(rt5651->regmap); + return 0; +} + +static int rt5651_sys_resume(struct device *dev) +{ + struct rt5651_priv *rt5651 = dev_get_drvdata(dev); + + regcache_cache_only(rt5651->regmap, false); + snd_soc_component_cache_sync(rt5651->component); + rt5651_index_sync(rt5651->component); + + return 0; +} +#endif + +static const struct dev_pm_ops rt5651_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(rt5651_sys_suspend, rt5651_sys_resume) +}; + @@ -2366,6 +2405,7 @@ static struct i2c_driver rt5651_i2c_driver = { .name = "rt5651", .acpi_match_table = ACPI_PTR(rt5651_acpi_match), .of_match_table = of_match_ptr(rt5651_of_match), + .pm = &rt5651_pm_ops, }, .probe = rt5651_i2c_probe, .id_table = rt5651_i2c_id,


唤醒过程相当于做了两次操作,rt5651_sys_resume这次即使失败了,rt5651_resume还会写每一次寄存器。

浙公网安备 33010602011771号