diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 60252fd796f6..6be2c454e72e 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -659,6 +659,12 @@ config HID_ORTEK
 	   - Ortek WKB-2000
 	   - Skycable wireless presenter
 
+config HID_OUYA
+	tristate "OUYA Game Controller"
+	depends on USB_HID
+	---help---
+	  Support for OUYA Game Controller.
+
 config HID_PANTHERLORD
 	tristate "Pantherlord/GreenAsia game controller"
 	depends on HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 17a8bd97da9d..4425890934e4 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_HID_MULTITOUCH)	+= hid-multitouch.o
 obj-$(CONFIG_HID_NTI)			+= hid-nti.o
 obj-$(CONFIG_HID_NTRIG)		+= hid-ntrig.o
 obj-$(CONFIG_HID_ORTEK)		+= hid-ortek.o
+obj-$(CONFIG_HID_OUYA)		+= hid-ouya.o
 obj-$(CONFIG_HID_PRODIKEYS)	+= hid-prodikeys.o
 obj-$(CONFIG_HID_PANTHERLORD)	+= hid-pl.o
 obj-$(CONFIG_HID_PENMOUNT)	+= hid-penmount.o
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 0b5cc910f62e..0528efb825fa 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -859,6 +859,9 @@
 #define USB_DEVICE_ID_ORTEK_WKB2000	0x2000
 #define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S	0x8003
 
+#define USB_VENDOR_ID_OUYA 0x2836
+#define USB_DEVICE_ID_OUYA_CONTROLLER 0x0001
+
 #define USB_VENDOR_ID_PLANTRONICS	0x047f
 
 #define USB_VENDOR_ID_PANASONIC		0x04da
diff --git a/drivers/hid/hid-ouya.c b/drivers/hid/hid-ouya.c
new file mode 100644
index 000000000000..16ff142fe49c
--- /dev/null
+++ b/drivers/hid/hid-ouya.c
@@ -0,0 +1,131 @@
+/*
+ *  HID driver for OUYA Game Controller(s)
+ *
+ *  Copyright (c) 2013 OUYA
+ *  Copyright (c) 2013 Gregorios Leach <gleach@fitbit.com>
+ *  Copyright (c) 2018 Lukas Rusak <lorusak@gmail.com>
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+static const unsigned int ouya_absmap[] = {
+	[0x30] = ABS_X,		/* left stick X */
+	[0x31] = ABS_Y,		/* left stick Y */
+	[0x32] = ABS_Z,		/* L2 */
+	[0x33] = ABS_RX,	/* right stick X */
+	[0x34] = ABS_RY,	/* right stick Y */
+	[0x35] = ABS_RZ,	/* R2 */
+};
+
+static const unsigned int ouya_keymap[] = {
+	[0x1] = BTN_SOUTH,	/* O */
+	[0x2] = BTN_WEST,	/* U */
+	[0x3] = BTN_NORTH,	/* Y */
+	[0x4] = BTN_EAST,	/* A */
+	[0x5] = BTN_TL,		/* L1 */
+	[0x6] = BTN_TR,		/* R1 */
+	[0x7] = BTN_THUMBL,	/* L3 */
+	[0x8] = BTN_THUMBR,	/* R3 */
+	[0x9] = BTN_DPAD_UP,	/* Up */
+	[0xa] = BTN_DPAD_DOWN,	/* Down */
+	[0xb] = BTN_DPAD_LEFT,	/* Left */
+	[0xc] = BTN_DPAD_RIGHT, /* Right */
+	[0xd] = BTN_TL2,	/* L2 */
+	[0xe] = BTN_TR2,	/* R2 */
+	[0xf] = BTN_MODE,	/* Power */
+};
+
+static int ouya_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+			       struct hid_field *field, struct hid_usage *usage,
+			       unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
+		unsigned int key = usage->hid & HID_USAGE;
+
+		if (key >= ARRAY_SIZE(ouya_keymap))
+			return -1;
+
+		key = ouya_keymap[key];
+		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
+
+		return 1;
+
+	} else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) {
+		unsigned int abs = usage->hid & HID_USAGE;
+
+		if (abs >= ARRAY_SIZE(ouya_absmap))
+			return -1;
+
+		abs = ouya_absmap[abs];
+		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs);
+
+		return 1;
+	}
+
+	return 0;
+}
+
+static int ouya_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		hid_err(hdev, "parse failed\n");
+		goto err_free;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE);
+	if (ret) {
+		hid_err(hdev, "hw start failed\n");
+		goto err_free;
+	}
+
+	return 0;
+
+err_free:
+	return ret;
+}
+
+static void ouya_remove(struct hid_device *hdev)
+{
+	hid_hw_stop(hdev);
+	kfree(hid_get_drvdata(hdev));
+}
+
+static const struct hid_device_id ouya_devices[] = {
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_OUYA, USB_DEVICE_ID_OUYA_CONTROLLER) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, ouya_devices);
+
+static struct hid_driver ouya_driver = {
+	.name = "ouya",
+	.id_table = ouya_devices,
+	.input_mapping = ouya_input_mapping,
+	.probe = ouya_probe,
+	.remove = ouya_remove,
+};
+
+static int __init ouya_init(void)
+{
+	return hid_register_driver(&ouya_driver);
+}
+
+static void __exit ouya_exit(void)
+{
+	hid_unregister_driver(&ouya_driver);
+}
+
+module_init(ouya_init);
+module_exit(ouya_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Lukas Rusak <lorusak@gmail.com>");
+MODULE_AUTHOR("Gregorios Leach <gleach@fitbit.com>");
+MODULE_DESCRIPTION("Ouya Controller Driver");
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 587e2681a53f..b5adc13e0df1 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -538,6 +538,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
 #endif
+#if IS_ENABLED(CONFIG_HID_OUYA)
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_OUYA, USB_DEVICE_ID_OUYA_CONTROLLER) },
+#endif
 #if IS_ENABLED(CONFIG_HID_PANTHERLORD)
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
