diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-12-31 13:06:50 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-12-31 13:06:50 +0000 |
commit | 8eda5d96920a8a82a75b71f6d4a1a7c01be2b367 (patch) | |
tree | 4b4ef36569243cfdc60825caa9fda0f9627db763 /sys/dev | |
parent | abe7f2dd3289f65b15fe446e9f1597c6259a98e9 (diff) |
Add pchtemp(4) a driver for the thermal sensor on recent Intel PCHs.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/files.pci | 7 | ||||
-rw-r--r-- | sys/dev/pci/pchtemp.c | 121 |
2 files changed, 127 insertions, 1 deletions
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index 0629f6bdb95..0614e568d71 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $OpenBSD: files.pci,v 1.321 2015/12/21 22:15:53 sf Exp $ +# $OpenBSD: files.pci,v 1.322 2015/12/31 13:06:49 kettenis Exp $ # $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $ # # Config file and device description for machine-independent PCI code. @@ -793,6 +793,11 @@ device itherm attach itherm at pci file dev/pci/itherm.c itherm +# Intel C610 temperature sensor +device pchtemp +attach pchtemp at pci +file dev/pci/pchtemp.c pchtemp + # AMD Geode CS5536 PCI-ISA bridge device glxpcib{}: isabus, gpiobus, i2cbus attach glxpcib at pci diff --git a/sys/dev/pci/pchtemp.c b/sys/dev/pci/pchtemp.c new file mode 100644 index 00000000000..7f51686f135 --- /dev/null +++ b/sys/dev/pci/pchtemp.c @@ -0,0 +1,121 @@ +/* $OpenBSD: pchtemp.c,v 1.1 2015/12/31 13:06:49 kettenis Exp $ */ +/* + * Copyright (c) 2015 Mark Kettenis + * + * 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. + */ + +/* + * Intel X99 and C610 PCH thermal sensor controller driver + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/sensors.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#define PCHTEMP_PCI_TBAR 0x10 + +#define PCHTEMP_TEMP 0x00 +#define PCHTEMP_TSEL 0x08 +#define PCHTEMP_TSEL_ETS 0x01 + +struct pchtemp_softc { + struct device sc_dev; + + bus_space_tag_t sc_memt; + bus_space_handle_t sc_memh; + bus_size_t sc_mems; + + struct ksensor sc_sensor; + struct ksensordev sc_sensordev; +}; + +int pchtemp_match(struct device *, void *, void *); +void pchtemp_attach(struct device *, struct device *, void *); +void pchtemp_refresh(void *); + +struct cfdriver pchtemp_cd = { + NULL, "pchtemp", DV_DULL +}; + +struct cfattach pchtemp_ca = { + sizeof(struct pchtemp_softc), pchtemp_match, pchtemp_attach +}; + +const struct pci_matchid pchtemp_devices[] = { + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C610_THERM } +}; + +int +pchtemp_match(struct device *parent, void *match, void *aux) +{ + return (pci_matchbyid(aux, pchtemp_devices, nitems(pchtemp_devices))); +} + +void +pchtemp_attach(struct device *parent, struct device *self, void *aux) +{ + struct pchtemp_softc *sc = (struct pchtemp_softc *)self; + struct pci_attach_args *pa = aux; + pcireg_t memtype; + uint8_t tsel; + + memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT; + if (pci_mapreg_map(pa, PCHTEMP_PCI_TBAR, memtype, 0, + &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems, 0)) { + printf(": can't map registers\n"); + return; + } + + tsel = bus_space_read_1(sc->sc_memt, sc->sc_memh, PCHTEMP_TSEL); + if ((tsel & PCHTEMP_TSEL_ETS) == 0) { + printf(": disabled\n"); + goto unmap; + } + + pchtemp_refresh(sc); + + strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, + sizeof(sc->sc_sensordev.xname)); + + sc->sc_sensor.type = SENSOR_TEMP; + sensor_attach(&sc->sc_sensordev, &sc->sc_sensor); + + if (sensor_task_register(sc, pchtemp_refresh, 5) == NULL) { + printf(": can't register update task\n"); + goto unmap; + } + + sensordev_install(&sc->sc_sensordev); + + printf("\n"); + return; + + unmap: + bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems); +} + +void +pchtemp_refresh(void *arg) +{ + struct pchtemp_softc *sc = arg; + uint16_t temp; + + temp = bus_space_read_2(sc->sc_memt, sc->sc_memh, PCHTEMP_TEMP); + sc->sc_sensor.value = (temp * 500000 - 50000000) + 273150000; +} |