diff options
author | Wolfram Sang <wsa+renesas@sang-engineering.com> | 2015-07-27 08:03:38 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2015-08-24 08:05:15 -0400 |
commit | cfa0327b0d03091e0c47249c080e50e287be762d (patch) | |
tree | 623f03aee6dc0bbdaada27b4f2cab5e4a7fd87fd | |
parent | 9bccc70a127cfe2a13e34d6b6e7300caae113f8f (diff) |
i2c: support 10 bit and slave addresses in sysfs 'new_device'
We now have seperate address spaces for 10 bit and we-are-slave clients.
Update the sysfs device instantiation method to support these types by
accepting the address offsets that are assigned to the extra address
spaces. Update the documentation, too.
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r-- | Documentation/i2c/slave-interface | 9 | ||||
-rw-r--r-- | Documentation/i2c/ten-bit-addresses | 4 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 12 |
3 files changed, 21 insertions, 4 deletions
diff --git a/Documentation/i2c/slave-interface b/Documentation/i2c/slave-interface index 2dee4e2d62df..61ed05cd9531 100644 --- a/Documentation/i2c/slave-interface +++ b/Documentation/i2c/slave-interface | |||
@@ -31,10 +31,13 @@ User manual | |||
31 | =========== | 31 | =========== |
32 | 32 | ||
33 | I2C slave backends behave like standard I2C clients. So, you can instantiate | 33 | I2C slave backends behave like standard I2C clients. So, you can instantiate |
34 | them as described in the document 'instantiating-devices'. A quick example for | 34 | them as described in the document 'instantiating-devices'. The only difference |
35 | instantiating the slave-eeprom driver from userspace at address 0x64 on bus 1: | 35 | is that i2c slave backends have their own address space. So, you have to add |
36 | 0x1000 to the address you would originally request. An example for | ||
37 | instantiating the slave-eeprom driver from userspace at the 7 bit address 0x64 | ||
38 | on bus 1: | ||
36 | 39 | ||
37 | # echo slave-24c02 0x64 > /sys/bus/i2c/devices/i2c-1/new_device | 40 | # echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-1/new_device |
38 | 41 | ||
39 | Each backend should come with separate documentation to describe its specific | 42 | Each backend should come with separate documentation to describe its specific |
40 | behaviour and setup. | 43 | behaviour and setup. |
diff --git a/Documentation/i2c/ten-bit-addresses b/Documentation/i2c/ten-bit-addresses index cdfe13901b99..7b2d11e53a49 100644 --- a/Documentation/i2c/ten-bit-addresses +++ b/Documentation/i2c/ten-bit-addresses | |||
@@ -2,6 +2,10 @@ 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). | 4 | address 0x10 (though a single device could respond to both of them). |
5 | To avoid ambiguity, the user sees 10 bit addresses mapped to a different | ||
6 | address space, namely 0xa000-0xa3ff. The leading 0xa (= 10) represents the | ||
7 | 10 bit mode. This is used for creating device names in sysfs. It is also | ||
8 | needed when instantiating 10 bit devices via the new_device file in sysfs. | ||
5 | 9 | ||
6 | I2C messages to and from 10-bit address devices have a different format. | 10 | I2C messages to and from 10-bit address devices have a different format. |
7 | See the I2C specification for the details. | 11 | See the I2C specification for the details. |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index fc6d89316144..039817eaecb5 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -1158,6 +1158,16 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr, | |||
1158 | return -EINVAL; | 1158 | return -EINVAL; |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | if ((info.addr & I2C_ADDR_OFFSET_TEN_BIT) == I2C_ADDR_OFFSET_TEN_BIT) { | ||
1162 | info.addr &= ~I2C_ADDR_OFFSET_TEN_BIT; | ||
1163 | info.flags |= I2C_CLIENT_TEN; | ||
1164 | } | ||
1165 | |||
1166 | if (info.addr & I2C_ADDR_OFFSET_SLAVE) { | ||
1167 | info.addr &= ~I2C_ADDR_OFFSET_SLAVE; | ||
1168 | info.flags |= I2C_CLIENT_SLAVE; | ||
1169 | } | ||
1170 | |||
1161 | client = i2c_new_device(adap, &info); | 1171 | client = i2c_new_device(adap, &info); |
1162 | if (!client) | 1172 | if (!client) |
1163 | return -EINVAL; | 1173 | return -EINVAL; |
@@ -1209,7 +1219,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, | |||
1209 | i2c_adapter_depth(adap)); | 1219 | i2c_adapter_depth(adap)); |
1210 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 1220 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
1211 | detected) { | 1221 | detected) { |
1212 | if (client->addr == addr) { | 1222 | if (i2c_encode_flags_to_addr(client) == addr) { |
1213 | dev_info(dev, "%s: Deleting device %s at 0x%02hx\n", | 1223 | dev_info(dev, "%s: Deleting device %s at 0x%02hx\n", |
1214 | "delete_device", client->name, client->addr); | 1224 | "delete_device", client->name, client->addr); |
1215 | 1225 | ||