diff options
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/charge_animation.c | 37 | ||||
-rw-r--r-- | drivers/power/dvfs/dvfs-uclass.c | 3 | ||||
-rw-r--r-- | drivers/power/fuel_gauge/fg_rk817.c | 7 | ||||
-rw-r--r-- | drivers/power/pmic/rk8xx.c | 10 |
4 files changed, 42 insertions, 15 deletions
diff --git a/drivers/power/charge_animation.c b/drivers/power/charge_animation.c index 3a0e885689..b1a814e02b 100644 --- a/drivers/power/charge_animation.c +++ b/drivers/power/charge_animation.c @@ -35,7 +35,7 @@ DECLARE_GLOBAL_DATA_PTR; #define IMAGE_RESET_IDX -1 #define IMAGE_SOC_100_IDX(n) ((n) - 2) #define IMAGE_LOWPOWER_IDX(n) ((n) - 1) - +#define SYSTEM_SUSPEND_DELAY_MS 5000 #define FUEL_GAUGE_POLL_MS 1000 #define LED_CHARGING_NAME "battery_charging" @@ -59,7 +59,8 @@ struct charge_animation_priv { int image_num; int auto_wakeup_key_state; - ulong auto_screen_off_timeout; + ulong auto_screen_off_timeout; /* ms */ + ulong suspend_delay_timeout; /* ms */ }; /* @@ -170,7 +171,7 @@ static int check_key_press(struct udevice *dev) * period timer is useless. */ #ifndef CONFIG_IRQ -static int system_suspend_enter(struct charge_animation_pdata *pdata) +static int system_suspend_enter(struct udevice *dev) { return 0; } @@ -179,8 +180,23 @@ static void autowakeup_timer_init(struct udevice *dev, uint32_t seconds) {} static void autowakeup_timer_uninit(void) {} #else -static int system_suspend_enter(struct charge_animation_pdata *pdata) +static int system_suspend_enter(struct udevice *dev) { + struct charge_animation_pdata *pdata = dev_get_platdata(dev); + struct charge_animation_priv *priv = dev_get_priv(dev); + + /* + * When cpu is in wfi and we try to give a long key press event without + * key release, cpu would wakeup and enter wfi again immediately. So + * here is the problem: cpu can only wakeup when long key released. + * + * Actually, we want cpu can detect long key event without key release, + * so we give a suspend delay timeout for cpu to detect this. + */ + if (priv->suspend_delay_timeout && + get_timer(priv->suspend_delay_timeout) <= SYSTEM_SUSPEND_DELAY_MS) + return 0; + if (pdata->system_suspend && IS_ENABLED(CONFIG_ARM_SMCCC)) { printf("\nSystem suspend: "); putc('0'); @@ -209,8 +225,11 @@ static int system_suspend_enter(struct charge_animation_pdata *pdata) } else { printf("\nWfi\n"); wfi(); + putc('1'); } + priv->suspend_delay_timeout = get_timer(0); + /* * We must wait for key release event finish, otherwise * we may read key state too early. @@ -362,7 +381,7 @@ static int charge_extrem_low_power(struct udevice *dev) pdata->low_power_voltage, voltage); /* System suspend */ - system_suspend_enter(pdata); + system_suspend_enter(dev); /* Update voltage */ voltage = fuel_gauge_get_voltage(fg); @@ -629,8 +648,7 @@ show_images: priv->auto_screen_off_timeout = get_timer(0); } else { priv->auto_screen_off_timeout = 0; - - system_suspend_enter(pdata); + system_suspend_enter(dev); } mdelay(5); @@ -673,14 +691,19 @@ show_images: if (screen_on) { charge_show_bmp(NULL); /* Turn off screen */ screen_on = false; + priv->suspend_delay_timeout = get_timer(0); } else { screen_on = true; } + + printf("screen %s\n", screen_on ? "on" : "off"); } else if (key_state == KEY_PRESS_LONG_DOWN) { /* Set screen_on=true anyway when key long pressed */ if (!screen_on) screen_on = true; + printf("screen %s\n", screen_on ? "on" : "off"); + /* Is able to boot now ? */ if (soc < pdata->exit_charge_level) { printf("soc=%d%%, threshold soc=%d%%\n", diff --git a/drivers/power/dvfs/dvfs-uclass.c b/drivers/power/dvfs/dvfs-uclass.c index abd04dcb5e..64778aaa8e 100644 --- a/drivers/power/dvfs/dvfs-uclass.c +++ b/drivers/power/dvfs/dvfs-uclass.c @@ -34,7 +34,8 @@ int dvfs_init(bool apply) ret = uclass_get_device(UCLASS_DVFS, 0, &dev); if (ret) { - printf("DVFS: Get dvfs device failed, ret=%d\n", ret); + if (ret != -ENODEV) + printf("DVFS: Get dvfs device failed, ret=%d\n", ret); return ret; } diff --git a/drivers/power/fuel_gauge/fg_rk817.c b/drivers/power/fuel_gauge/fg_rk817.c index 57ff70e5ec..86eaf93772 100644 --- a/drivers/power/fuel_gauge/fg_rk817.c +++ b/drivers/power/fuel_gauge/fg_rk817.c @@ -406,9 +406,10 @@ static int rk817_bat_get_battery_voltage(struct rk817_battery_device *battery) val |= rk817_bat_read(battery, BAT_VOL_L) << 0; vol = battery->voltage_k * val / 1000 + battery->voltage_b; - vol_temp = (vol * battery->bat_res_up / battery->bat_res_down + vol); - vol = vol_temp; - + if (battery->variant == RK809_ID) { + vol_temp = (vol * battery->bat_res_up / battery->bat_res_down + vol); + vol = vol_temp; + } return vol; } diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c index 02ea363e1a..1e5f45bfc0 100644 --- a/drivers/power/pmic/rk8xx.c +++ b/drivers/power/pmic/rk8xx.c @@ -13,17 +13,21 @@ DECLARE_GLOBAL_DATA_PTR; +static struct reg_data rk817_init_reg[] = { +/* enable the under-voltage protection, + * the under-voltage protection will shutdown the LDO3 and reset the PMIC + */ + { RK817_BUCK4_CMIN, 0x60, 0x60}, /* * Only when system suspend while U-Boot charge needs this config support */ #ifdef CONFIG_DM_CHARGE_DISPLAY -static struct reg_data rk817_init_reg[] = { /* Set pmic_sleep as sleep function */ { RK817_PMIC_SYS_CFG3, 0x08, 0x18 }, /* Set pmic_int active low */ { RK817_GPIO_INT_CFG, 0x00, 0x02 }, -}; #endif +}; static const struct pmic_child_info pmic_children_info[] = { { .prefix = "DCDC", .driver = "rk8xx_buck"}, @@ -213,10 +217,8 @@ static int rk8xx_probe(struct udevice *dev) case RK817_ID: on_source = RK817_ON_SOURCE; off_source = RK817_OFF_SOURCE; -#ifdef CONFIG_DM_CHARGE_DISPLAY init_data = rk817_init_reg; init_data_num = ARRAY_SIZE(rk817_init_reg); -#endif power_en0 = pmic_reg_read(dev, RK817_POWER_EN0); power_en1 = pmic_reg_read(dev, RK817_POWER_EN1); power_en2 = pmic_reg_read(dev, RK817_POWER_EN2); |