Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) // Driver for Xbox DVD Movie Playback Kit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) // Copyright (c) 2018 by Benjamin Valentin <benpicco@googlemail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  Xbox DVD Movie Playback Kit USB IR dongle support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  The driver was derived from the ati_remote driver 2.2.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *          and used information from lirc_xbox.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *          Copyright (c) 2011, 2012 Anssi Hannula <anssi.hannula@iki.fi>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *          Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *          Copyright (c) 2002 Vladimir Dergachev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *          Copyright (c) 2003-2004 Paul Miller <pmiller9@users.sourceforge.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/usb/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <media/rc-core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * Module and Version Information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define DRIVER_VERSION	"1.0.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define DRIVER_AUTHOR	"Benjamin Valentin <benpicco@googlemail.com>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define DRIVER_DESC		"Xbox DVD USB Remote Control"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define NAME_BUFSIZE      80    /* size of product name, path buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define DATA_BUFSIZE      8     /* size of URB data buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * USB vendor ids for XBOX DVD Dongles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define VENDOR_GAMESTER     0x040b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define VENDOR_MICROSOFT    0x045e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static const struct usb_device_id xbox_remote_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	/* Gamester Xbox DVD Movie Playback Kit IR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		USB_DEVICE(VENDOR_GAMESTER, 0x6521),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	/* Microsoft Xbox DVD Movie Playback Kit IR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		USB_DEVICE(VENDOR_MICROSOFT, 0x0284),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	{}	/* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) MODULE_DEVICE_TABLE(usb, xbox_remote_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) struct xbox_remote {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	struct rc_dev *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	struct usb_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	struct urb *irq_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	unsigned char inbuf[DATA_BUFSIZE] __aligned(sizeof(u16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	char rc_name[NAME_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	char rc_phys[NAME_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static int xbox_remote_rc_open(struct rc_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	struct xbox_remote *xbox_remote = rdev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	/* On first open, submit the read urb which was set up previously. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	xbox_remote->irq_urb->dev = xbox_remote->udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	if (usb_submit_urb(xbox_remote->irq_urb, GFP_KERNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		dev_err(&xbox_remote->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			"%s: usb_submit_urb failed!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static void xbox_remote_rc_close(struct rc_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	struct xbox_remote *xbox_remote = rdev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	usb_kill_urb(xbox_remote->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * xbox_remote_report_input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static void xbox_remote_input_report(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	struct xbox_remote *xbox_remote = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	unsigned char *data = xbox_remote->inbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	 * data[0] = 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	 * data[1] = length - always 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	 * data[2] = the key code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	 * data[3] = high part of key code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	 * data[4] = last_press_ms (low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	 * data[5] = last_press_ms (high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	/* Deal with strange looking inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	if (urb->actual_length != 6 || urb->actual_length != data[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		dev_warn(&urb->dev->dev, "Weird data, len=%d: %*ph\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			 urb->actual_length, urb->actual_length, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	rc_keydown(xbox_remote->rdev, RC_PROTO_XBOX_DVD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		   le16_to_cpup((__le16 *)(data + 2)), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * xbox_remote_irq_in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static void xbox_remote_irq_in(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	struct xbox_remote *xbox_remote = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	switch (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	case 0:			/* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		xbox_remote_input_report(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	case -ECONNRESET:	/* unlink */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		dev_dbg(&xbox_remote->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			"%s: urb error status, unlink?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	default:		/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		dev_dbg(&xbox_remote->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			"%s: Nonzero urb status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			__func__, urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	retval = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		dev_err(&xbox_remote->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			"%s: usb_submit_urb()=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 			__func__, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static void xbox_remote_rc_init(struct xbox_remote *xbox_remote)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	struct rc_dev *rdev = xbox_remote->rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	rdev->priv = xbox_remote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	rdev->allowed_protocols = RC_PROTO_BIT_XBOX_DVD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	rdev->driver_name = "xbox_remote";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	rdev->open = xbox_remote_rc_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	rdev->close = xbox_remote_rc_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	rdev->device_name = xbox_remote->rc_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	rdev->input_phys = xbox_remote->rc_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	rdev->timeout = MS_TO_US(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	usb_to_input_id(xbox_remote->udev, &rdev->input_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	rdev->dev.parent = &xbox_remote->interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int xbox_remote_initialize(struct xbox_remote *xbox_remote,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 				  struct usb_endpoint_descriptor *endpoint_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	struct usb_device *udev = xbox_remote->udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	int pipe, maxp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	/* Set up irq_urb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	pipe = usb_rcvintpipe(udev, endpoint_in->bEndpointAddress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	usb_fill_int_urb(xbox_remote->irq_urb, udev, pipe, xbox_remote->inbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			 maxp, xbox_remote_irq_in, xbox_remote,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			 endpoint_in->bInterval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * xbox_remote_probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static int xbox_remote_probe(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			     const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	struct usb_device *udev = interface_to_usbdev(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	struct usb_host_interface *iface_host = interface->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	struct usb_endpoint_descriptor *endpoint_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	struct xbox_remote *xbox_remote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	struct rc_dev *rc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	// why is there also a device with no endpoints?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (iface_host->desc.bNumEndpoints == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (iface_host->desc.bNumEndpoints != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		pr_err("%s: Unexpected desc.bNumEndpoints: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		       __func__, iface_host->desc.bNumEndpoints);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	endpoint_in = &iface_host->endpoint[0].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	if (!usb_endpoint_is_int_in(endpoint_in)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		pr_err("%s: Unexpected endpoint_in\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		pr_err("%s: endpoint_in message size==0?\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	xbox_remote = kzalloc(sizeof(*xbox_remote), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (!xbox_remote || !rc_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		goto exit_free_dev_rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	/* Allocate URB buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	xbox_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (!xbox_remote->irq_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		goto exit_free_buffers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	xbox_remote->udev = udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	xbox_remote->rdev = rc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	xbox_remote->interface = interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	usb_make_path(udev, xbox_remote->rc_phys, sizeof(xbox_remote->rc_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	strlcat(xbox_remote->rc_phys, "/input0", sizeof(xbox_remote->rc_phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	snprintf(xbox_remote->rc_name, sizeof(xbox_remote->rc_name), "%s%s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		 udev->manufacturer ?: "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		 udev->manufacturer && udev->product ? " " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		 udev->product ?: "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	if (!strlen(xbox_remote->rc_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		snprintf(xbox_remote->rc_name, sizeof(xbox_remote->rc_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			 DRIVER_DESC "(%04x,%04x)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			 le16_to_cpu(xbox_remote->udev->descriptor.idVendor),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			 le16_to_cpu(xbox_remote->udev->descriptor.idProduct));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	rc_dev->map_name = RC_MAP_XBOX_DVD; /* default map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	xbox_remote_rc_init(xbox_remote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	/* Device Hardware Initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	err = xbox_remote_initialize(xbox_remote, endpoint_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		goto exit_kill_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	/* Set up and register rc device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	err = rc_register_device(xbox_remote->rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		goto exit_kill_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	usb_set_intfdata(interface, xbox_remote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) exit_kill_urbs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	usb_kill_urb(xbox_remote->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) exit_free_buffers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	usb_free_urb(xbox_remote->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) exit_free_dev_rdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	rc_free_device(rc_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	kfree(xbox_remote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  * xbox_remote_disconnect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void xbox_remote_disconnect(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	struct xbox_remote *xbox_remote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	xbox_remote = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	usb_set_intfdata(interface, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	if (!xbox_remote) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		dev_warn(&interface->dev, "%s - null device?\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	usb_kill_urb(xbox_remote->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	rc_unregister_device(xbox_remote->rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	usb_free_urb(xbox_remote->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	kfree(xbox_remote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* usb specific object to register with the usb subsystem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static struct usb_driver xbox_remote_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	.name         = "xbox_remote",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	.probe        = xbox_remote_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	.disconnect   = xbox_remote_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	.id_table     = xbox_remote_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) module_usb_driver(xbox_remote_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) MODULE_LICENSE("GPL");