/*
 *  Keyboard driver for Sharp Tosa models (SL-6000x)
 *
 *  Copyright (c) 2005 Dirk Opfer
 *  Copyright (c) 2007 Dmitry Baryshkov
 *
 *  Based on xtkbd.c/locomkbd.c/corgikbd.c
 *
 *  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/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/interrupt.h>

#include <asm/arch/gpio.h>
#include <asm/arch/tosa.h>

#define KB_ROWMASK(r)		(1 << (r))
#define SCANCODE(r, c)		(((r)<<4) + (c) + 1)
#define NR_SCANCODES		SCANCODE(TOSA_KEY_SENSE_NUM - 1, TOSA_KEY_STROBE_NUM - 1) + 1

#define SCAN_INTERVAL		(HZ/10)

#define KB_DISCHARGE_DELAY	10
#define KB_ACTIVATE_DELAY	10

static unsigned int tosakbd_keycode[NR_SCANCODES] = {
0,
0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P,
0, 0, 0, 0, 0, 0, 0, 0,
KEY_Q, KEY_E, KEY_T, KEY_Y, 0, KEY_O, KEY_I, KEY_COMMA,
0, 0, 0, 0, 0, 0, 0, 0,
KEY_A, KEY_D, KEY_G, KEY_U, 0, KEY_L, KEY_ENTER, KEY_DOT,
0, 0, 0, 0, 0, 0, 0, 0,
KEY_Z, KEY_C, KEY_V, KEY_J, TOSA_KEY_ADDRESSBOOK, TOSA_KEY_CANCEL, TOSA_KEY_CENTER, TOSA_KEY_OK,
KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, 0,
KEY_S, KEY_R, KEY_B, KEY_N, TOSA_KEY_CALENDAR, TOSA_KEY_HOMEPAGE, KEY_LEFTCTRL, TOSA_KEY_LIGHT,
0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0,
KEY_TAB, KEY_SLASH, KEY_H, KEY_M, TOSA_KEY_MENU, 0, KEY_UP, 0,
0, 0, TOSA_KEY_FN, 0, 0, 0, 0, 0,
KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_RIGHT,
0, 0, 0,
};

struct tosakbd {
	unsigned int keycode[ARRAY_SIZE(tosakbd_keycode)];
	struct input_dev *input;

	spinlock_t lock; /* protect kbd scanning */
	struct timer_list timer;
};


/* Helper functions for reading the keyboard matrix
 * Note: We should really be using pxa_gpio_mode to alter GPDR but it
 *       requires a function call per GPIO bit which is excessive
 *       when we need to access 12 bits at once, multiple times.
 * These functions must be called within local_irq_save()/local_irq_restore()
 * or similar.
 */
#define GET_ROWS_STATUS(c)	((GPLR2 & TOSA_GPIO_ALL_SENSE_BIT) >> TOSA_GPIO_ALL_SENSE_RSHIFT)

static inline void tosakbd_discharge_all(void)
{
	/* STROBE All HiZ */
	GPCR1  = TOSA_GPIO_HIGH_STROBE_BIT;
	GPDR1 &= ~TOSA_GPIO_HIGH_STROBE_BIT;
	GPCR2  = TOSA_GPIO_LOW_STROBE_BIT;
	GPDR2 &= ~TOSA_GPIO_LOW_STROBE_BIT;
}

static inline void tosakbd_activate_all(void)
{
	/* STROBE ALL -> High */
	GPSR1  = TOSA_GPIO_HIGH_STROBE_BIT;
	GPDR1 |= TOSA_GPIO_HIGH_STROBE_BIT;
	GPSR2  = TOSA_GPIO_LOW_STROBE_BIT;
	GPDR2 |= TOSA_GPIO_LOW_STROBE_BIT;

	udelay(KB_DISCHARGE_DELAY);

	/* STATE CLEAR */
	GEDR2 |= TOSA_GPIO_ALL_SENSE_BIT;
}

static inline void tosakbd_activate_col(int col)
{
	if (col <= 5) {
		/* STROBE col -> High, not col -> HiZ */
		GPSR1 = TOSA_GPIO_STROBE_BIT(col);
		GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
	} else {
		/* STROBE col -> High, not col -> HiZ */
		GPSR2 = TOSA_GPIO_STROBE_BIT(col);
		GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
	}
}

static inline void tosakbd_reset_col(int col)
{
	if (col <= 5) {
		/* STROBE col -> Low */
		GPCR1 = TOSA_GPIO_STROBE_BIT(col);
		/* STROBE col -> out, not col -> HiZ */
		GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
	} else {
		/* STROBE col -> Low */
		GPCR2 = TOSA_GPIO_STROBE_BIT(col);
		/* STROBE col -> out, not col -> HiZ */
		GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
	}
}
/*
 * The tosa keyboard only generates interrupts when a key is pressed.
 * So when a key is pressed, we enable a timer.  This timer scans the
 * keyboard, and this is how we detect when the key is released.
 */

/* Scan the hardware keyboard and push any changes up through the input layer */
static void tosakbd_scankeyboard(struct platform_device *dev)
{
	struct tosakbd *tosakbd = platform_get_drvdata(dev);
	unsigned int row, col, rowd;
	unsigned long flags;
	unsigned int num_pressed = 0;

	spin_lock_irqsave(&tosakbd->lock, flags);

	for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) {
		/*
		 * Discharge the output driver capacitatance
		 * in the keyboard matrix. (Yes it is significant..)
		 */
		tosakbd_discharge_all();
		udelay(KB_DISCHARGE_DELAY);

		tosakbd_activate_col(col);
		udelay(KB_ACTIVATE_DELAY);

		rowd = GET_ROWS_STATUS(col);

		for (row = 0; row < TOSA_KEY_SENSE_NUM; row++) {
			unsigned int scancode, pressed;
			scancode = SCANCODE(row, col);
			pressed = rowd & KB_ROWMASK(row);

			if (pressed && !tosakbd->keycode[scancode])
				dev_warn(&dev->dev,
						"unhandled scancode: 0x%02x\n",
						scancode);

			input_report_key(tosakbd->input,
					tosakbd->keycode[scancode],
					pressed);
			if (pressed)
				num_pressed++;
		}

		tosakbd_reset_col(col);
	}

	tosakbd_activate_all();

	input_sync(tosakbd->input);

	/* if any keys are pressed, enable the timer */
	if (num_pressed)
		mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL);

	spin_unlock_irqrestore(&tosakbd->lock, flags);
}

/*
 * tosa keyboard interrupt handler.
 */
static irqreturn_t tosakbd_interrupt(int irq, void *__dev)
{
	struct platform_device *dev = __dev;
	struct tosakbd *tosakbd = platform_get_drvdata(dev);

	if (!timer_pending(&tosakbd->timer)) {
		/** wait chattering delay **/
		udelay(20);
		tosakbd_scankeyboard(dev);
	}

	return IRQ_HANDLED;
}

/*
 * tosa timer checking for released keys
 */
static void tosakbd_timer_callback(unsigned long __dev)
{
	struct platform_device *dev = (struct platform_device *)__dev;
	tosakbd_scankeyboard(dev);
}

#ifdef CONFIG_PM
static int tosakbd_suspend(struct platform_device *dev, pm_message_t state)
{
	struct tosakbd *tosakbd = platform_get_drvdata(dev);

	del_timer_sync(&tosakbd->timer);

	return 0;
}

static int tosakbd_resume(struct platform_device *dev)
{
	tosakbd_scankeyboard(dev);

	return 0;
}
#else
#define tosakbd_suspend		NULL
#define tosakbd_resume		NULL
#endif

static int __devinit tosakbd_probe(struct platform_device *pdev) {

	int i;
	struct tosakbd *tosakbd;
	struct input_dev *input_dev;
	int error;

	tosakbd = kzalloc(sizeof(struct tosakbd), GFP_KERNEL);
	if (!tosakbd)
		return -ENOMEM;

	input_dev = input_allocate_device();
	if (!input_dev) {
		kfree(tosakbd);
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, tosakbd);

	spin_lock_init(&tosakbd->lock);

	/* Init Keyboard rescan timer */
	init_timer(&tosakbd->timer);
	tosakbd->timer.function = tosakbd_timer_callback;
	tosakbd->timer.data = (unsigned long) pdev;

	tosakbd->input = input_dev;

	input_set_drvdata(input_dev, tosakbd);
	input_dev->name = "Tosa Keyboard";
	input_dev->phys = "tosakbd/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->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
	input_dev->keycode = tosakbd->keycode;
	input_dev->keycodesize = sizeof(unsigned int);
	input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode);

	memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd_keycode));

	for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++)
		__set_bit(tosakbd->keycode[i], input_dev->keybit);
	clear_bit(0, input_dev->keybit);

	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
	for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
		int gpio = TOSA_GPIO_KEY_SENSE(i);
		int irq;
		error = gpio_request(gpio, "tosakbd");
		if (error < 0) {
			printk(KERN_ERR "tosakbd: failed to request GPIO %d, "
				" error %d\n", gpio, error);
			goto fail;
		}

		error = gpio_direction_input(TOSA_GPIO_KEY_SENSE(i));
		if (error < 0) {
			printk(KERN_ERR "tosakbd: failed to configure input"
				" direction for GPIO %d, error %d\n",
				gpio, error);
			gpio_free(gpio);
			goto fail;
		}

		irq = gpio_to_irq(gpio);
		if (irq < 0) {
			error = irq;
			printk(KERN_ERR "gpio-keys: Unable to get irq number"
				" for GPIO %d, error %d\n",
				gpio, error);
			gpio_free(gpio);
			goto fail;
		}

		error = request_irq(irq, tosakbd_interrupt,
					IRQF_DISABLED | IRQF_TRIGGER_RISING,
					"tosakbd", pdev);

		if (error) {
			printk("tosakbd: Can't get IRQ: %d: error %d!\n",
					irq, error);
			gpio_free(gpio);
			goto fail;
		}
	}

	/* Set Strobe lines as outputs - set high */
	for (i = 0; i < TOSA_KEY_STROBE_NUM; i++) {
		int gpio = TOSA_GPIO_KEY_STROBE(i);
		error = gpio_request(gpio, "tosakbd");
		if (error < 0) {
			printk(KERN_ERR "tosakbd: failed to request GPIO %d, "
				" error %d\n", gpio, error);
			goto fail2;
		}

		error = gpio_direction_output(gpio, 1);
		if (error < 0) {
			printk(KERN_ERR "tosakbd: failed to configure input"
				" direction for GPIO %d, error %d\n",
				gpio, error);
			gpio_free(gpio);
			goto fail;
		}

	}

	error = input_register_device(input_dev);
	if (error) {
		printk(KERN_ERR "tosakbd: Unable to register input device, "
			"error: %d\n", error);
		goto fail;
	}

	printk(KERN_INFO "input: Tosa Keyboard Registered\n");

	return 0;

fail2:
	while (--i >= 0)
		gpio_free(TOSA_GPIO_KEY_STROBE(i));

	i = TOSA_KEY_SENSE_NUM;
fail:
	while (--i >= 0) {
		free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), pdev);
		gpio_free(TOSA_GPIO_KEY_SENSE(i));
	}

	platform_set_drvdata(pdev, NULL);
	input_free_device(input_dev);
	kfree(tosakbd);

	return error;
}

static int __devexit tosakbd_remove(struct platform_device *dev) {

	int i;
	struct tosakbd *tosakbd = platform_get_drvdata(dev);

	for (i = 0; i < TOSA_KEY_STROBE_NUM; i++)
		gpio_free(TOSA_GPIO_KEY_STROBE(i));

	for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
		free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), dev);
		gpio_free(TOSA_GPIO_KEY_SENSE(i));
	}

	del_timer_sync(&tosakbd->timer);

	input_unregister_device(tosakbd->input);

	kfree(tosakbd);

	return 0;
}

static struct platform_driver tosakbd_driver = {
	.probe		= tosakbd_probe,
	.remove		= __devexit_p(tosakbd_remove),
	.suspend	= tosakbd_suspend,
	.resume		= tosakbd_resume,
	.driver		= {
		.name	= "tosa-keyboard",
	},
};

static int __devinit tosakbd_init(void)
{
	return platform_driver_register(&tosakbd_driver);
}

static void __exit tosakbd_exit(void)
{
	platform_driver_unregister(&tosakbd_driver);
}

module_init(tosakbd_init);
module_exit(tosakbd_exit);

MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>");
MODULE_DESCRIPTION("Tosa Keyboard Driver");
MODULE_LICENSE("GPL v2");
