/*
 * 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>
 *
 * 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; version 2 of the License.
 *
 * 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/init.h>
#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;
	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_ioread8(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_update_register(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_update_register(BCOVE_PBIRQ, 0, MSIC_PWRBTNM);
	intel_scu_ipc_update_register(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,
};

#define ICPU(model, ddata)	\
	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (kernel_ulong_t)&ddata }

static const struct x86_cpu_id mid_pb_cpu_ids[] = {
	ICPU(INTEL_FAM6_ATOM_SALTWELL_MID,		mfld_ddata),
	ICPU(INTEL_FAM6_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;
	}

	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);
