diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2020-04-29 15:52:26 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2020-04-29 15:52:26 +0000 |
commit | 974f2fb59c28dd7c1b50054155d0d886ea478566 (patch) | |
tree | aa13166321e09d9c28824ee121176fb3a34c3b96 /sys/dev | |
parent | ddc3cd53483be54f3368ebc0664066fc2304332d (diff) |
Configure abcrtc(4)'s trickle charger. This uses information
from the device tree to configures the RTC to be able to charge
a connected battery or capacitor.
ok kettenis@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/i2c/abx80x.c | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/sys/dev/i2c/abx80x.c b/sys/dev/i2c/abx80x.c index 077ae7518ca..ad143b7176c 100644 --- a/sys/dev/i2c/abx80x.c +++ b/sys/dev/i2c/abx80x.c @@ -1,4 +1,4 @@ -/* $OpenBSD: abx80x.c,v 1.2 2020/04/29 15:50:48 patrick Exp $ */ +/* $OpenBSD: abx80x.c,v 1.3 2020/04/29 15:52:25 patrick Exp $ */ /* * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org> * Copyright (c) 2018 Patrick Wildt <patrick@blueri.se> @@ -24,6 +24,10 @@ #include <dev/clock_subr.h> +#if defined(__HAVE_FDT) +#include <dev/ofw/openfirm.h> +#endif + extern todr_chip_handle_t todr_handle; #define ABX8XX_HTH 0x00 @@ -43,6 +47,16 @@ extern todr_chip_handle_t todr_handle; #define ABX8XX_OSS 0x1d #define ABX8XX_OSS_OF (1 << 1) #define ABX8XX_OSS_OMODE (1 << 4) +#define ABX8XX_CFG_KEY 0x1f +#define ABX8XX_CFG_KEY_OSC 0xa1 +#define ABX8XX_CFG_KEY_MISC 0x9d +#define ABX8XX_TRICKLE 0x20 +#define ABX8XX_TRICKLE_RESISTOR_0 (0 << 0) +#define ABX8XX_TRICKLE_RESISTOR_3 (1 << 0) +#define ABX8XX_TRICKLE_RESISTOR_6 (2 << 0) +#define ABX8XX_TRICKLE_RESISTOR_11 (3 << 0) +#define ABX8XX_TRICKLE_DIODE_SCHOTTKY (1 << 2) +#define ABX8XX_TRICKLE_DIODE_STANDARD (1 << 3) #define ABX8XX_NRTC_REGS 8 @@ -72,6 +86,10 @@ int abcrtc_clock_write(struct abcrtc_softc *, struct clock_ymdhms *); int abcrtc_gettime(struct todr_chip_handle *, struct timeval *); int abcrtc_settime(struct todr_chip_handle *, struct timeval *); +#if defined(__HAVE_FDT) +void abcrtc_trickle_charger(struct abcrtc_softc *, int); +#endif + int abcrtc_match(struct device *parent, void *match, void *aux) { @@ -89,10 +107,17 @@ abcrtc_attach(struct device *parent, struct device *self, void *aux) struct abcrtc_softc *sc = (struct abcrtc_softc *)self; struct i2c_attach_args *ia = aux; uint8_t reg; +#if defined(__HAVE_FDT) + int node = *(int *)ia->ia_cookie; +#endif sc->sc_tag = ia->ia_tag; sc->sc_addr = ia->ia_addr; +#if defined(__HAVE_FDT) + abcrtc_trickle_charger(sc, node); +#endif + reg = abcrtc_reg_read(sc, ABX8XX_CTRL); reg &= ~(ABX8XX_CTRL_ARST | ABX8XX_CTRL_12_24); reg |= ABX8XX_CTRL_WRITE; @@ -258,3 +283,40 @@ abcrtc_clock_write(struct abcrtc_softc *sc, struct clock_ymdhms *dt) return 0; } + +#if defined(__HAVE_FDT) +void +abcrtc_trickle_charger(struct abcrtc_softc *sc, int node) +{ + char diode[16] = { 0 }; + uint8_t reg = 0; + + OF_getprop(node, "abracon,tc-diode", diode, sizeof(diode)); + if (!strcmp(diode, "standard")) + reg |= ABX8XX_TRICKLE_DIODE_STANDARD; + else if (!strcmp(diode, "schottky")) + reg |= ABX8XX_TRICKLE_DIODE_SCHOTTKY; + else + return; + + switch (OF_getpropint(node, "abracon,tc-resistor", -1)) { + case 0: + reg |= ABX8XX_TRICKLE_RESISTOR_0; + break; + case 3: + reg |= ABX8XX_TRICKLE_RESISTOR_3; + break; + case 6: + reg |= ABX8XX_TRICKLE_RESISTOR_6; + break; + case 11: + reg |= ABX8XX_TRICKLE_RESISTOR_11; + break; + default: + return; + } + + abcrtc_reg_write(sc, ABX8XX_CFG_KEY, ABX8XX_CFG_KEY_MISC); + abcrtc_reg_write(sc, ABX8XX_TRICKLE, reg); +} +#endif |