From c1866015488f3055bd95a5a8b666b5f42719a066 Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Mon, 7 Jan 2019 19:27:29 +0000 Subject: [PATCH] linux (Generic/RPi): XBOX remote support now upstream --- .../linux-052-xbox_dvd_remote_support.patch | 466 ------------------ .../linux-052-xbox_dvd_remote_support.patch | 466 ------------------ 2 files changed, 932 deletions(-) delete mode 100644 packages/linux/patches/default/linux-052-xbox_dvd_remote_support.patch delete mode 100644 packages/linux/patches/raspberrypi/linux-052-xbox_dvd_remote_support.patch diff --git a/packages/linux/patches/default/linux-052-xbox_dvd_remote_support.patch b/packages/linux/patches/default/linux-052-xbox_dvd_remote_support.patch deleted file mode 100644 index 8db97ddb2f..0000000000 --- a/packages/linux/patches/default/linux-052-xbox_dvd_remote_support.patch +++ /dev/null @@ -1,466 +0,0 @@ -From 4d331d301222dc0585ab8864a842b3e460b1f744 Mon Sep 17 00:00:00 2001 -From: Benjamin Valentin -Date: Thu, 4 Oct 2018 02:57:10 +0200 -Subject: [PATCH] media: rc: add driver for Xbox DVD Movie Playback Kit - -The Xbox DVD Movie Playback Kit is a USB dongle with an IR remote for the -Original Xbox. - -Historically it has been supported by the out-of-tree lirc_xbox driver, -but this one has fallen out of favour and was just dropped from popular -Kodi (formerly XBMC) distributions. - -This driver is heaviely based on the ati_remote driver where all the -boilerplate was taken from - I was mostly just removing code. - -Signed-off-by: Benjamin Valentin -Signed-off-by: Sean Young ---- - drivers/media/rc/Kconfig | 12 + - drivers/media/rc/Makefile | 1 + - drivers/media/rc/keymaps/Makefile | 1 + - drivers/media/rc/keymaps/rc-xbox-dvd.c | 63 +++++ - drivers/media/rc/xbox_remote.c | 306 +++++++++++++++++++++++++ - include/media/rc-map.h | 1 + - 6 files changed, 384 insertions(+) - create mode 100644 drivers/media/rc/keymaps/rc-xbox-dvd.c - create mode 100644 drivers/media/rc/xbox_remote.c - -diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig -index 1021c08a9ba4..8a216068a35a 100644 ---- a/drivers/media/rc/Kconfig -+++ b/drivers/media/rc/Kconfig -@@ -493,6 +493,18 @@ config IR_TANGO - The HW decoder supports NEC, RC-5, RC-6 IR protocols. - When compiled as a module, look for tango-ir. - -+config RC_XBOX_DVD -+ tristate "Xbox DVD Movie Playback Kit" -+ depends on RC_CORE -+ depends on USB_ARCH_HAS_HCD -+ select USB -+ help -+ Say Y here if you want to use the Xbox DVD Movie Playback Kit. -+ These are IR remotes with USB receivers for the Original Xbox (2001). -+ -+ To compile this driver as a module, choose M here: the module will be -+ called xbox_remote. -+ - config IR_ZX - tristate "ZTE ZX IR remote control" - depends on RC_CORE -diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile -index e0340d043fe8..92c163816849 100644 ---- a/drivers/media/rc/Makefile -+++ b/drivers/media/rc/Makefile -@@ -48,3 +48,4 @@ obj-$(CONFIG_IR_SIR) += sir_ir.o - obj-$(CONFIG_IR_MTK) += mtk-cir.o - obj-$(CONFIG_IR_ZX) += zx-irdec.o - obj-$(CONFIG_IR_TANGO) += tango-ir.o -+obj-$(CONFIG_RC_XBOX_DVD) += xbox_remote.o -diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile -index d6b913a3032d..5b1399af6b3a 100644 ---- a/drivers/media/rc/keymaps/Makefile -+++ b/drivers/media/rc/keymaps/Makefile -@@ -116,4 +116,5 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ - rc-winfast.o \ - rc-winfast-usbii-deluxe.o \ - rc-su3000.o \ -+ rc-xbox-dvd.o \ - rc-zx-irdec.o -diff --git a/drivers/media/rc/keymaps/rc-xbox-dvd.c b/drivers/media/rc/keymaps/rc-xbox-dvd.c -new file mode 100644 -index 000000000000..af387244636b ---- /dev/null -+++ b/drivers/media/rc/keymaps/rc-xbox-dvd.c -@@ -0,0 +1,63 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+// Keytable for Xbox DVD remote -+// Copyright (c) 2018 by Benjamin Valentin -+ -+#include -+#include -+ -+/* based on lircd.conf.xbox */ -+static struct rc_map_table xbox_dvd[] = { -+ {0xa0b, KEY_OK}, -+ {0xaa6, KEY_UP}, -+ {0xaa7, KEY_DOWN}, -+ {0xaa8, KEY_RIGHT}, -+ {0xaa9, KEY_LEFT}, -+ {0xac3, KEY_INFO}, -+ -+ {0xac6, KEY_9}, -+ {0xac7, KEY_8}, -+ {0xac8, KEY_7}, -+ {0xac9, KEY_6}, -+ {0xaca, KEY_5}, -+ {0xacb, KEY_4}, -+ {0xacc, KEY_3}, -+ {0xacd, KEY_2}, -+ {0xace, KEY_1}, -+ {0xacf, KEY_0}, -+ -+ {0xad5, KEY_ANGLE}, -+ {0xad8, KEY_BACK}, -+ {0xadd, KEY_PREVIOUSSONG}, -+ {0xadf, KEY_NEXTSONG}, -+ {0xae0, KEY_STOP}, -+ {0xae2, KEY_REWIND}, -+ {0xae3, KEY_FASTFORWARD}, -+ {0xae5, KEY_TITLE}, -+ {0xae6, KEY_PAUSE}, -+ {0xaea, KEY_PLAY}, -+ {0xaf7, KEY_MENU}, -+}; -+ -+static struct rc_map_list xbox_dvd_map = { -+ .map = { -+ .scan = xbox_dvd, -+ .size = ARRAY_SIZE(xbox_dvd), -+ .rc_proto = RC_PROTO_UNKNOWN, -+ .name = RC_MAP_XBOX_DVD, -+ } -+}; -+ -+static int __init init_rc_map(void) -+{ -+ return rc_map_register(&xbox_dvd_map); -+} -+ -+static void __exit exit_rc_map(void) -+{ -+ rc_map_unregister(&xbox_dvd_map); -+} -+ -+module_init(init_rc_map) -+module_exit(exit_rc_map) -+ -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c -new file mode 100644 -index 000000000000..07ed9be24a60 ---- /dev/null -+++ b/drivers/media/rc/xbox_remote.c -@@ -0,0 +1,306 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+// Driver for Xbox DVD Movie Playback Kit -+// Copyright (c) 2018 by Benjamin Valentin -+ -+/* -+ * Xbox DVD Movie Playback Kit USB IR dongle support -+ * -+ * The driver was derived from the ati_remote driver 2.2.1 -+ * and used information from lirc_xbox.c -+ * -+ * Copyright (c) 2011, 2012 Anssi Hannula -+ * Copyright (c) 2004 Torrey Hoffman -+ * Copyright (c) 2002 Vladimir Dergachev -+ * Copyright (c) 2003-2004 Paul Miller -+ */ -+ -+#include -+#include -+#include -+#include -+ -+/* -+ * Module and Version Information -+ */ -+#define DRIVER_VERSION "1.0.0" -+#define DRIVER_AUTHOR "Benjamin Valentin " -+#define DRIVER_DESC "Xbox DVD USB Remote Control" -+ -+#define NAME_BUFSIZE 80 /* size of product name, path buffers */ -+#define DATA_BUFSIZE 8 /* size of URB data buffers */ -+ -+/* -+ * USB vendor ids for XBOX DVD Dongles -+ */ -+#define VENDOR_GAMESTER 0x040b -+#define VENDOR_MICROSOFT 0x045e -+ -+static const struct usb_device_id xbox_remote_table[] = { -+ /* Gamester Xbox DVD Movie Playback Kit IR */ -+ { -+ USB_DEVICE(VENDOR_GAMESTER, 0x6521), -+ }, -+ /* Microsoft Xbox DVD Movie Playback Kit IR */ -+ { -+ USB_DEVICE(VENDOR_MICROSOFT, 0x0284), -+ }, -+ {} /* Terminating entry */ -+}; -+ -+MODULE_DEVICE_TABLE(usb, xbox_remote_table); -+ -+struct xbox_remote { -+ struct rc_dev *rdev; -+ struct usb_device *udev; -+ struct usb_interface *interface; -+ -+ struct urb *irq_urb; -+ unsigned char inbuf[DATA_BUFSIZE] __aligned(sizeof(u16)); -+ -+ char rc_name[NAME_BUFSIZE]; -+ char rc_phys[NAME_BUFSIZE]; -+}; -+ -+static int xbox_remote_rc_open(struct rc_dev *rdev) -+{ -+ struct xbox_remote *xbox_remote = rdev->priv; -+ -+ /* On first open, submit the read urb which was set up previously. */ -+ xbox_remote->irq_urb->dev = xbox_remote->udev; -+ if (usb_submit_urb(xbox_remote->irq_urb, GFP_KERNEL)) { -+ dev_err(&xbox_remote->interface->dev, -+ "%s: usb_submit_urb failed!\n", __func__); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static void xbox_remote_rc_close(struct rc_dev *rdev) -+{ -+ struct xbox_remote *xbox_remote = rdev->priv; -+ -+ usb_kill_urb(xbox_remote->irq_urb); -+} -+ -+/* -+ * xbox_remote_report_input -+ */ -+static void xbox_remote_input_report(struct urb *urb) -+{ -+ struct xbox_remote *xbox_remote = urb->context; -+ unsigned char *data = xbox_remote->inbuf; -+ -+ /* -+ * data[0] = 0x00 -+ * data[1] = length - always 0x06 -+ * data[2] = the key code -+ * data[3] = high part of key code -+ * data[4] = last_press_ms (low) -+ * data[5] = last_press_ms (high) -+ */ -+ -+ /* Deal with strange looking inputs */ -+ if (urb->actual_length != 6 || urb->actual_length != data[1]) { -+ dev_warn(&urb->dev->dev, "Weird data, len=%d: %*ph\n", -+ urb->actual_length, urb->actual_length, data); -+ return; -+ } -+ -+ rc_keydown(xbox_remote->rdev, RC_PROTO_UNKNOWN, -+ le16_to_cpup((__le16*)(data + 2)), 0); -+} -+ -+/* -+ * xbox_remote_irq_in -+ */ -+static void xbox_remote_irq_in(struct urb *urb) -+{ -+ struct xbox_remote *xbox_remote = urb->context; -+ int retval; -+ -+ switch (urb->status) { -+ case 0: /* success */ -+ xbox_remote_input_report(urb); -+ break; -+ case -ECONNRESET: /* unlink */ -+ case -ENOENT: -+ case -ESHUTDOWN: -+ dev_dbg(&xbox_remote->interface->dev, -+ "%s: urb error status, unlink?\n", -+ __func__); -+ return; -+ default: /* error */ -+ dev_dbg(&xbox_remote->interface->dev, -+ "%s: Nonzero urb status %d\n", -+ __func__, urb->status); -+ } -+ -+ retval = usb_submit_urb(urb, GFP_ATOMIC); -+ if (retval) -+ dev_err(&xbox_remote->interface->dev, -+ "%s: usb_submit_urb()=%d\n", -+ __func__, retval); -+} -+ -+static void xbox_remote_rc_init(struct xbox_remote *xbox_remote) -+{ -+ struct rc_dev *rdev = xbox_remote->rdev; -+ -+ rdev->priv = xbox_remote; -+ rdev->allowed_protocols = RC_PROTO_BIT_UNKNOWN; -+ rdev->driver_name = "xbox_remote"; -+ -+ rdev->open = xbox_remote_rc_open; -+ rdev->close = xbox_remote_rc_close; -+ -+ rdev->device_name = xbox_remote->rc_name; -+ rdev->input_phys = xbox_remote->rc_phys; -+ -+ usb_to_input_id(xbox_remote->udev, &rdev->input_id); -+ rdev->dev.parent = &xbox_remote->interface->dev; -+} -+ -+static int xbox_remote_initialize(struct xbox_remote *xbox_remote, -+ struct usb_endpoint_descriptor *endpoint_in) -+{ -+ struct usb_device *udev = xbox_remote->udev; -+ int pipe, maxp; -+ -+ /* Set up irq_urb */ -+ pipe = usb_rcvintpipe(udev, endpoint_in->bEndpointAddress); -+ maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); -+ maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp; -+ -+ usb_fill_int_urb(xbox_remote->irq_urb, udev, pipe, xbox_remote->inbuf, -+ maxp, xbox_remote_irq_in, xbox_remote, -+ endpoint_in->bInterval); -+ -+ return 0; -+} -+ -+/* -+ * xbox_remote_probe -+ */ -+static int xbox_remote_probe(struct usb_interface *interface, -+ const struct usb_device_id *id) -+{ -+ struct usb_device *udev = interface_to_usbdev(interface); -+ struct usb_host_interface *iface_host = interface->cur_altsetting; -+ struct usb_endpoint_descriptor *endpoint_in; -+ struct xbox_remote *xbox_remote; -+ struct rc_dev *rc_dev; -+ int err = -ENOMEM; -+ -+ // why is there also a device with no endpoints? -+ if (iface_host->desc.bNumEndpoints == 0) -+ return -ENODEV; -+ -+ if (iface_host->desc.bNumEndpoints != 1) { -+ pr_err("%s: Unexpected desc.bNumEndpoints: %d\n", -+ __func__, iface_host->desc.bNumEndpoints); -+ return -ENODEV; -+ } -+ -+ endpoint_in = &iface_host->endpoint[0].desc; -+ -+ if (!usb_endpoint_is_int_in(endpoint_in)) { -+ pr_err("%s: Unexpected endpoint_in\n", __func__); -+ return -ENODEV; -+ } -+ if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) { -+ pr_err("%s: endpoint_in message size==0?\n", __func__); -+ return -ENODEV; -+ } -+ -+ xbox_remote = kzalloc(sizeof(*xbox_remote), GFP_KERNEL); -+ rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); -+ if (!xbox_remote || !rc_dev) -+ goto exit_free_dev_rdev; -+ -+ /* Allocate URB buffer */ -+ xbox_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); -+ if (!xbox_remote->irq_urb) -+ goto exit_free_buffers; -+ -+ xbox_remote->udev = udev; -+ xbox_remote->rdev = rc_dev; -+ xbox_remote->interface = interface; -+ -+ usb_make_path(udev, xbox_remote->rc_phys, sizeof(xbox_remote->rc_phys)); -+ -+ strlcat(xbox_remote->rc_phys, "/input0", sizeof(xbox_remote->rc_phys)); -+ -+ snprintf(xbox_remote->rc_name, sizeof(xbox_remote->rc_name), "%s%s%s", -+ udev->manufacturer ?: "", -+ udev->manufacturer && udev->product ? " " : "", -+ udev->product ?: ""); -+ -+ if (!strlen(xbox_remote->rc_name)) -+ snprintf(xbox_remote->rc_name, sizeof(xbox_remote->rc_name), -+ DRIVER_DESC "(%04x,%04x)", -+ le16_to_cpu(xbox_remote->udev->descriptor.idVendor), -+ le16_to_cpu(xbox_remote->udev->descriptor.idProduct)); -+ -+ rc_dev->map_name = RC_MAP_XBOX_DVD; /* default map */ -+ -+ xbox_remote_rc_init(xbox_remote); -+ -+ /* Device Hardware Initialization */ -+ err = xbox_remote_initialize(xbox_remote, endpoint_in); -+ if (err) -+ goto exit_kill_urbs; -+ -+ /* Set up and register rc device */ -+ err = rc_register_device(xbox_remote->rdev); -+ if (err) -+ goto exit_kill_urbs; -+ -+ usb_set_intfdata(interface, xbox_remote); -+ -+ return 0; -+ -+exit_kill_urbs: -+ usb_kill_urb(xbox_remote->irq_urb); -+exit_free_buffers: -+ usb_free_urb(xbox_remote->irq_urb); -+exit_free_dev_rdev: -+ rc_free_device(rc_dev); -+ kfree(xbox_remote); -+ -+ return err; -+} -+ -+/* -+ * xbox_remote_disconnect -+ */ -+static void xbox_remote_disconnect(struct usb_interface *interface) -+{ -+ struct xbox_remote *xbox_remote; -+ -+ xbox_remote = usb_get_intfdata(interface); -+ usb_set_intfdata(interface, NULL); -+ if (!xbox_remote) { -+ dev_warn(&interface->dev, "%s - null device?\n", __func__); -+ return; -+ } -+ -+ usb_kill_urb(xbox_remote->irq_urb); -+ rc_unregister_device(xbox_remote->rdev); -+ usb_free_urb(xbox_remote->irq_urb); -+ kfree(xbox_remote); -+} -+ -+/* usb specific object to register with the usb subsystem */ -+static struct usb_driver xbox_remote_driver = { -+ .name = "xbox_remote", -+ .probe = xbox_remote_probe, -+ .disconnect = xbox_remote_disconnect, -+ .id_table = xbox_remote_table, -+}; -+ -+module_usb_driver(xbox_remote_driver); -+ -+MODULE_AUTHOR(DRIVER_AUTHOR); -+MODULE_DESCRIPTION(DRIVER_DESC); -+MODULE_LICENSE("GPL"); -diff --git a/include/media/rc-map.h b/include/media/rc-map.h -index bfa3017cecba..d621acadfbf3 100644 ---- a/include/media/rc-map.h -+++ b/include/media/rc-map.h -@@ -277,6 +277,7 @@ struct rc_map *rc_map_get(const char *name); - #define RC_MAP_WINFAST "rc-winfast" - #define RC_MAP_WINFAST_USBII_DELUXE "rc-winfast-usbii-deluxe" - #define RC_MAP_SU3000 "rc-su3000" -+#define RC_MAP_XBOX_DVD "rc-xbox-dvd" - #define RC_MAP_ZX_IRDEC "rc-zx-irdec" - - /* --- -2.17.1 - diff --git a/packages/linux/patches/raspberrypi/linux-052-xbox_dvd_remote_support.patch b/packages/linux/patches/raspberrypi/linux-052-xbox_dvd_remote_support.patch deleted file mode 100644 index 8db97ddb2f..0000000000 --- a/packages/linux/patches/raspberrypi/linux-052-xbox_dvd_remote_support.patch +++ /dev/null @@ -1,466 +0,0 @@ -From 4d331d301222dc0585ab8864a842b3e460b1f744 Mon Sep 17 00:00:00 2001 -From: Benjamin Valentin -Date: Thu, 4 Oct 2018 02:57:10 +0200 -Subject: [PATCH] media: rc: add driver for Xbox DVD Movie Playback Kit - -The Xbox DVD Movie Playback Kit is a USB dongle with an IR remote for the -Original Xbox. - -Historically it has been supported by the out-of-tree lirc_xbox driver, -but this one has fallen out of favour and was just dropped from popular -Kodi (formerly XBMC) distributions. - -This driver is heaviely based on the ati_remote driver where all the -boilerplate was taken from - I was mostly just removing code. - -Signed-off-by: Benjamin Valentin -Signed-off-by: Sean Young ---- - drivers/media/rc/Kconfig | 12 + - drivers/media/rc/Makefile | 1 + - drivers/media/rc/keymaps/Makefile | 1 + - drivers/media/rc/keymaps/rc-xbox-dvd.c | 63 +++++ - drivers/media/rc/xbox_remote.c | 306 +++++++++++++++++++++++++ - include/media/rc-map.h | 1 + - 6 files changed, 384 insertions(+) - create mode 100644 drivers/media/rc/keymaps/rc-xbox-dvd.c - create mode 100644 drivers/media/rc/xbox_remote.c - -diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig -index 1021c08a9ba4..8a216068a35a 100644 ---- a/drivers/media/rc/Kconfig -+++ b/drivers/media/rc/Kconfig -@@ -493,6 +493,18 @@ config IR_TANGO - The HW decoder supports NEC, RC-5, RC-6 IR protocols. - When compiled as a module, look for tango-ir. - -+config RC_XBOX_DVD -+ tristate "Xbox DVD Movie Playback Kit" -+ depends on RC_CORE -+ depends on USB_ARCH_HAS_HCD -+ select USB -+ help -+ Say Y here if you want to use the Xbox DVD Movie Playback Kit. -+ These are IR remotes with USB receivers for the Original Xbox (2001). -+ -+ To compile this driver as a module, choose M here: the module will be -+ called xbox_remote. -+ - config IR_ZX - tristate "ZTE ZX IR remote control" - depends on RC_CORE -diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile -index e0340d043fe8..92c163816849 100644 ---- a/drivers/media/rc/Makefile -+++ b/drivers/media/rc/Makefile -@@ -48,3 +48,4 @@ obj-$(CONFIG_IR_SIR) += sir_ir.o - obj-$(CONFIG_IR_MTK) += mtk-cir.o - obj-$(CONFIG_IR_ZX) += zx-irdec.o - obj-$(CONFIG_IR_TANGO) += tango-ir.o -+obj-$(CONFIG_RC_XBOX_DVD) += xbox_remote.o -diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile -index d6b913a3032d..5b1399af6b3a 100644 ---- a/drivers/media/rc/keymaps/Makefile -+++ b/drivers/media/rc/keymaps/Makefile -@@ -116,4 +116,5 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ - rc-winfast.o \ - rc-winfast-usbii-deluxe.o \ - rc-su3000.o \ -+ rc-xbox-dvd.o \ - rc-zx-irdec.o -diff --git a/drivers/media/rc/keymaps/rc-xbox-dvd.c b/drivers/media/rc/keymaps/rc-xbox-dvd.c -new file mode 100644 -index 000000000000..af387244636b ---- /dev/null -+++ b/drivers/media/rc/keymaps/rc-xbox-dvd.c -@@ -0,0 +1,63 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+// Keytable for Xbox DVD remote -+// Copyright (c) 2018 by Benjamin Valentin -+ -+#include -+#include -+ -+/* based on lircd.conf.xbox */ -+static struct rc_map_table xbox_dvd[] = { -+ {0xa0b, KEY_OK}, -+ {0xaa6, KEY_UP}, -+ {0xaa7, KEY_DOWN}, -+ {0xaa8, KEY_RIGHT}, -+ {0xaa9, KEY_LEFT}, -+ {0xac3, KEY_INFO}, -+ -+ {0xac6, KEY_9}, -+ {0xac7, KEY_8}, -+ {0xac8, KEY_7}, -+ {0xac9, KEY_6}, -+ {0xaca, KEY_5}, -+ {0xacb, KEY_4}, -+ {0xacc, KEY_3}, -+ {0xacd, KEY_2}, -+ {0xace, KEY_1}, -+ {0xacf, KEY_0}, -+ -+ {0xad5, KEY_ANGLE}, -+ {0xad8, KEY_BACK}, -+ {0xadd, KEY_PREVIOUSSONG}, -+ {0xadf, KEY_NEXTSONG}, -+ {0xae0, KEY_STOP}, -+ {0xae2, KEY_REWIND}, -+ {0xae3, KEY_FASTFORWARD}, -+ {0xae5, KEY_TITLE}, -+ {0xae6, KEY_PAUSE}, -+ {0xaea, KEY_PLAY}, -+ {0xaf7, KEY_MENU}, -+}; -+ -+static struct rc_map_list xbox_dvd_map = { -+ .map = { -+ .scan = xbox_dvd, -+ .size = ARRAY_SIZE(xbox_dvd), -+ .rc_proto = RC_PROTO_UNKNOWN, -+ .name = RC_MAP_XBOX_DVD, -+ } -+}; -+ -+static int __init init_rc_map(void) -+{ -+ return rc_map_register(&xbox_dvd_map); -+} -+ -+static void __exit exit_rc_map(void) -+{ -+ rc_map_unregister(&xbox_dvd_map); -+} -+ -+module_init(init_rc_map) -+module_exit(exit_rc_map) -+ -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c -new file mode 100644 -index 000000000000..07ed9be24a60 ---- /dev/null -+++ b/drivers/media/rc/xbox_remote.c -@@ -0,0 +1,306 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+// Driver for Xbox DVD Movie Playback Kit -+// Copyright (c) 2018 by Benjamin Valentin -+ -+/* -+ * Xbox DVD Movie Playback Kit USB IR dongle support -+ * -+ * The driver was derived from the ati_remote driver 2.2.1 -+ * and used information from lirc_xbox.c -+ * -+ * Copyright (c) 2011, 2012 Anssi Hannula -+ * Copyright (c) 2004 Torrey Hoffman -+ * Copyright (c) 2002 Vladimir Dergachev -+ * Copyright (c) 2003-2004 Paul Miller -+ */ -+ -+#include -+#include -+#include -+#include -+ -+/* -+ * Module and Version Information -+ */ -+#define DRIVER_VERSION "1.0.0" -+#define DRIVER_AUTHOR "Benjamin Valentin " -+#define DRIVER_DESC "Xbox DVD USB Remote Control" -+ -+#define NAME_BUFSIZE 80 /* size of product name, path buffers */ -+#define DATA_BUFSIZE 8 /* size of URB data buffers */ -+ -+/* -+ * USB vendor ids for XBOX DVD Dongles -+ */ -+#define VENDOR_GAMESTER 0x040b -+#define VENDOR_MICROSOFT 0x045e -+ -+static const struct usb_device_id xbox_remote_table[] = { -+ /* Gamester Xbox DVD Movie Playback Kit IR */ -+ { -+ USB_DEVICE(VENDOR_GAMESTER, 0x6521), -+ }, -+ /* Microsoft Xbox DVD Movie Playback Kit IR */ -+ { -+ USB_DEVICE(VENDOR_MICROSOFT, 0x0284), -+ }, -+ {} /* Terminating entry */ -+}; -+ -+MODULE_DEVICE_TABLE(usb, xbox_remote_table); -+ -+struct xbox_remote { -+ struct rc_dev *rdev; -+ struct usb_device *udev; -+ struct usb_interface *interface; -+ -+ struct urb *irq_urb; -+ unsigned char inbuf[DATA_BUFSIZE] __aligned(sizeof(u16)); -+ -+ char rc_name[NAME_BUFSIZE]; -+ char rc_phys[NAME_BUFSIZE]; -+}; -+ -+static int xbox_remote_rc_open(struct rc_dev *rdev) -+{ -+ struct xbox_remote *xbox_remote = rdev->priv; -+ -+ /* On first open, submit the read urb which was set up previously. */ -+ xbox_remote->irq_urb->dev = xbox_remote->udev; -+ if (usb_submit_urb(xbox_remote->irq_urb, GFP_KERNEL)) { -+ dev_err(&xbox_remote->interface->dev, -+ "%s: usb_submit_urb failed!\n", __func__); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static void xbox_remote_rc_close(struct rc_dev *rdev) -+{ -+ struct xbox_remote *xbox_remote = rdev->priv; -+ -+ usb_kill_urb(xbox_remote->irq_urb); -+} -+ -+/* -+ * xbox_remote_report_input -+ */ -+static void xbox_remote_input_report(struct urb *urb) -+{ -+ struct xbox_remote *xbox_remote = urb->context; -+ unsigned char *data = xbox_remote->inbuf; -+ -+ /* -+ * data[0] = 0x00 -+ * data[1] = length - always 0x06 -+ * data[2] = the key code -+ * data[3] = high part of key code -+ * data[4] = last_press_ms (low) -+ * data[5] = last_press_ms (high) -+ */ -+ -+ /* Deal with strange looking inputs */ -+ if (urb->actual_length != 6 || urb->actual_length != data[1]) { -+ dev_warn(&urb->dev->dev, "Weird data, len=%d: %*ph\n", -+ urb->actual_length, urb->actual_length, data); -+ return; -+ } -+ -+ rc_keydown(xbox_remote->rdev, RC_PROTO_UNKNOWN, -+ le16_to_cpup((__le16*)(data + 2)), 0); -+} -+ -+/* -+ * xbox_remote_irq_in -+ */ -+static void xbox_remote_irq_in(struct urb *urb) -+{ -+ struct xbox_remote *xbox_remote = urb->context; -+ int retval; -+ -+ switch (urb->status) { -+ case 0: /* success */ -+ xbox_remote_input_report(urb); -+ break; -+ case -ECONNRESET: /* unlink */ -+ case -ENOENT: -+ case -ESHUTDOWN: -+ dev_dbg(&xbox_remote->interface->dev, -+ "%s: urb error status, unlink?\n", -+ __func__); -+ return; -+ default: /* error */ -+ dev_dbg(&xbox_remote->interface->dev, -+ "%s: Nonzero urb status %d\n", -+ __func__, urb->status); -+ } -+ -+ retval = usb_submit_urb(urb, GFP_ATOMIC); -+ if (retval) -+ dev_err(&xbox_remote->interface->dev, -+ "%s: usb_submit_urb()=%d\n", -+ __func__, retval); -+} -+ -+static void xbox_remote_rc_init(struct xbox_remote *xbox_remote) -+{ -+ struct rc_dev *rdev = xbox_remote->rdev; -+ -+ rdev->priv = xbox_remote; -+ rdev->allowed_protocols = RC_PROTO_BIT_UNKNOWN; -+ rdev->driver_name = "xbox_remote"; -+ -+ rdev->open = xbox_remote_rc_open; -+ rdev->close = xbox_remote_rc_close; -+ -+ rdev->device_name = xbox_remote->rc_name; -+ rdev->input_phys = xbox_remote->rc_phys; -+ -+ usb_to_input_id(xbox_remote->udev, &rdev->input_id); -+ rdev->dev.parent = &xbox_remote->interface->dev; -+} -+ -+static int xbox_remote_initialize(struct xbox_remote *xbox_remote, -+ struct usb_endpoint_descriptor *endpoint_in) -+{ -+ struct usb_device *udev = xbox_remote->udev; -+ int pipe, maxp; -+ -+ /* Set up irq_urb */ -+ pipe = usb_rcvintpipe(udev, endpoint_in->bEndpointAddress); -+ maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); -+ maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp; -+ -+ usb_fill_int_urb(xbox_remote->irq_urb, udev, pipe, xbox_remote->inbuf, -+ maxp, xbox_remote_irq_in, xbox_remote, -+ endpoint_in->bInterval); -+ -+ return 0; -+} -+ -+/* -+ * xbox_remote_probe -+ */ -+static int xbox_remote_probe(struct usb_interface *interface, -+ const struct usb_device_id *id) -+{ -+ struct usb_device *udev = interface_to_usbdev(interface); -+ struct usb_host_interface *iface_host = interface->cur_altsetting; -+ struct usb_endpoint_descriptor *endpoint_in; -+ struct xbox_remote *xbox_remote; -+ struct rc_dev *rc_dev; -+ int err = -ENOMEM; -+ -+ // why is there also a device with no endpoints? -+ if (iface_host->desc.bNumEndpoints == 0) -+ return -ENODEV; -+ -+ if (iface_host->desc.bNumEndpoints != 1) { -+ pr_err("%s: Unexpected desc.bNumEndpoints: %d\n", -+ __func__, iface_host->desc.bNumEndpoints); -+ return -ENODEV; -+ } -+ -+ endpoint_in = &iface_host->endpoint[0].desc; -+ -+ if (!usb_endpoint_is_int_in(endpoint_in)) { -+ pr_err("%s: Unexpected endpoint_in\n", __func__); -+ return -ENODEV; -+ } -+ if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) { -+ pr_err("%s: endpoint_in message size==0?\n", __func__); -+ return -ENODEV; -+ } -+ -+ xbox_remote = kzalloc(sizeof(*xbox_remote), GFP_KERNEL); -+ rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); -+ if (!xbox_remote || !rc_dev) -+ goto exit_free_dev_rdev; -+ -+ /* Allocate URB buffer */ -+ xbox_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); -+ if (!xbox_remote->irq_urb) -+ goto exit_free_buffers; -+ -+ xbox_remote->udev = udev; -+ xbox_remote->rdev = rc_dev; -+ xbox_remote->interface = interface; -+ -+ usb_make_path(udev, xbox_remote->rc_phys, sizeof(xbox_remote->rc_phys)); -+ -+ strlcat(xbox_remote->rc_phys, "/input0", sizeof(xbox_remote->rc_phys)); -+ -+ snprintf(xbox_remote->rc_name, sizeof(xbox_remote->rc_name), "%s%s%s", -+ udev->manufacturer ?: "", -+ udev->manufacturer && udev->product ? " " : "", -+ udev->product ?: ""); -+ -+ if (!strlen(xbox_remote->rc_name)) -+ snprintf(xbox_remote->rc_name, sizeof(xbox_remote->rc_name), -+ DRIVER_DESC "(%04x,%04x)", -+ le16_to_cpu(xbox_remote->udev->descriptor.idVendor), -+ le16_to_cpu(xbox_remote->udev->descriptor.idProduct)); -+ -+ rc_dev->map_name = RC_MAP_XBOX_DVD; /* default map */ -+ -+ xbox_remote_rc_init(xbox_remote); -+ -+ /* Device Hardware Initialization */ -+ err = xbox_remote_initialize(xbox_remote, endpoint_in); -+ if (err) -+ goto exit_kill_urbs; -+ -+ /* Set up and register rc device */ -+ err = rc_register_device(xbox_remote->rdev); -+ if (err) -+ goto exit_kill_urbs; -+ -+ usb_set_intfdata(interface, xbox_remote); -+ -+ return 0; -+ -+exit_kill_urbs: -+ usb_kill_urb(xbox_remote->irq_urb); -+exit_free_buffers: -+ usb_free_urb(xbox_remote->irq_urb); -+exit_free_dev_rdev: -+ rc_free_device(rc_dev); -+ kfree(xbox_remote); -+ -+ return err; -+} -+ -+/* -+ * xbox_remote_disconnect -+ */ -+static void xbox_remote_disconnect(struct usb_interface *interface) -+{ -+ struct xbox_remote *xbox_remote; -+ -+ xbox_remote = usb_get_intfdata(interface); -+ usb_set_intfdata(interface, NULL); -+ if (!xbox_remote) { -+ dev_warn(&interface->dev, "%s - null device?\n", __func__); -+ return; -+ } -+ -+ usb_kill_urb(xbox_remote->irq_urb); -+ rc_unregister_device(xbox_remote->rdev); -+ usb_free_urb(xbox_remote->irq_urb); -+ kfree(xbox_remote); -+} -+ -+/* usb specific object to register with the usb subsystem */ -+static struct usb_driver xbox_remote_driver = { -+ .name = "xbox_remote", -+ .probe = xbox_remote_probe, -+ .disconnect = xbox_remote_disconnect, -+ .id_table = xbox_remote_table, -+}; -+ -+module_usb_driver(xbox_remote_driver); -+ -+MODULE_AUTHOR(DRIVER_AUTHOR); -+MODULE_DESCRIPTION(DRIVER_DESC); -+MODULE_LICENSE("GPL"); -diff --git a/include/media/rc-map.h b/include/media/rc-map.h -index bfa3017cecba..d621acadfbf3 100644 ---- a/include/media/rc-map.h -+++ b/include/media/rc-map.h -@@ -277,6 +277,7 @@ struct rc_map *rc_map_get(const char *name); - #define RC_MAP_WINFAST "rc-winfast" - #define RC_MAP_WINFAST_USBII_DELUXE "rc-winfast-usbii-deluxe" - #define RC_MAP_SU3000 "rc-su3000" -+#define RC_MAP_XBOX_DVD "rc-xbox-dvd" - #define RC_MAP_ZX_IRDEC "rc-zx-irdec" - - /* --- -2.17.1 -