Adding a simple Manchester encoder to rc-core.
Manchester coding is used by at least RC-5 protocol and its variants.

Signed-off-by: Antti Seppälä <a.sepp...@gmail.com>
---
 drivers/media/rc/ir-raw.c       | 56 +++++++++++++++++++++++++++++++++++++++++
 drivers/media/rc/rc-core-priv.h | 16 ++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c
index 9d734dd..b9cc45d 100644
--- a/drivers/media/rc/ir-raw.c
+++ b/drivers/media/rc/ir-raw.c
@@ -240,6 +240,62 @@ ir_raw_get_allowed_protocols(void)
        return protocols;
 }
 
+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;
+       int i, count = 0;
+       i = 1 << (n - 1);
+
+       if (n > max || max < 3)
+               return -EINVAL;
+
+       if (timings->pulse_space_start) {
+               init_ir_raw_event_duration((*ev)++, 1, timings->clock);
+               init_ir_raw_event_duration((*ev), 0, timings->clock);
+               count += 2;
+       } else {
+               init_ir_raw_event_duration((*ev), 1, timings->clock);
+               count++;
+       }
+       i >>= 1;
+
+       while (i > 0) {
+               need_pulse = !(data & i);
+               if (need_pulse == !!(*ev)->pulse) {
+                       (*ev)->duration += timings->clock;
+               } else {
+                       init_ir_raw_event_duration(++(*ev), need_pulse,
+                                                  timings->clock);
+                       count++;
+               }
+
+               if (count >= max)
+                       return -EINVAL;
+
+               init_ir_raw_event_duration(++(*ev), !need_pulse,
+                                          timings->clock);
+               count++;
+               i >>= 1;
+       }
+
+       if (timings->trailer_space) {
+               if (!(*ev)->pulse) {
+                       (*ev)->duration += timings->trailer_space;
+               } else if (count < max) {
+                       init_ir_raw_event_duration(++(*ev), 0,
+                                                  timings->trailer_space);
+                       count++;
+               } else {
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(ir_raw_gen_manchester);
+
 int ir_raw_gen_pd(struct ir_raw_event **ev, unsigned int max,
                  const struct ir_raw_timings_pd *timings,
                  unsigned int n, unsigned int data)
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 3bf8c7b..df3ab46 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -173,6 +173,22 @@ static inline void ir_raw_gen_pulse_space(struct 
ir_raw_event **ev,
 }
 
 /**
+ * struct ir_raw_timings_manchester - manchester coding timings
+ * @pulse_space_start: 1 for starting with pulse (0 for starting with space)
+ * @clock:             duration of each pulse/space in ns
+ * @trailer_space:     duration of trailer space in ns
+ */
+struct ir_raw_timings_manchester {
+       unsigned int pulse_space_start:1;
+       unsigned int clock;
+       unsigned int trailer_space;
+};
+
+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);
+
+/**
  * struct ir_raw_timings_pd - pulse-distance modulation timings
  * @header_pulse:      duration of header pulse in ns (0 for none)
  * @header_space:      duration of header space in ns
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to