[PATCH 2/3]: of_i2c: Add sparc support.
David Miller
davem at davemloft.net
Thu Aug 21 17:10:22 EST 2008
of_i2c: Add sparc support.
Signed-off-by: David S. Miller <davem at davemloft.net>
---
drivers/of/Kconfig | 2 +-
drivers/of/of_i2c.c | 58 ++++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index f821dbc..67dea24 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -10,7 +10,7 @@ config OF_GPIO
config OF_I2C
def_tristate I2C
- depends on PPC_OF && I2C
+ depends on OF && I2C
help
OpenFirmware I2C accessors
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index 6a98dc8..beb4102 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -19,8 +19,20 @@
void of_register_i2c_devices(struct i2c_adapter *adap,
struct device_node *adap_node)
{
- void *result;
struct device_node *node;
+ int num_addr_cells = 1;
+ const int *prop;
+ void *result;
+
+ prop = of_get_property(adap_node, "#address-cells", NULL);
+ if (prop)
+ num_addr_cells = *prop;
+
+ if (num_addr_cells != 1 && num_addr_cells != 2) {
+ printk(KERN_ERR "of-i2c: invalid address cells %d\n",
+ num_addr_cells);
+ return;
+ }
for_each_child_of_node(adap_node, node) {
struct i2c_board_info info = {};
@@ -31,16 +43,48 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
continue;
addr = of_get_property(node, "reg", &len);
- if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
- printk(KERN_ERR
- "of-i2c: invalid i2c device entry\n");
+ if (!addr || len < (num_addr_cells * sizeof(int))) {
+ printk(KERN_ERR "of-i2c: invalid i2c device entry\n");
continue;
}
+ switch (num_addr_cells) {
+ case 1:
+ info.addr = addr[0];
+ break;
+ case 2:
+ /* XXX addr[0], the first cell, is bus number XXX */
+ info.addr = addr[1];
+ break;
+ }
+#ifdef CONFIG_SPARC
+ /* In my copy of the I2C bindings for IEEE1275 the
+ * register value is encoded as a 2-cell value:
+ *
+ * Bit # 33222222 22221111 11111100 00000000
+ * 10987654 32109876 54321098 76543210
+ *
+ * bus: 00000000 00000000 00000000 bbbbbbbb
+ * address: 00000000 00000000 00000sss sssssss0
+ *
+ * where:
+ * bbbbbbbb 8-bit unsigned number representing
+ * the I2C bus address within this I2C bus
+ * controller node
+ * ssssssssss 10-bit unsigned number representing the
+ * slave address
+ *
+ * When doing I2C transfers to a device the low bit of
+ * the address indicates whether the transfer is a read or
+ * a write, and the upper bits indicate the device address.
+ *
+ * The Linux I2C layer wants device addresses which elide this
+ * direction bit. Thus we should shift the OF provided reg
+ * property address down by one bit.
+ */
+ info.addr >>= 1;
+#endif
info.irq = irq_of_parse_and_map(node, 0);
-
- info.addr = *addr;
-
request_module(info.type);
result = i2c_new_device(adap, &info);
--
1.5.6.5.GIT
More information about the Linuxppc-dev
mailing list