Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/thorpej-i2c-spi-conf]: src/sys/dev/ofw Define __HAVE_OPENFIRMWARE_VARIAN...



details:   https://anonhg.NetBSD.org/src/rev/28a8a6ebe414
branches:  thorpej-i2c-spi-conf
changeset: 1020802:28a8a6ebe414
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Fri May 14 01:52:36 2021 +0000

description:
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.

diffstat:

 sys/arch/sparc64/include/types.h |   3 +-
 sys/dev/ofw/ofw_i2c_subr.c       |  81 +++++++++++++++++++++++++++++++++------
 2 files changed, 69 insertions(+), 15 deletions(-)

diffs (135 lines):

diff -r bcf686a7954d -r 28a8a6ebe414 sys/arch/sparc64/include/types.h
--- a/sys/arch/sparc64/include/types.h  Fri May 14 01:08:53 2021 +0000
+++ b/sys/arch/sparc64/include/types.h  Fri May 14 01:52:36 2021 +0000
@@ -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
diff -r bcf686a7954d -r 28a8a6ebe414 sys/dev/ofw/ofw_i2c_subr.c
--- a/sys/dev/ofw/ofw_i2c_subr.c        Fri May 14 01:08:53 2021 +0000
+++ b/sys/dev/ofw/ofw_i2c_subr.c        Fri May 14 01:52:36 2021 +0000
@@ -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 @@
 #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;
+       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)) {
+       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 @@
                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;
                }
 



Home | Main Index | Thread Index | Old Index