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 scm-commits
mailing list