/*
 * 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 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 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 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		= 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>");
