Source
// SPDX-License-Identifier: GPL-2.0+
// ir-imon-decoder.c - handle iMon protocol
//
// Copyright (C) 2018 by Sean Young <sean@mess.org>
/* ns */
/*
* This protocol has 30 bits. The format is one IMON_UNIT header pulse,
* followed by 30 bits. Each bit is one IMON_UNIT check field, and then
* one IMON_UNIT field with the actual bit (1=space, 0=pulse).
* The check field is always space for some bits, for others it is pulse if
* both the preceding and current bit are zero, else space. IMON_CHKBITS
* defines which bits are of type check.
*
* There is no way to distinguish an incomplete message from one where
* the lower bits are all set, iow. the last pulse is for the lowest
* bit which is 0.
*/
enum imon_state {
STATE_INACTIVE,
STATE_BIT_CHK,
STATE_BIT_START,
STATE_FINISHED,
STATE_ERROR,
};
static void ir_imon_decode_scancode(struct rc_dev *dev)
{
struct imon_dec *imon = &dev->raw->imon;
/* Keyboard/Mouse toggle */
if (imon->bits == 0x299115b7)
imon->stick_keyboard = !imon->stick_keyboard;
if ((imon->bits & 0xfc0000ff) == 0x680000b7) {
int rel_x, rel_y;
u8 buf;
buf = imon->bits >> 16;
rel_x = (buf & 0x08) | (buf & 0x10) >> 2 |
(buf & 0x20) >> 4 | (buf & 0x40) >> 6;
if (imon->bits & 0x02000000)
rel_x |= ~0x0f;
buf = imon->bits >> 8;
rel_y = (buf & 0x08) | (buf & 0x10) >> 2 |
(buf & 0x20) >> 4 | (buf & 0x40) >> 6;
if (imon->bits & 0x01000000)
rel_y |= ~0x0f;
if (rel_x && rel_y && imon->stick_keyboard) {
if (abs(rel_y) > abs(rel_x))
imon->bits = rel_y > 0 ?