rpms/kernel/devel kernel.spec, 1.1708, 1.1709 linux-2.6.31-lirc.patch, 1.3, 1.4

Jarod Wilson jwilson at fedoraproject.org
Mon Aug 10 20:30:11 UTC 2009


Author: jwilson

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

Modified Files:
	kernel.spec linux-2.6.31-lirc.patch 
Log Message:
* Mon Aug 10 2009 Jarod Wilson <jarod at redhat.com>
- Add new device ID to lirc_mceusb (#512483)
- Fix some lockdep false positives
- Add support for setting and enabling iMON clock via sysfs
- Add tunable pad threshold support to lirc_imon
- Add new pseudo-IR protocl to lirc_imon for universals w/o a pad
- Fix mouse device support on older iMON devices



Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.1708
retrieving revision 1.1709
diff -u -p -r1.1708 -r1.1709
--- kernel.spec	10 Aug 2009 15:42:58 -0000	1.1708
+++ kernel.spec	10 Aug 2009 20:30:10 -0000	1.1709
@@ -1980,6 +1980,14 @@ fi
 # and build.
 
 %changelog
+* Mon Aug 10 2009 Jarod Wilson <jarod at redhat.com>
+- Add new device ID to lirc_mceusb (#512483)
+- Fix some lockdep false positives
+- Add support for setting and enabling iMON clock via sysfs
+- Add tunable pad threshold support to lirc_imon
+- Add new pseudo-IR protocl to lirc_imon for universals w/o a pad
+- Fix mouse device support on older iMON devices
+
 * Mon Aug 10 2009 David Woodhouse <David.Woodhouse at intel.com> 2.6.31-0.145.rc5.git3
 - Merge latest Intel IOMMU fixes and BIOS workarounds, re-enable by default.
 

linux-2.6.31-lirc.patch:
 MAINTAINERS                           |    9 
 drivers/input/Kconfig                 |    2 
 drivers/input/Makefile                |    2 
 drivers/input/lirc/Kconfig            |  112 +
 drivers/input/lirc/Makefile           |   20 
 drivers/input/lirc/lirc.h             |  100 +
 drivers/input/lirc/lirc_bt829.c       |  383 +++++
 drivers/input/lirc/lirc_dev.c         |  851 ++++++++++++
 drivers/input/lirc/lirc_dev.h         |  184 ++
 drivers/input/lirc/lirc_i2c.c         |  537 +++++++
 drivers/input/lirc/lirc_igorplugusb.c |  556 ++++++++
 drivers/input/lirc/lirc_imon.c        | 2298 ++++++++++++++++++++++++++++++++++
 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      | 1225 ++++++++++++++++++
 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         | 1283 ++++++++++++++++++
 drivers/input/lirc/lirc_streamzap.c   |  777 +++++++++++
 drivers/input/lirc/lirc_ttusbir.c     |  397 +++++
 drivers/input/lirc/lirc_zilog.c       | 1374 ++++++++++++++++++++
 24 files changed, 14733 insertions(+)

Index: linux-2.6.31-lirc.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6.31-lirc.patch,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -p -r1.3 -r1.4
--- linux-2.6.31-lirc.patch	31 Jul 2009 01:00:04 -0000	1.3
+++ linux-2.6.31-lirc.patch	10 Aug 2009 20:30:10 -0000	1.4
@@ -1,6 +1,6 @@
 Linux Infrared Remote Control drivers -- http://www.lirc.org
 
-Last updated: Tuesday, July 7, 2009
+Last updated: Monday, August 10, 2009
 
 From http://git.wilsonet.com/linux-2.6-lirc.git/
 
@@ -14,30 +14,30 @@ Signed-off-by: Jarod Wilson <jarod at redha
  drivers/input/lirc/Makefile           |   20 +
  drivers/input/lirc/lirc.h             |  100 ++
  drivers/input/lirc/lirc_bt829.c       |  383 ++++++
- drivers/input/lirc/lirc_dev.c         |  851 ++++++++++++++
+ drivers/input/lirc/lirc_dev.c         |  851 ++++++++++++
  drivers/input/lirc/lirc_dev.h         |  184 +++
- drivers/input/lirc/lirc_i2c.c         |  537 +++++++++
- drivers/input/lirc/lirc_igorplugusb.c |  556 +++++++++
- drivers/input/lirc/lirc_imon.c        | 2062 +++++++++++++++++++++++++++++++++
- drivers/input/lirc/lirc_it87.c        |  986 ++++++++++++++++
+ drivers/input/lirc/lirc_i2c.c         |  537 ++++++++
+ drivers/input/lirc/lirc_igorplugusb.c |  556 ++++++++
+ drivers/input/lirc/lirc_imon.c        | 2298 +++++++++++++++++++++++++++++++++
+ 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      | 1223 +++++++++++++++++++
- drivers/input/lirc/lirc_parallel.c    |  709 +++++++++++
+ drivers/input/lirc/lirc_ite8709.c     |  539 ++++++++
+ drivers/input/lirc/lirc_mceusb.c      | 1225 ++++++++++++++++++
+ 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_streamzap.c   |  777 +++++++++++++
- drivers/input/lirc/lirc_ttusbir.c     |  397 +++++++
- drivers/input/lirc/lirc_zilog.c       | 1374 ++++++++++++++++++++++
- 24 files changed, 14506 insertions(+), 0 deletions(-)
+ drivers/input/lirc/lirc_sasem.c       |  931 +++++++++++++
+ drivers/input/lirc/lirc_serial.c      | 1316 +++++++++++++++++++
+ drivers/input/lirc/lirc_sir.c         | 1283 ++++++++++++++++++
+ drivers/input/lirc/lirc_streamzap.c   |  777 +++++++++++
+ drivers/input/lirc/lirc_ttusbir.c     |  397 ++++++
+ drivers/input/lirc/lirc_zilog.c       | 1374 ++++++++++++++++++++
+ 24 files changed, 14733 insertions(+), 0 deletions(-)
 
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 381190c..fc79bdf 100644
+index b1114cf..eb86f8e 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -3632,6 +3632,15 @@ W:	http://www.pasemi.com/
+@@ -3122,6 +3122,15 @@ W:	http://www.pasemi.com/
  L:	linuxppc-dev at ozlabs.org
  S:	Supported
  
@@ -717,7 +717,7 @@ index 0000000..0485884
 +MODULE_PARM_DESC(debug, "Debug enabled or not");
 diff --git a/drivers/input/lirc/lirc_dev.c b/drivers/input/lirc/lirc_dev.c
 new file mode 100644
-index 0000000..a5d5c89
+index 0000000..0510b4e
 --- /dev/null
 +++ b/drivers/input/lirc/lirc_dev.c
 @@ -0,0 +1,851 @@
@@ -794,7 +794,7 @@ index 0000000..a5d5c89
 +	struct cdev cdev;
 +};
 +
-+static DEFINE_MUTEX(driver_lock);
++static DEFINE_MUTEX(lirc_dev_lock);
 +
 +static struct irctl *irctls[MAX_IRCTL_DEVICES];
 +
@@ -990,7 +990,7 @@ index 0000000..a5d5c89
 +		goto out;
 +	}
 +
-+	mutex_lock(&driver_lock);
++	mutex_lock(&lirc_dev_lock);
 +
 +	minor = d->minor;
 +
@@ -1079,7 +1079,7 @@ index 0000000..a5d5c89
 +		goto out_sysfs;
 +
 +	ir->attached = 1;
-+	mutex_unlock(&driver_lock);
++	mutex_unlock(&lirc_dev_lock);
 +
 +	dprintk("lirc_dev: driver %s registered at minor number = %d\n",
 +		ir->d.name, ir->d.minor);
@@ -1088,7 +1088,7 @@ index 0000000..a5d5c89
 +out_sysfs:
 +	device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor));
 +out_lock:
-+	mutex_unlock(&driver_lock);
++	mutex_unlock(&lirc_dev_lock);
 +out:
 +	return err;
 +}
@@ -1107,12 +1107,12 @@ index 0000000..a5d5c89
 +
 +	ir = irctls[minor];
 +
-+	mutex_lock(&driver_lock);
++	mutex_lock(&lirc_dev_lock);
 +
 +	if (ir->d.minor != minor) {
 +		printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
 +		       "minor (%d) device not registered!", minor);
-+		mutex_unlock(&driver_lock);
++		mutex_unlock(&lirc_dev_lock);
 +		return -ENOENT;
 +	}
 +
@@ -1140,7 +1140,7 @@ index 0000000..a5d5c89
 +		irctls[minor] = NULL;
 +	}
 +
-+	mutex_unlock(&driver_lock);
++	mutex_unlock(&lirc_dev_lock);
 +
 +	return 0;
 +}
@@ -1157,7 +1157,7 @@ index 0000000..a5d5c89
 +		return -ENODEV;
 +	}
 +
-+	if (mutex_lock_interruptible(&driver_lock))
++	if (mutex_lock_interruptible(&lirc_dev_lock))
 +		return -ERESTARTSYS;
 +
 +	ir = irctls[iminor(inode)];
@@ -1203,7 +1203,7 @@ index 0000000..a5d5c89
 +		dprintk(LOGHEAD "open result = %d\n", ir->d.name, ir->d.minor,
 +			retval);
 +
-+	mutex_unlock(&driver_lock);
++	mutex_unlock(&lirc_dev_lock);
 +
 +	return retval;
 +}
@@ -1215,7 +1215,7 @@ index 0000000..a5d5c89
 +
 +	dprintk(LOGHEAD "close called\n", ir->d.name, ir->d.minor);
 +
-+	WARN_ON(mutex_lock_killable(&driver_lock));
++	WARN_ON(mutex_lock_killable(&lirc_dev_lock));
 +
 +	--ir->open;
 +	if (ir->attached) {
@@ -1227,7 +1227,7 @@ index 0000000..a5d5c89
 +		kfree(ir);
 +	}
 +
-+	mutex_unlock(&driver_lock);
++	mutex_unlock(&lirc_dev_lock);
 +
 +	return 0;
 +}
@@ -1764,7 +1764,7 @@ index 0000000..8eeffa2
 +#endif
 diff --git a/drivers/input/lirc/lirc_i2c.c b/drivers/input/lirc/lirc_i2c.c
 new file mode 100644
-index 0000000..5a7f9d0
+index 0000000..e27d937
 --- /dev/null
 +++ b/drivers/input/lirc/lirc_i2c.c
 @@ -0,0 +1,537 @@
@@ -2122,8 +2122,8 @@ index 0000000..5a7f9d0
 +	.owner		= THIS_MODULE,
 +};
 +
-+static int ir_remove(struct i2c_client *client);
 +static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id);
++static int ir_remove(struct i2c_client *client);
 +static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg);
 +
 +static const struct i2c_device_id ir_receiver_id[] = {
@@ -2140,8 +2140,8 @@ index 0000000..5a7f9d0
 +	},
 +	.probe		= ir_probe,
 +	.remove		= ir_remove,
-+	.command	= ir_command,
 +	.id_table	= ir_receiver_id,
++	.command	= ir_command,
 +};
 +
 +static void pcf_probe(struct i2c_client *client, struct IR *ir)
@@ -2869,10 +2869,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..83e4101
+index 0000000..3c87d94
 --- /dev/null
 +++ b/drivers/input/lirc/lirc_imon.c
-@@ -0,0 +1,2062 @@
+@@ -0,0 +1,2298 @@
 +/*
 + *   lirc_imon.c:  LIRC/VFD/LCD driver for SoundGraph iMON IR/VFD/LCD
 + *		   including the iMON PAD model
@@ -2922,6 +2922,8 @@ index 0000000..83e4101
 +
 +#define BIT_DURATION	250	/* each bit received is 250us */
 +
++#define IMON_CLOCK_ENABLE_PACKETS	2
++
 +#define dprintk(fmt, args...)						\
 +	do {								\
 +		if (debug)						\
@@ -3008,7 +3010,7 @@ index 0000000..83e4101
 +	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 has_touchscreen;		/* touchscreen present? */
++	int display_type;		/* store the display type */
 +	int pad_mouse;			/* toggle kbd(0)/mouse(1) mode */
 +	int touch_x;			/* x coordinate on touchscreen */
 +	int touch_y;			/* y coordinate on touchscreen */
@@ -3038,8 +3040,9 @@ index 0000000..83e4101
 +};
 +
 +enum {
-+	IMON_IR_PROTOCOL_IMON = 0,
-+	IMON_IR_PROTOCOL_MCE  = 1,
++	IMON_IR_PROTOCOL_IMON       = 0,
++	IMON_IR_PROTOCOL_MCE        = 1,
++	IMON_IR_PROTOCOL_IMON_NOPAD = 2,
 +};
 +/*
 + * USB Device ID for iMON USB Control Boards
@@ -3236,7 +3239,7 @@ index 0000000..83e4101
 +/* 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) */
++/* IR protocol: native iMON, Windows MCE (RC-6), or iMON w/o PAD stabilize */
 +static int ir_protocol;
 +
 +/*
@@ -3245,6 +3248,9 @@ index 0000000..83e4101
 + */
 +static int nomouse;
 +
++/* threshold at which a pad push registers as an arrow key in kbd mode */
++static int pad_thresh;
++
 +
 +/***  M O D U L E   C O D E ***/
 +
@@ -3260,10 +3266,15 @@ index 0000000..83e4101
 +		 "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)");
 +module_param(ir_protocol, int, S_IRUGO | S_IWUSR);
 +MODULE_PARM_DESC(ir_protocol, "Which IR protocol to use. 0=native iMON, "
-+		 "1=Windows Media Center Ed. (RC-6) (default: native iMON)");
++		 "1=Windows Media Center Ed. (RC-6), 2=iMON w/o PAD stabilize "
++		 "(default: native iMON)");
 +module_param(nomouse, int, S_IRUGO | S_IWUSR);
 +MODULE_PARM_DESC(nomouse, "Disable mouse input device mode when IR device is "
 +		 "open. 0=don't disable, 1=disable. (default: don't disable)");
++module_param(pad_thresh, int, S_IRUGO | S_IWUSR);
++MODULE_PARM_DESC(pad_thresh, "Threshold at which a pad push registers as an "
++		 "arrow key in kbd mode (default 80 on newer devices, 15 on "
++		 "older devices)");
 +
 +static void free_imon_context(struct imon_context *context)
 +{
@@ -3481,21 +3492,105 @@ index 0000000..83e4101
 +		return -ENODEV;
 +	}
 +
-+	mutex_lock(&context->lock);
-+
 +	if (!context->dev_present_intf0) {
 +		err("%s: no iMON device present", __func__);
-+		retval = -ENODEV;
-+		goto exit;
++		return -ENODEV;
 +	}
 +
 +	memcpy(context->usb_tx_buf, packet, sizeof(packet));
 +	retval = send_packet(context);
 +
-+exit:
-+	mutex_unlock(&context->lock);
++	return retval;
++}
++
++/**
++ * Sends packets to setup and show clock on iMON display
++ *
++ * Arguments: year - last 2 digits of year, month - 1..12,
++ * day - 1..31, dow - day of the week (0-Sun...6-Sat),
++ * hour - 0..23, minute - 0..59, second - 0..59
++ */
++static int send_set_imon_clock(struct imon_context *context,
++			       unsigned int year, unsigned int month,
++			       unsigned int day, unsigned int dow,
++			       unsigned int hour, unsigned int minute,
++			       unsigned int second)
++{
++	unsigned char clock_enable_pkt[IMON_CLOCK_ENABLE_PACKETS][8];
++	int retval = 0;
++	int i;
++
++	if (!context) {
++		err("%s: no context for device", __func__);
++		return -ENODEV;
++	}
++
++	switch(context->display_type) {
++	case IMON_DISPLAY_TYPE_LCD:
++		clock_enable_pkt[0][0] = 0x80;
++		clock_enable_pkt[0][1] = year;
++		clock_enable_pkt[0][2] = month-1;
++		clock_enable_pkt[0][3] = day;
++		clock_enable_pkt[0][4] = hour;
++		clock_enable_pkt[0][5] = minute;
++		clock_enable_pkt[0][6] = second;
++
++		clock_enable_pkt[1][0] = 0x80;
++		clock_enable_pkt[1][1] = 0;
++		clock_enable_pkt[1][2] = 0;
++		clock_enable_pkt[1][3] = 0;
++		clock_enable_pkt[1][4] = 0;
++		clock_enable_pkt[1][5] = 0;
++		clock_enable_pkt[1][6] = 0;
++
++		if (context->ffdc_dev) {
++			clock_enable_pkt[0][7] = 0x50;
++			clock_enable_pkt[1][7] = 0x51;
++		} else {
++			clock_enable_pkt[0][7] = 0x88;
++			clock_enable_pkt[1][7] = 0x8a;
++		}
++
++		break;
++
++	case IMON_DISPLAY_TYPE_VFD:
++		clock_enable_pkt[0][0] = year;
++		clock_enable_pkt[0][1] = month-1;
++		clock_enable_pkt[0][2] = day;
++		clock_enable_pkt[0][3] = dow;
++		clock_enable_pkt[0][4] = hour;
++		clock_enable_pkt[0][5] = minute;
++		clock_enable_pkt[0][6] = second;
++		clock_enable_pkt[0][7] = 0x40;
++
++		clock_enable_pkt[1][0] = 0;
++		clock_enable_pkt[1][1] = 0;
++		clock_enable_pkt[1][2] = 1;
++		clock_enable_pkt[1][3] = 0;
++		clock_enable_pkt[1][4] = 0;
++		clock_enable_pkt[1][5] = 0;
++		clock_enable_pkt[1][6] = 0;
++		clock_enable_pkt[1][7] = 0x42;
++
++		break;
++
++	default:
++		return -ENODEV;
++	}
++
++
++	for (i = 0; i < IMON_CLOCK_ENABLE_PACKETS; i++) {
++		memcpy(context->usb_tx_buf, clock_enable_pkt[i], 8);
++		retval = send_packet(context);
++		if (retval) {
++			err("%s: send_packet failed for packet %d",
++			    __func__, i);
++			break;
++		}
++	}
 +
 +	return retval;
++
 +}
 +
 +/**
@@ -3551,16 +3646,104 @@ index 0000000..83e4101
 +	return count;
 +}
 +
++/**
++ * sysfs functions to control internal imon clock
++ */
++static ssize_t show_imon_clock(struct device *d,
++			       struct device_attribute *attr, char *buf)
++{
++	struct imon_context *context = dev_get_drvdata(d);
++	size_t len;
++
++	if (!context)
++		return -ENODEV;
++
++	mutex_lock(&context->lock);
++
++	if (!context->display_supported) {
++		len = snprintf(buf, PAGE_SIZE, "Not supported.");
++	} else {
++		len = snprintf(buf, PAGE_SIZE,
++			"To set the clock on your iMON display:\n"
++			"# date \"+%%y %%m %%d %%w %%H %%M %%S\" > imon_clock\n"
++			"%s", context->display_isopen ?
++			"\nNOTE: imon device must be closed\n" : "");
++	}
++
++	mutex_unlock(&context->lock);
++
++	return len;
++}
++
++static ssize_t store_imon_clock(struct device *d,
++				struct device_attribute *attr,
++				const char *buf, size_t count)
++{
++	struct imon_context *context = dev_get_drvdata(d);
++	ssize_t retval;
++	unsigned int year, month, day, dow, hour, minute, second;
++
++	if (!context)
++		return -ENODEV;
++
++	mutex_lock(&context->lock);
++
++	if (!context->display_supported) {
++		retval = -ENODEV;
++		goto exit;
++	} else if (context->display_isopen) {
++		retval = -EBUSY;
++		goto exit;
++	}
++
++	if (sscanf(buf, "%u %u %u %u %u %u %u",	&year, &month, &day, &dow,
++		   &hour, &minute, &second) != 7) {
++		retval = -EINVAL;
++		goto exit;
++	}
++
++	if ((month < 1 || month > 12) ||
++	    (day < 1 || day > 31) || (dow > 6) ||
++	    (hour > 23) || (minute > 59) || (second > 59)) {
++		retval = -EINVAL;
++		goto exit;
++	}
++
++	retval = send_set_imon_clock(context, year, month, day, dow,
++				     hour, minute, second);
++	if (retval)
++		goto exit;
++
++	retval = count;
++exit:
++	mutex_unlock(&context->lock);
++
++	return retval;
++}
++
++
++static DEVICE_ATTR(imon_clock, S_IWUSR | S_IRUGO, show_imon_clock,
++		   store_imon_clock);
++
 +static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote,
 +		   store_associate_remote);
 +
-+static struct attribute *imon_sysfs_entries[] = {
++static struct attribute *imon_display_sysfs_entries[] = {
++	&dev_attr_imon_clock.attr,
++	NULL
++};
++
++static struct attribute_group imon_display_attribute_group = {
++	.attrs = imon_display_sysfs_entries
++};
++
++static struct attribute *imon_rf_sysfs_entries[] = {
 +	&dev_attr_associate_remote.attr,
 +	NULL
 +};
 +
-+static struct attribute_group imon_attribute_group = {
-+	.attrs = imon_sysfs_entries
++static struct attribute_group imon_rf_attribute_group = {
++	.attrs = imon_rf_sysfs_entries
 +};
 +
 +/**
@@ -3743,12 +3926,15 @@ index 0000000..83e4101
 +	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:
++		/* MCE proto not supported on devices without tx control */
++		if (!context->tx_control) {
++			printk(KERN_INFO "%s: MCE IR protocol not supported on "
++			       "this device, using iMON protocol\n", __func__);
++			context->ir_protocol = IMON_IR_PROTOCOL_IMON;
++			return;
++		}
 +		dprintk("Configuring IR receiver for MCE protocol\n");
 +		ir_proto_packet[0] = 0x01;
 +		context->ir_protocol = IMON_IR_PROTOCOL_MCE;
@@ -3758,10 +3944,16 @@ index 0000000..83e4101
 +		/* ir_proto_packet[0] = 0x00; // already the default */
 +		context->ir_protocol = IMON_IR_PROTOCOL_IMON;
 +		break;
++	case IMON_IR_PROTOCOL_IMON_NOPAD:
++		dprintk("Configuring IR receiver for iMON protocol without "
++			"PAD stabilize function enabled\n");
++		/* ir_proto_packet[0] = 0x00; // already the default */
++		context->ir_protocol = IMON_IR_PROTOCOL_IMON_NOPAD;
++		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;
++		context->ir_protocol = IMON_IR_PROTOCOL_IMON;
 +		break;
 +	}
 +	memcpy(context->usb_tx_buf, &ir_proto_packet,
@@ -3891,12 +4083,14 @@ index 0000000..83e4101
 +}
 +
 +/**
-+ * The directional pad is overly sensitive in keyboard mode, so we do some
-+ * interesting contortions to make it less touchy.
++ * The directional pad behaves a bit differently, depending on whether this is
++ * one of the older ffdc devices or a newer device. Newer devices appear to
++ * have a higher resolution matrix for more precise mouse movement, but it
++ * makes things overly sensitive in keyboard mode, so we do some interesting
++ * contortions to make it less touchy. Older devices run through the same
++ * routine with shorter timeout and a smaller threshold.
 + */
-+#define IMON_PAD_TIMEOUT	1000	/* in msecs */
-+#define IMON_PAD_THRESHOLD	80	/* 160x160 square */
-+static int stabilize(int a, int b)
++static int stabilize(int a, int b, u16 timeout, u16 threshold)
 +{
 +	struct timeval ct;
 +	static struct timeval prev_time = {0, 0};
@@ -3920,7 +4114,7 @@ index 0000000..83e4101
 +
 +	prev_time = ct;
 +
-+	if (abs(x) > IMON_PAD_THRESHOLD || abs(y) > IMON_PAD_THRESHOLD) {
++	if (abs(x) > threshold || abs(y) > threshold) {
 +		if (abs(y) > abs(x))
 +			result = (y > 0) ? 0x7F : 0x80;
 +		else
@@ -3935,21 +4129,21 @@ index 0000000..83e4101
 +			if (hits > 3) {
 +				switch (result) {
 +				case 0x7F:
-+					y = 17 * IMON_PAD_THRESHOLD / 30;
++					y = 17 * threshold / 30;
 +					break;
 +				case 0x80:
-+					y -= 17 * IMON_PAD_THRESHOLD / 30;
++					y -= 17 * threshold / 30;
 +					break;
 +				case 0x7F00:
-+					x = 17 * IMON_PAD_THRESHOLD / 30;
++					x = 17 * threshold / 30;
 +					break;
 +				case 0x8000:
-+					x -= 17 * IMON_PAD_THRESHOLD / 30;
++					x -= 17 * threshold / 30;
 +					break;
 +				}
 +			}
 +
-+			if (hits == 2 && msec_hit < IMON_PAD_TIMEOUT) {
++			if (hits == 2 && msec_hit < timeout) {
 +				result = 0;
 +				hits = 1;
 +			}
@@ -3974,20 +4168,21 @@ index 0000000..83e4101
 +	char rel_x = 0x00, rel_y = 0x00;
 +	int octet, bit;
 +	unsigned char mask;
-+	int i, chunk_num, dir;
++	int i, chunk_num;
 +	int ts_input = 0;
 +	int mouse_input;
++	int right_shift = 1;
++	int dir = 0;
++	u16 timeout, threshold;
 +	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)
++	if (context->display_type == IMON_DISPLAY_TYPE_VGA)
 +		touch = context->touch;
 +
 +	/* keyboard/mouse mode toggle button */
@@ -4005,8 +4200,8 @@ index 0000000..83e4101
 +	}
 +
 +	/* 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 (context->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 &&
++	    buf[7] == 0x86) {
 +		if (touch == NULL) {
 +			printk(KERN_WARNING "%s: touchscreen input device is "
 +			       "NULL!\n", __func__);
@@ -4028,31 +4223,30 @@ index 0000000..83e4101
 +			mouse_input = 1;
 +			rel_x = buf[2];
 +			rel_y = buf[3];
-+		/* 0xffdc iMON PAD input */
++			right_shift = 1;
++		/* 0xffdc iMON PAD or mouse button 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 |= ~0x0f;
 +			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 |= ~0x0f;
 +			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;
++			right_shift = 2;
 +		/* ch+/- buttons, which we use for an emulated scroll wheel */
-+		} else if (!memcmp(buf, ch_up, 4) || !memcmp(buf, ch_down, 4))
++		} else if (!memcmp(buf, ch_up, 4)) {
 +			mouse_input = 1;
-+		else
++			dir = 1;
++		} else if (!memcmp(buf, ch_down, 4)) {
++			mouse_input = 1;
++			dir = -1;
++		} else
 +			mouse_input = 0;
 +
 +		if (mouse_input) {
@@ -4062,18 +4256,12 @@ index 0000000..83e4101
 +				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);
++						 buf[1] >> right_shift & 0x01);
 +				input_report_rel(mouse, REL_X, rel_x);
 +				input_report_rel(mouse, REL_Y, rel_y);
 +			} else
@@ -4098,6 +4286,9 @@ index 0000000..83e4101
 +		/* first, pad to 8 bytes so it conforms with everything else */
 +		buf[5] = buf[6] = buf[7] = 0;
 +		len = 8;
++		timeout = 500;	/* in msecs */
++		/* (2*threshold) x (2*threshold) square */
++		threshold = pad_thresh ? pad_thresh : 80;
 +		rel_x = buf[2];
 +		rel_y = buf[3];
 +
@@ -4111,12 +4302,23 @@ index 0000000..83e4101
 +		 * diagonals, it has a tendancy to jump back and forth, so lets
 +		 * try to ignore when they get too close
 +		 */
-+		if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
-+			dir = stabilize((int)rel_x, (int)rel_y);
-+			if (!dir)
-+				return;
-+			buf[2] = dir & 0xFF;
-+			buf[3] = (dir >> 8) & 0xFF;
++		if (context->ir_protocol == IMON_IR_PROTOCOL_IMON) {
++			if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
++				dir = stabilize((int)rel_x, (int)rel_y,
++						timeout, threshold);
++				if (!dir)
++					return;
++				buf[2] = dir & 0xFF;
++				buf[3] = (dir >> 8) & 0xFF;
++			}
++		} else {
++			if (abs(rel_y) > abs(rel_x)) {
++				buf[2] = (rel_y > 0) ? 0x7F : 0x80;
++				buf[3] = 0;
++			} else {
++				buf[2] = 0;
++				buf[3] = (rel_x > 0) ? 0x7F : 0x80;
++			}
 +		}
 +
 +	} else if ((len == 8) && (buf[0] & 0x40) &&
@@ -4134,6 +4336,9 @@ index 0000000..83e4101
 +		 * 0x01007F00, ..., so one can use the normal imon-pad config
 +		 * from the remotes dir.
 +		 */
++		timeout = 10;	/* in msecs */
++		/* (2*threshold) x (2*threshold) square */
++		threshold = pad_thresh ? pad_thresh : 15;
 +
 +		/* buf[1] is x */
 +		rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
@@ -4149,11 +4354,22 @@ index 0000000..83e4101
 +		buf[0] = 0x01;
 +		buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
 +
-+		dir = stabilize((int)rel_x, (int)rel_y);
-+		if (!dir)
-+			return;
-+		buf[2] = dir & 0xFF;
-+		buf[3] = (dir >> 8) & 0xFF;
++		if (context->ir_protocol == IMON_IR_PROTOCOL_IMON) {
++			dir = stabilize((int)rel_x, (int)rel_y,
++					timeout, threshold);
++			if (!dir)
++				return;
++			buf[2] = dir & 0xFF;
++			buf[3] = (dir >> 8) & 0xFF;
++		} else {
++			if (abs(rel_y) > abs(rel_x)) {
++				buf[2] = (rel_y > 0) ? 0x7F : 0x80;
++				buf[3] = 0;
++			} else {
++				buf[2] = 0;
++				buf[3] = (rel_x > 0) ? 0x7F : 0x80;
++			}
++		}
 +
 +	} else if (ts_input) {
 +		/*
@@ -4276,7 +4492,7 @@ index 0000000..83e4101
 +	struct imon_context *context = (struct imon_context *)data;
 +	struct input_dev *touch;
 +
-+	if (!context->has_touchscreen)
++	if (!context->display_type == IMON_DISPLAY_TYPE_VGA)
 +		return;
 +
 +	touch = context->touch;
@@ -4387,24 +4603,41 @@ index 0000000..83e4101
 +	int alloc_status = 0;
 +	int vfd_proto_6p = 0;
 +	int ir_onboard_decode = 0;
-+	int has_touchscreen = 0;
 +	int buf_chunk_size = BUF_CHUNK_SIZE;
 +	int code_length;
 +	int tx_control = 0;
 +	struct imon_context *context = NULL;
 +	struct imon_context *first_if_context = NULL;
-+	int i;
++	int i, sysfs_err;
++	int configured_display_type = IMON_DISPLAY_TYPE_VFD;
 +	u16 vendor, product;
 +	const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
 +					    0x00, 0x00, 0x00, 0x88 };
 +
 +	/*
++	 * Try to auto-detect the type of display if the user hasn't set
++	 * it by hand via the display_type modparam. Default is VFD.
++	 */
++	if (display_type == IMON_DISPLAY_TYPE_AUTO) {
++		if (usb_match_id(interface, lcd_device_list))
++			configured_display_type = IMON_DISPLAY_TYPE_LCD;
++		else if (usb_match_id(interface, imon_touchscreen_list))
++			configured_display_type = IMON_DISPLAY_TYPE_VGA;
++		else if (usb_match_id(interface, ir_only_list))
++			configured_display_type = IMON_DISPLAY_TYPE_NONE;
++		else
++			configured_display_type = IMON_DISPLAY_TYPE_VFD;
++	} else {
++		configured_display_type = display_type;
++		dprintk("%s: overriding display type to %d via modparam\n",
++			__func__, display_type);
++	}
++
++	/*
 +	 * If it's the LCD, as opposed to the VFD, we just need to replace
 +	 * the "write" file op.
 +	 */
-+	if ((display_type == IMON_DISPLAY_TYPE_AUTO &&
-+	     usb_match_id(interface, lcd_device_list)) ||
-+	    display_type == IMON_DISPLAY_TYPE_LCD)
++	if (configured_display_type == IMON_DISPLAY_TYPE_LCD)
 +		display_fops.write = &lcd_write;
 +
 +	/*
@@ -4480,9 +4713,7 @@ index 0000000..83e4101
 +	 * that SoundGraph recycles device IDs between devices both with
 +	 * and without... :\
 +	 */
-+	if ((display_type == IMON_DISPLAY_TYPE_AUTO &&
-+	     usb_match_id(interface, ir_only_list)) ||
-+	    display_type == IMON_DISPLAY_TYPE_NONE) {
++	if (configured_display_type == IMON_DISPLAY_TYPE_NONE) {
 +		display_ep_found = 0;
 +		dprintk("%s: device has no display\n", __func__);
 +	}
@@ -4491,11 +4722,8 @@ index 0000000..83e4101
 +	 * 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 ((display_type == IMON_DISPLAY_TYPE_AUTO &&
-+	     usb_match_id(interface, imon_touchscreen_list)) ||
-+	    display_type == IMON_DISPLAY_TYPE_VGA) {
++	if (configured_display_type == IMON_DISPLAY_TYPE_VGA) {
 +		display_ep_found = 0;
-+		has_touchscreen = 1;
 +		dprintk("%s: iMON Touch device found\n", __func__);
 +	}
 +
@@ -4636,7 +4864,7 @@ index 0000000..83e4101
 +		if (product == 0xffdc)
 +			context->ffdc_dev = 1;
 +
-+		context->has_touchscreen = has_touchscreen;
++		context->display_type = configured_display_type;
 +
 +		context->mouse = input_allocate_device();
 +
@@ -4689,7 +4917,7 @@ index 0000000..83e4101
 +		context->rx_endpoint_intf1 = rx_endpoint;
 +		context->rx_urb_intf1 = rx_urb;
 +
-+		if (context->has_touchscreen) {
++		if (context->display_type == IMON_DISPLAY_TYPE_VGA) {
 +			context->touch = input_allocate_device();
 +
 +			snprintf(context->name_touch,
@@ -4745,17 +4973,23 @@ index 0000000..83e4101
 +
 +	/* RF products *also* use 0xffdc... sigh... */
 +	if (context->ffdc_dev) {
-+		int err;
-+
-+		err = sysfs_create_group(&interface->dev.kobj,
-+					 &imon_attribute_group);
-+		if (err)
-+			err("%s: Could not create sysfs entries(%d)",
-+			    __func__, err);
++		sysfs_err = sysfs_create_group(&interface->dev.kobj,
++					       &imon_rf_attribute_group);
++		if (sysfs_err)
++			err("%s: Could not create RF sysfs entries(%d)",
++			    __func__, sysfs_err);
 +	}
 +
 +	if (context->display_supported && ifnum == 0) {
 +		dprintk("%s: Registering iMON display with sysfs\n", __func__);
++
++		/* set up sysfs entry for built-in clock */
++		sysfs_err = sysfs_create_group(&interface->dev.kobj,
++					       &imon_display_attribute_group);
++		if (sysfs_err)
++			err("%s: Could not create display sysfs entries(%d)",
++			    __func__, sysfs_err);
++
 +		if (usb_register_dev(interface, &imon_class)) {
 +			/* Not a fatal error, so ignore */
 +			printk(KERN_INFO "%s: could not get a minor number for "
@@ -4830,7 +5064,9 @@ index 0000000..83e4101
 +	 * hasn't been called
 +	 */
 +	sysfs_remove_group(&interface->dev.kobj,
-+			   &imon_attribute_group);
++			   &imon_display_attribute_group);
++	sysfs_remove_group(&interface->dev.kobj,
++			   &imon_rf_attribute_group);
 +
 +	usb_set_intfdata(interface, NULL);
 +
@@ -4849,7 +5085,7 @@ index 0000000..83e4101
 +	} else {
 +		context->dev_present_intf1 = 0;
 +		usb_kill_urb(context->rx_urb_intf1);
-+		if (context->has_touchscreen)
++		if (context->display_type == IMON_DISPLAY_TYPE_VGA)
 +			input_unregister_device(context->touch);
 +	}
 +
@@ -6596,10 +6832,10 @@ index 0000000..3d53181
 +MODULE_PARM_DESC(debug, "Enable debugging messages");
 diff --git a/drivers/input/lirc/lirc_mceusb.c b/drivers/input/lirc/lirc_mceusb.c
 new file mode 100644
-index 0000000..840d0e1
+index 0000000..58dfdd5
 --- /dev/null
 +++ b/drivers/input/lirc/lirc_mceusb.c
-@@ -0,0 +1,1223 @@
+@@ -0,0 +1,1225 @@
 +/*
 + * LIRC driver for Windows Media Center Edition USB Infrared Transceivers
 + *
@@ -6783,6 +7019,8 @@ index 0000000..840d0e1
 +	{ USB_DEVICE(VENDOR_FORMOSA, 0xe017) },
 +	/* Formosa Industrial Computing / Beanbag Emulation Device */
 +	{ USB_DEVICE(VENDOR_FORMOSA, 0xe018) },
++	/* Formosa Industrial Computing AIM IR605/A */
++	{ USB_DEVICE(VENDOR_FORMOSA, 0xe03c) },
 +	/* Fintek eHome Infrared Transceiver */
 +	{ USB_DEVICE(VENDOR_FINTEK, 0x0602) },
 +	/* Fintek eHome Infrared Transceiver (in the AOpen MP45) */
@@ -10831,10 +11069,10 @@ index 0000000..d602e90
 +MODULE_PARM_DESC(debug, "Enable debugging messages");
 diff --git a/drivers/input/lirc/lirc_sir.c b/drivers/input/lirc/lirc_sir.c
 new file mode 100644
-index 0000000..6c64072
+index 0000000..b497642
 --- /dev/null
 +++ b/drivers/input/lirc/lirc_sir.c
-@@ -0,0 +1,1294 @@
+@@ -0,0 +1,1283 @@
 +/*
 + * LIRC SIR driver, (C) 2000 Milan Pikula <www at fornax.sk>
 + *
@@ -10979,8 +11217,16 @@ index 0000000..6c64072
 +#define LIRC_IRQ 4
 +#endif
 +#ifndef LIRC_PORT
++/* for external dongles, default to com1 */
++#if defined(LIRC_SIR_ACTISYS_ACT200L) || \
++    defined(LIRC_SIR_ACTISYS_ACT220L) || \
++    defined(LIRC_SIR_TEKRAM)
++#define LIRC_PORT 0x3f8
++#else
++/* onboard sir ports are typically com3 */
 +#define LIRC_PORT 0x3e8
 +#endif
++#endif
 +
 +static int io = LIRC_PORT;
 +static int irq = LIRC_IRQ;
@@ -10998,7 +11244,6 @@ index 0000000..6c64072
 +static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue);
 +
 +static DEFINE_SPINLOCK(hardware_lock);
-+static DEFINE_SPINLOCK(dev_lock);
 +
 +static int rx_buf[RBUF_LEN];
 +static unsigned int rx_tail, rx_head;
@@ -11015,8 +11260,6 @@ index 0000000..6c64072
 +/* SECTION: Prototypes */
 +
 +/* Communication with user-space */
-+static int lirc_open(struct inode *inode, struct file *file);
-+static int lirc_close(struct inode *inode, struct file *file);
 +static unsigned int lirc_poll(struct file *file, poll_table *wait);
 +static ssize_t lirc_read(struct file *file, char *buf, size_t count,
 +		loff_t *ppos);
@@ -11076,22 +11319,6 @@ index 0000000..6c64072
 +
 +/* SECTION: Communication with user-space */
 +
-+static int lirc_open(struct inode *inode, struct file *file)
-+{
-+	spin_lock(&dev_lock);
-+	if (module_refcount(THIS_MODULE)) {
-+		spin_unlock(&dev_lock);
-+		return -EBUSY;
-+	}
-+	spin_unlock(&dev_lock);
-+	return 0;
-+}
-+
-+static int lirc_close(struct inode *inode, struct file *file)
-+{
-+	return 0;
-+}
-+
 +static unsigned int lirc_poll(struct file *file, poll_table *wait)
 +{
 +	poll_wait(file, &lirc_read_queue, wait);
@@ -11306,8 +11533,8 @@ index 0000000..6c64072
 +	.write		= lirc_write,
 +	.poll		= lirc_poll,
 +	.ioctl		= lirc_ioctl,
-+	.open		= lirc_open,
-+	.release	= lirc_close,
++	.open		= lirc_dev_fop_open,
++	.release	= lirc_dev_fop_close,
 +};
 +
 +static int set_use_inc(void *data)
@@ -13317,7 +13544,7 @@ 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..a06e6de
+index 0000000..c532399
 --- /dev/null
 +++ b/drivers/input/lirc/lirc_zilog.c
 @@ -0,0 +1,1374 @@




More information about the fedora-extras-commits mailing list