]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/demo/demo-shape.c
dm: demo: Add a simple GPIO demonstration
[karo-tx-uboot.git] / drivers / demo / demo-shape.c
index 3fa9c5994703d473494a4d2199ecae3e34a0c9c0..d908736cffe31e2acb1bfa787bc12b05265543b7 100644 (file)
@@ -11,6 +11,7 @@
 #include <malloc.h>
 #include <dm-demo.h>
 #include <asm/io.h>
+#include <asm/gpio.h>
 
 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),
 };