// SPDX-License-Identifier: GPL-2.0
/*
 * Power button driver for Intel MID platforms.
 *
 * Copyright (C) 2010,2017 Intel Corp
 *
 * Author: Hong Liu <hong.liu@intel.com>
 * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 */

#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/mfd/intel_msic.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_wakeirq.h>
#include <linux/slab.h>

#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <asm/intel_scu_ipc.h>

#define DRIVER_NAME "msic_power_btn"

#define MSIC_PB_LEVEL	(1 << 3) /* 1 - release, 0 - press */

/*
 * MSIC document ti_datasheet defines the 1st bit reg 0x21 is used to mask
 * power button interrupt
 */
#define MSIC_PWRBTNM    (1 << 0)

/* Intel Tangier */
#define BCOVE_PB_LEVEL		(1 << 4)	/* 1 - release, 0 - press */

/* Basin Cove PMIC */
#define BCOVE_PBIRQ		0x02
#define BCOVE_IRQLVL1MSK	0x0c
#define BCOVE_PBIRQMASK		0x0d
#define BCOVE_PBSTATUS		0x27

struct mid_pb_ddata {
	struct device *dev;
	int irq;
	struct input_dev *input;
	unsigned short mirqlvl1_addr;
	unsigned short pbstat_addr;
	u8 pbstat_mask;
	struct intel_scu_ipc_dev *scu;
	int (*setup)(struct mid_pb_ddata *ddata);
};

static int mid_pbstat(struct mid_pb_ddata *ddata, int *value)
{
	struct input_dev *input = ddata->input;
	int ret;
	u8 pbstat;

	ret = intel_scu_ipc_dev_ioread8(ddata->scu, ddata->pbstat_addr,
					&pbstat);
	if (ret)
		return ret;

	dev_dbg(input->dev.parent, "PB_INT status= %d\n", pbstat);

	*value = !(pbstat & ddata->pbstat_mask);
	return 0;
}

static int mid_irq_ack(struct mid_pb_ddata *ddata)
{
	return intel_scu_ipc_dev_update(ddata->scu, ddata->mirqlvl1_addr, 0,
					MSIC_PWRBTNM);
}

static int mrfld_setup(struct mid_pb_ddata *ddata)
{
	/* Unmask the PBIRQ and MPBIRQ on Tangier */
	intel_scu_ipc_dev_update(ddata->scu, BCOVE_PBIRQ, 0, MSIC_PWRBTNM);
	intel_scu_ipc_dev_update(ddata->scu, BCOVE_PBIRQMASK, 0, MSIC_PWRBTNM);

	return 0;
}

static irqreturn_t mid_pb_isr(int irq, void *dev_id)
{
	struct mid_pb_ddata *ddata = dev_id;
	struct input_dev *input = ddata->input;
	int value = 0;
	int ret;

	ret = mid_pbstat(ddata, &value);
	if (ret < 0) {
		dev_err(input->dev.parent,
			"Read error %d while reading MSIC_PB_STATUS\n", ret);
	} else {
		input_event(input, EV_KEY, KEY_POWER, value);
		input_sync(input);
	}

	mid_irq_ack(ddata);
	return IRQ_HANDLED;
}

static const struct mid_pb_ddata mfld_ddata = {
	.mirqlvl1_addr	= INTEL_MSIC_IRQLVL1MSK,
	.pbstat_addr	= INTEL_MSIC_PBSTATUS,
	.pbstat_mask	= MSIC_PB_LEVEL,
};

static const struct mid_pb_ddata mrfld_ddata = {
	.mirqlvl1_addr	= BCOVE_IRQLVL1MSK,
	.pbstat_addr	= BCOVE_PBSTATUS,
	.pbstat_mask	= BCOVE_PB_LEVEL,
	.setup	= mrfld_setup,
};

static const struct x86_cpu_id mid_pb_cpu_ids[] = {
	X86_MATCH_INTEL_FAM6_MODEL(ATOM_SALTWELL_MID,	&mfld_ddata),
	X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID,	&mrfld_ddata),
	{}
};

static int mid_pb_probe(struct platform_device *pdev)
{
	const struct x86_cpu_id *id;
	struct mid_pb_ddata *ddata;
	struct input_dev *input;
	int irq = platform_get_irq(pdev, 0);
	int error;

	id = x86_match_cpu(mid_pb_cpu_ids);
	if (!id)
		return -ENODEV;

	if (irq < 0) {
		dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq);
		return irq;
	}

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

	input->name = pdev->name;
	input->phys = "power-button/input0";
	input->id.bustype = BUS_HOST;
	input->dev.parent = &pdev->dev;

	input_set_capability(input, EV_KEY, KEY_POWER);

	ddata = devm_kmemdup(&pdev->dev, (void *)id->driver_data,
			     sizeof(*ddata), GFP_KERNEL);
	if (!ddata)
		return -ENOMEM;

	ddata->dev = &pdev->dev;
	ddata->irq = irq;
	ddata->input = input;

	if (ddata->setup) {
		error = ddata->setup(ddata);
		if (error)
			return error;
	}

	ddata->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
	if (!ddata->scu)
		return -EPROBE_DEFER;

	error = devm_request_threaded_irq(&pdev->dev, irq, NULL, mid_pb_isr,
					  IRQF_ONESHOT, DRIVER_NAME, ddata);
	if (error) {
		dev_err(&pdev->dev,
			"Unable to request irq %d for MID power button\n", irq);
		return error;
	}

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

	platform_set_drvdata(pdev, ddata);

	/*
	 * SCU firmware might send power button interrupts to IA core before
	 * kernel boots and doesn't get EOI from IA core. The first bit of
	 * MSIC reg 0x21 is kept masked, and SCU firmware doesn't send new
	 * power interrupt to Android kernel. Unmask the bit when probing
	 * power button in kernel.
	 * There is a very narrow race between irq handler and power button
	 * initialization. The race happens rarely. So we needn't worry
	 * about it.
	 */
	error = mid_irq_ack(ddata);
	if (error) {
		dev_err(&pdev->dev,
			"Unable to clear power button interrupt, error: %d\n",
			error);
		return error;
	}

	device_init_wakeup(&pdev->dev, true);
	dev_pm_set_wake_irq(&pdev->dev, irq);

	return 0;
}

static int mid_pb_remove(struct platform_device *pdev)
{
	dev_pm_clear_wake_irq(&pdev->dev);
	device_init_wakeup(&pdev->dev, false);

	return 0;
}

static struct platform_driver mid_pb_driver = {
	.driver = {
		.name = DRIVER_NAME,
	},
	.probe	= mid_pb_probe,
	.remove	= mid_pb_remove,
};

module_platform_driver(mid_pb_driver);

MODULE_AUTHOR("Hong Liu <hong.liu@intel.com>");
MODULE_DESCRIPTION("Intel MID Power Button Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRIVER_NAME);
