diff --git a/drivers/power/charge_animation.c b/drivers/power/charge_animation.c index 66b661158f..1735d97d18 100644 --- a/drivers/power/charge_animation.c +++ b/drivers/power/charge_animation.c @@ -90,6 +90,8 @@ static int charge_animation_ofdata_to_platdata(struct udevice *dev) pdata->android_charge = dev_read_u32_default(dev, "rockchip,android-charge-on", 0); + pdata->auto_exit_charge = + dev_read_u32_default(dev, "rockchip,uboot-exit-charge-auto", 0); pdata->exit_charge_level = dev_read_u32_default(dev, "rockchip,uboot-exit-charge-level", 0); pdata->exit_charge_voltage = @@ -114,6 +116,9 @@ static int charge_animation_ofdata_to_platdata(struct udevice *dev) if (pdata->screen_on_voltage > pdata->exit_charge_voltage) pdata->screen_on_voltage = pdata->exit_charge_voltage; + if (pdata->auto_exit_charge && !pdata->auto_wakeup_interval) + pdata->auto_wakeup_interval = 10; + debug("mode: uboot=%d, android=%d; exit: soc=%d%%, voltage=%dmv;\n" "lp_voltage=%d%%, screen_on=%dmv\n", pdata->uboot_charge, pdata->android_charge, @@ -435,6 +440,7 @@ static int charge_animation_show(struct udevice *dev) int i, charging = 1, ret; int boot_mode; int first_poll_fg = 1; + bool exit_charge = false; /* * Check sequence: @@ -474,9 +480,31 @@ static int charge_animation_show(struct udevice *dev) return 0; } #endif + charging = fg_charger_get_chrg_online(dev); + /* Not charger online and low power, shutdown */ + if (charging <= 0 && pdata->auto_exit_charge) { + soc = fuel_gauge_update_get_soc(fg); + voltage = fuel_gauge_get_voltage(fg); + if (soc < pdata->exit_charge_level) { + printf("soc(%d%%) < exit_charge_level(%d%%)\n", + soc, pdata->exit_charge_level); + exit_charge = true; + } + if (voltage < pdata->exit_charge_voltage) { + printf("voltage(%d) < exit_charge_voltage(%d)\n", + voltage, pdata->exit_charge_voltage); + exit_charge = true; + } + if (exit_charge) { + printf("Not charging and low power, Shutdown...\n"); + show_idx = IMAGE_LOWPOWER_IDX(image_num); + charge_show_bmp(image[show_idx].name); + mdelay(1000); + pmic_shutdown(pmic); + } + } /* Not charger online, exit */ - charging = fg_charger_get_chrg_online(dev); if (charging <= 0) { printf("Exit charge: due to charger offline\n"); return 0; @@ -584,6 +612,22 @@ static int charge_animation_show(struct udevice *dev) first_poll_fg = 0; local_irq_enable(); + if (pdata->auto_exit_charge) { + /* Is able to boot now ? */ + if (pdata->exit_charge_level && + soc >= pdata->exit_charge_level) { + printf("soc(%d%%) exit charge animation...\n", + soc); + break; + } + if (pdata->exit_charge_voltage && + voltage >= pdata->exit_charge_voltage) { + printf("vol(%d) exit charge animation...\n", + voltage); + break; + } + } + show_images: /* * Just for debug, otherwise there will be nothing output which diff --git a/include/power/charge_animation.h b/include/power/charge_animation.h index 9288718cf7..df68bc3eaa 100644 --- a/include/power/charge_animation.h +++ b/include/power/charge_animation.h @@ -11,6 +11,7 @@ struct charge_animation_pdata { int android_charge; /* android charge, 1: enable, 0: disable */ int uboot_charge; /* u-boot charge, 1: enable, 0: disable */ + int auto_exit_charge; /* energy enough auto exit uboot charging*/ int exit_charge_voltage;/* lowest voltage allowed to exit charging */ int exit_charge_level; /* lowest soc level allowed to exit charging */ int low_power_voltage; /* below this voltage, force system into charge mode anyway */