From: David Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
To: i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org
Subject: [PATCH 5/6]: i2c: Add bus addressing support.
Date: Thu, 21 Aug 2008 02:43:30 -0700 (PDT) [thread overview]
Message-ID: <20080821.024330.51639001.davem@davemloft.net> (raw)
i2c: Add bus addressing support.
Some I2C bus controllers support the driving of multiple I2C bus
segments (think PCI domains).
For example, the pcf8584 variants on some sparc64 boxes can do this.
They have an auxiliary 8-bit register that specifies the I2C bus each
I2C operation acts upon. In the openfirmware device tree, the I2C
client devices are described using an 8-bit bus address and a 10-bit
I2C device address.
In practice only really small numbers are used for the I2C bus
numbers, such as "0" and "1". So we don't need to really represent
the full 8-bits.
Adding this support is a little bit tricky, because we can't just add
a "bus" member to struct i2c_client, struct i2c_msg, etc. because
some of these structures are exported to userspace for the sake of the
i2c-dev driver interface.
Since we encode the I2C addresses in a 16-bit quantity, we steal the
top 6 bits for the bus number.
This works out because all current code will generate addresses with
those top 6-bits clear.
We add a new functionality bit, I2C_FUNC_BUS_ADDRESSING, that the
algorithm provider uses to indicate that it can support bus addressing.
If we see a non-zero bus address, we make sure the adapter can support
it.
Signed-off-by: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 550853f..3c0b5af 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -807,6 +807,10 @@ static int __i2c_check_addr(struct device *dev, void *addrp)
static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
{
+ if (I2C_ADDR_GET_BUS(addr) != 0 &&
+ !i2c_check_functionality(adapter, I2C_FUNC_BUS_ADDRESSING))
+ return -EOPNOTSUPP;
+
return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr);
}
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 08be0d2..c93561e 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -169,6 +169,31 @@ struct i2c_driver {
};
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
+/* In order to add bus addressing to the I2C layer without changing
+ * the layout of structures such as i2c_msg (for the sake of
+ * userspace), we encode the bus number into the top 6 bits of the
+ * address value.
+ *
+ * This allows existing userspace and drivers to keep working (the bus
+ * will be zero), and bus addressing support can be gradually added.
+ *
+ * Algorithm providers must indicate they support bus addressing via
+ * i2c_algorithm->functionality(). If they don't, the I2C layer will
+ * reject any attempt to attach, probe, or detect a device with a bus
+ * number other than zero.
+ */
+#define I2C_ADDR_ADDR_MASK 0x03ff
+#define I2C_ADDR_ADDR_SHIFT 0
+#define I2C_ADDR_BUS_MASK 0xfc00
+#define I2C_ADDR_BUS_SHIFT 10
+#define I2C_ADDR_GET_ADDR(addr) \
+ (((addr) & I2C_ADDR_ADDR_MASK) >> I2C_ADDR_ADDR_SHIFT)
+#define I2C_ADDR_GET_BUS(addr) \
+ (((addr) & I2C_ADDR_BUS_MASK) >> I2C_ADDR_BUS_SHIFT)
+#define I2C_ADDR_ENCODE(bus, addr) \
+ (((bus) << I2C_ADDR_BUS_SHIFT) | \
+ ((addr) << I2C_ADDR_ADDR_SHIFT))
+
/**
* struct i2c_client - represent an I2C slave device
* @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
@@ -531,6 +556,7 @@ struct i2c_msg {
#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */
#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */
+#define I2C_FUNC_BUS_ADDRESSING 0x40000000
#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
I2C_FUNC_SMBUS_WRITE_BYTE)
--
1.5.6.5.GIT
_______________________________________________
i2c mailing list
i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org
http://lists.lm-sensors.org/mailman/listinfo/i2c
next reply other threads:[~2008-08-21 9:43 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-21 9:43 David Miller [this message]
[not found] ` <20080821.024330.51639001.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2008-08-21 12:56 ` [PATCH 5/6]: i2c: Add bus addressing support Peter Korsgaard
2008-10-15 12:52 ` Jean Delvare
[not found] ` <20081015145228.14b1ae77-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-10-15 21:37 ` David Miller
[not found] ` <20081015.143722.260594637.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2008-10-17 15:24 ` Jean Delvare
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=20080821.024330.51639001.davem@davemloft.net \
--to=davem-ft/pcqaiutieiz0/mpfg9q@public.gmane.org \
--cc=i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox