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:
parent
f21744fba3
commit
3ad9434f2f
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue