diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index c2b365af11d..6bfee40ccac 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -100,3 +100,12 @@ config TWL4030_INPUT
 	bool "Enable TWL4030 Input controller"
 	help
 	  Enable TWL4030 Input controller
+
+config MOUSE
+	bool "Support for mice and other pointing devices"
+	default y if SANDBOX
+	help
+	  This allows U-Boot to access mouse input, typically needed for
+	  graphics boot menus and the like. The driver can provide mouse
+	  events based on user interaction and these can be used to control
+	  U-Boot's operation.
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 8d4107b8848..a4938d19903 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -15,3 +15,6 @@ obj-$(CONFIG_I8042_KEYB) += i8042.o
 obj-$(CONFIG_TEGRA_KEYBOARD) += input.o tegra-kbc.o
 obj-$(CONFIG_TWL4030_INPUT) += twl4030.o
 endif
+
+obj-$(CONFIG_MOUSE) += mouse-uclass.o
+obj-$(CONFIG_SANDBOX) += sandbox_mouse.o
diff --git a/drivers/input/mouse-uclass.c b/drivers/input/mouse-uclass.c
new file mode 100644
index 00000000000..ddf948f7e78
--- /dev/null
+++ b/drivers/input/mouse-uclass.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <dm.h>
+#include <mouse.h>
+
+int mouse_get_event(struct udevice *dev, struct mouse_event *evt)
+{
+	struct mouse_ops *ops = mouse_get_ops(dev);
+	int ret;
+
+	if (!ops->get_event)
+		return -ENOSYS;
+
+	ret = ops->get_event(dev, evt);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+UCLASS_DRIVER(mouse) = {
+	.id		= UCLASS_MOUSE,
+	.name		= "mouse",
+};
diff --git a/drivers/input/sandbox_mouse.c b/drivers/input/sandbox_mouse.c
new file mode 100644
index 00000000000..4aedf0fdf2d
--- /dev/null
+++ b/drivers/input/sandbox_mouse.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <dm.h>
+#include <mouse.h>
+#include <asm/sdl.h>
+
+static int mouse_sandbox_get_event(struct udevice *dev,
+				   struct mouse_event *event)
+{
+	int ret;
+
+	ret = sandbox_sdl_get_mouse_event(event);
+
+	return ret;
+}
+
+const struct mouse_ops mouse_sandbox_ops = {
+	.get_event	= mouse_sandbox_get_event,
+};
+
+static const struct udevice_id mouse_sandbox_ids[] = {
+	{ .compatible = "sandbox,mouse" },
+	{ }
+};
+
+U_BOOT_DRIVER(mouse_sandbox) = {
+	.name	= "mouse_sandbox",
+	.id	= UCLASS_MOUSE,
+	.of_match = mouse_sandbox_ids,
+	.ops	= &mouse_sandbox_ops,
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index c558c95f465..a424ef00fc9 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -97,6 +97,7 @@ enum uclass_id {
 	UCLASS_MISC,		/* Miscellaneous device */
 	UCLASS_MMC,		/* SD / MMC card or chip */
 	UCLASS_MOD_EXP,		/* RSA Mod Exp device */
+	UCLASS_MOUSE,		/* Mouse, trackpad or other pointing device */
 	UCLASS_MTD,		/* Memory Technology Device (MTD) device */
 	UCLASS_MUX,		/* Multiplexer device */
 	UCLASS_NOP,		/* No-op devices */
diff --git a/include/mouse.h b/include/mouse.h
new file mode 100644
index 00000000000..81704047f5d
--- /dev/null
+++ b/include/mouse.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Mouse/trackpad/touchscreen input uclass
+ *
+ * Copyright 2020 Google LLC
+ */
+
+#ifndef _MOUSE_H
+#define _MOUSE_H
+
+enum mouse_ev_t {
+	MOUSE_EV_NULL,
+	MOUSE_EV_MOTION,
+	MOUSE_EV_BUTTON,
+};
+
+enum mouse_state_t {
+	BUTTON_LEFT		= 1 << 0,
+	BUTTON_MIDDLE		= 1 << 1,
+	BUTTON_RIGHT		= 1 << 2,
+	BUTTON_SCROLL_PLUS	= 1 << 3,
+	BUTTON_SCROLL_MINUS	= 1 << 4,
+};
+
+enum mouse_press_state_t {
+	BUTTON_RELEASED		= 0,
+	BUTTON_PRESSED,
+};
+
+/**
+ * struct mouse_event - information about a mouse event
+ *
+ * @type: Mouse event ype
+ */
+struct mouse_event {
+	enum mouse_ev_t type;
+	union {
+		/**
+		 * @state: Mouse state (enum mouse_state_t bitmask)
+		 * @x: X position of mouse
+		 * @y: Y position of mouse
+		 * @xrel: Relative motion in X direction
+		 * @yrel: Relative motion in Y direction
+		 */
+		struct mouse_motion {
+			unsigned char state;
+			unsigned short x;
+			unsigned short y;
+			short xrel;
+			short yrel;
+		} motion;
+
+		/**
+		 * @button: Button number that was pressed/released (BUTTON_...)
+		 * @state: BUTTON_PRESSED / BUTTON_RELEASED
+		 * @clicks: number of clicks (normally 1; 2 = double-click)
+		 * @x: X position of mouse
+		 * @y: Y position of mouse
+		 */
+		struct mouse_button {
+			unsigned char button;
+			unsigned char press_state;
+			unsigned char clicks;
+			unsigned short x;
+			unsigned short y;
+		} button;
+	};
+};
+
+struct mouse_ops {
+	int (*get_event)(struct udevice *dev, struct mouse_event *event);
+};
+
+#define mouse_get_ops(dev)	((struct mouse_ops *)(dev)->driver->ops)
+
+int mouse_get_event(struct udevice *dev, struct mouse_event *event);
+
+#endif
