From 7a19eddcecb175e7e1c452973439d86e730a472e Mon Sep 17 00:00:00 2001 From: kettenis Date: Sat, 16 Jul 2022 11:26:13 +0000 Subject: [PATCH] Add support for using the power button to wake up from suspend. ok anton@ --- sys/dev/fdt/axppmic.c | 61 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/sys/dev/fdt/axppmic.c b/sys/dev/fdt/axppmic.c index ed9735090bb..9363038376a 100644 --- a/sys/dev/fdt/axppmic.c +++ b/sys/dev/fdt/axppmic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: axppmic.c,v 1.14 2022/06/28 23:43:12 naddy Exp $ */ +/* $OpenBSD: axppmic.c,v 1.15 2022/07/16 11:26:13 kettenis Exp $ */ /* * Copyright (c) 2017 Mark Kettenis * @@ -36,6 +36,20 @@ extern void (*powerdownfn)(void); #define AXP209_ADC_EN1_ACIN (3 << 4) #define AXP209_ADC_EN1_VBUS (3 << 2) +#define AXP803_IRQ1_EN 0x40 +#define AXP803_IRQ2_EN 0x41 +#define AXP803_IRQ3_EN 0x42 +#define AXP803_IRQ4_EN 0x43 +#define AXP803_IRQ5_EN 0x44 +#define AXP803_IRQ5_EN_PEK_SHORT (1 << 4) +#define AXP803_IRQ6_EN 0x45 +#define AXP803_IRQ1_STAT 0x48 +#define AXP803_IRQ2_STAT 0x49 +#define AXP803_IRQ3_STAT 0x4a +#define AXP803_IRQ4_STAT 0x4b +#define AXP803_IRQ5_STAT 0x4c +#define AXP803_IRQ5_STAT_PEK_SHORT (1 << 4) +#define AXP803_IRQ6_STAT 0x4d #define AXP803_BAT_CAP_WARN 0xe6 #define AXP803_BAT_CAP_WARN_LV1 0xf0 #define AXP803_BAT_CAP_WARN_LV1BASE 5 @@ -315,6 +329,7 @@ struct axppmic_softc { struct device sc_dev; void *sc_cookie; uint16_t sc_addr; + const char *sc_name; uint8_t (*sc_read)(struct axppmic_softc *, uint8_t); void (*sc_write)(struct axppmic_softc *, uint8_t, uint8_t); @@ -341,6 +356,7 @@ axppmic_write_reg(struct axppmic_softc *sc, uint8_t reg, uint8_t value) } void axppmic_attach_common(struct axppmic_softc *, const char *, int); +int axppmic_activate(struct device *, int); /* I2C interface */ @@ -348,7 +364,8 @@ int axppmic_i2c_match(struct device *, void *, void *); void axppmic_i2c_attach(struct device *, struct device *, void *); const struct cfattach axppmic_ca = { - sizeof(struct axppmic_softc), axppmic_i2c_match, axppmic_i2c_attach + sizeof(struct axppmic_softc), axppmic_i2c_match, axppmic_i2c_attach, + NULL, axppmic_activate }; struct cfdriver axppmic_cd = { @@ -424,7 +441,8 @@ int axppmic_rsb_match(struct device *, void *, void *); void axppmic_rsb_attach(struct device *, struct device *, void *); const struct cfattach axppmic_rsb_ca = { - sizeof(struct axppmic_softc), axppmic_rsb_match, axppmic_rsb_attach + sizeof(struct axppmic_softc), axppmic_rsb_match, axppmic_rsb_attach, + NULL, axppmic_activate }; struct cfdriver axppmic_rsb_cd = { @@ -488,6 +506,7 @@ axppmic_attach_common(struct axppmic_softc *sc, const char *name, int node) device = axppmic_lookup(name); printf(": %s\n", device->chip); + sc->sc_name = device->name; sc->sc_regdata = device->regdata; sc->sc_sensdata = device->sensdata; @@ -534,6 +553,16 @@ axppmic_attach_common(struct axppmic_softc *sc, const char *name, int node) if (sc->sc_sensdata) axppmic_attach_sensors(sc); + /* Disable all interrupts on AXP803. */ + if (strcmp(name, "x-powers,axp803") == 0) { + axppmic_write_reg(sc, AXP803_IRQ1_EN, 0); + axppmic_write_reg(sc, AXP803_IRQ2_EN, 0); + axppmic_write_reg(sc, AXP803_IRQ3_EN, 0); + axppmic_write_reg(sc, AXP803_IRQ4_EN, 0); + axppmic_write_reg(sc, AXP803_IRQ5_EN, 0); + axppmic_write_reg(sc, AXP803_IRQ6_EN, 0); + } + #ifdef __armv7__ if (strcmp(name, "x-powers,axp152") == 0 || strcmp(name, "x-powers,axp209") == 0) { @@ -556,6 +585,32 @@ axppmic_attach_node(struct axppmic_softc *sc, int node) sc->sc_sensdata = axp803_battery_sensdata; } +int +axppmic_activate(struct device *self, int act) +{ + struct axppmic_softc *sc = (struct axppmic_softc *)self; + + switch (act) { + case DVACT_SUSPEND: + if (strcmp(sc->sc_name, "x-powers,axp803") == 0) { + /* Enable interrupt for short power button press. */ + axppmic_write_reg(sc, AXP803_IRQ5_STAT, + AXP803_IRQ5_STAT_PEK_SHORT); + axppmic_write_reg(sc, AXP803_IRQ5_EN, + AXP803_IRQ5_EN_PEK_SHORT); + } + break; + case DVACT_RESUME: + if (strcmp(sc->sc_name, "x-powers,axp803") == 0) { + /* Disable interrupt for short power button press. */ + axppmic_write_reg(sc, AXP803_IRQ5_EN, 0); + } + break; + } + + return 0; +} + /* Regulators */ struct axppmic_regulator { -- 2.20.1