diff options
author | hrs <hrs@FreeBSD.org> | 2012-08-18 12:37:07 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2012-08-18 12:37:07 +0000 |
commit | 9f4aa1a3fb9ba99ad0d702c3f6dcf2120e924f10 (patch) | |
tree | 7b5d3ae291b9478d4117aba5cd4a004ea0d4219d | |
parent | c4e0514c26dd114eadf7a57644c243ca381054c9 (diff) | |
download | FreeBSD-src-9f4aa1a3fb9ba99ad0d702c3f6dcf2120e924f10.zip FreeBSD-src-9f4aa1a3fb9ba99ad0d702c3f6dcf2120e924f10.tar.gz |
Add mvts(4) driver for internal thermal sensor found on 88F6282 and 88F6283.
The temperature value will be exported via sysctl like this:
dev.mvts.0.temperature: 52.1C
-rw-r--r-- | sys/arm/mv/files.mv | 1 | ||||
-rw-r--r-- | sys/arm/mv/mv_ts.c | 178 |
2 files changed, 179 insertions, 0 deletions
diff --git a/sys/arm/mv/files.mv b/sys/arm/mv/files.mv index d13c71c..116356d 100644 --- a/sys/arm/mv/files.mv +++ b/sys/arm/mv/files.mv @@ -29,6 +29,7 @@ arm/mv/mv_localbus.c standard arm/mv/mv_machdep.c standard arm/mv/mv_pci.c optional pci arm/mv/mv_sata.c optional ata | atamvsata +arm/mv/mv_ts.c standard arm/mv/timer.c standard arm/mv/twsi.c optional iicbus diff --git a/sys/arm/mv/mv_ts.c b/sys/arm/mv/mv_ts.c new file mode 100644 index 0000000..ec4ee4f --- /dev/null +++ b/sys/arm/mv/mv_ts.c @@ -0,0 +1,178 @@ +/*- + * Copyright (c) 2012 Hiroki Sato <hrs@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Driver for on-die thermal sensor in 88F6282 and 88F6283. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/bus.h> +#include <sys/sysctl.h> +#include <machine/fdt.h> + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include <arm/mv/mvreg.h> +#include <arm/mv/mvvar.h> + +static struct resource_spec mvts_res[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { -1, 0 } +}; + +struct mvts_softc { + device_t sc_dev; + struct resource *sc_res[sizeof(mvts_res)]; +}; + +static int +ts_probe(device_t dev) +{ + uint32_t d, r; + + if (!ofw_bus_is_compatible(dev, "mrvl,ts")) + return (ENXIO); + soc_id(&d, &r); + switch (d) { + case MV_DEV_88F6282: + break; + default: + device_printf(dev, "unsupported SoC (ID: 0x%08X)!\n", d); + return (ENXIO); + } + device_set_desc(dev, "Marvell Thermal Sensor"); + + return (0); +} + +#define MV_TEMP_VALID_BIT (1 << 9) +#define MV_TEMP_SENS_OFFS 10 +#define MV_TEMP_SENS_MASK 0x1ff +#define MV_TEMP_SENS_READ_MAX 16 +#define TZ_ZEROC 2732 +#define MV_TEMP_CONVERT(x) ((((322 - x) * 100000) / 13625) + TZ_ZEROC) + +/* + * MSB LSB + * 0000 0000 0000 0000 0000 0000 0000 0000 + * ^- valid bit + * |---------| + * ^--- temperature (9 bits) + */ + +static int +ts_sysctl_handler(SYSCTL_HANDLER_ARGS) +{ + struct mvts_softc *sc; + device_t dev; + uint32_t ret, ret0; + u_int val; + int i; + + dev = (device_t)arg1; + sc = device_get_softc(dev); + val = TZ_ZEROC; + + ret = bus_read_4(sc->sc_res[0], 0); + if ((ret & MV_TEMP_VALID_BIT) == 0) { + device_printf(dev, "temperature sensor is broken.\n"); + goto ts_sysctl_handle_int; + } + ret0 = 0; + for (i = 0; i < MV_TEMP_SENS_READ_MAX; i++) { + ret = bus_read_4(sc->sc_res[0], 0); + ret = (ret >> MV_TEMP_SENS_OFFS) & MV_TEMP_SENS_MASK; + + /* + * Successive reads should returns the same value except + * for the LSB when the sensor is normal. + */ + if (((ret0 ^ ret) & 0x1fe) == 0) + break; + else + ret0 = ret; + } + if (i == MV_TEMP_SENS_READ_MAX) { + device_printf(dev, "temperature sensor is unstable.\n"); + goto ts_sysctl_handle_int; + } + val = (u_int)MV_TEMP_CONVERT(ret); + +ts_sysctl_handle_int: + return (sysctl_handle_int(oidp, &val, 0, req)); +} + +static int +ts_attach(device_t dev) +{ + struct mvts_softc *sc; + struct sysctl_ctx_list *ctx; + int error; + + sc = device_get_softc(dev); + sc->sc_dev = dev; + error = bus_alloc_resources(dev, mvts_res, sc->sc_res); + if (error) { + device_printf(dev, "could not allocate resources\n"); + return (ENXIO); + } + ctx = device_get_sysctl_ctx(dev); + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, dev, + 0, ts_sysctl_handler, "IK", "Current Temperature"); + + return (0); +} + +static int +ts_detach(device_t dev) +{ + + return (0); +} + +static device_method_t ts_methods[] = { + DEVMETHOD(device_probe, ts_probe), + DEVMETHOD(device_attach, ts_attach), + DEVMETHOD(device_detach, ts_detach), + {0, 0}, +}; + +static driver_t ts_driver = { + "mvts", + ts_methods, + sizeof(struct mvts_softc), +}; + +static devclass_t ts_devclass; +DRIVER_MODULE(mvts, simplebus, ts_driver, ts_devclass, 0, 0); +MODULE_VERSION(mvts, 1); |