aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWolfram Sang <wsa+renesas@sang-engineering.com>2015-07-27 08:03:38 -0400
committerWolfram Sang <wsa@the-dreams.de>2015-08-24 08:05:15 -0400
commitcfa0327b0d03091e0c47249c080e50e287be762d (patch)
tree623f03aee6dc0bbdaada27b4f2cab5e4a7fd87fd
parent9bccc70a127cfe2a13e34d6b6e7300caae113f8f (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-interface9
-rw-r--r--Documentation/i2c/ten-bit-addresses4
-rw-r--r--drivers/i2c/i2c-core.c12
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
33I2C slave backends behave like standard I2C clients. So, you can instantiate 33I2C slave backends behave like standard I2C clients. So, you can instantiate
34them as described in the document 'instantiating-devices'. A quick example for 34them as described in the document 'instantiating-devices'. The only difference
35instantiating the slave-eeprom driver from userspace at address 0x64 on bus 1: 35is that i2c slave backends have their own address space. So, you have to add
360x1000 to the address you would originally request. An example for
37instantiating the slave-eeprom driver from userspace at the 7 bit address 0x64
38on 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
39Each backend should come with separate documentation to describe its specific 42Each backend should come with separate documentation to describe its specific
40behaviour and setup. 43behaviour 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
2addresses, and an extended set of 10 bit addresses. The sets of addresses 2addresses, and an extended set of 10 bit addresses. The sets of addresses
3do not intersect: the 7 bit address 0x10 is not the same as the 10 bit 3do not intersect: the 7 bit address 0x10 is not the same as the 10 bit
4address 0x10 (though a single device could respond to both of them). 4address 0x10 (though a single device could respond to both of them).
5To avoid ambiguity, the user sees 10 bit addresses mapped to a different
6address space, namely 0xa000-0xa3ff. The leading 0xa (= 10) represents the
710 bit mode. This is used for creating device names in sysfs. It is also
8needed when instantiating 10 bit devices via the new_device file in sysfs.
5 9
6I2C messages to and from 10-bit address devices have a different format. 10I2C messages to and from 10-bit address devices have a different format.
7See the I2C specification for the details. 11See 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