diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-12-03 09:12:47 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-12-03 09:12:47 +0000 |
commit | 836f76b760c83baef9c6aaf7b81d83c9829f89bf (patch) | |
tree | d97e96448f3ef7fe5e07a99e62d5798ac84f45a2 | |
parent | 5660433c213e6c408fe8042fae733d1d4a5e8fae (diff) |
Add pwmfan(4), a driver for PWM-regulated fans.
ok kurt@
-rw-r--r-- | sys/arch/arm64/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/arch/arm64/conf/RAMDISK | 3 | ||||
-rw-r--r-- | sys/dev/fdt/files.fdt | 6 | ||||
-rw-r--r-- | sys/dev/fdt/pwmfan.c | 131 |
4 files changed, 140 insertions, 3 deletions
diff --git a/sys/arch/arm64/conf/GENERIC b/sys/arch/arm64/conf/GENERIC index 7da538d4a52..42af8a132a0 100644 --- a/sys/arch/arm64/conf/GENERIC +++ b/sys/arch/arm64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.134 2019/12/03 09:08:48 patrick Exp $ +# $OpenBSD: GENERIC,v 1.135 2019/12/03 09:12:46 patrick Exp $ # # GENERIC machine description file # @@ -90,6 +90,7 @@ pluart* at fdt? psci* at fdt? early 1 pwmreg* at fdt? early 1 syscon* at fdt? early 1 +pwmfan* at fdt? virtio* at fdt? virtio* at pci? diff --git a/sys/arch/arm64/conf/RAMDISK b/sys/arch/arm64/conf/RAMDISK index 44179edfc92..64ec77e05e4 100644 --- a/sys/arch/arm64/conf/RAMDISK +++ b/sys/arch/arm64/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.108 2019/12/03 09:08:48 patrick Exp $ +# $OpenBSD: RAMDISK,v 1.109 2019/12/03 09:12:46 patrick Exp $ # # GENERIC machine description file # @@ -96,6 +96,7 @@ plrtc* at fdt? pluart* at fdt? psci* at fdt? early 1 syscon* at fdt? early 1 +pwmfan* at fdt? virtio* at fdt? virtio* at pci? diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt index 6d36d9be722..af43cce1e9b 100644 --- a/sys/dev/fdt/files.fdt +++ b/sys/dev/fdt/files.fdt @@ -1,4 +1,4 @@ -# $OpenBSD: files.fdt,v 1.105 2019/12/03 09:08:48 patrick Exp $ +# $OpenBSD: files.fdt,v 1.106 2019/12/03 09:12:45 patrick Exp $ # # Config file and device description for machine-independent FDT code. # Included by ports that need it. @@ -144,6 +144,10 @@ device pwmbl attach pwmbl at fdt file dev/fdt/pwmbl.c pwmbl +device pwmfan +attach pwmfan at fdt +file dev/fdt/pwmfan.c pwmfan + device pwmreg attach pwmreg at fdt file dev/fdt/pwmreg.c pwmreg diff --git a/sys/dev/fdt/pwmfan.c b/sys/dev/fdt/pwmfan.c new file mode 100644 index 00000000000..261d6752bb3 --- /dev/null +++ b/sys/dev/fdt/pwmfan.c @@ -0,0 +1,131 @@ +/* $OpenBSD: pwmfan.c,v 1.1 2019/12/03 09:12:45 patrick Exp $ */ +/* + * Copyright (c) 2019 Krystian Lewandowski + * Copyright (c) 2019 Mark Kettenis <kettenis@openbsd.org> + * Copyright (c) 2019 Patrick Wildt <patrick@blueri.se> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/malloc.h> + +#include <machine/fdt.h> +#include <machine/bus.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_gpio.h> +#include <dev/ofw/ofw_misc.h> +#include <dev/ofw/ofw_thermal.h> + +struct pwmfan_softc { + struct device sc_dev; + uint32_t *sc_pwm; + int sc_pwm_len; + uint32_t *sc_levels; + int sc_nlevels; + int sc_curlevel; + + struct cooling_device sc_cd; +}; + +int pwmfan_match(struct device *, void *, void *); +void pwmfan_attach(struct device *, struct device *, void *); + +struct cfattach pwmfan_ca = { + sizeof(struct pwmfan_softc), pwmfan_match, pwmfan_attach +}; + +struct cfdriver pwmfan_cd = { + NULL, "pwmfan", DV_DULL +}; + +uint32_t pwmfan_get_cooling_level(void *, uint32_t *); +void pwmfan_set_cooling_level(void *, uint32_t *, uint32_t); + +int +pwmfan_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return OF_is_compatible(faa->fa_node, "pwm-fan"); +} + +void +pwmfan_attach(struct device *parent, struct device *self, void *aux) +{ + struct pwmfan_softc *sc = (struct pwmfan_softc *)self; + struct fdt_attach_args *faa = aux; + int len; + + len = OF_getproplen(faa->fa_node, "pwms"); + if (len < 0) { + printf(": no pwm\n"); + return; + } + + sc->sc_pwm = malloc(len, M_DEVBUF, M_WAITOK); + OF_getpropintarray(faa->fa_node, "pwms", sc->sc_pwm, len); + sc->sc_pwm_len = len; + + len = OF_getproplen(faa->fa_node, "cooling-levels"); + if (len < 0) { + free(sc->sc_pwm, M_DEVBUF, sc->sc_pwm_len); + printf(": no cooling levels\n"); + return; + } + + sc->sc_levels = malloc(len, M_DEVBUF, M_WAITOK); + OF_getpropintarray(faa->fa_node, "cooling-levels", + sc->sc_levels, len); + sc->sc_nlevels = len / sizeof(uint32_t); + + printf("\n"); + + sc->sc_cd.cd_node = faa->fa_node; + sc->sc_cd.cd_cookie = sc; + sc->sc_cd.cd_get_level = pwmfan_get_cooling_level; + sc->sc_cd.cd_set_level = pwmfan_set_cooling_level; + cooling_device_register(&sc->sc_cd); +} + +uint32_t +pwmfan_get_cooling_level(void *cookie, uint32_t *cells) +{ + struct pwmfan_softc *sc = cookie; + + return sc->sc_curlevel; +} + +void +pwmfan_set_cooling_level(void *cookie, uint32_t *cells, uint32_t level) +{ + struct pwmfan_softc *sc = cookie; + struct pwm_state ps; + + if (level == sc->sc_curlevel || level > sc->sc_nlevels || + sc->sc_levels[level] > 255) + return; + + if (pwm_init_state(sc->sc_pwm, &ps)) + return; + + sc->sc_curlevel = level; + level = sc->sc_levels[level]; + + ps.ps_enabled = level ? 1 : 0; + ps.ps_pulse_width = (ps.ps_period * level) / 255; + pwm_set_state(sc->sc_pwm, &ps); +} |