/*
 *  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;
	int suspended;
	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);

	if (tosakbd->suspended)
		goto out;

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

 out:
	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);
	unsigned long flags;

	spin_lock_irqsave(&tosakbd->lock, flags);
	tosakbd->suspended = 1;
	spin_unlock_irqrestore(&tosakbd->lock, flags);

	del_timer_sync(&tosakbd->timer);

	return 0;
}

static int tosakbd_resume(struct platform_device *dev)
{
	struct tosakbd *tosakbd = platform_get_drvdata(dev);

	tosakbd->suspended = 0;
	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",
		.owner	= THIS_MODULE,
	},
};

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");
MODULE_ALIAS("platform:tosa-keyboard");
