of_i2c: Add sparc support. Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe sparclinux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html