diff options
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/Makefile | 2 | ||||
-rw-r--r-- | drivers/misc/misc_sandbox.c | 133 |
2 files changed, 134 insertions, 1 deletions
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 4ce9d213f0..f66c9e8839 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -39,7 +39,7 @@ ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SANDBOX) += spltest_sandbox.o endif endif -obj-$(CONFIG_SANDBOX) += syscon_sandbox.o +obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o obj-$(CONFIG_TEGRA_CAR) += tegra_car.o obj-$(CONFIG_TEGRA186_BPMP) += tegra186_bpmp.o obj-$(CONFIG_TWL4030_LED) += twl4030_led.o diff --git a/drivers/misc/misc_sandbox.c b/drivers/misc/misc_sandbox.c new file mode 100644 index 0000000000..e4164f76fb --- /dev/null +++ b/drivers/misc/misc_sandbox.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018 + * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + */ + +#include <common.h> +#include <dm.h> +#include <misc.h> + +struct misc_sandbox_priv { + u8 mem[128]; + ulong last_ioctl; + bool enabled; +}; + +int misc_sandbox_read(struct udevice *dev, int offset, void *buf, int size) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + memcpy(buf, priv->mem + offset, size); + + return 0; +} + +int misc_sandbox_write(struct udevice *dev, int offset, const void *buf, + int size) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + memcpy(priv->mem + offset, buf, size); + + return 0; +} + +int misc_sandbox_ioctl(struct udevice *dev, unsigned long request, void *buf) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + priv->last_ioctl = request; + + return 0; +} + +int misc_sandbox_call(struct udevice *dev, int msgid, void *tx_msg, + int tx_size, void *rx_msg, int rx_size) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + if (msgid == 0) { + int num = *(int *)tx_msg; + + switch (num) { + case 0: + strncpy(rx_msg, "Zero", rx_size); + break; + case 1: + strncpy(rx_msg, "One", rx_size); + break; + case 2: + strncpy(rx_msg, "Two", rx_size); + break; + default: + return -EINVAL; + } + } + + if (msgid == 1) { + int num = *(int *)tx_msg; + + switch (num) { + case 0: + strncpy(rx_msg, "Forty", rx_size); + break; + case 1: + strncpy(rx_msg, "Forty-one", rx_size); + break; + case 2: + strncpy(rx_msg, "Forty-two", rx_size); + break; + default: + return -EINVAL; + } + } + + if (msgid == 2) + memcpy(rx_msg, &priv->last_ioctl, sizeof(priv->last_ioctl)); + + if (msgid == 3) + memcpy(rx_msg, &priv->enabled, sizeof(priv->enabled)); + + return 0; +} + +int misc_sandbox_set_enabled(struct udevice *dev, bool val) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + priv->enabled = !priv->enabled; + + return 0; +} + +static const struct misc_ops misc_sandbox_ops = { + .read = misc_sandbox_read, + .write = misc_sandbox_write, + .ioctl = misc_sandbox_ioctl, + .call = misc_sandbox_call, + .set_enabled = misc_sandbox_set_enabled, +}; + +int misc_sandbox_probe(struct udevice *dev) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + priv->enabled = true; + + return 0; +} + +static const struct udevice_id misc_sandbox_ids[] = { + { .compatible = "sandbox,misc_sandbox" }, + { } +}; + +U_BOOT_DRIVER(misc_sandbox) = { + .name = "misc_sandbox", + .id = UCLASS_MISC, + .ops = &misc_sandbox_ops, + .of_match = misc_sandbox_ids, + .probe = misc_sandbox_probe, + .priv_auto_alloc_size = sizeof(struct misc_sandbox_priv), +}; |