/*
 * Driver for a keypad w/16 buttons connected to a PCF8574 I2C I/O expander
 *
 * Copyright 2005-2008 Analog Devices Inc.
 *
 * Licensed under the GPL-2 or later.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/workqueue.h>

#define DRV_NAME "pcf8574_keypad"

static const unsigned char pcf8574_kp_btncode[] = {
	[0] = KEY_RESERVED,
	[1] = KEY_ENTER,
	[2] = KEY_BACKSLASH,
	[3] = KEY_0,
	[4] = KEY_RIGHTBRACE,
	[5] = KEY_C,
	[6] = KEY_9,
	[7] = KEY_8,
	[8] = KEY_7,
	[9] = KEY_B,
	[10] = KEY_6,
	[11] = KEY_5,
	[12] = KEY_4,
	[13] = KEY_A,
	[14] = KEY_3,
	[15] = KEY_2,
	[16] = KEY_1
};

struct kp_data {
	unsigned short btncode[ARRAY_SIZE(pcf8574_kp_btncode)];
	struct input_dev *idev;
	struct i2c_client *client;
	char name[64];
	char phys[32];
	unsigned char laststate;
};

static short read_state(struct kp_data *lp)
{
	unsigned char x, y, a, b;

	i2c_smbus_write_byte(lp->client, 240);
	x = 0xF & (~(i2c_smbus_read_byte(lp->client) >> 4));

	i2c_smbus_write_byte(lp->client, 15);
	y = 0xF & (~i2c_smbus_read_byte(lp->client));

	for (a = 0; x > 0; a++)
		x = x >> 1;
	for (b = 0; y > 0; b++)
		y = y >> 1;

	return ((a - 1) * 4) + b;
}

static irqreturn_t pcf8574_kp_irq_handler(int irq, void *dev_id)
{
	struct kp_data *lp = dev_id;
	unsigned char nextstate = read_state(lp);

	if (lp->laststate != nextstate) {
		int key_down = nextstate < ARRAY_SIZE(lp->btncode);
		unsigned short keycode = key_down ?
			lp->btncode[nextstate] : lp->btncode[lp->laststate];

		input_report_key(lp->idev, keycode, key_down);
		input_sync(lp->idev);

		lp->laststate = nextstate;
	}

	return IRQ_HANDLED;
}

static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int i, ret;
	struct input_dev *idev;
	struct kp_data *lp;

	if (i2c_smbus_write_byte(client, 240) < 0) {
		dev_err(&client->dev, "probe: write fail\n");
		return -ENODEV;
	}

	lp = kzalloc(sizeof(*lp), GFP_KERNEL);
	if (!lp)
		return -ENOMEM;

	idev = input_allocate_device();
	if (!idev) {
		dev_err(&client->dev, "Can't allocate input device\n");
		ret = -ENOMEM;
		goto fail_allocate;
	}

	lp->idev = idev;
	lp->client = client;

	idev->evbit[0] = BIT_MASK(EV_KEY);
	idev->keycode = lp->btncode;
	idev->keycodesize = sizeof(lp->btncode[0]);
	idev->keycodemax = ARRAY_SIZE(lp->btncode);

	for (i = 0; i < ARRAY_SIZE(pcf8574_kp_btncode); i++) {
		lp->btncode[i] = pcf8574_kp_btncode[i];
		__set_bit(lp->btncode[i] & KEY_MAX, idev->keybit);
	}

	sprintf(lp->name, DRV_NAME);
	sprintf(lp->phys, "kp_data/input0");

	idev->name = lp->name;
	idev->phys = lp->phys;
	idev->id.bustype = BUS_I2C;
	idev->id.vendor = 0x0001;
	idev->id.product = 0x0001;
	idev->id.version = 0x0100;

	lp->laststate = read_state(lp);

	ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler,
				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				   DRV_NAME, lp);
	if (ret) {
		dev_err(&client->dev, "IRQ %d is not free\n", client->irq);
		goto fail_free_device;
	}

	ret = input_register_device(idev);
	if (ret) {
		dev_err(&client->dev, "input_register_device() failed\n");
		goto fail_free_irq;
	}

	i2c_set_clientdata(client, lp);
	return 0;

 fail_free_irq:
	free_irq(client->irq, lp);
 fail_free_device:
	input_free_device(idev);
 fail_allocate:
	kfree(lp);

	return ret;
}

static int __devexit pcf8574_kp_remove(struct i2c_client *client)
{
	struct kp_data *lp = i2c_get_clientdata(client);

	free_irq(client->irq, lp);

	input_unregister_device(lp->idev);
	kfree(lp);

	return 0;
}

#ifdef CONFIG_PM
static int pcf8574_kp_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);

	enable_irq(client->irq);

	return 0;
}

static int pcf8574_kp_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);

	disable_irq(client->irq);

	return 0;
}

static const struct dev_pm_ops pcf8574_kp_pm_ops = {
	.suspend	= pcf8574_kp_suspend,
	.resume		= pcf8574_kp_resume,
};

#else
# define pcf8574_kp_resume  NULL
# define pcf8574_kp_suspend NULL
#endif

static const struct i2c_device_id pcf8574_kp_id[] = {
	{ DRV_NAME, 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, pcf8574_kp_id);

static struct i2c_driver pcf8574_kp_driver = {
	.driver = {
		.name  = DRV_NAME,
		.owner = THIS_MODULE,
#ifdef CONFIG_PM
		.pm = &pcf8574_kp_pm_ops,
#endif
	},
	.probe    = pcf8574_kp_probe,
	.remove   = __devexit_p(pcf8574_kp_remove),
	.id_table = pcf8574_kp_id,
};

static int __init pcf8574_kp_init(void)
{
	return i2c_add_driver(&pcf8574_kp_driver);
}
module_init(pcf8574_kp_init);

static void __exit pcf8574_kp_exit(void)
{
	i2c_del_driver(&pcf8574_kp_driver);
}
module_exit(pcf8574_kp_exit);

MODULE_AUTHOR("Michael Hennerich");
MODULE_DESCRIPTION("Keypad input driver for 16 keys connected to PCF8574");
MODULE_LICENSE("GPL");
