diff mbox

IR: allow disabling NEC checksum check, enable apple remote

Message ID 20101112223859.GA8205@redhat.com (mailing list archive)
State RFC
Headers show

Commit Message

Jarod Wilson Nov. 12, 2010, 10:38 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 8ff157a..abe9b4d 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -28,6 +28,16 @@ 
 #define	NEC_TRAILER_SPACE	(10 * NEC_UNIT) /* even longer in reality */
 #define NECX_REPEAT_BITS	1
 
+static bool csum = true;
+module_param(csum, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(csum, "Whether or not to perform NEC chucksum checks "
+		 "(default: true)");
+
+static bool pair;
+module_param(pair, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(pair, "Whether or not the Apple Pairing ID byte should "
+		 "be evaluated for scancode lookups (default: false)");
+
 enum nec_state {
 	STATE_INACTIVE,
 	STATE_HEADER_SPACE,
@@ -49,6 +59,7 @@  static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
 	struct nec_dec *data = &dev->raw->nec;
 	u32 scancode;
 	u8 address, not_address, command, not_command;
+	bool checksum = csum;
 
 	if (!(dev->raw->enabled_protocols & IR_TYPE_NEC))
 		return 0;
@@ -157,22 +168,37 @@  static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
 		command	    = bitrev8((data->bits >>  8) & 0xff);
 		not_command = bitrev8((data->bits >>  0) & 0xff);
 
-		if ((command ^ not_command) != 0xff) {
+		if ((address == 0xee) && (not_address == 0x87)) {
+			IR_dprintk(1, "Apple remote detected, pair ID 0x%02x\n",
+				   not_command);
+			checksum = false;
+			/* We have a default non-paired keymap using 0x00 */
+			if (!pair)
+				not_command = 0x00;
+		}
+
+		if (checksum && ((command ^ not_command) != 0xff)) {
 			IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
 				   data->bits);
 			break;
 		}
 
-		if ((address ^ not_address) != 0xff) {
-			/* Extended NEC */
+		if (checksum && ((address ^ not_address) == 0xff)) {
+			/* Normal NEC */
+			scancode = address << 8 | command;
+			IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
+		} else if (!checksum) {
+			/* Extended NEC, no checksum */
+			scancode = address << 24 | not_address << 16 |
+				   command <<  8 | not_command;
+			IR_dprintk(1, "NEC (Ext, no csum) scancode 0x%08x\n",
+				   scancode);
+		} else {
+			/* Extended NEC, standard */
 			scancode = address     << 16 |
 				   not_address <<  8 |
 				   command;
 			IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode);
-		} else {
-			/* Normal NEC */
-			scancode = address << 8 | command;
-			IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
 		}
 
 		if (data->is_nec_x)
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 3194d39..8fa0e53 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -53,6 +53,7 @@  obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
 			rc-msi-tvanywhere.o \
 			rc-msi-tvanywhere-plus.o \
 			rc-nebula.o \
+			rc-nec-apple.o \
 			rc-nec-terratec-cinergy-xs.o \
 			rc-norwood.o \
 			rc-npgtech.o \
diff --git a/drivers/media/rc/keymaps/rc-nec-apple.c b/drivers/media/rc/keymaps/rc-nec-apple.c
new file mode 100644
index 0000000..7450280
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-nec-apple.c
@@ -0,0 +1,51 @@ 
+/* rc-nec-apple.c - Keytable for Apple Remote Controls
+ *
+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+
+static struct ir_scancode nec_apple[] = {
+	{ 0xee870002, KEY_MENU},
+	{ 0xee870003, KEY_MENU},
+	{ 0xee870004, KEY_PLAYPAUSE},
+	{ 0xee870005, KEY_PLAYPAUSE},
+	{ 0xee870006, KEY_FORWARD},
+	{ 0xee870007, KEY_FORWARD},
+	{ 0xee870008, KEY_BACK},
+	{ 0xee870009, KEY_BACK},
+	{ 0xee87000a, KEY_VOLUMEUP},
+	{ 0xee87000b, KEY_VOLUMEUP},
+	{ 0xee87000c, KEY_VOLUMEDOWN},
+	{ 0xee87000d, KEY_VOLUMEDOWN},
+};
+
+static struct rc_keymap nec_apple_map = {
+	.map = {
+		.scan    = nec_apple,
+		.size    = ARRAY_SIZE(nec_apple),
+		.ir_type = IR_TYPE_NEC,
+		.name    = RC_MAP_NEC_APPLE,
+	}
+};
+
+static int __init init_rc_map_nec_apple(void)
+{
+	return ir_register_map(&nec_apple_map);
+}
+
+static void __exit exit_rc_map_nec_apple(void)
+{
+	ir_unregister_map(&nec_apple_map);
+}
+
+module_init(init_rc_map_nec_apple)
+module_exit(exit_rc_map_nec_apple)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index e0f17ed..2cdc523 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -110,6 +110,7 @@  void rc_map_init(void);
 #define RC_MAP_MSI_TVANYWHERE_PLUS       "rc-msi-tvanywhere-plus"
 #define RC_MAP_MSI_TVANYWHERE            "rc-msi-tvanywhere"
 #define RC_MAP_NEBULA                    "rc-nebula"
+#define RC_MAP_NEC_APPLE                 "rc-nec-apple"
 #define RC_MAP_NEC_TERRATEC_CINERGY_XS   "rc-nec-terratec-cinergy-xs"
 #define RC_MAP_NORWOOD                   "rc-norwood"
 #define RC_MAP_NPGTECH                   "rc-npgtech"