Commit 5907c5f8 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging

* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  i2c: Make i2cdev_notifier_call static
  i2c: Delete ANY_I2C_BUS
  i2c: Fix device name for 10-bit slave address
  i2c-algo-bit: Generate correct i2c address sequence for 10-bit target
parents 0a2c9865 eff245c8
The I2C protocol knows about two kinds of device addresses: normal 7 bit 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 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 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 address 0x10 (though a single device could respond to both of them).
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.
WARNING! The current 10 bit address support is EXPERIMENTAL. There are I2C messages to and from 10-bit address devices have a different format.
several places in the code that will cause SEVERE PROBLEMS with 10 bit See the I2C specification for the details.
addresses, even though there is some basic handling and hooks. Also,
almost no supported adapter handles the 10 bit addresses correctly.
As soon as a real 10 bit address device is spotted 'in the wild', we The current 10 bit address support is minimal. It should work, however
can and will add proper support. Right now, 10 bit address devices you can expect some problems along the way:
are defined by the I2C protocol, but we have never seen a single device * Not all bus drivers support 10-bit addresses. Some don't because the
which supports them. 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.
...@@ -488,7 +488,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) ...@@ -488,7 +488,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
if (flags & I2C_M_TEN) { if (flags & I2C_M_TEN) {
/* a ten bit address */ /* 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); bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
/* try extended address code...*/ /* try extended address code...*/
ret = try_address(i2c_adap, addr, retries); ret = try_address(i2c_adap, addr, retries);
...@@ -498,7 +498,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) ...@@ -498,7 +498,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
return -ENXIO; return -ENXIO;
} }
/* the remaining 8 bit address */ /* 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) { if ((ret != 1) && !nak_ok) {
/* the chip did not ack / xmission error occurred */ /* the chip did not ack / xmission error occurred */
dev_err(&i2c_adap->dev, "died at 2nd address code\n"); dev_err(&i2c_adap->dev, "died at 2nd address code\n");
......
...@@ -539,8 +539,10 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) ...@@ -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.type = &i2c_client_type;
client->dev.of_node = info->of_node; 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), 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); status = device_register(&client->dev);
if (status) if (status)
goto out_err; goto out_err;
......
...@@ -579,7 +579,7 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy) ...@@ -579,7 +579,7 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy)
return 0; 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) void *data)
{ {
struct device *dev = data; struct device *dev = data;
......
...@@ -432,9 +432,6 @@ void i2c_unlock_adapter(struct i2c_adapter *); ...@@ -432,9 +432,6 @@ void i2c_unlock_adapter(struct i2c_adapter *);
/* Internal numbers to terminate lists */ /* Internal numbers to terminate lists */
#define I2C_CLIENT_END 0xfffeU #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 */ /* Construct an I2C_CLIENT_END-terminated array of i2c addresses */
#define I2C_ADDRS(addr, addrs...) \ #define I2C_ADDRS(addr, addrs...) \
((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END }) ((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END })
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment