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>hifive-unleashed-5.1
parent
9bccc70a12
commit
cfa0327b0d
|
@ -31,10 +31,13 @@ User manual
|
||||||
===========
|
===========
|
||||||
|
|
||||||
I2C slave backends behave like standard I2C clients. So, you can instantiate
|
I2C slave backends behave like standard I2C clients. So, you can instantiate
|
||||||
them as described in the document 'instantiating-devices'. A quick example for
|
them as described in the document 'instantiating-devices'. The only difference
|
||||||
instantiating the slave-eeprom driver from userspace at address 0x64 on bus 1:
|
is that i2c slave backends have their own address space. So, you have to add
|
||||||
|
0x1000 to the address you would originally request. An example for
|
||||||
|
instantiating the slave-eeprom driver from userspace at the 7 bit address 0x64
|
||||||
|
on bus 1:
|
||||||
|
|
||||||
# echo slave-24c02 0x64 > /sys/bus/i2c/devices/i2c-1/new_device
|
# echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-1/new_device
|
||||||
|
|
||||||
Each backend should come with separate documentation to describe its specific
|
Each backend should come with separate documentation to describe its specific
|
||||||
behaviour and setup.
|
behaviour and setup.
|
||||||
|
|
|
@ -2,6 +2,10 @@ 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).
|
address 0x10 (though a single device could respond to both of them).
|
||||||
|
To avoid ambiguity, the user sees 10 bit addresses mapped to a different
|
||||||
|
address space, namely 0xa000-0xa3ff. The leading 0xa (= 10) represents the
|
||||||
|
10 bit mode. This is used for creating device names in sysfs. It is also
|
||||||
|
needed when instantiating 10 bit devices via the new_device file in sysfs.
|
||||||
|
|
||||||
I2C messages to and from 10-bit address devices have a different format.
|
I2C messages to and from 10-bit address devices have a different format.
|
||||||
See the I2C specification for the details.
|
See the I2C specification for the details.
|
||||||
|
|
|
@ -1158,6 +1158,16 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((info.addr & I2C_ADDR_OFFSET_TEN_BIT) == I2C_ADDR_OFFSET_TEN_BIT) {
|
||||||
|
info.addr &= ~I2C_ADDR_OFFSET_TEN_BIT;
|
||||||
|
info.flags |= I2C_CLIENT_TEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.addr & I2C_ADDR_OFFSET_SLAVE) {
|
||||||
|
info.addr &= ~I2C_ADDR_OFFSET_SLAVE;
|
||||||
|
info.flags |= I2C_CLIENT_SLAVE;
|
||||||
|
}
|
||||||
|
|
||||||
client = i2c_new_device(adap, &info);
|
client = i2c_new_device(adap, &info);
|
||||||
if (!client)
|
if (!client)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1209,7 +1219,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
|
||||||
i2c_adapter_depth(adap));
|
i2c_adapter_depth(adap));
|
||||||
list_for_each_entry_safe(client, next, &adap->userspace_clients,
|
list_for_each_entry_safe(client, next, &adap->userspace_clients,
|
||||||
detected) {
|
detected) {
|
||||||
if (client->addr == addr) {
|
if (i2c_encode_flags_to_addr(client) == addr) {
|
||||||
dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
|
dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
|
||||||
"delete_device", client->name, client->addr);
|
"delete_device", client->name, client->addr);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue