summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Yurchenko <grange@cvs.openbsd.org>2006-03-04 16:27:04 +0000
committerAlexander Yurchenko <grange@cvs.openbsd.org>2006-03-04 16:27:04 +0000
commitb9fdb6aa1f532061d14d21ff8ee5f45831608e29 (patch)
tree9e1d8c3405a020362b98336dad9791c05cf2d89e /sys
parent15aac0ded9c4353cc6a757bb184367d5503f80d8 (diff)
Dallas 1-Wire bus support. Includes the following drivers:
gpioow(4) 1-Wire bus bit-banging through GPIO pin onewire(4) 1-Wire bus driver owid(4) 1-Wire ID family type device owtemp(4) 1-Wire temperature family type device Drivers for RS-232 and USB bus masters will follow. ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/i386/conf/GENERIC9
-rw-r--r--sys/arch/i386/conf/files.i3867
-rw-r--r--sys/conf/files6
-rw-r--r--sys/dev/gpio/files.gpio7
-rw-r--r--sys/dev/gpio/gpioow.c245
-rw-r--r--sys/dev/onewire/Makefile7
-rw-r--r--sys/dev/onewire/devlist2h.awk55
-rw-r--r--sys/dev/onewire/files.onewire20
-rw-r--r--sys/dev/onewire/onewire.c452
-rw-r--r--sys/dev/onewire/onewire_bitbang.c77
-rw-r--r--sys/dev/onewire/onewire_subr.c112
-rw-r--r--sys/dev/onewire/onewiredevs31
-rw-r--r--sys/dev/onewire/onewirereg.h72
-rw-r--r--sys/dev/onewire/onewirevar.h86
-rw-r--r--sys/dev/onewire/owid.c117
-rw-r--r--sys/dev/onewire/owtemp.c167
16 files changed, 1466 insertions, 4 deletions
diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC
index b2f64d78a87..02096997e4c 100644
--- a/sys/arch/i386/conf/GENERIC
+++ b/sys/arch/i386/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.473 2006/03/04 15:33:37 grange Exp $
+# $OpenBSD: GENERIC,v 1.474 2006/03/04 16:27:03 grange Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -73,6 +73,7 @@ option ACPIVERBOSE
option PCIVERBOSE
option EISAVERBOSE
option USBVERBOSE
+option ONEWIREVERBOSE
pchb* at pci? # PCI-Host bridges
ppb* at pci? # PCI-PCI bridges
@@ -639,6 +640,12 @@ scsibus* at ioprbs?
# GPIO ``pin bus'' drivers
#gpioiic* at gpio? offset 0 mask 0x3 # I2C bus bit-banging
#iic* at gpioiic?
+#gpioow* at gpio? offset 0 mask 0x1 # 1-Wire bus bit-banging
+#onewire* at gpioow?
+
+# 1-Wire devices
+#owid* at onewire? # ID
+#owtemp* at onewire? # Temperature
pseudo-device pctr 1
pseudo-device mtrr 1 # Memory range attributes control
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386
index 8dd8e70e341..d3130003116 100644
--- a/sys/arch/i386/conf/files.i386
+++ b/sys/arch/i386/conf/files.i386
@@ -1,4 +1,4 @@
-# $OpenBSD: files.i386,v 1.143 2006/02/12 19:55:39 miod Exp $
+# $OpenBSD: files.i386,v 1.144 2006/03/04 16:27:03 grange Exp $
#
# new style config file for i386 architecture
#
@@ -394,6 +394,11 @@ include "dev/i2c/files.i2c"
#
include "dev/gpio/files.gpio"
+#
+# Machine-independent 1-Wire drivers
+#
+include "dev/onewire/files.onewire"
+
include "../../../dev/acpi/files.acpi"
file arch/i386/i386/acpi_machdep.c acpi
diff --git a/sys/conf/files b/sys/conf/files
index 1efe82f5165..00c4f96fcf7 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.365 2006/02/01 11:03:33 dlg Exp $
+# $OpenBSD: files,v 1.366 2006/03/04 16:27:02 grange Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -18,6 +18,7 @@ define midisyn
define radiobus {}
define i2cbus {}
define gpiobus {}
+define onewirebus {}
# filesystem firmware loading attribute
define firmload
@@ -110,6 +111,9 @@ define atapi {[channel = -1]}
device wdc: ata, atapi, wdc_base
file dev/ic/wdc.c wdc_base
+# 1-Wire bus bit-banging
+define onewire_bitbang
+
# "Chipset" drivers. These are the bus-independent routines which
# contain the cfdrivers. Attachments are provided by files.<bus>
diff --git a/sys/dev/gpio/files.gpio b/sys/dev/gpio/files.gpio
index add5a0cbe11..79fd80d3a03 100644
--- a/sys/dev/gpio/files.gpio
+++ b/sys/dev/gpio/files.gpio
@@ -1,4 +1,4 @@
-# $OpenBSD: files.gpio,v 1.5 2006/01/14 13:55:14 grange Exp $
+# $OpenBSD: files.gpio,v 1.6 2006/03/04 16:27:03 grange Exp $
define gpio {offset, mask}
@@ -10,3 +10,8 @@ file dev/gpio/gpio.c gpio needs-flag
device gpioiic: i2cbus, i2c_bitbang
attach gpioiic at gpio
file dev/gpio/gpioiic.c gpioiic
+
+# 1-Wire bus bit-banging
+device gpioow: onewirebus, onewire_bitbang
+attach gpioow at gpio
+file dev/gpio/gpioow.c gpioow
diff --git a/sys/dev/gpio/gpioow.c b/sys/dev/gpio/gpioow.c
new file mode 100644
index 00000000000..94364133eef
--- /dev/null
+++ b/sys/dev/gpio/gpioow.c
@@ -0,0 +1,245 @@
+/* $OpenBSD: gpioow.c,v 1.1 2006/03/04 16:27:03 grange Exp $ */
+
+/*
+ * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * 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.
+ */
+
+/*
+ * 1-Wire bus bit-banging through GPIO pin.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/gpio.h>
+
+#include <dev/gpio/gpiovar.h>
+
+#include <dev/onewire/onewirevar.h>
+
+#define GPIOOW_NPINS 1
+#define GPIOOW_PIN_DATA 0
+
+struct gpioow_softc {
+ struct device sc_dev;
+
+ void * sc_gpio;
+ struct gpio_pinmap sc_map;
+ int __map[GPIOOW_NPINS];
+
+ struct onewire_bus sc_ow_bus;
+ struct device * sc_ow_dev;
+
+ int sc_data;
+ int sc_dying;
+};
+
+int gpioow_match(struct device *, void *, void *);
+void gpioow_attach(struct device *, struct device *, void *);
+int gpioow_detach(struct device *, int);
+int gpioow_activate(struct device *, enum devact);
+
+int gpioow_ow_reset(void *);
+int gpioow_ow_bit(void *, int);
+
+void gpioow_bb_rx(void *);
+void gpioow_bb_tx(void *);
+int gpioow_bb_get(void *);
+void gpioow_bb_set(void *, int);
+
+struct cfattach gpioow_ca = {
+ sizeof(struct gpioow_softc),
+ gpioow_match,
+ gpioow_attach,
+ gpioow_detach,
+ gpioow_activate
+};
+
+struct cfdriver gpioow_cd = {
+ NULL, "gpioow", DV_DULL
+};
+
+static const struct onewire_bbops gpioow_bbops = {
+ gpioow_bb_rx,
+ gpioow_bb_tx,
+ gpioow_bb_get,
+ gpioow_bb_set
+};
+
+int
+gpioow_match(struct device *parent, void *match, void *aux)
+{
+ struct cfdata *cf = match;
+
+ return (strcmp(cf->cf_driver->cd_name, "gpioow") == 0);
+}
+
+void
+gpioow_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct gpioow_softc *sc = (struct gpioow_softc *)self;
+ struct gpio_attach_args *ga = aux;
+ struct onewirebus_attach_args oba;
+ int caps;
+
+ /* Check that we have enough pins */
+ if (gpio_npins(ga->ga_mask) != GPIOOW_NPINS) {
+ printf(": invalid pin mask\n");
+ return;
+ }
+
+ /* Map pins */
+ sc->sc_gpio = ga->ga_gpio;
+ sc->sc_map.pm_map = sc->__map;
+ if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
+ &sc->sc_map)) {
+ printf(": can't map pins\n");
+ return;
+ }
+
+ /* Configure data pin */
+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA);
+ if (!(caps & GPIO_PIN_OUTPUT)) {
+ printf(": data pin is unable to drive output\n");
+ goto fail;
+ }
+ if (!(caps & GPIO_PIN_INPUT)) {
+ printf(": data pin is unable to read input\n");
+ goto fail;
+ }
+ printf(": DATA[%d]", sc->sc_map.pm_map[GPIOOW_PIN_DATA]);
+ sc->sc_data = GPIO_PIN_OUTPUT;
+ if (caps & GPIO_PIN_OPENDRAIN) {
+ printf(" open-drain");
+ sc->sc_data |= GPIO_PIN_OPENDRAIN;
+ } else if ((caps & GPIO_PIN_PUSHPULL) && (caps & GPIO_PIN_TRISTATE)) {
+ printf(" push-pull tri-state");
+ sc->sc_data |= GPIO_PIN_PUSHPULL;
+ }
+ if (caps & GPIO_PIN_PULLUP) {
+ printf(" pull-up");
+ sc->sc_data |= GPIO_PIN_PULLUP;
+ }
+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA, sc->sc_data);
+
+ printf("\n");
+
+ /* Attach 1-Wire bus */
+ sc->sc_ow_bus.bus_cookie = sc;
+ sc->sc_ow_bus.bus_reset = gpioow_ow_reset;
+ sc->sc_ow_bus.bus_bit = gpioow_ow_bit;
+
+ bzero(&oba, sizeof(oba));
+ oba.oba_bus = &sc->sc_ow_bus;
+ sc->sc_ow_dev = config_found(self, &oba, onewirebus_print);
+
+ return;
+
+fail:
+ gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
+}
+
+int
+gpioow_detach(struct device *self, int flags)
+{
+ struct gpioow_softc *sc = (struct gpioow_softc *)self;
+ int rv = 0;
+
+ if (sc->sc_ow_dev != NULL)
+ rv = config_detach(sc->sc_ow_dev, flags);
+
+ return (rv);
+}
+
+int
+gpioow_activate(struct device *self, enum devact act)
+{
+ struct gpioow_softc *sc = (struct gpioow_softc *)self;
+ int rv = 0;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ return (EOPNOTSUPP);
+ case DVACT_DEACTIVATE:
+ sc->sc_dying = 1;
+ if (sc->sc_ow_dev != NULL)
+ rv = config_deactivate(sc->sc_ow_dev);
+ break;
+ }
+
+ return (rv);
+}
+
+int
+gpioow_ow_reset(void *arg)
+{
+ return (onewire_bb_reset(&gpioow_bbops, arg));
+}
+
+int
+gpioow_ow_bit(void *arg, int value)
+{
+ return (onewire_bb_bit(&gpioow_bbops, arg, value));
+}
+
+void
+gpioow_bb_rx(void *arg)
+{
+ struct gpioow_softc *sc = arg;
+ int data = sc->sc_data;
+
+ data &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
+ data |= GPIO_PIN_INPUT;
+ if (data & GPIO_PIN_PUSHPULL)
+ data |= GPIO_PIN_TRISTATE;
+ if (sc->sc_data != data) {
+ sc->sc_data = data;
+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA,
+ sc->sc_data);
+ }
+}
+
+void
+gpioow_bb_tx(void *arg)
+{
+ struct gpioow_softc *sc = arg;
+ int data = sc->sc_data;
+
+ data &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
+ data |= GPIO_PIN_OUTPUT;
+ if (sc->sc_data != data) {
+ sc->sc_data = data;
+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA,
+ sc->sc_data);
+ }
+}
+
+int
+gpioow_bb_get(void *arg)
+{
+ struct gpioow_softc *sc = arg;
+
+ return (gpio_pin_read(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA) ==
+ GPIO_PIN_HIGH ? 1 : 0);
+}
+
+void
+gpioow_bb_set(void *arg, int value)
+{
+ struct gpioow_softc *sc = arg;
+
+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA,
+ value ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
+}
diff --git a/sys/dev/onewire/Makefile b/sys/dev/onewire/Makefile
new file mode 100644
index 00000000000..269c4d22368
--- /dev/null
+++ b/sys/dev/onewire/Makefile
@@ -0,0 +1,7 @@
+# $OpenBSD: Makefile,v 1.1 2006/03/04 16:27:03 grange Exp $
+
+AWK?= awk
+
+onewiredevs.h onewiredevs_data.h: onewiredevs devlist2h.awk
+ /bin/rm -f onewiredevs.h onewiredevs_data.h
+ ${AWK} -f devlist2h.awk onewiredevs
diff --git a/sys/dev/onewire/devlist2h.awk b/sys/dev/onewire/devlist2h.awk
new file mode 100644
index 00000000000..fdb8357d9bf
--- /dev/null
+++ b/sys/dev/onewire/devlist2h.awk
@@ -0,0 +1,55 @@
+# $OpenBSD: devlist2h.awk,v 1.1 2006/03/04 16:27:03 grange Exp $
+
+#
+# Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
+#
+# 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.
+#
+
+BEGIN {
+ hfile = "onewiredevs.h"
+ dfile = "onewiredevs_data.h"
+}
+
+NR == 1 {
+ VERSION = $0
+ gsub("\\$", "", VERSION)
+
+ printf("/*\t$OpenBSD: devlist2h.awk,v 1.1 2006/03/04 16:27:03 grange Exp $\t*/\n\n" \
+ "/*\n * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n" \
+ " *\n * Generated from:\n *\t%s\n */\n\n", VERSION) > hfile
+ printf("/*\t$OpenBSD: devlist2h.awk,v 1.1 2006/03/04 16:27:03 grange Exp $\t*/\n\n" \
+ "/*\n * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n" \
+ " *\n * Generated from:\n *\t%s\n */\n\n", VERSION) > dfile
+ printf("static const struct onewire_family " \
+ "onewire_familytab[] = {\n") > dfile
+}
+
+$1 == "family" {
+ printf("#define ONEWIRE_FAMILY_%s\t%s\n", toupper($2), $3) > hfile
+ printf("\t{ ONEWIRE_FAMILY_%s, \"", toupper($2)) > dfile
+
+ f = 4
+ while (f <= NF) {
+ if (f > 4)
+ printf(" ") > dfile
+ printf("%s", $f) > dfile
+ f++
+ }
+ printf("\" },\n") > dfile
+ next
+}
+
+END {
+ printf("\t{ 0, NULL }\n};\n") > dfile
+}
diff --git a/sys/dev/onewire/files.onewire b/sys/dev/onewire/files.onewire
new file mode 100644
index 00000000000..682dcc4be73
--- /dev/null
+++ b/sys/dev/onewire/files.onewire
@@ -0,0 +1,20 @@
+# $OpenBSD: files.onewire,v 1.1 2006/03/04 16:27:03 grange Exp $
+
+define onewire {}
+
+device onewire: onewire
+attach onewire at onewirebus
+file dev/onewire/onewire.c onewire
+file dev/onewire/onewire_subr.c onewire
+
+file dev/onewire/onewire_bitbang.c onewire_bitbang
+
+# ID family type device
+device owid
+attach owid at onewire
+file dev/onewire/owid.c owid
+
+# Temperature family type device
+device owtemp
+attach owtemp at onewire
+file dev/onewire/owtemp.c owtemp
diff --git a/sys/dev/onewire/onewire.c b/sys/dev/onewire/onewire.c
new file mode 100644
index 00000000000..27144f5844e
--- /dev/null
+++ b/sys/dev/onewire/onewire.c
@@ -0,0 +1,452 @@
+/* $OpenBSD: onewire.c,v 1.1 2006/03/04 16:27:03 grange Exp $ */
+
+/*
+ * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * 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.
+ */
+
+/*
+ * 1-Wire bus driver.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+
+#include <dev/onewire/onewirereg.h>
+#include <dev/onewire/onewirevar.h>
+
+#ifdef ONEWIRE_DEBUG
+#define DPRINTF(x) printf x
+#else
+#define DPRINTF(x)
+#endif
+
+#define ONEWIRE_MAXDEVS 256
+#define ONEWIRE_SCANTIME 3
+
+struct onewire_softc {
+ struct device sc_dev;
+
+ struct onewire_bus * sc_bus;
+ struct lock sc_lock;
+ struct proc * sc_thread;
+ TAILQ_HEAD(, onewire_device) sc_devs;
+
+ int sc_dying;
+};
+
+struct onewire_device {
+ TAILQ_ENTRY(onewire_device) d_list;
+ struct device * d_dev;
+ u_int64_t d_rom;
+ int d_present;
+};
+
+int onewire_match(struct device *, void *, void *);
+void onewire_attach(struct device *, struct device *, void *);
+int onewire_detach(struct device *, int);
+int onewire_activate(struct device *, enum devact);
+int onewire_print(void *, const char *);
+
+void onewire_thread(void *);
+void onewire_createthread(void *);
+void onewire_scan(struct onewire_softc *);
+
+struct cfattach onewire_ca = {
+ sizeof(struct onewire_softc),
+ onewire_match,
+ onewire_attach,
+ onewire_detach,
+ onewire_activate
+};
+
+struct cfdriver onewire_cd = {
+ NULL, "onewire", DV_DULL
+};
+
+int
+onewire_match(struct device *parent, void *match, void *aux)
+{
+ struct cfdata *cf = match;
+
+ return (strcmp(cf->cf_driver->cd_name, "onewire") == 0);
+}
+
+void
+onewire_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct onewire_softc *sc = (struct onewire_softc *)self;
+ struct onewirebus_attach_args *oba = aux;
+
+ sc->sc_bus = oba->oba_bus;
+ lockinit(&sc->sc_lock, PRIBIO, "owlock", 0, 0);
+ TAILQ_INIT(&sc->sc_devs);
+
+ printf("\n");
+
+ kthread_create_deferred(onewire_createthread, sc);
+}
+
+int
+onewire_detach(struct device *self, int flags)
+{
+ struct onewire_softc *sc = (struct onewire_softc *)self;
+ int rv;
+
+ sc->sc_dying = 1;
+ if (sc->sc_thread != NULL) {
+ wakeup(sc->sc_thread);
+ tsleep(&sc->sc_dying, PWAIT, "owdt", 0);
+ }
+
+ onewire_lock(sc, 0);
+ rv = config_detach_children(self, flags);
+ onewire_unlock(sc);
+
+ return (rv);
+}
+
+int
+onewire_activate(struct device *self, enum devact act)
+{
+ struct onewire_softc *sc = (struct onewire_softc *)self;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ break;
+ case DVACT_DEACTIVATE:
+ sc->sc_dying = 1;
+ break;
+ }
+
+ return (config_activate_children(self, act));
+}
+
+int
+onewire_print(void *aux, const char *pnp)
+{
+ struct onewire_attach_args *oa = aux;
+ const char *famname;
+
+ if (pnp == NULL)
+ printf(" ");
+
+ famname = onewire_famname(ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom));
+ if (famname == NULL)
+ printf("family 0x%02x", ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom));
+ else
+ printf("\"%s\"", famname);
+ printf(" sn %012llx", ONEWIRE_ROM_SN(oa->oa_rom));
+
+ if (pnp != NULL)
+ printf(" at %s", pnp);
+
+ return (UNCONF);
+}
+
+int
+onewirebus_print(void *aux, const char *pnp)
+{
+ if (pnp != NULL)
+ printf("onewire at %s", pnp);
+
+ return (UNCONF);
+}
+
+int
+onewire_lock(void *arg, int flags)
+{
+ struct onewire_softc *sc = arg;
+ int lflags = LK_EXCLUSIVE;
+
+ if (flags & ONEWIRE_NOWAIT)
+ lflags |= LK_NOWAIT;
+
+ return (lockmgr(&sc->sc_lock, lflags, NULL));
+}
+
+void
+onewire_unlock(void *arg)
+{
+ struct onewire_softc *sc = arg;
+
+ lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
+}
+
+int
+onewire_reset(void *arg)
+{
+ struct onewire_softc *sc = arg;
+ struct onewire_bus *bus = sc->sc_bus;
+
+ return (bus->bus_reset(bus->bus_cookie));
+}
+
+int
+onewire_bit(void *arg, int value)
+{
+ struct onewire_softc *sc = arg;
+ struct onewire_bus *bus = sc->sc_bus;
+
+ return (bus->bus_bit(bus->bus_cookie, value));
+}
+
+int
+onewire_read_byte(void *arg)
+{
+ struct onewire_softc *sc = arg;
+ struct onewire_bus *bus = sc->sc_bus;
+ u_int8_t value = 0;
+ int i;
+
+ if (bus->bus_read_byte != NULL)
+ return (bus->bus_read_byte(bus->bus_cookie));
+
+ for (i = 0; i < 8; i++)
+ value |= (bus->bus_bit(bus->bus_cookie, 1) << i);
+
+ return (value);
+}
+
+void
+onewire_write_byte(void *arg, int value)
+{
+ struct onewire_softc *sc = arg;
+ struct onewire_bus *bus = sc->sc_bus;
+ int i;
+
+ if (bus->bus_write_byte != NULL)
+ return (bus->bus_write_byte(bus->bus_cookie, value));
+
+ for (i = 0; i < 8; i++)
+ bus->bus_bit(bus->bus_cookie, (value >> i) & 0x1);
+}
+
+int
+onewire_triplet(void *arg, int dir)
+{
+ struct onewire_softc *sc = arg;
+ struct onewire_bus *bus = sc->sc_bus;
+ int rv;
+
+ if (bus->bus_triplet != NULL)
+ return (bus->bus_triplet(bus->bus_cookie, dir));
+
+ rv = bus->bus_bit(bus->bus_cookie, 1);
+ rv <<= 1;
+ rv |= bus->bus_bit(bus->bus_cookie, 1);
+
+ switch (rv) {
+ case 0x0:
+ bus->bus_bit(bus->bus_cookie, dir);
+ break;
+ case 0x1:
+ bus->bus_bit(bus->bus_cookie, 0);
+ break;
+ default:
+ bus->bus_bit(bus->bus_cookie, 1);
+ }
+
+ return (rv);
+}
+
+void
+onewire_read_block(void *arg, void *buf, int len)
+{
+ u_int8_t *p = buf;
+
+ while (len--)
+ *p++ = onewire_read_byte(arg);
+}
+
+void
+onewire_write_block(void *arg, const void *buf, int len)
+{
+ const u_int8_t *p = buf;
+
+ while (len--)
+ onewire_write_byte(arg, *p++);
+}
+
+void
+onewire_matchrom(void *arg, u_int64_t rom)
+{
+ int i;
+
+ onewire_write_byte(arg, ONEWIRE_CMD_MATCH_ROM);
+ for (i = 0; i < 8; i++)
+ onewire_write_byte(arg, (rom >> (i * 8)) & 0xff);
+}
+
+void
+onewire_thread(void *arg)
+{
+ struct onewire_softc *sc = arg;
+
+ while (!sc->sc_dying) {
+ onewire_scan(sc);
+ tsleep(sc->sc_thread, PWAIT, "owidle", ONEWIRE_SCANTIME * hz);
+ }
+
+ sc->sc_thread = NULL;
+ wakeup(&sc->sc_dying);
+ kthread_exit(0);
+}
+
+void
+onewire_createthread(void *arg)
+{
+ struct onewire_softc *sc = arg;
+
+ if (kthread_create(onewire_thread, sc, &sc->sc_thread,
+ "%s", sc->sc_dev.dv_xname) != 0)
+ printf("%s: can't create kernel thread\n",
+ sc->sc_dev.dv_xname);
+}
+
+void
+onewire_scan(struct onewire_softc *sc)
+{
+ struct onewire_device *d, *next, *nd;
+ struct onewire_attach_args oa;
+ struct device *dev;
+ int search = 1, count = 0, present;
+ int dir, rv;
+ u_int64_t mask, rom = 0, lastrom;
+ u_int8_t data[8];
+ int i, i0 = -1;
+
+ TAILQ_FOREACH(d, &sc->sc_devs, d_list)
+ d->d_present = 0;
+
+ while (search && count++ < ONEWIRE_MAXDEVS) {
+ /* XXX: yield processor */
+ tsleep(sc, PWAIT, "owscan", hz / 10);
+
+ /*
+ * Reset the bus. If there's no presence pulse
+ * don't search for any devices.
+ */
+ onewire_lock(sc, 0);
+ if (onewire_reset(sc) != 0) {
+ DPRINTF(("%s: scan: no presence pulse\n",
+ sc->sc_dev.dv_xname));
+ onewire_unlock(sc);
+ break;
+ }
+
+ /*
+ * Start new search. Go through the previous path to
+ * the point we made a decision last time and make an
+ * opposite decision. If we didn't make any decision
+ * stop searching.
+ */
+ search = 0;
+ lastrom = rom;
+ rom = 0;
+ onewire_write_byte(sc, ONEWIRE_CMD_SEARCH_ROM);
+ for (i = 0; i < 64; i++) {
+ dir = (lastrom >> i) & 0x1;
+ if (i == i0)
+ dir = !dir;
+ rv = onewire_triplet(sc, dir);
+ switch (rv) {
+ case 0x0:
+ if (i != i0) {
+ i0 = i;
+ search = 1;
+ }
+ mask = dir;
+ break;
+ case 0x1:
+ mask = 0;
+ break;
+ case 0x2:
+ mask = 1;
+ break;
+ default:
+ DPRINTF(("%s: scan: triplet error 0x%x, "
+ "step %d\n",
+ sc->sc_dev.dv_xname, rv, i));
+ onewire_unlock(sc);
+ return;
+ }
+ rom |= (mask << i);
+ }
+ onewire_unlock(sc);
+
+ if (rom == 0)
+ continue;
+
+ /*
+ * The last byte of the ROM code contains a CRC calculated
+ * from the first 7 bytes. Re-calculate it to make sure
+ * we found a valid device.
+ */
+ for (i = 0; i < 8; i++)
+ data[i] = (rom >> (i * 8)) & 0xff;
+ if (onewire_crc(data, 7) != data[7])
+ continue;
+
+ /*
+ * Go through the list of attached devices to see if we
+ * found a new one.
+ */
+ present = 0;
+ TAILQ_FOREACH(d, &sc->sc_devs, d_list) {
+ if (d->d_rom == rom) {
+ d->d_present = 1;
+ present = 1;
+ break;
+ }
+ }
+ if (!present) {
+ bzero(&oa, sizeof(oa));
+ oa.oa_onewire = sc;
+ oa.oa_rom = rom;
+ if ((dev = config_found(&sc->sc_dev, &oa,
+ onewire_print)) == NULL)
+ continue;
+
+ MALLOC(nd, struct onewire_device *,
+ sizeof(struct onewire_device), M_DEVBUF, M_NOWAIT);
+ if (nd == NULL)
+ continue;
+ nd->d_dev = dev;
+ nd->d_rom = rom;
+ nd->d_present = 1;
+ TAILQ_INSERT_TAIL(&sc->sc_devs, nd, d_list);
+ }
+ }
+
+ /* Detach disappeared devices */
+ onewire_lock(sc, 0);
+ for (d = TAILQ_FIRST(&sc->sc_devs);
+ d != TAILQ_END(&sc->sc_dev); d = next) {
+ next = TAILQ_NEXT(d, d_list);
+ if (!d->d_present) {
+ config_detach(d->d_dev, DETACH_FORCE);
+ TAILQ_REMOVE(&sc->sc_devs, d, d_list);
+ FREE(d, M_DEVBUF);
+ }
+ }
+ onewire_unlock(sc);
+}
diff --git a/sys/dev/onewire/onewire_bitbang.c b/sys/dev/onewire/onewire_bitbang.c
new file mode 100644
index 00000000000..348fb67c4f1
--- /dev/null
+++ b/sys/dev/onewire/onewire_bitbang.c
@@ -0,0 +1,77 @@
+/* $OpenBSD: onewire_bitbang.c,v 1.1 2006/03/04 16:27:03 grange Exp $ */
+
+/*
+ * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * 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.
+ */
+
+/*
+ * 1-Wire bus bit-banging routines.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/onewire/onewirevar.h>
+
+int
+onewire_bb_reset(const struct onewire_bbops *ops, void *arg)
+{
+ int s, rv, i;
+
+ s = splhigh();
+ ops->bb_tx(arg);
+ ops->bb_set(arg, 0);
+ DELAY(480);
+ ops->bb_set(arg, 1);
+ ops->bb_rx(arg);
+ DELAY(30);
+ for (i = 0; i < 6; i++) {
+ if ((rv = ops->bb_get(arg)) == 0)
+ break;
+ DELAY(20);
+ }
+ DELAY(450);
+ splx(s);
+
+ return (rv);
+}
+
+int
+onewire_bb_bit(const struct onewire_bbops *ops, void *arg, int value)
+{
+ int s, rv, i;
+
+ s = splhigh();
+ ops->bb_tx(arg);
+ ops->bb_set(arg, 0);
+ DELAY(2);
+ if (value) {
+ ops->bb_set(arg, 1);
+ ops->bb_rx(arg);
+ for (i = 0; i < 15; i++) {
+ if ((rv = ops->bb_get(arg)) == 0)
+ break;
+ DELAY(2);
+ }
+ ops->bb_tx(arg);
+ }
+ DELAY(60);
+ ops->bb_set(arg, 1);
+ DELAY(5);
+ splx(s);
+
+ return (rv);
+}
diff --git a/sys/dev/onewire/onewire_subr.c b/sys/dev/onewire/onewire_subr.c
new file mode 100644
index 00000000000..f20e4913914
--- /dev/null
+++ b/sys/dev/onewire/onewire_subr.c
@@ -0,0 +1,112 @@
+/* $OpenBSD: onewire_subr.c,v 1.1 2006/03/04 16:27:03 grange Exp $ */
+
+/*
+ * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * 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.
+ */
+
+/*
+ * 1-Wire bus miscellaneous routines.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/onewire/onewiredevs.h>
+#include <dev/onewire/onewirereg.h>
+#include <dev/onewire/onewirevar.h>
+
+#ifdef ONEWIREVERBOSE
+struct onewire_family {
+ int of_type;
+ const char * of_name;
+};
+#include <dev/onewire/onewiredevs_data.h>
+#endif
+
+static const u_int8_t crctable[] = {
+ 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
+ 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
+ 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
+ 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
+ 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
+ 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
+ 0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
+ 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
+ 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,
+ 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
+ 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,
+ 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
+ 0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6,
+ 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
+ 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
+ 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,
+ 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f,
+ 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
+ 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
+ 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,
+ 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,
+ 0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,
+ 0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1,
+ 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
+ 0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
+ 0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
+ 0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
+ 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
+ 0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a,
+ 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
+ 0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
+ 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35
+};
+
+int
+onewire_crc(const void *buf, int len)
+{
+ const u_int8_t *p = buf;
+ u_int8_t crc = 0;
+
+ while (len--)
+ crc = crctable[crc ^ *p++];
+
+ return (crc);
+}
+
+const char *
+onewire_famname(int type)
+{
+#ifdef ONEWIREVERBOSE
+ const struct onewire_family *of;
+
+ for (of = onewire_famtab; of->of_name != NULL; of++)
+ if (of->of_type == type)
+ return (of->of_name);
+#endif
+
+ return (NULL);
+}
+
+int
+onewire_matchbyfam(struct onewire_attach_args *oa,
+ const struct onewire_matchfam *fams, int nent)
+{
+ const struct onewire_matchfam *om;
+ int i;
+
+ for (i = 0, om = fams; i < nent; i++, om++)
+ if (ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom) == om->om_type)
+ return (1);
+
+ return (0);
+}
diff --git a/sys/dev/onewire/onewiredevs b/sys/dev/onewire/onewiredevs
new file mode 100644
index 00000000000..4ff79e5d0b5
--- /dev/null
+++ b/sys/dev/onewire/onewiredevs
@@ -0,0 +1,31 @@
+$OpenBSD: onewiredevs,v 1.1 2006/03/04 16:27:03 grange Exp $
+
+/*
+ * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * 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.
+ */
+
+/*
+ * List of known 1-Wire family types.
+ */
+
+family DS1990 0x01 ID
+family DS1991 0x02 MultiKey
+family DS1994 0x04 4kb NVRAM + RTC
+family DS1993 0x06 4kb NVRAM
+family DS1992 0x08 1kb NVRAM
+family DS1982 0x09 1kb EPROM
+family DS1995 0x0a 16kb NVRAM
+family DS1996 0x0c 64kb NVRAM
+family DS1920 0x10 Temperature
diff --git a/sys/dev/onewire/onewirereg.h b/sys/dev/onewire/onewirereg.h
new file mode 100644
index 00000000000..6462e8db696
--- /dev/null
+++ b/sys/dev/onewire/onewirereg.h
@@ -0,0 +1,72 @@
+/* $OpenBSD: onewirereg.h,v 1.1 2006/03/04 16:27:03 grange Exp $ */
+
+/*
+ * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * 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.
+ */
+
+#ifndef _DEV_ONEWIRE_ONEWIREREG_H_
+#define _DEV_ONEWIRE_ONEWIREREG_H_
+
+/*
+ * 1-Wire bus protocol definitions.
+ */
+
+/*
+ * 64-bit ROM section.
+ */
+
+/* Family code */
+#define ONEWIRE_ROM_FAMILY(x) ((x) & 0xff)
+#define ONEWIRE_ROM_FAMILY_TYPE(x) ((x) & 0x7f)
+#define ONEWIRE_ROM_FAMILY_CUSTOM(x) (((x) >> 7) & 0x1)
+
+/* Serial number */
+#define ONEWIRE_ROM_SN(x) (((x) >> 8) & 0xffffffffffffULL)
+
+/* CRC */
+#define ONEWIRE_ROM_CRC(x) (((x) >> 56) & 0xff)
+
+/*
+ * Command set.
+ */
+
+/* ROM commands */
+#define ONEWIRE_CMD_READ_ROM 0x33
+#define ONEWIRE_CMD_SKIP_ROM 0xcc
+#define ONEWIRE_CMD_MATCH_ROM 0x55
+#define ONEWIRE_CMD_SEARCH_ROM 0xf0
+#define ONEWIRE_CMD_OVERDRIVE_SKIP_ROM 0x3c
+#define ONEWIRE_CMD_OVERDRIVE_MATCH_ROM 0x69
+
+/* Scratchpad commands */
+#define ONEWIRE_CMD_READ_SCRATCHPAD 0xaa
+#define ONEWIRE_CMD_WRITE_SCRATCHPAD 0x0f
+#define ONEWIRE_CMD_COPY_SCRATCHPAD 0x55
+
+/* Memory commands */
+#define ONEWIRE_CMD_READ_MEMORY 0xf0
+#define ONEWIRE_CMD_WRITE_MEMORY 0x0f
+#define ONEWIRE_CMD_EXT_READ_MEMORY 0xa5
+
+/* Password commands */
+#define ONEWIRE_CMD_READ_SUBKEY 0x66
+#define ONEWIRE_CMD_WRITE_SUBKEY 0x99
+#define ONEWIRE_CMD_WRITE_PASSWORD 0x5a
+
+/* Status commands */
+#define ONEWIRE_CMD_READ_STATUS 0xaa
+#define ONEWIRE_CMD_WRITE_STATUS 0x55
+
+#endif /* !_DEV_ONEWIRE_ONEWIREREG_H_ */
diff --git a/sys/dev/onewire/onewirevar.h b/sys/dev/onewire/onewirevar.h
new file mode 100644
index 00000000000..51b7ea4a434
--- /dev/null
+++ b/sys/dev/onewire/onewirevar.h
@@ -0,0 +1,86 @@
+/* $OpenBSD: onewirevar.h,v 1.1 2006/03/04 16:27:03 grange Exp $ */
+
+/*
+ * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * 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.
+ */
+
+#ifndef _DEV_ONEWIRE_ONEWIREVAR_H_
+#define _DEV_ONEWIRE_ONEWIREVAR_H_
+
+/*
+ * 1-Wire bus interface.
+ */
+
+/* Bus master interface */
+struct onewire_bus {
+ void * bus_cookie;
+
+ int (*bus_reset)(void *);
+ int (*bus_bit)(void *, int);
+ int (*bus_read_byte)(void *);
+ void (*bus_write_byte)(void *, int);
+ int (*bus_triplet)(void *, int);
+};
+
+/* Bus methods */
+int onewire_lock(void *, int);
+void onewire_unlock(void *);
+int onewire_reset(void *);
+int onewire_bit(void *, int);
+int onewire_read_byte(void *);
+void onewire_write_byte(void *, int);
+int onewire_triplet(void *, int);
+void onewire_read_block(void *, void *, int);
+void onewire_write_block(void *, const void *, int);
+void onewire_matchrom(void *, u_int64_t);
+
+#define ONEWIRE_NOWAIT 0x0001
+
+/* Bus attachment */
+struct onewirebus_attach_args {
+ struct onewire_bus * oba_bus;
+};
+
+int onewirebus_print(void *, const char *);
+
+/* Device attachment */
+struct onewire_attach_args {
+ void * oa_onewire;
+ u_int64_t oa_rom;
+};
+
+/* Family matching */
+struct onewire_matchfam {
+ int om_type;
+};
+
+/* Miscellaneous routines */
+int onewire_crc(const void *, int);
+const char * onewire_famname(int);
+int onewire_matchbyfam(struct onewire_attach_args *,
+ const struct onewire_matchfam *, int);
+
+/* Bus bit-banging */
+struct onewire_bbops {
+ void (*bb_rx)(void *);
+ void (*bb_tx)(void *);
+ int (*bb_get)(void *);
+ void (*bb_set)(void *, int);
+};
+
+int onewire_bb_reset(const struct onewire_bbops *, void *);
+int onewire_bb_bit(const struct onewire_bbops *, void *, int);
+
+#endif /* !_DEV_ONEWIRE_ONEWIREVAR_H_ */
diff --git a/sys/dev/onewire/owid.c b/sys/dev/onewire/owid.c
new file mode 100644
index 00000000000..21fdb9e8b3c
--- /dev/null
+++ b/sys/dev/onewire/owid.c
@@ -0,0 +1,117 @@
+/* $OpenBSD: owid.c,v 1.1 2006/03/04 16:27:03 grange Exp $ */
+
+/*
+ * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * 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.
+ */
+
+/*
+ * 1-Wire ID family type device driver.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/sensors.h>
+
+#include <dev/onewire/onewiredevs.h>
+#include <dev/onewire/onewirereg.h>
+#include <dev/onewire/onewirevar.h>
+
+struct owid_softc {
+ struct device sc_dev;
+
+ void * sc_onewire;
+ u_int64_t sc_rom;
+
+ struct sensor sc_sensor;
+
+ int sc_dying;
+};
+
+int owid_match(struct device *, void *, void *);
+void owid_attach(struct device *, struct device *, void *);
+int owid_detach(struct device *, int);
+int owid_activate(struct device *, enum devact);
+
+struct cfattach owid_ca = {
+ sizeof(struct owid_softc),
+ owid_match,
+ owid_attach,
+ owid_detach,
+ owid_activate
+};
+
+struct cfdriver owid_cd = {
+ NULL, "owid", DV_DULL
+};
+
+static const struct onewire_matchfam owid_fams[] = {
+ { ONEWIRE_FAMILY_DS1990 }
+};
+
+int
+owid_match(struct device *parent, void *match, void *aux)
+{
+ return (onewire_matchbyfam(aux, owid_fams,
+ sizeof(owid_fams) /sizeof(owid_fams[0])));
+}
+
+void
+owid_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct owid_softc *sc = (struct owid_softc *)self;
+ struct onewire_attach_args *oa = aux;
+
+ sc->sc_onewire = oa->oa_onewire;
+ sc->sc_rom = oa->oa_rom;
+
+ /* Initialize sensor */
+ strlcpy(sc->sc_sensor.device, sc->sc_dev.dv_xname,
+ sizeof(sc->sc_sensor.device));
+ sc->sc_sensor.type = SENSOR_INTEGER;
+ strlcpy(sc->sc_sensor.desc, "ID", sizeof(sc->sc_sensor.desc));
+ sc->sc_sensor.value = ONEWIRE_ROM_SN(sc->sc_rom);
+ sensor_add(&sc->sc_sensor);
+
+ printf("\n");
+}
+
+int
+owid_detach(struct device *self, int flags)
+{
+ struct owid_softc *sc = (struct owid_softc *)self;
+
+ sensor_del(&sc->sc_sensor);
+
+ return (0);
+}
+
+int
+owid_activate(struct device *self, enum devact act)
+{
+ struct owid_softc *sc = (struct owid_softc *)self;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ return (EOPNOTSUPP);
+ case DVACT_DEACTIVATE:
+ sc->sc_dying = 1;
+ break;
+ }
+
+ return (0);
+}
diff --git a/sys/dev/onewire/owtemp.c b/sys/dev/onewire/owtemp.c
new file mode 100644
index 00000000000..1fd5b673881
--- /dev/null
+++ b/sys/dev/onewire/owtemp.c
@@ -0,0 +1,167 @@
+/* $OpenBSD: owtemp.c,v 1.1 2006/03/04 16:27:03 grange Exp $ */
+
+/*
+ * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * 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.
+ */
+
+/*
+ * 1-Wire temperature family type device driver.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/sensors.h>
+
+#include <dev/onewire/onewiredevs.h>
+#include <dev/onewire/onewirereg.h>
+#include <dev/onewire/onewirevar.h>
+
+#define DS1920_CMD_CONVERT 0x44
+#define DS1920_CMD_READ_SCRATCHPAD 0xbe
+
+struct owtemp_softc {
+ struct device sc_dev;
+
+ void * sc_onewire;
+ u_int64_t sc_rom;
+
+ struct sensor sc_sensor;
+
+ int sc_dying;
+};
+
+int owtemp_match(struct device *, void *, void *);
+void owtemp_attach(struct device *, struct device *, void *);
+int owtemp_detach(struct device *, int);
+int owtemp_activate(struct device *, enum devact);
+
+void owtemp_update(void *);
+
+struct cfattach owtemp_ca = {
+ sizeof(struct owtemp_softc),
+ owtemp_match,
+ owtemp_attach,
+ owtemp_detach,
+ owtemp_activate
+};
+
+struct cfdriver owtemp_cd = {
+ NULL, "owtemp", DV_DULL
+};
+
+static const struct onewire_matchfam owtemp_fams[] = {
+ { ONEWIRE_FAMILY_DS1920 }
+};
+
+int
+owtemp_match(struct device *parent, void *match, void *aux)
+{
+ return (onewire_matchbyfam(aux, owtemp_fams,
+ sizeof(owtemp_fams) /sizeof(owtemp_fams[0])));
+}
+
+void
+owtemp_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct owtemp_softc *sc = (struct owtemp_softc *)self;
+ struct onewire_attach_args *oa = aux;
+
+ sc->sc_onewire = oa->oa_onewire;
+ sc->sc_rom = oa->oa_rom;
+
+ /* Initialize sensor */
+ strlcpy(sc->sc_sensor.device, sc->sc_dev.dv_xname,
+ sizeof(sc->sc_sensor.device));
+ sc->sc_sensor.type = SENSOR_TEMP;
+ strlcpy(sc->sc_sensor.desc, "Temp", sizeof(sc->sc_sensor.desc));
+
+ if (sensor_task_register(sc, owtemp_update, 5)) {
+ printf(": unable to register update task\n");
+ return;
+ }
+ sensor_add(&sc->sc_sensor);
+
+ printf("\n");
+}
+
+int
+owtemp_detach(struct device *self, int flags)
+{
+ struct owtemp_softc *sc = (struct owtemp_softc *)self;
+
+ sensor_del(&sc->sc_sensor);
+ sensor_task_unregister(sc);
+
+ return (0);
+}
+
+int
+owtemp_activate(struct device *self, enum devact act)
+{
+ struct owtemp_softc *sc = (struct owtemp_softc *)self;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ return (EOPNOTSUPP);
+ case DVACT_DEACTIVATE:
+ sc->sc_dying = 1;
+ break;
+ }
+
+ return (0);
+}
+
+void
+owtemp_update(void *arg)
+{
+ struct owtemp_softc *sc = arg;
+ u_int8_t data[9];
+
+ onewire_lock(sc->sc_onewire, 0);
+ if (onewire_reset(sc->sc_onewire) != 0)
+ goto done;
+ onewire_matchrom(sc->sc_onewire, sc->sc_rom);
+
+ /*
+ * Start temperature conversion. The conversion takes up to 750ms.
+ * After sending the command, the data line must be held high for
+ * at least 750ms to provide power during the conversion process.
+ * As such, no other activity may take place on the 1-Wire bus for
+ * at least this period.
+ */
+ onewire_write_byte(sc->sc_onewire, DS1920_CMD_CONVERT);
+ tsleep(sc, PRIBIO, "owtemp", hz);
+
+ if (onewire_reset(sc->sc_onewire) != 0)
+ goto done;
+ onewire_matchrom(sc->sc_onewire, sc->sc_rom);
+
+ /*
+ * The result of the temperature measurement is placed in the
+ * first two bytes of the scratchpad.
+ */
+ onewire_write_byte(sc->sc_onewire, DS1920_CMD_READ_SCRATCHPAD);
+ onewire_read_block(sc->sc_onewire, data, 9);
+ if (onewire_crc(data, 8) == data[8]) {
+ sc->sc_sensor.value = 273150000 +
+ (int)((u_int16_t)data[1] << 8 | data[0]) * 500000;
+ }
+
+done:
+ onewire_unlock(sc->sc_onewire);
+}