mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
i2c: Devices which have some i2c addr can work in same i2c bus
If i2c slave devices don't work at the same time, which have the same i2c addr, this patch can make them working. Change-Id: I1bfb7783924b08bdc6e12bf47c2de01bdac7c2e2 Signed-off-by: Zhang aihui <zah@rock-chips.com>
This commit is contained in:
@@ -67,6 +67,7 @@
|
||||
static DEFINE_MUTEX(core_lock);
|
||||
static DEFINE_IDR(i2c_adapter_idr);
|
||||
|
||||
static int i2c_check_addr_ex(struct i2c_adapter *adapter, int addr);
|
||||
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
|
||||
|
||||
static DEFINE_STATIC_KEY_FALSE(i2c_trace_msg_key);
|
||||
@@ -666,7 +667,8 @@ static void i2c_adapter_unlock_bus(struct i2c_adapter *adapter,
|
||||
|
||||
static void i2c_dev_set_name(struct i2c_adapter *adap,
|
||||
struct i2c_client *client,
|
||||
struct i2c_board_info const *info)
|
||||
struct i2c_board_info const *info,
|
||||
int status)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(&client->dev);
|
||||
|
||||
@@ -680,8 +682,12 @@ static void i2c_dev_set_name(struct i2c_adapter *adap,
|
||||
return;
|
||||
}
|
||||
|
||||
dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
|
||||
i2c_encode_flags_to_addr(client));
|
||||
if (status == 0)
|
||||
dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
|
||||
i2c_encode_flags_to_addr(client));
|
||||
else
|
||||
dev_set_name(&client->dev, "%d-%04x-%01x", i2c_adapter_id(adap),
|
||||
i2c_encode_flags_to_addr(client), status);
|
||||
}
|
||||
|
||||
static int i2c_dev_irq_from_resources(const struct resource *resources,
|
||||
@@ -757,7 +763,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
|
||||
}
|
||||
|
||||
/* Check for address business */
|
||||
status = i2c_check_addr_busy(adap, i2c_encode_flags_to_addr(client));
|
||||
status = i2c_check_addr_ex(adap, i2c_encode_flags_to_addr(client));
|
||||
if (status)
|
||||
goto out_err;
|
||||
|
||||
@@ -767,7 +773,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
|
||||
client->dev.of_node = of_node_get(info->of_node);
|
||||
client->dev.fwnode = info->fwnode;
|
||||
|
||||
i2c_dev_set_name(adap, client, info);
|
||||
i2c_dev_set_name(adap, client, info, status);
|
||||
|
||||
if (info->properties) {
|
||||
status = device_add_properties(&client->dev, info->properties);
|
||||
@@ -1650,6 +1656,33 @@ EXPORT_SYMBOL(i2c_del_driver);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
struct i2c_addr_cnt {
|
||||
int addr;
|
||||
int cnt;
|
||||
};
|
||||
|
||||
static int __i2c_check_addr_ex(struct device *dev, void *addrp)
|
||||
{
|
||||
struct i2c_client *client = i2c_verify_client(dev);
|
||||
struct i2c_addr_cnt *addrinfo = (struct i2c_addr_cnt *)addrp;
|
||||
int addr = addrinfo->addr;
|
||||
|
||||
if (client && client->addr == addr)
|
||||
addrinfo->cnt++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_check_addr_ex(struct i2c_adapter *adapter, int addr)
|
||||
{
|
||||
struct i2c_addr_cnt addrinfo;
|
||||
|
||||
addrinfo.addr = addr;
|
||||
addrinfo.cnt = 0;
|
||||
device_for_each_child(&adapter->dev, &addrinfo, __i2c_check_addr_ex);
|
||||
return addrinfo.cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* i2c_use_client - increments the reference count of the i2c client structure
|
||||
* @client: the client being referenced
|
||||
|
||||
Reference in New Issue
Block a user