IR: allow disabling NEC checksum check, enable apple remote
Subsystems (2)
PATCH 1/1 IR: allow disabling NEC checksum check, enable apple remote
In strict NEC extended IR protocol, a 32-bit signal consists of address, not address, command and not command, and checksums are performed between these two pairs of components. Currently, our NEC protocol decoder strictly enforces these checks, and only uses 24 bits (address, not address and command) to do scancode to keycode lookups. However, there are remotes out there using a variant of the NEC protocol, which assigns different meaning to some of these bits, without using any checksums.
The test case here is Apple's remotes, which send a two-byte vendor code instead of address/not address, a pairing ID byte, and a command byte instead of command/not command.
For further details on the Apple remotes, see:
http://en.wikipedia.org/wiki/Apple_Remote
If we make it possible to bypass the checksum checks and use the full 32 bits for scancode lookups, the current NEC decoder can successfully successfully decode and match keys from these remotes, as well as any others that might employ similar alternate bit meanings.
In the Apple case, we can simply match the vendor code and auto-skip the checksum checks. For other remotes, we can bypass the checksum by handing a modparam to the NEC decoder, unless of course we figure out some other means by which to determine if its a signal for which we should skip checksumming, and/or develop something cleaner, and/or decide to only warn (in debug mode) when checksum checks fail.
An Apple keytable using the full 32 bits is included. Existing NEC extended remotes should continue to fuction with their current 24-bit tables, but we *could* decide in the future to simplify things and just use the full 32 bits for all NEC extended (ish) remotes.
--- drivers/media/rc/ir-nec-decoder.c | 40 ++++++++++++++++++++---- drivers/media/rc/keymaps/Makefile | 1 + drivers/media/rc/keymaps/rc-nec-apple.c | 51 +++++++++++++++++++++++++++++++ include/media/rc-map.h | 1 + 4 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 drivers/media/rc/keymaps/rc-nec-apple.c
drivers/media/rc/ir-nec-decoder.c +33 -7
@@ -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)
drivers/media/rc/keymaps/Makefile +1 -0
@@ -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 \
drivers/media/rc/keymaps/rc-nec-apple.c new file +51 -0
51 lines not on this page · raw message
include/media/rc-map.h +1 -0
@@ -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"
Signature · 6 lines
1.7.1 -- Jarod Wilson [email protected]