diff options
Diffstat (limited to 'roms/u-boot/drivers/demo')
-rw-r--r-- | roms/u-boot/drivers/demo/Kconfig | 30 | ||||
-rw-r--r-- | roms/u-boot/drivers/demo/Makefile | 7 | ||||
-rw-r--r-- | roms/u-boot/drivers/demo/demo-pdata.c | 46 | ||||
-rw-r--r-- | roms/u-boot/drivers/demo/demo-shape.c | 199 | ||||
-rw-r--r-- | roms/u-boot/drivers/demo/demo-simple.c | 47 | ||||
-rw-r--r-- | roms/u-boot/drivers/demo/demo-uclass.c | 80 |
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; +} |