/*
 *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
 *
 * 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/input/matrix_keypad.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>

#define KEYPAD_SCAN_MODE	0x00
#define KEYPAD_CNTL		0x04
#define KEYPAD_INT		0x08
#define KEYPAD_INTMSK		0x0C

#define KEYPAD_DATA		0x10
#define KEYPAD_GPIO		0x30

#define KEYPAD_UNKNOWN_INT	0x40
#define KEYPAD_UNKNOWN_INT_STS	0x44

#define KEYPAD_BITMASK_COLS	11
#define KEYPAD_BITMASK_ROWS	8

struct nspire_keypad {
	void __iomem *reg_base;
	u32 int_mask;

	struct input_dev *input;
	struct clk *clk;

	struct matrix_keymap_data *keymap;
	int row_shift;

	/* Maximum delay estimated assuming 33MHz APB */
	u32 scan_interval;	/* In microseconds (~2000us max) */
	u32 row_delay;		/* In microseconds (~500us max) */

	u16 state[KEYPAD_BITMASK_ROWS];

	bool active_low;
};

static irqreturn_t nspire_keypad_irq(int irq, void *dev_id)
{
	struct nspire_keypad *keypad = dev_id;
	struct input_dev *input = keypad->input;
	unsigned short *keymap = input->keycode;
	unsigned int code;
	int row, col;
	u32 int_sts;
	u16 state[8];
	u16 bits, changed;

	int_sts = readl(keypad->reg_base + KEYPAD_INT) & keypad->int_mask;
	if (!int_sts)
		return IRQ_NONE;

	memcpy_fromio(state, keypad->reg_base + KEYPAD_DATA, sizeof(state));

	for (row = 0; row < KEYPAD_BITMASK_ROWS; row++) {
		bits = state[row];
		if (keypad->active_low)
			bits = ~bits;

		changed = bits ^ keypad->state[row];
		if (!changed)
			continue;

		keypad->state[row] = bits;

		for (col = 0; col < KEYPAD_BITMASK_COLS; col++) {
			if (!(changed & (1U << col)))
				continue;

			code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
			input_event(input, EV_MSC, MSC_SCAN, code);
			input_report_key(input, keymap[code],
					 bits & (1U << col));
		}
	}

	input_sync(input);

	writel(0x3, keypad->reg_base + KEYPAD_INT);

	return IRQ_HANDLED;
}

static int nspire_keypad_chip_init(struct nspire_keypad *keypad)
{
	unsigned long val = 0, cycles_per_us, delay_cycles, row_delay_cycles;

	cycles_per_us = (clk_get_rate(keypad->clk) / 1000000);
	if (cycles_per_us == 0)
		cycles_per_us = 1;

	delay_cycles = cycles_per_us * keypad->scan_interval;
	WARN_ON(delay_cycles >= (1 << 16)); /* Overflow */
	delay_cycles &= 0xffff;

	row_delay_cycles = cycles_per_us * keypad->row_delay;
	WARN_ON(row_delay_cycles >= (1 << 14)); /* Overflow */
	row_delay_cycles &= 0x3fff;

	val |= 3 << 0; /* Set scan mode to 3 (continuous scan) */
	val |= row_delay_cycles << 2; /* Delay between scanning each row */
	val |= delay_cycles << 16; /* Delay between scans */
	writel(val, keypad->reg_base + KEYPAD_SCAN_MODE);

	val = (KEYPAD_BITMASK_ROWS & 0xff) | (KEYPAD_BITMASK_COLS & 0xff)<<8;
	writel(val, keypad->reg_base + KEYPAD_CNTL);

	/* Enable interrupts */
	keypad->int_mask = 1 << 1;
	writel(keypad->int_mask, keypad->reg_base + KEYPAD_INTMSK);

	/* Disable GPIO interrupts to prevent hanging on touchpad */
	/* Possibly used to detect touchpad events */
	writel(0, keypad->reg_base + KEYPAD_UNKNOWN_INT);
	/* Acknowledge existing interrupts */
	writel(~0, keypad->reg_base + KEYPAD_UNKNOWN_INT_STS);

	return 0;
}

static int nspire_keypad_open(struct input_dev *input)
{
	struct nspire_keypad *keypad = input_get_drvdata(input);
	int error;

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

	error = nspire_keypad_chip_init(keypad);
	if (error)
		return error;

	return 0;
}

static void nspire_keypad_close(struct input_dev *input)
{
	struct nspire_keypad *keypad = input_get_drvdata(input);

	clk_disable_unprepare(keypad->clk);
}

static int nspire_keypad_probe(struct platform_device *pdev)
{
	const struct device_node *of_node = pdev->dev.of_node;
	struct nspire_keypad *keypad;
	struct input_dev *input;
	struct resource *res;
	int irq;
	int error;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "failed to get keypad irq\n");
		return -EINVAL;
	}

	keypad = devm_kzalloc(&pdev->dev, sizeof(struct nspire_keypad),
			      GFP_KERNEL);
	if (!keypad) {
		dev_err(&pdev->dev, "failed to allocate keypad memory\n");
		return -ENOMEM;
	}

	keypad->row_shift = get_count_order(KEYPAD_BITMASK_COLS);

	error = of_property_read_u32(of_node, "scan-interval",
				     &keypad->scan_interval);
	if (error) {
		dev_err(&pdev->dev, "failed to get scan-interval\n");
		return error;
	}

	error = of_property_read_u32(of_node, "row-delay",
				     &keypad->row_delay);
	if (error) {
		dev_err(&pdev->dev, "failed to get row-delay\n");
		return error;
	}

	keypad->active_low = of_property_read_bool(of_node, "active-low");

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

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

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

	input_set_drvdata(input, keypad);

	input->id.bustype = BUS_HOST;
	input->name = "nspire-keypad";
	input->open = nspire_keypad_open;
	input->close = nspire_keypad_close;

	__set_bit(EV_KEY, input->evbit);
	__set_bit(EV_REP, input->evbit);
	input_set_capability(input, EV_MSC, MSC_SCAN);

	error = matrix_keypad_build_keymap(NULL, NULL,
					   KEYPAD_BITMASK_ROWS,
					   KEYPAD_BITMASK_COLS,
					   NULL, input);
	if (error) {
		dev_err(&pdev->dev, "building keymap failed\n");
		return error;
	}

	error = devm_request_irq(&pdev->dev, irq, nspire_keypad_irq, 0,
				 "nspire_keypad", keypad);
	if (error) {
		dev_err(&pdev->dev, "allocate irq %d failed\n", irq);
		return error;
	}

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

	platform_set_drvdata(pdev, keypad);

	dev_dbg(&pdev->dev,
		"TI-NSPIRE keypad at %pR (scan_interval=%uus, row_delay=%uus%s)\n",
		res, keypad->row_delay, keypad->scan_interval,
		keypad->active_low ? ", active_low" : "");

	return 0;
}

static const struct of_device_id nspire_keypad_dt_match[] = {
	{ .compatible = "ti,nspire-keypad" },
	{ },
};
MODULE_DEVICE_TABLE(of, nspire_keypad_dt_match);

static struct platform_driver nspire_keypad_driver = {
	.driver = {
		.name = "nspire-keypad",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(nspire_keypad_dt_match),
	},
	.probe = nspire_keypad_probe,
};

module_platform_driver(nspire_keypad_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("TI-NSPIRE Keypad Driver");
