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