/*
 * Power key driver for SiRF PrimaII
 *
 * Copyright (c) 2013 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
 * company.
 *
 * Licensed under GPLv2 or later.
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/rtc/sirfsoc_rtciobrg.h>
#include <linux/of.h>
#include <linux/workqueue.h>

struct sirfsoc_pwrc_drvdata {
	u32			pwrc_base;
	struct input_dev	*input;
	struct delayed_work	work;
};

#define PWRC_ON_KEY_BIT			(1 << 0)

#define PWRC_INT_STATUS			0xc
#define PWRC_INT_MASK			0x10
#define PWRC_PIN_STATUS			0x14
#define PWRC_KEY_DETECT_UP_TIME		20	/* ms*/

static int sirfsoc_pwrc_is_on_key_down(struct sirfsoc_pwrc_drvdata *pwrcdrv)
{
	u32 state = sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base +
							PWRC_PIN_STATUS);
	return !(state & PWRC_ON_KEY_BIT); /* ON_KEY is active low */
}

static void sirfsoc_pwrc_report_event(struct work_struct *work)
{
	struct sirfsoc_pwrc_drvdata *pwrcdrv =
		container_of(work, struct sirfsoc_pwrc_drvdata, work.work);

	if (sirfsoc_pwrc_is_on_key_down(pwrcdrv)) {
		schedule_delayed_work(&pwrcdrv->work,
			msecs_to_jiffies(PWRC_KEY_DETECT_UP_TIME));
	} else {
		input_event(pwrcdrv->input, EV_KEY, KEY_POWER, 0);
		input_sync(pwrcdrv->input);
	}
}

static irqreturn_t sirfsoc_pwrc_isr(int irq, void *dev_id)
{
	struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_id;
	u32 int_status;

	int_status = sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base +
							PWRC_INT_STATUS);
	sirfsoc_rtc_iobrg_writel(int_status & ~PWRC_ON_KEY_BIT,
				 pwrcdrv->pwrc_base + PWRC_INT_STATUS);

	input_event(pwrcdrv->input, EV_KEY, KEY_POWER, 1);
	input_sync(pwrcdrv->input);
	schedule_delayed_work(&pwrcdrv->work,
			      msecs_to_jiffies(PWRC_KEY_DETECT_UP_TIME));

	return IRQ_HANDLED;
}

static void sirfsoc_pwrc_toggle_interrupts(struct sirfsoc_pwrc_drvdata *pwrcdrv,
					   bool enable)
{
	u32 int_mask;

	int_mask = sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base + PWRC_INT_MASK);
	if (enable)
		int_mask |= PWRC_ON_KEY_BIT;
	else
		int_mask &= ~PWRC_ON_KEY_BIT;
	sirfsoc_rtc_iobrg_writel(int_mask, pwrcdrv->pwrc_base + PWRC_INT_MASK);
}

static int sirfsoc_pwrc_open(struct input_dev *input)
{
	struct sirfsoc_pwrc_drvdata *pwrcdrv = input_get_drvdata(input);

	sirfsoc_pwrc_toggle_interrupts(pwrcdrv, true);

	return 0;
}

static void sirfsoc_pwrc_close(struct input_dev *input)
{
	struct sirfsoc_pwrc_drvdata *pwrcdrv = input_get_drvdata(input);

	sirfsoc_pwrc_toggle_interrupts(pwrcdrv, false);
	cancel_delayed_work_sync(&pwrcdrv->work);
}

static const struct of_device_id sirfsoc_pwrc_of_match[] = {
	{ .compatible = "sirf,prima2-pwrc" },
	{},
}
MODULE_DEVICE_TABLE(of, sirfsoc_pwrc_of_match);

static int sirfsoc_pwrc_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct sirfsoc_pwrc_drvdata *pwrcdrv;
	int irq;
	int error;

	pwrcdrv = devm_kzalloc(&pdev->dev, sizeof(struct sirfsoc_pwrc_drvdata),
			       GFP_KERNEL);
	if (!pwrcdrv) {
		dev_info(&pdev->dev, "Not enough memory for the device data\n");
		return -ENOMEM;
	}

	/*
	 * We can't use of_iomap because pwrc is not mapped in memory,
	 * the so-called base address is only offset in rtciobrg
	 */
	error = of_property_read_u32(np, "reg", &pwrcdrv->pwrc_base);
	if (error) {
		dev_err(&pdev->dev,
			"unable to find base address of pwrc node in dtb\n");
		return error;
	}

	pwrcdrv->input = devm_input_allocate_device(&pdev->dev);
	if (!pwrcdrv->input)
		return -ENOMEM;

	pwrcdrv->input->name = "sirfsoc pwrckey";
	pwrcdrv->input->phys = "pwrc/input0";
	pwrcdrv->input->evbit[0] = BIT_MASK(EV_KEY);
	input_set_capability(pwrcdrv->input, EV_KEY, KEY_POWER);

	INIT_DELAYED_WORK(&pwrcdrv->work, sirfsoc_pwrc_report_event);

	pwrcdrv->input->open = sirfsoc_pwrc_open;
	pwrcdrv->input->close = sirfsoc_pwrc_close;

	input_set_drvdata(pwrcdrv->input, pwrcdrv);

	/* Make sure the device is quiesced */
	sirfsoc_pwrc_toggle_interrupts(pwrcdrv, false);

	irq = platform_get_irq(pdev, 0);
	error = devm_request_irq(&pdev->dev, irq,
				 sirfsoc_pwrc_isr, 0,
				 "sirfsoc_pwrc_int", pwrcdrv);
	if (error) {
		dev_err(&pdev->dev, "unable to claim irq %d, error: %d\n",
			irq, error);
		return error;
	}

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

	dev_set_drvdata(&pdev->dev, pwrcdrv);
	device_init_wakeup(&pdev->dev, 1);

	return 0;
}

static int sirfsoc_pwrc_remove(struct platform_device *pdev)
{
	device_init_wakeup(&pdev->dev, 0);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int sirfsoc_pwrc_resume(struct device *dev)
{
	struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_get_drvdata(dev);
	struct input_dev *input = pwrcdrv->input;

	/*
	 * Do not mask pwrc interrupt as we want pwrc work as a wakeup source
	 * if users touch X_ONKEY_B, see arch/arm/mach-prima2/pm.c
	 */
	mutex_lock(&input->mutex);
	if (input->users)
		sirfsoc_pwrc_toggle_interrupts(pwrcdrv, true);
	mutex_unlock(&input->mutex);

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(sirfsoc_pwrc_pm_ops, NULL, sirfsoc_pwrc_resume);

static struct platform_driver sirfsoc_pwrc_driver = {
	.probe		= sirfsoc_pwrc_probe,
	.remove		= sirfsoc_pwrc_remove,
	.driver		= {
		.name	= "sirfsoc-pwrc",
		.owner	= THIS_MODULE,
		.pm	= &sirfsoc_pwrc_pm_ops,
		.of_match_table = sirfsoc_pwrc_of_match,
	}
};

module_platform_driver(sirfsoc_pwrc_driver);

MODULE_LICENSE("GPLv2");
MODULE_AUTHOR("Binghua Duan <Binghua.Duan@csr.com>, Xianglong Du <Xianglong.Du@csr.com>");
MODULE_DESCRIPTION("CSR Prima2 PWRC Driver");
MODULE_ALIAS("platform:sirfsoc-pwrc");
