media: rc: add new imon protocol decoder and encoder
Sean Young
maintainerPATCH 1/2 media: rc: add new imon protocol decoder and encoder
This makes it possible to use the various iMON remotes with any raw IR RC device.
Signed-off-by Sean Young <[email protected]>
--- drivers/media/rc/Kconfig | 9 ++ drivers/media/rc/Makefile | 1 + drivers/media/rc/ir-imon-codec.c | 192 +++++++++++++++++++++++++++++++++ drivers/media/rc/keymaps/rc-imon-pad.c | 2 +- drivers/media/rc/rc-core-priv.h | 6 ++ drivers/media/rc/rc-main.c | 8 ++ include/media/rc-map.h | 8 +- include/uapi/linux/lirc.h | 2 + 8 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 drivers/media/rc/ir-imon-codec.c
drivers/media/rc/Kconfig +9 -0
@@ -111,6 +111,15 @@ config IR_XMP_DECODER ---help--- Enable this option if you have IR with XMP protocol, and if the IR is decoded in software + +config IR_IMON_CODEC + tristate "Enable IR raw codec for the iMON protocol" + depends on RC_CORE + ---help--- + Enable this option if you have IR with iMON PAD protocol, and + would like to use it with a raw IR receiver, or if you wish + to use an encoder to transmit this IR. + endif #RC_DECODERS menuconfig RC_DEVICES
drivers/media/rc/Makefile +1 -0
@@ -14,6 +14,7 @@ obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o +obj-$(CONFIG_IR_IMON_CODEC) += ir-imon-codec.o # stand-alone IR receivers/transmitters obj-$(CONFIG_RC_ATI_REMOTE) += ati_remote.o
drivers/media/rc/ir-imon-codec.c new file +192 -0
192 lines not on this page · raw message
drivers/media/rc/keymaps/rc-imon-pad.c +1 -1
@@ -135,7 +135,7 @@ static struct rc_map_list imon_pad_map = { .scan = imon_pad, .size = ARRAY_SIZE(imon_pad), /* actual protocol details unknown, hardware decoder */ - .rc_proto = RC_PROTO_OTHER, + .rc_proto = RC_PROTO_IMON, .name = RC_MAP_IMON_PAD, } };
drivers/media/rc/rc-core-priv.h +6 -0
@@ -118,6 +118,12 @@ struct ir_raw_event_ctrl {unsigned count;u32 durations[16 ]; } xmp; +struct imon_dec { +int state; +int count; +int last_chk; +unsigned int bits; + } imon; };/* macros for IR decoders */
drivers/media/rc/rc-main.c +8 -0
@@ -68,6 +68,7 @@ static const struct { .scancode_bits = 0x1fff, .repeat_period = 250 }, [RC_PROTO_XMP] = { .name = "xmp", .repeat_period = 250 }, [RC_PROTO_CEC] = { .name = "cec", .repeat_period = 550 }, + [RC_PROTO_IMON] = { .name = "imon", .repeat_period = 250 }, };/* Used to keep track of known keymaps */
@@ -869,6 +870,12 @@ bool rc_validate_scancode(enum rc_proto proto, u32 scancode)if ((scancode &0xffff0000 ) ==0x800f0000 )return false;break ; +/* +* iMon hardware decoder always sets some bits, so assume the same +*/ +case RC_PROTO_IMON : +if ((scancode &0x800000001 ) !=1 ) +return false;default :break ; }
@@ -1004,6 +1011,7 @@ static const struct { RC_PROTO_BIT_MCIR2_MSE, "mce_kbd", "ir-mce_kbd-decoder" }, { RC_PROTO_BIT_XMP, "xmp", "ir-xmp-decoder" }, { RC_PROTO_BIT_CEC, "cec", NULL }, + { RC_PROTO_BIT_IMON, "imon", "ir-imon-codec" }, }; /**
include/media/rc-map.h +5 -3
@@ -36,6 +36,7 @@#define RC_PROTO_BIT_SHARP BIT_ULL(RC_PROTO_SHARP)#define RC_PROTO_BIT_XMP BIT_ULL(RC_PROTO_XMP)#define RC_PROTO_BIT_CEC BIT_ULL(RC_PROTO_CEC) +#define RC_PROTO_BIT_IMON BIT_ULL(RC_PROTO_IMON)#define RC_PROTO_BIT_ALL \ (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \
@@ -49,7 +50,8 @@ RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ - RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC) + RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC | \ + RC_PROTO_BIT_IMON)/* All rc protocols for which we have decoders */ #define RC_PROTO_BIT_ALL_IR_DECODER \ (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \
@@ -62,7 +64,7 @@ RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ - RC_PROTO_BIT_XMP) + RC_PROTO_BIT_XMP | RC_PROTO_BIT_IMON)#define RC_PROTO_BIT_ALL_IR_ENCODER \ (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \
@@ -75,7 +77,7 @@ RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ RC_PROTO_BIT_RC6_6A_24 | \ RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | \ - RC_PROTO_BIT_SHARP) + RC_PROTO_BIT_SHARP | RC_PROTO_BIT_IMON)#define RC_SCANCODE_UNKNOWN (x) (x)#define RC_SCANCODE_OTHER (x) (x)
include/uapi/linux/lirc.h +2 -0
@@ -186,6 +186,7 @@ struct lirc_scancode {* @RC_PROTO_SHARP: Sharp protocol * @RC_PROTO_XMP: XMP protocol * @RC_PROTO_CEC: CEC protocol +* @RC_PROTO_IMON: iMon Pad protocol */ enum rc_proto {RC_PROTO_UNKNOWN =0 ,
@@ -211,6 +212,7 @@ enum rc_proto {RC_PROTO_SHARP =20 ,RC_PROTO_XMP =21 ,RC_PROTO_CEC =22 , + RC_PROTO_IMON = 23, };#endif
Signature · 1 line
2.14.3
Sean Young
maintainerPATCH 2/2 media: imon: rename protocol from other to imon
This renames the protocol for the imon rc driver from other to imon, since it is now an known protocol. Although different name will show up in the sysfs protocol file, loading a keymap using existing ir-keytable versions still works.
Signed-off-by Sean Young <[email protected]>
--- drivers/media/rc/imon.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-)
drivers/media/rc/imon.c +23 -14
@@ -1110,18 +1110,18 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto)dev_dbg (dev,"Configuring IR receiver for MCE protocol\n" ); ir_proto_packet[0 ] =0x01 ; *rc_proto =RC_PROTO_BIT_RC6_MCE ; - }else if (*rc_proto &RC_PROTO_BIT_OTHER ) { + }else if (*rc_proto &RC_PROTO_BIT_IMON ) {dev_dbg (dev,"Configuring IR receiver for iMON protocol\n" );if (!pad_stabilize)dev_dbg (dev,"PAD stabilize functionality disabled\n" );/* ir_proto_packet[0] = 0x00; // already the default */ - *rc_proto =RC_PROTO_BIT_OTHER ; + *rc_proto =RC_PROTO_BIT_IMON ; }else {dev_warn (dev,"Unsupported IR protocol specified, overriding to iMON IR protocol\n" );if (!pad_stabilize)dev_dbg (dev,"PAD stabilize functionality disabled\n" );/* ir_proto_packet[0] = 0x00; // already the default */ - *rc_proto =RC_PROTO_BIT_OTHER ; + *rc_proto =RC_PROTO_BIT_IMON ; }memcpy (ictx->usb_tx_buf, &ir_proto_packet,sizeof (ir_proto_packet));
@@ -1388,7 +1388,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) rel_x = buf[2 ]; rel_y = buf[3 ]; -if (ictx->rc_proto ==RC_PROTO_BIT_OTHER && pad_stabilize) { +if (ictx->rc_proto ==RC_PROTO_BIT_IMON && pad_stabilize) {if ((buf[1 ] ==0 ) && ((rel_x !=0 ) || (rel_y !=0 ))) { dir =stabilize ((int )rel_x, (int )rel_y, timeout, threshold);
@@ -1455,7 +1455,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) buf[0 ] =0x01 ; buf[1 ] = buf[4 ] = buf[5 ] = buf[6 ] = buf[7 ] =0 ; -if (ictx->rc_proto ==RC_PROTO_BIT_OTHER && pad_stabilize) { +if (ictx->rc_proto ==RC_PROTO_BIT_IMON && pad_stabilize) { dir =stabilize ((int )rel_x, (int )rel_y, timeout, threshold);if (!dir) {
@@ -1639,11 +1639,18 @@ static void imon_incoming_packet(struct imon_context *ictx,if (press_type ==0 )rc_keyup (ictx->rdev);else { -if (ictx->rc_proto ==RC_PROTO_BIT_RC6_MCE || - ictx->rc_proto ==RC_PROTO_BIT_OTHER ) -rc_keydown (ictx->rdev, - ictx->rc_proto ==RC_PROTO_BIT_RC6_MCE ?RC_PROTO_RC6_MCE :RC_PROTO_OTHER , - ictx->rc_scancode, ictx->rc_toggle); +enum rc_proto proto; + +if (ictx->rc_proto ==RC_PROTO_BIT_RC6_MCE ) + proto =RC_PROTO_RC6_MCE ; +else if (ictx->rc_proto ==RC_PROTO_BIT_IMON ) + proto =RC_PROTO_IMON ; +else +return ; + +rc_keydown (ictx->rdev, proto, ictx->rc_scancode, + ictx->rc_toggle); +spin_lock_irqsave (&ictx->kc_lock, flags); ictx->last_keycode = ictx->kc;spin_unlock_irqrestore (&ictx->kc_lock, flags);
@@ -1800,7 +1807,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx) {u8 ffdc_cfg_byte = ictx->usb_rx_buf[6 ];u8 detected_display_type =IMON_DISPLAY_TYPE_NONE ; -u64 allowed_protos =RC_PROTO_BIT_OTHER ; +u64 allowed_protos =RC_PROTO_BIT_IMON ;switch (ffdc_cfg_byte) {/* iMON Knob, no display, iMON IR + vol knob */
@@ -1848,8 +1855,10 @@ static void imon_get_ffdc_type(struct imon_context *ictx)default :dev_info (ictx->dev,"Unknown 0xffdc device, defaulting to VFD and iMON IR" ); detected_display_type =IMON_DISPLAY_TYPE_VFD ; -/* We don't know which one it is, allow user to set the -* RC6 one from userspace if OTHER wasn't correct. */ +/* +* We don't know which one it is, allow user to set the +* RC6 one from userspace if IMON wasn't correct. +*/ allowed_protos |=RC_PROTO_BIT_RC6_MCE ;break ; }
@@ -1936,7 +1945,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) rdev->priv = ictx;/* iMON PAD or MCE */ - rdev->allowed_protocols =RC_PROTO_BIT_OTHER |RC_PROTO_BIT_RC6_MCE ; + rdev->allowed_protocols =RC_PROTO_BIT_IMON |RC_PROTO_BIT_RC6_MCE ; rdev->change_protocol = imon_ir_change_protocol; rdev->driver_name =MOD_NAME ;
Signature · 1 line
2.14.3