summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/charge_animation.c37
-rw-r--r--drivers/power/dvfs/dvfs-uclass.c3
-rw-r--r--drivers/power/fuel_gauge/fg_rk817.c7
-rw-r--r--drivers/power/pmic/rk8xx.c10
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);