diff options
author | James Hogan <james@albanarts.com> | 2014-03-15 00:04:12 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2017-01-30 16:50:05 +0100 |
commit | caec098477d228d44ae2266ee78a37bed070441a (patch) | |
tree | 829045d0cd56c392845df98b650b30b0d751d2ca | |
parent | [media] rc: rc-ir-raw: Add Manchester encoder (phase encoder) helper (diff) | |
download | linux-caec098477d228d44ae2266ee78a37bed070441a.tar.xz linux-caec098477d228d44ae2266ee78a37bed070441a.zip |
[media] rc: rc-ir-raw: Add pulse-distance modulation helper
Add IR encoding helper for pulse-distance modulation as used by the NEC
protocol.
Signed-off-by: James Hogan <james@albanarts.com>
Signed-off-by: Sean Young <sean@mess.org>
Cc: Antti Seppälä <a.seppala@gmail.com>
Cc: David Härdeman <david@hardeman.nu>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-rw-r--r-- | drivers/media/rc/rc-core-priv.h | 52 | ||||
-rw-r--r-- | drivers/media/rc/rc-ir-raw.c | 59 |
2 files changed, 111 insertions, 0 deletions
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index b8d40e6e6ecf..2471a3ccf931 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -187,6 +187,58 @@ 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); +/** + * ir_raw_gen_pulse_space() - generate pulse and space raw events. + * @ev: Pointer to pointer to next free raw event. + * Will be incremented for each raw event written. + * @max: Pointer to number of raw events available in buffer. + * Will be decremented for each raw event written. + * @pulse_width: Width of pulse in ns. + * @space_width: Width of space in ns. + * + * Returns: 0 on success. + * -ENOBUFS if there isn't enough buffer space to write both raw + * events. In this case @max events will have been written. + */ +static inline int ir_raw_gen_pulse_space(struct ir_raw_event **ev, + unsigned int *max, + unsigned int pulse_width, + unsigned int space_width) +{ + if (!*max) + return -ENOBUFS; + init_ir_raw_event_duration((*ev)++, 1, pulse_width); + if (!--*max) + return -ENOBUFS; + init_ir_raw_event_duration((*ev)++, 0, space_width); + --*max; + return 0; +} + +/** + * 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 + * @bit_pulse: duration of bit pulse in ns + * @bit_space: duration of bit space (for logic 0 and 1) in ns + * @trailer_pulse: duration of trailer pulse in ns + * @trailer_space: duration of trailer space in ns + * @msb_first: 1 if most significant bit is sent first + */ +struct ir_raw_timings_pd { + unsigned int header_pulse; + unsigned int header_space; + unsigned int bit_pulse; + unsigned int bit_space[2]; + unsigned int trailer_pulse; + unsigned int trailer_space; + unsigned int msb_first:1; +}; + +int ir_raw_gen_pd(struct ir_raw_event **ev, unsigned int max, + const struct ir_raw_timings_pd *timings, + unsigned int n, u64 data); + /* * Routines from rc-raw.c to be used internally and by decoders */ diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 85ac5070376c..58039e6666af 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -324,6 +324,65 @@ nobufs: EXPORT_SYMBOL(ir_raw_gen_manchester); /** + * ir_raw_gen_pd() - Encode data to raw events with pulse-distance 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: Pulse distance modulation timings. + * @n: Number of bits of data. + * @data: Data bits to encode. + * + * Encodes the @n least significant bits of @data using pulse-distance + * 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_pd(struct ir_raw_event **ev, unsigned int max, + const struct ir_raw_timings_pd *timings, + unsigned int n, u64 data) +{ + int i; + int ret; + unsigned int space; + + if (timings->header_pulse) { + ret = ir_raw_gen_pulse_space(ev, &max, timings->header_pulse, + timings->header_space); + if (ret) + return ret; + } + + if (timings->msb_first) { + for (i = n - 1; i >= 0; --i) { + space = timings->bit_space[(data >> i) & 1]; + ret = ir_raw_gen_pulse_space(ev, &max, + timings->bit_pulse, + space); + if (ret) + return ret; + } + } else { + for (i = 0; i < n; ++i, data >>= 1) { + space = timings->bit_space[data & 1]; + ret = ir_raw_gen_pulse_space(ev, &max, + timings->bit_pulse, + space); + if (ret) + return ret; + } + } + + ret = ir_raw_gen_pulse_space(ev, &max, timings->trailer_pulse, + timings->trailer_space); + return ret; +} +EXPORT_SYMBOL(ir_raw_gen_pd); + +/** * ir_raw_encode_scancode() - Encode a scancode as raw events * * @protocol: protocol |