From patchwork Tue Jun 14 22:43:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 70060 Delivered-To: patches@linaro.org Received: by 10.140.106.246 with SMTP id e109csp2280637qgf; Tue, 14 Jun 2016 15:43:37 -0700 (PDT) X-Received: by 10.66.196.203 with SMTP id io11mr2068367pac.107.1465944217077; Tue, 14 Jun 2016 15:43:37 -0700 (PDT) Return-Path: Received: from mail-pf0-x233.google.com (mail-pf0-x233.google.com. [2607:f8b0:400e:c00::233]) by mx.google.com with ESMTPS id ue10si26584861pac.220.2016.06.14.15.43.36 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 Jun 2016 15:43:37 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:400e:c00::233 as permitted sender) client-ip=2607:f8b0:400e:c00::233; 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::233 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: by mail-pf0-x233.google.com with SMTP id c2so1782773pfa.2 for ; Tue, 14 Jun 2016 15:43:36 -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=05qD130eCwIQS7jwGuopsNyzFyGuyxsWZxMLtdXUrQ4=; b=NLaK05xKq/GTHuCJ86d7lp9A3XGcVPpF+O4ZiezNsoCOkCBtNudBZPeG6psSPC6z0o HJ+ahN3k4F0ieZnkJwZ1fop6d6zTwDmGiDAPZ8jhYD8xbA9fy1EOV2r8PgEwioPWuG8K Yr6vae7P9Xk4TbIKJs9UlXVriMhHG9g9BueaA= 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=05qD130eCwIQS7jwGuopsNyzFyGuyxsWZxMLtdXUrQ4=; b=Puz4k2OOZK8kB40E5M2BPTTv8yZzicZqZCZjbrSf+xh57NbKjrfiVNVkdDEKr0QyXt gAUMeG/dhkTrqaHT4WT+ZrwtG0lesmIOji5FqH0Rx1qHrXMAmNr+xVzTS8YapSATkiCn vHm6l6xKVijT7Wv+FGAmRbjpMd/x6JyAT3yf73oxWCBiulCNyTH6tl13SUEQIboHYjm2 ZBsFh3jtwFq8xEx+1guLnXJeoPlB7JnfMDRaR51aMY42lM6m8g2gAkt79hWKJ+39GooY hYuymvFa5e1DFFuECSeo5asRwKTgGmLk0zqrIbjSyLbJ+IZ51X9dSC6J82xioNeasy6C a9ig== X-Gm-Message-State: ALyK8tIvyzIeBkFEk1xQsAuPSXEei+wA4BIE9ZVPYiAPjq+ESk+s7jy/EQOopWCBDH1EhcnR8Lo= X-Received: by 10.98.34.15 with SMTP id i15mr22022pfi.29.1465944216684; Tue, 14 Jun 2016 15:43:36 -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 q88sm47789676pfj.4.2016.06.14.15.43.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 14 Jun 2016 15:43:35 -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/4] drivers: input: powerkey for HISI 65xx SoC Date: Tue, 14 Jun 2016 15:43:29 -0700 Message-Id: <1465944212-17079-2-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1465944212-17079-1-git-send-email-john.stultz@linaro.org> References: <1465944212-17079-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. v4: Removed MODULE_DEVICE_TABLE(of, hi65xx_powerkey_of_match) line I missed in the last revision, which casued build issues w/ modules. drivers/input/misc/Kconfig | 9 +++ drivers/input/misc/Makefile | 1 + drivers/input/misc/hisi_powerkey.c | 147 +++++++++++++++++++++++++++++++++++++ 3 files changed, 157 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..e5ab5d8 --- /dev/null +++ b/drivers/input/misc/hisi_powerkey.c @@ -0,0 +1,147 @@ +/* + * 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; +} + +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