/*
 * SPEAr Keyboard Driver
 * Based on omap-keypad driver
 *
 * Copyright (C) 2010 ST Microelectronics
 * Rajeev Kumar<rajeev-dlh.kumar@st.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_wakeup.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <plat/keyboard.h>

/* Keyboard Registers */
#define MODE_REG	0x00	/* 16 bit reg */
#define STATUS_REG	0x0C	/* 2 bit reg */
#define DATA_REG	0x10	/* 8 bit reg */
#define INTR_MASK	0x54

/* Register Values */
/*
 * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode
 * control register as 1010010(82MHZ)
 */
#define PCLK_FREQ_MSK	0xA400	/* 82 MHz */
#define START_SCAN	0x0100
#define SCAN_RATE_10	0x0000
#define SCAN_RATE_20	0x0004
#define SCAN_RATE_40	0x0008
#define SCAN_RATE_80	0x000C
#define MODE_KEYBOARD	0x0002
#define DATA_AVAIL	0x2

#define KEY_MASK	0xFF000000
#define KEY_VALUE	0x00FFFFFF
#define ROW_MASK	0xF0
#define COLUMN_MASK	0x0F
#define ROW_SHIFT	4

struct spear_kbd {
	struct input_dev *input;
	struct resource *res;
	void __iomem *io_base;
	struct clk *clk;
	unsigned int irq;
	unsigned short last_key;
	unsigned short keycodes[256];
};

static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
{
	struct spear_kbd *kbd = dev_id;
	struct input_dev *input = kbd->input;
	unsigned int key;
	u8 sts, val;

	sts = readb(kbd->io_base + STATUS_REG);
	if (!(sts & DATA_AVAIL))
		return IRQ_NONE;

	if (kbd->last_key != KEY_RESERVED) {
		input_report_key(input, kbd->last_key, 0);
		kbd->last_key = KEY_RESERVED;
	}

	/* following reads active (row, col) pair */
	val = readb(kbd->io_base + DATA_REG);
	key = kbd->keycodes[val];

	input_event(input, EV_MSC, MSC_SCAN, val);
	input_report_key(input, key, 1);
	input_sync(input);

	kbd->last_key = key;

	/* clear interrupt */
	writeb(0, kbd->io_base + STATUS_REG);

	return IRQ_HANDLED;
}

static int spear_kbd_open(struct input_dev *dev)
{
	struct spear_kbd *kbd = input_get_drvdata(dev);
	int error;
	u16 val;

	kbd->last_key = KEY_RESERVED;

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

	/* program keyboard */
	val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK;
	writew(val, kbd->io_base + MODE_REG);
	writeb(1, kbd->io_base + STATUS_REG);

	/* start key scan */
	val = readw(kbd->io_base + MODE_REG);
	val |= START_SCAN;
	writew(val, kbd->io_base + MODE_REG);

	return 0;
}

static void spear_kbd_close(struct input_dev *dev)
{
	struct spear_kbd *kbd = input_get_drvdata(dev);
	u16 val;

	/* stop key scan */
	val = readw(kbd->io_base + MODE_REG);
	val &= ~START_SCAN;
	writew(val, kbd->io_base + MODE_REG);

	clk_disable(kbd->clk);

	kbd->last_key = KEY_RESERVED;
}

static int __devinit spear_kbd_probe(struct platform_device *pdev)
{
	const struct kbd_platform_data *pdata = pdev->dev.platform_data;
	const struct matrix_keymap_data *keymap;
	struct spear_kbd *kbd;
	struct input_dev *input_dev;
	struct resource *res;
	int irq;
	int error;

	if (!pdata) {
		dev_err(&pdev->dev, "Invalid platform data\n");
		return -EINVAL;
	}

	keymap = pdata->keymap;
	if (!keymap) {
		dev_err(&pdev->dev, "no keymap defined\n");
		return -EINVAL;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "no keyboard resource defined\n");
		return -EBUSY;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "not able to get irq for the device\n");
		return irq;
	}

	kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!kbd || !input_dev) {
		dev_err(&pdev->dev, "out of memory\n");
		error = -ENOMEM;
		goto err_free_mem;
	}

	kbd->input = input_dev;
	kbd->irq = irq;
	kbd->res = request_mem_region(res->start, resource_size(res),
				      pdev->name);
	if (!kbd->res) {
		dev_err(&pdev->dev, "keyboard region already claimed\n");
		error = -EBUSY;
		goto err_free_mem;
	}

	kbd->io_base = ioremap(res->start, resource_size(res));
	if (!kbd->io_base) {
		dev_err(&pdev->dev, "ioremap failed for kbd_region\n");
		error = -ENOMEM;
		goto err_release_mem_region;
	}

	kbd->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(kbd->clk)) {
		error = PTR_ERR(kbd->clk);
		goto err_iounmap;
	}

	input_dev->name = "Spear Keyboard";
	input_dev->phys = "keyboard/input0";
	input_dev->dev.parent = &pdev->dev;
	input_dev->id.bustype = BUS_HOST;
	input_dev->id.vendor = 0x0001;
	input_dev->id.product = 0x0001;
	input_dev->id.version = 0x0100;
	input_dev->open = spear_kbd_open;
	input_dev->close = spear_kbd_close;

	__set_bit(EV_KEY, input_dev->evbit);
	if (pdata->rep)
		__set_bit(EV_REP, input_dev->evbit);
	input_set_capability(input_dev, EV_MSC, MSC_SCAN);

	input_dev->keycode = kbd->keycodes;
	input_dev->keycodesize = sizeof(kbd->keycodes[0]);
	input_dev->keycodemax = ARRAY_SIZE(kbd->keycodes);

	matrix_keypad_build_keymap(keymap, ROW_SHIFT,
			input_dev->keycode, input_dev->keybit);

	input_set_drvdata(input_dev, kbd);

	error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd);
	if (error) {
		dev_err(&pdev->dev, "request_irq fail\n");
		goto err_put_clk;
	}

	error = input_register_device(input_dev);
	if (error) {
		dev_err(&pdev->dev, "Unable to register keyboard device\n");
		goto err_free_irq;
	}

	device_init_wakeup(&pdev->dev, 1);
	platform_set_drvdata(pdev, kbd);

	return 0;

err_free_irq:
	free_irq(kbd->irq, kbd);
err_put_clk:
	clk_put(kbd->clk);
err_iounmap:
	iounmap(kbd->io_base);
err_release_mem_region:
	release_mem_region(res->start, resource_size(res));
err_free_mem:
	input_free_device(input_dev);
	kfree(kbd);

	return error;
}

static int __devexit spear_kbd_remove(struct platform_device *pdev)
{
	struct spear_kbd *kbd = platform_get_drvdata(pdev);

	free_irq(kbd->irq, kbd);
	input_unregister_device(kbd->input);
	clk_put(kbd->clk);
	iounmap(kbd->io_base);
	release_mem_region(kbd->res->start, resource_size(kbd->res));
	kfree(kbd);

	device_init_wakeup(&pdev->dev, 1);
	platform_set_drvdata(pdev, NULL);

	return 0;
}

#ifdef CONFIG_PM
static int spear_kbd_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct spear_kbd *kbd = platform_get_drvdata(pdev);
	struct input_dev *input_dev = kbd->input;

	mutex_lock(&input_dev->mutex);

	if (input_dev->users)
		clk_enable(kbd->clk);

	if (device_may_wakeup(&pdev->dev))
		enable_irq_wake(kbd->irq);

	mutex_unlock(&input_dev->mutex);

	return 0;
}

static int spear_kbd_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct spear_kbd *kbd = platform_get_drvdata(pdev);
	struct input_dev *input_dev = kbd->input;

	mutex_lock(&input_dev->mutex);

	if (device_may_wakeup(&pdev->dev))
		disable_irq_wake(kbd->irq);

	if (input_dev->users)
		clk_enable(kbd->clk);

	mutex_unlock(&input_dev->mutex);

	return 0;
}

static const struct dev_pm_ops spear_kbd_pm_ops = {
	.suspend	= spear_kbd_suspend,
	.resume		= spear_kbd_resume,
};
#endif

static struct platform_driver spear_kbd_driver = {
	.probe		= spear_kbd_probe,
	.remove		= __devexit_p(spear_kbd_remove),
	.driver		= {
		.name	= "keyboard",
		.owner	= THIS_MODULE,
#ifdef CONFIG_PM
		.pm	= &spear_kbd_pm_ops,
#endif
	},
};

static int __init spear_kbd_init(void)
{
	return platform_driver_register(&spear_kbd_driver);
}
module_init(spear_kbd_init);

static void __exit spear_kbd_exit(void)
{
	platform_driver_unregister(&spear_kbd_driver);
}
module_exit(spear_kbd_exit);

MODULE_AUTHOR("Rajeev Kumar");
MODULE_DESCRIPTION("SPEAr Keyboard Driver");
MODULE_LICENSE("GPL");
