diff options
-rw-r--r-- | drivers/i2c/i2c-core-of.c | 48 | ||||
-rw-r--r-- | include/linux/i2c.h | 10 |
2 files changed, 41 insertions, 17 deletions
diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c index 9fb38e99a6c6..6cb7ad608bcd 100644 --- a/drivers/i2c/i2c-core-of.c +++ b/drivers/i2c/i2c-core-of.c @@ -22,46 +22,60 @@ #include "i2c-core.h" -static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, - struct device_node *node) +int of_i2c_get_board_info(struct device *dev, struct device_node *node, + struct i2c_board_info *info) { - struct i2c_client *client; - struct i2c_board_info info = {}; u32 addr; int ret; - dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node); + memset(info, 0, sizeof(*info)); - if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { - dev_err(&adap->dev, "of_i2c: modalias failure on %pOF\n", - node); - return ERR_PTR(-EINVAL); + if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) { + dev_err(dev, "of_i2c: modalias failure on %pOF\n", node); + return -EINVAL; } ret = of_property_read_u32(node, "reg", &addr); if (ret) { - dev_err(&adap->dev, "of_i2c: invalid reg on %pOF\n", node); - return ERR_PTR(ret); + dev_err(dev, "of_i2c: invalid reg on %pOF\n", node); + return ret; } if (addr & I2C_TEN_BIT_ADDRESS) { addr &= ~I2C_TEN_BIT_ADDRESS; - info.flags |= I2C_CLIENT_TEN; + info->flags |= I2C_CLIENT_TEN; } if (addr & I2C_OWN_SLAVE_ADDRESS) { addr &= ~I2C_OWN_SLAVE_ADDRESS; - info.flags |= I2C_CLIENT_SLAVE; + info->flags |= I2C_CLIENT_SLAVE; } - info.addr = addr; - info.of_node = node; + info->addr = addr; + info->of_node = node; if (of_property_read_bool(node, "host-notify")) - info.flags |= I2C_CLIENT_HOST_NOTIFY; + info->flags |= I2C_CLIENT_HOST_NOTIFY; if (of_get_property(node, "wakeup-source", NULL)) - info.flags |= I2C_CLIENT_WAKE; + info->flags |= I2C_CLIENT_WAKE; + + return 0; +} +EXPORT_SYMBOL_GPL(of_i2c_get_board_info); + +static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, + struct device_node *node) +{ + struct i2c_client *client; + struct i2c_board_info info; + int ret; + + dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node); + + ret = of_i2c_get_board_info(&adap->dev, node, &info); + if (ret) + return ERR_PTR(ret); client = i2c_new_device(adap, &info); if (!client) { diff --git a/include/linux/i2c.h b/include/linux/i2c.h index aeb655772ef8..254cd34eeae2 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -901,6 +901,9 @@ extern const struct of_device_id *i2c_of_match_device(const struct of_device_id *matches, struct i2c_client *client); +int of_i2c_get_board_info(struct device *dev, struct device_node *node, + struct i2c_board_info *info); + #else static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) @@ -925,6 +928,13 @@ static inline const struct of_device_id return NULL; } +static inline int of_i2c_get_board_info(struct device *dev, + struct device_node *node, + struct i2c_board_info *info) +{ + return -ENOTSUPP; +} + #endif /* CONFIG_OF */ #if IS_ENABLED(CONFIG_ACPI) |