[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>
This commit is contained in:
James Hogan 2014-03-14 20:04:12 -03:00 committed by Mauro Carvalho Chehab
parent 844a4f45f4
commit caec098477
2 changed files with 111 additions and 0 deletions

View File

@ -187,6 +187,58 @@ int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max,
const struct ir_raw_timings_manchester *timings, const struct ir_raw_timings_manchester *timings,
unsigned int n, unsigned int data); 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 * Routines from rc-raw.c to be used internally and by decoders
*/ */

View File

@ -323,6 +323,65 @@ int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max,
} }
EXPORT_SYMBOL(ir_raw_gen_manchester); 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 * ir_raw_encode_scancode() - Encode a scancode as raw events
* *