RK3288 主板上的RT5651芯片SPK音频无声音问题解决方案

简介: RK3288 主板上的RT5651芯片SPK音频无声音问题解决方案

本文介绍解决在早期出货的Rockchip RK3288主板运行Android 8.1时,我们遇到了RT5651芯片的SPK(扬声器)概率性无声音问题。将详细介绍问题的现象、之前的解决尝试以及最终的优化方法。

正常现象

当HDMI和SPK(或HP耳机)同时连接时,系统会优先通过HDMI输出音频。如果拔掉HDMI,系统则会切换到SPK或HP输出。

之前的现象

Android 5.1版本中,音频输出功能表现正常,没有发现问题。然而在Android 8.1版本中,部分主板在第一次刷机后能正常输出音频(日志显示Device IO被正确识别,且没有patch错误)。但是软重启(reboot)后音频仍能正常输出,断电重启则无声音。

怀疑是跟驱动+新做的主板硬件时序兼容性有关

优化方法

针对上述问题,我们对内核中的RT5651驱动代码进行了如下优化:

文件路径:kernel/sound/soc/codecs/rt5651.c

代码优化

static int rt5651_i2c_probe(struct i2c_client *i2c,
        const struct i2c_device_id *id)
{
  struct rt5651_platform_data *pdata = dev_get_platdata(&i2c->dev);
  struct rt5651_priv *rt5651;
  int ret;
  rt5651 = devm_kzalloc(&i2c->dev, sizeof(*rt5651), GFP_KERNEL);
  if (!rt5651)
    return -ENOMEM;
  i2c_set_clientdata(i2c, rt5651);
  rt5651->regmap = devm_regmap_init_i2c(i2c, &rt5651_regmap);
  if (IS_ERR(rt5651->regmap)) {
    ret = PTR_ERR(rt5651->regmap);
    dev_err(&i2c->dev, "Failed to allocate register map: %d\n", ret);
    return ret;
  }
  regmap_write(rt5651->regmap, RT5651_RESET, 0);
  msleep(120);
  regmap_write(rt5651->regmap, RT5651_RESET, 0);
}
static int rt5651_i2c_probe(struct i2c_client *i2c,
        const struct i2c_device_id *id)
{
  struct rt5651_platform_data *pdata = dev_get_platdata(&i2c->dev);
  struct rt5651_priv *rt5651;
  int ret;
  enum of_gpio_flags flags = 0;
  
  rt5651 = devm_kzalloc(&i2c->dev, sizeof(*rt5651),
        GFP_KERNEL);
  if (NULL == rt5651)
    return -ENOMEM;
  i2c_set_clientdata(i2c, rt5651);
  g_rt5651 = rt5651;
  if (pdata)
    rt5651->pdata = *pdata;
  
  rt5651->regmap = devm_regmap_init_i2c(i2c, &rt5651_regmap);
  if (IS_ERR(rt5651->regmap)) {
    ret = PTR_ERR(rt5651->regmap);
    dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
      ret);
    return ret;
  }
  regmap_write(rt5651->regmap, RT5651_RESET, 0);
  //add start 
  msleep(100);
  
  int retries = 10; // 设置重试次数
  while (retries > 0) {
    ret = regmap_register_patch(rt5651->regmap, init_list,
                  ARRAY_SIZE(init_list));
    if (ret != 0) {
      msleep(50);
      regmap_write(rt5651->regmap, RT5651_RESET, 0);
      dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
      retries--; // 减少重试次数
      continue; // 重新尝试
    }
    break; // 注册成功,退出循环
  }
  
  if (retries == 0) {
    dev_warn(&i2c->dev, "Failed to apply regmap patch after retries\n");
  }
  //add end
  if (rt5651->pdata.in2_diff)
    regmap_update_bits(rt5651->regmap, RT5651_IN1_IN2,
              RT5651_IN_DF2, RT5651_IN_DF2);
  if (rt5651->pdata.dmic_en)
    regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1,
              RT5651_GP2_PIN_MASK, RT5651_GP2_PIN_DMIC1_SCL);
...

优化结果

经过上述优化后,部分之前无声音的主板在Android 8.1软件上SPK和HP均恢复了声音输出。

调试相关

  1. RT5651驱动必须成功加载,否则HDMI无法输出声音。声卡是共用的,系统只显示一个声卡。
  2. RT5651不能以ko(内核模块)方式加载,即使加载成功,也只有HDMI有声音,SPK无法注册,这与底层的codec其他驱动时序加载不匹配。

调试命令

以下是一些有用的调试命令,可以帮助诊断声卡问题:

  1. 查看系统已注册的声卡:cat /proc/asound/cards
  2. 查看当前声卡设备:ls -l /dev/snd/
  3. 查看声卡状态和信息:cat /proc/asound/card*/pcm*/sub*/status | grep 'stat|close' -EC1

如果系统有声音,则会显示running,这可以排除软件问题。

相关文章
|
6月前
|
编解码 安全 芯片
七功能遥控编解码芯片
一、基本概述 TT6/TR6 是一对为遥控玩具车设计的 CMOS LSI 芯片。TT6 为发射编码芯片,TR6 为接收解码芯片。TT6/TR6 提供七个功能按键控制前进、后退、左转、右转、加速、独立功能 F1,独立功能 F2 的动作。除此以外,还有这五种常规小车功能(前、后、左、右和加速)的组合,此组合实现了前进和后退功能的两檔变速。 TT6 内置自动关机功能。当功能输入脚接地时,TT6 被唤醒,SO 和 SC 持续分别用 RF 格式(无载波)和 IR 格式(有载波)发送代码。当一个完整的代码发送出去且按键松开后,TT6 将自动进入待机模式。 TR6 提供了两个高效率的放大器和增强的信号
|
传感器 编解码 开发者
MCU SPI屏也能跑这么炫酷的特效?来,移植起来秀一秀
MCU SPI屏也能跑这么炫酷的特效?来,移植起来秀一秀
132 0
|
存储 物联网
stm32驱动RFID高频读卡器读取IC卡
stm32驱动RFID高频读卡器读取IC卡
169 0
|
6月前
|
编解码 并行计算 计算机视觉
jetson-ffmpeg对视频硬编解码实测记录
jetson-ffmpeg对视频硬编解码实测记录
420 0
|
缓存 物联网 编译器
国产MCU-CW32F030开发学习--按键检测
国产MCU-CW32F030开发学习--按键检测
208 0
国产MCU-CW32F030开发学习--按键检测
|
传感器
手持便携VH501TC混合信号采集仪的常见问题
不能开机 检查电池是否有电,检查电池安装极性是否正确。
手持便携VH501TC混合信号采集仪的常见问题
|
开发工具
RK3399平台开发系列讲解(内核驱动外设篇)6.19、摄像头OV4689模组驱动代码分析
RK3399平台开发系列讲解(内核驱动外设篇)6.19、摄像头OV4689模组驱动代码分析
199 0
 RK3399平台开发系列讲解(内核驱动外设篇)6.19、摄像头OV4689模组驱动代码分析
|
芯片
【全栈计划 —— 单片机】——Part_03 使用放大电路或拓展芯片解决GPIO的输出电流不足够支持驱动设备的问题(3)
【全栈计划 —— 单片机】——Part_03 使用放大电路或拓展芯片解决GPIO的输出电流不足够支持驱动设备的问题(3)
717 0
【全栈计划 —— 单片机】——Part_03 使用放大电路或拓展芯片解决GPIO的输出电流不足够支持驱动设备的问题(3)
|
芯片
【全栈计划 —— 单片机】——Part_03 使用放大电路或拓展芯片解决GPIO的输出电流不足够支持驱动设备的问题(1)
【全栈计划 —— 单片机】——Part_03 使用放大电路或拓展芯片解决GPIO的输出电流不足够支持驱动设备的问题(1)
230 0
【全栈计划 —— 单片机】——Part_03 使用放大电路或拓展芯片解决GPIO的输出电流不足够支持驱动设备的问题(1)
|
算法 芯片 计算机视觉
【全栈计划 —— 单片机】——Part_03 使用放大电路或拓展芯片解决GPIO的输出电流不足够支持驱动设备的问题(2)
【全栈计划 —— 单片机】——Part_03 使用放大电路或拓展芯片解决GPIO的输出电流不足够支持驱动设备的问题(2)
125 0
【全栈计划 —— 单片机】——Part_03 使用放大电路或拓展芯片解决GPIO的输出电流不足够支持驱动设备的问题(2)