电池 PMU
带电池开机的RK817的PMU
电路是怎样的?
怎样去修改不带电池开机的RK817的PMU电路?
回帖(1)
2022-3-2 16:12:17
1、硬件设计的原理
带电池开机的RK817的PMU电路图:
不带电池的开机的RK817的PMU电路图:
从RK817芯片手册得知道:
其中系统启动后可以使用以下命令查看系统配置:
echo r 0xde > /sys/rk8xx/rk8xx_dbg
使用以下命令查看RK817的充电状态:
echo r 0xe4 > /sys/rk8xx/rk8xx_dbg
echo r 0xe5 > /sys/rk8xx/rk8xx_dbg
echo r 0xe6 > /sys/rk8xx/rk8xx_dbg
所以从以上得知,当板子硬件设计不带电池的时候,需要修改RK817 IC的输入充电电流的限制。正常带电池启动时,RK817的充电电流限制在450mA。
而不带电池启动时,RK817的充电电流需要放开限制,调整到最大3A,同时需要修改u-boot和内核对不带电池不启动系统的限制。
2、u-boot对不带电池限制启动的修改
u-bootdriverspowercharge_animation.c
static int charge_animation_show(struct udevice *dev)
{
..............................
if (!fuel_gauge_bat_is_exist(fg)) { //这里将检查电池是否存在
printf("Exit charge: battery is not existn");
return 0;
}
/* Extrem low power charge */
ret = charge_extrem_low_power(dev);
if (ret < 0) {
printf("extrem low power charge failed, ret=%dn", ret);
return ret;
}
............................
}
------------>
方法一:
u-boot/drivers/power/fuel_gauge/fuel_gauge_uclass.c
int fuel_gauge_bat_is_exist(struct udevice *dev)
{
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
if (!ops || !ops->bat_is_exist){ //bat is no exit ,so return 0
printf("bat is no exist,return 0n");
//return -ENOSYS; //修改这里直接返回0,因为ops->bat_is_exist时,因为fg_rk817.c中的接口为空,所以这里会正常进入
return 0;
}
printf("ops->bat_is_exist,call rk817_bat_bat_is_exist()n");
return ops->bat_is_exist(dev);
}
方法二:
修改:u-bootdriverspowerfuel_gaugefg_rk816.c
添加bat_is_exist()接口函数,如下:
@@ -132,6 +132,7 @@ static int dbg_enable = 0;
#define CUR_ADC_K2 0x00ae
#define CUR_ADC_K1 0x00af
#define CUR_ADC_K0 0x00b0
+#define PMIC_CHRG_STS 0x00eb
#define BAT_DISCHRG 0x00ec
#define BAT_CON BIT(4)
@@ -1217,7 +1218,26 @@ static int rk817_bat_update_get_soc(struct udevice *dev)
return VIRTUAL_POWER_SOC;
}
+static int rk817_is_bat_exist(struct rk817_battery_device *battery)
+{
+ struct rk8xx_priv *rk8xx = dev_get_priv(battery->dev->parent);
+
+ if (rk8xx->variant == RK817_ID)
+ return (rk817_bat_read(battery, PMIC_CHRG_STS) & 0x80) ? 1 : 0;
+
+ return 1;
+}
+
+static int rk817_bat_bat_is_exit(struct udevice *dev)
+{
+ struct rk817_battery_device *battery = dev_get_priv(dev);
+
+ return rk817_is_bat_exist(battery);
+}
+
+
static struct dm_fuel_gauge_ops fg_ops = {
+ .bat_is_exist = rk817_bat_bat_is_exit,
.get_soc = rk817_bat_update_get_soc,
.get_voltage = rk817_bat_update_get_voltage,
.get_current = rk817_bat_update_get_current,
@@ -1274,6 +1294,10 @@ static int rk817_fg_ofdata_to_platdata(struct udevice *dev)
return -EINVAL;
}
+ battery->virtual_power = dev_read_u32_default(dev, "virtual_power", 0);
+ if (!rk817_is_bat_exist(battery))
+ battery->virtual_power = 1;
+
if (rk8xx->variant == RK809_ID) {
battery->bat_res_up = dev_read_u32_default(dev, "bat_res_up", -1);
if (battery->bat_res_up < 0) {
--
3、内核修改不带电池不允许启动
kernelarcharm64bootdtsrockchiprk3566-rk817-tablet.dts
battery {
compatible = "rk817,battery";
ocv_table = <3400 3513 3578 3687 3734 3752 3763
3766 3771 3784 3804 3836 3885 3925
3962 4005 4063 4114 4169 4227 4303>;
design_capacity = <5000>;
design_qmax = <5500>;
bat_res = <100>;
sleep_enter_current = <150>;
sleep_exit_current = <180>;
sleep_filter_current = <100>;
power_off_thresd = <3350>;
zero_algorithm_vol = <3850>;
max_soc_offset = <60>;
monitor_sec = <5>;
sample_res = <10>;
//virtual_power = <0>;
virtual_power = <1>; //bat_is_noexist
};
charger {
compatible = "rk817,charger";
min_input_voltage = <4500>;
max_input_current = <1500>;
max_chrg_current = <2000>;
max_chrg_voltage = <4300>;
chrg_term_mode = <0>;
chrg_finish_cur = <300>;
virtual_power = <0>;//1
dc_det_adc = <0>;
extcon = <&u***2phy0>;
};
其中各个参数请参考代码中的/RKDocs/common/PMIC/Rockchip_Developer_Guide_RK817_RK809_Fuel_Gauge_CN&EN.pdf
【virtual_power 】
测试模式。设置该值为 1,无论有没有接充电器都会上报正在充电状态。
其中只需要将batter选项中的virtual_power 设置成1即可,而charge中的virtual_power不需要设置成1
4、修改RK817充电输入电流的限制
需要将系统默认的输入电流限制从450mA修改成最大3A,这个主要解决USB线链接电脑插入拨出时系统重启的问题
4.1 u-boot部分将RK817输入充电电流从450mA修改成3A
u-bootdriverspowerfuel_gaugefg_rk817.c
//主要修改充电电流输入的限制,如下:
static void rk817_bat_charger_setting(struct rk817_battery_device *battery,
int charger)
{
static u8 old_charger = UNDEF_CHARGER;
rk817_bat_set_input_voltage(battery, VLIM_4500MV);
/* charger changed */
if (old_charger != charger) {
if (charger == NO_CHARGER) {//不充电的情况,即USB线拨出的情况
DBG("NO_CHARGERn");
//rk817_bat_set_input_current(battery, ILIM_450MA);
rk817_bat_set_input_current(battery, ILIM_3000MA); //从450mA修改到最大3A
} else if (charger == USB_CHARGER) { //充电情况,即插入USB线链接电脑情况
DBG("USB_CHARGERn");
//rk817_bat_set_input_current(battery, ILIM_450MA);
//rk817_bat_set_input_current(battery, ILIM_1500MA);
rk817_bat_set_input_current(battery, ILIM_3000MA);//从1500mA修改到最大3A
DBG("USB_CHARGER charger setting ILIM_3000MAn");
} else if (charger == DC_CHARGER || charger == AC_CHARGER) { //充电情况
DBG("DC OR AC CHARGEn");
//rk817_bat_set_input_current(battery, ILIM_1500MA);
rk817_bat_set_input_current(battery, ILIM_3000MA); //从1500mA修改到最大3A
DBG("DC OR AC CHARGE charger setting ILIM_3000MAn");
} else {
DBG("charger setting error %dn", charger);
}
old_charger = charger;
}
}
4.2 内核部分将RK817输入充电电流从450mA修改成3A
kerneldriverspowersupplyrk817_charger.c
//主要修改RK817在USB线在插入和拨出时,RK817的输入充电电流的限制
static void rk817_charge_set_chrg_param(struct rk817_charger *charge,
enum charger_t charger)
{
switch (charger) {
case USB_TYPE_NONE_CHARGER: //链接到电脑上的USB拨出时,RK817输入的充电电流从450mA修改到3A
charge->u***_in = 0;
charge->ac_in = 0;
if (charge->dc_in == 0) {
charge->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
//rk817_charge_set_input_current(charge, INPUT_450MA);
rk817_charge_set_input_current(charge, INPUT_3000MA);//不充电时的RK817输入充电电流
}
//rk817_charge_set_input_current(charge, INPUT_3000MA);
power_supply_changed(charge->u***_psy);
power_supply_changed(charge->ac_psy);
DBG("rk817_charge_set_chrg_param()::USB_TYPE_NONE_CHARGERn");
break;
case USB_TYPE_USB_CHARGER: //链接到电脑上的USB插入时,RK817输入的充电电流从450mA修改到3A
charge->u***_in = 1;
charge->ac_in = 0;
charge->prop_status = POWER_SUPPLY_STATUS_CHARGING;
if (charge->dc_in == 0)
//rk817_charge_set_input_current(charge, INPUT_450MA);
rk817_charge_set_input_current(charge, INPUT_3000MA);//充电时的RK817输入充电电流
power_supply_changed(charge->u***_psy);
power_supply_changed(charge->ac_psy);
DBG("rk817_charge_set_chrg_param()::USB_TYPE_USB_CHARGERn");
break;
case USB_TYPE_AC_CHARGER:
case USB_TYPE_CDP_CHARGER://链接到电脑上的USB插入或者AC电源插入时,RK817输入的充电电流从450mA修改到3A
charge->ac_in = 1;
charge->u***_in = 0;
charge->prop_status = POWER_SUPPLY_STATUS_CHARGING;
if (charger == USB_TYPE_AC_CHARGER)
//rk817_charge_set_input_current(charge,
// charge->max_input_current);
rk817_charge_set_input_current(charge,
INPUT_3000MA);//充电时的RK817输入充电电流
else
//rk817_charge_set_input_current(charge,
// INPUT_1500MA);
rk817_charge_set_input_current(charge,
INPUT_3000MA);//充电时的RK817输入充电电流
power_supply_changed(charge->u***_psy);
power_supply_changed(charge->ac_psy);
DBG("rk817_charge_set_chrg_param()::USB_TYPE_AC-DC_CHARGERn");
break;
case DC_TYPE_DC_CHARGER:
charge->dc_in = 1;
charge->prop_status = POWER_SUPPLY_STATUS_CHARGING;
//rk817_charge_set_input_current(charge,
// charge->max_input_current);
rk817_charge_set_input_current(charge, INPUT_3000MA);//充电时的RK817输入充电电流
power_supply_changed(charge->u***_psy);
power_supply_changed(charge->ac_psy);
DBG("rk817_charge_set_chrg_param()::DC_TYPE_DC_CHARGERn");
break;
case DC_TYPE_NONE_CHARGER:
charge->dc_in = 0;
if (!rk817_charge_get_plug_in_status(charge)) {
charge->ac_in = 0;
charge->u***_in = 0;
charge->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
//rk817_charge_set_input_current(charge, INPUT_450MA);
rk817_charge_set_input_current(charge, INPUT_3000MA);//不充电时的RK817输入充电电流
} else if (charge->u***_in) {
//rk817_charge_set_input_current(charge, INPUT_450MA);
rk817_charge_set_input_current(charge, INPUT_3000MA);//不充电时的RK817输入充电电流
charge->prop_status = POWER_SUPPLY_STATUS_CHARGING;
}
power_supply_changed(charge->u***_psy);
power_supply_changed(charge->ac_psy);
DBG("rk817_charge_set_chrg_param()::DC_TYPE_NONE_CHARGERn");
break;
default:
charge->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
//rk817_charge_set_input_current(charge, INPUT_450MA);
rk817_charge_set_input_current(charge, INPUT_3000MA);//不充电时的RK817输入充电电流
DBG("rk817_charge_set_chrg_param()::defaultn");
break;
}
if (rk817_charge_online(charge) && rk817_charge_get_dsoc(charge) == 100)
charge->prop_status = POWER_SUPPLY_STATUS_FULL;
}
修改完成后经过测试系统正常启动,USB口的adb和host都正常。
1、硬件设计的原理
带电池开机的RK817的PMU电路图:
不带电池的开机的RK817的PMU电路图:
从RK817芯片手册得知道:
其中系统启动后可以使用以下命令查看系统配置:
echo r 0xde > /sys/rk8xx/rk8xx_dbg
使用以下命令查看RK817的充电状态:
echo r 0xe4 > /sys/rk8xx/rk8xx_dbg
echo r 0xe5 > /sys/rk8xx/rk8xx_dbg
echo r 0xe6 > /sys/rk8xx/rk8xx_dbg
所以从以上得知,当板子硬件设计不带电池的时候,需要修改RK817 IC的输入充电电流的限制。正常带电池启动时,RK817的充电电流限制在450mA。
而不带电池启动时,RK817的充电电流需要放开限制,调整到最大3A,同时需要修改u-boot和内核对不带电池不启动系统的限制。
2、u-boot对不带电池限制启动的修改
u-bootdriverspowercharge_animation.c
static int charge_animation_show(struct udevice *dev)
{
..............................
if (!fuel_gauge_bat_is_exist(fg)) { //这里将检查电池是否存在
printf("Exit charge: battery is not existn");
return 0;
}
/* Extrem low power charge */
ret = charge_extrem_low_power(dev);
if (ret < 0) {
printf("extrem low power charge failed, ret=%dn", ret);
return ret;
}
............................
}
------------>
方法一:
u-boot/drivers/power/fuel_gauge/fuel_gauge_uclass.c
int fuel_gauge_bat_is_exist(struct udevice *dev)
{
const struct dm_fuel_gauge_ops *ops = dev_get_driver_ops(dev);
if (!ops || !ops->bat_is_exist){ //bat is no exit ,so return 0
printf("bat is no exist,return 0n");
//return -ENOSYS; //修改这里直接返回0,因为ops->bat_is_exist时,因为fg_rk817.c中的接口为空,所以这里会正常进入
return 0;
}
printf("ops->bat_is_exist,call rk817_bat_bat_is_exist()n");
return ops->bat_is_exist(dev);
}
方法二:
修改:u-bootdriverspowerfuel_gaugefg_rk816.c
添加bat_is_exist()接口函数,如下:
@@ -132,6 +132,7 @@ static int dbg_enable = 0;
#define CUR_ADC_K2 0x00ae
#define CUR_ADC_K1 0x00af
#define CUR_ADC_K0 0x00b0
+#define PMIC_CHRG_STS 0x00eb
#define BAT_DISCHRG 0x00ec
#define BAT_CON BIT(4)
@@ -1217,7 +1218,26 @@ static int rk817_bat_update_get_soc(struct udevice *dev)
return VIRTUAL_POWER_SOC;
}
+static int rk817_is_bat_exist(struct rk817_battery_device *battery)
+{
+ struct rk8xx_priv *rk8xx = dev_get_priv(battery->dev->parent);
+
+ if (rk8xx->variant == RK817_ID)
+ return (rk817_bat_read(battery, PMIC_CHRG_STS) & 0x80) ? 1 : 0;
+
+ return 1;
+}
+
+static int rk817_bat_bat_is_exit(struct udevice *dev)
+{
+ struct rk817_battery_device *battery = dev_get_priv(dev);
+
+ return rk817_is_bat_exist(battery);
+}
+
+
static struct dm_fuel_gauge_ops fg_ops = {
+ .bat_is_exist = rk817_bat_bat_is_exit,
.get_soc = rk817_bat_update_get_soc,
.get_voltage = rk817_bat_update_get_voltage,
.get_current = rk817_bat_update_get_current,
@@ -1274,6 +1294,10 @@ static int rk817_fg_ofdata_to_platdata(struct udevice *dev)
return -EINVAL;
}
+ battery->virtual_power = dev_read_u32_default(dev, "virtual_power", 0);
+ if (!rk817_is_bat_exist(battery))
+ battery->virtual_power = 1;
+
if (rk8xx->variant == RK809_ID) {
battery->bat_res_up = dev_read_u32_default(dev, "bat_res_up", -1);
if (battery->bat_res_up < 0) {
--
3、内核修改不带电池不允许启动
kernelarcharm64bootdtsrockchiprk3566-rk817-tablet.dts
battery {
compatible = "rk817,battery";
ocv_table = <3400 3513 3578 3687 3734 3752 3763
3766 3771 3784 3804 3836 3885 3925
3962 4005 4063 4114 4169 4227 4303>;
design_capacity = <5000>;
design_qmax = <5500>;
bat_res = <100>;
sleep_enter_current = <150>;
sleep_exit_current = <180>;
sleep_filter_current = <100>;
power_off_thresd = <3350>;
zero_algorithm_vol = <3850>;
max_soc_offset = <60>;
monitor_sec = <5>;
sample_res = <10>;
//virtual_power = <0>;
virtual_power = <1>; //bat_is_noexist
};
charger {
compatible = "rk817,charger";
min_input_voltage = <4500>;
max_input_current = <1500>;
max_chrg_current = <2000>;
max_chrg_voltage = <4300>;
chrg_term_mode = <0>;
chrg_finish_cur = <300>;
virtual_power = <0>;//1
dc_det_adc = <0>;
extcon = <&u***2phy0>;
};
其中各个参数请参考代码中的/RKDocs/common/PMIC/Rockchip_Developer_Guide_RK817_RK809_Fuel_Gauge_CN&EN.pdf
【virtual_power 】
测试模式。设置该值为 1,无论有没有接充电器都会上报正在充电状态。
其中只需要将batter选项中的virtual_power 设置成1即可,而charge中的virtual_power不需要设置成1
4、修改RK817充电输入电流的限制
需要将系统默认的输入电流限制从450mA修改成最大3A,这个主要解决USB线链接电脑插入拨出时系统重启的问题
4.1 u-boot部分将RK817输入充电电流从450mA修改成3A
u-bootdriverspowerfuel_gaugefg_rk817.c
//主要修改充电电流输入的限制,如下:
static void rk817_bat_charger_setting(struct rk817_battery_device *battery,
int charger)
{
static u8 old_charger = UNDEF_CHARGER;
rk817_bat_set_input_voltage(battery, VLIM_4500MV);
/* charger changed */
if (old_charger != charger) {
if (charger == NO_CHARGER) {//不充电的情况,即USB线拨出的情况
DBG("NO_CHARGERn");
//rk817_bat_set_input_current(battery, ILIM_450MA);
rk817_bat_set_input_current(battery, ILIM_3000MA); //从450mA修改到最大3A
} else if (charger == USB_CHARGER) { //充电情况,即插入USB线链接电脑情况
DBG("USB_CHARGERn");
//rk817_bat_set_input_current(battery, ILIM_450MA);
//rk817_bat_set_input_current(battery, ILIM_1500MA);
rk817_bat_set_input_current(battery, ILIM_3000MA);//从1500mA修改到最大3A
DBG("USB_CHARGER charger setting ILIM_3000MAn");
} else if (charger == DC_CHARGER || charger == AC_CHARGER) { //充电情况
DBG("DC OR AC CHARGEn");
//rk817_bat_set_input_current(battery, ILIM_1500MA);
rk817_bat_set_input_current(battery, ILIM_3000MA); //从1500mA修改到最大3A
DBG("DC OR AC CHARGE charger setting ILIM_3000MAn");
} else {
DBG("charger setting error %dn", charger);
}
old_charger = charger;
}
}
4.2 内核部分将RK817输入充电电流从450mA修改成3A
kerneldriverspowersupplyrk817_charger.c
//主要修改RK817在USB线在插入和拨出时,RK817的输入充电电流的限制
static void rk817_charge_set_chrg_param(struct rk817_charger *charge,
enum charger_t charger)
{
switch (charger) {
case USB_TYPE_NONE_CHARGER: //链接到电脑上的USB拨出时,RK817输入的充电电流从450mA修改到3A
charge->u***_in = 0;
charge->ac_in = 0;
if (charge->dc_in == 0) {
charge->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
//rk817_charge_set_input_current(charge, INPUT_450MA);
rk817_charge_set_input_current(charge, INPUT_3000MA);//不充电时的RK817输入充电电流
}
//rk817_charge_set_input_current(charge, INPUT_3000MA);
power_supply_changed(charge->u***_psy);
power_supply_changed(charge->ac_psy);
DBG("rk817_charge_set_chrg_param()::USB_TYPE_NONE_CHARGERn");
break;
case USB_TYPE_USB_CHARGER: //链接到电脑上的USB插入时,RK817输入的充电电流从450mA修改到3A
charge->u***_in = 1;
charge->ac_in = 0;
charge->prop_status = POWER_SUPPLY_STATUS_CHARGING;
if (charge->dc_in == 0)
//rk817_charge_set_input_current(charge, INPUT_450MA);
rk817_charge_set_input_current(charge, INPUT_3000MA);//充电时的RK817输入充电电流
power_supply_changed(charge->u***_psy);
power_supply_changed(charge->ac_psy);
DBG("rk817_charge_set_chrg_param()::USB_TYPE_USB_CHARGERn");
break;
case USB_TYPE_AC_CHARGER:
case USB_TYPE_CDP_CHARGER://链接到电脑上的USB插入或者AC电源插入时,RK817输入的充电电流从450mA修改到3A
charge->ac_in = 1;
charge->u***_in = 0;
charge->prop_status = POWER_SUPPLY_STATUS_CHARGING;
if (charger == USB_TYPE_AC_CHARGER)
//rk817_charge_set_input_current(charge,
// charge->max_input_current);
rk817_charge_set_input_current(charge,
INPUT_3000MA);//充电时的RK817输入充电电流
else
//rk817_charge_set_input_current(charge,
// INPUT_1500MA);
rk817_charge_set_input_current(charge,
INPUT_3000MA);//充电时的RK817输入充电电流
power_supply_changed(charge->u***_psy);
power_supply_changed(charge->ac_psy);
DBG("rk817_charge_set_chrg_param()::USB_TYPE_AC-DC_CHARGERn");
break;
case DC_TYPE_DC_CHARGER:
charge->dc_in = 1;
charge->prop_status = POWER_SUPPLY_STATUS_CHARGING;
//rk817_charge_set_input_current(charge,
// charge->max_input_current);
rk817_charge_set_input_current(charge, INPUT_3000MA);//充电时的RK817输入充电电流
power_supply_changed(charge->u***_psy);
power_supply_changed(charge->ac_psy);
DBG("rk817_charge_set_chrg_param()::DC_TYPE_DC_CHARGERn");
break;
case DC_TYPE_NONE_CHARGER:
charge->dc_in = 0;
if (!rk817_charge_get_plug_in_status(charge)) {
charge->ac_in = 0;
charge->u***_in = 0;
charge->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
//rk817_charge_set_input_current(charge, INPUT_450MA);
rk817_charge_set_input_current(charge, INPUT_3000MA);//不充电时的RK817输入充电电流
} else if (charge->u***_in) {
//rk817_charge_set_input_current(charge, INPUT_450MA);
rk817_charge_set_input_current(charge, INPUT_3000MA);//不充电时的RK817输入充电电流
charge->prop_status = POWER_SUPPLY_STATUS_CHARGING;
}
power_supply_changed(charge->u***_psy);
power_supply_changed(charge->ac_psy);
DBG("rk817_charge_set_chrg_param()::DC_TYPE_NONE_CHARGERn");
break;
default:
charge->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
//rk817_charge_set_input_current(charge, INPUT_450MA);
rk817_charge_set_input_current(charge, INPUT_3000MA);//不充电时的RK817输入充电电流
DBG("rk817_charge_set_chrg_param()::defaultn");
break;
}
if (rk817_charge_online(charge) && rk817_charge_get_dsoc(charge) == 100)
charge->prop_status = POWER_SUPPLY_STATUS_FULL;
}
修改完成后经过测试系统正常启动,USB口的adb和host都正常。
举报
更多回帖