9
0
Fork 0

i2c: i2c_gpio: add devicetree support

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Antony Pavlov 2014-06-24 01:21:11 +04:00 committed by Sascha Hauer
parent f21744fba3
commit 3ad9434f2f
2 changed files with 107 additions and 3 deletions

View File

@ -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);

View File

@ -35,10 +35,65 @@ static inline int of_get_named_gpio_flags(struct device_node *np,
#endif /* CONFIG_OF_GPIO */
/**
* of_gpio_named_count() - Count GPIOs for a device
* @np: device node to count GPIOs for
* @propname: property name containing gpio specifier(s)
*
* The function returns the count of GPIOs specified for a node.
* Note that the empty GPIO specifiers count too. Returns either
* Number of gpios defined in property,
* -EINVAL for an incorrectly formed gpios property, or
* -ENOENT for a missing gpios property
*
* Example:
* gpios = <0
* &gpio1 1 2
* 0
* &gpio2 3 4>;
*
* The above example defines four GPIOs, two of which are not specified.
* This function will return '4'
*/
static inline int of_gpio_named_count(struct device_node *np, const char* propname)
{
return of_count_phandle_with_args(np, propname, "#gpio-cells");
}
/**
* of_gpio_count() - Count GPIOs for a device
* @np: device node to count GPIOs for
*
* Same as of_gpio_named_count, but hard coded to use the 'gpios' property
*/
static inline int of_gpio_count(struct device_node *np)
{
return of_gpio_named_count(np, "gpios");
}
static inline int of_get_gpio_flags(struct device_node *np, int index,
enum of_gpio_flags *flags)
{
return of_get_named_gpio_flags(np, "gpios", index, flags);
}
static inline int of_get_named_gpio(struct device_node *np,
const char *list_name, int index)
{
return of_get_named_gpio_flags(np, list_name, index, NULL);
}
/**
* of_get_gpio() - Get a GPIO number to use with GPIO API
* @np: device node to get GPIO from
* @index: index of the GPIO
*
* Returns GPIO number to use with Linux generic GPIO API, or one of the errno
* value on the error condition.
*/
static inline int of_get_gpio(struct device_node *np, int index)
{
return of_get_gpio_flags(np, index, NULL);
}
#endif