]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/media/rc/ir-mce_kbd-decoder.c
[media] mce_kbd: add encoder
[karo-tx-linux.git] / drivers / media / rc / ir-mce_kbd-decoder.c
index 5226d510e84779f0dcf0cb47372fd0ddd6cee058..6a4d58b88d91ecf8cb95bbf54fc7a04de28b6ccf 100644 (file)
@@ -23,7 +23,7 @@
  * - MCIR-2 29-bit IR signals used for mouse movement and buttons
  * - MCIR-2 32-bit IR signals used for standard keyboard keys
  *
- * The media keys on the keyboard send RC-6 signals that are inditinguishable
+ * The media keys on the keyboard send RC-6 signals that are indistinguishable
  * from the keys of the same name on the stock MCE remote, and will be handled
  * by the standard RC-6 decoder, and be made available to the system via the
  * input device for the remote, rather than the keyboard/mouse one.
@@ -339,6 +339,7 @@ again:
                }
 
                data->state = STATE_INACTIVE;
+               input_event(data->idev, EV_MSC, MSC_SCAN, scancode);
                input_sync(data->idev);
                return 0;
        }
@@ -418,9 +419,53 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev)
        return 0;
 }
 
+static const struct ir_raw_timings_manchester ir_mce_kbd_timings = {
+       .leader         = MCIR2_PREFIX_PULSE,
+       .invert         = 1,
+       .clock          = MCIR2_UNIT,
+       .trailer_space  = MCIR2_UNIT * 10,
+};
+
+/**
+ * ir_mce_kbd_encode() - Encode a scancode as a stream of raw events
+ *
+ * @protocol:   protocol to encode
+ * @scancode:   scancode to encode
+ * @events:     array of raw ir events to write into
+ * @max:        maximum size of @events
+ *
+ * Returns:     The number of events written.
+ *              -ENOBUFS if there isn't enough space in the array to fit the
+ *              encoding. In this case all @max events will have been written.
+ */
+static int ir_mce_kbd_encode(enum rc_type protocol, u32 scancode,
+                            struct ir_raw_event *events, unsigned int max)
+{
+       struct ir_raw_event *e = events;
+       int len, ret;
+       u64 raw;
+
+       if (protocol == RC_TYPE_MCIR2_KBD) {
+               raw = scancode |
+                     ((u64)MCIR2_KEYBOARD_HEADER << MCIR2_KEYBOARD_NBITS);
+               len = MCIR2_KEYBOARD_NBITS + MCIR2_HEADER_NBITS + 1;
+       } else {
+               raw = scancode |
+                     ((u64)MCIR2_MOUSE_HEADER << MCIR2_MOUSE_NBITS);
+               len = MCIR2_MOUSE_NBITS + MCIR2_HEADER_NBITS + 1;
+       }
+
+       ret = ir_raw_gen_manchester(&e, max, &ir_mce_kbd_timings, len, raw);
+       if (ret < 0)
+               return ret;
+
+       return e - events;
+}
+
 static struct ir_raw_handler mce_kbd_handler = {
-       .protocols      = RC_BIT_MCE_KBD,
+       .protocols      = RC_BIT_MCIR2_KBD | RC_BIT_MCIR2_MSE,
        .decode         = ir_mce_kbd_decode,
+       .encode         = ir_mce_kbd_encode,
        .raw_register   = ir_mce_kbd_register,
        .raw_unregister = ir_mce_kbd_unregister,
 };