/*
 *  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_open(struct input_dev *input)
{
	struct nspire_keypad *keypad = input_get_drvdata(input);
	unsigned long val = 0, cycles_per_us, delay_cycles, row_delay_cycles;
	int error;

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

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

	return 0;
}

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

	/* Disable interrupts */
	writel(0, keypad->reg_base + KEYPAD_INTMSK);
	/* Acknowledge existing interrupts */
	writel(~0, keypad->reg_base + KEYPAD_INT);

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

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

	/* Disable interrupts */
	writel(0, keypad->reg_base + KEYPAD_INTMSK);
	/* Acknowledge existing interrupts */
	writel(~0, keypad->reg_base + KEYPAD_INT);

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

	clk_disable_unprepare(keypad->clk);

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

	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",
		.of_match_table = nspire_keypad_dt_match,
	},
	.probe = nspire_keypad_probe,
};

module_platform_driver(nspire_keypad_driver);

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