20250709荣品RD-RK3588开发板的Android13系统下修改为连续长按10s开机
2025/7/9 10:11
缘起:由于荣品RD-RK3588开发板使用的PMIC是RK806。
以前在荣品PRO-RK3566开发板上使用的PMIC是RK809上做过了长按开机的。
直接迁移过来了!
1、根据RK809的DATASHEET,短按开机【100ms/500ms】/长按关机,长按关机。6s/8s/10s
我在网上找到的DATASHEET是V1.0的,据说有V1.4的或者更新的?
如果有,方便的话,发一下。
2、我们希望长按2s开机。
如果 RK809的开机模式是写死了。我司需要 等待 2s时间 【以防 误操作/误触发】
可以使用这个上电逻辑不?
先让 RK809检测到500ms 开机指令,如果检测到,先【清除掉 寄存器中的开机指示?】,然后让 RK809等待1.5s == 1500ms,
现在 在 检测 电源键 是否还是按下的。如果是的。走正常的开机逻辑。
如果不是,就判定为 误操作,关机了。
或者您这边有更好的 上电逻辑/建议?
【荣品RD-RK3588开发板使用RK806这颗PMIC,看驱动名称使用了PMIC接口】
Z:\14TB\versions\RD-RK3588_Android13\u-boot\drivers\power\pmic\rk8xx_spi.c
【荣品PRO-RK3566开发板使用RK809这颗PMIC】
Z:\14TB\versions\pro3566_Android13.0\u-boot\drivers\power\pmic\rk8xx.c
Z:\14TB\versions\RD-RK3588_Android13\u-boot\drivers\power\pmic\rk8xx_spi.c
本次修改存在的问题:
1、uboot启动到pmic的probe大概1-2s。
之后需要检测POWERKEY按键是否连续按10s。
本程序简单的处理为10s的最后阶段检测一次。
实际上,需要在循环的每一次/一秒的延迟/间隔期间都需要检测,没有按POWER按键就直接走关机流程了!
2、本次关机流程,直接COPY了关机的代码。
实际上调用关机函数更好!
static int rk8xx_spi_probe(struct udevice *dev)
{
struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
struct rk8xx_priv *priv = dev_get_priv(dev);
struct udevice *spi = dev_get_parent(dev);
struct spi_slave *slave = NULL;
u8 on_source, off_source;
u8 msb, lsb, value = 0;
int ret;
printf("**** wyb 2025/6/26 16:58 %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
if (spi->seq < 0) {
dev_err(dev, "Failed to configure the spi num\n");
return -EINVAL;
}
slave = spi_setup_slave(spi->seq, plat->cs, plat->max_hz,
plat->mode);
if (!slave)
return -ENODEV;
priv->slave = slave;
/* read Chip variant */
ret = rk806_spi_read(dev, RK806_CHIP_NAME, &msb, 1);
if (ret) {
dev_err(dev, "rk806 name read error: %d\n", ret);
return ret;
}
ret = rk806_spi_read(dev, RK806_CHIP_VER, &lsb, 1);
if (ret) {
dev_err(dev, "rk806 version read error: %d\n", ret);
return ret;
}
priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
printf("spi%d: RK%x%x: %d\n", spi->seq, msb, (lsb >> 4), lsb & 0x0f);
rk806_spi_read(dev, RK806_ON_SOURCE, &on_source, 1);
rk806_spi_read(dev, RK806_OFF_SOURCE, &off_source, 1);
printf("ON=0x%02x, OFF=0x%02x\n", on_source, off_source);
ret = rk806_spi_read(dev, RK806_HW_VER, &value, 1);
if (ret)
panic("RK806: read RK806_HW_VER error!\n");
/* dual rk806 dev name: "rk806master@0", "rk806slave@1"
* single rk806 dev name: " rk806single@0"
*/
if ((!strcmp(dev->name, "rk806master@0")) || (!strcmp(dev->name, "rk806slave@1"))) {
if (value != HW_DUAL_PMIC) {
dev_err(dev, "HW single pmic, the firmware dual pmic(0x%x)!\n", value);
run_command("download", 0);
}
} else {
if (value != HW_SINGLE_PMIC) {
dev_err(dev, "HW dual pmic, the firmware single pmic(0x%x)!\n", value);
run_command("download", 0);
}
}
if ((lsb & 0x0f) == VERSION_AB) {
ret = rk806_spi_read(dev, RK806_SYS_CFG1, &value, 1);
if (ret) {
dev_err(dev, "rk806 RK806_SYS_CFG1 read error: %d\n", ret);
return ret;
}
value |= 0x80;
rk806_spi_write(dev, RK806_SYS_CFG1, &value, 1);
}
if (priv->rst_fun) {
rk806_spi_read(dev, RK806_SYS_CFG3, &value, 1);
value &= 0x3f;
if (priv->rst_fun == RK806_RST_MODE1) {
value |= (RK806_RST_MODE1 << 6);
rk806_spi_write(dev, RK806_SYS_CFG3, &value, 1);
} else if (priv->rst_fun == RK806_RST_MODE2) {
value |= (RK806_RST_MODE2 << 6);
rk806_spi_write(dev, RK806_SYS_CFG3, &value, 1);
}
}
rk8xx_spi_irq_chip_init(dev);
///* 10*100ms */
//mode = rockchip_get_boot_mode();
//printf("xxxx: mode: %d\n", mode);
//value=pmic_reg_read(dev, 0xf0)&0x80;
//printf("value=0x%x\n",value );
//if((pmic_reg_read(dev, 0xf0)&0x80) && mode == BOOT_MODE_UNDEFINE )
//{
// printf("xxxx: power off\n");
// rk8xx_shutdown(dev);
//}
//if ((pmic_reg_read(dev, 0xf0) & 0x80)==0 &&
// mode == BOOT_MODE_UNDEFINE) {
// i = 0;
// while (i < 10) {
// value = pmic_reg_read(dev, 0xf0) & 0x80;
// printf("value=0x%x\n",value );
// if ((value & 0x80)) {
// printf("xxxx: power off\n");
// rk8xx_shutdown(dev);
// }
// mdelay(100);
// i++;
// }
// printf("xxxx: power on\n");
//}
////for j = 0;
//for(j=0; j<256; j++)
//{
// //printf("0x%02x, ", pmic_reg_read(dev, j) );
// printf("0x%02x = 0x%02x\n", j, pmic_reg_read(dev, j) );
//}
//int j = 0;
//for(j=0; j<256; j++)
//{
// //printf("0x%02x, ", pmic_reg_read(dev, j) );
// //ret = rk806_spi_read(dev, RK806_SYS_CFG1, &value, 1);
// ret = rk806_spi_read(dev, j, &value, 1);
// //printf("0x%02x = 0x%02x\n", j, pmic_reg_read(dev, j) );
// printf("0x%02x = 0x%02x\n", j, value );
//}
int j = 0;
for(j=0; j<10; j++)
{
mdelay(1000);
printf("**** wyb 2025/6/26 16:58 %s %s %d j=%d\n", __FILE__, __FUNCTION__, __LINE__, j);
}
//ret = rk806_spi_read(dev, RK806_SYS_CFG3, &dev_off, 1);
ret = rk806_spi_read(dev, 0x5D, &value, 1);
if (0x80 == value)
{
u8 dev_off;
int ret = 0;
printf("**** wyb 2025/6/26 16:58 %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
ret = rk806_spi_read(dev, RK806_SYS_CFG3, &dev_off, 1);
if (ret)
return ret;
dev_off |= RK806_DEV_OFF;
ret = rk806_spi_write(dev, RK806_SYS_CFG3, &dev_off, 1);
if (ret) {
dev_err(dev, "rk806 shutdown error: %d\n", ret);
return ret;
}
while (1)
;
}
return 0;
}
static int rk8xx_spi_shutdown(struct udevice *dev)
{
u8 dev_off;
int ret = 0;
printf("**** wyb 2025/6/26 16:58 %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
ret = rk806_spi_read(dev, RK806_SYS_CFG3, &dev_off, 1);
if (ret)
return ret;
dev_off |= RK806_DEV_OFF;
ret = rk806_spi_write(dev, RK806_SYS_CFG3, &dev_off, 1);
if (ret) {
dev_err(dev, "rk806 shutdown error: %d\n", ret);
return ret;
}
while (1)
;
return 0;
}
参考资料:
https://blog.csdn.net/Y1anH/article/details/146641944?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-146641944-blog-127852443.235^v43^pc_blog_bottom_relevance_base5&spm=1001.2101.3001.4242.2&utm_relevant_index=3
RK806S PMIC电源管理芯片调试
https://blog.csdn.net/Y1anH/article/details/146641944
解析此处的核心代码
当点按PWRON按键时,rk806上电开始启动bootloader和uboot,在执行到此处时检测到是由于按键启动的,所以0x5d的值是0x80,0x74的值是0x80,在一般情况下,mode都默认是none的,所以mode值为11,因此就进入了我们的if判断,若是由于按键启动的,则直接调用rk8xx_shutdown函数关掉,进入这个函数会看到实际是通过i2c给0x72寄存器的BIT(0)写1,使其关机。
所以此操作就实现了点按PWRON按键无法开机,避免了误触情况。
在判断里加上0x74寄存器为0x40的情况,则避免了12V电源插入自动启动
而长按开机时,0x5d实际读到的值是0x00,所以不会进入此处的判断
关于此处按键寄存器检测的值,从逻辑上来看更像是按下为0x00,不按为0x80,这里后续还要再想办法测试一下,即rk806芯片手册与实际描述是相反的。或者与PWRON按键接vcc或GND有关,因为rk806手册按下按键时电平状态是拉低的
总之实现的逻辑是这样的,具体的场景需要微调寄存器判断的值
https://blog.csdn.net/u011774634/article/details/130585756?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ECtr-6-130585756-blog-127852443.235%5Ev43%5Epc_blog_bottom_relevance_base5&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ECtr-6-130585756-blog-127852443.235%5Ev43%5Epc_blog_bottom_relevance_base5&utm_relevant_index=11
RK3588S Android12修改PMIC(RK806)长按电源键强制关机的时长为10秒
https://blog.csdn.net/u011774634/article/details/130585756
--- a/kernel-5.10/drivers/mfd/rk806-core.c
+++ b/kernel-5.10/drivers/mfd/rk806-core.c
@@ -677,6 +677,8 @@ static int rk806_parse_dt(struct rk806 *rk806)
/* PWRON_ON_TIME: 0:500mS; 1:20mS */
if (device_property_read_bool(dev, "pwron-on-time-500ms"))
rk806_field_write(rk806, PWRON_ON_TIME, 0x00);
+
+ rk806_field_write(rk806,PWRON_LP_OFF_TIME,0x02);
return 0;
}
https://blog.csdn.net/u011774634/article/details/132744969?spm=1001.2101.3001.6650.7&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-132744969-blog-127852443.235%5Ev43%5Epc_blog_bottom_relevance_base5&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-132744969-blog-127852443.235%5Ev43%5Epc_blog_bottom_relevance_base5&utm_relevant_index=12
RK3588S Android12修改短按电源键的开机按键时长
https://blog.csdn.net/u011774634/article/details/132744969
RK806的power按键开机时长有2种选择,通过如下寄存器进行配置:
默认为20mS,如果要改为500mS,则将0x76寄存器的第7位写0即可。
dts修改方法为在rk806的节点中增加如下属性即可,如下修改:
--- a/kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588-rk806-single.dtsi
+++ b/kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588-rk806-single.dtsi
@@ -43,6 +43,8 @@
* and simultaneously pull down the RESETB PIN for 5mS before releasing
*/
pmic-reset-func = <1>;
+
+ pwron-on-time-500ms;
vcc1-supply = <&vcc5v0_sys>;
vcc2-supply = <&vcc5v0_sys>;
pwron-on-time-500ms的解析参考kernel-5.10\drivers\mfd\rk806-core.c中如下代码:
/* PWRON_ON_TIME: 0:500mS; 1:20mS */
if (device_property_read_bool(dev, "pwron-on-time-500ms"))
rk806_field_write(rk806, PWRON_ON_TIME, 0x00);
https://blog.csdn.net/weixin_43245753/article/details/127852443
RK3588长按power键强制关机的按键时间设置
https://wenku.csdn.net/answer/4cc3d5c9b6ae43f09a8c301a1ec7a02d?spm=1001.2101.3001.6650.20&utm_medium=distribute.pc_relevant.none-task-chatgpt-2%7Edefault%7ECTRLIST%7EPosition-20-4cc3d5c9b6ae43f09a8c301a1ec7a02d-blog-127852443.235%5Ev43%5Epc_blog_bottom_relevance_base5&depth_1-utm_source=distribute.pc_relevant.none-task-chatgpt-2%7Edefault%7ECTRLIST%7EPosition-20-4cc3d5c9b6ae43f09a8c301a1ec7a02d-blog-127852443.235%5Ev43%5Epc_blog_bottom_relevance_base5&utm_relevant_index=25
RK3568 Android11 去除长按power键关机的功能 - CSDN文库.mhtml
https://wenku.csdn.net/answer/4cc3d5c9b6ae43f09a8c301a1ec7a02d
RK3568 Android11 去除长按power键关机的功能
时间: 2023-09-11 13:10:10 浏览: 545
您可以通过修改系统源代码来实现去除长按power键关机的功能。具体的实现步骤如下:
1、打开系统源代码,并找到 frameworks/base/packages/systemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java 文件。
2、在该文件中找到 mPowerOptions = (Linearlayout) mDialog.findViewById(R.id.power_options);代码行。
3、在该代码行后面添加以下代码:
// 关闭长按 power 键关机功能
mPowerOptions.findViewById(R.id.shutdown).setVisibility(View.GONE);复制代码
4、保存文件并重新编译系统源代码。
5、在设备上安装编译后的系统镜像,并测试长按 power 键是否已经无法关机。
注意:该方法需要您具备一定的 Android 系统开发经验,并且需要对设备进行 ROOT 操作才能实现。另外,修改系统源代码可能会导致系统不稳定或无法正常升级,请谨慎操作。
https://www.rockchip.fr/RK809%20datasheet%20V1.01.pdf
RK809 Datasheet
【付费下载】
https://bbs.16rd.com/thread-566291-1-1.html
[瑞芯微RK资料]?瑞芯微RK809 datasheet数据手册1.4修订版本
如果 RK809的开机模式是写死了。我司需要 等待 2s时间 【以防 误操作/误触发】
可以使用这个上电逻辑不?
先让 RK809检测到500ms 开机指令,如果检测到,先【清除掉 寄存器中的开机指示?】,然后让 RK809等待1.5s == 1500ms,
现在 在 检测 电源键 是否还是按下的。如果是的。走正常的开机逻辑。
如果不是,就判定为 误操作,关机了。
或者您这边有更好的 上电逻辑/建议?
没有这样改过不清楚是否可行 ,如果是完全掉电的情况下rk809的寄存器是会重新初始化的,需要注意完全掉电的情况下 这个长按短按开机的判断不会生效@造诣==灶燚
1、我们地面站的电池是 直接 焊接到板上的。只要电池有电,可以保证 RK3566总是有电的。
2、我的考虑是在UBOOT阶段 使用2000 ms来判断RK809是 真实 需求上电?
还是 误触发。
【如果是误触发,直接在uboot阶段就关机了】
就算RK809掉电 也没有关系吧?
请问RK809的0xF7,里面的 PWRON_LP_TM 可以配置成为长按2秒钟开机吗?
不清楚这个寄存器实际对应的是哪个,你可以用i2cget 与i2cset 工具查看默认值 ,修改对应寄存器值测试
可以尝试在uboot 启动的时候在rk809的驱动 初始化部分添加操作寄存器的部分 通过这两个去获取对应pmic的引脚状态或着这个按键按下的状态看下
https://www.elecfans.com/d/2092347.html
【深圳触觉智能技术分享】RK3568 RK809电量计电池调试
https://www.elecfans.com/d/2089149.html
基于IDO-SBC3568主板说明PMIC RK809电量计的调试方法-电子发烧友网
https://blog.csdn.net/Industio_CSDN/article/details/130921874?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-130921874-blog-107173710.235^v43^pc_blog_bottom_relevance_base5&spm=1001.2101.3001.4242.2&utm_relevant_index=4
https://blog.csdn.net/Industio_CSDN/article/details/130921874
【深圳触觉智能技术分享】RK3568 RK809电量计电池调试
https://blog.csdn.net/qq_40715266/article/details/130229120?spm=1001.2101.3001.6650.18&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-18-130229120-blog-107173710.235%5Ev43%5Epc_blog_bottom_relevance_base5&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-18-130229120-blog-107173710.235%5Ev43%5Epc_blog_bottom_relevance_base5&utm_relevant_index=21
https://blog.csdn.net/qq_40715266/article/details/130229120
rk3568-rk809电池电量计
[*] CW2015 Battery driver
https://www.rockchip.fr/RK809%20datasheet%20V1.01.pdf
RK809 Datasheet
【PDF】
Rockchip RK809 Datasheet
文件格式:PDF/Adobe Acrobat -
翻译此页
7 RK809 Datasheet Rev 1.01 Chapter 1 Introduction 1.1 Overview The RK809 is a complex power-management integrated circuit (PMIC) integrated CODEC for multi-core system applications powered by an external power supply. The RK809 can provide a complete power management solution with very few ...
www.rockchip.fr/RK809 datasheet...
【参考资料:】
https://damodev.csdn.net/68243289a5baf817cf4bb2d5.html?dp_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MjQwNTYwLCJleHAiOjE3NDk1Mzk2ODksImlhdCI6MTc0ODkzNDg4OSwidXNlcm5hbWUiOiJ3YjQ5MTYifQ.H5IbfRcXuGLiIByHSErH_Ot8Y5r_XJUMkbGuVadaNkw&spm=1001.2101.3001.6650.4&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7Eactivity-4-146173693-blog-107173710.235%5Ev43%5Epc_blog_bottom_relevance_base5&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7Eactivity-4-146173693-blog-107173710.235%5Ev43%5Epc_blog_bottom_relevance_base5&utm_relevant_index=7
https://damodev.csdn.net/68243289a5baf817cf4bb2d5.html
RK809-5电源管理芯片(PMIC)主要有以下几种开机模式:
BING:RK809 dts press-on-time = <0>;
https://blog.csdn.net/cew333/article/details/126164529
[RK3568 Android11] RK809开机短按时间设置和长按电源键设置
https://www.codeleading.com/article/72216664876/
[RK3568 Android11] RK809开机短按时间设置和长按电源键设置
一、长按电源键 关机
二、短按开机电源键响应时间 开机
https://www.uudwc.com/A/dMX9M/
rk3568 长按电源键关机修改
https://blog.csdn.net/u011774634/article/details/132744969?spm=1001.2101.3001.6650.17&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-17-132744969-blog-115718749.235%5Ev43%5Epc_blog_bottom_relevance_base5&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-17-132744969-blog-115718749.235%5Ev43%5Epc_blog_bottom_relevance_base5&utm_relevant_index=21
https://blog.csdn.net/u011774634/article/details/132744969
RK3588S Android12修改短按电源键的开机按键时长
RK806的power按键开机时长有2种选择,通过如下寄存器进行配置:
默认为20mS,如果要改为500mS,则将0x76寄存器的第7位写0即可。
dts修改方法为在rk806的节点中增加如下属性即可,如下修改:
--- a/kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588-rk806-single.dtsi
+++ b/kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588-rk806-single.dtsi
@@ -43,6 +43,8 @@
* and simultaneously pull down the RESETB PIN for 5mS before releasing
*/
pmic-reset-func = <1>;
+
+ pwron-on-time-500ms;
vcc1-supply = <&vcc5v0_sys>;
vcc2-supply = <&vcc5v0_sys>;
pwron-on-time-500ms的解析参考kernel-5.10\drivers\mfd\rk806-core.c中如下代码:
/* PWRON_ON_TIME: 0:500mS; 1:20mS */
if (device_property_read_bool(dev, "pwron-on-time-500ms"))
rk806_field_write(rk806, PWRON_ON_TIME, 0x00);
https://blog.csdn.net/tianlai1009/article/details/107173710?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522d5016a5486700307a67c49ef8efaa4be%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=d5016a5486700307a67c49ef8efaa4be&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-8-107173710-null-null.142^v102^pc_search_result_base6&utm_term=RK3566%20uboot%20%E9%95%BF%E6%8C%89%20%E5%BC%80%E6%9C%BA&spm=1018.2226.3001.4187
https://blog.csdn.net/tianlai1009/article/details/107173710
RK809搞一下长按PWR键重启
拿到的源码默认长按关机,短按开机,
不要长按关机,
只要长按重启
那么看一下规格书:
看一下驱动:
没有做这个寄存器的配置?i2cset测试一下:
i2cget -f -y 0 0x20 0xf7
0x86
默认是86,长按关机,
那自己加一下试试:
i2cset -f -y 0 0x20 0xf7 0xc6
测试成功。
自己加一下寄存器初始化:
/* power down configuration 0xf7 */
#define RK817_PWR_KEY_LONG_PRESS_MASK BIT(6)
#define RK817_PWR_KEY_LONG_PRESS_H BIT(6)
#define RK817_PWR_KEY_LONG_PRESS_L (0)
static const struct rk808_reg_data rk817_pre_init_reg[] = {
{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_L},
{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
RK817_HOTDIE_105 | RK817_TSD_140},
{RK817_PMIC_PWRON_KEY,RK817_PWR_KEY_LONG_PRESS_MASK,RK817_PWR_KEY_LONG_PRESS_H}
};