/*
 * STMicroelectronics Key Scanning driver
 *
 * Copyright (c) 2014 STMicroelectonics Ltd.
 * Author: Stuart Menefy <stuart.menefy@st.com>
 *
 * Based on sh_keysc.c, copyright 2008 Magnus Damm
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/input/matrix_keypad.h>

#define ST_KEYSCAN_MAXKEYS 16

#define KEYSCAN_CONFIG_OFF		0x0
#define KEYSCAN_CONFIG_ENABLE		0x1
#define KEYSCAN_DEBOUNCE_TIME_OFF	0x4
#define KEYSCAN_MATRIX_STATE_OFF	0x8
#define KEYSCAN_MATRIX_DIM_OFF		0xc
#define KEYSCAN_MATRIX_DIM_X_SHIFT	0x0
#define KEYSCAN_MATRIX_DIM_Y_SHIFT	0x2

struct st_keyscan {
	void __iomem *base;
	int irq;
	struct clk *clk;
	struct input_dev *input_dev;
	unsigned long last_state;
	unsigned int n_rows;
	unsigned int n_cols;
	unsigned int debounce_us;
};

static irqreturn_t keyscan_isr(int irq, void *dev_id)
{
	struct st_keyscan *keypad = dev_id;
	unsigned short *keycode = keypad->input_dev->keycode;
	unsigned long state, change;
	int bit_nr;

	state = readl(keypad->base + KEYSCAN_MATRIX_STATE_OFF) & 0xffff;
	change = keypad->last_state ^ state;
	keypad->last_state = state;

	for_each_set_bit(bit_nr, &change, BITS_PER_LONG)
		input_report_key(keypad->input_dev,
				 keycode[bit_nr], state & BIT(bit_nr));

	input_sync(keypad->input_dev);

	return IRQ_HANDLED;
}

static int keyscan_start(struct st_keyscan *keypad)
{
	int error;

	error = clk_enable(keypad->clk);
	if (error)
		return error;

	writel(keypad->debounce_us * (clk_get_rate(keypad->clk) / 1000000),
	       keypad->base + KEYSCAN_DEBOUNCE_TIME_OFF);

	writel(((keypad->n_cols - 1) << KEYSCAN_MATRIX_DIM_X_SHIFT) |
	       ((keypad->n_rows - 1) << KEYSCAN_MATRIX_DIM_Y_SHIFT),
	       keypad->base + KEYSCAN_MATRIX_DIM_OFF);

	writel(KEYSCAN_CONFIG_ENABLE, keypad->base + KEYSCAN_CONFIG_OFF);

	return 0;
}

static void keyscan_stop(struct st_keyscan *keypad)
{
	writel(0, keypad->base + KEYSCAN_CONFIG_OFF);

	clk_disable(keypad->clk);
}

static int keyscan_open(struct input_dev *dev)
{
	struct st_keyscan *keypad = input_get_drvdata(dev);

	return keyscan_start(keypad);
}

static void keyscan_close(struct input_dev *dev)
{
	struct st_keyscan *keypad = input_get_drvdata(dev);

	keyscan_stop(keypad);
}

static int keypad_matrix_key_parse_dt(struct st_keyscan *keypad_data)
{
	struct device *dev = keypad_data->input_dev->dev.parent;
	struct device_node *np = dev->of_node;
	int error;

	error = matrix_keypad_parse_of_params(dev, &keypad_data->n_rows,
					      &keypad_data->n_cols);
	if (error) {
		dev_err(dev, "failed to parse keypad params\n");
		return error;
	}

	of_property_read_u32(np, "st,debounce-us", &keypad_data->debounce_us);

	dev_dbg(dev, "n_rows=%d n_col=%d debounce=%d\n",
		keypad_data->n_rows, keypad_data->n_cols,
		keypad_data->debounce_us);

	return 0;
}

static int keyscan_probe(struct platform_device *pdev)
{
	struct st_keyscan *keypad_data;
	struct input_dev *input_dev;
	struct resource *res;
	int error;

	if (!pdev->dev.of_node) {
		dev_err(&pdev->dev, "no DT data present\n");
		return -EINVAL;
	}

	keypad_data = devm_kzalloc(&pdev->dev, sizeof(*keypad_data),
				   GFP_KERNEL);
	if (!keypad_data)
		return -ENOMEM;

	input_dev = devm_input_allocate_device(&pdev->dev);
	if (!input_dev) {
		dev_err(&pdev->dev, "failed to allocate the input device\n");
		return -ENOMEM;
	}

	input_dev->name = pdev->name;
	input_dev->phys = "keyscan-keys/input0";
	input_dev->dev.parent = &pdev->dev;
	input_dev->open = keyscan_open;
	input_dev->close = keyscan_close;

	input_dev->id.bustype = BUS_HOST;

	error = keypad_matrix_key_parse_dt(keypad_data);
	if (error)
		return error;

	error = matrix_keypad_build_keymap(NULL, NULL,
					   keypad_data->n_rows,
					   keypad_data->n_cols,
					   NULL, input_dev);
	if (error) {
		dev_err(&pdev->dev, "failed to build keymap\n");
		return error;
	}

	input_set_drvdata(input_dev, keypad_data);

	keypad_data->input_dev = input_dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	keypad_data->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(keypad_data->base))
		return PTR_ERR(keypad_data->base);

	keypad_data->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(keypad_data->clk)) {
		dev_err(&pdev->dev, "cannot get clock\n");
		return PTR_ERR(keypad_data->clk);
	}

	error = clk_enable(keypad_data->clk);
	if (error) {
		dev_err(&pdev->dev, "failed to enable clock\n");
		return error;
	}

	keyscan_stop(keypad_data);

	keypad_data->irq = platform_get_irq(pdev, 0);
	if (keypad_data->irq < 0) {
		dev_err(&pdev->dev, "no IRQ specified\n");
		return -EINVAL;
	}

	error = devm_request_irq(&pdev->dev, keypad_data->irq, keyscan_isr, 0,
				 pdev->name, keypad_data);
	if (error) {
		dev_err(&pdev->dev, "failed to request IRQ\n");
		return error;
	}

	error = input_register_device(input_dev);
	if (error) {
		dev_err(&pdev->dev, "failed to register input device\n");
		return error;
	}

	platform_set_drvdata(pdev, keypad_data);

	device_set_wakeup_capable(&pdev->dev, 1);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int keyscan_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct st_keyscan *keypad = platform_get_drvdata(pdev);
	struct input_dev *input = keypad->input_dev;

	mutex_lock(&input->mutex);

	if (device_may_wakeup(dev))
		enable_irq_wake(keypad->irq);
	else if (input->users)
		keyscan_stop(keypad);

	mutex_unlock(&input->mutex);
	return 0;
}

static int keyscan_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct st_keyscan *keypad = platform_get_drvdata(pdev);
	struct input_dev *input = keypad->input_dev;
	int retval = 0;

	mutex_lock(&input->mutex);

	if (device_may_wakeup(dev))
		disable_irq_wake(keypad->irq);
	else if (input->users)
		retval = keyscan_start(keypad);

	mutex_unlock(&input->mutex);
	return retval;
}
#endif

static SIMPLE_DEV_PM_OPS(keyscan_dev_pm_ops, keyscan_suspend, keyscan_resume);

static const struct of_device_id keyscan_of_match[] = {
	{ .compatible = "st,sti-keyscan" },
	{ },
};
MODULE_DEVICE_TABLE(of, keyscan_of_match);

static struct platform_driver keyscan_device_driver = {
	.probe		= keyscan_probe,
	.driver		= {
		.name	= "st-keyscan",
		.pm	= &keyscan_dev_pm_ops,
		.of_match_table = of_match_ptr(keyscan_of_match),
	}
};

module_platform_driver(keyscan_device_driver);

MODULE_AUTHOR("Stuart Menefy <stuart.menefy@st.com>");
MODULE_DESCRIPTION("STMicroelectronics keyscan device driver");
MODULE_LICENSE("GPL");
