Date: Thu, 6 Oct 2011 21:31:22 +0000 (UTC) From: Andrew Thompson <thompsa@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r226077 - in projects/onewire/sys: conf dev/gpio dev/onewire Message-ID: <201110062131.p96LVMZq078588@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: thompsa Date: Thu Oct 6 21:31:21 2011 New Revision: 226077 URL: http://svn.freebsd.org/changeset/base/226077 Log: Add the OpenBSD onewire stack as a work in progress. A DS18B20 attaches as owtemp0 and reads the temp via a gpio pin. Locking isnt really done and there are many rough edges. Obtained from: OpenBSD Added: projects/onewire/sys/dev/gpio/gpio1wire.c (contents, props changed) projects/onewire/sys/dev/onewire/ projects/onewire/sys/dev/onewire/devlist2h.awk (contents, props changed) projects/onewire/sys/dev/onewire/onewire.c (contents, props changed) projects/onewire/sys/dev/onewire/onewirebb.c (contents, props changed) projects/onewire/sys/dev/onewire/onewirebus.c (contents, props changed) projects/onewire/sys/dev/onewire/onewiredevs projects/onewire/sys/dev/onewire/onewiredevs.h (contents, props changed) projects/onewire/sys/dev/onewire/onewiredevs_data.h (contents, props changed) projects/onewire/sys/dev/onewire/onewirereg.h (contents, props changed) projects/onewire/sys/dev/onewire/onewirevar.h (contents, props changed) projects/onewire/sys/dev/onewire/owbb_if.m projects/onewire/sys/dev/onewire/owbus_if.m projects/onewire/sys/dev/onewire/owctr.c (contents, props changed) projects/onewire/sys/dev/onewire/owid.c (contents, props changed) projects/onewire/sys/dev/onewire/owsbm.c (contents, props changed) projects/onewire/sys/dev/onewire/owtemp.c (contents, props changed) Modified: projects/onewire/sys/conf/files Modified: projects/onewire/sys/conf/files ============================================================================== --- projects/onewire/sys/conf/files Thu Oct 6 21:23:06 2011 (r226076) +++ projects/onewire/sys/conf/files Thu Oct 6 21:31:21 2011 (r226077) @@ -1099,6 +1099,7 @@ dev/gpio/gpiobus.c optional gpio \ dependency "gpiobus_if.h" dev/gpio/gpioc.c optional gpio \ dependency "gpio_if.h" +dev/gpio/gpio1wire.c optional gpio1w dev/gpio/gpioiic.c optional gpioiic dev/gpio/gpioled.c optional gpioled dev/gpio/gpio_if.m optional gpio @@ -1526,6 +1527,14 @@ dev/nmdm/nmdm.c optional nmdm dev/nsp/nsp.c optional nsp dev/nsp/nsp_pccard.c optional nsp pccard dev/null/null.c standard +dev/onewire/onewire.c optional onewire +dev/onewire/onewirebus.c optional onewire \ + dependency "owbus_if.h" +dev/onewire/onewirebb.c optional onewirebb \ + dependency "owbb_if.h" +dev/onewire/owtemp.c optional owtemp +dev/onewire/owbus_if.m optional onewire +dev/onewire/owbb_if.m optional onewirebb dev/patm/if_patm.c optional patm pci dev/patm/if_patm_attach.c optional patm pci dev/patm/if_patm_intr.c optional patm pci Added: projects/onewire/sys/dev/gpio/gpio1wire.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/onewire/sys/dev/gpio/gpio1wire.c Thu Oct 6 21:31:21 2011 (r226077) @@ -0,0 +1,162 @@ +/*- + * Copyright (c) 2009 Oleksandr Tymoshenko <gonzo@freebsd.org> + * Copyright (c) 2010 Luiz Otavio O Souza + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bio.h> +#include <sys/bus.h> +#include <sys/conf.h> +#include <sys/kernel.h> +#include <sys/kthread.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> + +#include <sys/gpio.h> +#include "gpiobus_if.h" + +#include <dev/onewire/onewirevar.h> +#include "owbus_if.h" +#include "owbb_if.h" + +#define ONEWIRE_PIN 0 /* Only one pin */ + +struct gpio1w_softc +{ + device_t sc_dev; + device_t sc_busdev; +}; + +static int gpio1w_probe(device_t); +static int gpio1w_attach(device_t); + +/* owbb interface */ +static void gpio1w_rx(device_t); +static void gpio1w_tx(device_t); +static int gpio1w_get(device_t); +static void gpio1w_set(device_t, int); + +static int +gpio1w_probe(device_t dev) +{ + + device_set_desc(dev, "GPIO 1wire bit-banging driver"); + return (0); +} + +static int +gpio1w_attach(device_t dev) +{ + struct gpio1w_softc *sc = device_get_softc(dev); + device_t bitbang; + + sc->sc_dev = dev; + sc->sc_busdev = device_get_parent(dev); + + /* add generic bit-banging code */ + bitbang = device_add_child(dev, "owbb", -1); + device_probe_and_attach(bitbang); + + return (0); +} + +/* + * Reset bus by setting SDA first and then SCL. + * Must always be called with gpio bus locked. + */ +static void +gpio1w_rx(device_t dev) +{ + struct gpio1w_softc *sc = device_get_softc(dev); + + GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, ONEWIRE_PIN, + GPIO_PIN_INPUT); +} + +static void +gpio1w_tx(device_t dev) +{ + struct gpio1w_softc *sc = device_get_softc(dev); + + GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, ONEWIRE_PIN, + GPIO_PIN_OUTPUT); +} + +static int +gpio1w_get(device_t dev) +{ + struct gpio1w_softc *sc = device_get_softc(dev); + unsigned int val; + + GPIOBUS_LOCK_BUS(sc->sc_busdev); + GPIOBUS_PIN_GET(sc->sc_busdev, sc->sc_dev, ONEWIRE_PIN, &val); + GPIOBUS_UNLOCK_BUS(sc->sc_busdev); + + return (val); +} + +static void +gpio1w_set(device_t dev, int value) +{ + struct gpio1w_softc *sc = device_get_softc(dev); + + GPIOBUS_LOCK_BUS(sc->sc_busdev); + GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev, ONEWIRE_PIN, value ? 1:0); + GPIOBUS_UNLOCK_BUS(sc->sc_busdev); +} + +static devclass_t gpio1w_devclass; + +static device_method_t gpio1w_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, gpio1w_probe), + DEVMETHOD(device_attach, gpio1w_attach), + DEVMETHOD(device_detach, bus_generic_detach), + + /* owbb interface */ + DEVMETHOD(owbb_rx, gpio1w_rx), + DEVMETHOD(owbb_tx, gpio1w_tx), + DEVMETHOD(owbb_get, gpio1w_get), + DEVMETHOD(owbb_set, gpio1w_set), + + { 0, 0 } +}; + +static driver_t gpio1w_driver = { + "gpio1w", + gpio1w_methods, + sizeof(struct gpio1w_softc), +}; + +DRIVER_MODULE(gpio1w, gpiobus, gpio1w_driver, gpio1w_devclass, 0, 0); +DRIVER_MODULE(owbb, gpio1w, owbb_driver, owbb_devclass, 0, 0); +MODULE_DEPEND(gpio1w, owbb, 1, 1, 1); +MODULE_DEPEND(gpio1w, gpiobus, 1, 1, 1); Added: projects/onewire/sys/dev/onewire/devlist2h.awk ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/onewire/sys/dev/onewire/devlist2h.awk Thu Oct 6 21:31:21 2011 (r226077) @@ -0,0 +1,62 @@ +# $OpenBSD: devlist2h.awk,v 1.4 2007/02/28 22:31:32 deraadt 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\$\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\$\t*/\n\n" \ + "/*\n * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n" \ + " *\n * Generated from:\n *\t%s\n */\n\n", VERSION) > dfile + + printf("struct onewire_family {\n") > dfile + printf("\tint\t\tof_type;\n") > dfile + printf("\tconst char\t*of_name;\n") > dfile + printf("};\n\n") > dfile + + printf("static const struct onewire_family " \ + "onewire_famtab[] = {\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 +} Added: projects/onewire/sys/dev/onewire/onewire.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/onewire/sys/dev/onewire/onewire.c Thu Oct 6 21:31:21 2011 (r226077) @@ -0,0 +1,264 @@ +/* $OpenBSD: onewire_subr.c,v 1.4 2010/07/19 23:44:09 deraadt 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 routines. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> + +#include <dev/onewire/onewiredevs.h> +#include <dev/onewire/onewirereg.h> +#include <dev/onewire/onewirevar.h> + +#ifdef ONEWIREVERBOSE +#include <dev/onewire/onewiredevs_data.h> +#endif + +#include "owbus_if.h" + +static const uint8_t crc8_table[] = { + 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 +}; + +static const uint8_t crc16_table_low[] = { + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, + 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40 +}; + +static const uint8_t crc16_table_high[] = { + 0x00, 0xc0, 0xc1, 0x01, 0xc3, 0x03, 0x02, 0xc2, + 0xc6, 0x06, 0x07, 0xc7, 0x05, 0xc5, 0xc4, 0x04, + 0xcc, 0x0c, 0x0d, 0xcd, 0x0f, 0xcf, 0xce, 0x0e, + 0x0a, 0xca, 0xcb, 0x0b, 0xc9, 0x09, 0x08, 0xc8, + 0xd8, 0x18, 0x19, 0xd9, 0x1b, 0xdb, 0xda, 0x1a, + 0x1e, 0xde, 0xdf, 0x1f, 0xdd, 0x1d, 0x1c, 0xdc, + 0x14, 0xd4, 0xd5, 0x15, 0xd7, 0x17, 0x16, 0xd6, + 0xd2, 0x12, 0x13, 0xd3, 0x11, 0xd1, 0xd0, 0x10, + 0xf0, 0x30, 0x31, 0xf1, 0x33, 0xf3, 0xf2, 0x32, + 0x36, 0xf6, 0xf7, 0x37, 0xf5, 0x35, 0x34, 0xf4, + 0x3c, 0xfc, 0xfd, 0x3d, 0xff, 0x3f, 0x3e, 0xfe, + 0xfa, 0x3a, 0x3b, 0xfb, 0x39, 0xf9, 0xf8, 0x38, + 0x28, 0xe8, 0xe9, 0x29, 0xeb, 0x2b, 0x2a, 0xea, + 0xee, 0x2e, 0x2f, 0xef, 0x2d, 0xed, 0xec, 0x2c, + 0xe4, 0x24, 0x25, 0xe5, 0x27, 0xe7, 0xe6, 0x26, + 0x22, 0xe2, 0xe3, 0x23, 0xe1, 0x21, 0x20, 0xe0, + 0xa0, 0x60, 0x61, 0xa1, 0x63, 0xa3, 0xa2, 0x62, + 0x66, 0xa6, 0xa7, 0x67, 0xa5, 0x65, 0x64, 0xa4, + 0x6c, 0xac, 0xad, 0x6d, 0xaf, 0x6f, 0x6e, 0xae, + 0xaa, 0x6a, 0x6b, 0xab, 0x69, 0xa9, 0xa8, 0x68, + 0x78, 0xb8, 0xb9, 0x79, 0xbb, 0x7b, 0x7a, 0xba, + 0xbe, 0x7e, 0x7f, 0xbf, 0x7d, 0xbd, 0xbc, 0x7c, + 0xb4, 0x74, 0x75, 0xb5, 0x77, 0xb7, 0xb6, 0x76, + 0x72, 0xb2, 0xb3, 0x73, 0xb1, 0x71, 0x70, 0xb0, + 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, + 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, + 0x9c, 0x5c, 0x5d, 0x9d, 0x5f, 0x9f, 0x9e, 0x5e, + 0x5a, 0x9a, 0x9b, 0x5b, 0x99, 0x59, 0x58, 0x98, + 0x88, 0x48, 0x49, 0x89, 0x4b, 0x8b, 0x8a, 0x4a, + 0x4e, 0x8e, 0x8f, 0x4f, 0x8d, 0x4d, 0x4c, 0x8c, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, + 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 +}; + +void +onewire_lock(device_t dev) +{ + return (OWBUS_LOCK_BUS(dev)); +} + +void +onewire_unlock(device_t dev) +{ + return (OWBUS_UNLOCK_BUS(dev)); +} + +int +onewire_reset(device_t dev) +{ + return (OWBUS_RESET(dev)); +} + +int +onewire_bit(device_t dev, int val) +{ + return (OWBUS_BIT(dev, val)); +} + +int +onewire_read_byte(device_t dev) +{ + return (OWBUS_READ_BYTE(dev)); +} + +void +onewire_write_byte(device_t dev, int val) +{ + return (OWBUS_WRITE_BYTE(dev, val)); +} + +void +onewire_read_block(device_t dev, void *buf, int len) +{ + return (OWBUS_READ_BLOCK(dev, buf, len)); +} + +void +onewire_write_block(device_t dev, const void *buf, int len) +{ + return (OWBUS_WRITE_BLOCK(dev, buf, len)); +} + +int +onewire_triplet(device_t dev, int dir) +{ + return (OWBUS_TRIPLET(dev, dir)); +} + +void +onewire_matchrom(device_t dev, uint64_t rom) +{ + return (OWBUS_MATCHROM(dev, rom)); +} + +int +onewire_search(device_t dev, uint64_t *buf, int size, uint64_t startrom) +{ + return (OWBUS_SEARCH(dev, buf, size, startrom)); +} + +int +onewire_crc(const void *buf, int len) +{ + const uint8_t *p = buf; + uint8_t crc = 0; + + while (len--) + crc = crc8_table[crc ^ *p++]; + + return (crc); +} + +uint16_t +onewire_crc16(const void *buf, int len) +{ + const uint8_t *p = buf; + uint16_t crc = 0; + uint16_t tmpcrc; + int idx; + + while (len--) { + idx = (crc & 0xff) ^ *p++; + tmpcrc = crc16_table_high[idx] << 8; + tmpcrc |= crc16_table_low[idx] ^ (crc >> 8); + crc = tmpcrc; + } + + 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); +} + +const struct onewire_matchfam * +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 (om); + + return (NULL); +} Added: projects/onewire/sys/dev/onewire/onewirebb.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/onewire/sys/dev/onewire/onewirebb.c Thu Oct 6 21:31:21 2011 (r226077) @@ -0,0 +1,343 @@ +/* $OpenBSD: onewire_bitbang.c,v 1.2 2010/07/02 03:13:42 tedu 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/types.h> + +#include <sys/bus.h> +#include <sys/conf.h> +#include <sys/ioccom.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/queue.h> +#include <machine/bus.h> +#include <machine/resource.h> + +#include <dev/onewire/onewirereg.h> +#include <dev/onewire/onewirevar.h> + +#include "owbb_if.h" +#include "owbus_if.h" + +struct owbb_softc { + device_t owbus; +}; + +static int owbb_probe(device_t); +static int owbb_attach(device_t); +static int owbb_detach(device_t); + +static int owbb_reset(device_t); +static int owbb_bit(device_t, int); +static int owbb_read_byte(device_t); +static void owbb_write_byte(device_t, int); +static void owbb_read_block(device_t, void *, int); +static void owbb_write_block(device_t, const void *, int); +static int owbb_triplet(device_t, int); +static void owbb_matchrom(device_t, uint64_t); +static int owbb_search(device_t, uint64_t *, int, uint64_t); + +static int +owbb_probe(device_t dev) +{ + device_set_desc(dev, "1wire bit-banging driver"); + + return (0); +} + +static int +owbb_attach(device_t dev) +{ + struct owbb_softc *sc = (struct owbb_softc *)device_get_softc(dev); + + sc->owbus = device_add_child(dev, "owbus", -1); + if (!sc->owbus) + return (ENXIO); + bus_generic_attach(dev); + + return (0); +} + +static int +owbb_detach(device_t dev) +{ + struct owbb_softc *sc = (struct owbb_softc *)device_get_softc(dev); + device_t child; + + /* + * We need to save child because the detach indirectly causes + * sc->owbus to be zeroed. Since we added the device + * unconditionally in owbb_attach, we need to make sure we + * delete it here. See owbb_child_detached. We need that + * callback in case newbus detached our children w/o detaching + * us (say owbus is a module and unloaded w/o owbb being + * unloaded). + */ + child = sc->owbus; + bus_generic_detach(dev); + if (child) + device_delete_child(dev, child); + + return (0); +} + +static void +owbb_child_detached( device_t dev, device_t child ) +{ + struct owbb_softc *sc = (struct owbb_softc *)device_get_softc(dev); + + if (child == sc->owbus) + sc->owbus = NULL; +} + +static int +owbb_reset(device_t dev) +{ + device_t pdev = device_get_parent(dev); + int rv, i; + + OWBB_TX(pdev); + OWBB_SET(pdev, 0); + DELAY(480); + OWBB_SET(pdev, 1); + OWBB_RX(pdev); + DELAY(30); + for (i = 0; i < 6; i++) { + if ((rv = OWBB_GET(pdev)) == 0) + break; + DELAY(20); + } + DELAY(450); + + return (rv); +} + +static int +owbb_bit(device_t dev, int value) +{ + device_t pdev = device_get_parent(dev); + int rv, i; + + OWBB_TX(pdev); + OWBB_SET(pdev, 0); + DELAY(2); + rv = 0; + if (value) { + OWBB_SET(pdev, 1); + OWBB_RX(pdev); + for (i = 0; i < 15; i++) { + if ((rv = OWBB_GET(pdev)) == 0) + break; + DELAY(2); + } + OWBB_TX(pdev); + } + DELAY(60); + OWBB_SET(pdev, 1); + DELAY(5); + + return (rv); +} + +static int +owbb_read_byte(device_t dev) +{ + uint8_t value = 0; + int i; + + for (i = 0; i < 8; i++) + value |= (owbb_bit(dev, 1) << i); + + return (value); +} + +static void +owbb_write_byte(device_t dev, int value) +{ + int i; + + for (i = 0; i < 8; i++) + owbb_bit(dev, (value >> i) & 0x1); +} + +static void +owbb_read_block(device_t dev, void *buf, int len) +{ + uint8_t *p = buf; + + while (len--) + *p++ = owbb_read_byte(dev); +} + +static void +owbb_write_block(device_t dev, const void *buf, int len) +{ + const uint8_t *p = buf; + + while (len--) + owbb_write_byte(dev, *p++); +} + +static int +owbb_triplet(device_t dev, int dir) +{ + int rv; + + rv = owbb_bit(dev, 1); + rv <<= 1; + rv |= owbb_bit(dev, 1); + + switch (rv) { + case 0x0: + owbb_bit(dev, dir); + break; + case 0x1: + owbb_bit(dev, 0); + break; + default: + owbb_bit(dev, 1); + } + + return (rv); +} + +static void +owbb_matchrom(device_t dev, uint64_t rom) +{ + int i; + + owbb_write_byte(dev, ONEWIRE_CMD_MATCH_ROM); + for (i = 0; i < 8; i++) + owbb_write_byte(dev, (rom >> (i * 8)) & 0xff); +} + +static int +owbb_search(device_t dev, uint64_t *buf, int size, uint64_t startrom) +{ + int search = 1, count = 0, lastd = -1, dir, rv, i, i0; + uint64_t mask, rom = startrom, lastrom; + uint8_t data[8]; + + while (search && count < size) { + /* XXX: yield processor */ + tsleep(dev, PWAIT, "owscan", hz / 10); + + /* + * 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. + */ + lastrom = rom; + rom = 0; + OWBUS_LOCK_BUS(dev); + owbb_reset(dev); + owbb_write_byte(dev, ONEWIRE_CMD_SEARCH_ROM); + for (i = 0, i0 = -1; i < 64; i++) { + dir = (lastrom >> i) & 0x1; + if (i == lastd) + dir = 1; + else if (i > lastd) + dir = 0; + rv = owbb_triplet(dev, dir); + switch (rv) { + case 0x0: + if (i != lastd && dir == 0) + i0 = i; + mask = dir; + break; + case 0x1: + mask = 0; + break; + case 0x2: + mask = 1; + break; + default: + printf("%s: search triplet error 0x%x, " + "step %d\n", + device_get_nameunit(dev), rv, i); + OWBUS_UNLOCK_BUS(dev); + return (-1); + } + rom |= (mask << i); + } + OWBUS_UNLOCK_BUS(dev); + + if ((lastd = i0) == -1) + search = 0; + + 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; + + buf[count++] = rom; + } + + return (count); +} +static device_method_t owbb_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, owbb_probe), + DEVMETHOD(device_attach, owbb_attach), + DEVMETHOD(device_detach, owbb_detach), + + /* bus interface */ + DEVMETHOD(bus_child_detached, owbb_child_detached), + + /* ONEWIRE protocol */ + DEVMETHOD(owbus_bit, owbb_bit), + DEVMETHOD(owbus_reset, owbb_reset), + DEVMETHOD(owbus_read_byte, owbb_read_byte), + DEVMETHOD(owbus_write_byte, owbb_write_byte), + DEVMETHOD(owbus_read_block, owbb_read_block), + DEVMETHOD(owbus_write_block, owbb_write_block), + DEVMETHOD(owbus_triplet, owbb_triplet), + DEVMETHOD(owbus_matchrom, owbb_matchrom), + DEVMETHOD(owbus_search, owbb_search), + + + { 0, 0 } +}; + +driver_t owbb_driver = { + "owbb", + owbb_methods, + sizeof(struct owbb_softc), +}; + +devclass_t owbb_devclass; + +DRIVER_MODULE(owbus, owbb, owbus_driver, owbus_devclass, 0, 0); + +MODULE_DEPEND(owbb, owbus, 1, 1, 1); +MODULE_VERSION(owbb, 1); Added: projects/onewire/sys/dev/onewire/onewirebus.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/onewire/sys/dev/onewire/onewirebus.c Thu Oct 6 21:31:21 2011 (r226077) @@ -0,0 +1,371 @@ +/* $OpenBSD: onewire.c,v 1.12 2011/07/03 15:47:16 matthew 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/types.h> + +#include <sys/bus.h> +#include <sys/conf.h> +#include <sys/ioccom.h> +#include <sys/kernel.h> +#include <sys/kthread.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/queue.h> +#include <machine/bus.h> +#include <machine/resource.h> + +#include <dev/onewire/onewirereg.h> +#include <dev/onewire/onewirevar.h> + +#include "owbus_if.h" + +#define ONEWIRE_DEBUG +#ifdef ONEWIRE_DEBUG +#define DPRINTF(x) printf x +#else +#define DPRINTF(x) +#endif + +#define OWBUS_IVAR(d) (struct owbus_ivar *) device_get_ivars(d) +#define OWBUS_SOFTC(d) (struct owbus_softc *) device_get_softc(d) + +#define OWBUS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) +#define OWBUS_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) +#define OWBUS_LOCK_INIT(_sc) \ + mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_busdev), \ + "owbus", MTX_DEF) +#define OWBUS_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); +#define OWBUS_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); +#define OWBUS_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); + +struct onewire_device +{ + TAILQ_ENTRY(onewire_device) d_list; + struct device * d_dev; /* may be NULL */ + uint64_t d_rom; + int d_present; +}; + +struct owbus_softc +{ + struct mtx sc_mtx; /* bus mutex */ + device_t sc_busdev; /* bus device */ + device_t sc_owner; /* bus owner */ + device_t sc_dev; /* driver device */ + struct proc *sc_p; + uint64_t sc_rombuf[ONEWIRE_MAXDEVS]; + TAILQ_HEAD(, onewire_device) sc_devs; +}; + +static int owbus_probe(device_t); +static int owbus_attach(device_t); +static int owbus_detach(device_t); + +static void owbus_lock_bus(device_t); +static void owbus_unlock_bus(device_t); +static int owbus_reset(device_t); +static int owbus_bit(device_t, int); +static int owbus_read_byte(device_t); +static void owbus_write_byte(device_t, int); +static void owbus_read_block(device_t, void *, int); +static void owbus_write_block(device_t, const void *, int); +static int owbus_triplet(device_t, int); +static void owbus_matchrom(device_t, uint64_t); +static int owbus_search(device_t, uint64_t *, int, uint64_t); + +static void owbus_thread(void *); +static void owbus_scan(struct owbus_softc *); + +static int +owbus_probe(device_t dev) +{ + device_set_desc(dev, "onewire bus"); + return (0); +} + +static int +owbus_attach(device_t dev) +{ + struct owbus_softc *sc = OWBUS_SOFTC(dev); + + sc->sc_busdev = dev; + sc->sc_dev = device_get_parent(dev); + OWBUS_LOCK_INIT(sc); + TAILQ_INIT(&sc->sc_devs); + + kproc_create(&owbus_thread, sc, &sc->sc_p, 0, 0, "%s scan", device_get_nameunit(dev)); + + return (bus_generic_attach(dev)); +} + +int +owbus_detach(struct device *dev) +{ + struct owbus_softc *sc = OWBUS_SOFTC(dev); + + OWBUS_LOCK_DESTROY(sc); + + return (0); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110062131.p96LVMZq078588>