Dallas Semiconductor 1-Wire bus support, from OpenBSD. Currently includes

gpioow(4), attaching a bit-banging driver via a GPIO pin.  Also,
owtemp(4) which supports some of the 1-Wire temperature sensors, including
the DS18b20 and DS1920 - temperatures are returned via the envsys(4)
framework.

Original drivers by Alexander Yurchenko (grange@openbsd), with envsys(4)
support and a fix to the 1-wire search algorithm (for discovering
devices on the bus) by me.

As discussed on tech-kern earlier this week.
This commit is contained in:
riz 2006-04-07 18:55:21 +00:00
parent 5b93dbb4b1
commit 637bfc29f9
22 changed files with 1732 additions and 8 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.873 2006/04/03 08:15:50 scw Exp $
# $NetBSD: mi,v 1.874 2006/04/07 18:55:22 riz Exp $
./etc/mtree/set.man man-sys-root
./usr/share/info/am-utils.info man-amd-info info
./usr/share/info/as.info man-computil-info bfd,info
@ -826,6 +826,7 @@
./usr/share/man/cat4/gphyter.0 man-sys-catman .cat
./usr/share/man/cat4/gpib.0 man-sys-catman .cat
./usr/share/man/cat4/gpio.0 man-sys-catman .cat
./usr/share/man/cat4/gpioow.0 man-sys-catman .cat
./usr/share/man/cat4/gre.0 man-sys-catman .cat
./usr/share/man/cat4/gsip.0 man-sys-catman .cat
./usr/share/man/cat4/gus.0 man-sys-catman .cat
@ -1084,12 +1085,14 @@
./usr/share/man/cat4/oboe.0 man-sys-catman .cat
./usr/share/man/cat4/ofisa.0 man-sys-catman .cat
./usr/share/man/cat4/ohci.0 man-sys-catman .cat
./usr/share/man/cat4/onewire.0 man-sys-catman .cat
./usr/share/man/cat4/oosiop.0 man-sys-catman .cat
./usr/share/man/cat4/opl.0 man-sys-catman .cat
./usr/share/man/cat4/opms.0 man-obsolete obsolete
./usr/share/man/cat4/optiide.0 man-sys-catman .cat
./usr/share/man/cat4/options.0 man-sys-catman .cat
./usr/share/man/cat4/osiop.0 man-sys-catman .cat
./usr/share/man/cat4/owtemp.0 man-sys-catman .cat
./usr/share/man/cat4/pas.0 man-sys-catman .cat
./usr/share/man/cat4/pc532/lpt.0 man-sys-catman .cat
./usr/share/man/cat4/pc532/mem.0 man-sys-catman .cat
@ -3141,6 +3144,7 @@
./usr/share/man/man4/gphyter.4 man-sys-man .man
./usr/share/man/man4/gpib.4 man-sys-man .man
./usr/share/man/man4/gpio.4 man-sys-man .man
./usr/share/man/man4/gpioow.4 man-sys-man .man
./usr/share/man/man4/gre.4 man-sys-man .man
./usr/share/man/man4/gsip.4 man-sys-man .man
./usr/share/man/man4/gus.4 man-sys-man .man
@ -3399,12 +3403,14 @@
./usr/share/man/man4/oboe.4 man-sys-man .man
./usr/share/man/man4/ofisa.4 man-sys-man .man
./usr/share/man/man4/ohci.4 man-sys-man .man
./usr/share/man/man4/onewire.4 man-sys-man .man
./usr/share/man/man4/oosiop.4 man-sys-man .man
./usr/share/man/man4/opl.4 man-sys-man .man
./usr/share/man/man4/opms.4 man-obsolete obsolete
./usr/share/man/man4/optiide.4 man-sys-man .man
./usr/share/man/man4/options.4 man-sys-man .man
./usr/share/man/man4/osiop.4 man-sys-man .man
./usr/share/man/man4/owtemp.4 man-sys-man .man
./usr/share/man/man4/pas.4 man-sys-man .man
./usr/share/man/man4/pc532/lpt.4 man-sys-man .man
./usr/share/man/man4/pc532/mem.4 man-sys-man .man

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.381 2006/04/03 08:15:49 scw Exp $
# $NetBSD: Makefile,v 1.382 2006/04/07 18:55:21 riz Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 adc.4 adt7467c.4 adv.4 \
@ -100,6 +100,9 @@ MAN+= faith.4 gif.4 inet6.4 icmp6.4 ip6.4 ipsec.4 stf.4
MAN+= daic.4 isdntrc.4 isdntel.4 isdnbchan.4 ippp.4 irip.4 isdnctl.4 isdn.4 \
ifpci.4 isic.4 iwic.4 isdncapi.4 iavc.4
# onewire bus and devices
MAN+= gpioow.4 onewire.4 owtemp.4
MLINKS+=ata.4 atabus.4
MLINKS+=audio.4 mixer.4
MLINKS+=audio.4 sound.4

58
share/man/man4/gpioow.4 Normal file
View File

@ -0,0 +1,58 @@
.\" $OpenBSD: gpioow.4,v 1.3 2006/03/06 10:24:46 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.
.\"
.Dd March 4, 2006
.Dt GPIOOW 4
.Os
.Sh NAME
.Nm gpioow
.Nd 1-Wire bus bit-banging through GPIO pin
.Sh SYNOPSIS
.Cd "gpioow* at gpio? offset 0 mask 0x1"
.Cd "onewire* at gpioow?"
.Sh DESCRIPTION
The
.Nm
driver allows bit-banging a 1-Wire bus as a master using one GPIO pin.
The pin is used as a data signal.
The GPIO pin must be able to drive an output and read an input.
.Pp
The pin number is specified in the kernel configuration with the
.Ar offset
locator.
The
.Ar mask
locator should always be 0x1.
.Sh SEE ALSO
.Xr gpio 4 ,
.Xr intro 4 ,
.Xr onewire 4
.Sh HISTORY
The
.Nm
driver first appeared in
.Ox 4.0
and
.Nx 4.0 .
.Sh AUTHORS
.An -nosplit
The
.Nm
driver was written by
.An Alexander Yurchenko Aq grange@openbsd.org
and was ported to
.Nx by
.An Jeff Rizzo Aq riz@NetBSD.org .

74
share/man/man4/onewire.4 Normal file
View File

@ -0,0 +1,74 @@
.\" $OpenBSD: onewire.4,v 1.2 2006/03/06 10:24:46 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.
.\"
.Dd April 4, 2006
.Dt ONEWIRE 4
.Os
.Sh NAME
.Nm onewire
.Nd 1-Wire bus
.Sh SYNOPSIS
.Cd "onewire* at gpioow?"
.Pp
.Cd "option ONEWIREVERBOSE"
.Sh DESCRIPTION
1-Wire bus was originally developed by Dallas Semiconductor for connecting
integrated circuits.
It is commonly used for connecting devices such as electronic keys, EEPROMs,
temperature sensors, real-time clocks, security chips, etc.
.Pp
The
.Nm
driver provides a uniform programming interface layer between
1-Wire master controllers and various 1-Wire slave devices.
Each 1-Wire master controller attaches a
.Nm
framework; several slave devices can then be attached to the
.Nm
bus.
.Pp
The driver supports plugging and unplugging slave devices on the fly.
.Sh SUPPORTED MASTERS
.Bl -tag -width 10n -offset ind -compact
.It Xr gpioow 4
1-Wire bus bit-banging through GPIO pin
.El
.Sh SUPPORTED SLAVES
.Bl -tag -width 10n -offset ind -compact
.It Xr owid 4
ID family type device
.It Xr owtemp 4
temperature family type device
.El
.Sh SEE ALSO
.Xr intro 4
.Sh HISTORY
The
.Nm
driver first appeared in
.Ox 4.0
and
.Nx 4.0 .
.Sh AUTHORS
.An -nosplit
The
.Nm
driver was written by
.An Alexander Yurchenko Aq grange@openbsd.org
and ported to
.Nx
by
.An Jeff Rizzo Aq riz@NetBSD.org .

61
share/man/man4/owtemp.4 Normal file
View File

@ -0,0 +1,61 @@
.\" $OpenBSD: owtemp.4,v 1.3 2006/03/06 10:24:46 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.
.\"
.Dd April 4, 2006
.Dt OWTEMP 4
.Os
.Sh NAME
.Nm owtemp
.Nd 1-Wire temperature family type device
.Sh SYNOPSIS
.Cd "owtemp* at onewire?"
.Sh DESCRIPTION
The
.Nm
driver provides support for the 1-Wire temperature sensor.
The sensor possesses a single temperature value that can be accessed
through the
.Xr envsys 4
interface.
.Pp
The following chips are supported by the driver:
.Pp
.Bl -bullet -compact -offset indent
.It
Maxim/Dallas DS18B20, DS1822, DS1920
.El
.Sh SEE ALSO
.Xr envsys 4 ,
.Xr intro 4 ,
.Xr onewire 4 ,
.Xr envstat 8
.Sh HISTORY
The
.Nm
driver first appeared in
.Ox 4.0
and
.Nx 4.0 .
.Sh AUTHORS
.An -nosplit
The
.Nm
driver was written by
.An Alexander Yurchenko Aq grange@openbsd.org
and was ported to
.Nx
by
.An Jeff Rizzo Aq riz@NetBSD.org .

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.739 2006/04/03 16:08:49 scw Exp $
# $NetBSD: GENERIC,v 1.740 2006/04/07 18:55:22 riz Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.739 $"
#ident "GENERIC-$Revision: 1.740 $"
maxusers 32 # estimated number of users
@ -611,6 +611,12 @@ dpti* at iop? tid 0 # DPT/Adaptec control interface
# GPIO devices
#gpio* at gscpcib?
# 1-Wire support
#gpioow* at gpio? offset 6 mask 0x1 # 1-wire bus bitbanging via gpio
#onewire* at gpioow?
# 1-Wire devices
#owtemp* at onewire? # Temperature sensors
# SCSI Controllers and Devices

View File

@ -1,4 +1,4 @@
# $NetBSD: NET4501,v 1.47 2006/02/05 05:01:55 cube Exp $
# $NetBSD: NET4501,v 1.48 2006/04/07 18:55:22 riz Exp $
#
# NET4501 -- kernel configuration for a Soekris Engineering net4501
# single-board computer.
@ -10,7 +10,7 @@ include "arch/i386/conf/std.i386"
#options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "NET4501-$Revision: 1.47 $"
#ident "NET4501-$Revision: 1.48 $"
maxusers 32 # estimated number of users
@ -202,6 +202,11 @@ pci* at mainbus? bus ?
# PCI bridges
elansc* at pci? dev ? function ? # Elan SC520 System Controller
gpio* at elansc?
#gpioow* at gpio? offset 6 mask 0x1 # 1-wire bus bitbanging via gpio
#onewire* at gpioow?
# 1-Wire devices
#owtemp* at onewire? # Temperature sensors
# ISA bus support
isa0 at mainbus?

View File

@ -1,4 +1,4 @@
# $NetBSD: files,v 1.768 2006/04/07 01:39:13 gdamore Exp $
# $NetBSD: files,v 1.769 2006/04/07 18:55:22 riz Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@ -232,6 +232,7 @@ define atapi { }
define radiodev { }
define gpibdev {[address = -1]}
define gpiobus { }
define onewirebus { }
define pckbport {[slot = -1]}
define pckbport_machdep_cnattach
define firmload
@ -1398,4 +1399,7 @@ include "net/agr/files.agr"
#
# General Purpose Input/Output framework
#
define onewire_bitbang
include "dev/gpio/files.gpio"
include "dev/onewire/files.onewire"

View File

@ -1,7 +1,11 @@
# $NetBSD: files.gpio,v 1.3 2006/02/20 03:18:36 riz Exp $
# $NetBSD: files.gpio,v 1.4 2006/04/07 18:55:21 riz Exp $
define gpio {offset, mask}
device gpio: gpio
attach gpio at gpiobus
file dev/gpio/gpio.c gpio needs-flag
device gpioow: onewirebus, onewire_bitbang
attach gpioow at gpio
file dev/gpio/gpioow.c gpioow

240
sys/dev/gpio/gpioow.c Normal file
View File

@ -0,0 +1,240 @@
/* $NetBSD: gpioow.c,v 1.1 2006/04/07 18:55:21 riz Exp $ */
/* $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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gpioow.c,v 1.1 2006/04/07 18:55:21 riz Exp $");
/*
* 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 *, struct cfdata *, 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);
CFATTACH_DECL(gpioow, sizeof(struct gpioow_softc),
gpioow_match, gpioow_attach, gpioow_detach, gpioow_activate);
extern struct cfdriver gpioow_cd;
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, struct cfdata *cf, void *aux)
{
return 1;
}
void
gpioow_attach(struct device *parent, struct device *self, void *aux)
{
struct gpioow_softc *sc = device_private(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 = device_private(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 = device_private(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);
}

View File

@ -0,0 +1,8 @@
# $NetBSD: Makefile.onewiredevs,v 1.1 2006/04/07 18:55:22 riz Exp $
# $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

View File

@ -0,0 +1,56 @@
# $NetBSD: devlist2h.awk,v 1.1 2006/04/07 18:55:22 riz Exp $
# $OpenBSD: devlist2h.awk,v 1.3 2006/03/10 14:36:32 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\$NetBSD\$\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\$NetBSD\$\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_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
}

View File

@ -0,0 +1,15 @@
# $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
# Temperature family type device
device owtemp: sysmon_envsys
attach owtemp at onewire
file dev/onewire/owtemp.c owtemp

462
sys/dev/onewire/onewire.c Normal file
View File

@ -0,0 +1,462 @@
/* $NetBSD: onewire.c,v 1.1 2006/04/07 18:55:22 riz Exp $ */
/* $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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: onewire.c,v 1.1 2006/04/07 18:55:22 riz Exp $");
/*
* 1-Wire bus driver.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.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_MAXDEVS 8
#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 *, struct cfdata *, 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 *);
CFATTACH_DECL(onewire, sizeof(struct onewire_softc),
onewire_match, onewire_attach, onewire_detach, onewire_activate);
const struct cdevsw onewire_cdevsw = {
noopen, noclose, noread, nowrite, noioctl, nostop, notty,
nopoll, nommap, nokqfilter,
};
extern struct cfdriver onewire_cd;
int
onewire_match(struct device *parent, struct cfdata *cf, void *aux)
{
return 1;
}
void
onewire_attach(struct device *parent, struct device *self, void *aux)
{
struct onewire_softc *sc = device_private(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(onewire_createthread, sc);
}
int
onewire_detach(struct device *self, int flags)
{
struct onewire_softc *sc = device_private(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);
rv = 0; /* XXX riz */
onewire_unlock(sc);
return (rv);
}
int
onewire_activate(struct device *self, enum devact act)
{
struct onewire_softc *sc = device_private(self);
int rv = 0;
switch (act) {
case DVACT_ACTIVATE:
rv = EOPNOTSUPP;
break;
case DVACT_DEACTIVATE:
sc->sc_dying = 1;
break;
}
//return (config_activate_children(self, act));
return rv;
}
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", (uint)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_create1(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, lastd = -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,i0 = -1; i < 64; i++) {
dir = (lastrom >> i) & 0x1;
if (i == lastd)
dir = 1;
else if (i > lastd)
dir = 0;
rv = onewire_triplet(sc, dir);
switch (rv) {
case 0x0:
if (i != lastd) {
if (dir == 0)
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);
}
lastd = i0;
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 != NULL; 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);
}

View File

@ -0,0 +1,81 @@
/* $NetBSD: onewire_bitbang.c,v 1.1 2006/04/07 18:55:22 riz Exp $ */
/* $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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: onewire_bitbang.c,v 1.1 2006/04/07 18:55:22 riz Exp $");
/*
* 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 = 0, 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 = 0, 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);
}

View File

@ -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);
}

View File

@ -0,0 +1,34 @@
$NetBSD: onewiredevs,v 1.1 2006/04/07 18:55:22 riz Exp $
/* $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
family DS1822 0x22 Temperature
family DS18B20 0x28 Temperature

View File

@ -0,0 +1,20 @@
/* $NetBSD: onewiredevs.h,v 1.1 2006/04/07 18:55:22 riz Exp $ */
/*
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* Generated from:
* NetBSD
*/
#define ONEWIRE_FAMILY_DS1990 0x01
#define ONEWIRE_FAMILY_DS1991 0x02
#define ONEWIRE_FAMILY_DS1994 0x04
#define ONEWIRE_FAMILY_DS1993 0x06
#define ONEWIRE_FAMILY_DS1992 0x08
#define ONEWIRE_FAMILY_DS1982 0x09
#define ONEWIRE_FAMILY_DS1995 0x0a
#define ONEWIRE_FAMILY_DS1996 0x0c
#define ONEWIRE_FAMILY_DS1920 0x10
#define ONEWIRE_FAMILY_DS1822 0x22
#define ONEWIRE_FAMILY_DS18B20 0x28

View File

@ -0,0 +1,23 @@
/* $NetBSD: onewiredevs_data.h,v 1.1 2006/04/07 18:55:22 riz Exp $ */
/*
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* Generated from:
* NetBSD
*/
static const struct onewire_family onewire_famtab[] = {
{ ONEWIRE_FAMILY_DS1990, "ID" },
{ ONEWIRE_FAMILY_DS1991, "MultiKey" },
{ ONEWIRE_FAMILY_DS1994, "4kb NVRAM + RTC" },
{ ONEWIRE_FAMILY_DS1993, "4kb NVRAM" },
{ ONEWIRE_FAMILY_DS1992, "1kb NVRAM" },
{ ONEWIRE_FAMILY_DS1982, "1kb EPROM" },
{ ONEWIRE_FAMILY_DS1995, "16kb NVRAM" },
{ ONEWIRE_FAMILY_DS1996, "64kb NVRAM" },
{ ONEWIRE_FAMILY_DS1920, "Temperature" },
{ ONEWIRE_FAMILY_DS1822, "Temperature" },
{ ONEWIRE_FAMILY_DS18B20, "Temperature" },
{ 0, NULL }
};

View File

@ -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_ */

View File

@ -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_ */

294
sys/dev/onewire/owtemp.c Normal file
View File

@ -0,0 +1,294 @@
/* $NetBSD */
/* $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/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <dev/sysmon/sysmonvar.h>
#include <dev/onewire/onewiredevs.h>
#include <dev/onewire/onewirereg.h>
#include <dev/onewire/onewirevar.h>
#define DS_CMD_CONVERT 0x44
#define DS_CMD_READ_SCRATCHPAD 0xbe
struct owtemp_softc {
struct device sc_dev;
void * sc_onewire;
u_int64_t sc_rom;
struct envsys_tre_data sc_sensor[1];
struct envsys_basic_info sc_info[1];
struct sysmon_envsys sc_sysmon;
uint32_t (*sc_owtemp_decode)(const uint8_t *);
int sc_dying;
};
int owtemp_match(struct device *, struct cfdata *, 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 *);
CFATTACH_DECL(owtemp, sizeof(struct owtemp_softc),
owtemp_match, owtemp_attach, owtemp_detach, owtemp_activate);
extern struct cfdriver owtemp_cd;
static const struct onewire_matchfam owtemp_fams[] = {
{ ONEWIRE_FAMILY_DS1920 },
{ ONEWIRE_FAMILY_DS18B20 },
{ ONEWIRE_FAMILY_DS1822 },
};
static const struct envsys_range owtemp_ranges[] = {
{ 0, 1, ENVSYS_STEMP },
{ 1, 0, -1 },
};
static int owtemp_gtredata(struct sysmon_envsys *,
struct envsys_tre_data *);
static int owtemp_streinfo(struct sysmon_envsys *,
struct envsys_basic_info *);
static uint32_t owtemp_decode_ds18b20(const uint8_t *);
static uint32_t owtemp_decode_ds1920(const uint8_t *);
int
owtemp_match(struct device *parent, struct cfdata *cf, 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 = device_private(self);
struct onewire_attach_args *oa = aux;
int ptype;
sc->sc_onewire = oa->oa_onewire;
sc->sc_rom = oa->oa_rom;
switch(ONEWIRE_ROM_FAMILY_TYPE(sc->sc_rom)) {
case ONEWIRE_FAMILY_DS18B20:
case ONEWIRE_FAMILY_DS1822:
sc->sc_owtemp_decode = owtemp_decode_ds18b20;
break;
case ONEWIRE_FAMILY_DS1920:
sc->sc_owtemp_decode = owtemp_decode_ds1920;
break;
}
/* Initialize sensor */
sc->sc_sensor[0].sensor = sc->sc_info[0].sensor = 0;
sc->sc_sensor[0].validflags = ENVSYS_FVALID;
sc->sc_info[0].validflags = ENVSYS_FVALID;
sc->sc_sensor[0].warnflags = ENVSYS_WARN_OK;
sc->sc_sensor[0].units = sc->sc_info[0].units = ENVSYS_STEMP;
if (devprop_get(&sc->sc_dev, "description",
sc->sc_info[0].desc, sizeof(sc->sc_info[0].desc),
&ptype) < 1 ||
ptype != PROP_STRING)
strcpy(sc->sc_info[0].desc, sc->sc_dev.dv_xname);
/* Hook into system monitor. */
sc->sc_sysmon.sme_ranges = owtemp_ranges;
sc->sc_sysmon.sme_sensor_info = sc->sc_info;
sc->sc_sysmon.sme_sensor_data = sc->sc_sensor;
sc->sc_sysmon.sme_cookie = sc;
sc->sc_sysmon.sme_gtredata = owtemp_gtredata;
sc->sc_sysmon.sme_streinfo = owtemp_streinfo;
sc->sc_sysmon.sme_nsensors = 1;
sc->sc_sysmon.sme_envsys_version = 1000;
if (sysmon_envsys_register(&sc->sc_sysmon))
aprint_error("%s: unable to register with sysmon\n",
sc->sc_dev.dv_xname);
#if 0 /* Old OpenBSD code */
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);
#endif
printf("\n");
}
int
owtemp_detach(struct device *self, int flags)
{
struct owtemp_softc *sc = device_private(self);
sysmon_envsys_unregister(&sc->sc_sysmon);
return 0;
}
int
owtemp_activate(struct device *self, enum devact act)
{
struct owtemp_softc *sc = device_private(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, DS_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, DS_CMD_READ_SCRATCHPAD);
onewire_read_block(sc->sc_onewire, data, 9);
#if 0
if (onewire_crc(data, 8) == data[8]) {
sc->sc_sensor.value = 273150000 +
(int)((u_int16_t)data[1] << 8 | data[0]) * 500000;
}
#endif
sc->sc_sensor[0].cur.data_us = sc->sc_owtemp_decode(data);
sc->sc_sensor[0].validflags |= ENVSYS_FCURVALID;
done:
onewire_unlock(sc->sc_onewire);
}
static int
owtemp_gtredata(struct sysmon_envsys *sme, struct envsys_tre_data *tred)
{
struct owtemp_softc *sc = sme->sme_cookie;
owtemp_update(sc);
*tred = sc->sc_sensor[tred->sensor];
return 0;
}
static int
owtemp_streinfo(struct sysmon_envsys *sme, struct envsys_basic_info *binfo)
{
struct owtemp_softc *sc = sme->sme_cookie;
onewire_lock(sc->sc_onewire,0); /* Also locks our instance */
memcpy(sc->sc_info[binfo->sensor].desc, binfo->desc,
sizeof(sc->sc_info[binfo->sensor].desc));
sc->sc_info[binfo->sensor].desc[
sizeof(sc->sc_info[binfo->sensor].desc) - 1] = '\0';
onewire_unlock(sc->sc_onewire);
binfo->validflags = ENVSYS_FVALID;
return 0;
}
static uint32_t
owtemp_decode_ds18b20(const uint8_t *buf)
{
int temp;
/*
* Sign-extend the MSB byte, and add in the fractions of a
* degree contained in the LSB (precision 1/16th DegC).
*/
temp = (int8_t)buf[1];
temp = (temp << 8) | buf[0];
/*
* Conversion to uK is simple.
*/
return (temp * 62500 + 273150000);
}
static uint32_t
owtemp_decode_ds1920(const uint8_t *buf)
{
int temp;
/*
* Sign-extend the MSB byte, and add in the fractions of a
* degree contained in the LSB (precision 1/2 DegC).
*/
temp = (int8_t)buf[1];
temp = (temp << 8) | buf[0];
/* Convert to uK */
return (temp * 500000 + 273150000);
}