From patchwork Thu Oct 18 11:27:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Young X-Patchwork-Id: 10647043 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D4F28109C for ; Thu, 18 Oct 2018 11:27:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C8B5828505 for ; Thu, 18 Oct 2018 11:27:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BCB8528653; Thu, 18 Oct 2018 11:27:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE8E128644 for ; Thu, 18 Oct 2018 11:27:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727476AbeJRT1y (ORCPT ); Thu, 18 Oct 2018 15:27:54 -0400 Received: from gofer.mess.org ([88.97.38.141]:47331 "EHLO gofer.mess.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727434AbeJRT1x (ORCPT ); Thu, 18 Oct 2018 15:27:53 -0400 Received: by gofer.mess.org (Postfix, from userid 1000) id 94F276015A; Thu, 18 Oct 2018 12:27:17 +0100 (BST) From: Sean Young To: linux-media@vger.kernel.org Cc: Benjamin Valentin Subject: [PATCH v4l-utils] keytable: bpf decoder and keymap for XBox DVD Remote Date: Thu, 18 Oct 2018 12:27:16 +0100 Message-Id: <20181018112717.8361-1-sean@mess.org> X-Mailer: git-send-email 2.11.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This uses a modified nec protocol, where 24 bits are sent and the first 12 bits are inverted. Signed-off-by: Sean Young --- utils/keytable/bpf_protocols/Makefile.am | 2 +- utils/keytable/bpf_protocols/xbox.c | 129 ++++++++++++++++++ .../rc_keymaps_userspace/xbox_dvd.toml | 31 +++++ 3 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 utils/keytable/bpf_protocols/xbox.c create mode 100644 utils/keytable/rc_keymaps_userspace/xbox_dvd.toml diff --git a/utils/keytable/bpf_protocols/Makefile.am b/utils/keytable/bpf_protocols/Makefile.am index 8887b897..2d005b1f 100644 --- a/utils/keytable/bpf_protocols/Makefile.am +++ b/utils/keytable/bpf_protocols/Makefile.am @@ -10,7 +10,7 @@ CLANG_SYS_INCLUDES := $(shell $(CLANG) -v -E - &1 \ %.o: %.c bpf_helpers.h $(CLANG) $(CLANG_SYS_INCLUDES) -I$(top_srcdir)/include -target bpf -O2 -c $< -PROTOCOLS = grundig.o pulse_distance.o pulse_length.o rc_mm.o manchester.o +PROTOCOLS = grundig.o pulse_distance.o pulse_length.o rc_mm.o manchester.o xbox.o all: $(PROTOCOLS) diff --git a/utils/keytable/bpf_protocols/xbox.c b/utils/keytable/bpf_protocols/xbox.c new file mode 100644 index 00000000..e48e0a79 --- /dev/null +++ b/utils/keytable/bpf_protocols/xbox.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright (C) 2018 Sean Young + +#include +#include + +#include "bpf_helpers.h" + +enum state { + STATE_INACTIVE, + STATE_HEADER_SPACE, + STATE_BITS_SPACE, + STATE_BITS_PULSE, + STATE_TRAILER, +}; + +struct decoder_state { + unsigned long bits; + enum state state; + unsigned int count; +}; + +struct bpf_map_def SEC("maps") decoder_state_map = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(unsigned int), + .value_size = sizeof(struct decoder_state), + .max_entries = 1, +}; + +// These values can be overridden in the rc_keymap toml +// +// We abuse elf relocations. We cast the address of these variables to +// an int, so that the compiler emits a mov immediate for the address +// but uses it as an int. The bpf loader replaces the relocation with the +// actual value (either overridden or taken from the data segment). +int margin = 200; +int header_pulse = 4000; +int header_space = 3900; +int bit_pulse = 550; +int bit_0_space = 900; +int bit_1_space = 1900; +int trailer_pulse = 550; +int bits = 24; +int rc_protocol = 68; + +#define BPF_PARAM(x) (int)(&(x)) + +static inline int eq_margin(unsigned d1, unsigned d2) +{ + return ((d1 > (d2 - BPF_PARAM(margin))) && (d1 < (d2 + BPF_PARAM(margin)))); +} + +SEC("xbox") +int bpf_decoder(unsigned int *sample) +{ + unsigned int key = 0; + struct decoder_state *s = bpf_map_lookup_elem(&decoder_state_map, &key); + + if (!s) + return 0; + + switch (*sample & LIRC_MODE2_MASK) { + case LIRC_MODE2_SPACE: + case LIRC_MODE2_PULSE: + case LIRC_MODE2_TIMEOUT: + break; + default: + // not a timing events + return 0; + } + + int duration = LIRC_VALUE(*sample); + int pulse = LIRC_IS_PULSE(*sample); + + switch (s->state) { + case STATE_HEADER_SPACE: + if (!pulse && eq_margin(BPF_PARAM(header_space), duration)) + s->state = STATE_BITS_PULSE; + else + s->state = STATE_INACTIVE; + break; + case STATE_INACTIVE: + if (pulse && eq_margin(BPF_PARAM(header_pulse), duration)) { + s->bits = 0; + s->state = STATE_HEADER_SPACE; + s->count = 0; + } + break; + case STATE_BITS_PULSE: + if (pulse && eq_margin(BPF_PARAM(bit_pulse), duration)) + s->state = STATE_BITS_SPACE; + else + s->state = STATE_INACTIVE; + break; + case STATE_BITS_SPACE: + if (pulse) { + s->state = STATE_INACTIVE; + break; + } + + s->bits <<= 1; + + if (eq_margin(BPF_PARAM(bit_1_space), duration)) + s->bits |= 1; + else if (!eq_margin(BPF_PARAM(bit_0_space), duration)) { + s->state = STATE_INACTIVE; + break; + } + + s->count++; + if (s->count == BPF_PARAM(bits)) + s->state = STATE_TRAILER; + else + s->state = STATE_BITS_PULSE; + break; + case STATE_TRAILER: + if (pulse && eq_margin(BPF_PARAM(trailer_pulse), duration)) { + if (((s->bits >> 12) ^ (s->bits & 0xfff)) == 0xfff) + bpf_rc_keydown(sample, BPF_PARAM(rc_protocol), s->bits & 0xfff, 0); + } + + s->state = STATE_INACTIVE; + } + + return 0; +} + +char _license[] SEC("license") = "GPL"; diff --git a/utils/keytable/rc_keymaps_userspace/xbox_dvd.toml b/utils/keytable/rc_keymaps_userspace/xbox_dvd.toml new file mode 100644 index 00000000..4f86c73c --- /dev/null +++ b/utils/keytable/rc_keymaps_userspace/xbox_dvd.toml @@ -0,0 +1,31 @@ +[[protocols]] +name = 'XBox DVD' +protocol = 'xbox' +[protocols.scancodes] +0xad5 = 'KEY_ANGLE' +0xae2 = 'KEY_REWIND' +0xaea = 'KEY_PLAY' +0xae3 = 'KEY_FORWARD' +0xadd = 'KEY_PREVIOUSSONG' +0xae0 = 'KEY_STOP' +0xae6 = 'KEY_PAUSE' +0xadf = 'KEY_NEXTSONG' +0xae5 = 'KEY_TITLE' +0xac3 = 'KEY_INFO' +0xaa6 = 'KEY_UP' +0xaa9 = 'KEY_LEFT' +0xaa8 = 'KEY_RIGHT' +0xaa7 = 'KEY_DOWN' +0xa0b = 'KEY_SELECT' +0xaf7 = 'KEY_MENU' +0xad8 = 'KEY_BACK' +0xace = 'KEY_1' +0xacd = 'KEY_2' +0xacc = 'KEY_3' +0xacb = 'KEY_4' +0xaca = 'KEY_5' +0xac9 = 'KEY_6' +0xac8 = 'KEY_7' +0xac7 = 'KEY_8' +0xac6 = 'KEY_9' +0xacf = 'KEY_0'