From patchwork Tue Mar 31 17:48:09 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?QW50dGkgU2VwcMOkbMOk?= X-Patchwork-Id: 6133201 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 458ADBF4A6 for ; Tue, 31 Mar 2015 17:49:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3E5AE201BC for ; Tue, 31 Mar 2015 17:49:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 32278201B9 for ; Tue, 31 Mar 2015 17:49:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752778AbbCaRtE (ORCPT ); Tue, 31 Mar 2015 13:49:04 -0400 Received: from mail-lb0-f174.google.com ([209.85.217.174]:35587 "EHLO mail-lb0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752285AbbCaRtC (ORCPT ); Tue, 31 Mar 2015 13:49:02 -0400 Received: by lbdc10 with SMTP id c10so18198284lbd.2 for ; Tue, 31 Mar 2015 10:49:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=YLB/W3l3xUNiB56K6OCtLK7KB6zGwXX93RjqpNotM8s=; b=Xwd5TWwNbTtyEWXAJgUtklzzlz456oA5vicVdoI7e2yQAlkAqh+/Nrey4Bg4VPDrXf SjxXfgtciz0FozcnjRljrq/SZPUHwGRVX1MPs8oaXHupfoRuvILlLo8gT/H68YO01hxa MrHfMRDI2BVHjF4v+lJePimY4lVZCADOQZzVIQjqsqKhJotGQ2OBmzg21a8u3d0VE8tQ xx9pvQhn5tQYAUeqmIOgacv0fJpI1SVGGGaa8xOkRL/xxz3MbkjsoUaUR8rQVHIx54vC 70F3LjxZpt9P4BrLG3sv8xorvPbwNqRbX5MXTXcNmSyVO9XH+gtTo4xQP64R0OCpjIiQ kIhQ== X-Received: by 10.112.10.197 with SMTP id k5mr4478273lbb.86.1427824140878; Tue, 31 Mar 2015 10:49:00 -0700 (PDT) Received: from pixie.elisa-laajakaista.fi (a91-154-178-36.elisa-laajakaista.fi. [91.154.178.36]) by mx.google.com with ESMTPSA id qw1sm2771382lbb.21.2015.03.31.10.48.59 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 31 Mar 2015 10:49:00 -0700 (PDT) From: =?UTF-8?q?Antti=20Sepp=C3=A4l=C3=A4?= To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , =?UTF-8?q?Antti=20Sepp=C3=A4l=C3=A4?= , James Hogan , =?UTF-8?q?David=20H=C3=A4rdeman?= Subject: [PATCH v3 4/7] rc: ir-rc6-decoder: Add encode capability Date: Tue, 31 Mar 2015 20:48:09 +0300 Message-Id: <1427824092-23163-5-git-send-email-a.seppala@gmail.com> X-Mailer: git-send-email 2.0.5 In-Reply-To: <1427824092-23163-1-git-send-email-a.seppala@gmail.com> References: <1427824092-23163-1-git-send-email-a.seppala@gmail.com> MIME-Version: 1.0 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.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 the capability to encode RC-6 and RC-6A scancodes as raw events. The protocol is chosen based on the specified protocol mask, and whether all the required bits are set in the scancode mask, and none of the unused bits are set in the scancode data. The Manchester modulation helper is used several times with various timings so that RC-6 header preamble, the header, header trailing bit and the data itself can be modulated correctly. Signed-off-by: Antti Seppälä Cc: James Hogan Cc: David Härdeman --- Notes: Changes in v3: - New patch drivers/media/rc/ir-rc6-decoder.c | 122 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index d16bc67..f9c70ba 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -291,11 +291,133 @@ out: return -EINVAL; } +static struct ir_raw_timings_manchester ir_rc6_timings[4] = { + { + .leader = RC6_PREFIX_PULSE, + .pulse_space_start = 0, + .clock = RC6_UNIT, + .invert = 1, + .trailer_space = RC6_PREFIX_SPACE, + }, + { + .clock = RC6_UNIT, + .invert = 1, + }, + { + .clock = RC6_UNIT * 2, + .invert = 1, + }, + { + .clock = RC6_UNIT, + .invert = 1, + .trailer_space = RC6_SUFFIX_SPACE, + }, +}; + +static int ir_rc6_validate_filter(const struct rc_scancode_filter *scancode, + unsigned int important_bits) +{ + /* all important bits of scancode should be set in mask */ + if (~scancode->mask & important_bits) + return -EINVAL; + /* extra bits in mask should be zero in data */ + if (scancode->mask & scancode->data & ~important_bits) + return -EINVAL; + return 0; +} + +/** + * ir_rc6_encode() - Encode a scancode as a stream of raw events + * + * @protocols: allowed protocols + * @scancode: scancode filter describing scancode (helps distinguish between + * protocol subtypes when scancode is ambiguous) + * @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. + */ +static int ir_rc6_encode(u64 protocols, + const struct rc_scancode_filter *scancode, + struct ir_raw_event *events, unsigned int max) +{ + int ret; + struct ir_raw_event *e = events; + + if (protocols & RC_BIT_RC6_0 && + !ir_rc6_validate_filter(scancode, 0xffff)) { + + /* Modulate the preamble */ + ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0); + if (ret < 0) + return ret; + + /* Modulate the header (Start Bit & Mode-0) */ + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc6_timings[1], + 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[2], 1, 0); + if (ret < 0) + return ret; + + /* Modulate rest of the data */ + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc6_timings[3], RC6_0_NBITS, + scancode->data); + if (ret < 0) + return ret; + + } else if (protocols & (RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | + RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE) && + !ir_rc6_validate_filter(scancode, 0x8fffffff)) { + + /* Modulate the preamble */ + ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0); + if (ret < 0) + return ret; + + /* Modulate the header (Start Bit & Header-version 6 */ + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc6_timings[1], + 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[2], 1, 0); + if (ret < 0) + return ret; + + /* Modulate rest of the data */ + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc6_timings[3], + fls(scancode->mask), + scancode->data); + if (ret < 0) + return ret; + + } else { + return -EINVAL; + } + + return e - events; +} + static struct ir_raw_handler rc6_handler = { .protocols = RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE, .decode = ir_rc6_decode, + .encode = ir_rc6_encode, }; static int __init ir_rc6_decode_init(void)