Thread (14 messages) 14 messages, 4 authors, 2015-06-09

RE: [RESEND PATCH V4 1/3] input: misc: da9063: OnKey driver

From: Opensource [Steve Twiss] <hidden>
Date: 2015-06-01 14:02:24
Also in: linux-devicetree, lkml

On 27 May 2015 16:38, Steve Twiss wrote: 
On 19 May 2015 11:33, S Twiss wrote:
quoted
To: Dmitry Torokhov
Subject: [RESEND PATCH V4 1/3] input: misc: da9063: OnKey driver

From: Steve Twiss <redacted>
Add OnKey driver support for DA9063
Signed-off-by: Steve Twiss <redacted>

---
The changes made here have been taken from the DA9062 OnKey review
thread.

Please see https://lkml.org/lkml/2015/4/29/406 for more information on this.

Version History

Changes in V4
 - No change
Hi Dmitry,

Could I please ask: is this OnKey driver suitable? Or are there still comments
pending for it? If there are any outstanding issues with this OnKey driver
then could you please let me know so I can resolve them?
Hi again Dmitry,

The date of your original review was 17th April and it is now been 6 weeks since
I sent my replies. If there is a problem with the DA9063 onkey driver as it stands,
please can you let me know quickly?

The core and device tree parts of this driver patch have already been applied.
LKML: https://lkml.org/lkml/2015/5/26/350 
LKML: https://lkml.org/lkml/2015/5/26/352

Regards,
Steve

CC: Jiri Kosina <redacted>
Thanks,
Regards,
Steve
quoted
Changes in V3
 - Move the MFD code changes into a separate patch [PATCH V3 3/3]
 - Rename OnKey driver to use underscore: da9063_onkey.c
 - Header and MODULE_LICENSE macro update for GPL and filename
change
quoted
 - Remove MAINTAINERS file (no longer needed due to rename of onkey
driver)
 - Delete input_unregister_device call from platform driver remove
function
quoted
 - Replaced dev_notice() with dev_dbg() for key press notification

Changes in V2
 - Remove the circular dependency comment in the main e-mail body
   linking PATCH V1 1/2 and 2/2
 - Alter the copyright header information to match expected GPLv2
   text from http://www.gnu.org/licenses/gpl-2.0.html

This patch applies against linux-next and v4.1-rc3


 drivers/input/misc/Kconfig        |  10 ++
 drivers/input/misc/Makefile       |   1 +
 drivers/input/misc/da9063_onkey.c | 227
++++++++++++++++++++++++++++++++++++++
 3 files changed, 238 insertions(+)
 create mode 100644 drivers/input/misc/da9063_onkey.c
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 4436ab1..d917883 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -610,6 +610,16 @@ config INPUT_DA9055_ONKEY
 	  To compile this driver as a module, choose M here: the module
 	  will be called da9055_onkey.

+config INPUT_DA9063_ONKEY
+	tristate "Dialog DA9063 OnKey"
+	depends on MFD_DA9063
+	help
+	  Support the ONKEY of Dialog DA9063 Power Management IC as an
+	  input device reporting power button statue.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called da9063-onkey.
+
 config INPUT_DM355EVM
 	tristate "TI DaVinci DM355 EVM Keypad and IR Remote"
 	depends on MFD_DM355EVM_MSP
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 78ba4c1..4f95c56 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_INPUT_CMA3000_I2C)		+=
cma3000_d0x_i2c.o
 obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
 obj-$(CONFIG_INPUT_DA9052_ONKEY)	+= da9052_onkey.o
 obj-$(CONFIG_INPUT_DA9055_ONKEY)	+= da9055_onkey.o
+obj-$(CONFIG_INPUT_DA9063_ONKEY)	+= da9063_onkey.o
 obj-$(CONFIG_INPUT_DM355EVM)		+= dm355evm_keys.o
 obj-$(CONFIG_INPUT_E3X0_BUTTON)		+= e3x0-button.o
 obj-$(CONFIG_INPUT_DRV260X_HAPTICS)	+= drv260x.o
diff --git a/drivers/input/misc/da9063_onkey.c
b/drivers/input/misc/da9063_onkey.c
new file mode 100644
index 0000000..250595c
--- /dev/null
+++ b/drivers/input/misc/da9063_onkey.c
@@ -0,0 +1,227 @@
+/*
+ * da9063_onkey.c - Onkey device driver for DA9063
+ * Copyright (C) 2015  Dialog Semiconductor Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 <linux/module.h>
+#include <linux/errno.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/mfd/da9063/core.h>
+#include <linux/mfd/da9063/pdata.h>
+#include <linux/mfd/da9063/registers.h>
+
+struct da9063_onkey {
+	struct	da9063 *hw;
+	struct delayed_work work;
+	struct	input_dev *input;
+	int irq;
+	bool key_power;
+};
+
+static void da9063_poll_on(struct work_struct *work)
+{
+	struct da9063_onkey *onkey = container_of(work, struct
da9063_onkey,
+						  work.work);
+	unsigned int val;
+	int fault_log = 0;
+	bool poll = true;
+	int ret;
+
+	/* poll to see when the pin is released */
+	ret = regmap_read(onkey->hw->regmap, DA9063_REG_STATUS_A,
&val);
+	if (ret < 0) {
+		dev_err(&onkey->input->dev,
+			"Failed to read ON status: %d\n", ret);
+		goto err_poll;
+	}
+
+	if (!(val & DA9063_NONKEY)) {
+		ret = regmap_update_bits(onkey->hw->regmap,
+					 DA9063_REG_CONTROL_B,
+					 DA9063_NONKEY_LOCK, 0);
+		if (ret < 0) {
+			dev_err(&onkey->input->dev,
+				"Failed to reset the Key Delay %d\n", ret);
+			goto err_poll;
+		}
+
+		input_report_key(onkey->input, KEY_POWER, 0);
+		input_sync(onkey->input);
+
+		poll = false;
+	}
+
+	/* if the fault log KEY_RESET is detected,
+	 * then clear it and shutdown via I2C
+	 */
+	ret = regmap_read(onkey->hw->regmap, DA9063_REG_FAULT_LOG,
&fault_log);
+	if (ret < 0)
+		dev_warn(&onkey->input->dev, "Cannot read
FAULT_LOG\n");
+
+	if (fault_log & DA9063_KEY_RESET) {
+		ret = regmap_write(onkey->hw->regmap,
+				   DA9063_REG_FAULT_LOG,
+				   DA9063_KEY_RESET);
+		if (ret < 0)
+			dev_warn(&onkey->input->dev,
+				 "Cannot reset KEY_RESET fault log\n");
+		else {
+			/* at this point we do any S/W housekeeping
+			 * and then send shutdown command
+			 */
+			dev_dbg(&onkey->input->dev,
+				 "Sending SHUTDOWN to DA9063 ...\n");
+			ret = regmap_write(onkey->hw->regmap,
+					   DA9063_REG_CONTROL_F,
+					   DA9063_SHUTDOWN);
+			if (ret < 0)
+				dev_err(&onkey->input->dev,
+					"Cannot SHUTDOWN DA9063\n");
+		}
+	}
+
+err_poll:
+	if (poll)
+		schedule_delayed_work(&onkey->work, 50);
+}
+
+static irqreturn_t da9063_onkey_irq_handler(int irq, void *data)
+{
+	struct da9063_onkey *onkey = data;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(onkey->hw->regmap, DA9063_REG_STATUS_A,
&val);
+	if (onkey->key_power && (ret >= 0) && (val & DA9063_NONKEY)) {
+		input_report_key(onkey->input, KEY_POWER, 1);
+		input_sync(onkey->input);
+		schedule_delayed_work(&onkey->work, 0);
+		dev_dbg(&onkey->input->dev, "KEY_POWER pressed.\n");
+	} else {
+		input_report_key(onkey->input, KEY_SLEEP, 1);
+		input_sync(onkey->input);
+		input_report_key(onkey->input, KEY_SLEEP, 0);
+		input_sync(onkey->input);
+		dev_dbg(&onkey->input->dev, "KEY_SLEEP pressed.\n");
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int da9063_onkey_probe(struct platform_device *pdev)
+{
+	struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent);
+	struct da9063_pdata *pdata = dev_get_platdata(da9063->dev);
+	struct da9063_onkey *onkey;
+	bool kp_tmp = true;
+	int ret = 0;
+
+	if (pdata)
+		kp_tmp = pdata->key_power;
+	else {
+		kp_tmp = of_property_read_bool((&pdev->dev)->of_node,
+					       "dlg,disable-key-power");
+		kp_tmp = !kp_tmp;
+	}
+
+	onkey = devm_kzalloc(&pdev->dev, sizeof(struct da9063_onkey),
+			     GFP_KERNEL);
+	if (!onkey) {
+		dev_err(&pdev->dev, "Failed to allocate memory.\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	INIT_DELAYED_WORK(&onkey->work, da9063_poll_on);
+
+	onkey->input = devm_input_allocate_device(&pdev->dev);
+	if (!onkey->input) {
+		dev_err(&pdev->dev, "Failed to allocated input device.\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = platform_get_irq_byname(pdev, "ONKEY");
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to get platform IRQ.\n");
+		goto err;
+	}
+	onkey->irq = ret;
+
+	ret = request_threaded_irq(onkey->irq, NULL,
+				   da9063_onkey_irq_handler,
+				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+				   "ONKEY", onkey);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to request input device IRQ.\n");
+		goto err;
+	}
+
+	onkey->hw = da9063;
+	onkey->key_power = kp_tmp;
+	onkey->input->evbit[0] = BIT_MASK(EV_KEY);
+	onkey->input->name = DA9063_DRVNAME_ONKEY;
+	onkey->input->phys = DA9063_DRVNAME_ONKEY "/input0";
+	onkey->input->dev.parent = &pdev->dev;
+
+	if (onkey->key_power)
+		input_set_capability(onkey->input, EV_KEY, KEY_POWER);
+	input_set_capability(onkey->input, EV_KEY, KEY_SLEEP);
+
+	ret = input_register_device(onkey->input);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to register input device.\n");
+		goto err_irq;
+	}
+
+	platform_set_drvdata(pdev, onkey);
+	return 0;
+
+err_irq:
+	free_irq(onkey->irq, onkey);
+	cancel_delayed_work_sync(&onkey->work);
+err:
+	return ret;
+}
+
+static int da9063_onkey_remove(struct platform_device *pdev)
+{
+	struct	da9063_onkey *onkey = platform_get_drvdata(pdev);
+
+	free_irq(onkey->irq, onkey);
+	cancel_delayed_work_sync(&onkey->work);
+	return 0;
+}
+
+static struct platform_driver da9063_onkey_driver = {
+	.probe	= da9063_onkey_probe,
+	.remove	= da9063_onkey_remove,
+	.driver	= {
+		.name	= DA9063_DRVNAME_ONKEY,
+		.owner	= THIS_MODULE,
+	},
+};
+
+module_platform_driver(da9063_onkey_driver);
+
+MODULE_AUTHOR("S Twiss [off-list ref]");
+MODULE_DESCRIPTION("Onkey device driver for Dialog DA9063");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DA9063_DRVNAME_ONKEY);
--
end-of-patch for RESEND PATCH V4
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help