From cc6bcf7d2ec2234e7b41770185e4dc826390185e Mon Sep 17 00:00:00 2001 From: "Jeffrey (Sheng-Hui) Chu" Date: Wed, 23 Nov 2011 11:33:07 +0100 Subject: [PATCH 1/4] i2c-algo-bit: Generate correct i2c address sequence for 10-bit target The wrong bits were put on the wire, fix that. This fixes kernel bug #42562. Signed-off-by: Sheng-Hui J. Chu Cc: stable@kernel.org Signed-off-by: Jean Delvare --- drivers/i2c/algos/i2c-algo-bit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 85584a547c25..525c7345fa0b 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -488,7 +488,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) if (flags & I2C_M_TEN) { /* a ten bit address */ - addr = 0xf0 | ((msg->addr >> 7) & 0x03); + addr = 0xf0 | ((msg->addr >> 7) & 0x06); bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); /* try extended address code...*/ ret = try_address(i2c_adap, addr, retries); @@ -498,7 +498,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) return -ENXIO; } /* the remaining 8 bit address */ - ret = i2c_outb(i2c_adap, msg->addr & 0x7f); + ret = i2c_outb(i2c_adap, msg->addr & 0xff); if ((ret != 1) && !nak_ok) { /* the chip did not ack / xmission error occurred */ dev_err(&i2c_adap->dev, "died at 2nd address code\n"); From cbb44514048a250647c6c6b3df27ff62cb71f7d5 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 23 Nov 2011 11:33:07 +0100 Subject: [PATCH 2/4] i2c: Fix device name for 10-bit slave address 10-bit addresses overlap with traditional 7-bit addresses, leading in device name collisions. Add an arbitrary offset to 10-bit addresses to prevent this collision. The offset was chosen so that the address is still easily recognizable. Signed-off-by: Jean Delvare Acked-by: Wolfram Sang --- Documentation/i2c/ten-bit-addresses | 36 +++++++++++++++-------------- drivers/i2c/i2c-core.c | 4 +++- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/Documentation/i2c/ten-bit-addresses b/Documentation/i2c/ten-bit-addresses index e9890709c508..cdfe13901b99 100644 --- a/Documentation/i2c/ten-bit-addresses +++ b/Documentation/i2c/ten-bit-addresses @@ -1,22 +1,24 @@ The I2C protocol knows about two kinds of device addresses: normal 7 bit addresses, and an extended set of 10 bit addresses. The sets of addresses do not intersect: the 7 bit address 0x10 is not the same as the 10 bit -address 0x10 (though a single device could respond to both of them). You -select a 10 bit address by adding an extra byte after the address -byte: - S Addr7 Rd/Wr .... -becomes - S 11110 Addr10 Rd/Wr -S is the start bit, Rd/Wr the read/write bit, and if you count the number -of bits, you will see the there are 8 after the S bit for 7 bit addresses, -and 16 after the S bit for 10 bit addresses. +address 0x10 (though a single device could respond to both of them). -WARNING! The current 10 bit address support is EXPERIMENTAL. There are -several places in the code that will cause SEVERE PROBLEMS with 10 bit -addresses, even though there is some basic handling and hooks. Also, -almost no supported adapter handles the 10 bit addresses correctly. +I2C messages to and from 10-bit address devices have a different format. +See the I2C specification for the details. -As soon as a real 10 bit address device is spotted 'in the wild', we -can and will add proper support. Right now, 10 bit address devices -are defined by the I2C protocol, but we have never seen a single device -which supports them. +The current 10 bit address support is minimal. It should work, however +you can expect some problems along the way: +* Not all bus drivers support 10-bit addresses. Some don't because the + hardware doesn't support them (SMBus doesn't require 10-bit address + support for example), some don't because nobody bothered adding the + code (or it's there but not working properly.) Software implementation + (i2c-algo-bit) is known to work. +* Some optional features do not support 10-bit addresses. This is the + case of automatic detection and instantiation of devices by their, + drivers, for example. +* Many user-space packages (for example i2c-tools) lack support for + 10-bit addresses. + +Note that 10-bit address devices are still pretty rare, so the limitations +listed above could stay for a long time, maybe even forever if nobody +needs them to be fixed. diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 131079a3e292..1e5606185b4f 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -539,8 +539,10 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->dev.type = &i2c_client_type; client->dev.of_node = info->of_node; + /* For 10-bit clients, add an arbitrary offset to avoid collisions */ dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), - client->addr); + client->addr | ((client->flags & I2C_CLIENT_TEN) + ? 0xa000 : 0)); status = device_register(&client->dev); if (status) goto out_err; From 67820021dc9c8da37f773025190280f55f3626d4 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 23 Nov 2011 11:33:07 +0100 Subject: [PATCH 3/4] i2c: Delete ANY_I2C_BUS Last piece of code using ANY_I2C_BUS was deleted almost 2 years ago, so ANY_I2C_BUS can go away as well. Signed-off-by: Jean Delvare --- include/linux/i2c.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a81bf6d23b3e..07d103a06d64 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -432,9 +432,6 @@ void i2c_unlock_adapter(struct i2c_adapter *); /* Internal numbers to terminate lists */ #define I2C_CLIENT_END 0xfffeU -/* The numbers to use to set I2C bus address */ -#define ANY_I2C_BUS 0xffff - /* Construct an I2C_CLIENT_END-terminated array of i2c addresses */ #define I2C_ADDRS(addr, addrs...) \ ((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END }) From eff245c82f115059648cdce95dd68bb940f2b006 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Wed, 23 Nov 2011 11:33:07 +0100 Subject: [PATCH 4/4] i2c: Make i2cdev_notifier_call static The function i2cdev_notifier_call is used only in i2c-dev file making it static. Also removes the following sparse warning drivers/i2c/i2c-dev.c:582:5: warning: symbol 'i2cdev_notifier_call' was not declared. Should it be static? Signed-off-by: Shubhrajyoti D Signed-off-by: Jean Delvare --- drivers/i2c/i2c-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index c90ce50b619f..57a45ce84b2d 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -579,7 +579,7 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy) return 0; } -int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, +static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, void *data) { struct device *dev = data;