From patchwork Fri Oct 9 13:46:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ezequiel Garcia X-Patchwork-Id: 7361961 Return-Path: X-Original-To: patchwork-linux-input@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 1736CBEEA4 for ; Fri, 9 Oct 2015 13:51:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2219420575 for ; Fri, 9 Oct 2015 13:51:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 069142053A for ; Fri, 9 Oct 2015 13:51:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756357AbbJINvT (ORCPT ); Fri, 9 Oct 2015 09:51:19 -0400 Received: from mail-qg0-f49.google.com ([209.85.192.49]:35207 "EHLO mail-qg0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752845AbbJINvQ (ORCPT ); Fri, 9 Oct 2015 09:51:16 -0400 Received: by qgt47 with SMTP id 47so68840456qgt.2 for ; Fri, 09 Oct 2015 06:51:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; bh=HHCTJncnDpt05o2RZTC9YcJ/nc04+vH5pgx9cq0nwYc=; b=LHWp8jsE66r6T2mwMIawsKptx7zYCzZ87Knofe/i82e17BHcyFuOADpFw004I1l0H7 5xiDSl466QYEQVw1hy+QbYv9LKb5dfKxjNgL0VSZf0Il4pR5wdCJMe+CE8+5PuvgiWVZ ZyKjKyN7uULpPMLllMY2mI8CJ94JwyVOnNmeqA0azsW+EokgteksUQ9Qstpvkc1cvPEd 1i1iwydnuewFPR/UsxDl9flpUB/AcyeXHj37CCkt/jDG9wvuOMi/02eVBKBWpT6+IQ/F xIfqlA+ES7UU0ud00/poxUYOuEmyytXyhxo5HhSEWKLQe71WN9GYqbvEGC/syVjQalv8 8Dww== X-Gm-Message-State: ALoCoQmOkKsZ9GCtuxNkavvMAjngJsVcdCEF+Nqjgv2foyXjpiIIVZBVp90J4n2hxIKph+HzK9La X-Received: by 10.140.131.135 with SMTP id 129mr16490282qhd.31.1444398675502; Fri, 09 Oct 2015 06:51:15 -0700 (PDT) Received: from localhost.localdomain ([190.2.108.156]) by smtp.gmail.com with ESMTPSA id q75sm679167qki.3.2015.10.09.06.51.12 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Oct 2015 06:51:14 -0700 (PDT) From: Ezequiel Garcia To: , Cc: Dmitry Torokhov , Daniel Mack , Sascha Hauer , mark.rutland@arm.com, robh+dt@kernel.org, pawel.moll@arm.com, ijc+devicetree@hellion.org.uk, galak@codeaurora.org, ariel@vanguardiasur.com.ar, Ezequiel Garcia , =?UTF-8?q?Guido=20Mart=C3=ADnez?= Subject: [PATCH 3/3] input: rotary-encoder: Support 'steps-per-period' DT property Date: Fri, 9 Oct 2015 10:46:56 -0300 Message-Id: <1444398416-3073-4-git-send-email-ezequiel@vanguardiasur.com.ar> X-Mailer: git-send-email 2.5.2 In-Reply-To: <1444398416-3073-1-git-send-email-ezequiel@vanguardiasur.com.ar> References: <1444398416-3073-1-git-send-email-ezequiel@vanguardiasur.com.ar> MIME-Version: 1.0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 As per the recent devicetree binding changes, this commit adds the support for the new 'steps-per-period' property. Legacy properties to specify the rotary behavior, are now deprecated and instead the new 'steps-per-period' is supported. The default behavior is retained. This allows to support rotary-encoder devices with detents wich are capable of producing a stable event on each step. Signed-off-by: Guido Martínez Signed-off-by: Ezequiel Garcia --- drivers/input/misc/rotary_encoder.c | 87 +++++++++++++++++++++++++++++++++++-- include/linux/rotary_encoder.h | 2 +- 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 15a4cc670a3f..e021615dd3c0 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -142,6 +142,55 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id) +{ + struct rotary_encoder *encoder = dev_id; + unsigned char sum; + int state; + + state = rotary_encoder_get_state(encoder->pdata); + + /* + * We encode the previous and the current state using a byte. + * The previous state in the MSB nibble, the current state in the LSB + * nibble. Then use a table to decide the direction of the turn. + */ + sum = (encoder->last_stable << 4) + state; + switch (sum) { + case 0x31: + case 0x10: + case 0x02: + case 0x23: + encoder->dir = 0; /* clockwise */ + break; + + case 0x13: + case 0x01: + case 0x20: + case 0x32: + encoder->dir = 1; /* counter-clockwise */ + break; + + default: + /* + * Ignore all other values. This covers the case when the + * state didn't change (a spurious interrupt) and the + * cases where the state changed by two steps, making it + * impossible to tell the direction. + * + * In either case, don't report any event and save the + * state for later. + */ + goto out; + } + + rotary_encoder_report_event(encoder); + +out: + encoder->last_stable = state; + return IRQ_HANDLED; +} + #ifdef CONFIG_OF static const struct of_device_id rotary_encoder_of_match[] = { { .compatible = "rotary-encoder", }, @@ -176,7 +225,26 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic pdata->relative_axis = of_property_read_bool(np, "rotary-encoder,relative-axis"); pdata->rollover = of_property_read_bool(np, "rotary-encoder,rollover"); - pdata->half_period = of_property_read_bool(np, "rotary-encoder,half-period"); + + if (!of_get_property(np, "rotary-encoder,steps-per-period", NULL)) { + /* + * Fallback to a one step per period behavior if the + * 'steps-per-period' is not set. + */ + pdata->steps_per_period = 1; + } else { + of_property_read_u32(np, "rotary-encoder,steps-per-period", + &pdata->steps_per_period); + } + + /* + * The 'half-period' property has been deprecated, you must use + * 'steps-per-period' and set an appropriate value. + */ + if (of_get_property(np, "rotary-encoder,half-period", NULL)) { + pr_warn(FW_WARN "\"rotary-encoder,half-period\" is deprecated\n"); + pdata->steps_per_period = 2; + } return pdata; } @@ -247,12 +315,23 @@ static int rotary_encoder_probe(struct platform_device *pdev) encoder->irq_a = gpio_to_irq(pdata->gpio_a); encoder->irq_b = gpio_to_irq(pdata->gpio_b); - /* request the IRQs */ - if (pdata->half_period) { + switch (pdata->steps_per_period) { + case 4: + handler = &rotary_encoder_quarter_period_irq; + encoder->last_stable = rotary_encoder_get_state(pdata); + break; + case 2: handler = &rotary_encoder_half_period_irq; encoder->last_stable = rotary_encoder_get_state(pdata); - } else { + break; + case 1: handler = &rotary_encoder_irq; + break; + default: + dev_err(dev, "'%d' is not a valid steps-per-period value\n", + pdata->steps_per_period); + err = -EINVAL; + goto exit_free_gpio_b; } err = request_irq(encoder->irq_a, handler, diff --git a/include/linux/rotary_encoder.h b/include/linux/rotary_encoder.h index 3f594dce5716..0bebba31908c 100644 --- a/include/linux/rotary_encoder.h +++ b/include/linux/rotary_encoder.h @@ -10,7 +10,7 @@ struct rotary_encoder_platform_data { unsigned int inverted_b; bool relative_axis; bool rollover; - bool half_period; + unsigned int steps_per_period; }; #endif /* __ROTARY_ENCODER_H__ */