From patchwork Fri Jun 10 05:34:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 69742 Delivered-To: patches@linaro.org Received: by 10.140.106.246 with SMTP id e109csp122807qgf; Thu, 9 Jun 2016 22:34:49 -0700 (PDT) X-Received: by 10.98.152.76 with SMTP id q73mr293876pfd.38.1465536889571; Thu, 09 Jun 2016 22:34:49 -0700 (PDT) Return-Path: Received: from mail-pf0-x230.google.com (mail-pf0-x230.google.com. [2607:f8b0:400e:c00::230]) by mx.google.com with ESMTPS id n21si11423618pfb.123.2016.06.09.22.34.49 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Jun 2016 22:34:49 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:400e:c00::230 as permitted sender) client-ip=2607:f8b0:400e:c00::230; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:400e:c00::230 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: by mail-pf0-x230.google.com with SMTP id t190so20150817pfb.3 for ; Thu, 09 Jun 2016 22:34:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YQeCQT4ZMzRZvfEIWFMkhYTdv42aUOnImXMAtkrsK/M=; b=PBXmKZulX9piG380hxVjdKm6/Pvor6HPaS+e/b2BtDLohb1Tqh1sDKC7Hp5pjJ2OfT oKlMV9LiVg48gOnBm4pGH8MmVoB7txKWVjvqGv67oJ5wbZb9ITi74jAc5gWgdgYXWOp8 574YK+q9uUYfDV012h5+jOt+/9WjGFxCDBK7w= 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; bh=YQeCQT4ZMzRZvfEIWFMkhYTdv42aUOnImXMAtkrsK/M=; b=mGKraQ1YtMcWCh+/wx89lzPs8BwEgmwujAsfFgdGNLom0AYo5TMtgiLnPD0JjNIEoO PXg3RhLURvgaSxySZwGePI0nw0wPNY8nkQprRaraAHtMZZrEQD7tKmOPAHYVQtIT+SeC wU0mHk/vCRRe/9mbJT1T/tDtGLdJlIK+XIeNtiL8yQZ6C04m8xz6Xr/ARBDvtuqgPtbv xzzbBTRLg0eYoMi2GRSTvwXSSqT5kZe0LNPs61S8vonWvoWAIGh8ffockt78CvUdnEoQ v1s/HFJOSmThXvdBvo1k/0vMNwtpHJ18mtbwhQZc6C7QwKt6Mmo2zk5YvzDGZBc01X0x /Ivg== X-Gm-Message-State: ALyK8tKtBOBHb14RLugBOyYxDdliujkVyjegWOzlOt6rxE5ilvxTzUjx/OUWLg1QiN/gZorg4ZM= X-Received: by 10.98.155.4 with SMTP id r4mr240015pfd.1.1465536888642; Thu, 09 Jun 2016 22:34:48 -0700 (PDT) Return-Path: Received: from localhost.localdomain (c-73-67-244-238.hsd1.or.comcast.net. [73.67.244.238]) by smtp.gmail.com with ESMTPSA id c15sm14072566pfj.65.2016.06.09.22.34.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 09 Jun 2016 22:34:48 -0700 (PDT) From: John Stultz To: lkml Cc: Jorge Ramirez-Ortiz , Dmitry Torokhov , Rob Herring , Lee Jones , Feng Chen , Wei Xu , Guodong Xu , John Stultz Subject: [PATCH 1/3] drivers: input: powerkey for HISI 65xx SoC Date: Thu, 9 Jun 2016 22:34:35 -0700 Message-Id: <1465536877-18452-2-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1465536877-18452-1-git-send-email-john.stultz@linaro.org> References: <1465536877-18452-1-git-send-email-john.stultz@linaro.org> From: Jorge Ramirez-Ortiz This driver provides a input driver for the power button on the HiSi 65xx SoC for boards like HiKey. This driver was originally by Zhiliang Xue then basically rewritten by Jorge, but preserving the original module author credits. Cc: Dmitry Torokhov Cc: Rob Herring Cc: Lee Jones Cc: Jorge Ramirez-Ortiz Cc: Feng Chen Cc: Wei Xu Cc: Guodong Xu Signed-off-by: Jorge Ramirez-Ortiz [jstultz: Reworked commit message, folded in other fixes/cleanups from Jorge, implemented some larger cleanups suggested by DmitryT] Signed-off-by: John Stultz --- v2: Major rework integrating feedback from Dmitry. v3: Dropped of_match compatible line since no longer using DT for this. drivers/input/misc/Kconfig | 9 +++ drivers/input/misc/Makefile | 1 + drivers/input/misc/hisi_powerkey.c | 149 +++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 drivers/input/misc/hisi_powerkey.c -- 1.9.1 diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 1f2337a..07aacfc 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -796,4 +796,13 @@ config INPUT_DRV2667_HAPTICS To compile this driver as a module, choose M here: the module will be called drv2667-haptics. +config HISI_POWERKEY + tristate "Hisilicon PMIC ONKEY support" + depends on ARCH_HISI || COMPILE_TEST + help + Say Y to enable support for PMIC ONKEY. + + To compile this driver as a module, choose M here: the + module will be called hisi_powerkey. + endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 0357a08..f264777 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -75,3 +75,4 @@ obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o obj-$(CONFIG_INPUT_YEALINK) += yealink.o obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o +obj-$(CONFIG_HISI_POWERKEY) += hisi_powerkey.o diff --git a/drivers/input/misc/hisi_powerkey.c b/drivers/input/misc/hisi_powerkey.c new file mode 100644 index 0000000..d3afebc --- /dev/null +++ b/drivers/input/misc/hisi_powerkey.c @@ -0,0 +1,149 @@ +/* + * Hisilicon PMIC powerkey driver + * + * Copyright (C) 2013 Hisilicon Ltd. + * Copyright (C) 2015, 2016 Linaro Ltd. + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of this + * archive for more details. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* the held interrupt will trigger after 4 seconds */ +#define MAX_HELD_TIME (4 * MSEC_PER_SEC) + + +enum id_action { ID_PRESSED, ID_RELEASED, ID_HELD, ID_LAST }; +const char *const irq_names[ID_LAST] = {"down", "up", "hold 4s"}; + +struct hi65xx_priv { + struct input_dev *input; +}; + +static irqreturn_t hi65xx_power_press_isr(int irq, void *q) +{ + struct hi65xx_priv *p = q; + + pm_wakeup_event(p->input->dev.parent, MAX_HELD_TIME); + input_report_key(p->input, KEY_POWER, 1); + input_sync(p->input); + + return IRQ_HANDLED; +} + +static irqreturn_t hi65xx_power_release_isr(int irq, void *q) +{ + struct hi65xx_priv *p = q; + + pm_wakeup_event(p->input->dev.parent, MAX_HELD_TIME); + input_report_key(p->input, KEY_POWER, 0); + input_sync(p->input); + + return IRQ_HANDLED; +} + +static irqreturn_t hi65xx_restart_toggle_isr(int irq, void *q) +{ + struct hi65xx_priv *p = q; + int value = test_bit(KEY_RESTART, p->input->key); + + pm_wakeup_event(p->input->dev.parent, MAX_HELD_TIME); + input_report_key(p->input, KEY_RESTART, !value); + input_sync(p->input); + + return IRQ_HANDLED; +} + +irqreturn_t (*irq_handlers[ID_LAST])(int irq, void *q) = { + hi65xx_power_press_isr, + hi65xx_power_release_isr, + hi65xx_restart_toggle_isr, +}; + +static int hi65xx_powerkey_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct hi65xx_priv *priv; + int irq, i, ret; + + priv = devm_kzalloc(dev, sizeof(struct hi65xx_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->input = devm_input_allocate_device(&pdev->dev); + if (!priv->input) { + dev_err(&pdev->dev, "failed to allocate input device\n"); + return -ENOMEM; + } + + priv->input->phys = "hisi_on/input0"; + priv->input->name = "HISI 65xx PowerOn Key"; + + input_set_capability(priv->input, EV_KEY, KEY_POWER); + input_set_capability(priv->input, EV_KEY, KEY_RESTART); + + for (i = 0; i < ID_LAST; i++) { + + irq = platform_get_irq_byname(pdev, irq_names[i]); + if (irq < 0) { + dev_err(dev, "couldn't get irq %s\n", irq_names[i]); + return irq; + } + + ret = devm_request_any_context_irq(dev, irq, + irq_handlers[i], IRQF_ONESHOT, + irq_names[i], priv); + if (ret < 0) { + dev_err(dev, "couldn't get irq %s\n", irq_names[i]); + return ret; + } + } + + ret = input_register_device(priv->input); + if (ret) { + dev_err(&pdev->dev, "failed to register input device: %d\n", + ret); + return ret; + } + + platform_set_drvdata(pdev, priv); + device_init_wakeup(&pdev->dev, 1); + + return 0; +} + +static int hi65xx_powerkey_remove(struct platform_device *pdev) +{ + device_init_wakeup(&pdev->dev, 0); + return 0; +} + +MODULE_DEVICE_TABLE(of, hi65xx_powerkey_of_match); + +static struct platform_driver hi65xx_powerkey_driver = { + .driver = { + .name = "hi65xx-powerkey", + }, + .probe = hi65xx_powerkey_probe, + .remove = hi65xx_powerkey_remove, +}; + +module_platform_driver(hi65xx_powerkey_driver); + +MODULE_AUTHOR("Zhiliang Xue