// SPDX-License-Identifier: GPL-2.0
// Copyright (C) STMicroelectronics 2018
// Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.

#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/mfd/stpmic1.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>

/**
 * struct stpmic1_onkey - OnKey data
 * @input_dev:		pointer to input device
 * @irq_falling:	irq that we are hooked on to
 * @irq_rising:		irq that we are hooked on to
 */
struct stpmic1_onkey {
	struct input_dev *input_dev;
	int irq_falling;
	int irq_rising;
};

static irqreturn_t onkey_falling_irq(int irq, void *ponkey)
{
	struct stpmic1_onkey *onkey = ponkey;
	struct input_dev *input_dev = onkey->input_dev;

	input_report_key(input_dev, KEY_POWER, 1);
	pm_wakeup_event(input_dev->dev.parent, 0);
	input_sync(input_dev);

	return IRQ_HANDLED;
}

static irqreturn_t onkey_rising_irq(int irq, void *ponkey)
{
	struct stpmic1_onkey *onkey = ponkey;
	struct input_dev *input_dev = onkey->input_dev;

	input_report_key(input_dev, KEY_POWER, 0);
	pm_wakeup_event(input_dev->dev.parent, 0);
	input_sync(input_dev);

	return IRQ_HANDLED;
}

static int stpmic1_onkey_probe(struct platform_device *pdev)
{
	struct stpmic1 *pmic = dev_get_drvdata(pdev->dev.parent);
	struct device *dev = &pdev->dev;
	struct input_dev *input_dev;
	struct stpmic1_onkey *onkey;
	unsigned int val, reg = 0;
	int error;

	onkey = devm_kzalloc(dev, sizeof(*onkey), GFP_KERNEL);
	if (!onkey)
		return -ENOMEM;

	onkey->irq_falling = platform_get_irq_byname(pdev, "onkey-falling");
	if (onkey->irq_falling < 0) {
		dev_err(dev, "failed: request IRQ onkey-falling %d\n",
			onkey->irq_falling);
		return onkey->irq_falling;
	}

	onkey->irq_rising = platform_get_irq_byname(pdev, "onkey-rising");
	if (onkey->irq_rising < 0) {
		dev_err(dev, "failed: request IRQ onkey-rising %d\n",
			onkey->irq_rising);
		return onkey->irq_rising;
	}

	if (!device_property_read_u32(dev, "power-off-time-sec", &val)) {
		if (val > 0 && val <= 16) {
			dev_dbg(dev, "power-off-time=%d seconds\n", val);
			reg |= PONKEY_PWR_OFF;
			reg |= ((16 - val) & PONKEY_TURNOFF_TIMER_MASK);
		} else {
			dev_err(dev, "power-off-time-sec out of range\n");
			return -EINVAL;
		}
	}

	if (device_property_present(dev, "st,onkey-clear-cc-flag"))
		reg |= PONKEY_CC_FLAG_CLEAR;

	error = regmap_update_bits(pmic->regmap, PKEY_TURNOFF_CR,
				   PONKEY_TURNOFF_MASK, reg);
	if (error) {
		dev_err(dev, "PKEY_TURNOFF_CR write failed: %d\n", error);
		return error;
	}

	if (device_property_present(dev, "st,onkey-pu-inactive")) {
		error = regmap_update_bits(pmic->regmap, PADS_PULL_CR,
					   PONKEY_PU_INACTIVE,
					   PONKEY_PU_INACTIVE);
		if (error) {
			dev_err(dev, "ONKEY Pads configuration failed: %d\n",
				error);
			return error;
		}
	}

	input_dev = devm_input_allocate_device(dev);
	if (!input_dev) {
		dev_err(dev, "Can't allocate Pwr Onkey Input Device\n");
		return -ENOMEM;
	}

	input_dev->name = "pmic_onkey";
	input_dev->phys = "pmic_onkey/input0";

	input_set_capability(input_dev, EV_KEY, KEY_POWER);

	onkey->input_dev = input_dev;

	/* interrupt is nested in a thread */
	error = devm_request_threaded_irq(dev, onkey->irq_falling, NULL,
					  onkey_falling_irq, IRQF_ONESHOT,
					  dev_name(dev), onkey);
	if (error) {
		dev_err(dev, "Can't get IRQ Onkey Falling: %d\n", error);
		return error;
	}

	error = devm_request_threaded_irq(dev, onkey->irq_rising, NULL,
					  onkey_rising_irq, IRQF_ONESHOT,
					  dev_name(dev), onkey);
	if (error) {
		dev_err(dev, "Can't get IRQ Onkey Rising: %d\n", error);
		return error;
	}

	error = input_register_device(input_dev);
	if (error) {
		dev_err(dev, "Can't register power button: %d\n", error);
		return error;
	}

	platform_set_drvdata(pdev, onkey);
	device_init_wakeup(dev, true);

	return 0;
}

static int __maybe_unused stpmic1_onkey_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);

	if (device_may_wakeup(dev)) {
		enable_irq_wake(onkey->irq_falling);
		enable_irq_wake(onkey->irq_rising);
	}
	return 0;
}

static int __maybe_unused stpmic1_onkey_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);

	if (device_may_wakeup(dev)) {
		disable_irq_wake(onkey->irq_falling);
		disable_irq_wake(onkey->irq_rising);
	}
	return 0;
}

static SIMPLE_DEV_PM_OPS(stpmic1_onkey_pm,
			 stpmic1_onkey_suspend,
			 stpmic1_onkey_resume);

static const struct of_device_id of_stpmic1_onkey_match[] = {
	{ .compatible = "st,stpmic1-onkey" },
	{ },
};

MODULE_DEVICE_TABLE(of, of_stpmic1_onkey_match);

static struct platform_driver stpmic1_onkey_driver = {
	.probe	= stpmic1_onkey_probe,
	.driver	= {
		.name	= "stpmic1_onkey",
		.of_match_table = of_match_ptr(of_stpmic1_onkey_match),
		.pm	= &stpmic1_onkey_pm,
	},
};
module_platform_driver(stpmic1_onkey_driver);

MODULE_DESCRIPTION("Onkey driver for STPMIC1");
MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
MODULE_LICENSE("GPL v2");
