Received: by 10.223.185.116 with SMTP id b49csp6138059wrg; Wed, 28 Feb 2018 04:46:14 -0800 (PST) X-Google-Smtp-Source: AH8x224c2JiwtxjG9QQKHe9HmAKkgy81zim3XRzo8EedziHbsdEcnq9pac+UWykeN1rIhakF3gPL X-Received: by 10.167.129.67 with SMTP id d3mr17590150pfn.108.1519821974436; Wed, 28 Feb 2018 04:46:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519821974; cv=none; d=google.com; s=arc-20160816; b=sm33y8G76lxG8kJt/r7RgOPJTNKn69hTR6KvHqUMU+fGpTlPyZU65VghsAyq7IccSz nclrTpL2rZlwJedByS9cdQVl/It7EVrioD9GdUxNWZbemfyKj+WmoK8l1QkkwHdVHWBo BcrTd/SgPK7Eg9QM6ocBYR53zee4RekRd7iXTiEUECB8g72EyKZfKc6Wxv7O9A3J1G2i GsGOb0TEmiZ5q0q2WLwOXIfP5sKr7yZlvs2JMn7COUm+30KRp0mBv/+d0KxaDpXzZMIr vvW/iynHDusosYNOUU8vaxrNF1U1WWBIEjiljFxicc/n4utTjEjGNrRCLJJeBrWJDSoq JmCQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=PHB58ugZyHCrmN8anIQa/VSNJ5iqk7j285imOYhNisc=; b=e/dIUmk/5iKc9jPKIl+4Nc/hK9OaLzlfNEtyTZqb+nH9NDWcDemGIKbEYekD8yNoG8 jYhE4TxBA98isJx4Uoba10jyT9D4HMpzEi5MMvHokjknIAuhGIxtbl2t0gsk/Uf3bEEw yPS0gDNwlDZkHo0bKVn5C4a8ld6rC9NuxFRo7+IQXQs8PVteoiVNeh4W7V1A1TYNfqPj qbxaw/CwzYzvv7ytfuNWoXeNjPHU+YjRQePDie+34GuqiXcXzIMh5ngUgo+dr4tmXbHK RNlADiQd9fzC2utUPgbJIh3dF17cCr1RszUuSQHFx89+I2UrX46sFUwyoLDjMseTrPit Ky7w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=XkYGAGzL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c14si1143884pfn.313.2018.02.28.04.45.59; Wed, 28 Feb 2018 04:46:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=XkYGAGzL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752428AbeB1MpT (ORCPT + 99 others); Wed, 28 Feb 2018 07:45:19 -0500 Received: from mail-pl0-f68.google.com ([209.85.160.68]:42237 "EHLO mail-pl0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752267AbeB1MpR (ORCPT ); Wed, 28 Feb 2018 07:45:17 -0500 Received: by mail-pl0-f68.google.com with SMTP id 93-v6so1417803plc.9 for ; Wed, 28 Feb 2018 04:45:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=PHB58ugZyHCrmN8anIQa/VSNJ5iqk7j285imOYhNisc=; b=XkYGAGzLLuDy4S2LJvX3wrjgUnksVjis+mv47FAkLwCB1WQJoXl0HdpXudGWUmXofK j4qdMDw57Bwi6i5ijlZxri49DN94wheCOZKYfPPFhdVIT5VyJwq0BwQLVdaTI2Eb6U0S YiVYIJFGstaUmBvtdCqtBaGkDz7nqpcsz18gk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=PHB58ugZyHCrmN8anIQa/VSNJ5iqk7j285imOYhNisc=; b=eVMQKMhFOdVHuNSnVDYnCW0z/aPWSgO7anRkuFth17OverkLVfyCS8ecdGsqET85dH IeY3R+EclB8A2W178eXJZ3PikoYNyyw8+BrK07PnRH5WnoBIJT4OMImkPSB07m6N7PCa WwGlWWRs8gdeEJzDWFY08gEzdnsaGflT1qXAHS4cHlnYKH8KxuveG+dnKmNb1DW6duJ4 /W+Rxba1pxX1w69j9d+gmrERJxWn5xh4iPHj2YbZj/bhJn3tXeAIXs3wVL2fl8hZlDZS g0ezYaRYoBxFduhNeFfdFT34ZaN3OSZLw5RK5jvtCBPB+1hRetq0emdk/vYaSGwBn7Hz 376g== X-Gm-Message-State: APf1xPA2QVP3+SkbRE1q12WbIh5XfpmU7fyhyM6iSGof0YTU0Qx3mV9L CNuW8gdqPfhQmXq0JTMFDvr4+Q== X-Received: by 2002:a17:902:5797:: with SMTP id l23-v6mr17577028pli.56.1519821916538; Wed, 28 Feb 2018 04:45:16 -0800 (PST) Received: from baolinwangubtpc.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id w24sm1491379pfl.14.2018.02.28.04.45.12 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 28 Feb 2018 04:45:15 -0800 (PST) From: Baolin Wang To: dmitry.torokhov@gmail.com, robh+dt@kernel.org, mark.rutland@arm.com Cc: gregkh@linuxfoundation.org, lumotuwe@gmail.com, arvind.yadav.cs@gmail.com, josephl@nvidia.com, kstewart@linuxfoundation.org, pombredanne@nexb.com, tglx@linutronix.de, linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, broonie@kernel.org, linus.walleij@linaro.org, arnd@arndb.de, baolin.wang@linaro.org Subject: [PATCH v3] Input: gpio_keys: Add level trigger support for GPIO keys Date: Wed, 28 Feb 2018 20:44:36 +0800 Message-Id: <826093167e8fb24723f474b0272f3dcab1b6a97e.1519821626.git.baolin.wang@linaro.org> X-Mailer: git-send-email 1.7.9.5 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On some platforms (such as Spreadtrum platform), the GPIO keys can only be triggered by level type. So this patch introduces one property to indicate if the GPIO trigger type is level trigger or edge trigger. Signed-off-by: Baolin Wang --- Changes since v2: - Use 'interrupt' property to indicate the irq type. Changes since v1: - Diable the GPIO irq until reversing the GPIO level type. --- drivers/input/keyboard/gpio_keys.c | 32 ++++++++++++++++++++++++++++++-- include/linux/gpio_keys.h | 3 +++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 87e613d..9e05c80 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -385,6 +385,20 @@ static void gpio_keys_gpio_work_func(struct work_struct *work) struct gpio_button_data *bdata = container_of(work, struct gpio_button_data, work.work); + if (bdata->button->level_trigger) { + unsigned int trigger = + irq_get_trigger_type(bdata->irq) & ~IRQF_TRIGGER_MASK; + int state = gpiod_get_raw_value_cansleep(bdata->gpiod); + + if (state) + trigger |= IRQF_TRIGGER_LOW; + else + trigger |= IRQF_TRIGGER_HIGH; + + irq_set_irq_type(bdata->irq, trigger); + enable_irq(bdata->irq); + } + gpio_keys_gpio_report_event(bdata); if (bdata->button->wakeup) @@ -397,6 +411,9 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) BUG_ON(irq != bdata->irq); + if (bdata->button->level_trigger) + disable_irq_nosync(bdata->irq); + if (bdata->button->wakeup) { const struct gpio_keys_button *button = bdata->button; @@ -566,7 +583,11 @@ static int gpio_keys_setup_key(struct platform_device *pdev, INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func); isr = gpio_keys_gpio_isr; - irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; + if (button->level_trigger) + irqflags = gpiod_is_active_low(bdata->gpiod) ? + IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH; + else + irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; } else { if (!button->irq) { @@ -696,10 +717,17 @@ static void gpio_keys_close(struct input_dev *input) device_property_read_string(dev, "label", &pdata->name); device_for_each_child_node(dev, child) { - if (is_of_node(child)) + if (is_of_node(child)) { button->irq = irq_of_parse_and_map(to_of_node(child), 0); + if (button->irq) + button->level_trigger = + irq_get_trigger_type(button->irq) & + (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW) ? + true : false; + } + if (fwnode_property_read_u32(child, "linux,code", &button->code)) { dev_err(dev, "Button without keycode\n"); diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index d06bf77..1286136 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -16,6 +16,8 @@ * @debounce_interval: debounce ticks interval in msecs * @can_disable: %true indicates that userspace is allowed to * disable button via sysfs + * @level_trigger: indicate if the button's interrupt type is + * level trigger or not * @value: axis value for %EV_ABS * @irq: Irq number in case of interrupt keys */ @@ -28,6 +30,7 @@ struct gpio_keys_button { int wakeup; int debounce_interval; bool can_disable; + bool level_trigger; int value; unsigned int irq; }; -- 1.7.9.5