All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/3] i2c: add support for offset overflow in to chip address
@ 2019-10-28 17:44 Robert Beckett
  2019-10-28 17:44 ` [U-Boot] [PATCH 1/3] i2c: add support for offset overflow in to address Robert Beckett
  0 siblings, 1 reply; 10+ messages in thread
From: Robert Beckett @ 2019-10-28 17:44 UTC (permalink / raw)
  To: u-boot

Add support for devices that can overflow the offset in to the chip
address. This makes the devices effectively steal consecutive chip
addresses.

Also improve i2c testing and add new test for this new addressing mode.


Robert Beckett (3):
  i2c: add support for offset overflow in to address
  dm: i2c: EEPROM simulator allow tests visibility of addr and offset
  dm: i2c: EEPROM simulator add tests for addr offset mask

 arch/sandbox/include/asm/test.h |   7 ++
 drivers/i2c/i2c-uclass.c        |  34 ++++++++--
 drivers/misc/i2c_eeprom_emul.c  |  80 +++++++++++++++++------
 include/i2c.h                   |  33 ++++++++++
 test/dm/i2c.c                   | 112 ++++++++++++++++++++++++++++----
 5 files changed, 226 insertions(+), 40 deletions(-)

-- 
2.20.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH 1/3] i2c: add support for offset overflow in to address
  2019-10-28 17:44 [U-Boot] [PATCH 0/3] i2c: add support for offset overflow in to chip address Robert Beckett
@ 2019-10-28 17:44 ` Robert Beckett
  2019-10-28 17:44   ` [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset Robert Beckett
                     ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Robert Beckett @ 2019-10-28 17:44 UTC (permalink / raw)
  To: u-boot

Some devices (2 wire eeproms for example) use some bits from the chip
address to represent the high bits of the offset instead of or as well
as using multiple bytes for the offset, effectively stealing chip
addresses on the bus.

Add a chip offset mask that can be set for any i2c chip which gets
filled with the offset overflow during offset setup.

Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
Signed-off-by: Ian Ray <ian.ray@ge.com>
---

 drivers/i2c/i2c-uclass.c | 34 +++++++++++++++++++++++++++-------
 include/i2c.h            | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index e47abf1833..44aace3a36 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -52,16 +52,19 @@ void i2c_dump_msgs(struct i2c_msg *msg, int nmsgs)
 static int i2c_setup_offset(struct dm_i2c_chip *chip, uint offset,
 			    uint8_t offset_buf[], struct i2c_msg *msg)
 {
-	int offset_len;
+	int offset_len = chip->offset_len;
 
 	msg->addr = chip->chip_addr;
+	if (chip->chip_addr_offset_mask)
+		msg->addr |= (offset >> (8 * offset_len)) &
+			chip->chip_addr_offset_mask;
 	msg->flags = chip->flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0;
 	msg->len = chip->offset_len;
 	msg->buf = offset_buf;
-	if (!chip->offset_len)
+	if (!offset_len)
 		return -EADDRNOTAVAIL;
-	assert(chip->offset_len <= I2C_MAX_OFFSET_LEN);
-	offset_len = chip->offset_len;
+	assert(offset_len <= I2C_MAX_OFFSET_LEN);
+
 	while (offset_len--)
 		*offset_buf++ = offset >> (8 * offset_len);
 
@@ -83,7 +86,7 @@ static int i2c_read_bytewise(struct udevice *dev, uint offset,
 		if (i2c_setup_offset(chip, offset + i, offset_buf, msg))
 			return -EINVAL;
 		ptr = msg + 1;
-		ptr->addr = chip->chip_addr;
+		ptr->addr = msg->addr;
 		ptr->flags = msg->flags | I2C_M_RD;
 		ptr->len = 1;
 		ptr->buf = &buffer[i];
@@ -139,7 +142,7 @@ int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len)
 		ptr++;
 
 	if (len) {
-		ptr->addr = chip->chip_addr;
+		ptr->addr = msg->addr;
 		ptr->flags = chip->flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0;
 		ptr->flags |= I2C_M_RD;
 		ptr->len = len;
@@ -323,7 +326,8 @@ int i2c_get_chip(struct udevice *bus, uint chip_addr, uint offset_len,
 		struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 		int ret;
 
-		if (chip->chip_addr == chip_addr) {
+		if (chip->chip_addr == (chip_addr &
+					~chip->chip_addr_offset_mask)) {
 			ret = device_probe(dev);
 			debug("found, ret=%d\n", ret);
 			if (ret)
@@ -465,6 +469,22 @@ int i2c_get_chip_offset_len(struct udevice *dev)
 	return chip->offset_len;
 }
 
+int i2c_set_chip_addr_offset_mask(struct udevice *dev, uint mask)
+{
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+	chip->chip_addr_offset_mask = mask;
+
+	return 0;
+}
+
+uint i2c_get_chip_addr_offset_mask(struct udevice *dev)
+{
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+	return chip->chip_addr_offset_mask;
+}
+
 #ifdef CONFIG_DM_GPIO
 static void i2c_gpio_set_pin(struct gpio_desc *pin, int bit)
 {
diff --git a/include/i2c.h b/include/i2c.h
index 33570f5404..72e2e8e426 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -45,12 +45,26 @@ struct udevice;
  *		represent up to 256 bytes. A value larger than 1 may be
  *		needed for larger devices.
  * @flags:	Flags for this chip (dm_i2c_chip_flags)
+ * @chip_addr_offset_mask: Mask of offset bits within chip_addr. Used for
+ *			   devices which steal addresses as part of offset.
+ *			   If offset_len is zero, then the offset is encoded
+ *			   completely within the chip address itself.
+ *			   e.g. a devce with chip address of 0x2c with 512
+ *			   registers might use the bottom bit of the address
+ *			   to indicate which half of the address space is being
+ *			   accessed while still only using 1 byte offset.
+ *			   This means it will respond to  chip address 0x2c and
+ *			   0x2d.
+ *			   A real world example is the Atmel AT24C04. It's
+ *			   datasheet explains it's usage of this addressing
+ *			   mode.
  * @emul: Emulator for this chip address (only used for emulation)
  */
 struct dm_i2c_chip {
 	uint chip_addr;
 	uint offset_len;
 	uint flags;
+	uint chip_addr_offset_mask;
 #ifdef CONFIG_SANDBOX
 	struct udevice *emul;
 	bool test_mode;
@@ -261,6 +275,25 @@ int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len);
  */
 int i2c_get_chip_offset_len(struct udevice *dev);
 
+/**
+ * i2c_set_chip_addr_offset_mask() - set mask of address bits usable by offset
+ *
+ * Some devices listen on multiple chip addresses to achieve larger offsets
+ * than their single or multiple byte offsets would allow for. You can use this
+ * function to set the bits that are valid to be used for offset overflow.
+ *
+ * @mask: The mask to be used for high offset bits within address
+ * @return 0 if OK, other -ve value on error
+ */
+int i2c_set_chip_addr_offset_mask(struct udevice *dev, uint mask);
+
+/*
+ * i2c_get_chip_addr_offset_mask() - get mask of address bits usable by offset
+ *
+ * @return current chip addr offset mask
+ */
+uint i2c_get_chip_addr_offset_mask(struct udevice *dev);
+
 /**
  * i2c_deblock() - recover a bus that is in an unknown state
  *
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset
  2019-10-28 17:44 ` [U-Boot] [PATCH 1/3] i2c: add support for offset overflow in to address Robert Beckett
@ 2019-10-28 17:44   ` Robert Beckett
  2019-10-28 17:44     ` [U-Boot] [PATCH 3/3] dm: i2c: EEPROM simulator add tests for addr offset mask Robert Beckett
                       ` (2 more replies)
  2019-11-20  5:43   ` [U-Boot] [PATCH 1/3] i2c: add support for offset overflow in to address Heiko Schocher
  2019-12-17 11:57   ` [U-Boot][PATCH " Heiko Schocher
  2 siblings, 3 replies; 10+ messages in thread
From: Robert Beckett @ 2019-10-28 17:44 UTC (permalink / raw)
  To: u-boot

Improve i2c EEPROM simulator testing by providing access functions to
check the previous chip addr and offset.

Given that we can now directly test the offsets, also simplified the
offset mapping and allow for wrapping acceses.

Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
---

 arch/sandbox/include/asm/test.h |  4 +++
 drivers/misc/i2c_eeprom_emul.c  | 61 +++++++++++++++++++++++++--------
 test/dm/i2c.c                   | 50 +++++++++++++++++++--------
 3 files changed, 86 insertions(+), 29 deletions(-)

diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index cd2b9e3155..73cb451e7f 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -72,6 +72,10 @@ void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev,
 
 void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len);
 
+uint sanbox_i2c_eeprom_get_prev_addr(struct udevice *dev);
+
+uint sanbox_i2c_eeprom_get_prev_offset(struct udevice *dev);
+
 /**
  * sandbox_i2c_rtc_set_offset() - set the time offset from system/base time
  *
diff --git a/drivers/misc/i2c_eeprom_emul.c b/drivers/misc/i2c_eeprom_emul.c
index 29ed45923f..284267f2ea 100644
--- a/drivers/misc/i2c_eeprom_emul.c
+++ b/drivers/misc/i2c_eeprom_emul.c
@@ -27,6 +27,8 @@ struct sandbox_i2c_flash_plat_data {
 
 struct sandbox_i2c_flash {
 	uint8_t *data;
+	uint prev_addr;		/* slave address of previous access */
+	uint prev_offset;	/* offset of previous access */
 };
 
 void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev,
@@ -44,6 +46,20 @@ void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len)
 	plat->offset_len = offset_len;
 }
 
+uint sanbox_i2c_eeprom_get_prev_addr(struct udevice *dev)
+{
+	struct sandbox_i2c_flash *priv = dev_get_priv(dev);
+
+	return priv->prev_addr;
+}
+
+uint sanbox_i2c_eeprom_get_prev_offset(struct udevice *dev)
+{
+	struct sandbox_i2c_flash *priv = dev_get_priv(dev);
+
+	return priv->prev_offset;
+}
+
 static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
 				  int nmsgs)
 {
@@ -52,6 +68,10 @@ static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
 
 	debug("\n%s\n", __func__);
 	debug_buffer(0, priv->data, 1, 16, 0);
+
+	/* store addr for testing visibity */
+	priv->prev_addr = msg->addr;
+
 	for (; nmsgs > 0; nmsgs--, msg++) {
 		struct sandbox_i2c_flash_plat_data *plat =
 				dev_get_platdata(emul);
@@ -60,11 +80,6 @@ static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
 
 		if (!plat->size)
 			return -ENODEV;
-		if (msg->addr + msg->len > plat->size) {
-			debug("%s: Address %x, len %x is outside range 0..%x\n",
-			      __func__, msg->addr, msg->len, plat->size);
-			return -EINVAL;
-		}
 		len = msg->len;
 		debug("   %s: msg->len=%d",
 		      msg->flags & I2C_M_RD ? "read" : "write",
@@ -73,7 +88,16 @@ static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
 			if (plat->test_mode == SIE_TEST_MODE_SINGLE_BYTE)
 				len = 1;
 			debug(", offset %x, len %x: ", offset, len);
-			memcpy(msg->buf, priv->data + offset, len);
+			if (offset + len > plat->size) {
+				int overflow = offset + len - plat->size;
+				int initial = len - overflow;
+
+				memcpy(msg->buf, priv->data + offset, initial);
+				memcpy(msg->buf + initial, priv->data,
+				       overflow);
+			} else {
+				memcpy(msg->buf, priv->data + offset, len);
+			}
 			memset(msg->buf + len, '\xff', msg->len - len);
 			debug_buffer(0, msg->buf, 1, msg->len, 0);
 		} else if (len >= plat->offset_len) {
@@ -87,15 +111,24 @@ static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
 			if (plat->test_mode == SIE_TEST_MODE_SINGLE_BYTE)
 				len = min(len, 1);
 
-			/* For testing, map offsets into our limited buffer */
-			for (i = 24; i > 0; i -= 8) {
-				if (offset > (1 << i)) {
-					offset = (offset >> i) |
-						(offset & ((1 << i) - 1));
-					offset += i;
-				}
+			/* store offset for testing visibility */
+			priv->prev_offset = offset;
+
+			/* For testing, map offsets into our limited buffer.
+			 * offset wraps every 256 bytes
+			 */
+			offset &= 0xff;
+			debug("mapped offset to %x\n", offset);
+
+			if (offset + len > plat->size) {
+				int overflow = offset + len - plat->size;
+				int initial = len - overflow;
+
+				memcpy(priv->data + offset, ptr, initial);
+				memcpy(priv->data, ptr + initial, overflow);
+			} else {
+				memcpy(priv->data + offset, ptr, len);
 			}
-			memcpy(priv->data + offset, ptr, len);
 		}
 	}
 	debug_buffer(0, priv->data, 1, 16, 0);
diff --git a/test/dm/i2c.c b/test/dm/i2c.c
index cbbd4aa29a..bf5597b7a6 100644
--- a/test/dm/i2c.c
+++ b/test/dm/i2c.c
@@ -15,6 +15,7 @@
 #include <dm/test.h>
 #include <dm/uclass-internal.h>
 #include <dm/util.h>
+#include <hexdump.h>
 #include <test/ut.h>
 
 static const int busnum;
@@ -185,35 +186,54 @@ static int dm_test_i2c_offset(struct unit_test_state *uts)
 	ut_assertok(i2c_set_chip_offset_len(dev, 0));
 	ut_assertok(dm_i2c_write(dev, 10 /* ignored */, (uint8_t *)"AB", 2));
 	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
-	ut_assertok(memcmp(buf, "AB\0\0\0\0", sizeof(buf)));
+	ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
+	ut_asserteq(0, sanbox_i2c_eeprom_get_prev_offset(eeprom));
 
 	/* Offset length 1 */
 	sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
 	ut_assertok(i2c_set_chip_offset_len(dev, 1));
 	ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
+	ut_asserteq(2, sanbox_i2c_eeprom_get_prev_offset(eeprom));
 	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
-	ut_assertok(memcmp(buf, "ABAB\0", sizeof(buf)));
+	ut_asserteq_mem("ABAB\0", buf, sizeof(buf));
+	ut_asserteq(0, sanbox_i2c_eeprom_get_prev_offset(eeprom));
 
-	/* Offset length 2 */
+	/* Offset length 2 boundary - check model wrapping */
 	sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
 	ut_assertok(i2c_set_chip_offset_len(dev, 2));
-	ut_assertok(dm_i2c_write(dev, 0x210, (uint8_t *)"AB", 2));
-	ut_assertok(dm_i2c_read(dev, 0x210, buf, 5));
-	ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
+	ut_assertok(dm_i2c_write(dev, 0xFF, (uint8_t *)"A", 1));
+	ut_asserteq(0xFF, sanbox_i2c_eeprom_get_prev_offset(eeprom));
+	ut_assertok(dm_i2c_write(dev, 0x100, (uint8_t *)"B", 1));
+	ut_asserteq(0x100, sanbox_i2c_eeprom_get_prev_offset(eeprom));
+	ut_assertok(dm_i2c_write(dev, 0x101, (uint8_t *)"C", 1));
+	ut_asserteq(0x101, sanbox_i2c_eeprom_get_prev_offset(eeprom));
+	ut_assertok(dm_i2c_read(dev, 0xFF, buf, 5));
+	ut_asserteq_mem("ABCAB", buf, sizeof(buf));
+	ut_asserteq(0xFF, sanbox_i2c_eeprom_get_prev_offset(eeprom));
 
-	/* Offset length 3 */
+	/* Offset length 2 */
 	sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
 	ut_assertok(i2c_set_chip_offset_len(dev, 2));
-	ut_assertok(dm_i2c_write(dev, 0x410, (uint8_t *)"AB", 2));
-	ut_assertok(dm_i2c_read(dev, 0x410, buf, 5));
-	ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
+	ut_assertok(dm_i2c_write(dev, 0x2020, (uint8_t *)"AB", 2));
+	ut_assertok(dm_i2c_read(dev, 0x2020, buf, 5));
+	ut_asserteq_mem("AB\0\0\0", buf, sizeof(buf));
+	ut_asserteq(0x2020, sanbox_i2c_eeprom_get_prev_offset(eeprom));
+
+	/* Offset length 3 */
+	sandbox_i2c_eeprom_set_offset_len(eeprom, 3);
+	ut_assertok(i2c_set_chip_offset_len(dev, 3));
+	ut_assertok(dm_i2c_write(dev, 0x303030, (uint8_t *)"AB", 2));
+	ut_assertok(dm_i2c_read(dev, 0x303030, buf, 5));
+	ut_asserteq_mem("AB\0\0\0", buf, sizeof(buf));
+	ut_asserteq(0x303030, sanbox_i2c_eeprom_get_prev_offset(eeprom));
 
 	/* Offset length 4 */
-	sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
-	ut_assertok(i2c_set_chip_offset_len(dev, 2));
-	ut_assertok(dm_i2c_write(dev, 0x420, (uint8_t *)"AB", 2));
-	ut_assertok(dm_i2c_read(dev, 0x420, buf, 5));
-	ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
+	sandbox_i2c_eeprom_set_offset_len(eeprom, 4);
+	ut_assertok(i2c_set_chip_offset_len(dev, 4));
+	ut_assertok(dm_i2c_write(dev, 0x40404040, (uint8_t *)"AB", 2));
+	ut_assertok(dm_i2c_read(dev, 0x40404040, buf, 5));
+	ut_asserteq_mem("AB\0\0\0", buf, sizeof(buf));
+	ut_asserteq(0x40404040, sanbox_i2c_eeprom_get_prev_offset(eeprom));
 
 	/* Restore defaults */
 	sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH 3/3] dm: i2c: EEPROM simulator add tests for addr offset mask
  2019-10-28 17:44   ` [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset Robert Beckett
@ 2019-10-28 17:44     ` Robert Beckett
  2019-11-20  5:45       ` Heiko Schocher
  2019-12-17 11:59       ` [U-Boot][PATCH " Heiko Schocher
  2019-11-20  5:44     ` [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset Heiko Schocher
  2019-12-17 11:58     ` [U-Boot][PATCH " Heiko Schocher
  2 siblings, 2 replies; 10+ messages in thread
From: Robert Beckett @ 2019-10-28 17:44 UTC (permalink / raw)
  To: u-boot

Add support for setting the chip address offset mask to EEPROM sumulator
and add tests to test it.

Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
---

 arch/sandbox/include/asm/test.h |  3 ++
 drivers/misc/i2c_eeprom_emul.c  | 19 +++++++---
 test/dm/i2c.c                   | 64 +++++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+), 5 deletions(-)

diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index 73cb451e7f..28c4c7bcef 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -72,6 +72,9 @@ void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev,
 
 void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len);
 
+void sandbox_i2c_eeprom_set_chip_addr_offset_mask(struct udevice *dev,
+						  uint mask);
+
 uint sanbox_i2c_eeprom_get_prev_addr(struct udevice *dev);
 
 uint sanbox_i2c_eeprom_get_prev_offset(struct udevice *dev);
diff --git a/drivers/misc/i2c_eeprom_emul.c b/drivers/misc/i2c_eeprom_emul.c
index 284267f2ea..16758a0ef9 100644
--- a/drivers/misc/i2c_eeprom_emul.c
+++ b/drivers/misc/i2c_eeprom_emul.c
@@ -23,6 +23,7 @@ struct sandbox_i2c_flash_plat_data {
 	const char *filename;
 	int offset_len;		/* Length of an offset in bytes */
 	int size;		/* Size of data buffer */
+	uint chip_addr_offset_mask; /* mask of addr bits used for offset */
 };
 
 struct sandbox_i2c_flash {
@@ -46,6 +47,14 @@ void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len)
 	plat->offset_len = offset_len;
 }
 
+void sandbox_i2c_eeprom_set_chip_addr_offset_mask(struct udevice *dev,
+						  uint mask)
+{
+	struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);
+
+	plat->chip_addr_offset_mask = mask;
+}
+
 uint sanbox_i2c_eeprom_get_prev_addr(struct udevice *dev)
 {
 	struct sandbox_i2c_flash *priv = dev_get_priv(dev);
@@ -64,7 +73,8 @@ static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
 				  int nmsgs)
 {
 	struct sandbox_i2c_flash *priv = dev_get_priv(emul);
-	uint offset = 0;
+	struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(emul);
+	uint offset = msg->addr & plat->chip_addr_offset_mask;
 
 	debug("\n%s\n", __func__);
 	debug_buffer(0, priv->data, 1, 16, 0);
@@ -73,17 +83,15 @@ static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
 	priv->prev_addr = msg->addr;
 
 	for (; nmsgs > 0; nmsgs--, msg++) {
-		struct sandbox_i2c_flash_plat_data *plat =
-				dev_get_platdata(emul);
 		int len;
 		u8 *ptr;
 
 		if (!plat->size)
 			return -ENODEV;
 		len = msg->len;
-		debug("   %s: msg->len=%d",
+		debug("   %s: msg->addr=%x msg->len=%d",
 		      msg->flags & I2C_M_RD ? "read" : "write",
-		      msg->len);
+		      msg->addr, msg->len);
 		if (msg->flags & I2C_M_RD) {
 			if (plat->test_mode == SIE_TEST_MODE_SINGLE_BYTE)
 				len = 1;
@@ -153,6 +161,7 @@ static int sandbox_i2c_eeprom_ofdata_to_platdata(struct udevice *dev)
 	}
 	plat->test_mode = SIE_TEST_MODE_NONE;
 	plat->offset_len = 1;
+	plat->chip_addr_offset_mask = 0;
 
 	return 0;
 }
diff --git a/test/dm/i2c.c b/test/dm/i2c.c
index bf5597b7a6..4035f82f46 100644
--- a/test/dm/i2c.c
+++ b/test/dm/i2c.c
@@ -241,3 +241,67 @@ static int dm_test_i2c_offset(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_i2c_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+static int dm_test_i2c_addr_offset(struct unit_test_state *uts)
+{
+	struct udevice *eeprom;
+	struct udevice *dev;
+	u8 buf[5];
+
+	ut_assertok(i2c_get_chip_for_busnum(busnum, chip, 1, &dev));
+
+	/* Do a transfer so we can find the emulator */
+	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
+	ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
+
+	/* Offset length 0 */
+	sandbox_i2c_eeprom_set_offset_len(eeprom, 0);
+	sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
+	ut_assertok(i2c_set_chip_offset_len(dev, 0));
+	ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
+	ut_assertok(dm_i2c_write(dev, 0x3, (uint8_t *)"AB", 2));
+	ut_assertok(dm_i2c_read(dev, 0x3, buf, 5));
+	ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
+	ut_asserteq(0x3, sanbox_i2c_eeprom_get_prev_offset(eeprom));
+	ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
+
+	/* Offset length 1 */
+	sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
+	sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
+	ut_assertok(i2c_set_chip_offset_len(dev, 1));
+	ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
+	ut_assertok(dm_i2c_write(dev, 0x310, (uint8_t *)"AB", 2));
+	ut_assertok(dm_i2c_read(dev, 0x310, buf, 5));
+	ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
+	ut_asserteq(0x310, sanbox_i2c_eeprom_get_prev_offset(eeprom));
+	ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
+
+	/* Offset length 2 */
+	sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
+	sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
+	ut_assertok(i2c_set_chip_offset_len(dev, 2));
+	ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
+	ut_assertok(dm_i2c_write(dev, 0x32020, (uint8_t *)"AB", 2));
+	ut_assertok(dm_i2c_read(dev, 0x32020, buf, 5));
+	ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
+	ut_asserteq(0x32020, sanbox_i2c_eeprom_get_prev_offset(eeprom));
+	ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
+
+	/* Offset length 3 */
+	sandbox_i2c_eeprom_set_offset_len(eeprom, 3);
+	sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
+	ut_assertok(i2c_set_chip_offset_len(dev, 3));
+	ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
+	ut_assertok(dm_i2c_write(dev, 0x3303030, (uint8_t *)"AB", 2));
+	ut_assertok(dm_i2c_read(dev, 0x3303030, buf, 5));
+	ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
+	ut_asserteq(0x3303030, sanbox_i2c_eeprom_get_prev_offset(eeprom));
+	ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
+
+	/* Restore defaults */
+	sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
+	sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0);
+
+	return 0;
+}
+DM_TEST(dm_test_i2c_addr_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH 1/3] i2c: add support for offset overflow in to address
  2019-10-28 17:44 ` [U-Boot] [PATCH 1/3] i2c: add support for offset overflow in to address Robert Beckett
  2019-10-28 17:44   ` [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset Robert Beckett
@ 2019-11-20  5:43   ` Heiko Schocher
  2019-12-17 11:57   ` [U-Boot][PATCH " Heiko Schocher
  2 siblings, 0 replies; 10+ messages in thread
From: Heiko Schocher @ 2019-11-20  5:43 UTC (permalink / raw)
  To: u-boot

Hello Robert

Am 28.10.2019 um 18:44 schrieb Robert Beckett:
> Some devices (2 wire eeproms for example) use some bits from the chip
> address to represent the high bits of the offset instead of or as well
> as using multiple bytes for the offset, effectively stealing chip
> addresses on the bus.
> 
> Add a chip offset mask that can be set for any i2c chip which gets
> filled with the offset overflow during offset setup.
> 
> Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
> Signed-off-by: Ian Ray <ian.ray@ge.com>
> ---
> 
>   drivers/i2c/i2c-uclass.c | 34 +++++++++++++++++++++++++++-------
>   include/i2c.h            | 33 +++++++++++++++++++++++++++++++++
>   2 files changed, 60 insertions(+), 7 deletions(-)

Reviewed-by: Heiko Schocher <hs@denx.de>

Thanks!

bye,
Heiko
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: hs at denx.de

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset
  2019-10-28 17:44   ` [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset Robert Beckett
  2019-10-28 17:44     ` [U-Boot] [PATCH 3/3] dm: i2c: EEPROM simulator add tests for addr offset mask Robert Beckett
@ 2019-11-20  5:44     ` Heiko Schocher
  2019-12-17 11:58     ` [U-Boot][PATCH " Heiko Schocher
  2 siblings, 0 replies; 10+ messages in thread
From: Heiko Schocher @ 2019-11-20  5:44 UTC (permalink / raw)
  To: u-boot

Hello Robert,

Am 28.10.2019 um 18:44 schrieb Robert Beckett:
> Improve i2c EEPROM simulator testing by providing access functions to
> check the previous chip addr and offset.
> 
> Given that we can now directly test the offsets, also simplified the
> offset mapping and allow for wrapping acceses.
> 
> Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
> ---
> 
>   arch/sandbox/include/asm/test.h |  4 +++
>   drivers/misc/i2c_eeprom_emul.c  | 61 +++++++++++++++++++++++++--------
>   test/dm/i2c.c                   | 50 +++++++++++++++++++--------
>   3 files changed, 86 insertions(+), 29 deletions(-)

Reviewed-by: Heiko Schocher <hs@denx.de>

Thanks!

bye,
Heiko
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: hs at denx.de

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH 3/3] dm: i2c: EEPROM simulator add tests for addr offset mask
  2019-10-28 17:44     ` [U-Boot] [PATCH 3/3] dm: i2c: EEPROM simulator add tests for addr offset mask Robert Beckett
@ 2019-11-20  5:45       ` Heiko Schocher
  2019-12-17 11:59       ` [U-Boot][PATCH " Heiko Schocher
  1 sibling, 0 replies; 10+ messages in thread
From: Heiko Schocher @ 2019-11-20  5:45 UTC (permalink / raw)
  To: u-boot

Hello Robert,

Am 28.10.2019 um 18:44 schrieb Robert Beckett:
> Add support for setting the chip address offset mask to EEPROM sumulator
> and add tests to test it.
> 
> Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
> ---
> 
>   arch/sandbox/include/asm/test.h |  3 ++
>   drivers/misc/i2c_eeprom_emul.c  | 19 +++++++---
>   test/dm/i2c.c                   | 64 +++++++++++++++++++++++++++++++++
>   3 files changed, 81 insertions(+), 5 deletions(-)

Reviewed-by: Heiko Schocher <hs@denx.de>

Thanks for adding al this testing stuff!

bye,
Heiko
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: hs at denx.de

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot][PATCH 1/3] i2c: add support for offset overflow in to address
  2019-10-28 17:44 ` [U-Boot] [PATCH 1/3] i2c: add support for offset overflow in to address Robert Beckett
  2019-10-28 17:44   ` [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset Robert Beckett
  2019-11-20  5:43   ` [U-Boot] [PATCH 1/3] i2c: add support for offset overflow in to address Heiko Schocher
@ 2019-12-17 11:57   ` Heiko Schocher
  2 siblings, 0 replies; 10+ messages in thread
From: Heiko Schocher @ 2019-12-17 11:57 UTC (permalink / raw)
  To: u-boot

Hello Robert,

Am 28.10.2019 um 18:44 schrieb Robert Beckett:
> Some devices (2 wire eeproms for example) use some bits from the chip
> address to represent the high bits of the offset instead of or as well
> as using multiple bytes for the offset, effectively stealing chip
> addresses on the bus.
> 
> Add a chip offset mask that can be set for any i2c chip which gets
> filled with the offset overflow during offset setup.
> 
> Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
> Signed-off-by: Ian Ray <ian.ray@ge.com>
> ---
> 
>   drivers/i2c/i2c-uclass.c | 34 +++++++++++++++++++++++++++-------
>   include/i2c.h            | 33 +++++++++++++++++++++++++++++++++
>   2 files changed, 60 insertions(+), 7 deletions(-)

Applied to u-boot-i2c next branch.

Thanks!

bye,
Heiko
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: hs at denx.de

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot][PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset
  2019-10-28 17:44   ` [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset Robert Beckett
  2019-10-28 17:44     ` [U-Boot] [PATCH 3/3] dm: i2c: EEPROM simulator add tests for addr offset mask Robert Beckett
  2019-11-20  5:44     ` [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset Heiko Schocher
@ 2019-12-17 11:58     ` Heiko Schocher
  2 siblings, 0 replies; 10+ messages in thread
From: Heiko Schocher @ 2019-12-17 11:58 UTC (permalink / raw)
  To: u-boot

Hello Robert,

Am 28.10.2019 um 18:44 schrieb Robert Beckett:
> Improve i2c EEPROM simulator testing by providing access functions to
> check the previous chip addr and offset.
> 
> Given that we can now directly test the offsets, also simplified the
> offset mapping and allow for wrapping acceses.
> 
> Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
> ---
> 
>   arch/sandbox/include/asm/test.h |  4 +++
>   drivers/misc/i2c_eeprom_emul.c  | 61 +++++++++++++++++++++++++--------
>   test/dm/i2c.c                   | 50 +++++++++++++++++++--------
>   3 files changed, 86 insertions(+), 29 deletions(-)

Applied to u-boot-i2c next branch.

Thanks!

bye,
Heiko
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: hs at denx.de

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot][PATCH 3/3] dm: i2c: EEPROM simulator add tests for addr offset mask
  2019-10-28 17:44     ` [U-Boot] [PATCH 3/3] dm: i2c: EEPROM simulator add tests for addr offset mask Robert Beckett
  2019-11-20  5:45       ` Heiko Schocher
@ 2019-12-17 11:59       ` Heiko Schocher
  1 sibling, 0 replies; 10+ messages in thread
From: Heiko Schocher @ 2019-12-17 11:59 UTC (permalink / raw)
  To: u-boot

Hello Robert,

Am 28.10.2019 um 18:44 schrieb Robert Beckett:
> Add support for setting the chip address offset mask to EEPROM sumulator
> and add tests to test it.
> 
> Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
> ---
> 
>   arch/sandbox/include/asm/test.h |  3 ++
>   drivers/misc/i2c_eeprom_emul.c  | 19 +++++++---
>   test/dm/i2c.c                   | 64 +++++++++++++++++++++++++++++++++
>   3 files changed, 81 insertions(+), 5 deletions(-)

Applied to u-boot-i2c next branch.

Thanks!

bye,
Heiko
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: hs at denx.de

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-12-17 11:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-28 17:44 [U-Boot] [PATCH 0/3] i2c: add support for offset overflow in to chip address Robert Beckett
2019-10-28 17:44 ` [U-Boot] [PATCH 1/3] i2c: add support for offset overflow in to address Robert Beckett
2019-10-28 17:44   ` [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset Robert Beckett
2019-10-28 17:44     ` [U-Boot] [PATCH 3/3] dm: i2c: EEPROM simulator add tests for addr offset mask Robert Beckett
2019-11-20  5:45       ` Heiko Schocher
2019-12-17 11:59       ` [U-Boot][PATCH " Heiko Schocher
2019-11-20  5:44     ` [U-Boot] [PATCH 2/3] dm: i2c: EEPROM simulator allow tests visibility of addr and offset Heiko Schocher
2019-12-17 11:58     ` [U-Boot][PATCH " Heiko Schocher
2019-11-20  5:43   ` [U-Boot] [PATCH 1/3] i2c: add support for offset overflow in to address Heiko Schocher
2019-12-17 11:57   ` [U-Boot][PATCH " Heiko Schocher

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.