rpms/kernel/devel kernel.spec, 1.1572, 1.1573 linux-2.6.29-lirc.patch, 1.8, 1.9

Jarod Wilson jwilson at fedoraproject.org
Wed Jun 17 18:04:21 UTC 2009


Author: jwilson

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv28778

Modified Files:
	kernel.spec linux-2.6.29-lirc.patch 
Log Message:
* Wed Jun 17 2009 Jarod Wilson <jarod at redhat.com>
- New lirc_imon hotness, update 2:
  * support dual-interface devices with a single lirc device
  * directional pad functions as an input device mouse
  * touchscreen devices finally properly supported
  * support for using MCE/RC-6 protocol remotes
  * fix oops in RF remote association code (F10 bug #475496)
  * fix re-enabling case/panel buttons and/or knobs
- Add some misc additional lirc_mceusb2 transceiver IDs
- Add missing unregister_chrdev_region() call to lirc_dev exit
- Add it8720 support to lirc_it87



Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.1572
retrieving revision 1.1573
diff -u -p -r1.1572 -r1.1573
--- kernel.spec	16 Jun 2009 21:38:37 -0000	1.1572
+++ kernel.spec	17 Jun 2009 18:03:50 -0000	1.1573
@@ -1827,6 +1827,18 @@ fi
 # and build.
 
 %changelog
+* Wed Jun 17 2009 Jarod Wilson <jarod at redhat.com>
+- New lirc_imon hotness, update 2:
+  * support dual-interface devices with a single lirc device
+  * directional pad functions as an input device mouse
+  * touchscreen devices finally properly supported
+  * support for using MCE/RC-6 protocol remotes
+  * fix oops in RF remote association code (F10 bug #475496)
+  * fix re-enabling case/panel buttons and/or knobs
+- Add some misc additional lirc_mceusb2 transceiver IDs
+- Add missing unregister_chrdev_region() call to lirc_dev exit
+- Add it8720 support to lirc_it87
+
 * Tue Jun 16 2009 Chuck Ebbert <cebbert at redhat.com>
 - Update via-sdmmc driver
 

linux-2.6.29-lirc.patch:

Index: linux-2.6.29-lirc.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6.29-lirc.patch,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -p -r1.8 -r1.9
--- linux-2.6.29-lirc.patch	15 Jun 2009 14:25:10 -0000	1.8
+++ linux-2.6.29-lirc.patch	17 Jun 2009 18:03:50 -0000	1.9
@@ -11,26 +11,26 @@ Signed-off-by: Jarod Wilson <jarod at redha
  drivers/input/lirc/Kconfig            |  118 ++
  drivers/input/lirc/Makefile           |   21 +
  drivers/input/lirc/lirc.h             |  100 ++
- drivers/input/lirc/lirc_bt829.c       |  383 +++++++
+ drivers/input/lirc/lirc_bt829.c       |  383 ++++++
  drivers/input/lirc/lirc_dev.c         |  849 ++++++++++++++
- drivers/input/lirc/lirc_dev.h         |  184 ++++
+ drivers/input/lirc/lirc_dev.h         |  184 +++
  drivers/input/lirc/lirc_i2c.c         |  649 +++++++++++
- drivers/input/lirc/lirc_igorplugusb.c |  556 ++++++++++
- drivers/input/lirc/lirc_imon.c        | 1942 +++++++++++++++++++++++++++++++++
- drivers/input/lirc/lirc_it87.c        |  986 +++++++++++++++++
+ drivers/input/lirc/lirc_igorplugusb.c |  556 +++++++++
+ drivers/input/lirc/lirc_imon.c        | 2047 +++++++++++++++++++++++++++++++++
+ drivers/input/lirc/lirc_it87.c        |  986 ++++++++++++++++
  drivers/input/lirc/lirc_it87.h        |  116 ++
  drivers/input/lirc/lirc_ite8709.c     |  539 +++++++++
- drivers/input/lirc/lirc_mceusb.c      |  749 +++++++++++++
- drivers/input/lirc/lirc_mceusb2.c     | 1101 +++++++++++++++++++
+ drivers/input/lirc/lirc_mceusb.c      |  749 ++++++++++++
+ drivers/input/lirc/lirc_mceusb2.c     | 1103 ++++++++++++++++++
  drivers/input/lirc/lirc_parallel.c    |  709 ++++++++++++
  drivers/input/lirc/lirc_parallel.h    |   26 +
- drivers/input/lirc/lirc_sasem.c       |  931 ++++++++++++++++
- drivers/input/lirc/lirc_serial.c      | 1316 ++++++++++++++++++++++
- drivers/input/lirc/lirc_sir.c         | 1294 ++++++++++++++++++++++
+ drivers/input/lirc/lirc_sasem.c       |  931 +++++++++++++++
+ drivers/input/lirc/lirc_serial.c      | 1316 +++++++++++++++++++++
+ drivers/input/lirc/lirc_sir.c         | 1294 +++++++++++++++++++++
  drivers/input/lirc/lirc_streamzap.c   |  777 +++++++++++++
  drivers/input/lirc/lirc_ttusbir.c     |  397 +++++++
- drivers/input/lirc/lirc_zilog.c       | 1385 +++++++++++++++++++++++
- 25 files changed, 15141 insertions(+), 0 deletions(-)
+ drivers/input/lirc/lirc_zilog.c       | 1384 ++++++++++++++++++++++
+ 25 files changed, 15247 insertions(+), 0 deletions(-)
 
 diff --git a/MAINTAINERS b/MAINTAINERS
 index 59fd2d1..ad1b16c 100644
@@ -2985,10 +2985,10 @@ index 0000000..ff49bdd
 +
 diff --git a/drivers/input/lirc/lirc_imon.c b/drivers/input/lirc/lirc_imon.c
 new file mode 100644
-index 0000000..4d1fc7a
+index 0000000..3de77ea
 --- /dev/null
 +++ b/drivers/input/lirc/lirc_imon.c
-@@ -0,0 +1,1942 @@
+@@ -0,0 +1,2047 @@
 +/*
 + *   lirc_imon.c:  LIRC/VFD/LCD driver for SoundGraph iMON IR/VFD/LCD
 + *		   including the iMON PAD model
@@ -3038,6 +3038,12 @@ index 0000000..4d1fc7a
 +
 +#define BIT_DURATION	250	/* each bit received is 250us */
 +
++#define dprintk(fmt, args...)						\
++	do {								\
++		if (debug)						\
++			printk(KERN_INFO MOD_NAME ": " fmt, ## args);	\
++	} while (0)
++
 +/*** P R O T O T Y P E S ***/
 +
 +/* USB Callback prototypes */
@@ -3052,7 +3058,7 @@ index 0000000..4d1fc7a
 +static int imon_resume(struct usb_interface *intf);
 +static int imon_suspend(struct usb_interface *intf, pm_message_t message);
 +
-+/* display file_operations function prototypes */
++/* Display file_operations function prototypes */
 +static int display_open(struct inode *inode, struct file *file);
 +static int display_close(struct inode *inode, struct file *file);
 +
@@ -3087,7 +3093,6 @@ index 0000000..4d1fc7a
 +	struct mutex lock;		/* to lock this object */
 +	wait_queue_head_t remove_ok;	/* For unexpected USB disconnects */
 +
-+	int has_touchscreen;		/* touchscreen present? */
 +	int display_proto_6p;		/* display requires 6th packet */
 +	int ir_onboard_decode;		/* IR signals decoded onboard */
 +
@@ -3115,9 +3120,12 @@ index 0000000..4d1fc7a
 +		int status;			/* status of tx completion */
 +	} tx;
 +
++	int ffdc_dev;			/* is this the overused ffdc ID? */
++	int ir_protocol;		/* iMON or MCE (RC6) IR protocol? */
 +	struct input_dev *mouse;	/* input device for iMON PAD remote */
 +	struct input_dev *touch;	/* input device for touchscreen */
-+	int is_mouse;			/* toggle between mouse/remote mode */
++	int has_touchscreen;		/* touchscreen present? */
++	int pad_mouse;			/* toggle kbd(0)/mouse(1) mode */
 +	int touch_x;			/* x coordinate on touchscreen */
 +	int touch_y;			/* y coordinate on touchscreen */
 +	char name[128];
@@ -3136,12 +3144,17 @@ index 0000000..4d1fc7a
 +};
 +
 +enum {
-+	IMON_DISPLAY_TYPE_AUTO,
-+	IMON_DISPLAY_TYPE_VFD,
-+	IMON_DISPLAY_TYPE_LCD,
-+	IMON_DISPLAY_TYPE_NONE,
++	IMON_DISPLAY_TYPE_AUTO = 0,
++	IMON_DISPLAY_TYPE_VFD  = 1,
++	IMON_DISPLAY_TYPE_LCD  = 2,
++	IMON_DISPLAY_TYPE_VGA  = 3,
++	IMON_DISPLAY_TYPE_NONE = 4,
 +};
 +
++enum {
++	IMON_IR_PROTOCOL_IMON  = 0,
++	IMON_IR_PROTOCOL_MCE   = 1,
++};
 +/*
 + * USB Device ID for iMON USB Control Boards
 + *
@@ -3219,33 +3232,14 @@ index 0000000..4d1fc7a
 +	{}
 +};
 +
-+/* Some iMON models requires a 6th packet */
++/* Some iMON VFD models requires a 6th packet for VFD writes */
 +static struct usb_device_id display_proto_6p_list[] = {
 +	{ USB_DEVICE(0x15c2, 0xffda) },
 +	{ USB_DEVICE(0x15c2, 0xffdc) },
-+	{ USB_DEVICE(0x15c2, 0x0034) },
-+	{ USB_DEVICE(0x15c2, 0x0035) },
 +	{ USB_DEVICE(0x15c2, 0x0036) },
-+	{ USB_DEVICE(0x15c2, 0x0037) },
-+	{ USB_DEVICE(0x15c2, 0x0038) },
-+	{ USB_DEVICE(0x15c2, 0x0039) },
-+	{ USB_DEVICE(0x15c2, 0x003a) },
-+	{ USB_DEVICE(0x15c2, 0x003b) },
-+	{ USB_DEVICE(0x15c2, 0x003c) },
-+	{ USB_DEVICE(0x15c2, 0x003d) },
-+	{ USB_DEVICE(0x15c2, 0x003e) },
-+	{ USB_DEVICE(0x15c2, 0x003f) },
-+	{ USB_DEVICE(0x15c2, 0x0040) },
-+	{ USB_DEVICE(0x15c2, 0x0041) },
-+	{ USB_DEVICE(0x15c2, 0x0042) },
-+	{ USB_DEVICE(0x15c2, 0x0043) },
 +	{ USB_DEVICE(0x15c2, 0x0044) },
-+	{ USB_DEVICE(0x15c2, 0x0045) },
-+	{ USB_DEVICE(0x15c2, 0x0046) },
 +	{}
 +};
-+static unsigned char display_packet6[] = {
-+	0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
 +
 +/* newer iMON models use control endpoints */
 +static struct usb_device_id ctl_ep_device_list[] = {
@@ -3271,7 +3265,7 @@ index 0000000..4d1fc7a
 +	{}
 +};
 +
-+/* iMON LCD models user a different write op */
++/* iMON LCD models use a different write op */
 +static struct usb_device_id lcd_device_list[] = {
 +	{ USB_DEVICE(0x15c2, 0xffdc) },
 +	{ USB_DEVICE(0x15c2, 0x0038) },
@@ -3353,9 +3347,12 @@ index 0000000..4d1fc7a
 +
 +static int debug;
 +
-+/* lcd, vfd or none? should be auto-detected, but can be overridden... */
++/* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */
 +static int display_type;
 +
++/* IR protocol: native iMON or Windows MCE (RC-6) */
++static int ir_protocol;
++
 +
 +/***  M O D U L E   C O D E ***/
 +
@@ -3368,12 +3365,14 @@ index 0000000..4d1fc7a
 +MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)");
 +module_param(display_type, int, S_IRUGO);
 +MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, "
-+		 "1=vfd, 2=lcd, 3=none (default: autodetect)");
++		 "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)");
++module_param(ir_protocol, int, S_IRUGO);
++MODULE_PARM_DESC(ir_protocol, "Which IR protocol to use. 0=native iMON, "
++		 "1=Windows Media Center Ed. (RC-6) (default: native iMON)");
 +
 +static void free_imon_context(struct imon_context *context)
 +{
-+	if (context->display_supported)
-+		usb_free_urb(context->tx_urb);
++	usb_free_urb(context->tx_urb);
 +	usb_free_urb(context->rx_urb_intf0);
 +	usb_free_urb(context->rx_urb_intf1);
 +	lirc_buffer_free(context->driver->rbuf);
@@ -3381,8 +3380,7 @@ index 0000000..4d1fc7a
 +	kfree(context->driver);
 +	kfree(context);
 +
-+	if (debug)
-+		printk(KERN_INFO "%s: iMON context freed\n", __func__);
++	dprintk("%s: iMON context freed\n", __func__);
 +}
 +
 +static void deregister_from_lirc(struct imon_context *context)
@@ -3401,7 +3399,7 @@ index 0000000..4d1fc7a
 +}
 +
 +/**
-+ * Called when the display device (e.g. /dev/lcd0)
++ * Called when the Display device (e.g. /dev/lcd0)
 + * is opened by the application.
 + */
 +static int display_open(struct inode *inode, struct file *file)
@@ -3689,6 +3687,9 @@ index 0000000..4d1fc7a
 +	int seq;
 +	int retval = 0;
 +	struct imon_context *context;
++	const unsigned char display_packet6[] = {
++		0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
++
 +
 +	context = (struct imon_context *)file->private_data;
 +	if (!context) {
@@ -3806,9 +3807,8 @@ index 0000000..4d1fc7a
 +	if (retval) {
 +		err("%s: send packet failed!", __func__);
 +		goto exit;
-+	} else if (debug) {
-+		printk(KERN_INFO "%s: write %d bytes to LCD\n",
-+		       __func__, (int) n_bytes);
++	} else {
++		dprintk("%s: write %d bytes to LCD\n", __func__, (int) n_bytes);
 +	}
 +exit:
 +	mutex_unlock(&context->lock);
@@ -3838,6 +3838,47 @@ index 0000000..4d1fc7a
 +}
 +
 +/**
++ * iMON IR receivers support two different signal sets -- those used by
++ * the iMON remotes, and those used by the Windows MCE remotes (which is
++ * really just RC-6), but only one or the other at a time, as the signals
++ * are decoded onboard the receiver.
++ */
++static void imon_set_ir_protocol(struct imon_context *context)
++{
++	int retval;
++	unsigned char ir_proto_packet[] =
++		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
++
++	/* not supported on devices that don't do onboard decoding */
++	if (!context->ir_onboard_decode)
++		return;
++
++	switch (ir_protocol) {
++	case IMON_IR_PROTOCOL_MCE:
++		dprintk("Configuring IR receiver for MCE protocol\n");
++		ir_proto_packet[0] = 0x01;
++		context->ir_protocol = IMON_IR_PROTOCOL_MCE;
++		break;
++	case IMON_IR_PROTOCOL_IMON:
++		dprintk("Configuring IR receiver for iMON protocol\n");
++		/* ir_proto_packet[0] = 0x00; // already the default */
++		context->ir_protocol = IMON_IR_PROTOCOL_IMON;
++		break;
++	default:
++		printk(KERN_INFO "%s: unknown IR protocol specified, will "
++		       "just default to iMON protocol\n", __func__);
++		context->ir_protocol = IMON_IR_PROTOCOL_MCE;
++		break;
++	}
++	memcpy(context->usb_tx_buf, &ir_proto_packet,
++	       sizeof(ir_proto_packet));
++	retval = send_packet(context);
++	if (retval)
++		printk(KERN_INFO "%s: failed to set remote type\n", __func__);
++}
++
++
++/**
 + * Called by lirc_dev when the application opens /dev/lirc
 + */
 +static int ir_open(void *data)
@@ -3855,42 +3896,13 @@ index 0000000..4d1fc7a
 +	context->rx.initial_space = 1;
 +	context->rx.prev_bit = 0;
 +
-+	usb_fill_int_urb(context->rx_urb_intf0, context->usbdev_intf0,
-+		usb_rcvintpipe(context->usbdev_intf0,
-+				context->rx_endpoint_intf0->bEndpointAddress),
-+		context->usb_rx_buf, sizeof(context->usb_rx_buf),
-+		usb_rx_callback_intf0, context,
-+		context->rx_endpoint_intf0->bInterval);
-+
-+	retval = usb_submit_urb(context->rx_urb_intf0, GFP_KERNEL);
-+
-+	if (retval) {
-+		err("%s: usb_submit_urb failed for intf0 (%d)",
-+		    __func__, retval);
-+		goto out;
-+	}
-+
-+	if (context->dev_present_intf1) {
-+		usb_fill_int_urb(context->rx_urb_intf1, context->usbdev_intf1,
-+			usb_rcvintpipe(context->usbdev_intf1,
-+				context->rx_endpoint_intf1->bEndpointAddress),
-+			context->usb_rx_buf, sizeof(context->usb_rx_buf),
-+			usb_rx_callback_intf1, context,
-+			context->rx_endpoint_intf1->bInterval);
-+
-+		retval = usb_submit_urb(context->rx_urb_intf1, GFP_KERNEL);
-+
-+		if (retval) {
-+			err("%s: usb_submit_urb failed for intf1 (%d)",
-+			    __func__, retval);
-+			goto out;
-+		}
-+	}
++	/* set new IR protocol if it has changed since init or last open */
++	if (ir_protocol != context->ir_protocol)
++		imon_set_ir_protocol(context);
 +
 +	context->ir_isopen = 1;
 +	printk(KERN_INFO MOD_NAME ": IR port opened\n");
 +
-+out:
 +	mutex_unlock(&driver_lock);
 +	return retval;
 +}
@@ -3910,9 +3922,6 @@ index 0000000..4d1fc7a
 +
 +	mutex_lock(&context->lock);
 +
-+	usb_kill_urb(context->rx_urb_intf0);
-+	if (context->dev_present_intf1)
-+		usb_kill_urb(context->rx_urb_intf1);
 +	context->ir_isopen = 0;
 +	context->ir_isassociating = 0;
 +	printk(KERN_INFO MOD_NAME ": IR port closed\n");
@@ -3949,8 +3958,7 @@ index 0000000..4d1fc7a
 +	int value = context->rx.count;
 +	int i;
 +
-+	if (debug)
-+		printk(KERN_INFO MOD_NAME ": submitting data to LIRC\n");
++	dprintk("submitting data to LIRC\n");
 +
 +	value *= BIT_DURATION;
 +	value &= PULSE_MASK;
@@ -4064,16 +4072,125 @@ index 0000000..4d1fc7a
 +/**
 + * Process the incoming packet
 + */
-+static void imon_incoming_lirc_packet(struct imon_context *context,
-+				      struct urb *urb, int intf)
++static void imon_incoming_packet(struct imon_context *context,
++				 struct urb *urb, int intf)
 +{
 +	int len = urb->actual_length;
 +	unsigned char *buf = urb->transfer_buffer;
-+	char rel_x, rel_y;
++	char rel_x = 0x00, rel_y = 0x00;
 +	int octet, bit;
 +	unsigned char mask;
 +	int i, chunk_num, dir;
 +	int ts_input = 0;
++	int mouse_input;
++	struct input_dev *mouse = NULL;
++	struct input_dev *touch = NULL;
++	const unsigned char toggle_button1[] = { 0x29, 0x91, 0x15, 0xb7 };
++	const unsigned char toggle_button2[] = { 0x29, 0x91, 0x35, 0xb7 };
++	const unsigned char ch_up[]   = { 0x28, 0x93, 0x95, 0xb7 };
++	const unsigned char ch_down[] = { 0x28, 0x87, 0x95, 0xb7 };
++	const unsigned char btn_left[]  = { 0x68, 0x83, 0x01, 0xb7 };
++	const unsigned char btn_right[] = { 0x68, 0x84, 0x81, 0xb7 };
++
++	mouse = context->mouse;
++	if (context->has_touchscreen)
++		touch = context->touch;
++
++	/* keyboard/mouse mode toggle button */
++	if (memcmp(buf, toggle_button1, 4) == 0 ||
++	    memcmp(buf, toggle_button2, 4) == 0) {
++		context->pad_mouse = ~(context->pad_mouse) & 0x1;
++		dprintk("toggling to %s mode\n",
++			context->pad_mouse ? "mouse" : "keyboard");
++		return;
++	}
++
++	/* send touchscreen events through input subsystem if touchpad data */
++	if (context->has_touchscreen && len == 8 &&
++	    (buf[6] == 0x14 || buf[6] == 0x03) && buf[7] == 0x86) {
++		if (touch == NULL) {
++			printk(KERN_WARNING "%s: touchscreen input device is "
++			       "NULL!\n", __func__);
++			return;
++		}
++		mod_timer(&context->timer, jiffies + TOUCH_TIMEOUT);
++		context->touch_x = (buf[0] << 4) | (buf[1] >> 4);
++		context->touch_y = 0xfff - ((buf[2] << 4) | (buf[1] & 0xf));
++		input_report_abs(touch, ABS_X, context->touch_x);
++		input_report_abs(touch, ABS_Y, context->touch_y);
++		input_report_key(touch, BTN_TOUCH, 0x01);
++		input_sync(touch);
++		ts_input = 1;
++
++	/* send mouse events through input subsystem in mouse mode */
++	} else if ((context->pad_mouse || !context->ir_isopen) && !ts_input) {
++		/* newer iMON device PAD or mouse button */
++		if (!context->ffdc_dev && (buf[0] & 0x01)) {
++			mouse_input = 1;
++			rel_x = buf[2];
++			rel_y = buf[3];
++		/* 0xffdc iMON PAD input */
++		} else if (context->ffdc_dev && (buf[0] & 0x40) &&
++			   !((buf[1] & 0x01) || ((buf[1] >> 2) & 0x01))) {
++			mouse_input = 1;
++			rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
++				(buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
++			if (buf[0] & 0x02)
++				rel_x |= ~0x11;
++			rel_x = rel_x + rel_x / 2;
++			rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
++				(buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
++			if (buf[0] & 0x01)
++				rel_y |= ~0x11;
++			rel_y = rel_y + rel_y / 2;
++		/* 0xffdc mouse buttons */
++		} else if (context->ffdc_dev && !memcmp(buf, btn_left, 4)) {
++			mouse_input = 1;
++			buf[1] = 0x01;
++		} else if (context->ffdc_dev && !memcmp(buf, btn_right, 4)) {
++			mouse_input = 1;
++			buf[1] = 0x02;
++		/* ch+/- buttons, which we use for an emulated scroll wheel */
++		} else if (!memcmp(buf, ch_up, 4) ||
++			   !memcmp(buf, ch_down, 4))
++			mouse_input = 1;
++		else
++			mouse_input = 0;
++
++		if (mouse_input) {
++			if (mouse == NULL) {
++				printk(KERN_WARNING "%s: mouse input device "
++				       "is NULL!\n", __func__);
++				return;
++			}
++			dprintk("sending mouse data via input subsystem\n");
++			if (!memcmp(buf, ch_up, 4))
++				dir = 1;
++			else if (!memcmp(buf, ch_down, 4))
++				dir = -1;
++			else
++				dir = 0;
++
++			if (dir == 0) {
++				input_report_key(mouse, BTN_LEFT,
++						 buf[1] & 0x01);
++				input_report_key(mouse, BTN_RIGHT,
++						 buf[1] >> 1 & 0x01);
++				input_report_rel(mouse, REL_X, rel_x);
++				input_report_rel(mouse, REL_Y, rel_y);
++			} else
++				input_report_rel(mouse, REL_WHEEL, dir);
++			input_sync(mouse);
++			return;
++		}
++	}
++
++	/*
++	 * at this point, mouse and touchscreen input has been handled, so
++	 * anything else goes to lirc -- bail out if no listening IR client
++	 */
++	if (!context->ir_isopen)
++		return;
 +
 +	/*
 +	 * we need to add some special handling for
@@ -4140,7 +4257,7 @@ index 0000000..4d1fc7a
 +		buf[2] = dir & 0xFF;
 +		buf[3] = (dir >> 8) & 0xFF;
 +
-+	} else if (buf[6] == 0x14 && buf[7] == 0x86 && intf == 1) {
++	} else if (ts_input) {
 +		/*
 +		 * this is touchscreen input, which we need to down-sample
 +		 * to a 64 button matrix at the moment...
@@ -4153,7 +4270,6 @@ index 0000000..4d1fc7a
 +		buf[5] = 0x00;
 +		buf[6] = 0x14;
 +		buf[7] = 0xff;
-+		ts_input = 1;
 +	}
 +
 +	if (len != 8) {
@@ -4280,11 +4396,9 @@ index 0000000..4d1fc7a
 +static void usb_rx_callback_intf0(struct urb *urb)
 +{
 +	struct imon_context *context;
-+	struct input_dev *mouse = NULL;
 +	unsigned char *buf;
 +	int len;
 +	int intfnum = 0;
-+	char rel_x, rel_y;
 +
 +	if (!urb)
 +		return;
@@ -4296,30 +4410,12 @@ index 0000000..4d1fc7a
 +	buf = urb->transfer_buffer;
 +	len = urb->actual_length;
 +
-+	mouse = context->mouse;
-+	if (!context->mouse)
-+		return;
-+
 +	switch (urb->status) {
 +	case -ENOENT:		/* usbcore unlink successful! */
 +		return;
 +
 +	case 0:
-+		/* if we're in mouse mode, send input events */
-+		if (context->is_mouse && buf[0] & 0x01) {
-+			if (debug)
-+				printk(KERN_INFO MOD_NAME ": sending mouse "
-+				       "data via input subsystem\n");
-+			input_report_key(mouse, BTN_LEFT, buf[1] & 0x01);
-+			input_report_key(mouse, BTN_RIGHT, buf[1] >> 2 & 0x01);
-+			rel_x = buf[2];
-+			rel_y = buf[3];
-+			input_report_rel(mouse, REL_X, rel_x);
-+			input_report_rel(mouse, REL_Y, rel_y);
-+			input_sync(mouse);
-+		/* otherwise, we're in IR mode, process lirc packets */
-+		} else if (context->ir_isopen)
-+			imon_incoming_lirc_packet(context, urb, intfnum);
++		imon_incoming_packet(context, urb, intfnum);
 +		break;
 +
 +	default:
@@ -4338,9 +4434,7 @@ index 0000000..4d1fc7a
 +	struct imon_context *context;
 +	unsigned char *buf;
 +	int len;
-+	struct input_dev *touch = NULL;
 +	int intfnum = 1;
-+	const unsigned char toggle_button[] = { 0x29, 0x91, 0x15, 0xb7 };
 +
 +	if (!urb)
 +		return;
@@ -4352,40 +4446,12 @@ index 0000000..4d1fc7a
 +	buf = urb->transfer_buffer;
 +	len = urb->actual_length;
 +
-+	if (context->has_touchscreen) {
-+		touch = context->touch;
-+		if (!context->touch)
-+			return;
-+	}
-+
 +	switch (urb->status) {
 +	case -ENOENT:		/* usbcore unlink successful! */
 +		return;
 +
 +	case 0:
-+		/* keyboard/mouse mode toggle button */
-+		if (memcmp(buf, toggle_button, 4) == 0) {
-+			if (debug)
-+				printk(KERN_INFO MOD_NAME ": toggling "
-+				       "keyboard/mouse mode (%d)\n",
-+				       context->is_mouse);
-+			context->is_mouse = ~(context->is_mouse) & 0x1;
-+			break;
-+		}
-+		/* handle touchscreen input */
-+		if (context->has_touchscreen &&
-+		    buf[6] == 0x14 && buf[7] == 0x86) {
-+			mod_timer(&context->timer, jiffies + TOUCH_TIMEOUT);
-+			context->touch_x = (buf[0] << 4) | (buf[1] >> 4);
-+			context->touch_y = 0xfff - ((buf[2] << 4) |
-+					   (buf[1] & 0xf));
-+			input_report_abs(touch, ABS_X, context->touch_x);
-+			input_report_abs(touch, ABS_Y, context->touch_y);
-+			input_report_key(touch, BTN_TOUCH, 0x01);
-+			input_sync(touch);
-+		/* otherwise, process lirc packets */
-+		} else if (context->ir_isopen)
-+			imon_incoming_lirc_packet(context, urb, intfnum);
++		imon_incoming_packet(context, urb, intfnum);
 +		break;
 +
 +	default:
@@ -4459,9 +4525,8 @@ index 0000000..4d1fc7a
 +	vendor     = le16_to_cpu(usbdev->descriptor.idVendor);
 +	product    = le16_to_cpu(usbdev->descriptor.idProduct);
 +
-+	if (debug)
-+		printk(KERN_INFO "%s: found iMON device (%04x:%04x, intf%d)\n",
-+		       __func__, vendor, product, ifnum);
++	dprintk("%s: found iMON device (%04x:%04x, intf%d)\n",
++		__func__, vendor, product, ifnum);
 +
 +	/* prevent races probing devices w/multiple interfaces */
 +	mutex_lock(&driver_lock);
@@ -4488,18 +4553,14 @@ index 0000000..4d1fc7a
 +
 +			rx_endpoint = ep;
 +			ir_ep_found = 1;
-+			if (debug)
-+				printk(KERN_INFO "%s: found IR endpoint\n",
-+				       __func__);
++			dprintk("%s: found IR endpoint\n", __func__);
 +
 +		} else if (!display_ep_found &&
 +			   ep_dir == USB_DIR_OUT &&
 +			   ep_type == USB_ENDPOINT_XFER_INT) {
 +			tx_endpoint = ep;
 +			display_ep_found = 1;
-+			if (debug)
-+				printk(KERN_INFO "%s: found display endpoint\n",
-+				       __func__);
++			dprintk("%s: found display endpoint\n", __func__);
 +		}
 +	}
 +
@@ -4511,10 +4572,8 @@ index 0000000..4d1fc7a
 +		if (usb_match_id(interface, ctl_ep_device_list)) {
 +			tx_control = 1;
 +			display_ep_found = 1;
-+			if (debug)
-+				printk(KERN_INFO "%s: LCD device uses control "
-+				       "endpoint, not interface OUT "
-+				       "endpoint\n", __func__);
++			dprintk("%s: LCD device uses control endpoint, not "
++				"interface OUT endpoint\n", __func__);
 +		}
 +	}
 +
@@ -4528,22 +4587,20 @@ index 0000000..4d1fc7a
 +	    display_type == IMON_DISPLAY_TYPE_NONE) {
 +		tx_control = 0;
 +		display_ep_found = 0;
-+		if (debug)
-+			printk(KERN_INFO "%s: device has no display\n",
-+			       __func__);
++		dprintk("%s: device has no display\n", __func__);
 +	}
 +
 +	/*
 +	 * iMON Touch devices have a VGA touchscreen, but no "display", as
 +	 * that refers to e.g. /dev/lcd0 (a character device LCD or VFD).
 +	 */
-+	if (usb_match_id(interface, imon_touchscreen_list)) {
++	if ((display_type == IMON_DISPLAY_TYPE_AUTO &&
++	     usb_match_id(interface, imon_touchscreen_list)) ||
++	    display_type == IMON_DISPLAY_TYPE_VGA) {
 +		tx_control = 0;
 +		display_ep_found = 0;
 +		has_touchscreen = 1;
-+		if (debug)
-+			printk(KERN_INFO "%s: iMON Touch device found\n",
-+			       __func__);
++		dprintk("%s: iMON Touch device found\n", __func__);
 +	}
 +
 +	/* Input endpoint is mandatory */
@@ -4556,9 +4613,8 @@ index 0000000..4d1fc7a
 +		if (usb_match_id(interface, ir_onboard_decode_list))
 +			ir_onboard_decode = 1;
 +
-+		if (debug)
-+			printk(KERN_INFO "%s: ir_onboard_decode: %d\n",
-+			       __func__, ir_onboard_decode);
++		dprintk("%s: ir_onboard_decode: %d\n",
++			__func__, ir_onboard_decode);
 +	}
 +
 +	/* Determine if display requires 6 packets */
@@ -4566,9 +4622,8 @@ index 0000000..4d1fc7a
 +		if (usb_match_id(interface, display_proto_6p_list))
 +			display_proto_6p = 1;
 +
-+		if (debug)
-+			printk(KERN_INFO "%s: display_proto_6p: %d\n",
-+			       __func__, display_proto_6p);
++		dprintk("%s: display_proto_6p: %d\n",
++			__func__, display_proto_6p);
 +	}
 +
 +	if (ifnum == 0) {
@@ -4601,14 +4656,12 @@ index 0000000..4d1fc7a
 +			alloc_status = 5;
 +			goto alloc_status_switch;
 +		}
-+		if (display_ep_found) {
-+			tx_urb = usb_alloc_urb(0, GFP_KERNEL);
-+			if (!tx_urb) {
-+				err("%s: usb_alloc_urb failed for display urb",
-+				    __func__);
-+				alloc_status = 6;
-+				goto alloc_status_switch;
-+			}
++		tx_urb = usb_alloc_urb(0, GFP_KERNEL);
++		if (!tx_urb) {
++			err("%s: usb_alloc_urb failed for display urb",
++			    __func__);
++			alloc_status = 6;
++			goto alloc_status_switch;
 +		}
 +
 +		mutex_init(&context->lock);
@@ -4633,7 +4686,7 @@ index 0000000..4d1fc7a
 +
 +		context->driver = driver;
 +		/* start out in keyboard mode */
-+		context->is_mouse = 0;
++		context->pad_mouse = 0;
 +
 +		init_timer(&context->timer);
 +		context->timer.data = (unsigned long)context;
@@ -4667,18 +4720,26 @@ index 0000000..4d1fc7a
 +		mutex_lock(&context->lock);
 +	}
 +
-+
 +	if (ifnum == 0) {
 +		context->usbdev_intf0 = usbdev;
 +		context->dev_present_intf0 = 1;
 +		context->rx_endpoint_intf0 = rx_endpoint;
 +		context->rx_urb_intf0 = rx_urb;
-+		if (display_ep_found) {
++
++		/*
++		 * tx is used to send characters to lcd/vfd, associate RF
++		 * remotes, set IR protocol, and maybe more...
++		 */
++		context->tx_endpoint = tx_endpoint;
++		context->tx_urb = tx_urb;
++		context->tx_control = tx_control;
++
++		if (display_ep_found)
 +			context->display_supported = 1;
-+			context->tx_endpoint = tx_endpoint;
-+			context->tx_urb = tx_urb;
-+			context->tx_control = tx_control;
-+		}
++
++		if (product == 0xffdc)
++			context->ffdc_dev = 1;
++
 +		context->has_touchscreen = has_touchscreen;
 +
 +		context->mouse = input_allocate_device();
@@ -4705,6 +4766,25 @@ index 0000000..4d1fc7a
 +		usb_to_input_id(usbdev, &context->mouse->id);
 +		context->mouse->dev.parent = &interface->dev;
 +		retval = input_register_device(context->mouse);
++		if (retval)
++			printk(KERN_INFO "%s: pad mouse input device setup failed\n",
++			       __func__);
++
++		usb_fill_int_urb(context->rx_urb_intf0, context->usbdev_intf0,
++			usb_rcvintpipe(context->usbdev_intf0,
++					context->rx_endpoint_intf0->bEndpointAddress),
++			context->usb_rx_buf, sizeof(context->usb_rx_buf),
++			usb_rx_callback_intf0, context,
++			context->rx_endpoint_intf0->bInterval);
++
++		retval = usb_submit_urb(context->rx_urb_intf0, GFP_KERNEL);
++
++		if (retval) {
++			err("%s: usb_submit_urb failed for intf0 (%d)",
++			    __func__, retval);
++			mutex_unlock(&context->lock);
++			goto exit;
++		}
 +
 +	} else {
 +		context->usbdev_intf1 = usbdev;
@@ -4740,20 +4820,33 @@ index 0000000..4d1fc7a
 +			usb_to_input_id(usbdev, &context->touch->id);
 +			context->touch->dev.parent = &interface->dev;
 +			retval = input_register_device(context->touch);
-+		} else {
++			if (retval)
++				printk(KERN_INFO "%s: touchscreen input device setup failed\n",
++				       __func__);
++		} else
 +			context->touch = NULL;
-+			retval = 0;
++
++		usb_fill_int_urb(context->rx_urb_intf1, context->usbdev_intf1,
++			usb_rcvintpipe(context->usbdev_intf1,
++				context->rx_endpoint_intf1->bEndpointAddress),
++			context->usb_rx_buf, sizeof(context->usb_rx_buf),
++			usb_rx_callback_intf1, context,
++			context->rx_endpoint_intf1->bInterval);
++
++		retval = usb_submit_urb(context->rx_urb_intf1, GFP_KERNEL);
++
++		if (retval) {
++			err("%s: usb_submit_urb failed for intf1 (%d)",
++			    __func__, retval);
++			mutex_unlock(&context->lock);
++			goto exit;
 +		}
 +	}
 +
-+	if (retval)
-+		printk(KERN_INFO "%s: input device setup on intf%d failed\n",
-+		       __func__, ifnum);
-+
 +	usb_set_intfdata(interface, context);
 +
 +	/* RF products *also* use 0xffdc... sigh... */
-+	if (product == 0xffdc) {
++	if (context->ffdc_dev) {
 +		int err;
 +
 +		err = sysfs_create_group(&interface->dev.kobj,
@@ -4764,9 +4857,7 @@ index 0000000..4d1fc7a
 +	}
 +
 +	if (context->display_supported && ifnum == 0) {
-+		if (debug)
-+			printk(KERN_INFO "%s: Registering iMON display with "
-+			       "sysfs\n", __func__);
++		dprintk("%s: Registering iMON display with sysfs\n", __func__);
 +		if (usb_register_dev(interface, &imon_class)) {
 +			/* Not a fatal error, so ignore */
 +			printk(KERN_INFO "%s: could not get a minor number for "
@@ -4782,6 +4873,9 @@ index 0000000..4d1fc7a
 +			       "buttons and/or knobs\n", __func__);
 +	}
 +
++	/* set IR protocol/remote type */
++	imon_set_ir_protocol(context);
++
 +	printk(KERN_INFO MOD_NAME ": iMON device (%04x:%04x, intf%d) on "
 +	       "usb<%d:%d> initialized\n", vendor, product, ifnum,
 +	       usbdev->bus->busnum, usbdev->devnum);
@@ -4791,8 +4885,7 @@ index 0000000..4d1fc7a
 +
 +	switch (alloc_status) {
 +	case 7:
-+		if (display_ep_found)
-+			usb_free_urb(tx_urb);
++		usb_free_urb(tx_urb);
 +	case 6:
 +		usb_free_urb(rx_urb);
 +	case 5:
@@ -4882,12 +4975,10 @@ index 0000000..4d1fc7a
 +	struct imon_context *context = usb_get_intfdata(intf);
 +	int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
 +
-+	if (context->ir_isopen) {
-+		if (ifnum == 0)
-+			usb_kill_urb(context->rx_urb_intf0);
-+		else
-+			usb_kill_urb(context->rx_urb_intf1);
-+	}
++	if (ifnum == 0)
++		usb_kill_urb(context->rx_urb_intf0);
++	else
++		usb_kill_urb(context->rx_urb_intf1);
 +
 +	return 0;
 +}
@@ -4898,11 +4989,25 @@ index 0000000..4d1fc7a
 +	struct imon_context *context = usb_get_intfdata(intf);
 +	int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
 +
-+	if (context->ir_isopen) {
-+		if (ifnum == 0)
-+			rc = usb_submit_urb(context->rx_urb_intf0, GFP_ATOMIC);
-+		else
-+			rc = usb_submit_urb(context->rx_urb_intf1, GFP_ATOMIC);
++	if (ifnum == 0) {
++		usb_fill_int_urb(context->rx_urb_intf0, context->usbdev_intf0,
++			usb_rcvintpipe(context->usbdev_intf0,
++					context->rx_endpoint_intf0->bEndpointAddress),
++			context->usb_rx_buf, sizeof(context->usb_rx_buf),
++			usb_rx_callback_intf0, context,
++			context->rx_endpoint_intf0->bInterval);
++
++		rc = usb_submit_urb(context->rx_urb_intf0, GFP_ATOMIC);
++
++	} else {
++		usb_fill_int_urb(context->rx_urb_intf1, context->usbdev_intf1,
++			usb_rcvintpipe(context->usbdev_intf1,
++				context->rx_endpoint_intf1->bEndpointAddress),
++			context->usb_rx_buf, sizeof(context->usb_rx_buf),
++			usb_rx_callback_intf1, context,
++			context->rx_endpoint_intf1->bInterval);
++
++		rc = usb_submit_urb(context->rx_urb_intf1, GFP_ATOMIC);
 +	}
 +
 +	return rc;
@@ -7347,10 +7452,10 @@ index 0000000..12d9723
 +MODULE_PARM_DESC(debug, "Debug enabled or not");
 diff --git a/drivers/input/lirc/lirc_mceusb2.c b/drivers/input/lirc/lirc_mceusb2.c
 new file mode 100644
-index 0000000..3af45dd
+index 0000000..36ef032
 --- /dev/null
 +++ b/drivers/input/lirc/lirc_mceusb2.c
-@@ -0,0 +1,1101 @@
+@@ -0,0 +1,1103 @@
 +/*
 + * LIRC driver for Philips eHome USB Infrared Transceiver
 + * and the Microsoft Media Center Edition Remote Control
@@ -7549,8 +7654,10 @@ index 0000000..3af45dd
 +	{ USB_DEVICE(VENDOR_SMK, 0x0322) },
 +	{ USB_DEVICE(VENDOR_SMK, 0x0334) },
 +	{ USB_DEVICE(VENDOR_TOPSEED, 0x0001) },
++	{ USB_DEVICE(VENDOR_TOPSEED, 0x0006) },
 +	{ USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
 +	{ USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
++	{ USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
 +	{ USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
 +	{}
 +};
@@ -13946,10 +14053,10 @@ index 0000000..2955bad
 +module_exit(ttusbir_exit_module);
 diff --git a/drivers/input/lirc/lirc_zilog.c b/drivers/input/lirc/lirc_zilog.c
 new file mode 100644
-index 0000000..ec503d7
+index 0000000..049c3da
 --- /dev/null
 +++ b/drivers/input/lirc/lirc_zilog.c
-@@ -0,0 +1,1385 @@
+@@ -0,0 +1,1384 @@
 +/*
 + * i2c IR lirc driver for devices with zilog IR processors
 + *
@@ -15301,7 +15408,6 @@ index 0000000..ec503d7
 +static int __init zilog_init(void)
 +{
 +	mutex_init(&tx_data_lock);
-+	request_module("ivtv");
 +	request_module("firmware_class");
 +	i2c_add_driver(&driver);
 +	return 0;




More information about the fedora-extras-commits mailing list