/*
 * Intel MID Resistive Touch Screen Driver
 *
 * Copyright (C) 2008 Intel Corp
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * This program 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; version 2 of the License.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com)
 *			    Ramesh Agarwal (ramesh.agarwal@intel.com)
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * TODO:
 *	review conversion of r/m/w sequences
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/param.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <asm/intel_scu_ipc.h>

/* PMIC Interrupt registers */
#define PMIC_REG_ID1		0x00 /* PMIC ID1 register */

/* PMIC Interrupt registers */
#define PMIC_REG_INT		0x04 /* PMIC interrupt register */
#define PMIC_REG_MINT		0x05 /* PMIC interrupt mask register */

/* ADC Interrupt registers */
#define PMIC_REG_ADCINT		0x5F /* ADC interrupt register */
#define PMIC_REG_MADCINT	0x60 /* ADC interrupt mask register */

/* ADC Control registers */
#define PMIC_REG_ADCCNTL1	0x61 /* ADC control register */

/* ADC Channel Selection registers */
#define PMICADDR0		0xA4
#define END_OF_CHANNEL		0x1F

/* ADC Result register */
#define PMIC_REG_ADCSNS0H	0x64

/* ADC channels for touch screen */
#define MRST_TS_CHAN10		0xA /* Touch screen X+ connection */
#define MRST_TS_CHAN11		0xB /* Touch screen X- connection */
#define MRST_TS_CHAN12		0xC /* Touch screen Y+ connection */
#define MRST_TS_CHAN13		0xD /* Touch screen Y- connection */

/* Touch screen channel BIAS constants */
#define MRST_XBIAS		0x20
#define MRST_YBIAS		0x40
#define MRST_ZBIAS		0x80

/* Touch screen coordinates */
#define MRST_X_MIN		10
#define MRST_X_MAX		1024
#define MRST_X_FUZZ		5
#define MRST_Y_MIN		10
#define MRST_Y_MAX		1024
#define MRST_Y_FUZZ		5
#define MRST_PRESSURE_MIN	0
#define MRST_PRESSURE_NOMINAL	50
#define MRST_PRESSURE_MAX	100

#define WAIT_ADC_COMPLETION	10 /* msec */

/* PMIC ADC round robin delays */
#define ADC_LOOP_DELAY0		0x0 /* Continuous loop */
#define ADC_LOOP_DELAY1		0x1 /* 4.5  ms approximate */

/* PMIC Vendor Identifiers */
#define PMIC_VENDOR_FS		0 /* PMIC vendor FreeScale */
#define PMIC_VENDOR_MAXIM	1 /* PMIC vendor MAXIM */
#define PMIC_VENDOR_NEC		2 /* PMIC vendor NEC */
#define MRSTOUCH_MAX_CHANNELS	32 /* Maximum ADC channels */

/* Touch screen device structure */
struct mrstouch_dev {
	struct device *dev; /* device associated with touch screen */
	struct input_dev *input;
	char phys[32];
	u16 asr;		/* Address selection register */
	int irq;
	unsigned int vendor;	/* PMIC vendor */
	unsigned int rev;	/* PMIC revision */

	int (*read_prepare)(struct mrstouch_dev *tsdev);
	int (*read)(struct mrstouch_dev *tsdev, u16 *x, u16 *y, u16 *z);
	int (*read_finish)(struct mrstouch_dev *tsdev);
};


/*************************** NEC and Maxim Interface ************************/

static int mrstouch_nec_adc_read_prepare(struct mrstouch_dev *tsdev)
{
	return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0, 0x20);
}

/*
 * Enables PENDET interrupt.
 */
static int mrstouch_nec_adc_read_finish(struct mrstouch_dev *tsdev)
{
	int err;

	err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x20, 0x20);
	if (!err)
		err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, 0, 0x05);

	return err;
}

/*
 * Reads PMIC ADC touch screen result
 * Reads ADC storage registers for higher 7 and lower 3 bits and
 * converts the two readings into a single value and turns off gain bit
 */
static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm)
{
	int err;
	u16 result;
	u32 res;

	result = PMIC_REG_ADCSNS0H + offset;

	if (chan == MRST_TS_CHAN12)
		result += 4;

	err = intel_scu_ipc_ioread32(result, &res);
	if (err)
		return err;

	/* Mash the bits up */

	*vp = (res & 0xFF) << 3;	/* Highest 7 bits */
	*vp |= (res >> 8) & 0x07;	/* Lower 3 bits */
	*vp &= 0x3FF;

	res >>= 16;

	*vm = (res & 0xFF) << 3;	/* Highest 7 bits */
	*vm |= (res >> 8) & 0x07;	/* Lower 3 bits */
	*vm &= 0x3FF;

	return 0;
}

/*
 * Enables X, Y and Z bias values
 * Enables YPYM for X channels and XPXM for Y channels
 */
static int mrstouch_ts_bias_set(uint offset, uint bias)
{
	int count;
	u16 chan, start;
	u16 reg[4];
	u8 data[4];

	chan = PMICADDR0 + offset;
	start = MRST_TS_CHAN10;

	for (count = 0; count <= 3; count++) {
		reg[count] = chan++;
		data[count] = bias | (start + count);
	}

	return intel_scu_ipc_writev(reg, data, 4);
}

/* To read touch screen channel values */
static int mrstouch_nec_adc_read(struct mrstouch_dev *tsdev,
				 u16 *x, u16 *y, u16 *z)
{
	int err;
	u16 xm, ym, zm;

	/* configure Y bias for X channels */
	err = mrstouch_ts_bias_set(tsdev->asr, MRST_YBIAS);
	if (err)
		goto ipc_error;

	msleep(WAIT_ADC_COMPLETION);

	/* read x+ and x- channels */
	err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, x, &xm);
	if (err)
		goto ipc_error;

	/* configure x bias for y channels */
	err = mrstouch_ts_bias_set(tsdev->asr, MRST_XBIAS);
	if (err)
		goto ipc_error;

	msleep(WAIT_ADC_COMPLETION);

	/* read y+ and y- channels */
	err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, y, &ym);
	if (err)
		goto ipc_error;

	/* configure z bias for x and y channels */
	err = mrstouch_ts_bias_set(tsdev->asr, MRST_ZBIAS);
	if (err)
		goto ipc_error;

	msleep(WAIT_ADC_COMPLETION);

	/* read z+ and z- channels */
	err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, z, &zm);
	if (err)
		goto ipc_error;

	return 0;

ipc_error:
	dev_err(tsdev->dev, "ipc error during adc read\n");
	return err;
}


/*************************** Freescale Interface ************************/

static int mrstouch_fs_adc_read_prepare(struct mrstouch_dev *tsdev)
{
	int err, count;
	u16 chan;
	u16 reg[5];
	u8 data[5];

	/* Stop the ADC */
	err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02);
	if (err)
		goto ipc_error;

	chan = PMICADDR0 + tsdev->asr;

	/* Set X BIAS */
	for (count = 0; count <= 3; count++) {
		reg[count] = chan++;
		data[count] = 0x2A;
	}
	reg[count] =  chan++; /* Dummy */
	data[count] = 0;

	err = intel_scu_ipc_writev(reg, data, 5);
	if (err)
		goto ipc_error;

	msleep(WAIT_ADC_COMPLETION);

	/* Set Y BIAS */
	for (count = 0; count <= 3; count++) {
		reg[count] = chan++;
		data[count] = 0x4A;
	}
	reg[count] = chan++; /* Dummy */
	data[count] = 0;

	err = intel_scu_ipc_writev(reg, data, 5);
	if (err)
		goto ipc_error;

	msleep(WAIT_ADC_COMPLETION);

	/* Set Z BIAS */
	err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A);
	if (err)
		goto ipc_error;

	msleep(WAIT_ADC_COMPLETION);

	return 0;

ipc_error:
	dev_err(tsdev->dev, "ipc error during %s\n", __func__);
	return err;
}

static int mrstouch_fs_adc_read(struct mrstouch_dev *tsdev,
				u16 *x, u16 *y, u16 *z)
{
	int err;
	u16 result;
	u16 reg[4];
	u8 data[4];

	result = PMIC_REG_ADCSNS0H + tsdev->asr;

	reg[0] = result + 4;
	reg[1] = result + 5;
	reg[2] = result + 16;
	reg[3] = result + 17;

	err = intel_scu_ipc_readv(reg, data, 4);
	if (err)
		goto ipc_error;

	*x = data[0] << 3; /* Higher 7 bits */
	*x |= data[1] & 0x7; /* Lower 3 bits */
	*x &= 0x3FF;

	*y = data[2] << 3; /* Higher 7 bits */
	*y |= data[3] & 0x7; /* Lower 3 bits */
	*y &= 0x3FF;

	/* Read Z value */
	reg[0] = result + 28;
	reg[1] = result + 29;

	err = intel_scu_ipc_readv(reg, data, 4);
	if (err)
		goto ipc_error;

	*z = data[0] << 3; /* Higher 7 bits */
	*z |= data[1] & 0x7; /* Lower 3 bits */
	*z &= 0x3FF;

	return 0;

ipc_error:
	dev_err(tsdev->dev, "ipc error during %s\n", __func__);
	return err;
}

static int mrstouch_fs_adc_read_finish(struct mrstouch_dev *tsdev)
{
	int err, count;
	u16 chan;
	u16 reg[5];
	u8 data[5];

	/* Clear all TS channels */
	chan = PMICADDR0 + tsdev->asr;
	for (count = 0; count <= 4; count++) {
		reg[count] = chan++;
		data[count] = 0;
	}
	err = intel_scu_ipc_writev(reg, data, 5);
	if (err)
		goto ipc_error;

	for (count = 0; count <= 4; count++) {
		reg[count] = chan++;
		data[count] = 0;
	}
	err = intel_scu_ipc_writev(reg, data, 5);
	if (err)
		goto ipc_error;

	err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000);
	if (err)
		goto ipc_error;

	/* Start ADC */
	err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02);
	if (err)
		goto ipc_error;

	return 0;

ipc_error:
	dev_err(tsdev->dev, "ipc error during %s\n", __func__);
	return err;
}

static void mrstouch_report_event(struct input_dev *input,
			unsigned int x, unsigned int y, unsigned int z)
{
	if (z > MRST_PRESSURE_NOMINAL) {
		/* Pen touched, report button touch and coordinates */
		input_report_key(input, BTN_TOUCH, 1);
		input_report_abs(input, ABS_X, x);
		input_report_abs(input, ABS_Y, y);
	} else {
		input_report_key(input, BTN_TOUCH, 0);
	}

	input_report_abs(input, ABS_PRESSURE, z);
	input_sync(input);
}

/* PENDET interrupt handler */
static irqreturn_t mrstouch_pendet_irq(int irq, void *dev_id)
{
	struct mrstouch_dev *tsdev = dev_id;
	u16 x, y, z;

	/*
	 * Should we lower thread priority? Probably not, since we are
	 * not spinning but sleeping...
	 */

	if (tsdev->read_prepare(tsdev))
		goto out;

	do {
		if (tsdev->read(tsdev, &x, &y, &z))
			break;

		mrstouch_report_event(tsdev->input, x, y, z);
	} while (z > MRST_PRESSURE_NOMINAL);

	tsdev->read_finish(tsdev);

out:
	return IRQ_HANDLED;
}

/* Utility to read PMIC ID */
static int __devinit mrstouch_read_pmic_id(uint *vendor, uint *rev)
{
	int err;
	u8 r;

	err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r);
	if (err)
		return err;

	*vendor = r & 0x7;
	*rev = (r >> 3) & 0x7;

	return 0;
}

/*
 * Parse ADC channels to find end of the channel configured by other ADC user
 * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels
 */
static int __devinit mrstouch_chan_parse(struct mrstouch_dev *tsdev)
{
	int err, i, found;
	u8 r8;

	found = -1;

	for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) {
		if (found >= 0)
			break;

		err = intel_scu_ipc_ioread8(PMICADDR0 + i, &r8);
		if (err)
			return err;

		if (r8 == END_OF_CHANNEL) {
			found = i;
			break;
		}
	}
	if (found < 0)
		return 0;

	if (tsdev->vendor == PMIC_VENDOR_FS) {
		if (found && found > (MRSTOUCH_MAX_CHANNELS - 18))
			return -ENOSPC;
	} else {
		if (found && found > (MRSTOUCH_MAX_CHANNELS - 4))
			return -ENOSPC;
	}
	return found;
}


/*
 * Writes touch screen channels to ADC address selection registers
 */
static int __devinit mrstouch_ts_chan_set(uint offset)
{
	u16 chan;

	int ret, count;

	chan = PMICADDR0 + offset;
	for (count = 0; count <= 3; count++) {
		ret = intel_scu_ipc_iowrite8(chan++, MRST_TS_CHAN10 + count);
		if (ret)
			return ret;
	}
	return intel_scu_ipc_iowrite8(chan++, END_OF_CHANNEL);
}

/* Initialize ADC */
static int __devinit mrstouch_adc_init(struct mrstouch_dev *tsdev)
{
	int err, start;
	u8 ra, rm;

	err = mrstouch_read_pmic_id(&tsdev->vendor, &tsdev->rev);
	if (err) {
		dev_err(tsdev->dev, "Unable to read PMIC id\n");
		return err;
	}

	switch (tsdev->vendor) {
	case PMIC_VENDOR_NEC:
	case PMIC_VENDOR_MAXIM:
		tsdev->read_prepare = mrstouch_nec_adc_read_prepare;
		tsdev->read = mrstouch_nec_adc_read;
		tsdev->read_finish = mrstouch_nec_adc_read_finish;
		break;

	case PMIC_VENDOR_FS:
		tsdev->read_prepare = mrstouch_fs_adc_read_prepare;
		tsdev->read = mrstouch_fs_adc_read;
		tsdev->read_finish = mrstouch_fs_adc_read_finish;
		break;

	default:
		dev_err(tsdev->dev,
			"Unsupported touchscreen: %d\n", tsdev->vendor);
		return -ENXIO;
	}

	start = mrstouch_chan_parse(tsdev);
	if (start < 0) {
		dev_err(tsdev->dev, "Unable to parse channels\n");
		return start;
	}

	tsdev->asr = start;

	/*
	 * ADC power on, start, enable PENDET and set loop delay
	 * ADC loop delay is set to 4.5 ms approximately
	 * Loop delay more than this results in jitter in adc readings
	 * Setting loop delay to 0 (continous loop) in MAXIM stops PENDET
	 * interrupt generation sometimes.
	 */

	if (tsdev->vendor == PMIC_VENDOR_FS) {
		ra = 0xE0 | ADC_LOOP_DELAY0;
		rm = 0x5;
	} else {
		/* NEC and MAXIm not consistent with loop delay 0 */
		ra = 0xE0 | ADC_LOOP_DELAY1;
		rm = 0x0;

		/* configure touch screen channels */
		err = mrstouch_ts_chan_set(tsdev->asr);
		if (err)
			return err;
	}

	err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7);
	if (err)
		return err;

	err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03);
	if (err)
		return err;

	return 0;
}


/* Probe function for touch screen driver */
static int __devinit mrstouch_probe(struct platform_device *pdev)
{
	struct mrstouch_dev *tsdev;
	struct input_dev *input;
	int err;
	int irq;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "no interrupt assigned\n");
		return -EINVAL;
	}

	tsdev = kzalloc(sizeof(struct mrstouch_dev), GFP_KERNEL);
	input = input_allocate_device();
	if (!tsdev || !input) {
		dev_err(&pdev->dev, "unable to allocate memory\n");
		err = -ENOMEM;
		goto err_free_mem;
	}

	tsdev->dev = &pdev->dev;
	tsdev->input = input;
	tsdev->irq = irq;

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

	err = mrstouch_adc_init(tsdev);
	if (err) {
		dev_err(&pdev->dev, "ADC initialization failed\n");
		goto err_free_mem;
	}

	input->name = "mrst_touchscreen";
	input->phys = tsdev->phys;
	input->dev.parent = tsdev->dev;

	input->id.vendor = tsdev->vendor;
	input->id.version = tsdev->rev;

	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(tsdev->input, ABS_X,
			     MRST_X_MIN, MRST_X_MAX, MRST_X_FUZZ, 0);
	input_set_abs_params(tsdev->input, ABS_Y,
			     MRST_Y_MIN, MRST_Y_MAX, MRST_Y_FUZZ, 0);
	input_set_abs_params(tsdev->input, ABS_PRESSURE,
			     MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0);

	err = request_threaded_irq(tsdev->irq, NULL, mrstouch_pendet_irq,
				   0, "mrstouch", tsdev);
	if (err) {
		dev_err(tsdev->dev, "unable to allocate irq\n");
		goto err_free_mem;
	}

	err = input_register_device(tsdev->input);
	if (err) {
		dev_err(tsdev->dev, "unable to register input device\n");
		goto err_free_irq;
	}

	platform_set_drvdata(pdev, tsdev);
	return 0;

err_free_irq:
	free_irq(tsdev->irq, tsdev);
err_free_mem:
	input_free_device(input);
	kfree(tsdev);
	return err;
}

static int __devexit mrstouch_remove(struct platform_device *pdev)
{
	struct mrstouch_dev *tsdev = platform_get_drvdata(pdev);

	free_irq(tsdev->irq, tsdev);
	input_unregister_device(tsdev->input);
	kfree(tsdev);

	platform_set_drvdata(pdev, NULL);

	return 0;
}

static struct platform_driver mrstouch_driver = {
	.driver = {
		.name	= "pmic_touch",
		.owner	= THIS_MODULE,
	},
	.probe		= mrstouch_probe,
	.remove		= __devexit_p(mrstouch_remove),
};

static int __init mrstouch_init(void)
{
	return platform_driver_register(&mrstouch_driver);
}
module_init(mrstouch_init);

static void __exit mrstouch_exit(void)
{
	platform_driver_unregister(&mrstouch_driver);
}
module_exit(mrstouch_exit);

MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com");
MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver");
MODULE_LICENSE("GPL");
