/*
 * Driver for AUO in-cell touchscreens
 *
 * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de>
 *
 * loosely based on auo_touch.c from Dell Streak vendor-kernel
 *
 * Copyright (c) 2008 QUALCOMM Incorporated.
 * Copyright (c) 2008 QUALCOMM USA, INC.
 *
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program 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.
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/input/auo-pixcir-ts.h>

/*
 * Coordinate calculation:
 * X1 = X1_LSB + X1_MSB*256
 * Y1 = Y1_LSB + Y1_MSB*256
 * X2 = X2_LSB + X2_MSB*256
 * Y2 = Y2_LSB + Y2_MSB*256
 */
#define AUO_PIXCIR_REG_X1_LSB		0x00
#define AUO_PIXCIR_REG_X1_MSB		0x01
#define AUO_PIXCIR_REG_Y1_LSB		0x02
#define AUO_PIXCIR_REG_Y1_MSB		0x03
#define AUO_PIXCIR_REG_X2_LSB		0x04
#define AUO_PIXCIR_REG_X2_MSB		0x05
#define AUO_PIXCIR_REG_Y2_LSB		0x06
#define AUO_PIXCIR_REG_Y2_MSB		0x07

#define AUO_PIXCIR_REG_STRENGTH		0x0d
#define AUO_PIXCIR_REG_STRENGTH_X1_LSB	0x0e
#define AUO_PIXCIR_REG_STRENGTH_X1_MSB	0x0f

#define AUO_PIXCIR_REG_RAW_DATA_X	0x2b
#define AUO_PIXCIR_REG_RAW_DATA_Y	0x4f

#define AUO_PIXCIR_REG_X_SENSITIVITY	0x6f
#define AUO_PIXCIR_REG_Y_SENSITIVITY	0x70
#define AUO_PIXCIR_REG_INT_SETTING	0x71
#define AUO_PIXCIR_REG_INT_WIDTH	0x72
#define AUO_PIXCIR_REG_POWER_MODE	0x73

#define AUO_PIXCIR_REG_VERSION		0x77
#define AUO_PIXCIR_REG_CALIBRATE	0x78

#define AUO_PIXCIR_REG_TOUCHAREA_X1	0x1e
#define AUO_PIXCIR_REG_TOUCHAREA_Y1	0x1f
#define AUO_PIXCIR_REG_TOUCHAREA_X2	0x20
#define AUO_PIXCIR_REG_TOUCHAREA_Y2	0x21

#define AUO_PIXCIR_REG_EEPROM_CALIB_X	0x42
#define AUO_PIXCIR_REG_EEPROM_CALIB_Y	0xad

#define AUO_PIXCIR_INT_TPNUM_MASK	0xe0
#define AUO_PIXCIR_INT_TPNUM_SHIFT	5
#define AUO_PIXCIR_INT_RELEASE		(1 << 4)
#define AUO_PIXCIR_INT_ENABLE		(1 << 3)
#define AUO_PIXCIR_INT_POL_HIGH		(1 << 2)
#define AUO_PIXCIR_INT_MODE_MASK	0x03

/*
 * Power modes:
 * active:	scan speed 60Hz
 * sleep:	scan speed 10Hz can be auto-activated, wakeup on 1st touch
 * deep sleep:	scan speed 1Hz can only be entered or left manually.
 */
#define AUO_PIXCIR_POWER_ACTIVE		0x00
#define AUO_PIXCIR_POWER_SLEEP		0x01
#define AUO_PIXCIR_POWER_DEEP_SLEEP	0x02
#define AUO_PIXCIR_POWER_MASK		0x03

#define AUO_PIXCIR_POWER_ALLOW_SLEEP	(1 << 2)
#define AUO_PIXCIR_POWER_IDLE_TIME(ms)	((ms & 0xf) << 4)

#define AUO_PIXCIR_CALIBRATE		0x03

#define AUO_PIXCIR_EEPROM_CALIB_X_LEN	62
#define AUO_PIXCIR_EEPROM_CALIB_Y_LEN	36

#define AUO_PIXCIR_RAW_DATA_X_LEN	18
#define AUO_PIXCIR_RAW_DATA_Y_LEN	11

#define AUO_PIXCIR_STRENGTH_ENABLE	(1 << 0)

/* Touchscreen absolute values */
#define AUO_PIXCIR_REPORT_POINTS	2
#define AUO_PIXCIR_MAX_AREA		0xff
#define AUO_PIXCIR_PENUP_TIMEOUT_MS	10

struct auo_pixcir_ts {
	struct i2c_client	*client;
	struct input_dev	*input;
	char			phys[32];

	/* special handling for touch_indicate interupt mode */
	bool			touch_ind_mode;

	wait_queue_head_t	wait;
	bool			stopped;
};

struct auo_point_t {
	int	coord_x;
	int	coord_y;
	int	area_major;
	int	area_minor;
	int	orientation;
};

static int auo_pixcir_collect_data(struct auo_pixcir_ts *ts,
				   struct auo_point_t *point)
{
	struct i2c_client *client = ts->client;
	const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data;
	uint8_t raw_coord[8];
	uint8_t raw_area[4];
	int i, ret;

	/* touch coordinates */
	ret = i2c_smbus_read_i2c_block_data(client, AUO_PIXCIR_REG_X1_LSB,
					    8, raw_coord);
	if (ret < 0) {
		dev_err(&client->dev, "failed to read coordinate, %d\n", ret);
		return ret;
	}

	/* touch area */
	ret = i2c_smbus_read_i2c_block_data(client, AUO_PIXCIR_REG_TOUCHAREA_X1,
					    4, raw_area);
	if (ret < 0) {
		dev_err(&client->dev, "could not read touch area, %d\n", ret);
		return ret;
	}

	for (i = 0; i < AUO_PIXCIR_REPORT_POINTS; i++) {
		point[i].coord_x =
			raw_coord[4 * i + 1] << 8 | raw_coord[4 * i];
		point[i].coord_y =
			raw_coord[4 * i + 3] << 8 | raw_coord[4 * i + 2];

		if (point[i].coord_x > pdata->x_max ||
		    point[i].coord_y > pdata->y_max) {
			dev_warn(&client->dev, "coordinates (%d,%d) invalid\n",
				point[i].coord_x, point[i].coord_y);
			point[i].coord_x = point[i].coord_y = 0;
		}

		/* determine touch major, minor and orientation */
		point[i].area_major = max(raw_area[2 * i], raw_area[2 * i + 1]);
		point[i].area_minor = min(raw_area[2 * i], raw_area[2 * i + 1]);
		point[i].orientation = raw_area[2 * i] > raw_area[2 * i + 1];
	}

	return 0;
}

static irqreturn_t auo_pixcir_interrupt(int irq, void *dev_id)
{
	struct auo_pixcir_ts *ts = dev_id;
	struct i2c_client *client = ts->client;
	const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data;
	struct auo_point_t point[AUO_PIXCIR_REPORT_POINTS];
	int i;
	int ret;
	int fingers = 0;
	int abs = -1;

	while (!ts->stopped) {

		/* check for up event in touch touch_ind_mode */
		if (ts->touch_ind_mode) {
			if (gpio_get_value(pdata->gpio_int) == 0) {
				input_mt_sync(ts->input);
				input_report_key(ts->input, BTN_TOUCH, 0);
				input_sync(ts->input);
				break;
			}
		}

		ret = auo_pixcir_collect_data(ts, point);
		if (ret < 0) {
			/* we want to loop only in touch_ind_mode */
			if (!ts->touch_ind_mode)
				break;

			wait_event_timeout(ts->wait, ts->stopped,
				msecs_to_jiffies(AUO_PIXCIR_PENUP_TIMEOUT_MS));
			continue;
		}

		for (i = 0; i < AUO_PIXCIR_REPORT_POINTS; i++) {
			if (point[i].coord_x > 0 || point[i].coord_y > 0) {
				input_report_abs(ts->input, ABS_MT_POSITION_X,
						 point[i].coord_x);
				input_report_abs(ts->input, ABS_MT_POSITION_Y,
						 point[i].coord_y);
				input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR,
						 point[i].area_major);
				input_report_abs(ts->input, ABS_MT_TOUCH_MINOR,
						 point[i].area_minor);
				input_report_abs(ts->input, ABS_MT_ORIENTATION,
						 point[i].orientation);
				input_mt_sync(ts->input);

				/* use first finger as source for singletouch */
				if (fingers == 0)
					abs = i;

				/* number of touch points could also be queried
				 * via i2c but would require an additional call
				 */
				fingers++;
			}
		}

		input_report_key(ts->input, BTN_TOUCH, fingers > 0);

		if (abs > -1) {
			input_report_abs(ts->input, ABS_X, point[abs].coord_x);
			input_report_abs(ts->input, ABS_Y, point[abs].coord_y);
		}

		input_sync(ts->input);

		/* we want to loop only in touch_ind_mode */
		if (!ts->touch_ind_mode)
			break;

		wait_event_timeout(ts->wait, ts->stopped,
				 msecs_to_jiffies(AUO_PIXCIR_PENUP_TIMEOUT_MS));
	}

	return IRQ_HANDLED;
}

/*
 * Set the power mode of the device.
 * Valid modes are
 * - AUO_PIXCIR_POWER_ACTIVE
 * - AUO_PIXCIR_POWER_SLEEP - automatically left on first touch
 * - AUO_PIXCIR_POWER_DEEP_SLEEP
 */
static int auo_pixcir_power_mode(struct auo_pixcir_ts *ts, int mode)
{
	struct i2c_client *client = ts->client;
	int ret;

	ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_POWER_MODE);
	if (ret < 0) {
		dev_err(&client->dev, "unable to read reg %Xh, %d\n",
			AUO_PIXCIR_REG_POWER_MODE, ret);
		return ret;
	}

	ret &= ~AUO_PIXCIR_POWER_MASK;
	ret |= mode;

	ret = i2c_smbus_write_byte_data(client, AUO_PIXCIR_REG_POWER_MODE, ret);
	if (ret) {
		dev_err(&client->dev, "unable to write reg %Xh, %d\n",
			AUO_PIXCIR_REG_POWER_MODE, ret);
		return ret;
	}

	return 0;
}

static __devinit int auo_pixcir_int_config(struct auo_pixcir_ts *ts,
					   int int_setting)
{
	struct i2c_client *client = ts->client;
	struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data;
	int ret;

	ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_INT_SETTING);
	if (ret < 0) {
		dev_err(&client->dev, "unable to read reg %Xh, %d\n",
			AUO_PIXCIR_REG_INT_SETTING, ret);
		return ret;
	}

	ret &= ~AUO_PIXCIR_INT_MODE_MASK;
	ret |= int_setting;
	ret |= AUO_PIXCIR_INT_POL_HIGH; /* always use high for interrupts */

	ret = i2c_smbus_write_byte_data(client, AUO_PIXCIR_REG_INT_SETTING,
					ret);
	if (ret < 0) {
		dev_err(&client->dev, "unable to write reg %Xh, %d\n",
			AUO_PIXCIR_REG_INT_SETTING, ret);
		return ret;
	}

	ts->touch_ind_mode = pdata->int_setting == AUO_PIXCIR_INT_TOUCH_IND;

	return 0;
}

/* control the generation of interrupts on the device side */
static int auo_pixcir_int_toggle(struct auo_pixcir_ts *ts, bool enable)
{
	struct i2c_client *client = ts->client;
	int ret;

	ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_INT_SETTING);
	if (ret < 0) {
		dev_err(&client->dev, "unable to read reg %Xh, %d\n",
			AUO_PIXCIR_REG_INT_SETTING, ret);
		return ret;
	}

	if (enable)
		ret |= AUO_PIXCIR_INT_ENABLE;
	else
		ret &= ~AUO_PIXCIR_INT_ENABLE;

	ret = i2c_smbus_write_byte_data(client, AUO_PIXCIR_REG_INT_SETTING,
					ret);
	if (ret < 0) {
		dev_err(&client->dev, "unable to write reg %Xh, %d\n",
			AUO_PIXCIR_REG_INT_SETTING, ret);
		return ret;
	}

	return 0;
}

static int auo_pixcir_start(struct auo_pixcir_ts *ts)
{
	struct i2c_client *client = ts->client;
	int ret;

	ret = auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_ACTIVE);
	if (ret < 0) {
		dev_err(&client->dev, "could not set power mode, %d\n",
			ret);
		return ret;
	}

	ts->stopped = false;
	mb();
	enable_irq(client->irq);

	ret = auo_pixcir_int_toggle(ts, 1);
	if (ret < 0) {
		dev_err(&client->dev, "could not enable interrupt, %d\n",
			ret);
		disable_irq(client->irq);
		return ret;
	}

	return 0;
}

static int auo_pixcir_stop(struct auo_pixcir_ts *ts)
{
	struct i2c_client *client = ts->client;
	int ret;

	ret = auo_pixcir_int_toggle(ts, 0);
	if (ret < 0) {
		dev_err(&client->dev, "could not disable interrupt, %d\n",
			ret);
		return ret;
	}

	/* disable receiving of interrupts */
	disable_irq(client->irq);
	ts->stopped = true;
	mb();
	wake_up(&ts->wait);

	return auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_DEEP_SLEEP);
}

static int auo_pixcir_input_open(struct input_dev *dev)
{
	struct auo_pixcir_ts *ts = input_get_drvdata(dev);
	int ret;

	ret = auo_pixcir_start(ts);
	if (ret)
		return ret;

	return 0;
}

static void auo_pixcir_input_close(struct input_dev *dev)
{
	struct auo_pixcir_ts *ts = input_get_drvdata(dev);

	auo_pixcir_stop(ts);

	return;
}

#ifdef CONFIG_PM_SLEEP
static int auo_pixcir_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct auo_pixcir_ts *ts = i2c_get_clientdata(client);
	struct input_dev *input = ts->input;
	int ret = 0;

	mutex_lock(&input->mutex);

	/* when configured as wakeup source, device should always wake system
	 * therefore start device if necessary
	 */
	if (device_may_wakeup(&client->dev)) {
		/* need to start device if not open, to be wakeup source */
		if (!input->users) {
			ret = auo_pixcir_start(ts);
			if (ret)
				goto unlock;
		}

		enable_irq_wake(client->irq);
		ret = auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_SLEEP);
	} else if (input->users) {
		ret = auo_pixcir_stop(ts);
	}

unlock:
	mutex_unlock(&input->mutex);

	return ret;
}

static int auo_pixcir_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct auo_pixcir_ts *ts = i2c_get_clientdata(client);
	struct input_dev *input = ts->input;
	int ret = 0;

	mutex_lock(&input->mutex);

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

		/* need to stop device if it was not open on suspend */
		if (!input->users) {
			ret = auo_pixcir_stop(ts);
			if (ret)
				goto unlock;
		}

		/* device wakes automatically from SLEEP */
	} else if (input->users) {
		ret = auo_pixcir_start(ts);
	}

unlock:
	mutex_unlock(&input->mutex);

	return ret;
}
#endif

static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops, auo_pixcir_suspend,
			 auo_pixcir_resume);

static int __devinit auo_pixcir_probe(struct i2c_client *client,
				      const struct i2c_device_id *id)
{
	const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data;
	struct auo_pixcir_ts *ts;
	struct input_dev *input_dev;
	int ret;

	if (!pdata)
		return -EINVAL;

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

	ret = gpio_request(pdata->gpio_int, "auo_pixcir_ts_int");
	if (ret) {
		dev_err(&client->dev, "request of gpio %d failed, %d\n",
			pdata->gpio_int, ret);
		goto err_gpio_int;
	}

	if (pdata->init_hw)
		pdata->init_hw(client);

	ts->client = client;
	ts->touch_ind_mode = 0;
	init_waitqueue_head(&ts->wait);

	snprintf(ts->phys, sizeof(ts->phys),
		 "%s/input0", dev_name(&client->dev));

	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(&client->dev, "could not allocate input device\n");
		goto err_input_alloc;
	}

	ts->input = input_dev;

	input_dev->name = "AUO-Pixcir touchscreen";
	input_dev->phys = ts->phys;
	input_dev->id.bustype = BUS_I2C;
	input_dev->dev.parent = &client->dev;

	input_dev->open = auo_pixcir_input_open;
	input_dev->close = auo_pixcir_input_close;

	__set_bit(EV_ABS, input_dev->evbit);
	__set_bit(EV_KEY, input_dev->evbit);

	__set_bit(BTN_TOUCH, input_dev->keybit);

	/* For single touch */
	input_set_abs_params(input_dev, ABS_X, 0, pdata->x_max, 0, 0);
	input_set_abs_params(input_dev, ABS_Y, 0, pdata->y_max, 0, 0);

	/* For multi touch */
	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
			     pdata->x_max, 0, 0);
	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
			     pdata->y_max, 0, 0);
	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0,
			     AUO_PIXCIR_MAX_AREA, 0, 0);
	input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0,
			     AUO_PIXCIR_MAX_AREA, 0, 0);
	input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);

	ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_VERSION);
	if (ret < 0)
		goto err_fw_vers;
	dev_info(&client->dev, "firmware version 0x%X\n", ret);

	ret = auo_pixcir_int_config(ts, pdata->int_setting);
	if (ret)
		goto err_fw_vers;

	input_set_drvdata(ts->input, ts);
	ts->stopped = true;

	ret = request_threaded_irq(client->irq, NULL, auo_pixcir_interrupt,
				   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
				   input_dev->name, ts);
	if (ret) {
		dev_err(&client->dev, "irq %d requested failed\n", client->irq);
		goto err_fw_vers;
	}

	/* stop device and put it into deep sleep until it is opened */
	ret = auo_pixcir_stop(ts);
	if (ret < 0)
		goto err_input_register;

	ret = input_register_device(input_dev);
	if (ret) {
		dev_err(&client->dev, "could not register input device\n");
		goto err_input_register;
	}

	i2c_set_clientdata(client, ts);

	return 0;

err_input_register:
	free_irq(client->irq, ts);
err_fw_vers:
	input_free_device(input_dev);
err_input_alloc:
	if (pdata->exit_hw)
		pdata->exit_hw(client);
	gpio_free(pdata->gpio_int);
err_gpio_int:
	kfree(ts);

	return ret;
}

static int __devexit auo_pixcir_remove(struct i2c_client *client)
{
	struct auo_pixcir_ts *ts = i2c_get_clientdata(client);
	const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data;

	free_irq(client->irq, ts);

	input_unregister_device(ts->input);

	if (pdata->exit_hw)
		pdata->exit_hw(client);

	gpio_free(pdata->gpio_int);

	kfree(ts);

	return 0;
}

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

static struct i2c_driver auo_pixcir_driver = {
	.driver = {
		.owner	= THIS_MODULE,
		.name	= "auo_pixcir_ts",
		.pm	= &auo_pixcir_pm_ops,
	},
	.probe		= auo_pixcir_probe,
	.remove		= __devexit_p(auo_pixcir_remove),
	.id_table	= auo_pixcir_idtable,
};

module_i2c_driver(auo_pixcir_driver);

MODULE_DESCRIPTION("AUO-PIXCIR touchscreen driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
