关键函数: val = dev_read_bool(dev, "vccsys-shutdown-in-poweroff-mode");
因为rk提供了一个修复漏电的patch,如下:
From 273c2528ca9a1db484f188533d446231d15dc49f Mon Sep 17 00:00:00 2001
From: shengfei Xu <xsf@rock-chips.com>
Date: Tue, 13 Dec 2022 07:00:30 +0000
Subject: [PATCH] pmic: rk8xx: control the vccsys on/off in PWR_OFF mode
whether the system voltage can be shutdown in PWR_OFF mode config from dts
Signed-off-by: shengfei Xu <xsf@rock-chips.com>
Change-Id: I806d7c78fd37758e2a8637203b640dec9fb9f839
---
drivers/power/pmic/rk8xx.c | 23 +++++++++++++++++++++++
include/power/rk8xx_pmic.h | 2 ++
2 files changed, 25 insertions(+)
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index e361015337..abd42085c4 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -408,6 +408,9 @@ static int rk8xx_ofdata_to_platdata(struct udevice *dev)
val = dev_read_u32_default(dev, "not-save-power-en", 0);
rk8xx->not_save_power_en = val;
+ val = dev_read_bool(dev, "vccsys-shutdown-in-poweroff-mode");
+ rk8xx->sys_can_sd = val;
+
return 0;
}
@@ -541,6 +544,26 @@ static int rk8xx_probe(struct udevice *dev)
lp_act_msk = RK8XX_LP_ACTION_MSK;
init_data = rk817_init_reg;
init_data_num = ARRAY_SIZE(rk817_init_reg);
+
+ /* whether the system voltage can be shutdown in PWR_off mode */
+ if (priv->sys_can_sd) {
+ ret = rk8xx_read(dev, RK817_PMIC_CHRG_TERM, &value, 1);
+ if (ret)
+ return ret;
+ value |= 0x80;
+ ret = rk8xx_write(dev, RK817_PMIC_CHRG_TERM, &value, 1);
+ if (ret)
+ return ret;
+ } else {
+ ret = rk8xx_read(dev, RK817_PMIC_CHRG_TERM, &value, 1);
+ if (ret)
+ return ret;
+ value &= 0x7f;
+ ret = rk8xx_write(dev, RK817_PMIC_CHRG_TERM, &value, 1);
+ if (ret)
+ return ret;
+ }
+
/* judge whether save the PMIC_POWER_EN register */
if (priv->not_save_power_en)
break;
diff --git a/include/power/rk8xx_pmic.h b/include/power/rk8xx_pmic.h
index aa51e887e4..84d1104dab 100644
--- a/include/power/rk8xx_pmic.h
+++ b/include/power/rk8xx_pmic.h
@@ -206,6 +206,7 @@ enum {
#define RK817_ID_LSB 0xee
#define RK8XX_ID_MSK 0xfff0
+#define RK817_PMIC_CHRG_TERM 0xe6
#define RK817_PMIC_SYS_CFG1 0xf1
#define RK817_PMIC_SYS_CFG3 0xf4
#define RK817_GPIO_INT_CFG 0xfe
@@ -287,6 +288,7 @@ struct rk8xx_priv {
uint8_t sleep_pin;
uint8_t rst_fun;
int not_save_power_en;
+ int sys_can_sd;
};
int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt);
--
2.17.1
其中逻辑上:
if (priv->sys_can_sd) 这个逻辑判断是来自priv->sys_can_sd的属性,那么结合上面的
+ val = dev_read_bool(dev, "vccsys-shutdown-in-poweroff-mode");
+ rk8xx->sys_can_sd = val;
就看起来很清晰易懂,这两行代码是一个设备驱动中读取设备树配置的常见操作:
1. dev_read_bool(dev, "vccsys-shutdown-in-poweroff-mode")
功能:
从设备树(Device Tree)中读取一个布尔属性值。
参数解析:
-
dev: 指向设备结构体的指针,通常代表一个硬件设备 -
"vccsys-shutdown-in-poweroff-mode": 设备树中的属性名
工作原理:
-
在设备树(.dts文件)中查找当前设备节点
-
查找该节点下名为
vccsys-shutdown-in-poweroff-mode的属性 -
如果属性存在且为
true,返回true -
如果属性不存在或为
false,返回false
设备树示例:
&rk808 {
vccsys-shutdown-in-poweroff-mode = <1>; // 1表示true
// 或者
// vccsys-shutdown-in-poweroff-mode;
};
2. rk8xx->sys_can_sd = val
功能:
将读取到的布尔值存储到驱动数据结构中。
参数解析:
-
rk8xx: 指向设备私有数据结构的指针 -
sys_can_sd: 结构体成员,可能是 "system can shutdown" 的缩写 -
val: 从设备树读取的布尔值
整体功能
这两行代码组合起来的意思是:
-
从设备树配置中读取系统是否支持在关机模式下关闭VCCSYS电源
-
将这个配置保存到驱动的内部状态中,供后续的电源管理逻辑使用
实际应用场景
这在RK8xx系列电源管理芯片(PMIC)驱动中很常见,用于控制:
-
系统关机时是否完全切断电源
-
低功耗模式下的电源管理策略
-
系统唤醒和休眠的电源控制
这样设计的好处是:
-
灵活性:通过设备树配置,同一个驱动可以适应不同的硬件设计
-
可移植性:不同板级配置只需修改设备树,无需修改驱动代码
-
运行时配置:系统可以根据配置决定最优的电源管理策略
实测验证;
hzs@sr658:~/rk3562-optmv-idd1/u-boot$ git diff ./
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index 64c48f8a2d..06e67b692a 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -604,6 +604,12 @@ static int rk8xx_ofdata_to_platdata(struct udevice *dev)
rk8xx->pwr_ctr[1] = dev_read_u32_default(dev, "pwrctrl2_output", -1);
rk8xx->pwr_ctr[2] = dev_read_u32_default(dev, "pwrctrl3_output", -1);
+ //Add by rk for 11mA patch
+ val = dev_read_bool(dev, "vccsys-shutdown-in-poweroff-mode");
+ rk8xx->sys_can_sd = val;
+ printf("[%s] val = %d, rk8xx->sys_can_sd = %d \n", __func__, val, rk8xx->sys_can_sd);
+ //end by rk
+
return 0;
}
@@ -647,6 +653,7 @@ static int rk8xx_probe(struct udevice *dev)
uint8_t on, off;
uint8_t value;
+ printf("[%s] enter 2025-12-23 14:16 \n", __func__);
/* read Chip variant */
if (device_is_compatible(dev, "rockchip,rk817") ||
device_is_compatible(dev, "rockchip,rk809")) {
@@ -757,7 +764,9 @@ static int rk8xx_probe(struct udevice *dev)
init_data_num = ARRAY_SIZE(rk817_init_reg);
/* whether the system voltage can be shutdown in PWR_off mode */
- if (priv->sys_can_sd) {
+ //if (priv->sys_can_sd) {
+ if (1) { //add by rk for 11mA BUG
+ printf("[%s] RK817_ID = %x LINE = %d \n", __func__, RK817_ID, __LINE__);
ret = rk8xx_read(dev, RK817_PMIC_CHRG_TERM, &value, 1);
if (ret)
return ret;
hzs@sr658:~/rk3562-optmv-idd1/u-boot$
DTS部分的修改:

rk817: pmic@20 {
compatible = "rockchip,rk817";
reg = <0x20>;
interrupt-parent = <&gpio0>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default", "pmic-sleep",
"pmic-power-off", "pmic-reset";
pinctrl-0 = <&pmic_int>;
pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>;
pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>;
pinctrl-3 = <&soc_slppin_gpio>, <&rk817_slppin_rst>;
rockchip,system-power-controller;
vccsys-shutdown-in-poweroff-mode = <1>; // 1表示true
wakeup-source;
#clock-cells = <1>;
clock-output-names = "rk808-clkout1", "rk808-clkout2";
/* 1: rst regs (default in codes), 0: rst the pmic */
pmic-reset-func = <0>;
vcc1-supply = <&vcc_sys>;
vcc2-supply = <&vcc_sys>;
vcc3-supply = <&vcc_sys>;
vcc4-supply = <&vcc_sys>;
vcc5-supply = <&vcc_sys>;
vcc6-supply = <&vcc_sys>;
vcc7-supply = <&vcc_sys>;
vcc8-supply = <&vcc_sys>;
vcc9-supply = <&dcdc_boost>;
pwrkey {
status = "okay";
};
那么编译烧录uboot和kernel,通过串口可以获取到:

尝试一下另外一个语法的修改也都是能正常获取:

注意:
vccsys-shutdown-in-poweroff-mode = \<1\>; // 1表示true
vccsys-shutdown-in-poweroff-mode = \<0\>; // 0也表示true,val获取回来的值就是为1

但如果dts移除相关属性,则获取回来的是为0:


补充一下RK817的寄存器操作:
先写
echo w 0xe6 0x42 > sys/rk8xx/rk8xx_dbg
再读
echo r 0xe6 > sys/rk8xx/rk8xx_dbg
读出来的值bit7为0后,再走关机流程看关机电流。