// SPDX-License-Identifier: GPL-2.0-only /* ir-rc6-decoder.c - A decoder for the RC6 IR protocol * * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
*/
/* * This decoder currently supports: * RC6-0-16 (standard toggle bit in header) * RC6-6A-20 (no toggle bit) * RC6-6A-24 (no toggle bit) * RC6-6A-32 (MCE version with toggle bit in body)
*/
staticenum rc6_mode rc6_mode(struct rc6_dec *data)
{ switch (data->header & RC6_MODE_MASK) { case 0: return RC6_MODE_0; case 6: if (!data->toggle) return RC6_MODE_6A;
fallthrough; default: return RC6_MODE_UNKNOWN;
}
}
/** * ir_rc6_decode() - Decode one RC6 pulse or space * @dev: the struct rc_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine
*/ staticint ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
{ struct rc6_dec *data = &dev->raw->rc6;
u32 scancode;
u8 toggle; enum rc_proto protocol;
if (!is_timing_event(ev)) { if (ev.overflow)
data->state = STATE_INACTIVE; return 0;
}
if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) goto out;
again:
dev_dbg(&dev->dev, "RC6 decode started at state %i (%uus %s)\n",
data->state, ev.duration, TO_STR(ev.pulse));
if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) return 0;
switch (data->state) {
case STATE_INACTIVE: if (!ev.pulse) break;
/* Note: larger margin on first pulse since each RC6_UNIT is quite short and some hardware takes some time to
adjust to the signal */ if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT)) break;
/** * ir_rc6_encode() - Encode a scancode as a stream of raw events * * @protocol: protocol to encode * @scancode: scancode to encode * @events: array of raw ir events to write into * @max: maximum size of @events * * Returns: The number of events written. * -ENOBUFS if there isn't enough space in the array to fit the * encoding. In this case all @max events will have been written. * -EINVAL if the scancode is ambiguous or invalid.
*/ staticint ir_rc6_encode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsignedint max)
{ int ret; struct ir_raw_event *e = events;
if (protocol == RC_PROTO_RC6_0) { /* Modulate the header (Start Bit & Mode-0) */
ret = ir_raw_gen_manchester(&e, max - (e - events),
&ir_rc6_timings[0],
RC6_HEADER_NBITS, (1 << 3)); if (ret < 0) return ret;
/* Modulate Trailer Bit */
ret = ir_raw_gen_manchester(&e, max - (e - events),
&ir_rc6_timings[1], 1, 0); if (ret < 0) return ret;
/* Modulate rest of the data */
ret = ir_raw_gen_manchester(&e, max - (e - events),
&ir_rc6_timings[2], RC6_0_NBITS,
scancode); if (ret < 0) return ret;
} else { int bits;
switch (protocol) { case RC_PROTO_RC6_MCE: case RC_PROTO_RC6_6A_32:
bits = 32; break; case RC_PROTO_RC6_6A_24:
bits = 24; break; case RC_PROTO_RC6_6A_20:
bits = 20; break; default: return -EINVAL;
}
/* Modulate the header (Start Bit & Header-version 6 */
ret = ir_raw_gen_manchester(&e, max - (e - events),
&ir_rc6_timings[0],
RC6_HEADER_NBITS, (1 << 3 | 6)); if (ret < 0) return ret;
/* Modulate Trailer Bit */
ret = ir_raw_gen_manchester(&e, max - (e - events),
&ir_rc6_timings[1], 1, 0); if (ret < 0) return ret;
/* Modulate rest of the data */
ret = ir_raw_gen_manchester(&e, max - (e - events),
&ir_rc6_timings[2],
bits,
scancode); if (ret < 0) return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.