From 00d11ef213f1c3a1d3496098a6e200c68e485c64 Mon Sep 17 00:00:00 2001 From: Shunqing Chen Date: Wed, 25 Nov 2020 08:26:44 +0000 Subject: [PATCH] pmic: rk8xx: support power key config from dts Signed-off-by: Shunqing Chen Change-Id: I4b2def4e5b171b2b46f26695e9cabec8a7b496e2 --- drivers/power/pmic/rk8xx.c | 40 +++++++++++++++++++++++++++++++++++++- include/power/rk8xx_pmic.h | 13 +++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c index a0a2e80aed..ca952ea1a0 100644 --- a/drivers/power/pmic/rk8xx.c +++ b/drivers/power/pmic/rk8xx.c @@ -333,7 +333,7 @@ static void rk8xx_plug_out_handler(int irq, void *data) static int rk8xx_ofdata_to_platdata(struct udevice *dev) { struct rk8xx_priv *rk8xx = dev_get_priv(dev); - u32 interrupt, phandle; + u32 interrupt, phandle, val; int ret; phandle = dev_read_u32_default(dev, "interrupt-parent", -ENODATA); @@ -354,6 +354,22 @@ static int rk8xx_ofdata_to_platdata(struct udevice *dev) return rk8xx->irq; } + val = dev_read_u32_default(dev, "long-press-off-time-sec", 0); + if (val <= 6) + rk8xx->lp_off_time = RK8XX_LP_TIME_6S; + else if (val <= 8) + rk8xx->lp_off_time = RK8XX_LP_TIME_8S; + else if (val <= 10) + rk8xx->lp_off_time = RK8XX_LP_TIME_10S; + else + rk8xx->lp_off_time = RK8XX_LP_TIME_12S; + + val = dev_read_u32_default(dev, "long-press-restart", 0); + if (val) + rk8xx->lp_action = RK8XX_LP_RESTART; + else + rk8xx->lp_action = RK8XX_LP_OFF; + return 0; } @@ -424,6 +440,7 @@ static int rk8xx_probe(struct udevice *dev) int ret = 0, i, show_variant; uint8_t msb, lsb, id_msb, id_lsb; uint8_t on_source = 0, off_source = 0; + uint8_t pwron_key = 0, lp_off_msk = 0, lp_act_msk = 0; uint8_t power_en0, power_en1, power_en2, power_en3; uint8_t value; @@ -449,15 +466,23 @@ static int rk8xx_probe(struct udevice *dev) switch (priv->variant) { case RK808_ID: show_variant = 0x808; /* RK808 hardware ID is 0 */ + pwron_key = RK8XX_DEVCTRL_REG; + lp_off_msk = RK8XX_LP_OFF_MSK; break; case RK805_ID: case RK816_ID: on_source = RK8XX_ON_SOURCE; off_source = RK8XX_OFF_SOURCE; + pwron_key = RK8XX_DEVCTRL_REG; + lp_off_msk = RK8XX_LP_OFF_MSK; + lp_act_msk = RK8XX_LP_ACTION_MSK; break; case RK818_ID: on_source = RK8XX_ON_SOURCE; off_source = RK8XX_OFF_SOURCE; + pwron_key = RK8XX_DEVCTRL_REG; + lp_off_msk = RK8XX_LP_OFF_MSK; + lp_act_msk = RK8XX_LP_ACTION_MSK; /* set current if no fuel gauge */ if (!ofnode_valid(dev_read_subnode(dev, "battery"))) { init_current = rk818_init_current; @@ -468,6 +493,9 @@ static int rk8xx_probe(struct udevice *dev) case RK817_ID: on_source = RK817_ON_SOURCE; off_source = RK817_OFF_SOURCE; + pwron_key = RK817_PWRON_KEY; + lp_off_msk = RK8XX_LP_OFF_MSK; + lp_act_msk = RK8XX_LP_ACTION_MSK; init_data = rk817_init_reg; init_data_num = ARRAY_SIZE(rk817_init_reg); power_en0 = pmic_reg_read(dev, RK817_POWER_EN0); @@ -517,6 +545,16 @@ static int rk8xx_probe(struct udevice *dev) pmic_reg_read(dev, off_source)); printf("\n"); + if (pwron_key) { + value = pmic_reg_read(dev, pwron_key); + value &= ~(lp_off_msk | lp_act_msk); + if (lp_off_msk) + value |= priv->lp_off_time; + if (lp_act_msk) + value |= priv->lp_action; + pmic_reg_write(dev, pwron_key, value); + } + ret = rk8xx_irq_chip_init(dev); if (ret) { printf("IRQ chip initial failed\n"); diff --git a/include/power/rk8xx_pmic.h b/include/power/rk8xx_pmic.h index 4031456553..5f3bb30a37 100644 --- a/include/power/rk8xx_pmic.h +++ b/include/power/rk8xx_pmic.h @@ -216,6 +216,17 @@ enum { #define RK817_OFF_SOURCE 0xf6 #define RK817_NUM_OF_REGS 0xff +#define RK8XX_DEVCTRL_REG 0x4b +#define RK817_PWRON_KEY 0xf7 +#define RK8XX_LP_ACTION_MSK BIT(6) +#define RK8XX_LP_OFF (0 << 6) +#define RK8XX_LP_RESTART (1 << 6) +#define RK8XX_LP_OFF_MSK BIT(4) | BIT(5) +#define RK8XX_LP_TIME_6S (0 << 4) +#define RK8XX_LP_TIME_8S (1 << 4) +#define RK8XX_LP_TIME_10S (2 << 4) +#define RK8XX_LP_TIME_12S (3 << 4) + /* IRQ definitions */ #define RK8XX_IRQ_PWRON_FALL 0 #define RK8XX_IRQ_PWRON_RISE 1 @@ -269,6 +280,8 @@ struct rk8xx_priv { int variant; int irq; struct virq_chip *irq_chip; + int lp_off_time; + int lp_action; }; int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt);