/*
 * Touch Screen driver for EETI's I2C connected touch screen panels
 *   Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
 *
 * See EETI's software guide for the protocol specification:
 *   http://home.eeti.com.tw/web20/eg/guide.htm
 *
 * Based on migor_ts.c
 *   Copyright (c) 2008 Magnus Damm
 *   Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com>
 *
 * This file is free software; you can redistribute it and/or
 * modify it under the terms of the GNU  General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This file is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/timer.h>
#include <linux/gpio.h>
#include <linux/input/eeti_ts.h>
#include <linux/slab.h>

static bool flip_x;
module_param(flip_x, bool, 0644);
MODULE_PARM_DESC(flip_x, "flip x coordinate");

static bool flip_y;
module_param(flip_y, bool, 0644);
MODULE_PARM_DESC(flip_y, "flip y coordinate");

struct eeti_ts_priv {
	struct i2c_client *client;
	struct input_dev *input;
	struct work_struct work;
	struct mutex mutex;
	int irq_gpio, irq, irq_active_high;
};

#define EETI_TS_BITDEPTH	(11)
#define EETI_MAXVAL		((1 << (EETI_TS_BITDEPTH + 1)) - 1)

#define REPORT_BIT_PRESSED	(1 << 0)
#define REPORT_BIT_AD0		(1 << 1)
#define REPORT_BIT_AD1		(1 << 2)
#define REPORT_BIT_HAS_PRESSURE	(1 << 6)
#define REPORT_RES_BITS(v)	(((v) >> 1) + EETI_TS_BITDEPTH)

static inline int eeti_ts_irq_active(struct eeti_ts_priv *priv)
{
	return gpio_get_value(priv->irq_gpio) == priv->irq_active_high;
}

static void eeti_ts_read(struct work_struct *work)
{
	char buf[6];
	unsigned int x, y, res, pressed, to = 100;
	struct eeti_ts_priv *priv =
		container_of(work, struct eeti_ts_priv, work);

	mutex_lock(&priv->mutex);

	while (eeti_ts_irq_active(priv) && --to)
		i2c_master_recv(priv->client, buf, sizeof(buf));

	if (!to) {
		dev_err(&priv->client->dev,
			"unable to clear IRQ - line stuck?\n");
		goto out;
	}

	/* drop non-report packets */
	if (!(buf[0] & 0x80))
		goto out;

	pressed = buf[0] & REPORT_BIT_PRESSED;
	res = REPORT_RES_BITS(buf[0] & (REPORT_BIT_AD0 | REPORT_BIT_AD1));
	x = buf[2] | (buf[1] << 8);
	y = buf[4] | (buf[3] << 8);

	/* fix the range to 11 bits */
	x >>= res - EETI_TS_BITDEPTH;
	y >>= res - EETI_TS_BITDEPTH;

	if (flip_x)
		x = EETI_MAXVAL - x;

	if (flip_y)
		y = EETI_MAXVAL - y;

	if (buf[0] & REPORT_BIT_HAS_PRESSURE)
		input_report_abs(priv->input, ABS_PRESSURE, buf[5]);

	input_report_abs(priv->input, ABS_X, x);
	input_report_abs(priv->input, ABS_Y, y);
	input_report_key(priv->input, BTN_TOUCH, !!pressed);
	input_sync(priv->input);

out:
	mutex_unlock(&priv->mutex);
}

static irqreturn_t eeti_ts_isr(int irq, void *dev_id)
{
	struct eeti_ts_priv *priv = dev_id;

	 /* postpone I2C transactions as we are atomic */
	schedule_work(&priv->work);

	return IRQ_HANDLED;
}

static void eeti_ts_start(struct eeti_ts_priv *priv)
{
	enable_irq(priv->irq);

	/* Read the events once to arm the IRQ */
	eeti_ts_read(&priv->work);
}

static void eeti_ts_stop(struct eeti_ts_priv *priv)
{
	disable_irq(priv->irq);
	cancel_work_sync(&priv->work);
}

static int eeti_ts_open(struct input_dev *dev)
{
	struct eeti_ts_priv *priv = input_get_drvdata(dev);

	eeti_ts_start(priv);

	return 0;
}

static void eeti_ts_close(struct input_dev *dev)
{
	struct eeti_ts_priv *priv = input_get_drvdata(dev);

	eeti_ts_stop(priv);
}

static int eeti_ts_probe(struct i2c_client *client,
				   const struct i2c_device_id *idp)
{
	struct eeti_ts_platform_data *pdata = dev_get_platdata(&client->dev);
	struct eeti_ts_priv *priv;
	struct input_dev *input;
	unsigned int irq_flags;
	int err = -ENOMEM;

	/*
	 * In contrast to what's described in the datasheet, there seems
	 * to be no way of probing the presence of that device using I2C
	 * commands. So we need to blindly believe it is there, and wait
	 * for interrupts to occur.
	 */

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&client->dev, "failed to allocate driver data\n");
		goto err0;
	}

	mutex_init(&priv->mutex);
	input = input_allocate_device();

	if (!input) {
		dev_err(&client->dev, "Failed to allocate input device.\n");
		goto err1;
	}

	input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

	input_set_abs_params(input, ABS_X, 0, EETI_MAXVAL, 0, 0);
	input_set_abs_params(input, ABS_Y, 0, EETI_MAXVAL, 0, 0);
	input_set_abs_params(input, ABS_PRESSURE, 0, 0xff, 0, 0);

	input->name = client->name;
	input->id.bustype = BUS_I2C;
	input->dev.parent = &client->dev;
	input->open = eeti_ts_open;
	input->close = eeti_ts_close;

	priv->client = client;
	priv->input = input;
	priv->irq_gpio = pdata->irq_gpio;
	priv->irq = gpio_to_irq(pdata->irq_gpio);

	err = gpio_request_one(pdata->irq_gpio, GPIOF_IN, client->name);
	if (err < 0)
		goto err1;

	priv->irq_active_high = pdata->irq_active_high;

	irq_flags = priv->irq_active_high ?
		IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;

	INIT_WORK(&priv->work, eeti_ts_read);
	i2c_set_clientdata(client, priv);
	input_set_drvdata(input, priv);

	err = input_register_device(input);
	if (err)
		goto err2;

	err = request_irq(priv->irq, eeti_ts_isr, irq_flags,
			  client->name, priv);
	if (err) {
		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
		goto err3;
	}

	/*
	 * Disable the device for now. It will be enabled once the
	 * input device is opened.
	 */
	eeti_ts_stop(priv);

	device_init_wakeup(&client->dev, 0);
	return 0;

err3:
	input_unregister_device(input);
	input = NULL; /* so we dont try to free it below */
err2:
	gpio_free(pdata->irq_gpio);
err1:
	input_free_device(input);
	kfree(priv);
err0:
	return err;
}

static int eeti_ts_remove(struct i2c_client *client)
{
	struct eeti_ts_priv *priv = i2c_get_clientdata(client);

	free_irq(priv->irq, priv);
	/*
	 * eeti_ts_stop() leaves IRQ disabled. We need to re-enable it
	 * so that device still works if we reload the driver.
	 */
	enable_irq(priv->irq);

	input_unregister_device(priv->input);
	kfree(priv);

	return 0;
}

static int __maybe_unused eeti_ts_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct eeti_ts_priv *priv = i2c_get_clientdata(client);
	struct input_dev *input_dev = priv->input;

	mutex_lock(&input_dev->mutex);

	if (input_dev->users)
		eeti_ts_stop(priv);

	mutex_unlock(&input_dev->mutex);

	if (device_may_wakeup(&client->dev))
		enable_irq_wake(priv->irq);

	return 0;
}

static int __maybe_unused eeti_ts_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct eeti_ts_priv *priv = i2c_get_clientdata(client);
	struct input_dev *input_dev = priv->input;

	if (device_may_wakeup(&client->dev))
		disable_irq_wake(priv->irq);

	mutex_lock(&input_dev->mutex);

	if (input_dev->users)
		eeti_ts_start(priv);

	mutex_unlock(&input_dev->mutex);

	return 0;
}

static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume);

static const struct i2c_device_id eeti_ts_id[] = {
	{ "eeti_ts", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, eeti_ts_id);

static struct i2c_driver eeti_ts_driver = {
	.driver = {
		.name = "eeti_ts",
		.pm = &eeti_ts_pm,
	},
	.probe = eeti_ts_probe,
	.remove = eeti_ts_remove,
	.id_table = eeti_ts_id,
};

module_i2c_driver(eeti_ts_driver);

MODULE_DESCRIPTION("EETI Touchscreen driver");
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
MODULE_LICENSE("GPL");
