Module Name: src
Committed By: thorpej
Date: Fri May 14 01:52:36 UTC 2021
Modified Files:
src/sys/arch/sparc64/include [thorpej-i2c-spi-conf]: types.h
src/sys/dev/ofw [thorpej-i2c-spi-conf]: ofw_i2c_subr.c
Log Message:
Define __HAVE_OPENFIRMWARE_VARIANT_SUNW for sparc64 systems and handle
its OpenFirmware quirks with respect to i2c:
- "reg" property is 2 cells, the first one containing the channel the
device is on, the second one containing the i2c device address.
- The i2c device address is shifted left 1 bit to account for the r/w
bit on the wire.
To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.28.16.1 src/sys/arch/sparc64/include/types.h
cvs rdiff -u -r1.1.6.3 -r1.1.6.4 src/sys/dev/ofw/ofw_i2c_subr.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/sparc64/include/types.h
diff -u src/sys/arch/sparc64/include/types.h:1.28 src/sys/arch/sparc64/include/types.h:1.28.16.1
--- src/sys/arch/sparc64/include/types.h:1.28 Sat Apr 6 03:06:27 2019
+++ src/sys/arch/sparc64/include/types.h Fri May 14 01:52:36 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: types.h,v 1.28 2019/04/06 03:06:27 thorpej Exp $ */
+/* $NetBSD: types.h,v 1.28.16.1 2021/05/14 01:52:36 thorpej Exp $ */
#ifndef _SPARC64_TYPES_H_
#define _SPARC64_TYPES_H_
@@ -11,5 +11,6 @@
#define __HAVE_COMPAT_NETBSD32
#define __HAVE_UCAS_FULL
+#define __HAVE_OPENFIRMWARE_VARIANT_SUNW
#endif
Index: src/sys/dev/ofw/ofw_i2c_subr.c
diff -u src/sys/dev/ofw/ofw_i2c_subr.c:1.1.6.3 src/sys/dev/ofw/ofw_i2c_subr.c:1.1.6.4
--- src/sys/dev/ofw/ofw_i2c_subr.c:1.1.6.3 Fri May 14 00:44:13 2021
+++ src/sys/dev/ofw/ofw_i2c_subr.c Fri May 14 01:52:36 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: ofw_i2c_subr.c,v 1.1.6.3 2021/05/14 00:44:13 thorpej Exp $ */
+/* $NetBSD: ofw_i2c_subr.c,v 1.1.6.4 2021/05/14 01:52:36 thorpej Exp $ */
/*
* Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ofw_i2c_subr.c,v 1.1.6.3 2021/05/14 00:44:13 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ofw_i2c_subr.c,v 1.1.6.4 2021/05/14 01:52:36 thorpej Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -70,27 +70,80 @@ __KERNEL_RCSID(0, "$NetBSD: ofw_i2c_subr
#include <dev/ofw/openfirm.h>
#include <dev/i2c/i2cvar.h>
+#ifdef __HAVE_OPENFIRMWARE_VARIANT_AAPL
+/*
+ * Apple OpenFirmware implementations have the i2c device
+ * address shifted left 1 bit to account for the r/w bit
+ * on the wire. We also want to look at only the least-
+ * significant 8 bits of the address cell.
+ */
+#define OFW_I2C_ADDRESS_MASK __BITS(0,7)
+#define OFW_I2C_ADDRESS_SHIFT 1
+#endif /* __HAVE_OPENFIRMWARE_VARIANT_AAPL */
+
+#ifdef __HAVE_OPENFIRMWARE_VARIANT_SUNW
+/*
+ * Sun OpenFirmware implementations use 2 cells for the
+ * i2c device "reg" property, the first containing the
+ * channel number, the second containing the i2c device
+ * address shifted left 1 bit to account for the r/w bit
+ * on the wire.
+ */
+#define OFW_I2C_REG_NCELLS 2
+#define OFW_I2C_REG_CHANNEL 0
+#define OFW_I2C_REG_ADDRESS 1
+#define OFW_I2C_ADDRESS_SHIFT 1
+#endif /* __HAVE_OPENFIRMWARE_VARIANT_SUNW */
+
+#ifndef OFW_I2C_REG_NCELLS
+#define OFW_I2C_REG_NCELLS 1
+#endif
+
+#ifndef OFW_I2C_REG_ADDRESS
+#define OFW_I2C_REG_ADDRESS 0
+#endif
+
+/* No default for OFW_I2C_REG_CHANNEL. */
+
+#ifndef OFW_I2C_ADDRESS_MASK
+#define OFW_I2C_ADDRESS_MASK __BITS(0,31)
+#endif
+
+#ifndef OFW_I2C_ADDRESS_SHIFT
+#define OFW_I2C_ADDRESS_SHIFT 0
+#endif
+
static bool
-of_i2c_get_address(int node, uint32_t *addrp)
+of_i2c_get_address(i2c_tag_t tag, int node, uint32_t *addrp)
{
- uint32_t reg;
-
- if (OF_getprop(node, "reg", ®, sizeof(reg)) != sizeof(reg)) {
+ uint32_t reg[OFW_I2C_REG_NCELLS];
+ uint32_t addr;
+#ifdef OFW_I2C_REG_CHANNEL
+ uint32_t channel;
+#endif
+
+ if (OF_getprop(node, "reg", reg, sizeof(reg)) != sizeof(reg)) {
+ /*
+ * "reg" property is malformed; reject the device.
+ */
return false;
}
- reg = be32toh(reg);
+ addr = be32toh(reg[OFW_I2C_REG_ADDRESS]);
+ addr = (addr & OFW_I2C_ADDRESS_MASK) >> OFW_I2C_ADDRESS_SHIFT;
-#ifdef __HAVE_OPENFIRMWARE_VARIANT_AAPL
+#ifdef OFW_I2C_REG_CHANNEL
/*
- * Apple OpenFirmware implementations have the i2c device
- * address shifted left 1 bit to account for the r/w bit
- * on the wire.
+ * If the channel in the "reg" property does not match,
+ * reject the device.
*/
- reg = (reg & 0xff) >> 1;
-#endif /* __HAVE_OPENFIRMWARE_VARIANT_AAPL */
+ channel = be32toh(reg[OFW_I2C_REG_CHANNEL]);
+ if (channel != tag->ic_channel) {
+ return false;
+ }
+#endif
- *addrp = reg;
+ *addrp = addr;
return true;
}
@@ -118,7 +171,7 @@ of_i2c_enumerate_devices(device_t dev, d
if (OF_getprop(node, "name", name, sizeof(name)) <= 0) {
continue;
}
- if (!of_i2c_get_address(node, &addr)) {
+ if (!of_i2c_get_address(args->ia->ia_tag, node, &addr)) {
continue;
}