aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/drivers/demo
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/drivers/demo')
-rw-r--r--roms/u-boot/drivers/demo/Kconfig30
-rw-r--r--roms/u-boot/drivers/demo/Makefile7
-rw-r--r--roms/u-boot/drivers/demo/demo-pdata.c46
-rw-r--r--roms/u-boot/drivers/demo/demo-shape.c199
-rw-r--r--roms/u-boot/drivers/demo/demo-simple.c47
-rw-r--r--roms/u-boot/drivers/demo/demo-uclass.c80
6 files changed, 409 insertions, 0 deletions
diff --git a/roms/u-boot/drivers/demo/Kconfig b/roms/u-boot/drivers/demo/Kconfig
new file mode 100644
index 000000000..98bb6333c
--- /dev/null
+++ b/roms/u-boot/drivers/demo/Kconfig
@@ -0,0 +1,30 @@
+menu "Demo for driver model"
+
+config DM_DEMO
+ bool "Enable demo uclass support"
+ depends on DM
+ help
+ This uclass allows you to play around with driver model. It provides
+ an interface to a couple of demo devices. You can access it using
+ the 'demo' command or by calling the uclass functions from your
+ own code.
+
+config DM_DEMO_SIMPLE
+ bool "Enable simple demo device for driver model"
+ depends on DM_DEMO
+ help
+ This device allows you to play around with driver model. It prints
+ a message when the 'demo hello' command is executed which targets
+ this device. It can be used to help understand how driver model
+ works.
+
+config DM_DEMO_SHAPE
+ bool "Enable shape demo device for driver model"
+ depends on DM_DEMO
+ help
+ This device allows you to play around with driver model. It prints
+ a shape when the 'demo hello' command is executed which targets
+ this device. It can be used to help understand how driver model
+ works.
+
+endmenu
diff --git a/roms/u-boot/drivers/demo/Makefile b/roms/u-boot/drivers/demo/Makefile
new file mode 100644
index 000000000..9acd918a2
--- /dev/null
+++ b/roms/u-boot/drivers/demo/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2013 Google, Inc
+
+obj-y += demo-uclass.o demo-pdata.o
+obj-$(CONFIG_DM_DEMO_SIMPLE) += demo-simple.o
+obj-$(CONFIG_DM_DEMO_SHAPE) += demo-shape.o
diff --git a/roms/u-boot/drivers/demo/demo-pdata.c b/roms/u-boot/drivers/demo/demo-pdata.c
new file mode 100644
index 000000000..818f77503
--- /dev/null
+++ b/roms/u-boot/drivers/demo/demo-pdata.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 Google, Inc
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm-demo.h>
+
+static const struct dm_demo_pdata red_square = {
+ .colour = "red",
+ .sides = 4.
+};
+static const struct dm_demo_pdata green_triangle = {
+ .colour = "green",
+ .sides = 3.
+};
+static const struct dm_demo_pdata yellow_hexagon = {
+ .colour = "yellow",
+ .sides = 6.
+};
+
+U_BOOT_DRVINFO(demo0) = {
+ .name = "demo_shape_drv",
+ .plat = &red_square,
+};
+
+U_BOOT_DRVINFO(demo1) = {
+ .name = "demo_simple_drv",
+ .plat = &red_square,
+};
+
+U_BOOT_DRVINFO(demo2) = {
+ .name = "demo_shape_drv",
+ .plat = &green_triangle,
+};
+
+U_BOOT_DRVINFO(demo3) = {
+ .name = "demo_simple_drv",
+ .plat = &yellow_hexagon,
+};
+
+U_BOOT_DRVINFO(demo4) = {
+ .name = "demo_shape_drv",
+ .plat = &yellow_hexagon,
+};
diff --git a/roms/u-boot/drivers/demo/demo-shape.c b/roms/u-boot/drivers/demo/demo-shape.c
new file mode 100644
index 000000000..b6b29bcb3
--- /dev/null
+++ b/roms/u-boot/drivers/demo/demo-shape.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 Google, Inc
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <log.h>
+#include <malloc.h>
+#include <dm-demo.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Shape size */
+#define WIDTH 8
+#define HEIGHT 6
+
+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 */
+static int shape_hello(struct udevice *dev, int ch)
+{
+ const struct dm_demo_pdata *pdata = dev_get_plat(dev);
+ struct shape_data *data = dev_get_priv(dev);
+ static const struct shape {
+ int start;
+ int end;
+ int dstart;
+ int dend;
+ } shapes[3] = {
+ { 0, 1, 0, 1 },
+ { 0, WIDTH, 0, 0 },
+ { HEIGHT / 2 - 1, WIDTH - HEIGHT / 2 + 1, -1, 1},
+ };
+ struct shape shape;
+ unsigned int index;
+ int line, pos, inside;
+ const char *colour = pdata->colour;
+ int first = 0;
+
+ if (!ch)
+ ch = pdata->default_char;
+ if (!ch)
+ ch = '@';
+
+ index = (pdata->sides / 2) - 1;
+ if (index >= ARRAY_SIZE(shapes))
+ return -EIO;
+ shape = shapes[index];
+
+ for (line = 0; line < HEIGHT; line++) {
+ first = 1;
+ for (pos = 0; pos < WIDTH; pos++) {
+ inside = pos >= shape.start && pos < shape.end;
+ if (inside) {
+ putc(first ? *colour++ : ch);
+ data->num_chars++;
+ first = 0;
+ if (!*colour)
+ colour = pdata->colour;
+ } else {
+ putc(' ');
+ }
+ }
+ putc('\n');
+ shape.start += shape.dstart;
+ shape.end += shape.dend;
+ if (shape.start < 0) {
+ shape.dstart = -shape.dstart;
+ shape.dend = -shape.dend;
+ shape.start += shape.dstart;
+ shape.end += shape.dend;
+ }
+ }
+
+ return 0;
+}
+
+static int shape_status(struct udevice *dev, int *status)
+{
+ struct shape_data *data = dev_get_priv(dev);
+
+ *status = data->num_chars;
+ 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_of_to_plat(struct udevice *dev)
+{
+ struct dm_demo_pdata *pdata = dev_get_plat(dev);
+ int ret;
+
+ /* Parse the data that is common with all demo devices */
+ ret = demo_parse_dt(dev);
+ if (ret)
+ return ret;
+
+ /* Parse the data that only we need */
+ pdata->default_char = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+ "character", '@');
+
+ 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 },
+ { },
+};
+
+U_BOOT_DRIVER(demo_shape_drv) = {
+ .name = "demo_shape_drv",
+ .of_match = demo_shape_id,
+ .id = UCLASS_DEMO,
+ .of_to_plat = shape_of_to_plat,
+ .ops = &shape_ops,
+ .probe = dm_shape_probe,
+ .remove = dm_shape_remove,
+ .priv_auto = sizeof(struct shape_data),
+ .plat_auto = sizeof(struct dm_demo_pdata),
+};
diff --git a/roms/u-boot/drivers/demo/demo-simple.c b/roms/u-boot/drivers/demo/demo-simple.c
new file mode 100644
index 000000000..28b271f77
--- /dev/null
+++ b/roms/u-boot/drivers/demo/demo-simple.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 Google, Inc
+ *
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis@gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm-demo.h>
+#include <mapmem.h>
+#include <asm/io.h>
+
+static int simple_hello(struct udevice *dev, int ch)
+{
+ const struct dm_demo_pdata *pdata = dev_get_plat(dev);
+
+ printf("Hello from %08x: %s %d\n", (uint)map_to_sysmem(dev), pdata->colour,
+ pdata->sides);
+
+ return 0;
+}
+
+static const struct demo_ops simple_ops = {
+ .hello = simple_hello,
+};
+
+static int demo_shape_of_to_plat(struct udevice *dev)
+{
+ /* Parse the data that is common with all demo devices */
+ return demo_parse_dt(dev);
+}
+
+static const struct udevice_id demo_shape_id[] = {
+ { "demo-simple", 0 },
+ { },
+};
+
+U_BOOT_DRIVER(demo_simple_drv) = {
+ .name = "demo_simple_drv",
+ .of_match = demo_shape_id,
+ .id = UCLASS_DEMO,
+ .of_to_plat = demo_shape_of_to_plat,
+ .ops = &simple_ops,
+ .plat_auto = sizeof(struct dm_demo_pdata),
+};
diff --git a/roms/u-boot/drivers/demo/demo-uclass.c b/roms/u-boot/drivers/demo/demo-uclass.c
new file mode 100644
index 000000000..815f8de64
--- /dev/null
+++ b/roms/u-boot/drivers/demo/demo-uclass.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 Google, Inc
+ *
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis@gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm-demo.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <linux/list.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+UCLASS_DRIVER(demo) = {
+ .name = "demo",
+ .id = UCLASS_DEMO,
+};
+
+int demo_hello(struct udevice *dev, int ch)
+{
+ const struct demo_ops *ops = device_get_ops(dev);
+
+ if (!ops->hello)
+ return -ENOSYS;
+
+ return ops->hello(dev, ch);
+}
+
+int demo_status(struct udevice *dev, int *status)
+{
+ const struct demo_ops *ops = device_get_ops(dev);
+
+ if (!ops->status)
+ return -ENOSYS;
+
+ 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_plat(dev);
+ int dn = dev_of_offset(dev);
+
+ pdata->sides = fdtdec_get_int(gd->fdt_blob, dn, "sides", 0);
+ pdata->colour = fdt_getprop(gd->fdt_blob, dn, "colour", NULL);
+ if (!pdata->sides || !pdata->colour) {
+ debug("%s: Invalid device tree data\n", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}