572 lines · 14.6 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* * keyspan_remote: USB driver for the Keyspan DMR * * Copyright (C) 2005 Zymeta Corporation - Michael Downey (downey@zymeta.com) * * This driver has been put together with the support of Innosys, Inc. * and Keyspan, Inc the manufacturers of the Keyspan USB DMR product. */ #include <linux/kernel.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/module.h>#include <linux/usb/input.h> /* Parameters that can be passed to the driver. */static int debug;module_param(debug, int, 0444);MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); /* Vendor and product ids */#define USB_KEYSPAN_VENDOR_ID		0x06CD#define USB_KEYSPAN_PRODUCT_UIA11	0x0202 /* Defines for converting the data from the remote. */#define ZERO		0x18#define ZERO_MASK	0x1F	/* 5 bits for a 0 */#define ONE		0x3C#define ONE_MASK	0x3F	/* 6 bits for a 1 */#define SYNC		0x3F80#define SYNC_MASK	0x3FFF	/* 14 bits for a SYNC sequence */#define STOP		0x00#define STOP_MASK	0x1F	/* 5 bits for the STOP sequence */#define GAP		0xFF #define RECV_SIZE	8	/* The UIA-11 type have a 8 byte limit. */ /* * Table that maps the 31 possible keycodes to input keys. * Currently there are 15 and 17 button models so RESERVED codes * are blank areas in the mapping. */static const unsigned short keyspan_key_table[] = {	KEY_RESERVED,		/* 0 is just a place holder. */	KEY_RESERVED,	KEY_STOP,	KEY_PLAYCD,	KEY_RESERVED,	KEY_PREVIOUSSONG,	KEY_REWIND,	KEY_FORWARD,	KEY_NEXTSONG,	KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,	KEY_PAUSE,	KEY_VOLUMEUP,	KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,	KEY_VOLUMEDOWN,	KEY_RESERVED,	KEY_UP,	KEY_RESERVED,	KEY_MUTE,	KEY_LEFT,	KEY_ENTER,	KEY_RIGHT,	KEY_RESERVED,	KEY_RESERVED,	KEY_DOWN,	KEY_RESERVED,	KEY_KPASTERISK,	KEY_RESERVED,	KEY_MENU}; /* table of devices that work with this driver */static const struct usb_device_id keyspan_table[] = {	{ USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) },	{ }					/* Terminating entry */}; /* Structure to store all the real stuff that a remote sends to us. */struct keyspan_message {	u16	system;	u8	button;	u8	toggle;}; /* Structure used for all the bit testing magic needed to be done. */struct bit_tester {	u32	tester;	int	len;	int	pos;	int	bits_left;	u8	buffer[32];}; /* Structure to hold all of our driver specific stuff */struct usb_keyspan {	char				name[128];	char				phys[64];	unsigned short			keymap[ARRAY_SIZE(keyspan_key_table)];	struct usb_device		*udev;	struct input_dev		*input;	struct usb_interface		*interface;	struct usb_endpoint_descriptor	*in_endpoint;	struct urb*			irq_urb;	int				open;	dma_addr_t			in_dma;	unsigned char			*in_buffer; 	/* variables used to parse messages from remote. */	struct bit_tester		data;	int				stage;	int				toggle;}; static struct usb_driver keyspan_driver; /* * Debug routine that prints out what we've received from the remote. */static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/{	char codes[4 * RECV_SIZE];	int i; 	for (i = 0; i < RECV_SIZE; i++)		snprintf(codes + i * 3, 4, "%02x ", dev->in_buffer[i]); 	dev_info(&dev->udev->dev, "%s\n", codes);} /* * Routine that manages the bit_tester structure.  It makes sure that there are * at least bits_needed bits loaded into the tester. */static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed){	if (dev->data.bits_left >= bits_needed)		return 0; 	/*	 * Somehow we've missed the last message. The message will be repeated	 * though so it's not too big a deal	 */	if (dev->data.pos >= dev->data.len) {		dev_dbg(&dev->interface->dev,			"%s - Error ran out of data. pos: %d, len: %d\n",			__func__, dev->data.pos, dev->data.len);		return -1;	} 	/* Load as much as we can into the tester. */	while ((dev->data.bits_left + 7 < (sizeof(dev->data.tester) * 8)) &&	       (dev->data.pos < dev->data.len)) {		dev->data.tester += (dev->data.buffer[dev->data.pos++] << dev->data.bits_left);		dev->data.bits_left += 8;	} 	return 0;} static void keyspan_report_button(struct usb_keyspan *remote, int button, int press){	struct input_dev *input = remote->input; 	input_event(input, EV_MSC, MSC_SCAN, button);	input_report_key(input, remote->keymap[button], press);	input_sync(input);} /* * Routine that handles all the logic needed to parse out the message from the remote. */static void keyspan_check_data(struct usb_keyspan *remote){	int i;	int found = 0;	struct keyspan_message message; 	switch(remote->stage) {	case 0:		/*		 * In stage 0 we want to find the start of a message.  The remote sends a 0xFF as filler.		 * So the first byte that isn't a FF should be the start of a new message.		 */		for (i = 0; i < RECV_SIZE && remote->in_buffer[i] == GAP; ++i); 		if (i < RECV_SIZE) {			memcpy(remote->data.buffer, remote->in_buffer, RECV_SIZE);			remote->data.len = RECV_SIZE;			remote->data.pos = 0;			remote->data.tester = 0;			remote->data.bits_left = 0;			remote->stage = 1;		}		break; 	case 1:		/*		 * Stage 1 we should have 16 bytes and should be able to detect a		 * SYNC.  The SYNC is 14 bits, 7 0's and then 7 1's.		 */		memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);		remote->data.len += RECV_SIZE; 		found = 0;		while ((remote->data.bits_left >= 14 || remote->data.pos < remote->data.len) && !found) {			for (i = 0; i < 8; ++i) {				if (keyspan_load_tester(remote, 14) != 0) {					remote->stage = 0;					return;				} 				if ((remote->data.tester & SYNC_MASK) == SYNC) {					remote->data.tester = remote->data.tester >> 14;					remote->data.bits_left -= 14;					found = 1;					break;				} else {					remote->data.tester = remote->data.tester >> 1;					--remote->data.bits_left;				}			}		} 		if (!found) {			remote->stage = 0;			remote->data.len = 0;		} else {			remote->stage = 2;		}		break; 	case 2:		/*		 * Stage 2 we should have 24 bytes which will be enough for a full		 * message.  We need to parse out the system code, button code,		 * toggle code, and stop.		 */		memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);		remote->data.len += RECV_SIZE; 		message.system = 0;		for (i = 0; i < 9; i++) {			keyspan_load_tester(remote, 6); 			if ((remote->data.tester & ZERO_MASK) == ZERO) {				message.system = message.system << 1;				remote->data.tester = remote->data.tester >> 5;				remote->data.bits_left -= 5;			} else if ((remote->data.tester & ONE_MASK) == ONE) {				message.system = (message.system << 1) + 1;				remote->data.tester = remote->data.tester >> 6;				remote->data.bits_left -= 6;			} else {				dev_err(&remote->interface->dev,					"%s - Unknown sequence found in system data.\n",					__func__);				remote->stage = 0;				return;			}		} 		message.button = 0;		for (i = 0; i < 5; i++) {			keyspan_load_tester(remote, 6); 			if ((remote->data.tester & ZERO_MASK) == ZERO) {				message.button = message.button << 1;				remote->data.tester = remote->data.tester >> 5;				remote->data.bits_left -= 5;			} else if ((remote->data.tester & ONE_MASK) == ONE) {				message.button = (message.button << 1) + 1;				remote->data.tester = remote->data.tester >> 6;				remote->data.bits_left -= 6;			} else {				dev_err(&remote->interface->dev,					"%s - Unknown sequence found in button data.\n",					__func__);				remote->stage = 0;				return;			}		} 		keyspan_load_tester(remote, 6);		if ((remote->data.tester & ZERO_MASK) == ZERO) {			message.toggle = 0;			remote->data.tester = remote->data.tester >> 5;			remote->data.bits_left -= 5;		} else if ((remote->data.tester & ONE_MASK) == ONE) {			message.toggle = 1;			remote->data.tester = remote->data.tester >> 6;			remote->data.bits_left -= 6;		} else {			dev_err(&remote->interface->dev,				"%s - Error in message, invalid toggle.\n",				__func__);			remote->stage = 0;			return;		} 		keyspan_load_tester(remote, 5);		if ((remote->data.tester & STOP_MASK) == STOP) {			remote->data.tester = remote->data.tester >> 5;			remote->data.bits_left -= 5;		} else {			dev_err(&remote->interface->dev,				"Bad message received, no stop bit found.\n");		} 		dev_dbg(&remote->interface->dev,			"%s found valid message: system: %d, button: %d, toggle: %d\n",			__func__, message.system, message.button, message.toggle); 		if (message.toggle != remote->toggle) {			keyspan_report_button(remote, message.button, 1);			keyspan_report_button(remote, message.button, 0);			remote->toggle = message.toggle;		} 		remote->stage = 0;		break;	}} /* * Routine for sending all the initialization messages to the remote. */static int keyspan_setup(struct usb_device* dev){	int retval = 0; 	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),				 0x11, 0x40, 0x5601, 0x0, NULL, 0,				 USB_CTRL_SET_TIMEOUT);	if (retval) {		dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n",			__func__, retval);		return(retval);	} 	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),				 0x44, 0x40, 0x0, 0x0, NULL, 0,				 USB_CTRL_SET_TIMEOUT);	if (retval) {		dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n",			__func__, retval);		return(retval);	} 	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),				 0x22, 0x40, 0x0, 0x0, NULL, 0,				 USB_CTRL_SET_TIMEOUT);	if (retval) {		dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n",			__func__, retval);		return(retval);	} 	dev_dbg(&dev->dev, "%s - Setup complete.\n", __func__);	return(retval);} /* * Routine used to handle a new message that has come in. */static void keyspan_irq_recv(struct urb *urb){	struct usb_keyspan *dev = urb->context;	int retval; 	/* Check our status in case we need to bail out early. */	switch (urb->status) {	case 0:		break; 	/* Device went away so don't keep trying to read from it. */	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		return; 	default:		goto resubmit;	} 	if (debug)		keyspan_print(dev); 	keyspan_check_data(dev); resubmit:	retval = usb_submit_urb(urb, GFP_ATOMIC);	if (retval)		dev_err(&dev->interface->dev,			"%s - usb_submit_urb failed with result: %d\n",			__func__, retval);} static int keyspan_open(struct input_dev *dev){	struct usb_keyspan *remote = input_get_drvdata(dev); 	remote->irq_urb->dev = remote->udev;	if (usb_submit_urb(remote->irq_urb, GFP_KERNEL))		return -EIO; 	return 0;} static void keyspan_close(struct input_dev *dev){	struct usb_keyspan *remote = input_get_drvdata(dev); 	usb_kill_urb(remote->irq_urb);} /* * Routine that sets up the driver to handle a specific USB device detected on the bus. */static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id){	struct usb_device *udev = interface_to_usbdev(interface);	struct usb_endpoint_descriptor *endpoint;	struct usb_keyspan *remote;	struct input_dev *input_dev;	int i, error; 	error = usb_find_int_in_endpoint(interface->cur_altsetting, &endpoint);	if (error)		return -ENODEV; 	remote = kzalloc_obj(*remote);	input_dev = input_allocate_device();	if (!remote || !input_dev) {		error = -ENOMEM;		goto fail1;	} 	remote->udev = udev;	remote->input = input_dev;	remote->interface = interface;	remote->in_endpoint = endpoint;	remote->toggle = -1;	/* Set to -1 so we will always not match the toggle from the first remote message. */ 	remote->in_buffer = usb_alloc_coherent(udev, RECV_SIZE, GFP_KERNEL, &remote->in_dma);	if (!remote->in_buffer) {		error = -ENOMEM;		goto fail1;	} 	remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);	if (!remote->irq_urb) {		error = -ENOMEM;		goto fail2;	} 	error = keyspan_setup(udev);	if (error) {		error = -ENODEV;		goto fail3;	} 	if (udev->manufacturer)		strscpy(remote->name, udev->manufacturer, sizeof(remote->name)); 	if (udev->product) {		if (udev->manufacturer)			strlcat(remote->name, " ", sizeof(remote->name));		strlcat(remote->name, udev->product, sizeof(remote->name));	} 	if (!strlen(remote->name))		snprintf(remote->name, sizeof(remote->name),			 "USB Keyspan Remote %04x:%04x",			 le16_to_cpu(udev->descriptor.idVendor),			 le16_to_cpu(udev->descriptor.idProduct)); 	usb_make_path(udev, remote->phys, sizeof(remote->phys));	strlcat(remote->phys, "/input0", sizeof(remote->phys));	memcpy(remote->keymap, keyspan_key_table, sizeof(remote->keymap)); 	input_dev->name = remote->name;	input_dev->phys = remote->phys;	usb_to_input_id(udev, &input_dev->id);	input_dev->dev.parent = &interface->dev;	input_dev->keycode = remote->keymap;	input_dev->keycodesize = sizeof(unsigned short);	input_dev->keycodemax = ARRAY_SIZE(remote->keymap); 	input_set_capability(input_dev, EV_MSC, MSC_SCAN);	__set_bit(EV_KEY, input_dev->evbit);	for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)		__set_bit(keyspan_key_table[i], input_dev->keybit);	__clear_bit(KEY_RESERVED, input_dev->keybit);

Lines 1–500 of 572.