summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2013-05-20 21:54:52 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2013-05-31 15:53:11 +0200
commitb1a4a659c68bb0c37c5265a354c6a32b321c3446 (patch)
tree86fc2588b82affe6b56b95699bbed86a0678d44c /drivers/i2c
parent75ea5f1c0f6b93eae17470dfc62b40d254bb171b (diff)
downloadbarebox-b1a4a659c68bb0c37c5265a354c6a32b321c3446.tar.gz
barebox-b1a4a659c68bb0c37c5265a354c6a32b321c3446.tar.xz
i2c: Add devicetree support
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/i2c.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index ddf00826b4..b63d94604d 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -254,6 +254,7 @@ struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
client->dev.platform_data = chip->platform_data;
client->dev.id = DEVICE_ID_DYNAMIC;
client->dev.bus = &i2c_bus;
+ client->dev.device_node = chip->of_node;
client->adapter = adapter;
client->addr = chip->addr;
@@ -269,6 +270,45 @@ struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
}
EXPORT_SYMBOL(i2c_new_device);
+void of_i2c_register_devices(struct i2c_adapter *adap)
+{
+ struct device_node *n;
+
+ /* Only register child devices if the adapter has a node pointer set */
+ if (!IS_ENABLED(CONFIG_OFDEVICE) || !adap->dev.device_node)
+ return;
+
+ device_node_for_nach_child(adap->dev.device_node, n) {
+ struct i2c_board_info info = {};
+ struct i2c_client *result;
+ const __be32 *addr;
+ int len;
+
+ of_modalias_node(n, info.type, I2C_NAME_SIZE);
+
+ info.of_node = n;
+
+ addr = of_get_property(n, "reg", &len);
+ if (!addr || (len < sizeof(int))) {
+ dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
+ n->full_name);
+ continue;
+ }
+
+ info.addr = be32_to_cpup(addr);
+ if (info.addr > (1 << 10) - 1) {
+ dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
+ info.addr, n->full_name);
+ continue;
+ }
+
+ result = i2c_new_device(adap, &info);
+ if (!result)
+ dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
+ n->full_name);
+ }
+}
+
/**
* i2c_new_dummy - return a new i2c device bound to a dummy driver
* @adapter: the adapter managing the device
@@ -408,6 +448,8 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
/* populate children from any i2c device tables */
scan_boardinfo(adapter);
+ of_i2c_register_devices(adapter);
+
return 0;
}
EXPORT_SYMBOL(i2c_add_numbered_adapter);