Skip to contentSkip to conversation

V3 - Implementation of IR support using the input subsystem

RFC PATCH In review Jon Smirl 4 participants 16 messages Oct 6, 2008 – May 29, 2009

Subsystems (3)
lore
Share & tools
lore

Jon Smirl

author
#0 lore raw

cover V3 - Implementation of IR support using the input subsystem

Third pass at implementing evdev support for IR. The goal of in-kernel IR is to integrate IR events into the evdev input event queue and maintain ordering of events from all input devices.

New feature, raw mode. There are three sysfs attributes - ir_raw, ir_carrier, ir_xmitter. Read from ir_raw to get the raw timing data from the IR device. Set carrier and active xmitters and then copy raw data to ir_raw to send. These attributes may be better on a debug switch. You would use raw mode when decoding a new protocol. After you figure out the new protocol, write an in-kernel encoder/decoder for it.

What should the IR API look like?

How are IR events mapped into keyboard events? Should they be mapped? Map them in the kernel or in user space? The maps are tiny, less than 1K per remote. Sysfs can be used to load maps into the kernel driver. Make maps only for the common buttons and don't map unusual ones?

How should multiple remotes be handled? Split them out into individual input devices, or group them onto a single IR device? I can implement either.

The in-kernel code is tiny, about 20K including a driver.

Quoted 1 line

From last post...

Note that user space IR device drivers can use the existing support in evdev to inject events into the input queue.

Send and receive are implemented. Received IR messages are decoded and sent to user space as input messages. Send is done via an IOCTL on the input device.

Two drivers are supplied. mceusb2 implements send and receive support for the Microsoft USB IR dongle.

The GPT driver implements receive only support for a GPT pin - GPT is a GPIO with a timer attached.

Code is only lightly tested. Encoders and decoders have not been written for all protocols. Repeat is not handled for any protocol.
I'm looking for help. There are 15 more existing LIRC drivers.

---

Jon Smirl (4):
Microsoft mceusb2 driver for in-kernel IR subsystem
Example of PowerPC device tree support for GPT based IR
GPT driver for in-kernel IR support.
Changes to core input subsystem to allow send and receive of IR messages. Encode and decode state machines are provided for common IR porotocols such as Sony, JVC, NEC, Philips, etc.

 arch/powerpc/boot/dts/dspeak01.dts |   19 -
 drivers/input/Kconfig              |    2 
 drivers/input/Makefile             |    3 
 drivers/input/evdev.c              |   55 +++
 drivers/input/input.c              |   21 +
 drivers/input/ir-core.c            |  659 ++++++++++++++++++++++++++++++++
 drivers/input/ir/Kconfig           |   26 +
 drivers/input/ir/Makefile          |    7 
 drivers/input/ir/ir-gpt.c          |  221 +++++++++++
 drivers/input/ir/ir-mceusb2.c      |  741 ++++++++++++++++++++++++++++++++++++
 include/linux/input.h              |  101 +++++
 include/linux/mod_devicetable.h    |    3 
 12 files changed, 1846 insertions(+), 12 deletions(-)
 create mode 100644 drivers/input/ir-core.c
 create mode 100644 drivers/input/ir/Kconfig
 create mode 100644 drivers/input/ir/Makefile
 create mode 100644 drivers/input/ir/ir-gpt.c
 create mode 100644 drivers/input/ir/ir-mceusb2.c
Signature · 2 lines
Jon Smirl
[email protected]
author
#1 lore raw

RFC PATCH 1/4 Changes to core input subsystem to allow send and receive of IR messages. Encode and decode state machines are provided for common IR porotocols such as Sony, JVC, NEC, Philips, etc.

Received IR messages generate event in the input queue. IR messages are sent using an input IOCTL.

Jon Smirl
<[email protected]>

---
 drivers/input/Kconfig           |    2 
 drivers/input/Makefile          |    3 
 drivers/input/evdev.c           |   55 +++
 drivers/input/input.c           |   21 +
 drivers/input/ir-core.c         |  659 +++++++++++++++++++++++++++++++++++++++
 drivers/input/ir/Kconfig        |   14 +
 drivers/input/ir/Makefile       |    5 
 include/linux/input.h           |  101 ++++++
 include/linux/mod_devicetable.h |    3 
 9 files changed, 862 insertions(+), 1 deletions(-)
 create mode 100644 drivers/input/ir-core.c
 create mode 100644 drivers/input/ir/Kconfig
 create mode 100644 drivers/input/ir/Makefile
drivers/input/Kconfig +2 -0
index 747633c..780d321 100644
@@ -172,6 +172,8 @@ source "drivers/input/touchscreen/Kconfig"
 
 source "drivers/input/misc/Kconfig"
 
+source "drivers/input/ir/Kconfig"
+
 endif
 
 menu "Hardware I/O ports"
drivers/input/Makefile +2 -1
index 6a1049b..da47340 100644
@@ -5,7 +5,7 @@
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_INPUT)		+= input-core.o
-input-core-objs := input.o ff-core.o
+input-core-objs := input.o ff-core.o ir-core.o
 
 obj-$(CONFIG_INPUT_FF_MEMLESS)	+= ff-memless.o
 obj-$(CONFIG_INPUT_POLLDEV)	+= input-polldev.o
@@ -21,6 +21,7 @@ obj-$(CONFIG_INPUT_JOYSTICK)	+= joystick/
 obj-$(CONFIG_INPUT_TABLET)	+= tablet/
 obj-$(CONFIG_INPUT_TOUCHSCREEN)	+= touchscreen/
 obj-$(CONFIG_INPUT_MISC)	+= misc/
+obj-$(CONFIG_INPUT_IR)		+= ir/
 
 obj-$(CONFIG_INPUT_APMPOWER)	+= apm-power.o
 
drivers/input/evdev.c +55 -0

85 lines not on this page · raw message

drivers/input/input.c +21 -0
index c13ced3..18f36d7 100644
@@ -240,6 +240,10 @@ static void input_handle_event(struct input_dev *dev,
 	case EV_PWR:
 		disposition = INPUT_PASS_TO_ALL;
 		break;
+
+	case EV_IR:
+		disposition = INPUT_PASS_TO_ALL;
+		break;
 	}
 
 	if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
@@ -693,6 +697,7 @@ static const struct input_device_id *input_match_device(const struct input_devic
 		MATCH_BIT(sndbit, SND_MAX);
 		MATCH_BIT(ffbit,  FF_MAX);
 		MATCH_BIT(swbit,  SW_MAX);
+		MATCH_BIT(irbit,  IR_MAX);
 
 		return id;
 	}
@@ -815,6 +820,8 @@ static int input_devices_seq_show(struct seq_file *seq, void *v)
 		input_seq_print_bitmap(seq, "FF", dev->ffbit, FF_MAX);
 	if (test_bit(EV_SW, dev->evbit))
 		input_seq_print_bitmap(seq, "SW", dev->swbit, SW_MAX);
+	if (test_bit(EV_IR, dev->evbit))
+		input_seq_print_bitmap(seq, "IR", dev->irbit, IR_MAX);
 
 	seq_putc(seq, '\n');
 
@@ -992,6 +999,8 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id,
 				'f', id->ffbit, 0, FF_MAX);
 	len += input_print_modalias_bits(buf + len, size - len,
 				'w', id->swbit, 0, SW_MAX);
+	len += input_print_modalias_bits(buf + len, size - len,
+				'i', id->irbit, 0, IR_MAX);
 
 	if (add_cr)
 		len += snprintf(buf + len, max(size - len, 0), "\n");
@@ -1093,6 +1102,7 @@ INPUT_DEV_CAP_ATTR(LED, led);
 INPUT_DEV_CAP_ATTR(SND, snd);
 INPUT_DEV_CAP_ATTR(FF, ff);
 INPUT_DEV_CAP_ATTR(SW, sw);
+INPUT_DEV_CAP_ATTR(IR, ir);
 
 static struct attribute *input_dev_caps_attrs[] = {
 	&dev_attr_ev.attr,
@@ -1104,6 +1114,7 @@ static struct attribute *input_dev_caps_attrs[] = {
 	&dev_attr_snd.attr,
 	&dev_attr_ff.attr,
 	&dev_attr_sw.attr,
+	&dev_attr_ir.attr,
 	NULL
 };
 
@@ -1221,6 +1232,8 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
 		INPUT_ADD_HOTPLUG_BM_VAR("FF=", dev->ffbit, FF_MAX);
 	if (test_bit(EV_SW, dev->evbit))
 		INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX);
+	if (test_bit(EV_IR, dev->evbit))
+		INPUT_ADD_HOTPLUG_BM_VAR("IR=", dev->irbit, IR_MAX);
 
 	INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev);
 
@@ -1333,6 +1346,10 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int
 		__set_bit(code, dev->ffbit);
 		break;
 
+	case EV_IR:
+		__set_bit(code, dev->irbit);
+		break;
+
 	case EV_PWR:
 		/* do nothing */
 		break;
@@ -1396,6 +1413,10 @@ int input_register_device(struct input_dev *dev)
 	if (error)
 		return error;
 
+	error = input_ir_register(dev);
+	if (error)
+		return error;
+
 	path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
 	printk(KERN_INFO "input: %s as %s\n",
 		dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
drivers/input/ir-core.c new file +659 -0

659 lines not on this page · raw message

drivers/input/ir/Kconfig new file +14 -0
new file mode 100644
index 0000000..8afd2d6
@@ -0,0 +1,14 @@
+#
+# LIRC driver(s) configuration
+#
+menuconfig INPUT_IR
+	bool "Infrared Remote (IR) receiver/transmitter drivers"
+	default n
+	help
+	  Say Y here, and all supported Infrared Remote Control IR
+	  receiver and transmitter drivers will be displayed. The receiver drivers
+	  allow control of your Linux system via remote control.
+
+if INPUT_IR
+
+endif
drivers/input/ir/Makefile new file +5 -0
new file mode 100644
index 0000000..08e6954
@@ -0,0 +1,5 @@
+# Makefile for the ir drivers.
+#
+
+# Each configuration option enables a list of files.
+
include/linux/input.h +101 -0

148 lines not on this page · raw message

include/linux/mod_devicetable.h +3 -0
index c4db582..cb088ec 100644
@@ -282,6 +282,7 @@ struct pcmcia_device_id {
 #define INPUT_DEVICE_ID_SND_MAX		0x07
 #define INPUT_DEVICE_ID_FF_MAX		0x7f
 #define INPUT_DEVICE_ID_SW_MAX		0x0f
+#define INPUT_DEVICE_ID_IR_MAX		0x0f
 
 #define INPUT_DEVICE_ID_MATCH_BUS	1
 #define INPUT_DEVICE_ID_MATCH_VENDOR	2
@@ -297,6 +298,7 @@ struct pcmcia_device_id {
 #define INPUT_DEVICE_ID_MATCH_SNDBIT	0x0400
 #define INPUT_DEVICE_ID_MATCH_FFBIT	0x0800
 #define INPUT_DEVICE_ID_MATCH_SWBIT	0x1000
+#define INPUT_DEVICE_ID_MATCH_IRBIT	0x2000
 
 struct input_device_id {
 
@@ -316,6 +318,7 @@ struct input_device_id {
 	kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1];
 	kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1];
 	kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1];
+	kernel_ulong_t irbit[INPUT_DEVICE_ID_IR_MAX / BITS_PER_LONG + 1];
 
 	kernel_ulong_t driver_info;
 };
#2 lore raw

Re: [RFC PATCH 1/4] Changes to core input subsystem to allow send and receive of IR messages. Encode and decode state machines are provided for common IR porotocols such as Sony, JVC, NEC, Philips, etc.

Quoted 2 lines · Jon Smirl

Received IR messages generate event in the input queue. IR messages are sent using an input IOCTL.

Another question.

So input device sends its events as a special event type? This would mean that none of current drivers will be able to pick these events.

I think that input device should have better configuration support, like generic way to set a keymap (raw->keycode) for a device, and the IR timing can be set too.
And send normal keypreses.

Regards,
Maxim Levitsky

author
#3 lore raw

Re: [RFC PATCH 1/4] Changes to core input subsystem to allow send and receive of IR messages. Encode and decode state machines are provided for common IR porotocols such as Sony, JVC, NEC, Philips, etc.

Quoted 9 lines · Maxim Levitsky
Quoted 2 lines · Jon Smirl

Received IR messages generate event in the input queue. IR messages are sent using an input IOCTL.

Another question.

So input device sends its events as a special event type? This would mean that none of current drivers will be able to pick these events.

There is a later version of this patch set that uses configfs to map IR events into keystrokes on the /dev/input device. I have later additions to the code that haven't been posted. They fix issues with calling configfs at interrupt time.

-------------------------------------------

I posted V4 of my in-kernel IR system to LKML. It supports mapping from IR events to key strokes now.
http://lkml.org/lkml/2008/11/5/233

To do the mapping it uses configfs (part of the kernel). The main directory is remotes. You use a shell script to build mappings between the IR event and key stroke.

mkdir /config/remotes/sony
-- this creates a new evdev device
mkdir remotes/sony/one
echo 7 >remotes/sony/one/procotol
echo 264 >remotes/sony/one/command
echo 2 >remotes/sony/one/keycode

This transforms a button push of 1 on my remote into a key stroke for KEY_1

 *   configfs root
 *   --remotes
 *   ----specific remote
 *   ------keymap
 *   --------protocol
 *   --------device
 *   --------command
 *   --------keycode
 *   ------repeat keymaps
 *   --------....
 *   ----another remote
 *   ------more keymaps

You can map the 1 button from multiple remote to KEY_1 if you want. Or you can use a single remote to create multiple virtual keyboards.

I'm always looking for help with this code. I've implemented support for my embedded GPIO based receiver and Microsoft MCEUSB. I'd really like to see IR added to existing Linux input family of keyboards, mice, joystick, tablet, touchscreen and gameport.

Quoted 11 lines

I think that input device should have better configuration support, like generic way to set a keymap (raw->keycode) for a device, and the IR timing can be set too.
And send normal keypreses.

Regards,
       Maxim Levitsky

Signature · 2 lines
Jon Smirl
[email protected]
author
#4 lore raw

RFC PATCH 2/4 GPT driver for in-kernel IR support.

In reply to Jon Smirl

GPT is a GPIO pin that is cable able of measuring the lenght of pulses. GPTs are common on embedded systems

---
 drivers/input/ir/Kconfig  |    6 +
 drivers/input/ir/Makefile |    1 
 drivers/input/ir/ir-gpt.c |  221 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 228 insertions(+), 0 deletions(-)
 create mode 100644 drivers/input/ir/ir-gpt.c
drivers/input/ir/Kconfig +6 -0
index 8afd2d6..b80ab31 100644
@@ -11,4 +11,10 @@ menuconfig INPUT_IR
 
 if INPUT_IR
 
+config IR_GPT
+	tristate "GPT Based IR Receiver"
+	default m
+	help
+	  Driver for GPT-based IR receiver found on Digispeaker
+
 endif
drivers/input/ir/Makefile +1 -0
index 08e6954..7082f1d 100644
@@ -3,3 +3,4 @@
 
 # Each configuration option enables a list of files.
 
+obj-$(CONFIG_IR_GPT)		+= ir-gpt.o
drivers/input/ir/ir-gpt.c new file +221 -0

221 lines not on this page · raw message

author
#5 lore raw

RFC PATCH 3/4 Example of PowerPC device tree support for GPT based IR

In reply to Jon Smirl
---
 arch/powerpc/boot/dts/dspeak01.dts |   19 ++++++++-----------
 1 files changed, 8 insertions(+), 11 deletions(-)
arch/powerpc/boot/dts/dspeak01.dts +8 -11
index 1d10f0a..cbb22a1 100644
@@ -131,16 +131,6 @@
 			#gpio-cells = <2>;
 		};
 
-		gpt7: timer@670 { /* General Purpose Timer in GPIO mode */
-			compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
-			cell-index = <7>;
-			reg = <0x670 0x10>;
-			interrupts = <0x1 0x10 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
-			gpio-controller;
-			#gpio-cells = <2>;
-		};
-
 		rtc@800 {	// Real time clock
 			compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
 			device_type = "rtc";
@@ -328,6 +318,14 @@
 			reg = <0x8000 0x4000>;
 		};
 
+		ir0: timer@670 { /* General Purpose Timer 6 in Input mode */
+			compatible = "gpt-ir";
+			cell-index = <7>;
+			reg = <0x670 0x10>;
+			interrupts = <0x1 0x10 0x0>;
+			interrupt-parent = <&mpc5200_pic>;
+		};
+
 		/* This is only an example device to show the usage of gpios. It maps all available
 		 * gpios to the "gpio-provider" device.
 		 */
@@ -345,7 +343,6 @@
 				 &gpt4		0 0 /* timer4		61c		x2-16	   */
 				 &gpt5		0 0 /* timer5		44c		x7-11	   */
 				 &gpt6		0 0 /* timer6		60c		x8-15	   */
-				 &gpt7		0 0 /* timer7		36a		x17-9	   */
 				 >;
 		};
 	};
author
#6 lore raw

RFC PATCH 4/4 Microsoft mceusb2 driver for in-kernel IR subsystem

In reply to Jon Smirl

USB device commonly found on Microsoft Media Center boxes.

Hardware can send and recieve at all common IR frequencies - 36K, 38K, 40K, 56K

---
 drivers/input/ir/Kconfig      |    6 
 drivers/input/ir/Makefile     |    1 
 drivers/input/ir/ir-mceusb2.c |  741 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 748 insertions(+), 0 deletions(-)
 create mode 100644 drivers/input/ir/ir-mceusb2.c
drivers/input/ir/Kconfig +6 -0
index b80ab31..29657d0 100644
@@ -16,5 +16,11 @@ config IR_GPT
 	default m
 	help
 	  Driver for GPT-based IR receiver found on Digispeaker
+	  
+config IR_MCEUSB2
+	tristate "Microsoft Media Center Ed. Receiver, v2"
+	default m
+	help
+	  Driver for the Microsoft Media Center Ed. Receiver, v2
 
 endif
drivers/input/ir/Makefile +1 -0
index 7082f1d..780de6c 100644
@@ -4,3 +4,4 @@
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_IR_GPT)		+= ir-gpt.o
+obj-$(CONFIG_IR_MCEUSB2)		+= ir-mceusb2.o
drivers/input/ir/ir-mceusb2.c new file +741 -0

741 lines not on this page · raw message

author
#7 lore raw
In reply to Jon Smirl
Quoted 1 line · Jon Smirl

Third pass at implementing evdev support for IR. The goal of in-kernel IR is to integrate IR events into the evdev input event queue and maintain ordering of events from all input devices.

Mail to LIRC list still bounces because it is slightly too big - over the 20K limit.

Messages are here:
http://lkml.org/lkml/2008/10/6/202

Signature · 2 lines
Jon Smirl
[email protected]
#8 lore raw
In reply to Jon Smirl

Hi!

Quoted 5 lines

What should the IR API look like? How are IR events mapped into
keyboard events? Should they be mapped? Map them in the kernel or in user space? The maps are tiny, less than 1K per remote. Sysfs can be used to load maps into the kernel driver. Make maps only for the common buttons and don't map unusual ones?

Map them in kernel, in analogy with normal keyboards.

Quoted 3 lines

How should multiple remotes be handled? Split them out into individual input devices, or group them onto a single IR device? I can implement either.

Individual input devices, I'd say... so that app can only listen for 'its' remote.

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#9 lore raw
Quoted 9 lines · Pavel Machek

Hi!

Quoted 5 lines

What should the IR API look like? How are IR events mapped into
keyboard events? Should they be mapped? Map them in the kernel or in user space? The maps are tiny, less than 1K per remote. Sysfs can be used to load maps into the kernel driver. Make maps only for the common buttons and don't map unusual ones?

Map them in kernel, in analogy with normal keyboards.

My thought was to basically follow what the ati_remote{,2} driver does.

Quoted 6 lines
Quoted 3 lines

How should multiple remotes be handled? Split them out into individual input devices, or group them onto a single IR device? I can implement either.

Individual input devices, I'd say... so that app can only listen for 'its' remote.

I don't quite get it. How can we tell there are multiple remotes to set up multiple input devices when the system comes up? All we can know about at driver init time is the receiver(s), no? Or would this be keyed off a config file? Or ______ ?

Signature · 2 lines
Jarod Wilson
[email protected]
author
#10 lore raw
Quoted 17 lines · Jarod Wilson
Quoted 9 lines · Pavel Machek

Hi!

Quoted 5 lines

What should the IR API look like? How are IR events mapped into
keyboard events? Should they be mapped? Map them in the kernel or in user space? The maps are tiny, less than 1K per remote. Sysfs can be used to load maps into the kernel driver. Make maps only for the common buttons and don't map unusual ones?

Map them in kernel, in analogy with normal keyboards.

My thought was to basically follow what the ati_remote{,2} driver does.

Quoted 4 lines
Quoted 3 lines

How should multiple remotes be handled? Split them out into individual input devices, or group them onto a single IR device? I can implement either.

Quoted 7 lines
Quoted 2 lines

Individual input devices, I'd say... so that app can only listen for 'its' remote.

I don't quite get it. How can we tell there are multiple remotes to set up multiple input devices when the system comes up? All we can know about at driver init time is the receiver(s), no? Or would this be keyed off a config file? Or ______ ?

We could create a sysfs attribut named ir_config. For each config file you copy to it it creates a new input device. The config files have lists of map this protocol, device, command tuple to this key. When a remote button is pressed the raw codes are fed to the in-kernel protocol engine. That engine turns the raw codes into tuples. Tuples are matched against the configs that have been loaded until a hit is found. If no hit they get sent out the catch-all device.

Most remotes send out unique codes, they have to or they would turn on unintended devices.

Quoted 7 lines

--
Jarod Wilson
[email protected]

Signature · 2 lines
Jon Smirl
[email protected]
#11 lore raw
Quoted 2 lines · Jon Smirl
Quoted 1 line · Jarod Wilson

On Thu, 2008-10-09 at 14:03 +0200, Pavel Machek wrote:

[...]

Quoted 13 lines
Quoted 11 lines
Quoted 6 lines
Quoted 3 lines

How should multiple remotes be handled? Split them out into individual input devices, or group them onto a single IR device? I can implement either.

Individual input devices, I'd say... so that app can only listen for 'its' remote.

I don't quite get it. How can we tell there are multiple remotes to set up multiple input devices when the system comes up? All we can know about at driver init time is the receiver(s), no? Or would this be keyed off a config file? Or ______ ?

Quoted 7 lines

We could create a sysfs attribut named ir_config. For each config file you copy to it it creates a new input device. The config files have lists of map this protocol, device, command tuple to this key. When a remote button is pressed the raw codes are fed to the in-kernel protocol engine. That engine turns the raw codes into tuples. Tuples are matched against the configs that have been loaded until a hit is found. If no hit they get sent out the catch-all device.

Okay. I presume the catch-all device would simply note that it saw something, and not actually take any action beyond that.

Also, a minor clarification: If its config file based, then its not so much one input device per remote, its one input device per config file, so one could set up two separate config files that are actually commands from the same remote, but have them listened to by different apps, or one could group together commands from multiple remotes in a single config so that multiple remotes would all control the same thing. Sounds good to me, provides for a reasonable amount of flexibility.

Of course, this suggests a receiver wouldn't be able to do anything until the user provided a key mapping table of some sort. Would it make sense to provide a default IR-to-key mapping for each receiver type? A bit difficult to provide a sane default for something like a home-brew serial IR receiver, but you could certainly provide sane defaults for things like mceusb and imon (i.e., mappings for the remotes typically bundled with those receivers).

Quoted 2 lines

Most remotes send out unique codes, they have to or they would turn on unintended devices.

Yep, that's actually where the root of my concern was. I have at least a half dozen different remote-controlled devices in my AV cabinet near my myth box, and I obviously don't want anything but the codes I've set up for my myth box acted upon on the myth box. :)

Signature · 2 lines
Jarod Wilson
[email protected]
author
#12 lore raw
Quoted 25 lines · Jarod Wilson
Quoted 2 lines · Jon Smirl
Quoted 1 line · Jarod Wilson

On Thu, 2008-10-09 at 14:03 +0200, Pavel Machek wrote:

[...]

Quoted 13 lines
Quoted 11 lines
Quoted 6 lines
Quoted 3 lines

How should multiple remotes be handled? Split them out into individual input devices, or group them onto a single IR device? I can implement either.

Individual input devices, I'd say... so that app can only listen for 'its' remote.

I don't quite get it. How can we tell there are multiple remotes to set up multiple input devices when the system comes up? All we can know about at driver init time is the receiver(s), no? Or would this be keyed off a config file? Or ______ ?

Quoted 7 lines

We could create a sysfs attribut named ir_config. For each config file you copy to it it creates a new input device. The config files have lists of map this protocol, device, command tuple to this key. When a remote button is pressed the raw codes are fed to the in-kernel protocol engine. That engine turns the raw codes into tuples. Tuples are matched against the configs that have been loaded until a hit is found. If no hit they get sent out the catch-all device.

Quoted 2 lines

Okay. I presume the catch-all device would simply note that it saw something, and not actually take any action beyond that.

The catch-all device is an device in /dev/input. It gets the input tuples in protocol/device/command form sent to it. I should probably send all IR input to this device, and flag the events that were translated and sent to another input device.

Quoted 8 lines

Also, a minor clarification: If its config file based, then its not so much one input device per remote, its one input device per config file, so one could set up two separate config files that are actually commands from the same remote, but have them listened to by different apps, or one could group together commands from multiple remotes in a single config so that multiple remotes would all control the same thing. Sounds good to me, provides for a reasonable amount of flexibility.

That is how it works.

Quoted 7 lines

Of course, this suggests a receiver wouldn't be able to do anything until the user provided a key mapping table of some sort. Would it make sense to provide a default IR-to-key mapping for each receiver type? A bit difficult to provide a sane default for something like a home-brew serial IR receiver, but you could certainly provide sane defaults for things like mceusb and imon (i.e., mappings for the remotes typically bundled with those receivers).

Receivers can process the raw tuples using the catch-all device.

You could write a little app like udev that listens to the catch-all device and then search the config files for untranslated tuples. When you match on an untranslated tuple, load that config file into the kernel.

I'm taking the kids on their first trip to Disneyworld next week so I won't be able to work on this for a while.

Quoted 15 lines
Quoted 3 lines

Most remotes send out unique codes, they have to or they would turn on unintended devices.

Yep, that's actually where the root of my concern was. I have at least a half dozen different remote-controlled devices in my AV cabinet near my myth box, and I obviously don't want anything but the codes I've set up for my myth box acted upon on the myth box. :)

--
Jarod Wilson
[email protected]

Signature · 2 lines
Jon Smirl
[email protected]
#13 lore raw
Quoted 26 lines · Jon Smirl
Quoted 25 lines · Jarod Wilson
Quoted 2 lines · Jon Smirl
Quoted 1 line · Jarod Wilson

On Thu, 2008-10-09 at 14:03 +0200, Pavel Machek wrote:

[...]

Quoted 20 lines
Quoted 11 lines
Quoted 6 lines
Quoted 3 lines

How should multiple remotes be handled? Split them out into individual input devices, or group them onto a single IR device? I can implement either.

Individual input devices, I'd say... so that app can only listen for 'its' remote.

I don't quite get it. How can we tell there are multiple remotes to set up multiple input devices when the system comes up? All we can know about at driver init time is the receiver(s), no? Or would this be keyed off a config file? Or ______ ?

We could create a sysfs attribut named ir_config. For each config file you copy to it it creates a new input device. The config files have lists of map this protocol, device, command tuple to this key. When a remote button is pressed the raw codes are fed to the in-kernel protocol engine. That engine turns the raw codes into tuples. Tuples are matched against the configs that have been loaded until a hit is found. If no hit they get sent out the catch-all device.

Quoted 7 lines
Quoted 2 lines

Okay. I presume the catch-all device would simply note that it saw something, and not actually take any action beyond that.

The catch-all device is an device in /dev/input. It gets the input tuples in protocol/device/command form sent to it. I should probably send all IR input to this device, and flag the events that were translated and sent to another input device.

Sounds sane.

Quoted 9 lines
Quoted 7 lines

Also, a minor clarification: If its config file based, then its not so much one input device per remote, its one input device per config file, so one could set up two separate config files that are actually commands from the same remote, but have them listened to by different apps, or one could group together commands from multiple remotes in a single config so that multiple remotes would all control the same thing. Sounds good to me, provides for a reasonable amount of flexibility.

That is how it works.

Cool. Still getting this all straight in my head... :)

Quoted 8 lines
Quoted 7 lines

Of course, this suggests a receiver wouldn't be able to do anything until the user provided a key mapping table of some sort. Would it make sense to provide a default IR-to-key mapping for each receiver type? A bit difficult to provide a sane default for something like a home-brew serial IR receiver, but you could certainly provide sane defaults for things like mceusb and imon (i.e., mappings for the remotes typically bundled with those receivers).

Quoted 6 lines

Receivers can process the raw tuples using the catch-all device.

You could write a little app like udev that listens to the catch-all device and then search the config files for untranslated tuples. When you match on an untranslated tuple, load that config file into the kernel.

That's just the sort of thing I *don't* want though -- I can imagine my receiver picking up all the signals intended for my other AV devices and loading up a bunch of configs, thinking it should do something with these signals. Seems you'd want a training/pairing mode you could put the driver in to set this stuff up.

Quoted 2 lines

I'm taking the kids on their first trip to Disneyworld next week so I won't be able to work on this for a while.

Have fun! In the mean time, I've got a bit of porting to try out still, as well as some remaining review clean-ups...

Signature · 2 lines
Jarod Wilson
[email protected]
#14 lore raw
In reply to Jon Smirl
Quoted 17 lines · Jon Smirl

Third pass at implementing evdev support for IR. The goal of in-kernel IR is to integrate IR events into the evdev input event queue and maintain ordering of events from all input devices.

New feature, raw mode. There are three sysfs attributes - ir_raw, ir_carrier, ir_xmitter. Read from ir_raw to get the raw timing data from the IR device. Set carrier and active xmitters and then copy raw data to ir_raw to send. These attributes may be better on a debug switch. You would use raw mode when decoding a new protocol. After you figure out the new protocol, write an in-kernel encoder/decoder for it.

What should the IR API look like?

How are IR events mapped into keyboard events? Should they be mapped? Map them in the kernel or in user space? The maps are tiny, less than 1K per remote. Sysfs can be used to load maps into the kernel driver. Make maps only for the common buttons and don't map unusual ones?

How should multiple remotes be handled? Split them out into individual input devices, or group them onto a single IR device? I can implement either.

The in-kernel code is tiny, about 20K including a driver.

Quoted 1 line

From last post...

Note that user space IR device drivers can use the existing support in evdev to inject events into the input queue.

Send and receive are implemented. Received IR messages are decoded and sent to user space as input messages. Send is done via an IOCTL on the input device.

Quoted 7 lines

Two drivers are supplied. mceusb2 implements send and receive support for the Microsoft USB IR dongle.

The GPT driver implements receive only support for a GPT pin - GPT is a GPIO with a timer attached.

Code is only lightly tested. Encoders and decoders have not been written for all protocols. Repeat is not handled for any protocol.
I'm looking for help. There are 15 more existing LIRC drivers.

Any update on that?

I have a suggestion:

Instead of decoding protocols in kernel, why not to allow userspace to upload timing signatures as specified in lirc.conf ?

As a example, what protocol this is:

http://lirc.sourceforge.net/remotes/toshiba/CT-9922

Best regards,
Maxim Levitsky

#15 lore raw
Quoted 31 lines · Maxim Levitsky
Quoted 17 lines · Jon Smirl

Third pass at implementing evdev support for IR. The goal of in-kernel IR is to integrate IR events into the evdev input event queue and maintain ordering of events from all input devices.

New feature, raw mode. There are three sysfs attributes - ir_raw, ir_carrier, ir_xmitter. Read from ir_raw to get the raw timing data from the IR device. Set carrier and active xmitters and then copy raw data to ir_raw to send. These attributes may be better on a debug switch. You would use raw mode when decoding a new protocol. After you figure out the new protocol, write an in-kernel encoder/decoder for it.

What should the IR API look like?

How are IR events mapped into keyboard events? Should they be mapped? Map them in the kernel or in user space? The maps are tiny, less than 1K per remote. Sysfs can be used to load maps into the kernel driver. Make maps only for the common buttons and don't map unusual ones?

How should multiple remotes be handled? Split them out into individual input devices, or group them onto a single IR device? I can implement either.

The in-kernel code is tiny, about 20K including a driver.

Quoted 1 line

From last post...

Note that user space IR device drivers can use the existing support in evdev to inject events into the input queue.

Send and receive are implemented. Received IR messages are decoded and sent to user space as input messages. Send is done via an IOCTL on the input device.

Quoted 7 lines

Two drivers are supplied. mceusb2 implements send and receive support for the Microsoft USB IR dongle.

The GPT driver implements receive only support for a GPT pin - GPT is a GPIO with a timer attached.

Code is only lightly tested. Encoders and decoders have not been written for all protocols. Repeat is not handled for any protocol.
I'm looking for help. There are 15 more existing LIRC drivers.

Any update on that?

I have a suggestion:

Quoted 6 lines

Instead of decoding protocols in kernel, why not to allow userspace to upload timing signatures as specified in lirc.conf ?

As a example, what protocol this is:

http://lirc.sourceforge.net/remotes/toshiba/CT-9922

Replying to myself... this is NEC protocol, and this config file isn't correct (since it was auto generated)

Quoted 4 lines

Best regards,
Maxim Levitsky