Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit caec0984 authored by James Hogan's avatar James Hogan Committed by Mauro Carvalho Chehab
Browse files

[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: default avatarJames Hogan <james@albanarts.com>
Signed-off-by: default avatarSean Young <sean@mess.org>
Cc: Antti Seppälä <a.seppala@gmail.com>
Cc: David Härdeman <david@hardeman.nu>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 844a4f45
Loading
Loading
Loading
Loading
+52 −0
Original line number Original line Diff line number Diff line
@@ -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
 */
 */
+59 −0
Original line number Original line Diff line number Diff line
@@ -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
 *
 *