From a02af4aeece40e93bc7d79cd5dc912409efb7020 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:31 -0700 Subject: dm: demo: Add a simple GPIO demonstration Add a new 'demo light' command which uses GPIOs to control imaginary lights. Each light is assigned a bit number in the overall value. This provides an example driver for using the new GPIO API. Signed-off-by: Simon Glass --- drivers/demo/demo-shape.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/demo/demo-uclass.c | 20 +++++++++++++ 2 files changed, 91 insertions(+) (limited to 'drivers') diff --git a/drivers/demo/demo-shape.c b/drivers/demo/demo-shape.c index 3fa9c59947..d908736cff 100644 --- a/drivers/demo/demo-shape.c +++ b/drivers/demo/demo-shape.c @@ -11,6 +11,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -20,6 +21,8 @@ DECLARE_GLOBAL_DATA_PTR; struct shape_data { int num_chars; /* Number of non-space characters output so far */ + struct gpio_desc gpio_desc[8]; + int gpio_count; }; /* Crazy little function to draw shapes on the console */ @@ -89,9 +92,52 @@ static int shape_status(struct udevice *dev, int *status) return 0; } +static int set_light(struct udevice *dev, int light) +{ + struct shape_data *priv = dev_get_priv(dev); + struct gpio_desc *desc; + int ret; + int i; + + desc = priv->gpio_desc; + for (i = 0; i < priv->gpio_count; i++, desc++) { + uint mask = 1 << i; + + ret = dm_gpio_set_value(desc, light & mask); + if (ret < 0) + return ret; + } + + return 0; +} + +static int get_light(struct udevice *dev) +{ + struct shape_data *priv = dev_get_priv(dev); + struct gpio_desc *desc; + uint value = 0; + int ret; + int i; + + desc = priv->gpio_desc; + for (i = 0; i < priv->gpio_count; i++, desc++) { + uint mask = 1 << i; + + ret = dm_gpio_get_value(desc); + if (ret < 0) + return ret; + if (ret) + value |= mask; + } + + return value; +} + static const struct demo_ops shape_ops = { .hello = shape_hello, .status = shape_status, + .get_light = get_light, + .set_light = set_light, }; static int shape_ofdata_to_platdata(struct udevice *dev) @@ -111,6 +157,29 @@ static int shape_ofdata_to_platdata(struct udevice *dev) return 0; } +static int dm_shape_probe(struct udevice *dev) +{ + struct shape_data *priv = dev_get_priv(dev); + int ret; + + ret = gpio_request_list_by_name(dev, "light-gpios", priv->gpio_desc, + ARRAY_SIZE(priv->gpio_desc), + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + if (ret < 0) + return ret; + priv->gpio_count = ret; + debug("%s: %d GPIOs\n", __func__, priv->gpio_count); + + return 0; +} + +static int dm_shape_remove(struct udevice *dev) +{ + struct shape_data *priv = dev_get_priv(dev); + + return gpio_free_list(dev, priv->gpio_desc, priv->gpio_count); +} + static const struct udevice_id demo_shape_id[] = { { "demo-shape", 0 }, { }, @@ -122,6 +191,8 @@ U_BOOT_DRIVER(demo_shape_drv) = { .id = UCLASS_DEMO, .ofdata_to_platdata = shape_ofdata_to_platdata, .ops = &shape_ops, + .probe = dm_shape_probe, + .remove = dm_shape_remove, .priv_auto_alloc_size = sizeof(struct shape_data), .platdata_auto_alloc_size = sizeof(struct dm_demo_pdata), }; diff --git a/drivers/demo/demo-uclass.c b/drivers/demo/demo-uclass.c index f6510d602c..725f06898f 100644 --- a/drivers/demo/demo-uclass.c +++ b/drivers/demo/demo-uclass.c @@ -43,6 +43,26 @@ int demo_status(struct udevice *dev, int *status) return ops->status(dev, status); } +int demo_get_light(struct udevice *dev) +{ + const struct demo_ops *ops = device_get_ops(dev); + + if (!ops->get_light) + return -ENOSYS; + + return ops->get_light(dev); +} + +int demo_set_light(struct udevice *dev, int light) +{ + const struct demo_ops *ops = device_get_ops(dev); + + if (!ops->set_light) + return -ENOSYS; + + return ops->set_light(dev, light); +} + int demo_parse_dt(struct udevice *dev) { struct dm_demo_pdata *pdata = dev_get_platdata(dev); -- cgit v1.2.1