diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-23 12:50:05 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-23 12:50:05 -0500 |
commit | 5907c5f8adbd0bb7ab69124520304e5b25c8eb5e (patch) | |
tree | c3e1bc99f41c74b369293c74a1752e57e538f706 | |
parent | 0a2c986557b964453f8deeaf56f6d88bf3e65e92 (diff) | |
parent | eff245c82f115059648cdce95dd68bb940f2b006 (diff) |
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
-rw-r--r-- | Documentation/i2c/ten-bit-addresses | 36 | ||||
-rw-r--r-- | drivers/i2c/algos/i2c-algo-bit.c | 4 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 4 | ||||
-rw-r--r-- | drivers/i2c/i2c-dev.c | 2 | ||||
-rw-r--r-- | include/linux/i2c.h | 3 |
5 files changed, 25 insertions, 24 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 @@ | |||
1 | The I2C protocol knows about two kinds of device addresses: normal 7 bit | 1 | The I2C protocol knows about two kinds of device addresses: normal 7 bit |
2 | addresses, and an extended set of 10 bit addresses. The sets of addresses | 2 | addresses, and an extended set of 10 bit addresses. The sets of addresses |
3 | do not intersect: the 7 bit address 0x10 is not the same as the 10 bit | 3 | do not intersect: the 7 bit address 0x10 is not the same as the 10 bit |
4 | address 0x10 (though a single device could respond to both of them). You | 4 | address 0x10 (though a single device could respond to both of them). |
5 | select a 10 bit address by adding an extra byte after the address | ||
6 | byte: | ||
7 | S Addr7 Rd/Wr .... | ||
8 | becomes | ||
9 | S 11110 Addr10 Rd/Wr | ||
10 | S is the start bit, Rd/Wr the read/write bit, and if you count the number | ||
11 | of bits, you will see the there are 8 after the S bit for 7 bit addresses, | ||
12 | and 16 after the S bit for 10 bit addresses. | ||
13 | 5 | ||
14 | WARNING! The current 10 bit address support is EXPERIMENTAL. There are | 6 | I2C messages to and from 10-bit address devices have a different format. |
15 | several places in the code that will cause SEVERE PROBLEMS with 10 bit | 7 | See the I2C specification for the details. |
16 | addresses, even though there is some basic handling and hooks. Also, | ||
17 | almost no supported adapter handles the 10 bit addresses correctly. | ||
18 | 8 | ||
19 | As soon as a real 10 bit address device is spotted 'in the wild', we | 9 | The current 10 bit address support is minimal. It should work, however |
20 | can and will add proper support. Right now, 10 bit address devices | 10 | you can expect some problems along the way: |
21 | are defined by the I2C protocol, but we have never seen a single device | 11 | * Not all bus drivers support 10-bit addresses. Some don't because the |
22 | which supports them. | 12 | hardware doesn't support them (SMBus doesn't require 10-bit address |
13 | support for example), some don't because nobody bothered adding the | ||
14 | code (or it's there but not working properly.) Software implementation | ||
15 | (i2c-algo-bit) is known to work. | ||
16 | * Some optional features do not support 10-bit addresses. This is the | ||
17 | case of automatic detection and instantiation of devices by their, | ||
18 | drivers, for example. | ||
19 | * Many user-space packages (for example i2c-tools) lack support for | ||
20 | 10-bit addresses. | ||
21 | |||
22 | Note that 10-bit address devices are still pretty rare, so the limitations | ||
23 | listed above could stay for a long time, maybe even forever if nobody | ||
24 | needs them to be fixed. | ||
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) | |||
488 | 488 | ||
489 | if (flags & I2C_M_TEN) { | 489 | if (flags & I2C_M_TEN) { |
490 | /* a ten bit address */ | 490 | /* a ten bit address */ |
491 | addr = 0xf0 | ((msg->addr >> 7) & 0x03); | 491 | addr = 0xf0 | ((msg->addr >> 7) & 0x06); |
492 | bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); | 492 | bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); |
493 | /* try extended address code...*/ | 493 | /* try extended address code...*/ |
494 | ret = try_address(i2c_adap, addr, retries); | 494 | 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 | return -ENXIO; | 498 | return -ENXIO; |
499 | } | 499 | } |
500 | /* the remaining 8 bit address */ | 500 | /* the remaining 8 bit address */ |
501 | ret = i2c_outb(i2c_adap, msg->addr & 0x7f); | 501 | ret = i2c_outb(i2c_adap, msg->addr & 0xff); |
502 | if ((ret != 1) && !nak_ok) { | 502 | if ((ret != 1) && !nak_ok) { |
503 | /* the chip did not ack / xmission error occurred */ | 503 | /* the chip did not ack / xmission error occurred */ |
504 | dev_err(&i2c_adap->dev, "died at 2nd address code\n"); | 504 | dev_err(&i2c_adap->dev, "died at 2nd address code\n"); |
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) | |||
539 | client->dev.type = &i2c_client_type; | 539 | client->dev.type = &i2c_client_type; |
540 | client->dev.of_node = info->of_node; | 540 | client->dev.of_node = info->of_node; |
541 | 541 | ||
542 | /* For 10-bit clients, add an arbitrary offset to avoid collisions */ | ||
542 | dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), | 543 | dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), |
543 | client->addr); | 544 | client->addr | ((client->flags & I2C_CLIENT_TEN) |
545 | ? 0xa000 : 0)); | ||
544 | status = device_register(&client->dev); | 546 | status = device_register(&client->dev); |
545 | if (status) | 547 | if (status) |
546 | goto out_err; | 548 | goto out_err; |
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) | |||
579 | return 0; | 579 | return 0; |
580 | } | 580 | } |
581 | 581 | ||
582 | int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, | 582 | static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, |
583 | void *data) | 583 | void *data) |
584 | { | 584 | { |
585 | struct device *dev = data; | 585 | struct device *dev = data; |
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 *); | |||
432 | /* Internal numbers to terminate lists */ | 432 | /* Internal numbers to terminate lists */ |
433 | #define I2C_CLIENT_END 0xfffeU | 433 | #define I2C_CLIENT_END 0xfffeU |
434 | 434 | ||
435 | /* The numbers to use to set I2C bus address */ | ||
436 | #define ANY_I2C_BUS 0xffff | ||
437 | |||
438 | /* Construct an I2C_CLIENT_END-terminated array of i2c addresses */ | 435 | /* Construct an I2C_CLIENT_END-terminated array of i2c addresses */ |
439 | #define I2C_ADDRS(addr, addrs...) \ | 436 | #define I2C_ADDRS(addr, addrs...) \ |
440 | ((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END }) | 437 | ((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END }) |