From patchwork Fri Feb 28 23:28:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hogan X-Patchwork-Id: 3745111 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 94E7DBF13A for ; Fri, 28 Feb 2014 23:30:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 86FE1200ED for ; Fri, 28 Feb 2014 23:30:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 415B2200DE for ; Fri, 28 Feb 2014 23:30:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752540AbaB1X3z (ORCPT ); Fri, 28 Feb 2014 18:29:55 -0500 Received: from mail-we0-f178.google.com ([74.125.82.178]:33776 "EHLO mail-we0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752129AbaB1X3x (ORCPT ); Fri, 28 Feb 2014 18:29:53 -0500 Received: by mail-we0-f178.google.com with SMTP id q59so1121078wes.9 for ; Fri, 28 Feb 2014 15:29:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=lx2pGSRiL77b0YIYFnmR0tebo1mxJg+HNXydY/D2xmo=; b=ZHIPu57ldqs0jZMj+T+RKRMHLoXk9S7/JyIga0fEHvi1v7lNJGX/RPeG6JIIiikjvy ROFdS0Pa5MbQvafR0uVqm1CxmH1W0uxRzclRJics+i/ZNUKqclUiZcRxIyDvf7X4buTa ifs6Hmhr2mzZdSHHth7pS04HdpbQsABdd+e+skA8m94MUGKlWCJU4ZQ2ddZg+5kaMcQn TlwpP7imPPaa/istQgGB3M+Jz0H8zwOrdqxdgHM9znKMamAoVXhCCBY62vxz/poQqGtX r6hLfPW7U4yL3+6D+t/501TniZE7ZxatSklnPYB97m+uXs+ktGvW3R07OlLJV7+POG+b zMeg== X-Gm-Message-State: ALoCoQmKRL43e7NlHwIZMzQbHHez2KMtja3NP+G1u6lBIoY4+S6briN0Oqjyg+zZGGyrby/UE4Eb X-Received: by 10.180.219.66 with SMTP id pm2mr5548285wic.60.1393630192530; Fri, 28 Feb 2014 15:29:52 -0800 (PST) Received: from radagast.lan (jahogan.plus.com. [212.159.75.221]) by mx.google.com with ESMTPSA id lz3sm9172173wic.1.2014.02.28.15.29.51 for (version=TLSv1.2 cipher=AES128-GCM-SHA256 bits=128/128); Fri, 28 Feb 2014 15:29:52 -0800 (PST) From: James Hogan To: Mauro Carvalho Chehab , linux-media@vger.kernel.org Cc: James Hogan Subject: [PATCH v4 06/10] rc: img-ir: add NEC decoder module Date: Fri, 28 Feb 2014 23:28:56 +0000 Message-Id: <1393630140-31765-7-git-send-email-james.hogan@imgtec.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1393630140-31765-1-git-send-email-james.hogan@imgtec.com> References: <1393630140-31765-1-git-send-email-james.hogan@imgtec.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add an img-ir module for decoding the NEC and extended NEC infrared protocols. Signed-off-by: James Hogan Cc: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org --- v2: - Update scancode and filter callbacks to handle 32-bit NEC as used by Apple and TiVo remotes (the new 32-bit NEC scancode format is used, with the correct bit orientation). - Update to new scancode interface so that 32-bit NEC scancodes can be returned reliably. - Update to new filtering interface (generic struct rc_scancode_filter). - Make it possible to set the filter to extended NEC even when the high bits of the scancode value aren't set, by taking the mask into account too. My TV remote happens to use extended NEC with address 0x7f00, which unfortunately maps to scancodes 0x007f** which looks like normal NEC and couldn't previously be filtered. - Remove modularity and dynamic registration/unregistration, adding NEC directly to the list of decoders in img-ir-hw.c. --- drivers/media/rc/img-ir/Kconfig | 7 ++ drivers/media/rc/img-ir/Makefile | 1 + drivers/media/rc/img-ir/img-ir-hw.c | 5 ++ drivers/media/rc/img-ir/img-ir-nec.c | 148 +++++++++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 drivers/media/rc/img-ir/img-ir-nec.c diff --git a/drivers/media/rc/img-ir/Kconfig b/drivers/media/rc/img-ir/Kconfig index 60eaba6..28498a2 100644 --- a/drivers/media/rc/img-ir/Kconfig +++ b/drivers/media/rc/img-ir/Kconfig @@ -24,3 +24,10 @@ config IR_IMG_HW signals in hardware. This is more reliable, consumes less processing power since only a single interrupt is received for each scancode, and allows an IR scancode to be used as a wake event. + +config IR_IMG_NEC + bool "NEC protocol support" + depends on IR_IMG_HW + help + Say Y here to enable support for the NEC, extended NEC, and 32-bit + NEC protocols in the ImgTec infrared decoder block. diff --git a/drivers/media/rc/img-ir/Makefile b/drivers/media/rc/img-ir/Makefile index 4ef86ed..c409197 100644 --- a/drivers/media/rc/img-ir/Makefile +++ b/drivers/media/rc/img-ir/Makefile @@ -1,6 +1,7 @@ img-ir-y := img-ir-core.o img-ir-$(CONFIG_IR_IMG_RAW) += img-ir-raw.o img-ir-$(CONFIG_IR_IMG_HW) += img-ir-hw.o +img-ir-$(CONFIG_IR_IMG_NEC) += img-ir-nec.o img-ir-objs := $(img-ir-y) obj-$(CONFIG_IR_IMG) += img-ir.o diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c index 21c8bbc..139f2c7 100644 --- a/drivers/media/rc/img-ir/img-ir-hw.c +++ b/drivers/media/rc/img-ir/img-ir-hw.c @@ -20,8 +20,13 @@ /* Decoders lock (only modified to preprocess them) */ static DEFINE_SPINLOCK(img_ir_decoders_lock); +extern struct img_ir_decoder img_ir_nec; + static bool img_ir_decoders_preprocessed; static struct img_ir_decoder *img_ir_decoders[] = { +#ifdef CONFIG_IR_IMG_NEC + &img_ir_nec, +#endif NULL }; diff --git a/drivers/media/rc/img-ir/img-ir-nec.c b/drivers/media/rc/img-ir/img-ir-nec.c new file mode 100644 index 0000000..e7a731b --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-nec.c @@ -0,0 +1,148 @@ +/* + * ImgTec IR Decoder setup for NEC protocol. + * + * Copyright 2010-2014 Imagination Technologies Ltd. + */ + +#include "img-ir-hw.h" + +/* Convert NEC data to a scancode */ +static int img_ir_nec_scancode(int len, u64 raw, int *scancode, u64 protocols) +{ + unsigned int addr, addr_inv, data, data_inv; + /* a repeat code has no data */ + if (!len) + return IMG_IR_REPEATCODE; + if (len != 32) + return -EINVAL; + /* raw encoding: ddDDaaAA */ + addr = (raw >> 0) & 0xff; + addr_inv = (raw >> 8) & 0xff; + data = (raw >> 16) & 0xff; + data_inv = (raw >> 24) & 0xff; + if ((data_inv ^ data) != 0xff) { + /* 32-bit NEC (used by Apple and TiVo remotes) */ + /* scan encoding: aaAAddDD */ + *scancode = addr_inv << 24 | + addr << 16 | + data_inv << 8 | + data; + } else if ((addr_inv ^ addr) != 0xff) { + /* Extended NEC */ + /* scan encoding: AAaaDD */ + *scancode = addr << 16 | + addr_inv << 8 | + data; + } else { + /* Normal NEC */ + /* scan encoding: AADD */ + *scancode = addr << 8 | + data; + } + return IMG_IR_SCANCODE; +} + +/* Convert NEC scancode to NEC data filter */ +static int img_ir_nec_filter(const struct rc_scancode_filter *in, + struct img_ir_filter *out, u64 protocols) +{ + unsigned int addr, addr_inv, data, data_inv; + unsigned int addr_m, addr_inv_m, data_m, data_inv_m; + + data = in->data & 0xff; + data_m = in->mask & 0xff; + + if ((in->data | in->mask) & 0xff000000) { + /* 32-bit NEC (used by Apple and TiVo remotes) */ + /* scan encoding: aaAAddDD */ + addr_inv = (in->data >> 24) & 0xff; + addr_inv_m = (in->mask >> 24) & 0xff; + addr = (in->data >> 16) & 0xff; + addr_m = (in->mask >> 16) & 0xff; + data_inv = (in->data >> 8) & 0xff; + data_inv_m = (in->mask >> 8) & 0xff; + } else if ((in->data | in->mask) & 0x00ff0000) { + /* Extended NEC */ + /* scan encoding AAaaDD */ + addr = (in->data >> 16) & 0xff; + addr_m = (in->mask >> 16) & 0xff; + addr_inv = (in->data >> 8) & 0xff; + addr_inv_m = (in->mask >> 8) & 0xff; + data_inv = data ^ 0xff; + data_inv_m = data_m; + } else { + /* Normal NEC */ + /* scan encoding: AADD */ + addr = (in->data >> 8) & 0xff; + addr_m = (in->mask >> 8) & 0xff; + addr_inv = addr ^ 0xff; + addr_inv_m = addr_m; + data_inv = data ^ 0xff; + data_inv_m = data_m; + } + + /* raw encoding: ddDDaaAA */ + out->data = data_inv << 24 | + data << 16 | + addr_inv << 8 | + addr; + out->mask = data_inv_m << 24 | + data_m << 16 | + addr_inv_m << 8 | + addr_m; + return 0; +} + +/* + * NEC decoder + * See also http://www.sbprojects.com/knowledge/ir/nec.php + * http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol + */ +struct img_ir_decoder img_ir_nec = { + .type = RC_BIT_NEC, + .control = { + .decoden = 1, + .code_type = IMG_IR_CODETYPE_PULSEDIST, + }, + /* main timings */ + .unit = 562500, /* 562.5 us */ + .timings = { + /* leader symbol */ + .ldr = { + .pulse = { 16 /* 9ms */ }, + .space = { 8 /* 4.5ms */ }, + }, + /* 0 symbol */ + .s00 = { + .pulse = { 1 /* 562.5 us */ }, + .space = { 1 /* 562.5 us */ }, + }, + /* 1 symbol */ + .s01 = { + .pulse = { 1 /* 562.5 us */ }, + .space = { 3 /* 1687.5 us */ }, + }, + /* free time */ + .ft = { + .minlen = 32, + .maxlen = 32, + .ft_min = 10, /* 5.625 ms */ + }, + }, + /* repeat codes */ + .repeat = 108, /* 108 ms */ + .rtimings = { + /* leader symbol */ + .ldr = { + .space = { 4 /* 2.25 ms */ }, + }, + /* free time */ + .ft = { + .minlen = 0, /* repeat code has no data */ + .maxlen = 0, + }, + }, + /* scancode logic */ + .scancode = img_ir_nec_scancode, + .filter = img_ir_nec_filter, +};