Module Name:    src
Committed By:   brad
Date:           Mon Nov  4 20:43:39 UTC 2024

Modified Files:
        src/distrib/sets/lists/man: mi
        src/distrib/sets/lists/manhtml: mi
        src/distrib/sets/lists/modules: mi
        src/share/man/man4: Makefile
        src/sys/dev/i2c: files.i2c
        src/sys/modules: Makefile
Added Files:
        src/share/man/man4: ds2482ow.4
        src/sys/dev/i2c: ds2482ow.c ds2482owreg.h ds2482owvar.h
        src/sys/modules/ds2482ow: Makefile ds2482ow.ioconf

Log Message:
Add a driver for the Maxim DS2482-100 and DS2482-800 I2C to 1-Wire
bridge.

This chip provides a I2C device that then has 1 or 8 1-Wire busses on
the other side.  The 1-Wire buses show up as onewire(4) buses in the
NetBSD.

The chip can be used in situations where:

* You have a I2C bus extended a long distance, say with a LTC4311
  active terminator / extender or one of the differential I2C
  extenders and you would like to have a 1-Wire device on the far end
  and it isn't possible to add wiring to get to the far end.

* You are either out of GPIO pins or the GPIO pins are not reliable
  enough to use gpioow(4), but you do have working I2C.

The DS2482 does all of the 1-Wire signals in hardware and provides for
a couple of pullup options for the 1-Wire devices.

All of the functions of the DS2482-100 and -800 are supported except
for overdrive speed support.  To do this will likely require some API
changes to onewire(4).

Breakout boards exist for the DS2482 for both variants, but they
appear to be more expensive than expected.  The chip itself is quiet
cheap and wasn't all that hard to SMD solder to a board.  No other
components are really needed.

There are other members in the same family, the DS2482-101, DS2484 and
DS2485.  The DS2482-101 has a sleep pin, but from the datasheet
appears to program the same as the -100 variant.  The DS2484 has a
slightly different way to set configuration information and probably
won't quite work with the driver, but isn't far off.  The DS2485 is
very different and would require a new driver to function.


To generate a diff of this commit:
cvs rdiff -u -r1.1789 -r1.1790 src/distrib/sets/lists/man/mi
cvs rdiff -u -r1.11 -r1.12 src/distrib/sets/lists/manhtml/mi
cvs rdiff -u -r1.160 -r1.161 src/distrib/sets/lists/modules/mi
cvs rdiff -u -r1.736 -r1.737 src/share/man/man4/Makefile
cvs rdiff -u -r0 -r1.1 src/share/man/man4/ds2482ow.4
cvs rdiff -u -r0 -r1.1 src/sys/dev/i2c/ds2482ow.c \
    src/sys/dev/i2c/ds2482owreg.h src/sys/dev/i2c/ds2482owvar.h
cvs rdiff -u -r1.126 -r1.127 src/sys/dev/i2c/files.i2c
cvs rdiff -u -r1.292 -r1.293 src/sys/modules/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/modules/ds2482ow/Makefile \
    src/sys/modules/ds2482ow/ds2482ow.ioconf

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/man/mi
diff -u src/distrib/sets/lists/man/mi:1.1789 src/distrib/sets/lists/man/mi:1.1790
--- src/distrib/sets/lists/man/mi:1.1789	Wed Oct 30 18:09:17 2024
+++ src/distrib/sets/lists/man/mi	Mon Nov  4 20:43:38 2024
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1789 2024/10/30 18:09:17 christos Exp $
+# $NetBSD: mi,v 1.1790 2024/11/04 20:43:38 brad Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 ./etc/mtree/set.man				man-sys-root
@@ -1151,6 +1151,7 @@
 ./usr/share/man/cat4/drm.0			man-sys-catman		.cat
 ./usr/share/man/cat4/drum.0			man-sys-catman		.cat
 ./usr/share/man/cat4/drvctl.0			man-sys-catman		.cat
+./usr/share/man/cat4/ds2482ow.0			man-sys-catman		.cat
 ./usr/share/man/cat4/dse.0			man-sys-catman		.cat
 ./usr/share/man/cat4/dtide.0			man-sys-catman		.cat
 ./usr/share/man/cat4/dtv.0			man-sys-catman		.cat
@@ -4717,6 +4718,7 @@
 ./usr/share/man/man4/drm.4			man-sys-man		.man
 ./usr/share/man/man4/drum.4			man-sys-man		.man
 ./usr/share/man/man4/drvctl.4			man-sys-man		.man
+./usr/share/man/man4/ds2482ow.4			man-sys-man		.man
 ./usr/share/man/man4/dse.4			man-sys-man		.man
 ./usr/share/man/man4/dtide.4			man-sys-man		.man
 ./usr/share/man/man4/dtv.4			man-sys-man		.man

Index: src/distrib/sets/lists/manhtml/mi
diff -u src/distrib/sets/lists/manhtml/mi:1.11 src/distrib/sets/lists/manhtml/mi:1.12
--- src/distrib/sets/lists/manhtml/mi:1.11	Wed Oct 30 18:09:17 2024
+++ src/distrib/sets/lists/manhtml/mi	Mon Nov  4 20:43:39 2024
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.11 2024/10/30 18:09:17 christos Exp $
+# $NetBSD: mi,v 1.12 2024/11/04 20:43:39 brad Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -1034,6 +1034,7 @@
 ./usr/share/man/html4/drm.html			man-sys-htmlman		html
 ./usr/share/man/html4/drum.html			man-sys-htmlman		html
 ./usr/share/man/html4/drvctl.html		man-sys-htmlman		html
+./usr/share/man/html4/ds2482ow.html		man-sys-htmlman		html
 ./usr/share/man/html4/dse.html			man-sys-htmlman		html
 ./usr/share/man/html4/dtide.html		man-sys-htmlman		html
 ./usr/share/man/html4/dtv.html			man-sys-htmlman		html

Index: src/distrib/sets/lists/modules/mi
diff -u src/distrib/sets/lists/modules/mi:1.160 src/distrib/sets/lists/modules/mi:1.161
--- src/distrib/sets/lists/modules/mi:1.160	Thu Jul 18 04:28:54 2024
+++ src/distrib/sets/lists/modules/mi	Mon Nov  4 20:43:38 2024
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.160 2024/07/18 04:28:54 rin Exp $
+# $NetBSD: mi,v 1.161 2024/11/04 20:43:38 brad Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -143,6 +143,8 @@
 ./@MODULEDIR@/dm/dm.kmod			modules-base-kernel	lvm,kmod
 ./@MODULEDIR@/drvctl				modules-base-kernel	kmod
 ./@MODULEDIR@/drvctl/drvctl.kmod		modules-base-kernel	kmod
+./@MODULEDIR@/ds2482ow				modules-base-kernel	kmod
+./@MODULEDIR@/ds2482ow/ds2482ow.kmod		modules-base-kernel	kmod
 ./@MODULEDIR@/dtrace				modules-base-kernel	kmod,dtrace
 ./@MODULEDIR@/dtrace/dtrace.kmod		modules-base-kernel	kmod,dtrace
 ./@MODULEDIR@/dtrace_fbt				modules-base-kernel	kmod,dtrace

Index: src/share/man/man4/Makefile
diff -u src/share/man/man4/Makefile:1.736 src/share/man/man4/Makefile:1.737
--- src/share/man/man4/Makefile:1.736	Sun Oct 20 14:22:37 2024
+++ src/share/man/man4/Makefile	Mon Nov  4 20:43:37 2024
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.736 2024/10/20 14:22:37 mlelstv Exp $
+#	$NetBSD: Makefile,v 1.737 2024/11/04 20:43:37 brad Exp $
 #	@(#)Makefile	8.1 (Berkeley) 6/18/93
 
 MAN=	aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
@@ -20,8 +20,8 @@ MAN=	aac.4 ac97.4 acardide.4 aceride.4 a
 	clockctl.4 cmdide.4 cmpci.4 cms.4 cnw.4 \
 	com.4 coram.4 crypto.4 cs80bus.4 cuda.4 cypide.4 cxdtv.4 \
 	ddb.4 ddc.4 dge.4 dk.4 dm.4 dmoverio.4 \
-	dmphy.4 dpt.4 dpti.4 drm.4 drum.4 drvctl.4 dse.4 dtv.4 dtviic.4 \
-	dwctwo.4 \
+	dmphy.4 dpt.4 dpti.4 drm.4 drum.4 drvctl.4 ds2482ow.4 dse.4 dtv.4 \
+	dtviic.4 dwctwo.4 \
 	eap.4 ebus.4 edc.4 elmc.4 emuxki.4 ena.4 envsys.4 ep.4 \
 	eqos.4 esa.4 esiop.4 esm.4 eso.4 et.4 etphy.4 exphy.4 \
 	fd.4 finsio.4 flash.4 fms.4 fss.4 \

Index: src/sys/dev/i2c/files.i2c
diff -u src/sys/dev/i2c/files.i2c:1.126 src/sys/dev/i2c/files.i2c:1.127
--- src/sys/dev/i2c/files.i2c:1.126	Sat Dec  3 01:04:43 2022
+++ src/sys/dev/i2c/files.i2c	Mon Nov  4 20:43:38 2024
@@ -1,4 +1,4 @@
-#	$NetBSD: files.i2c,v 1.126 2022/12/03 01:04:43 brad Exp $
+#	$NetBSD: files.i2c,v 1.127 2024/11/04 20:43:38 brad Exp $
 
 obsolete defflag	opt_i2cbus.h		I2C_SCAN
 define	i2cbus { }
@@ -439,3 +439,8 @@ file dev/i2c/aht20.c				aht20temp
 # Bosch Sensortec BMP280/BME280 Temperature, Humidity and Pressure sensor
 attach	bmx280thp at iic with bmx280thpi2c
 file dev/i2c/bmx280thpi2c.c			bmx280thpi2c
+
+# Maxim DS2482-100 and DS2482-800 I2C to Onewire bridge
+device ds2482ow: onewirebus
+attach ds2482ow at iic
+file dev/i2c/ds2482ow.c				ds2482ow

Index: src/sys/modules/Makefile
diff -u src/sys/modules/Makefile:1.292 src/sys/modules/Makefile:1.293
--- src/sys/modules/Makefile:1.292	Mon Aug 26 13:38:28 2024
+++ src/sys/modules/Makefile	Mon Nov  4 20:43:38 2024
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.292 2024/08/26 13:38:28 riastradh Exp $
+#	$NetBSD: Makefile,v 1.293 2024/11/04 20:43:38 brad Exp $
 
 .include <bsd.own.mk>
 
@@ -60,6 +60,7 @@ SUBDIR+=	dbcool
 SUBDIR+=	des
 SUBDIR+=	dk_subr
 SUBDIR+=	drvctl
+SUBDIR+=	ds2482ow
 SUBDIR+=	efs
 SUBDIR+=	ext2fs
 SUBDIR+=	exec_script

Added files:

Index: src/share/man/man4/ds2482ow.4
diff -u /dev/null src/share/man/man4/ds2482ow.4:1.1
--- /dev/null	Mon Nov  4 20:43:39 2024
+++ src/share/man/man4/ds2482ow.4	Mon Nov  4 20:43:37 2024
@@ -0,0 +1,87 @@
+.\" $NetBSD: ds2482ow.4,v 1.1 2024/11/04 20:43:37 brad Exp $
+.\"
+.\" Copyright (c) 2024 Brad Spencer <b...@anduin.eldar.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 October 31, 2024
+.Dt DS2482OW 4
+.Os
+.Sh NAME
+.Nm ds2482ow
+.Nd Driver for Maxim DS2482-100 and DS2482-800 IC2 to 1-Wire bridge
+.Sh SYNOPSIS
+.Cd "ds2482ow* at iic? addr 0x18"
+.Cd "ds2482ow* at iic? addr 0x19"
+.Cd "ds2482ow* at iic? addr 0x1a"
+.Cd "ds2482ow* at iic? addr 0x1b"
+.Cd "ds2482ow* at iic? addr 0x1c" DS2482-800 only
+.Cd "ds2482ow* at iic? addr 0x1d" DS2482-800 only
+.Cd "ds2482ow* at iic? addr 0x1e" DS2482-800 only
+.Cd "ds2482ow* at iic? addr 0x1f" DS2482-800 only
+.Cd "onewire* at ds2482ow?"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides 1 or 8
+.Xr onewire 4
+busses via an I2C interface.
+The
+.Nm
+.Ar addr
+argument selects the address at the
+.Xr iic 4
+bus.
+The chip generates all of the needed 1-Wire pulses on its own
+and provides for the pullup needed on the 1-Wire data line.
+The method that the chip uses for pullup can be changed through
+.Xr sysctl 8
+nodes.
+.Sh SYSCTL VARIABLES
+The following
+.Xr sysctl 3
+variables are provided:
+.Bl -tag -width indent
+.It Li hw.ds2482ow0.pullup.active
+If true, turn on active pullup on all channels supported by the chip.
+.It Li hw.ds2482ow0.pullup.strong
+If true, turn on strong pullup on all channels that the chip supports
+and on the DS2482-100 chip, allow the PCTLZ pin to provide addition
+current to the 1-Wire bus.  This mode conflicts with a 1-Wire reset
+and will be disabled if that command is sent to the 1-Wire bus.
+
+.It Li If neither active pullup or strong pullup are enabled the chip will
+use an internal passive resister.
+.It Li hw.ds2482ow0.debug
+If the driver is compiled with
+.Dv DS2482_DEBUG ,
+this node will appear and can be used to set the debugging level.
+.El
+.Sh SEE ALSO
+.Xr onewire 4 ,
+.Xr iic 4 ,
+.Xr sysctl 8
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Nx 11.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Brad Spencer Aq Mt b...@anduin.eldar.org .
+.Sh BUGS
+The DS2482 chip supports overdrive speed on a 1-Wire bus.
+This driver does not support overdrive speed mode.

Index: src/sys/dev/i2c/ds2482ow.c
diff -u /dev/null src/sys/dev/i2c/ds2482ow.c:1.1
--- /dev/null	Mon Nov  4 20:43:39 2024
+++ src/sys/dev/i2c/ds2482ow.c	Mon Nov  4 20:43:38 2024
@@ -0,0 +1,746 @@
+/*	$NetBSD: ds2482ow.c,v 1.1 2024/11/04 20:43:38 brad Exp $	*/
+
+/*
+ * Copyright (c) 2024 Brad Spencer <b...@anduin.eldar.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: ds2482ow.c,v 1.1 2024/11/04 20:43:38 brad Exp $");
+
+/*
+  Driver for the DS2482-100 and DS2482-800 I2C to Onewire bridge
+*/
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+#include <sys/mutex.h>
+
+#include <dev/i2c/i2cvar.h>
+#include <dev/onewire/onewirevar.h>
+#include <dev/i2c/ds2482owreg.h>
+#include <dev/i2c/ds2482owvar.h>
+
+#define DS2482_ONEWIRE_SINGLE_BIT_READ	0xF7 /* Artifical */
+#define DS2482_ONEWIRE_SINGLE_BIT_WRITE	0xF8 /* Artifical */
+
+static int 	ds2482_poke(i2c_tag_t, i2c_addr_t, bool);
+static int 	ds2482_match(device_t, cfdata_t, void *);
+static void 	ds2482_attach(device_t, device_t, void *);
+static int 	ds2482_detach(device_t, int);
+static int 	ds2482_verify_sysctl(SYSCTLFN_ARGS);
+
+static int	ds2482_ow_reset(void *);
+static int	ds2482_ow_read_bit(void *);
+static void	ds2482_ow_write_bit(void *, int);
+static int	ds2482_ow_read_byte(void *);
+static void	ds2482_ow_write_byte(void *, int);
+static int	ds2482_ow_triplet(void *, int);
+
+#define DS2482_DEBUG
+
+#ifdef DS2482_DEBUG
+#define DPRINTF(s, l, x) \
+    do { \
+	if (l <= s->sc_ds2482debug) \
+	    aprint_normal x; \
+    } while (/*CONSTCOND*/0)
+#else
+#define DPRINTF(s, l, x)
+#endif
+
+#ifdef DS2482_DEBUG
+#define DPRINTF2(dl, l, x)			\
+    do { \
+	if (l <= dl) \
+	    aprint_normal x; \
+    } while (/*CONSTCOND*/0)
+#else
+#define DPRINTF2(dl, l, x)
+#endif
+
+CFATTACH_DECL_NEW(ds2482ow, sizeof(struct ds2482ow_sc),
+    ds2482_match, ds2482_attach, ds2482_detach, NULL);
+
+
+#define DS2482_QUICK_DELAY 18
+#define DS2482_SLOW_DELAY 35
+
+int
+ds2482_verify_sysctl(SYSCTLFN_ARGS)
+{
+	int error, t;
+	struct sysctlnode node;
+
+	node = *rnode;
+	t = *(int *)rnode->sysctl_data;
+	node.sysctl_data = &t;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error || newp == NULL)
+		return error;
+
+	if (t < 0)
+		return EINVAL;
+
+	*(int *)rnode->sysctl_data = t;
+
+	return 0;
+}
+
+static int
+ds2482_set_pullup(i2c_tag_t tag, i2c_addr_t addr, bool activepullup,
+    bool strongpullup, int debuglevel)
+{
+	int error;
+	uint8_t cmd = DS2482_WRITE_CONFIG;
+	uint8_t pu = 0;
+	uint8_t pux;
+
+	if (activepullup == true)
+		pu = pu | DS2482_CONFIG_APU;
+	if (strongpullup == true)
+		pu = pu | DS2482_CONFIG_SPU;
+
+	/* The Write Config command wants the top bits of the config buffer to be
+	 * the ones complement of the lower bits.
+	 */
+
+	pux = ~(pu << 4);
+	pux = pux & 0xf0;
+	pu = pu | pux;
+
+	error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &cmd, 1, &pu, 1, 0);
+
+	DPRINTF2(debuglevel, 4, ("ds2482_set_pullup: pu: %02x ; error: %x %d\n", pu, error, error));
+
+	return error;
+}
+
+static int
+ds2482_wait_with_status(i2c_tag_t tag, i2c_addr_t addr, uint8_t *status,
+    unsigned int d, bool set_pointer, int debuglevel)
+{
+	int error = 0;
+	uint8_t xcmd, xbuf;
+
+	DPRINTF2(debuglevel, 5, ("ds2482_wait_with_status: start\n"));
+
+	xcmd = DS2482_SET_READ_POINTER;
+	xbuf = DS2482_REGISTER_STATUS;
+	if (set_pointer == true)
+		error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &xcmd, 1, &xbuf, 1, 0);
+	if (! error) {
+		error = iic_exec(tag, I2C_OP_READ, addr, NULL, 0, status, 1, 0);
+		if ((*status & DS2482_STATUS_1WB) && (! error)) {
+			do {
+				delay(d);
+				error = iic_exec(tag, I2C_OP_READ, addr, NULL, 0, status, 1, 0);
+			} while ((*status & DS2482_STATUS_1WB) &&
+			    (! error));
+		}
+	}
+
+	DPRINTF2(debuglevel, 5, ("ds2482_wait_with_status: end ; status: %02x %d ; error: %x %d\n", *status, *status, error, error));
+
+	return error;
+}
+
+static int
+ds2482_cmd(i2c_tag_t tag, i2c_addr_t addr, uint8_t *cmd,
+    uint8_t *cmdarg, uint8_t *obuf, size_t obuflen, bool activepullup,
+    bool strongpullup, int debuglevel)
+{
+	int error;
+	uint8_t xcmd;
+	uint8_t xbuf;
+
+	switch (*cmd) {
+		/* The datasheet says that none of these are effected by what sort of pullup
+		 * is set and only the Write Config command needs to happen when idle.
+		 */
+	case DS2482_SET_READ_POINTER:
+	case DS2482_WRITE_CONFIG:
+	case DS2482_SELECT_CHANNEL:
+		KASSERT(cmdarg != NULL);
+
+		error = 0;
+
+		if (*cmd == DS2482_WRITE_CONFIG)
+			error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_QUICK_DELAY, true, debuglevel);
+
+		if (! error)
+			error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, cmd, 1, cmdarg, 1, 0);
+
+		DPRINTF2(debuglevel, 4, ("ds2482_cmd: cmd: %02x ; error: %x %d\n", *cmd, error, error));
+
+		break;
+
+
+	case DS2482_DEVICE_RESET:
+	case DS2482_ONEWIRE_RESET:
+		/* Device reset resets everything, including pullup
+		 * configuration settings, but that doesn't matter as we will
+		 * always set the config before doing anything that actions on
+		 * the 1-Wire bus.
+		 *
+		 * The data sheet warns about using the strong pull up feature
+		 * with a 1-Wire reset, so we will simply not allow that
+		 * combination.
+		 *
+		 * The data sheet does not mention if the 1-Wire reset effects
+		 * just a single channel all channels.  It seems likely that it
+		 * is the currently active channel, and the driver works on that
+		 * assumption.
+		*/
+
+		error = 0;
+		if (*cmd == DS2482_ONEWIRE_RESET) {
+			error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_QUICK_DELAY, true, debuglevel);
+			if (! error)
+				error = ds2482_set_pullup(tag, addr, activepullup, false, debuglevel);
+		}
+
+		if (! error)
+			error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, cmd, 1, NULL, 0, 0);
+
+		DPRINTF2(debuglevel, 4, ("ds2482_cmd: cmd: %02x ; error: %x %d\n", *cmd, error, error));
+
+		if (*cmd == DS2482_DEVICE_RESET)
+			delay(1);
+		if (*cmd == DS2482_ONEWIRE_RESET)
+			delay(1300);
+
+		break;
+
+	case DS2482_ONEWIRE_SINGLE_BIT_WRITE:
+		KASSERT(cmdarg != NULL);
+
+		DPRINTF2(debuglevel, 4, ("ds2482_cmd: DS2482_ONEWIRE_SINGLE_BIT_WRITE: cmdarg: %02x %d\n", *cmdarg, *cmdarg));
+
+		xcmd = DS2482_SET_READ_POINTER;
+		xbuf = DS2482_REGISTER_STATUS;
+		error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &xcmd, 1, &xbuf, 1, 0);
+		if (! error)
+			error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_QUICK_DELAY, false, debuglevel);
+
+		if (! error) {
+			xcmd = DS2482_ONEWIRE_SINGLE_BIT;
+			xbuf = DS2482_ONEWIRE_BIT_ZERO;
+			if (*cmdarg & 0x01)
+				xbuf = DS2482_ONEWIRE_BIT_ONE;
+			error = ds2482_set_pullup(tag, addr, activepullup, strongpullup, debuglevel);
+			if (! error)
+				error = iic_exec(tag, I2C_OP_WRITE, addr, &xcmd, 1, &xbuf, 1, 0);
+			if (! error) {
+				xbuf = 0xff;
+				error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_SLOW_DELAY, false, debuglevel);
+			}
+		}
+		break;
+
+	case DS2482_ONEWIRE_SINGLE_BIT_READ:
+		KASSERT(obuf != NULL);
+		KASSERT(obuflen == 1);
+
+		DPRINTF2(debuglevel, 4, ("ds2482_cmd: DS2482_ONEWIRE_SINGLE_BIT_READ\n"));
+
+		xcmd = DS2482_SET_READ_POINTER;
+		xbuf = DS2482_REGISTER_STATUS;
+		error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &xcmd, 1, &xbuf, 1, 0);
+		if (! error)
+			error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_QUICK_DELAY, false, debuglevel);
+
+		if (! error) {
+			xcmd = DS2482_ONEWIRE_SINGLE_BIT;
+			xbuf = DS2482_ONEWIRE_BIT_ONE;
+			error = ds2482_set_pullup(tag, addr, activepullup, strongpullup, debuglevel);
+			if (! error)
+				error = iic_exec(tag, I2C_OP_WRITE, addr, &xcmd, 1, &xbuf, 1, 0);
+			if (! error) {
+				xbuf = 0xff;
+				error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_SLOW_DELAY, false, debuglevel);
+				if (! error) {
+					*obuf = (xbuf & DS2482_STATUS_SBR) >> DS2482_STATUS_SBR_SHIFT;
+				}
+			}
+		}
+		break;
+
+	case DS2482_ONEWIRE_WRITE_BYTE:
+		KASSERT(cmdarg != NULL);
+
+		DPRINTF2(debuglevel, 4, ("ds2482_cmd: DS2482_ONEWIRE_WRITE_BYTE: cmdarg: %02x %d\n", *cmdarg, *cmdarg));
+
+		xcmd = DS2482_SET_READ_POINTER;
+		xbuf = DS2482_REGISTER_STATUS;
+		error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &xcmd, 1, &xbuf, 1, 0);
+		if (! error)
+			error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_QUICK_DELAY, false, debuglevel);
+
+		if (! error) {
+			error = ds2482_set_pullup(tag, addr, activepullup, strongpullup, debuglevel);
+			if (! error)
+				error = iic_exec(tag, I2C_OP_WRITE, addr, cmd, 1, cmdarg, 1, 0);
+			if (! error) {
+				xbuf = 0xff;
+				error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_SLOW_DELAY, false, debuglevel);
+			}
+		}
+		break;
+
+	case DS2482_ONEWIRE_READ_BYTE:
+		KASSERT(obuf != NULL);
+		KASSERT(obuflen == 1);
+
+		DPRINTF2(debuglevel, 4, ("ds2482_cmd: DS2482_ONEWIRE_READ_BYTE\n"));
+
+		xcmd = DS2482_SET_READ_POINTER;
+		xbuf = DS2482_REGISTER_STATUS;
+		error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &xcmd, 1, &xbuf, 1, 0);
+		if (! error)
+			error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_QUICK_DELAY, false, debuglevel);
+
+		if (! error) {
+			error = ds2482_set_pullup(tag, addr, activepullup, strongpullup, debuglevel);
+			if (! error)
+				error = iic_exec(tag, I2C_OP_WRITE, addr, cmd, 1, NULL, 0, 0);
+			if (! error) {
+				xbuf = 0xff;
+				error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_SLOW_DELAY, false, debuglevel);
+				if (! error) {
+					xcmd = DS2482_SET_READ_POINTER;
+					xbuf = DS2482_REGISTER_DATA;
+					error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &xcmd, 1, &xbuf, 1, 0);
+					if (! error) {
+						xbuf = 0xff;
+						error = iic_exec(tag, I2C_OP_READ_WITH_STOP, addr, NULL, 0, &xbuf, 1, 0);
+						if (! error) {
+							*obuf = xbuf;
+						}
+					}
+				}
+			}
+		}
+		break;
+
+	case DS2482_ONEWIRE_TRIPLET:
+		KASSERT(cmdarg != NULL);
+		KASSERT(obuf != NULL);
+		KASSERT(obuflen == 1);
+
+		DPRINTF2(debuglevel, 4, ("ds2482_cmd: DS2482_ONEWIRE_TRIPLET: cmdarg: %02x %d\n", *cmdarg, *cmdarg));
+
+		xcmd = DS2482_SET_READ_POINTER;
+		xbuf = DS2482_REGISTER_STATUS;
+		error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &xcmd, 1, &xbuf, 1, 0);
+		if (! error)
+			error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_QUICK_DELAY, false, debuglevel);
+
+		if (! error) {
+			xbuf = DS2482_TRIPLET_DIR_ZERO;
+			if (*cmdarg & 0x01) {
+				xbuf = DS2482_TRIPLET_DIR_ONE;
+			}
+			error = ds2482_set_pullup(tag, addr, activepullup, strongpullup, debuglevel);
+			if (! error)
+				error = iic_exec(tag, I2C_OP_WRITE, addr, cmd, 1, &xbuf, 1, 0);
+			if (! error) {
+				xbuf = 0xff;
+				error = ds2482_wait_with_status(tag, addr, &xbuf, DS2482_SLOW_DELAY, false, debuglevel);
+				if (! error) {
+					/* This is undocumented anywhere I could find, but what has to be returned is
+					 * 0x01 is the triplet path was taken, 0x02 is the Not-triplet path was taken,
+					 * and 0x00 is neither was taken.  The DIR bit in the status of the DS2482 may
+					 * help with this some, but what is below seems to work.
+					 */
+					*obuf = 0;
+					if (xbuf & DS2482_STATUS_TSB) {
+						*obuf = 0x01;
+					} else {
+						if (xbuf & DS2482_STATUS_SBR) {
+							*obuf = 0x02;
+						}
+					}
+				}
+			}
+		}
+
+		break;
+
+	default:
+		error = EINVAL;
+		break;
+	}
+
+	return error;
+}
+
+static int
+ds2482_cmdr(struct ds2482ow_sc *sc, uint8_t cmd, uint8_t cmdarg, uint8_t *buf, size_t blen)
+{
+	DPRINTF(sc, 3, ("%s: ds2482_cmdr: cmd: %02x\n",
+	    device_xname(sc->sc_dev), cmd));
+	return ds2482_cmd(sc->sc_tag, sc->sc_addr, &cmd, &cmdarg, buf, blen, sc->sc_activepullup, sc->sc_strongpullup, sc->sc_ds2482debug);
+}
+
+static const uint8_t ds2482_channels[] = {
+	DS2482_CHANNEL_IO0,
+	DS2482_CHANNEL_IO1,
+	DS2482_CHANNEL_IO2,
+	DS2482_CHANNEL_IO3,
+	DS2482_CHANNEL_IO4,
+	DS2482_CHANNEL_IO5,
+	DS2482_CHANNEL_IO6,
+	DS2482_CHANNEL_IO7
+};
+
+static int
+ds2482_set_channel(struct ds2482ow_sc *sc, int channel)
+{
+	int error = 0;
+
+	KASSERT(channel >= 0 && channel < DS2482_NUM_INSTANCES);
+
+	if (sc->sc_is_800 == true)
+		error = ds2482_cmdr(sc, DS2482_SELECT_CHANNEL, ds2482_channels[channel], NULL, 0);
+
+	return error;
+}
+
+static int
+ds2482_poke(i2c_tag_t tag, i2c_addr_t addr, bool matchdebug)
+{
+	uint8_t reg = DS2482_SET_READ_POINTER;
+	uint8_t rbuf = DS2482_REGISTER_STATUS;
+	uint8_t obuf;
+	int error;
+
+	error = ds2482_cmd(tag, addr, &reg, &rbuf, &obuf, 1, false, false, 0);
+	if (matchdebug) {
+		printf("poke X 1: %d\n", error);
+	}
+	return error;
+}
+
+static int
+ds2482_match(device_t parent, cfdata_t match, void *aux)
+{
+	struct i2c_attach_args *ia = aux;
+	int error, match_result;
+	const bool matchdebug = false;
+
+	if (iic_use_direct_match(ia, match, NULL, &match_result))
+		return match_result;
+
+	/* indirect config - check for configured address */
+	if (!(ia->ia_addr >= DS2482_LOWEST_ADDR &&
+	    ia->ia_addr <= DS2482_HIGHEST_ADDR))
+		return 0;
+
+	/*
+	 * Check to see if something is really at this i2c address. This will
+	 * keep phantom devices from appearing
+	 */
+	if (iic_acquire_bus(ia->ia_tag, 0) != 0) {
+		if (matchdebug)
+			printf("in match acquire bus failed\n");
+		return 0;
+	}
+
+	error = ds2482_poke(ia->ia_tag, ia->ia_addr, matchdebug);
+	iic_release_bus(ia->ia_tag, 0);
+
+	return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
+}
+
+static void
+ds2482_attach(device_t parent, device_t self, void *aux)
+{
+	struct ds2482ow_sc *sc;
+	struct i2c_attach_args *ia;
+	int error, i, num_channels = 1;
+	struct onewirebus_attach_args oba;
+	const struct sysctlnode *cnode;
+	int sysctlroot_num, pullup_num;
+
+	ia = aux;
+	sc = device_private(self);
+
+	sc->sc_dev = self;
+	sc->sc_tag = ia->ia_tag;
+	sc->sc_addr = ia->ia_addr;
+	sc->sc_ds2482debug = 0;
+	sc->sc_activepullup = false;
+	sc->sc_strongpullup = false;
+	sc->sc_is_800 = false;
+
+	aprint_normal("\n");
+
+	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE);
+
+	if ((error = sysctl_createv(&sc->sc_ds2482log, 0, NULL, &cnode,
+	    0, CTLTYPE_NODE, device_xname(sc->sc_dev),
+	    SYSCTL_DESCR("DS2482 controls"), NULL, 0, NULL, 0, CTL_HW,
+	    CTL_CREATE, CTL_EOL)) != 0)
+		goto out;
+
+	sysctlroot_num = cnode->sysctl_num;
+
+#ifdef DS2482_DEBUG
+	if ((error = sysctl_createv(&sc->sc_ds2482log, 0, NULL, &cnode,
+	    CTLFLAG_READWRITE, CTLTYPE_INT, "debug",
+	    SYSCTL_DESCR("Debug level"), ds2482_verify_sysctl, 0,
+	    &sc->sc_ds2482debug, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
+	    CTL_EOL)) != 0)
+		goto out;
+#endif
+
+	if ((error = sysctl_createv(&sc->sc_ds2482log, 0, NULL, &cnode,
+	    0, CTLTYPE_NODE, "pullup",
+	    SYSCTL_DESCR("Pullup controls"), NULL, 0, NULL, 0, CTL_HW,
+	    sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
+		goto out;
+
+	pullup_num = cnode->sysctl_num;
+
+	if ((error = sysctl_createv(&sc->sc_ds2482log, 0, NULL, &cnode,
+	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "active",
+	    SYSCTL_DESCR("Active pullup"), NULL, 0, &sc->sc_activepullup,
+	    0, CTL_HW, sysctlroot_num, pullup_num, CTL_CREATE, CTL_EOL)) != 0)
+		goto out;
+
+	if ((error = sysctl_createv(&sc->sc_ds2482log, 0, NULL, &cnode,
+	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "strong",
+	    SYSCTL_DESCR("Strong pullup"), NULL, 0, &sc->sc_strongpullup,
+	    0, CTL_HW, sysctlroot_num, pullup_num, CTL_CREATE, CTL_EOL)) != 0)
+		goto out;
+
+	error = iic_acquire_bus(sc->sc_tag, 0);
+	if (error) {
+		aprint_error_dev(self, "Could not acquire iic bus: %d\n",
+		    error);
+		goto out;
+	}
+
+	error = ds2482_cmdr(sc, DS2482_DEVICE_RESET, 0, NULL, 0);
+	if (error != 0)
+		aprint_error_dev(self, "Reset failed: %d\n", error);
+
+	if (! error) {
+		int xerror;
+		xerror = ds2482_cmdr(sc, DS2482_SELECT_CHANNEL, DS2482_CHANNEL_IO0, NULL, 0);
+		if (! xerror)
+			sc->sc_is_800 = true;
+	}
+
+	iic_release_bus(sc->sc_tag, 0);
+
+	if (error != 0) {
+		aprint_error_dev(self, "Unable to setup device\n");
+		goto out;
+	}
+
+	if (sc->sc_is_800 == true) {
+		num_channels = DS2482_NUM_INSTANCES;
+	}
+
+	aprint_normal_dev(self, "Maxim DS2482-%s I2C to 1-Wire bridge, Channels available: %d\n",
+	    (sc->sc_is_800 == true) ? "800" : "100",
+	    num_channels);
+
+	for(i = 0;i < num_channels;i++) {
+		sc->sc_instances[i].sc_i_channel = i;
+		sc->sc_instances[i].sc = sc;
+		sc->sc_instances[i].sc_i_ow_bus.bus_cookie = &sc->sc_instances[i];
+		sc->sc_instances[i].sc_i_ow_bus.bus_reset = ds2482_ow_reset;
+		sc->sc_instances[i].sc_i_ow_bus.bus_read_bit = ds2482_ow_read_bit;
+		sc->sc_instances[i].sc_i_ow_bus.bus_write_bit = ds2482_ow_write_bit;
+		sc->sc_instances[i].sc_i_ow_bus.bus_read_byte = ds2482_ow_read_byte;
+		sc->sc_instances[i].sc_i_ow_bus.bus_write_byte = ds2482_ow_write_byte;
+		sc->sc_instances[i].sc_i_ow_bus.bus_triplet = ds2482_ow_triplet;
+
+		memset(&oba, 0, sizeof(oba));
+		oba.oba_bus = &sc->sc_instances[i].sc_i_ow_bus;
+		sc->sc_instances[i].sc_i_ow_dev = config_found(self, &oba, onewirebus_print, CFARGS_NONE);
+	}
+
+out:
+	return;
+}
+
+/* Hmmm...  except in the case of reset, there really doesn't seem to be any
+ * way with the onewire(4) API to indicate an error condition.
+*/
+
+static int
+ds2482_generic_action(struct ds2482_instance *sci, uint8_t cmd, uint8_t cmdarg, uint8_t *buf, size_t blen)
+{
+	struct ds2482ow_sc *sc = sci->sc;
+	int rv;
+
+	mutex_enter(&sc->sc_mutex);
+	rv = iic_acquire_bus(sc->sc_tag, 0);
+	if (!rv) {
+		rv = ds2482_set_channel(sc, sci->sc_i_channel);
+		if (!rv)
+			rv = ds2482_cmdr(sc, cmd, cmdarg, buf, blen);
+	}
+	iic_release_bus(sc->sc_tag, 0);
+	mutex_exit(&sc->sc_mutex);
+
+	return rv;
+}
+
+static int
+ds2482_ow_reset(void *arg)
+{
+	struct ds2482_instance *sci = arg;
+	struct ds2482ow_sc *sc = sci->sc;
+	int rv;
+
+	rv = ds2482_generic_action(sci, DS2482_ONEWIRE_RESET, 0, NULL, 0);
+
+	DPRINTF(sc, 3, ("%s: ds2482_ow_reset: channel: %d ; rv: %x %d\n",
+	    device_xname(sc->sc_dev), sci->sc_i_channel, rv, rv));
+
+	return rv;
+}
+
+static int
+ds2482_ow_read_bit(void *arg)
+{
+	struct ds2482_instance *sci = arg;
+	struct ds2482ow_sc *sc = sci->sc;
+	int rv;
+	uint8_t buf = 0x55;
+
+	rv = ds2482_generic_action(sci, DS2482_ONEWIRE_SINGLE_BIT_READ, 0, &buf, 1);
+
+	DPRINTF(sc, 3, ("%s: ds2482_read_bit: channel: %d ; rv: %x %d ; buf: %02x %d\n",
+	    device_xname(sc->sc_dev), sci->sc_i_channel, rv, rv, buf, buf));
+
+	return (int)buf;
+}
+
+static void
+ds2482_ow_write_bit(void *arg, int value)
+{
+	struct ds2482_instance *sci = arg;
+	struct ds2482ow_sc *sc = sci->sc;
+	int rv;
+
+	rv = ds2482_generic_action(sci, DS2482_ONEWIRE_SINGLE_BIT_WRITE, (uint8_t)value, NULL, 0);
+
+	DPRINTF(sc, 3, ("%s: ds2482_write_bit: channel: %d ; rv: %x %d ; value: %02x %d\n",
+	    device_xname(sc->sc_dev), sci->sc_i_channel, rv, rv, (uint8_t)value, (uint8_t)value));
+
+	return;
+}
+
+static int
+ds2482_ow_read_byte(void *arg)
+{
+	struct ds2482_instance *sci = arg;
+	uint8_t buf = 0x55;
+	struct ds2482ow_sc *sc = sci->sc;
+	int rv;
+
+	rv = ds2482_generic_action(sci, DS2482_ONEWIRE_READ_BYTE, 0, &buf, 1);
+
+	DPRINTF(sc, 3, ("%s: ds2482_read_byte: channel: %d ; rv: %x %d ; buf: %02x %d\n",
+	    device_xname(sc->sc_dev), sci->sc_i_channel, rv, rv, buf, buf));
+
+	return (int)buf;
+}
+
+static void
+ds2482_ow_write_byte(void *arg, int value)
+{
+	struct ds2482_instance *sci = arg;
+	struct ds2482ow_sc *sc = sci->sc;
+	int rv;
+
+	rv = ds2482_generic_action(sci, DS2482_ONEWIRE_WRITE_BYTE, (uint8_t)value, NULL, 0);
+
+	DPRINTF(sc, 3, ("%s: ds2482_write_byte: channel: %d ; rv: %x %d ; value: %02x %d\n",
+	    device_xname(sc->sc_dev), sci->sc_i_channel, rv, rv, (uint8_t)value, (uint8_t)value));
+
+	return;
+}
+
+static int
+ds2482_ow_triplet(void *arg, int dir)
+{
+	struct ds2482_instance *sci = arg;
+	uint8_t buf = 0x55;
+	struct ds2482ow_sc *sc = sci->sc;
+	int rv;
+
+	rv = ds2482_generic_action(sci, DS2482_ONEWIRE_TRIPLET, (uint8_t) dir, &buf, 1);
+
+	DPRINTF(sc, 3, ("%s: ds2482_triplet: channel: %d ; rv: %x %d ; dir: %x %d ; buf: %02x %d\n",
+	    device_xname(sc->sc_dev), sci->sc_i_channel, rv, rv, dir, dir, (uint8_t)buf, (uint8_t)buf));
+
+	return (int)buf;
+}
+
+static int
+ds2482_detach(device_t self, int flags)
+{
+	struct ds2482ow_sc *sc;
+
+	sc = device_private(self);
+
+	/* Remove the sysctl tree */
+	sysctl_teardown(&sc->sc_ds2482log);
+
+	/* Remove the mutex */
+	mutex_destroy(&sc->sc_mutex);
+
+	return 0;
+}
+
+MODULE(MODULE_CLASS_DRIVER, ds2482ow, "iic,onewire");
+
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+
+static int
+ds2482ow_modcmd(modcmd_t cmd, void *opaque)
+{
+
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+#ifdef _MODULE
+		return config_init_component(cfdriver_ioconf_ds2482ow,
+		    cfattach_ioconf_ds2482ow, cfdata_ioconf_ds2482ow);
+#else
+		return 0;
+#endif
+	case MODULE_CMD_FINI:
+#ifdef _MODULE
+		return config_fini_component(cfdriver_ioconf_ds2482ow,
+		      cfattach_ioconf_ds2482ow, cfdata_ioconf_ds2482ow);
+#else
+		return 0;
+#endif
+	default:
+		return ENOTTY;
+	}
+}
Index: src/sys/dev/i2c/ds2482owreg.h
diff -u /dev/null src/sys/dev/i2c/ds2482owreg.h:1.1
--- /dev/null	Mon Nov  4 20:43:39 2024
+++ src/sys/dev/i2c/ds2482owreg.h	Mon Nov  4 20:43:38 2024
@@ -0,0 +1,63 @@
+/*	$NetBSD: ds2482owreg.h,v 1.1 2024/11/04 20:43:38 brad Exp $	*/
+
+/*
+ * Copyright (c) 2024 Brad Spencer <b...@anduin.eldar.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_I2C_DS2482REG_H_
+#define _DEV_I2C_DS2482REG_H_
+
+#define DS2482_LOWEST_ADDR		0x18
+#define DS2482_HIGHEST_ADDR		0x1F
+
+#define DS2482_DEVICE_RESET		0xF0
+#define DS2482_SET_READ_POINTER		0xE1
+#define 	DS2482_REGISTER_STATUS	0xF0
+#define			DS2482_STATUS_1WB	0x01
+#define			DS2482_STATUS_PPD	0x02
+#define			DS2482_STATUS_SD	0x04
+#define			DS2482_STATUS_LL	0x08
+#define			DS2482_STATUS_RST	0x10
+#define			DS2482_STATUS_SBR	0x20
+#define				DS2482_STATUS_SBR_SHIFT	5
+#define			DS2482_STATUS_TSB	0x40
+#define			DS2482_STATUS_DIR	0x80
+#define		DS2482_REGISTER_DATA	0xE1
+#define		DS2482_REGISTER_CONFIG	0xC3
+#define		DS2482_REGISTER_CHANNEL	0xD2 /* DS2482-800 only */
+#define DS2482_WRITE_CONFIG		0xD2
+#define		DS2482_CONFIG_1WS	0x08
+#define		DS2482_CONFIG_SPU	0x04
+#define		DS2482_CONFIG_APU	0x01
+#define DS2482_SELECT_CHANNEL		0xC3 /* DS2482-800 only */
+#define 	DS2482_CHANNEL_IO0	0xF0
+#define 	DS2482_CHANNEL_IO1	0xE1
+#define 	DS2482_CHANNEL_IO2	0xD2
+#define 	DS2482_CHANNEL_IO3	0xC3
+#define 	DS2482_CHANNEL_IO4	0xB4
+#define 	DS2482_CHANNEL_IO5	0xA5
+#define 	DS2482_CHANNEL_IO6	0x96
+#define 	DS2482_CHANNEL_IO7	0x87
+#define DS2482_ONEWIRE_RESET		0xB4
+#define DS2482_ONEWIRE_SINGLE_BIT	0x87
+#define		DS2482_ONEWIRE_BIT_ZERO		0x00
+#define		DS2482_ONEWIRE_BIT_ONE		0x80
+#define DS2482_ONEWIRE_WRITE_BYTE	0xA5
+#define DS2482_ONEWIRE_READ_BYTE	0x96
+#define DS2482_ONEWIRE_TRIPLET		0x78
+#define		DS2482_TRIPLET_DIR_ZERO 0x00
+#define		DS2482_TRIPLET_DIR_ONE	0x80
+
+#endif
Index: src/sys/dev/i2c/ds2482owvar.h
diff -u /dev/null src/sys/dev/i2c/ds2482owvar.h:1.1
--- /dev/null	Mon Nov  4 20:43:39 2024
+++ src/sys/dev/i2c/ds2482owvar.h	Mon Nov  4 20:43:38 2024
@@ -0,0 +1,47 @@
+/*	$NetBSD: ds2482owvar.h,v 1.1 2024/11/04 20:43:38 brad Exp $	*/
+
+/*
+ * Copyright (c) 2024 Brad Spencer <b...@anduin.eldar.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_I2C_DS2482VAR_H_
+#define _DEV_I2C_DS2482VAR_H_
+
+#define DS2482_NUM_INSTANCES	8
+
+struct ds2482ow_sc;
+
+struct ds2482_instance {
+	int				sc_i_channel;
+	struct onewire_bus		sc_i_ow_bus;
+	device_t			sc_i_ow_dev;
+	struct ds2482ow_sc		*sc;
+};
+
+struct ds2482ow_sc {
+	int 		sc_ds2482debug;
+	device_t 	sc_dev;
+	i2c_tag_t 	sc_tag;
+	i2c_addr_t 	sc_addr;
+	kmutex_t 	sc_mutex;
+	struct sysctllog *sc_ds2482log;
+	bool		sc_activepullup;
+	bool		sc_strongpullup;
+	bool		sc_is_800;
+	struct		ds2482_instance	sc_instances[DS2482_NUM_INSTANCES];
+};
+
+
+#endif

Index: src/sys/modules/ds2482ow/Makefile
diff -u /dev/null src/sys/modules/ds2482ow/Makefile:1.1
--- /dev/null	Mon Nov  4 20:43:39 2024
+++ src/sys/modules/ds2482ow/Makefile	Mon Nov  4 20:43:38 2024
@@ -0,0 +1,11 @@
+.include "../Makefile.inc"
+
+.PATH:	${S}/dev/i2c
+
+KMOD=	ds2482ow
+IOCONF=	ds2482ow.ioconf
+SRCS=	ds2482ow.c
+
+WARNS=	3
+
+.include <bsd.kmodule.mk>
Index: src/sys/modules/ds2482ow/ds2482ow.ioconf
diff -u /dev/null src/sys/modules/ds2482ow/ds2482ow.ioconf:1.1
--- /dev/null	Mon Nov  4 20:43:39 2024
+++ src/sys/modules/ds2482ow/ds2482ow.ioconf	Mon Nov  4 20:43:38 2024
@@ -0,0 +1,14 @@
+ioconf ds2482ow
+
+include "conf/files"
+
+pseudo-root iic*
+
+ds2482ow* at iic? addr 0x18
+ds2482ow* at iic? addr 0x19
+ds2482ow* at iic? addr 0x1a
+ds2482ow* at iic? addr 0x1b
+ds2482ow* at iic? addr 0x1c
+ds2482ow* at iic? addr 0x1d
+ds2482ow* at iic? addr 0x1e
+ds2482ow* at iic? addr 0x1f

Reply via email to