summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-07-04 17:26:05 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2014-07-04 17:26:05 +0200
commit45d593bc5ec78e26e3a967517ed7a51f27c8b91f (patch)
tree197cc45c686dc86b4537ce55313d5ec074671918 /drivers/i2c
parent6724928c6972842b73962dc5af70d26de9969582 (diff)
parent988ecf42691e101a35ecae83d26253e9590d14c6 (diff)
downloadbarebox-45d593bc5ec78e26e3a967517ed7a51f27c8b91f.tar.gz
barebox-45d593bc5ec78e26e3a967517ed7a51f27c8b91f.tar.xz
Merge branch 'for-next/mips'
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-gpio.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 8b49c2c1bf..b4a0ecdb20 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -15,6 +15,7 @@
#include <i2c/i2c-gpio.h>
#include <init.h>
#include <gpio.h>
+#include <of_gpio.h>
struct i2c_gpio_private_data {
struct i2c_adapter adap;
@@ -83,6 +84,41 @@ static int i2c_gpio_getscl(void *data)
return gpio_get_value(pdata->scl_pin);
}
+static int of_i2c_gpio_probe(struct device_node *np,
+ struct i2c_gpio_platform_data *pdata)
+{
+ u32 reg;
+
+ if (!IS_ENABLED(CONFIG_OFDEVICE))
+ return -ENODEV;
+
+ if (of_gpio_count(np) < 2)
+ return -ENODEV;
+
+ pdata->sda_pin = of_get_gpio(np, 0);
+ pdata->scl_pin = of_get_gpio(np, 1);
+
+ if (!gpio_is_valid(pdata->sda_pin) || !gpio_is_valid(pdata->scl_pin)) {
+ pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+ np->full_name, pdata->sda_pin, pdata->scl_pin);
+ return -ENODEV;
+ }
+
+ of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay);
+
+ if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", &reg))
+ pdata->timeout_ms = reg;
+
+ pdata->sda_is_open_drain =
+ of_property_read_bool(np, "i2c-gpio,sda-open-drain");
+ pdata->scl_is_open_drain =
+ of_property_read_bool(np, "i2c-gpio,scl-open-drain");
+ pdata->scl_is_output_only =
+ of_property_read_bool(np, "i2c-gpio,scl-output-only");
+
+ return 0;
+}
+
static int i2c_gpio_probe(struct device_d *dev)
{
struct i2c_gpio_private_data *priv;
@@ -97,9 +133,15 @@ static int i2c_gpio_probe(struct device_d *dev)
bit_data = &priv->bit_data;
pdata = &priv->pdata;
- if (!dev->platform_data)
- return -ENXIO;
- memcpy(pdata, dev->platform_data, sizeof(*pdata));
+ if (dev->device_node) {
+ ret = of_i2c_gpio_probe(dev->device_node, pdata);
+ if (ret)
+ return ret;
+ } else {
+ if (!dev->platform_data)
+ return -ENXIO;
+ memcpy(pdata, dev->platform_data, sizeof(*pdata));
+ }
ret = gpio_request(pdata->sda_pin, "sda");
if (ret)
@@ -144,6 +186,7 @@ static int i2c_gpio_probe(struct device_d *dev)
adap->algo_data = bit_data;
adap->dev.parent = dev;
+ adap->dev.device_node = dev->device_node;
adap->nr = dev->id;
ret = i2c_bit_add_numbered_bus(adap);
@@ -165,8 +208,14 @@ err_request_sda:
return ret;
}
+static struct of_device_id i2c_gpio_dt_ids[] = {
+ { .compatible = "i2c-gpio", },
+ { /* sentinel */ }
+};
+
static struct driver_d i2c_gpio_driver = {
.name = "i2c-gpio",
.probe = i2c_gpio_probe,
+ .of_compatible = DRV_OF_COMPAT(i2c_gpio_dt_ids),
};
device_platform_driver(i2c_gpio_driver);