/*
 *  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 <mach/gpio.h>
#include <mach/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");
