20250607 在荣品 PRO-RK3566 开发板的 Android13 系统下,解决长按开机后插入适配器不会自动启动的问题

[复制链接]
发表于 10 小时前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
在荣品 PRO-RK3566 开发板上跑 Android 13,把开机改成"长按 2 秒"牵动的不只是一行参数,而是 PMIC 的整个上电时序。这篇记录我在 U-Boot 2017.09 里改 drivers/power/pmic/rk8xx.c 的做法和踩到的坑:长按开机的补丁做完,插上适配器后板子却不再自动开机,最后靠 RK809 的 PMIC_ON_SOURCE 寄存器才把上电来源理顺。

RK809 的开机时序约定

先把硬件约定说清楚。按 RK809 的 DATASHEET,短按开机是【100ms/500ms】,长按关机分成 6s/8s/10s 几档。我在网上找到的 DATASHEET 是 V1.0 版,听说还有 V1.4 或者更新的版本,手上有新版的方便的话发我一份。

我们的目标是把开机改成长按 2s。如果 RK809 的开机模式是写死的,那就只能在软件里多等 2s 再判一次,避免误操作触发。上电逻辑可以这么走:


  • 先让 RK809 检测到 500ms 的开机指令;
  • 检测到之后先把寄存器里的开机指示清掉;
  • 再让 RK809 等 1.5s,也就是 1500ms;
  • 等完重新读电源键是不是还按着;
  • 还按着就走正常开机流程,已经松开就判为误操作,直接关机。


这块如果你有更干净的上电逻辑或者别的做法,欢迎回帖交流。

U-Boot 侧的补丁实现

下面这个 patch 已经实测可以把按键 2s 开机跑通,改动的文件是 Z:\Android13.0\u-boot\drivers\power\pmic\rk8xx.c:
  1. diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
  2. old mode 100644
  3. new mode 100755
  4. index e361015337..e44c38448a
  5. --- a/drivers/power/pmic/rk8xx.c
  6. +++ b/drivers/power/pmic/rk8xx.c
  7. @@ -6,6 +6,7 @@
  8.    */
  9. #include <common.h>
  10. +#include <boot_rkimg.h>
  11. #include <dm.h>
  12. #include <errno.h>
  13. #include <irq-generic.h>
  14. @@ -486,6 +487,8 @@ static int rk8xx_probe(struct udevice *dev)
  15.            uint8_t power_en0, power_en1, power_en2, power_en3;
  16.            uint8_t on, off;
  17.            uint8_t value;
  18. +        int mode;
  19. +
  20.            /* read Chip variant */
  21.            if (device_is_compatible(dev, "rockchip,rk817") ||
  22. @@ -618,6 +621,31 @@ static int rk8xx_probe(struct udevice *dev)
  23.                    printf("IRQ chip initial failed\n");
  24.                    return ret;
  25.            }
  26. +        /* 10*100ms */
  27. +        mode = rockchip_get_boot_mode();
  28. +        printf("xxxx: mode: %d\n", mode);
  29. +        value=pmic_reg_read(dev, 0xf0)&0x80;
  30. +        printf("value=0x%x\n",value );
  31. +        if((pmic_reg_read(dev, 0xf0)&0x80) && mode == BOOT_MODE_UNDEFINE )
  32. +        {
  33. +                printf("xxxx: power off\n");
  34. +                rk8xx_shutdown(dev);
  35. +        }
  36. +        if ((pmic_reg_read(dev, 0xf0) & 0x80)==0 &&
  37. +                mode == BOOT_MODE_UNDEFINE) {
  38. +                i = 0;
  39. +                while (i < 10) {
  40. +                        value = pmic_reg_read(dev, 0xf0) & 0x80;
  41. +                        printf("value=0x%x\n",value );
  42. +                        if ((value & 0x80)) {
  43. +                                printf("xxxx: power off\n");
  44. +                                rk8xx_shutdown(dev);
  45. +                        }
  46. +                        mdelay(100);
  47. +                        i++;
  48. +                }
  49. +                printf("xxxx: power on\n");
  50. +        }
  51.            return 0;
  52.   }
复制代码

改完之后 rk8xx_probe 里在 rk8xx_irq_chip_init 返回之后插入的这一段,就是上面那套"先等 1.5s 再看按键"的逻辑:
  1.           ret = rk8xx_irq_chip_init(dev);
  2.           if (ret) {
  3.                   printf("IRQ chip initial failed\n");
  4.                   return ret;
  5.           }
  6.           /* 10*100ms */
  7.           mode = rockchip_get_boot_mode();
  8.           printf("xxxx: mode: %d\n", mode);
  9.           for j = 0;
  10.           //for(j=0; j<256; j++)
  11.           //{
  12.           //          //printf("0x%02x, ", pmic_reg_read(dev, j) );
  13.           //          printf("0x%02x = 0x%02x\n", j, pmic_reg_read(dev, j) );
  14.           //}
  15.           //if( 0x82 == pmic_reg_read(dev, 0xf0) )
  16.           if( 0x40 == pmic_reg_read(dev, 0xf5) )
  17.           //if( 0 )
  18.           {
  19.                   printf("**** Success 2025/6/5 20:12 %s %s %d have +12V !\n", __FILE__, __FUNCTION__, __LINE__);
  20.           }
  21.           else
  22.           {
  23.                   value=pmic_reg_read(dev, 0xf0)&0x80;
  24.                   printf("value=0x%x\n",value );
  25.                   if((pmic_reg_read(dev, 0xf0)&0x80) && mode == BOOT_MODE_UNDEFINE )
  26.                   {
  27.                           printf("xxxx: power off\n");
  28.                           rk8xx_shutdown(dev);
  29.                   }
  30.                   if ((pmic_reg_read(dev, 0xf0) & 0x80)==0 &&
  31.                       mode == BOOT_MODE_UNDEFINE) {
  32.                           i = 0;
  33.                           //while (i < 30) {
  34.                           //while (i < 5) {
  35.                           while (i < 2) {
  36.                                   value = pmic_reg_read(dev, 0xf0) & 0x80;
  37.                                   printf("value=0x%x\n",value );
  38.                                   if ((value & 0x80)) {
  39.                                           printf("xxxx: power off\n");
  40.                                           rk8xx_shutdown(dev);
  41.                                   }
  42.                                   mdelay(10);
  43.                                   printf("**** wyb 2025/6/4 17:43 %s %s %d i=%d s! loop 2 ---- mdelay 10ms\n", __FILE__, __FUNCTION__, __LINE__, i);
  44.                                   //mdelay(1000);
  45.                                   i++;
  46.                           }
  47.                           printf("xxxx: power on\n");
  48.                   }
  49.           }
  50.           return 0;
  51. }
复制代码

实测启动日志与环境信息
  1. U-Boot 2017.09 (Jun 07 2025 - 17:34:50 +0800)
  2. Model: Rockchip RK3568 Evaluation Board
  3. MPIDR: 0x81000000
  4. PreSerial: 2, raw, 0xfe660000
  5. DRAM:  4 GiB
  6. Sysmem: init
  7. Relocation Offset: ed218000
  8. Relocation fdt: eb9f8aa8 - eb9fecd0
  9. CR: M/C/I
  10. Using default environment
  11. optee api revision: 2.0
  12. dwmmc@fe2b0000: 1, dwmmc@fe2c0000: 2, sdhci@fe310000: 0
  13. Bootdev(atags): mmc 0
  14. MMC0: HS200, 200Mhz
  15. PartType: EFI
  16. DM: v1
  17. Android 13.0, Build 2023.8, v2
  18. boot mode: None
  19. RESC: 'boot', blk@0x0001da6c
  20. Device is: UNLOCKED
  21. DTB: rk-kernel.dtb
  22. HASH(c): OK
  23. ANDROID: fdt overlay OK
  24. **** wyb 2025/5/30 17:47 drivers/power/pmic/rk8xx.c rk8xx_bind 334
  25. I2c0 speed: 100000Hz
  26. **** wyb 2025/5/30 17:47 drivers/power/pmic/rk8xx.c rk8xx_ofdata_to_platdata 389
  27. **** wyb 2025/5/30 17:47 drivers/power/pmic/rk8xx.c rk8xx_probe 521
  28. PMIC:  RK8090 (on=0x40, off=0x80)
  29. **** wyb 2025/5/30 17:47 drivers/power/pmic/rk8xx.c rk8xx_irq_chip_init 447
  30. xxxx: mode: 11
  31. value=0x80
  32. xxxx: power off
  33. **** wyb 2025/5/30 17:47 drivers/power/pmic/rk8xx.c rk8xx_shutdown 293
复制代码

版本号和时序都对得上:U-Boot 2017.09、Android 13.0 Build 2023.8、DRAM 4 GiB,PMIC 打印成 RK8090(on=0x40, off=0x80)。但日志最后停在 xxxx: mode: 11 → value=0x80 → xxxx: power off,说明这次上电被流程判成了"该关机"。

已知问题:插适配器之后不自动开机

这个 patch 已经能做到按键 2s 开机,但留下一个明确的 BUG:现在插电或者插适配器之后,RK3566 不会自动开机了。这一步正好和"插上电就自己起来"相反,所以想请教一下这里能不能修,还是说要实现这个行为必须再补别的条件。

对着原理图找放电路径



把原理图对了一遍,逻辑本身是成立的:VDC 应该只在 DC 上电的那一瞬间有电压导通启动,之后靠其他电路把它放掉。也就是说手动按开机键这条路径和插适配器那条路径,在 PMIC 看来不是一回事,不能用同一套判断套在一起。







用 PMIC_ON_SOURCE 区分上电方式

翻手册时看到可以用 PMIC_ON_SOURCE 寄存器拿到当前的启动方式,把这次的启动来源区分开:


  • 读 0xf5 寄存器的第 6 位,就能知道现在是哪种方式启动;
  • 这一位读出来是 1,说明这次是 DC 触发开机;
  • 既然是 DC 触发,就不要再跑后面那套 power 判定逻辑;
  • 只有不是 DC 上电的情况,才走长按 2s 的按键判断。


这样处理的话,插适配器直接自动开机和长按按键开机两条路径就不会互相打架。





RK809 开机时序这套改动目前还停在 U-Boot 阶段,判别条件依赖 BOOT_MODE_UNDEFINE 和 0xf5 第 6 位这两个点,改之前先把 DATASHEET 新版拿到手对一遍。

编辑提示:要做长按开机的可以先照着 patch 改 rk8xx.c,但务必先确认自己板子的 VDC 放电电路,否则插适配器不自动开机的问题只会更明显。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表