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还会写每一次寄存器。

posted @   M-kobe  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示