summaryrefslogtreecommitdiff
path: root/drivers/media/rc/rc-ir-raw.c
diff options
context:
space:
mode:
authorAntti Seppälä <a.seppala@gmail.com>2015-03-31 14:48:07 -0300
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2017-01-30 13:48:46 -0200
commit844a4f45f43b6d46b4dd87f61b3e2d2836c822b1 (patch)
tree7ee7968e86fb060937cbb7f380679de510fd1d5d /drivers/media/rc/rc-ir-raw.c
parent3875233d0b42c6d194657735d1a4b6a8797bfaaa (diff)
[media] rc: rc-ir-raw: Add Manchester encoder (phase encoder) helper
Adding a simple Manchester encoder to rc-core. Manchester coding is used by at least RC-5 and RC-6 protocols and their variants. Signed-off-by: Antti Seppälä <a.seppala@gmail.com> Signed-off-by: James Hogan <james@albanarts.com> Signed-off-by: Sean Young <sean@mess.org> Cc: David Härdeman <david@hardeman.nu> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/rc/rc-ir-raw.c')
-rw-r--r--drivers/media/rc/rc-ir-raw.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index d1c9cbb86615..85ac5070376c 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -239,6 +239,91 @@ static void ir_raw_disable_protocols(struct rc_dev *dev, u64 protocols)
}
/**
+ * ir_raw_gen_manchester() - Encode data with Manchester (bi-phase) modulation.
+ * @ev: Pointer to pointer to next free event. *@ev is incremented for
+ * each raw event filled.
+ * @max: Maximum number of raw events to fill.
+ * @timings: Manchester modulation timings.
+ * @n: Number of bits of data.
+ * @data: Data bits to encode.
+ *
+ * Encodes the @n least significant bits of @data using Manchester (bi-phase)
+ * modulation with the timing characteristics described by @timings, writing up
+ * to @max raw IR events using the *@ev pointer.
+ *
+ * Returns: 0 on success.
+ * -ENOBUFS if there isn't enough space in the array to fit the
+ * full encoded data. In this case all @max events will have been
+ * written.
+ */
+int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max,
+ const struct ir_raw_timings_manchester *timings,
+ unsigned int n, unsigned int data)
+{
+ bool need_pulse;
+ unsigned int i;
+ int ret = -ENOBUFS;
+
+ i = 1 << (n - 1);
+
+ if (timings->leader) {
+ if (!max--)
+ return ret;
+ if (timings->pulse_space_start) {
+ init_ir_raw_event_duration((*ev)++, 1, timings->leader);
+
+ if (!max--)
+ return ret;
+ init_ir_raw_event_duration((*ev), 0, timings->leader);
+ } else {
+ init_ir_raw_event_duration((*ev), 1, timings->leader);
+ }
+ i >>= 1;
+ } else {
+ /* continue existing signal */
+ --(*ev);
+ }
+ /* from here on *ev will point to the last event rather than the next */
+
+ while (n && i > 0) {
+ need_pulse = !(data & i);
+ if (timings->invert)
+ need_pulse = !need_pulse;
+ if (need_pulse == !!(*ev)->pulse) {
+ (*ev)->duration += timings->clock;
+ } else {
+ if (!max--)
+ goto nobufs;
+ init_ir_raw_event_duration(++(*ev), need_pulse,
+ timings->clock);
+ }
+
+ if (!max--)
+ goto nobufs;
+ init_ir_raw_event_duration(++(*ev), !need_pulse,
+ timings->clock);
+ i >>= 1;
+ }
+
+ if (timings->trailer_space) {
+ if (!(*ev)->pulse)
+ (*ev)->duration += timings->trailer_space;
+ else if (!max--)
+ goto nobufs;
+ else
+ init_ir_raw_event_duration(++(*ev), 0,
+ timings->trailer_space);
+ }
+
+ ret = 0;
+nobufs:
+ /* point to the next event rather than last event before returning */
+ ++(*ev);
+ return ret;
+}
+EXPORT_SYMBOL(ir_raw_gen_manchester);
+
+/**
* ir_raw_encode_scancode() - Encode a scancode as raw events
*
* @protocol: protocol