// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * OnKey device driver for DA9063, DA9062 and DA9061 PMICs
 * Copyright (C) 2015  Dialog Semiconductor Ltd.
 */

#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/registers.h>
#include <linux/mfd/da9062/core.h>
#include <linux/mfd/da9062/registers.h>

struct da906x_chip_config {
	/* REGS */
	int onkey_status;
	int onkey_pwr_signalling;
	int onkey_fault_log;
	int onkey_shutdown;
	/* MASKS */
	int onkey_nonkey_mask;
	int onkey_nonkey_lock_mask;
	int onkey_key_reset_mask;
	int onkey_shutdown_mask;
	/* NAMES */
	const char *name;
};

struct da9063_onkey {
	struct delayed_work work;
	struct input_dev *input;
	struct device *dev;
	struct regmap *regmap;
	const struct da906x_chip_config *config;
	char phys[32];
	bool key_power;
};

static const struct da906x_chip_config da9063_regs = {
	/* REGS */
	.onkey_status = DA9063_REG_STATUS_A,
	.onkey_pwr_signalling = DA9063_REG_CONTROL_B,
	.onkey_fault_log = DA9063_REG_FAULT_LOG,
	.onkey_shutdown = DA9063_REG_CONTROL_F,
	/* MASKS */
	.onkey_nonkey_mask = DA9063_NONKEY,
	.onkey_nonkey_lock_mask = DA9063_NONKEY_LOCK,
	.onkey_key_reset_mask = DA9063_KEY_RESET,
	.onkey_shutdown_mask = DA9063_SHUTDOWN,
	/* NAMES */
	.name = DA9063_DRVNAME_ONKEY,
};

static const struct da906x_chip_config da9062_regs = {
	/* REGS */
	.onkey_status = DA9062AA_STATUS_A,
	.onkey_pwr_signalling = DA9062AA_CONTROL_B,
	.onkey_fault_log = DA9062AA_FAULT_LOG,
	.onkey_shutdown = DA9062AA_CONTROL_F,
	/* MASKS */
	.onkey_nonkey_mask = DA9062AA_NONKEY_MASK,
	.onkey_nonkey_lock_mask = DA9062AA_NONKEY_LOCK_MASK,
	.onkey_key_reset_mask = DA9062AA_KEY_RESET_MASK,
	.onkey_shutdown_mask = DA9062AA_SHUTDOWN_MASK,
	/* NAMES */
	.name = "da9062-onkey",
};

static const struct of_device_id da9063_compatible_reg_id_table[] = {
	{ .compatible = "dlg,da9063-onkey", .data = &da9063_regs },
	{ .compatible = "dlg,da9062-onkey", .data = &da9062_regs },
	{ },
};
MODULE_DEVICE_TABLE(of, da9063_compatible_reg_id_table);

static void da9063_poll_on(struct work_struct *work)
{
	struct da9063_onkey *onkey = container_of(work,
						struct da9063_onkey,
						work.work);
	const struct da906x_chip_config *config = onkey->config;
	unsigned int val;
	int fault_log = 0;
	bool poll = true;
	int error;

	/* Poll to see when the pin is released */
	error = regmap_read(onkey->regmap,
			    config->onkey_status,
			    &val);
	if (error) {
		dev_err(onkey->dev,
			"Failed to read ON status: %d\n", error);
		goto err_poll;
	}

	if (!(val & config->onkey_nonkey_mask)) {
		error = regmap_update_bits(onkey->regmap,
					   config->onkey_pwr_signalling,
					   config->onkey_nonkey_lock_mask,
					   0);
		if (error) {
			dev_err(onkey->dev,
				"Failed to reset the Key Delay %d\n", error);
			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 shut down the system.
	 */
	error = regmap_read(onkey->regmap,
			    config->onkey_fault_log,
			    &fault_log);
	if (error) {
		dev_warn(&onkey->input->dev,
			 "Cannot read FAULT_LOG: %d\n", error);
	} else if (fault_log & config->onkey_key_reset_mask) {
		error = regmap_write(onkey->regmap,
				     config->onkey_fault_log,
				     config->onkey_key_reset_mask);
		if (error) {
			dev_warn(&onkey->input->dev,
				 "Cannot reset KEY_RESET fault log: %d\n",
				 error);
		} else {
			/* at this point we do any S/W housekeeping
			 * and then send shutdown command
			 */
			dev_dbg(&onkey->input->dev,
				"Sending SHUTDOWN to PMIC ...\n");
			error = regmap_write(onkey->regmap,
					     config->onkey_shutdown,
					     config->onkey_shutdown_mask);
			if (error)
				dev_err(&onkey->input->dev,
					"Cannot SHUTDOWN PMIC: %d\n",
					error);
		}
	}

err_poll:
	if (poll)
		schedule_delayed_work(&onkey->work, msecs_to_jiffies(50));
}

static irqreturn_t da9063_onkey_irq_handler(int irq, void *data)
{
	struct da9063_onkey *onkey = data;
	const struct da906x_chip_config *config = onkey->config;
	unsigned int val;
	int error;

	error = regmap_read(onkey->regmap,
			    config->onkey_status,
			    &val);
	if (onkey->key_power && !error && (val & config->onkey_nonkey_mask)) {
		input_report_key(onkey->input, KEY_POWER, 1);
		input_sync(onkey->input);
		schedule_delayed_work(&onkey->work, 0);
		dev_dbg(onkey->dev, "KEY_POWER long press.\n");
	} else {
		input_report_key(onkey->input, KEY_POWER, 1);
		input_sync(onkey->input);
		input_report_key(onkey->input, KEY_POWER, 0);
		input_sync(onkey->input);
		dev_dbg(onkey->dev, "KEY_POWER short press.\n");
	}

	return IRQ_HANDLED;
}

static void da9063_cancel_poll(void *data)
{
	struct da9063_onkey *onkey = data;

	cancel_delayed_work_sync(&onkey->work);
}

static int da9063_onkey_probe(struct platform_device *pdev)
{
	struct da9063_onkey *onkey;
	const struct of_device_id *match;
	int irq;
	int error;

	match = of_match_node(da9063_compatible_reg_id_table,
			      pdev->dev.of_node);
	if (!match)
		return -ENXIO;

	onkey = devm_kzalloc(&pdev->dev, sizeof(struct da9063_onkey),
			     GFP_KERNEL);
	if (!onkey) {
		dev_err(&pdev->dev, "Failed to allocate memory.\n");
		return -ENOMEM;
	}

	onkey->config = match->data;
	onkey->dev = &pdev->dev;

	onkey->regmap = dev_get_regmap(pdev->dev.parent, NULL);
	if (!onkey->regmap) {
		dev_err(&pdev->dev, "Parent regmap unavailable.\n");
		return -ENXIO;
	}

	onkey->key_power = !of_property_read_bool(pdev->dev.of_node,
						  "dlg,disable-key-power");

	onkey->input = devm_input_allocate_device(&pdev->dev);
	if (!onkey->input) {
		dev_err(&pdev->dev, "Failed to allocated input device.\n");
		return -ENOMEM;
	}

	onkey->input->name = onkey->config->name;
	snprintf(onkey->phys, sizeof(onkey->phys), "%s/input0",
		 onkey->config->name);
	onkey->input->phys = onkey->phys;
	onkey->input->dev.parent = &pdev->dev;

	input_set_capability(onkey->input, EV_KEY, KEY_POWER);

	INIT_DELAYED_WORK(&onkey->work, da9063_poll_on);

	error = devm_add_action(&pdev->dev, da9063_cancel_poll, onkey);
	if (error) {
		dev_err(&pdev->dev,
			"Failed to add cancel poll action: %d\n",
			error);
		return error;
	}

	irq = platform_get_irq_byname(pdev, "ONKEY");
	if (irq < 0)
		return irq;

	error = devm_request_threaded_irq(&pdev->dev, irq,
					  NULL, da9063_onkey_irq_handler,
					  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
					  "ONKEY", onkey);
	if (error) {
		dev_err(&pdev->dev,
			"Failed to request IRQ %d: %d\n", irq, error);
		return error;
	}

	error = input_register_device(onkey->input);
	if (error) {
		dev_err(&pdev->dev,
			"Failed to register input device: %d\n", error);
		return error;
	}

	return 0;
}

static struct platform_driver da9063_onkey_driver = {
	.probe	= da9063_onkey_probe,
	.driver	= {
		.name	= DA9063_DRVNAME_ONKEY,
		.of_match_table = da9063_compatible_reg_id_table,
	},
};
module_platform_driver(da9063_onkey_driver);

MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>");
MODULE_DESCRIPTION("Onkey device driver for Dialog DA9063, DA9062 and DA9061");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DA9063_DRVNAME_ONKEY);
