diff options
author | Antony Pavlov <antonynpavlov@gmail.com> | 2014-06-24 01:21:11 +0400 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2014-06-25 08:34:48 +0200 |
commit | 3ad9434f2faed97331670de1f5a6317df8c493b5 (patch) | |
tree | b2a9c6686b01d1a756389f53610534e6b57463bf /drivers | |
parent | f21744fba3eebb3eb90954c7397226047ecd0d98 (diff) | |
download | barebox-3ad9434f2faed97331670de1f5a6317df8c493b5.tar.gz barebox-3ad9434f2faed97331670de1f5a6317df8c493b5.tar.xz |
i2c: i2c_gpio: add devicetree support
Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/i2c-gpio.c | 55 |
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", ®)) + 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); |