-/* $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 <kettenis@openbsd.org>
*
#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
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);
}
void axppmic_attach_common(struct axppmic_softc *, const char *, int);
+int axppmic_activate(struct device *, int);
/* I2C interface */
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 = {
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 = {
device = axppmic_lookup(name);
printf(": %s\n", device->chip);
+ sc->sc_name = device->name;
sc->sc_regdata = device->regdata;
sc->sc_sensdata = device->sensdata;
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) {
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 {