summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2012-08-18 12:37:07 +0000
committerhrs <hrs@FreeBSD.org>2012-08-18 12:37:07 +0000
commit9f4aa1a3fb9ba99ad0d702c3f6dcf2120e924f10 (patch)
tree7b5d3ae291b9478d4117aba5cd4a004ea0d4219d
parentc4e0514c26dd114eadf7a57644c243ca381054c9 (diff)
downloadFreeBSD-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.mv1
-rw-r--r--sys/arm/mv/mv_ts.c178
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);
OpenPOWER on IntegriCloud