From patchwork Fri Jun 3 22:11:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 69303 Delivered-To: patches@linaro.org Received: by 10.140.106.246 with SMTP id e109csp477153qgf; Fri, 3 Jun 2016 15:11:40 -0700 (PDT) X-Received: by 10.98.86.151 with SMTP id h23mr8698855pfj.16.1464991894630; Fri, 03 Jun 2016 15:11:34 -0700 (PDT) Return-Path: Received: from mail-pf0-x22f.google.com (mail-pf0-x22f.google.com. [2607:f8b0:400e:c00::22f]) by mx.google.com with ESMTPS id hr2si8130893pac.234.2016.06.03.15.11.34 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Jun 2016 15:11:34 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:400e:c00::22f as permitted sender) client-ip=2607:f8b0:400e:c00::22f; 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::22f as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: by mail-pf0-x22f.google.com with SMTP id g64so47602767pfb.2 for ; Fri, 03 Jun 2016 15:11:34 -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=NQv5q0LePZKXITy73crkxv/tqd/7fsqJ+AZLnAKWmHs=; b=cnD1BNfoW/f/okgMny/dPL/IJjp74PF7H+feAr9V/zg4qFGWb69s4PEioJSOAeEMXX cXYUL6i+gxFwKuWb8UiJVZfeufQ6+Rm800qQh08RUtlNptEN774j+thbO3O/AYhs6dVB BnM677PShyetqOrLzrQp6naCuXdzrj/vxAFFE= 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=NQv5q0LePZKXITy73crkxv/tqd/7fsqJ+AZLnAKWmHs=; b=c7igCHUBLXeVxNZtUJIgLEFBAbzPirLCPo+7tKYzPj550nq15JJnQT8dyh19L9lpdv YE+/Ved4zN48svfcQajZezFeeOqp0YWjTV/JMcSliUAv3J9P/XvkQjZKHmDHBVnRyeza 2UqfAqtBR0c85WaRdJD4L0YB2SEKq6/4PDjsAewEGxb/yAuwkZGAV8ty9IozXMevEH5e 04kPUWPUTfewuov65wKesAIZORnLwlrkviJxJT0tv8Gb+VnvWkvO2ElfzZPNZ7Ary1pt oO7BzJLqjx2Tem0goIfsovI4Pxo4eODG6DqTXW98nQdP8qls9vEgk1GqRs5nUIERPbPo ZDkw== X-Gm-Message-State: ALyK8tKbOAM6XBPQK9OYjabw0XYH95ClVmFFO1cDbcQ8Vwhl1pvgOXLSiHRMb9N0nu+DMkYcUMs= X-Received: by 10.98.2.74 with SMTP id 71mr8554226pfc.49.1464991894271; Fri, 03 Jun 2016 15:11:34 -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 d184sm10596841pfc.56.2016.06.03.15.11.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 03 Jun 2016 15:11:33 -0700 (PDT) From: John Stultz To: lkml Cc: Jorge Ramirez-Ortiz , Dmitry Torokhov , Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , Lee Jones , Wei Xu , Guodong Xu , John Stultz Subject: [PATCH 4/5] drivers: input: powerkey for HISI 65xx SoC Date: Fri, 3 Jun 2016 15:11:25 -0700 Message-Id: <1464991886-632-5-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1464991886-632-1-git-send-email-john.stultz@linaro.org> References: <1464991886-632-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: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: Lee Jones Cc: Jorge Ramirez-Ortiz 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 --- drivers/input/misc/Kconfig | 9 +++ drivers/input/misc/Makefile | 1 + drivers/input/misc/hisi_powerkey.c | 155 +++++++++++++++++++++++++++++++++++++ 3 files changed, 165 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..270b881 --- /dev/null +++ b/drivers/input/misc/hisi_powerkey.c @@ -0,0 +1,155 @@ +/* + * 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 const struct of_device_id hi65xx_powerkey_of_match[] = { + { .compatible = "hisilicon,hi6552-powerkey", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, hi65xx_powerkey_of_match); + +static struct platform_driver hi65xx_powerkey_driver = { + .driver = { + .name = "hi65xx-powerkey", + .of_match_table = of_match_ptr(hi65xx_powerkey_of_match), + }, + .probe = hi65xx_powerkey_probe, + .remove = hi65xx_powerkey_remove, +}; + +module_platform_driver(hi65xx_powerkey_driver); + +MODULE_AUTHOR("Zhiliang Xue