All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Beckett <bob.beckett@collabora.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 16/37] i2c: add support for offset overflow in to address
Date: Tue, 15 Oct 2019 16:53:29 +0100	[thread overview]
Message-ID: <fb506fd93d4b4366d1452497a5a9a1381ec2f3de.1571150958.git.bob.beckett@collabora.com> (raw)
In-Reply-To: <cover.1571150958.git.bob.beckett@collabora.com>

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 | 32 ++++++++++++++++++++++++++------
 include/i2c.h            | 24 ++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index e47abf1833..7580867dc1 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];
@@ -132,6 +135,7 @@ int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len)
 
 	if (!ops->xfer)
 		return -ENOSYS;
+
 	if (chip->flags & DM_I2C_CHIP_RD_ADDRESS)
 		return i2c_read_bytewise(dev, offset, buffer, len);
 	ptr = msg;
@@ -139,7 +143,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;
@@ -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..3c927340da 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -45,12 +45,17 @@ 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.
  * @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 +266,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

  parent reply	other threads:[~2019-10-15 15:53 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-15 15:53 [U-Boot] [PATCH 00/37] convert GE boards to DM Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 01/37] configs: bx50v3: Fix boot hang with video Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 02/37] board: ge: bx50v3: Fix run-time warning Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 03/37] board: ge: bx50v3: Fix message output to video console Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 04/37] configs: ppd: DM for USB and regulators PPD Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 05/37] board: ge: bx50v3: Enable DM for PCI and ethernet Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 06/37] board: ge: pass rtc_status via device tree Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 07/37] board: ge: bx50v3: use imx wdt Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 08/37] board: ge: mx53ppd: " Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 09/37] board: ge: bx50v3: Add i2c bus description Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 10/37] board: ge: mx53ppd: Add i2c bus descritpion Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 11/37] misc: i2c_eeprom: add fixed partitions support Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 12/37] misc: i2c_eeprom: add size query Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 13/37] board: ge: bx50v3: use DM I2C Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 14/37] board: ge: mx53ppd: " Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 15/37] board: ge: convert vpd to use i2c eeprom Robert Beckett
2019-10-15 15:53 ` Robert Beckett [this message]
2019-10-16  3:40   ` [U-Boot] [PATCH 16/37] i2c: add support for offset overflow in to address Simon Glass
2019-10-17 14:35     ` Robert Beckett
2019-10-21 23:47       ` Simon Glass
2019-10-15 15:53 ` [U-Boot] [PATCH 17/37] misc: i2c_eeprom: set offset len and chip addr offset mask Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 18/37] bootcount: add a DM i2c eeprom backing store for bootcount Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 19/37] board: ge: bx50v3: add i2c eeprom bootcount storage Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 20/37] board: ge: mx53ppd: " Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 21/37] rtc: rx8010sj: fix DM initialization Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 22/37] board: ge: bx50v3, mx53ppd: use DM rtc Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 23/37] board: ge: bx50v3: use DM i2c for PMIC initialization Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 24/37] board: ge: mx53ppd: remove redundant power config Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 25/37] board: ge: bx50v3, mx53ppd: disable I2C compatibility API Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 26/37] board: ge: mx53ppd: move uart initialisation to own function Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 27/37] board: ge: mx53ppd: enable DM_VIDEO Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 28/37] rtc: s35392a: encode command correctly Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 29/37] board: ge: mx53ppd: fix RTC compatible definition Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 30/37] board: ge: bx50v3: Enable DM PWM for backlight Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 31/37] board: ge: mx53ppd: clean up DM PWM video and backlight Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 32/37] board: ge: mx53ppd: Use DM for ethernet Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 33/37] board: ge: bx50v3: use DM for uart Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 34/37] serial: mxc: add imx53 and imx21 compatible string Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 35/37] board: ge: mx53ppd: use DM for uart Robert Beckett
2019-10-15 15:53 ` [U-Boot] [PATCH 36/37] dm: pmic: add da9063 PMIC driver and regulators Robert Beckett
2019-10-16  7:24   ` Schrempf Frieder
2019-10-16 11:11     ` Robert Beckett
2019-10-16 12:06       ` Martin Fuzzey
2019-10-15 15:53 ` [U-Boot] [PATCH 37/37] board: ge: bx50v3: use DM PMIC driver Robert Beckett

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fb506fd93d4b4366d1452497a5a9a1381ec2f3de.1571150958.git.bob.beckett@collabora.com \
    --to=bob.beckett@collabora.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.