lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Wed, 14 Jul 2010 11:25:48 +0100
From:	Dajun Chen <dajun.chen@...il.com>
To:	dmitry.torokhov@...il.com, dtor@...l.ru
Cc:	linux-kernel@...r.kernel.org
Subject: [PATCHv2 8/11] TOUCHSCREEN: Touch module of DA9052 device driver 
	(RESEND)

TSI module of the device driver for DA9052 PMIC device from Dialog
Semiconductor.

It is a resend for format disruptions in previous submission.

Changes made since last submission:
. collection of raw TSI samples moved from EH to TSI module as per MFD comments
. da9052-tsi.c, da9052-tsi_calibrate.c, da9052_tsi_filter.c changed to
. da9052-ts.c, da9052-ts-core.c and da9052-ts-process.c
. da9052-ts.c: Main tsi driver file
. da9052-ts-core.c; TSI configuration and event handling
. da9052-ts-process.c: TSI data processing
. removal of redundant printk and comments

Linux Kernel Version: 2.6.34

Signed-off-by: D. Chen <dchen@...semi.com>
---
diff -urpN linux-2.6.34/drivers/input/touchscreen/da9052-ts.c
linux-2.6.34_test/drivers/input/touchscreen/da9052-ts.c
--- linux-2.6.34/drivers/input/touchscreen/da9052-ts.c	1970-01-01
05:00:00.000000000 +0500
+++ linux-2.6.34_test/drivers/input/touchscreen/da9052-ts.c	2010-07-01
18:20:48.000000000 +0500
@@ -0,0 +1,219 @@
+/*
+ * Copyright(c) 2009 Dialog Semiconductor Ltd.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * da9052-tsi.c: Driver for Touch Screen interface on DA9052 chip.
+ */
+
+#include <linux/mfd/da9052/reg.h>
+#include <linux/mfd/da9052/tsi.h>
+
+ssize_t da9052_config_state(struct da9052_ts_priv *ts, enum TSI_STATE state)
+{
+	s32 ret;
+
+	if (ts->tsi_conf.state == state)
+		return 0;
+
+	switch (state) {
+	case TSI_AUTO_MODE:
+		ts->tsi_zero_data_cnt = 0;
+
+		ret = da9052_config_auto_mode(ts, DISABLE);
+		if (ret)
+			return 0;
+
+		ret = da9052_config_power_supply(ts, DISABLE);
+		if (ret)
+			return ret;
+
+		ret = da9052_tsi_enable_irq(ts, TSI_PEN_DWN);
+		if (ret)
+			return ret;
+		ts->tsi_conf.tsi_pendown_irq_mask = RESET;
+
+		ret = da9052_tsi_disable_irq(ts, TSI_DATA_RDY);
+		if (ret)
+			return ret;
+		ts->tsi_conf.tsi_ready_irq_mask	  = SET;
+
+		da9052_tsi_reg_pendwn_event(ts);
+
+		ret = da9052_config_pen_detect(ts, ENABLE);
+		if (ret)
+			return ret;
+		break;
+	case TSI_IDLE:
+		ts->pen_dwn_event = RESET;
+
+		ret = da9052_config_pen_detect(ts, DISABLE);
+		if (ret)
+			return ret;
+
+		ret = da9052_config_auto_mode(ts, DISABLE);
+		if (ret)
+			return ret;
+
+		ret = da9052_config_power_supply(ts, DISABLE);
+		if (ret)
+			return ret;
+
+		if (ts->pd_reg_status) {
+			ts->da9052->unregister_event_notifier(ts->da9052,
+								&ts->eh_data);
+			ts->pd_reg_status = RESET;
+		}
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	ts->tsi_conf.state = state;
+
+	return 0;
+}
+
+static int da9052_ts_open(struct input_dev *dev)
+{
+	struct da9052_ts_priv *priv = input_get_drvdata(dev);
+	int ret;
+
+	ret = da9052_config_gpio(priv->da9052);
+	if (ret)
+		return ret;
+
+	ret = da9052_config_state(priv, TSI_IDLE);
+	if (ret)
+		return ret;
+	priv->tsi_conf.state = TSI_IDLE;
+
+	ret = da9052_config_measure_seq(priv, TSI_MODE_VALUE);
+	if (ret)
+		return ret;
+
+	ret = da9052_config_skip_slots(priv, TSI_SLOT_SKIP_VALUE);
+	if (ret)
+		return ret;
+
+	ret =  da9052_config_delay(priv, TSI_DELAY_VALUE);
+	if (ret)
+		return ret;
+
+	da9052_set_sampling_mode(priv, DEFAULT_TSI_SAMPLING_MODE);
+	if (ret)
+		return ret;
+
+	priv->fifo_start = 0;
+	priv->fifo_end = 0;
+
+	mutex_init(&priv->tsi_fifo_lock);
+
+	priv->tsi_state = WAIT_FOR_PEN_DOWN;
+
+	INIT_DELAYED_WORK(&priv->tsi_work, da9052_tsi_work);
+
+	ret = da9052_config_state(priv, DEFAULT_TSI_STATE);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void da9052_ts_close(struct input_dev *dev)
+{
+	struct da9052_ts_priv *priv = input_get_drvdata(dev);
+	cancel_delayed_work_sync(&priv->tsi_work);
+	mutex_destroy(&priv->tsi_fifo_lock);
+	return;
+}
+static int __devinit da9052_touch_probe(struct platform_device *pdev)
+{
+	struct da9052_ts_priv *priv;
+	struct input_dev *idev;
+	int ret = -ENOMEM;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	idev = input_allocate_device();
+	if (!priv || !idev)
+		goto err_free_mem;
+
+	priv->da9052 = dev_get_drvdata(pdev->dev.parent);
+	priv->idev = idev;
+
+
+	idev->name = DA9052_TSI_INPUT_DEV;
+	idev->phys = "input(tsi)";
+	idev->dev.parent = &pdev->dev;
+	idev->id.vendor = DA9052_VENDOR_ID;
+	idev->id.product = DA9052_PRODUCT_ID;
+	idev->id.bustype = BUS_RS232;
+	idev->id.version = TSI_VERSION;
+	idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	idev->evbit[0] = (BIT_MASK(EV_SYN) |
+			BIT_MASK(EV_KEY) |
+			BIT_MASK(EV_ABS));
+
+	input_set_abs_params(idev, ABS_X, 0, 0x3FF, 0, 0);
+	input_set_abs_params(idev, ABS_Y, 0, 0x3FF, 0, 0);
+	input_set_abs_params(idev, ABS_PRESSURE, 0, 0x3FF, 0, 0);
+
+	idev->open = da9052_ts_open;
+	idev->close = da9052_ts_close;
+
+	input_set_drvdata(idev, priv);
+
+	ret = input_register_device(priv->idev);
+	if (ret)
+		goto err_free_mem;
+
+	platform_set_drvdata(pdev, priv);
+
+	return 0;
+
+err_free_mem:
+	input_free_device(idev);
+	kfree(priv);
+	return ret;
+}
+
+static int __devexit da9052_touch_remove(struct platform_device *pdev)
+{
+	struct da9052_ts_priv *priv = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	input_unregister_device(priv->idev);
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver da9052_touch_driver = {
+	.driver	= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= da9052_touch_probe,
+	.remove		= __devexit_p(da9052_touch_remove),
+};
+
+static int __init da9052_touch_init(void)
+{
+	return platform_driver_register(&da9052_touch_driver);
+}
+module_init(da9052_touch_init);
+
+static void __exit da9052_touch_exit(void)
+{
+	platform_driver_unregister(&da9052_touch_driver);
+}
+module_exit(da9052_touch_exit);
+
+MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9052");
+MODULE_AUTHOR("David Dajun Chen <dchen@...semi.com>")
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff -urpN linux-2.6.34/drivers/input/touchscreen/da9052-ts-core.c
linux-2.6.34_test/drivers/input/touchscreen/da9052-ts-core.c
--- linux-2.6.34/drivers/input/touchscreen/da9052-ts-core.c	1970-01-01
05:00:00.000000000 +0500
+++ linux-2.6.34_test/drivers/input/touchscreen/da9052-ts-core.c	2010-07-01
18:20:48.000000000 +0500
@@ -0,0 +1,641 @@
+/*
+ * Copyright(c) 2009 Dialog Semiconductor Ltd.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * da9052-tsi-core.c: TSI driver configuration and raw samples handling.
+*/
+
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/freezer.h>
+
+#include <linux/mfd/da9052/reg.h>
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/tsi.h>
+
+#define NUM_GPIO_TSI_REGISTERS			3
+#define TSI_DELAY_BIT_SHIFT			6
+#define TSI_SKIP_BIT_SHIFT			3
+
+static int process_pendwn_event(struct da9052_ts_priv *ts);
+static int da9052_tsi_start_sampling(struct da9052_ts_priv *ts);
+
+int da9052_config_gpio(struct da9052 *da9052)
+{
+	unsigned char idx = 0;
+	int ret = 0;
+	struct da9052_ssc_msg ssc_msg[NUM_GPIO_TSI_REGISTERS];
+
+	ssc_msg[idx++].addr  = DA9052_GPIO0203_REG;
+	ssc_msg[idx++].addr  = DA9052_GPIO0405_REG;
+	ssc_msg[idx++].addr  = DA9052_GPIO0607_REG;
+
+	da9052_lock(da9052);
+	ret = da9052->read_many(da9052, ssc_msg, idx);
+	if (ret) {
+		da9052_unlock(da9052);
+		return ret;
+	}
+	da9052_unlock(da9052);
+
+	idx = 0;
+	ssc_msg[idx].data = (ssc_msg[idx].data & ~(DA9052_GPIO0203_GPIO3PIN));
+
+	idx++;
+	ssc_msg[idx].data = (ssc_msg[idx].data &
+			~(DA9052_GPIO0405_GPIO4PIN | DA9052_GPIO0405_GPIO5PIN));
+
+	idx++;
+	ssc_msg[idx].data = (ssc_msg[idx].data &
+			~(DA9052_GPIO0607_GPIO6PIN | DA9052_GPIO0607_GPIO7PIN));
+	idx++;
+
+	da9052_lock(da9052);
+	ret = da9052->write_many(da9052, ssc_msg, idx);
+	if (ret) {
+		da9052_unlock(da9052);
+		return ret;
+	}
+	da9052_unlock(da9052);
+
+	return 0;
+}
+
+int da9052_config_pen_detect(struct da9052_ts_priv *ts, unsigned char flag)
+{
+	u32 ret;
+	struct da9052_ssc_msg msg;
+
+	msg.addr = DA9052_TSICONTA_REG;
+	msg.data = 0;
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->read(ts->da9052, &msg);
+	if (ret < 0) {
+		da9052_unlock(ts->da9052);
+		return ret;
+	}
+	da9052_unlock(ts->da9052);
+
+	if (flag == ENABLE)
+		msg.data = (msg.data | DA9052_TSICONTA_PENDETEN);
+	else if (flag == DISABLE)
+		msg.data = (msg.data  & ~(DA9052_TSICONTA_PENDETEN));
+	else
+		return -EINVAL;
+
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->write(ts->da9052, &msg);
+	if (ret < 0) {
+		da9052_unlock(ts->da9052);
+		return ret;
+	}
+	da9052_unlock(ts->da9052);
+	ts->tsi_conf.auto_cont.da9052_tsi_cont_a = msg.data;
+
+	return 0;
+}
+
+int da9052_config_auto_mode(struct da9052_ts_priv *ts, unsigned char state)
+{
+	unsigned char data;
+	int ret = 0;
+	struct da9052_ssc_msg msg;
+
+	if (state != ENABLE && state != DISABLE)
+		return -EINVAL;
+
+	msg.addr = DA9052_TSICONTA_REG;
+	msg.data = 0;
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->read(ts->da9052, &msg);
+	if (ret) {
+		da9052_unlock(ts->da9052);
+		return ret;
+	}
+	da9052_unlock(ts->da9052);
+
+	data = (unsigned char)ret;
+
+	if (state == ENABLE)
+		msg.data = (msg.data |= DA9052_TSICONTA_AUTOTSIEN);
+	else if (state == DISABLE)
+		msg.data = (msg.data &= ~DA9052_TSICONTA_AUTOTSIEN);
+	else
+		return -EINVAL;
+
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->write(ts->da9052, &msg);
+	if (ret) {
+		da9052_unlock(ts->da9052);
+		return ret;
+	}
+	da9052_unlock(ts->da9052);
+
+	ts->tsi_conf.auto_cont.da9052_tsi_cont_a = data;
+
+	return 0;
+}
+
+int da9052_pm_configure_set_ldo(struct da9052_ts_priv *ts, unsigned char state)
+{
+	u8 ldo_conf_bit = 0;
+	u8 ldo_en_bit = 0;
+	struct da9052_ssc_msg msg;
+	int ret = 0;
+
+	if ((ts->ldo_config.ldo_volt >= DA9052_LDO9_VOLT_LOWER) &&
+			(ts->ldo_config.ldo_volt <= DA9052_LDO9_VOLT_UPPER))
+		return -EINVAL;
+
+	if ((ts->ldo_config.ldo_volt -
+				DA9052_LDO9_VOLT_LOWER) % LDO9_VOLT_STEP)
+		return -EINVAL;
+
+	ts->ldo_config.ldo_volt = (ts->ldo_config.ldo_volt -
+				DA9052_LDO9_VOLT_LOWER/LDO9_VOLT_STEP);
+	ldo_conf_bit = DA9052_LDO9_LDO9CONF;
+	ldo_en_bit = DA9052_LDO9_LDO9EN;
+	msg.addr = DA9052_LDO9_REG;
+	msg.data = 0;
+
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->read(ts->da9052, &msg);
+	if (ret) {
+		da9052_unlock(ts->da9052);
+		return ret;
+	}
+	msg.data = ts->ldo_config.ldo_volt |
+		(ts->ldo_config.ldo_conf ? ldo_conf_bit : 0) |
+		(msg.data & ldo_en_bit);
+
+	msg.data = (state & ldo_en_bit) | msg.data;
+
+	ret = ts->da9052->write(ts->da9052, &msg);
+	if (ret) {
+		da9052_unlock(ts->da9052);
+		return ret;
+	}
+
+	da9052_unlock(ts->da9052);
+	return ret;
+}
+
+int da9052_config_power_supply(struct da9052_ts_priv *ts, unsigned char state)
+{
+	if (state != ENABLE && state != DISABLE)
+		return -EINVAL;
+
+	ts->ldo_config.ldo_volt = DA9052_TSI_SUPPLY_VOLTAGE;
+	ts->ldo_config.ldo_num = DA9052_TSI_REF_SOURCE;
+	ts->ldo_config.ldo_conf = RESET;
+
+	if (da9052_pm_configure_set_ldo(ts, state))
+		return -EIO;
+
+	if (state == ENABLE)
+		ts->tsi_conf.ldo9_en = SET;
+	else
+		ts->tsi_conf.ldo9_en = RESET;
+
+	return 0;
+}
+
+int da9052_tsi_enable_irq(struct da9052_ts_priv *ts, enum TSI_IRQ tsi_irq)
+{
+	int ret = 0;
+	struct da9052_ssc_msg msg;
+
+	msg.addr = DA9052_IRQMASKB_REG;
+	msg.data = 0;
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->read(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	switch (tsi_irq) {
+	case TSI_PEN_DWN:
+			msg.data = (msg.data & ~DA9052_IRQMASKB_MPENDOWN);
+		break;
+	case TSI_DATA_RDY:
+			msg.data = (msg.data & ~DA9052_IRQMASKB_MTSIREADY);
+		break;
+	default:
+			return -EINVAL;
+	}
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->write(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	switch (tsi_irq) {
+	case TSI_PEN_DWN:
+			ts->tsi_conf.tsi_pendown_irq_mask = RESET;
+		break;
+	case TSI_DATA_RDY:
+			ts->tsi_conf.tsi_ready_irq_mask = RESET;
+	break;
+	}
+	return 0;
+err_ssc:
+	da9052_unlock(ts->da9052);
+	return -EIO;
+}
+
+int da9052_tsi_disable_irq(struct da9052_ts_priv *ts, enum TSI_IRQ tsi_irq)
+{
+	int ret = 0;
+	struct da9052_ssc_msg msg;
+
+	msg.addr = DA9052_IRQMASKB_REG;
+	msg.data = 0;
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->read(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	switch (tsi_irq) {
+	case TSI_PEN_DWN:
+		msg.data = (msg.data |= DA9052_IRQMASKB_MPENDOWN);
+		break;
+	case TSI_DATA_RDY:
+		msg.data = (msg.data |= DA9052_IRQMASKB_MTSIREADY);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->write(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	switch (tsi_irq) {
+	case TSI_PEN_DWN:
+		ts->tsi_conf.tsi_pendown_irq_mask = SET;
+		break;
+	case TSI_DATA_RDY:
+		ts->tsi_conf.tsi_ready_irq_mask = SET;
+		break;
+	}
+
+	return 0;
+err_ssc:
+	da9052_unlock(ts->da9052);
+	return -EIO;
+}
+void da9052_tsi_notifier(struct da9052_eh_nb *eh_data, unsigned int event)
+{
+	struct da9052_ts_priv *tsi = \
+		container_of(eh_data,
+			struct da9052_ts_priv, eh_data);
+
+	int ret = 0;
+	struct da9052_ssc_msg tsi_reg_data[4];
+
+	switch (tsi->tsi_state) {
+	case WAIT_FOR_PEN_DOWN:
+		if (event == PEN_DOWN_EVE) {
+			dev_info(&tsi->idev->dev, "PEN DOWN DETECTED\n");
+
+			tsi->tsi_state = WAIT_FOR_SAMPLING;
+
+			process_pendwn_event(tsi);
+
+			tsi->tsi_rdy_event =
+				(DA9052_EVENTB_ETSIREADY & (event>>8));
+			tsi->pen_dwn_event =
+				(DA9052_EVENTB_EPENDOWN & (event>>8));
+		}
+		break;
+	case WAIT_FOR_SAMPLING:
+		break;
+	case SAMPLING_ACTIVE:
+		if (event == TSI_READY_EVE) {
+			tsi_reg_data[0].addr  = DA9052_TSIXMSB_REG;
+			tsi_reg_data[1].addr  = DA9052_TSIYMSB_REG;
+			tsi_reg_data[2].addr  = DA9052_TSILSB_REG;
+			tsi_reg_data[3].addr  = DA9052_TSIZMSB_REG;
+			tsi_reg_data[0].data  = 0;
+			tsi_reg_data[1].data  = 0;
+			tsi_reg_data[2].data  = 0;
+			tsi_reg_data[3].data  = 0;
+
+			da9052_lock(tsi->da9052);
+			ret = tsi->da9052->read_many(tsi->da9052,
+					tsi_reg_data, 4);
+			if (ret) {
+				dev_err(&tsi->idev->dev, "Error in \
+					reading TSi registers \n");
+				da9052_unlock(tsi->da9052);
+				return;
+			}
+			da9052_unlock(tsi->da9052);
+
+			if (mutex_lock_interruptible(&tsi->tsi_fifo_lock))
+				return;
+			tsi->tsi_data[tsi->fifo_end].x_msb =
+					tsi_reg_data[0].data;
+			tsi->tsi_data[tsi->fifo_end].y_msb =
+					tsi_reg_data[1].data;
+			tsi->tsi_data[tsi->fifo_end].lsb =
+					tsi_reg_data[2].data;
+			tsi->tsi_data[tsi->fifo_end].z_msb
+					= tsi_reg_data[3].data;
+
+			incr_with_wrap(tsi->fifo_end);
+
+			if (tsi->fifo_end == tsi->fifo_start)
+				tsi->fifo_start++;
+
+			if (tsi->fifo_start >= TSI_FIFO_SIZE)
+				tsi->fifo_start %= TSI_FIFO_SIZE;
+
+			mutex_unlock(&tsi->tsi_fifo_lock);
+
+		}
+		break;
+	default:
+		break;
+	}
+}
+int da9052_tsi_reg_pendwn_event(struct da9052_ts_priv *ts)
+{
+	int ret = 0;
+
+	if (ts->pd_reg_status)
+		return 0;
+
+	ts->eh_data.eve_type = PEN_DOWN_EVE;
+	ts->eh_data.call_back = da9052_tsi_notifier;
+	ret = ts->da9052->register_event_notifier(ts->da9052, &ts->eh_data);
+
+	if (ret) {
+		ts->pd_reg_status = RESET;
+		return -EIO;
+
+	} else {
+		ts->pd_reg_status = SET;
+	}
+
+	return 0;
+}
+
+int da9052_tsi_reg_datardy_event(struct da9052_ts_priv *ts)
+{
+	int ret = 0;
+
+	if (ts->dr_reg_status)
+		return 0;
+
+	ts->eh_data.eve_type = TSI_READY_EVE;
+	ts->eh_data.call_back = da9052_tsi_notifier;
+	ret = ts->da9052->register_event_notifier(ts->da9052, &ts->eh_data);
+
+	if (ret) {
+		ts->dr_reg_status = RESET;
+		return -EIO;
+
+	} else {
+		ts->dr_reg_status = SET;
+	}
+
+	return 0;
+}
+
+int da9052_config_measure_seq(struct da9052_ts_priv *ts,
+				enum TSI_MEASURE_SEQ seq)
+{
+	int ret = 0;
+	struct da9052_ssc_msg msg;
+
+	if (seq > 1)
+		return -EINVAL;
+
+	msg.addr = DA9052_TSICONTA_REG;
+	msg.data = 0;
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->read(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	if (seq == XYZP_MODE)
+		msg.data = (msg.data &= ~DA9052_TSICONTA_TSIMODE);
+	else if (seq == XP_MODE)
+		msg.data = (msg.data |= DA9052_TSICONTA_TSIMODE);
+	else
+		return -EINVAL;
+
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->write(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	ts->tsi_conf.auto_cont.da9052_tsi_cont_a = msg.data;
+
+	return 0;
+err_ssc:
+	da9052_unlock(ts->da9052);
+	return -EIO;
+}
+
+int da9052_config_skip_slots(struct da9052_ts_priv *ts,
+				enum TSI_SLOT_SKIP skip)
+{
+	int ret = 0;
+	struct da9052_ssc_msg msg;
+
+	if (skip > MAX_TSI_SKIP_SLOT)
+		return -EINVAL;
+
+	msg.addr = DA9052_TSICONTA_REG;
+	msg.data = 0;
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->read(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	msg.data = (msg.data & ~(DA9052_TSICONTA_TSISKIP));
+	msg.data = (msg.data & ~(skip << TSI_SKIP_BIT_SHIFT));
+
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->write(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+	ts->tsi_conf.auto_cont.da9052_tsi_cont_a = msg.data;
+
+	return 0;
+err_ssc:
+	da9052_unlock(ts->da9052);
+	return -EIO;
+}
+
+int da9052_config_delay(struct da9052_ts_priv *ts,
+			enum TSI_DELAY delay)
+{
+	int ret = 0;
+	struct da9052_ssc_msg msg;
+
+	if (delay > MAX_TSI_DELAY)
+		return -EINVAL;
+
+	msg.addr = DA9052_TSICONTA_REG;
+	msg.data = 0;
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->read(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	msg.data = (msg.data & ~(DA9052_TSICONTA_TSIDELAY));
+
+	msg.data = (msg.data | (delay << TSI_DELAY_BIT_SHIFT));
+
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->write(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	ts->tsi_conf.auto_cont.da9052_tsi_cont_a = msg.data;
+
+	return 0;
+err_ssc:
+	da9052_unlock(ts->da9052);
+	return -EIO;
+}
+
+int da9052_set_sampling_mode(struct da9052_ts_priv *ts, unsigned char mode)
+{
+	int ret = 0;
+	struct da9052_ssc_msg msg;
+
+	msg.addr = DA9052_ADCCONT_REG;
+	msg.data = 0;
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->read(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	if (mode == ECONOMY_MODE)
+		msg.data = (msg.data &= ~DA9052_ADCCONT_ADCMODE);
+	else if (mode == FAST_MODE)
+		msg.data = (msg.data |= DA9052_ADCCONT_ADCMODE);
+	else
+		return -EINVAL;
+
+	da9052_lock(ts->da9052);
+	ret = ts->da9052->write(ts->da9052, &msg);
+	if (ret)
+		goto err_ssc;
+	da9052_unlock(ts->da9052);
+
+	switch (mode) {
+	case ECONOMY_MODE:
+		ts->tsi_state = ECONOMY_MODE;
+		break;
+	case FAST_MODE:
+		ts->tsi_state = FAST_MODE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ts->tsi_penup_count = (u32)TS_PENUP_DETECT_INTERVEL;
+	ts->tsi_data_poll_interval = 0;
+
+	return 0;
+err_ssc:
+	da9052_unlock(ts->da9052);
+	return -EIO;
+}
+
+static int da9052_tsi_start_sampling(struct da9052_ts_priv *ts)
+{
+	if (ts->tsi_state == WAIT_FOR_SAMPLING) {
+		ts->tsi_state =  SAMPLING_ACTIVE;
+		return 0;
+	} else
+		return -EINVAL;
+}
+
+static int process_pendwn_event(struct da9052_ts_priv *ts)
+{
+	int ret = 0;
+	struct input_dev *ip_dev = ts->idev;
+
+	if (ts->tsi_conf.state != TSI_AUTO_MODE) {
+		dev_err(&ts->idev->dev, "Configure TSI in auto mode\n");
+		goto fail;
+	}
+
+	ret = da9052_config_power_supply(ts, ENABLE);
+	if (ret)
+		goto fail;
+
+	ret = da9052_tsi_disable_irq(ts, TSI_PEN_DWN);
+	if (ret)
+		goto fail;
+
+	ret = da9052_tsi_enable_irq(ts, TSI_DATA_RDY);
+	if (ret)
+		goto fail;
+
+	ret = da9052_config_auto_mode(ts, ENABLE);
+	if (ret)
+		goto fail;
+	ts->tsi_conf.auto_cont.tsi_cont_a.auto_tsi_en = SET;
+
+	ret = da9052_tsi_reg_datardy_event(ts);
+	if (ret)
+		goto fail;
+
+	input_report_abs(ip_dev, BTN_TOUCH, 1);
+	input_sync(ip_dev);
+
+	ret = da9052_tsi_start_sampling(ts);
+	if (ret)
+		goto fail;
+
+	switch (ts->tsi_state) {
+	case ECONOMY_MODE:
+		ts->tsi_data_poll_interval =
+			TSI_ECO_MODE_DATA_PROCESSING_INTERVAL;
+		break;
+	case FAST_MODE:
+		ts->tsi_data_poll_interval =
+			TSI_FAST_MODE_DATA_PROCESSING_INTERVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	schedule_delayed_work(&ts->tsi_work,
+			msecs_to_jiffies(ts->tsi_data_poll_interval));
+
+	return 0;
+
+fail:
+	if (ts->pd_reg_status) {
+		ts->da9052->unregister_event_notifier(ts->da9052, &ts->eh_data);
+		ts->pd_reg_status = RESET;
+		da9052_tsi_reg_pendwn_event(ts);
+	}
+	return ret;
+}
+
diff -urpN linux-2.6.34/drivers/input/touchscreen/da9052-ts-process.c
linux-2.6.34_test/drivers/input/touchscreen/da9052-ts-process.c
--- linux-2.6.34/drivers/input/touchscreen/da9052-ts-process.c	1970-01-01
05:00:00.000000000 +0500
+++ linux-2.6.34_test/drivers/input/touchscreen/da9052-ts-process.c	2010-07-01
18:20:48.000000000 +0500
@@ -0,0 +1,152 @@
+ /*
+ * Copyright(c) 2009 Dialog Semiconductor Ltd.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * da9052-tsi-process.c: Converts the TSI reg co-ordinates to
+ *			raw co-ordinates and reports the sample
+ *			to the input sub-system
+ *
+ */
+#include <linux/mfd/da9052/tsi.h>
+
+/* The data from EH is copied in to this buffer. */
+struct da9052_tsi_reg tsidata[TSI_FIFO_SIZE];
+
+static void da9052_penup_event(struct da9052_ts_priv *ts);
+
+u16 da9052_get_tsi_data(struct da9052_ts_priv *ts)
+{
+	u16 data_nt = 0;
+
+	if (mutex_lock_interruptible(&ts->tsi_fifo_lock))
+		return 0;
+
+	if (ts->fifo_start  < ts->fifo_end) {
+		data_nt = (ts->fifo_end - ts->fifo_start);
+
+		memcpy(tsidata, &ts->tsi_data[ts->fifo_start],
+			sizeof(struct da9052_tsi_reg)*data_nt);
+
+	} else if (ts->fifo_start > ts->fifo_end) {
+		data_nt = TSI_FIFO_SIZE;
+
+		memcpy(tsidata, &ts->tsi_data[ts->fifo_start],
+		sizeof(struct da9052_tsi_reg)*(TSI_FIFO_SIZE - ts->fifo_start));
+
+		memcpy(tsidata, &ts->tsi_data[0],
+		sizeof(struct da9052_tsi_reg)*(ts->fifo_end));
+		ts->fifo_start = 0;
+		ts->fifo_end = 0;
+	} else {
+		data_nt = 0;
+	}
+
+	mutex_unlock(&ts->tsi_fifo_lock);
+
+	return data_nt;
+}
+
+static void da9052_tsi_convert_reg_to_coord(struct da9052_tsi_reg  *src,
+					struct tsi_data *raw_data)
+{
+	/* Convert data from REG format to co-ordinate format */
+	raw_data->x = (src->x_msb << X_MSB_SHIFT);
+	raw_data->x |= (src->lsb & X_LSB_MASK) >> X_LSB_SHIFT;
+
+	raw_data->y = (src->y_msb << Y_MSB_SHIFT);
+	raw_data->y |= (src->lsb & Y_LSB_MASK) >> Y_LSB_SHIFT;
+
+	raw_data->z = (src->z_msb << Z_MSB_SHIFT);
+	raw_data->z |= (src->lsb & Z_LSB_MASK) >> Z_LSB_SHIFT;
+}
+
+void da9052_tsi_work(struct work_struct *work)
+{
+	struct da9052_ts_priv *ts =
+		container_of(work, struct da9052_ts_priv, tsi_work.work);
+	u16 data_cnt;
+	struct tsi_data tsi_data;
+	u16 cnt = 0;
+
+	if (!ts->pen_dwn_event)
+		return;
+
+	memset(&tsi_data, 0, sizeof(tsi_data));
+
+	data_cnt = da9052_get_tsi_data(ts);
+
+	if (data_cnt) {
+		ts->tsi_zero_data_cnt = 0;
+	} else {
+		ts->tsi_zero_data_cnt++;
+		if (ts->tsi_zero_data_cnt > ts->tsi_penup_count) {
+			dev_info(&ts->idev->dev, "TSI PEN\
+				UP DETECTED \n");
+			ts->pen_dwn_event = RESET;
+			da9052_penup_event(ts);
+		}
+	}
+
+	while (cnt++ <= data_cnt) {
+		da9052_tsi_convert_reg_to_coord(&ts->tsi_data[cnt],
+						&tsi_data);
+
+		if ((tsi_data.x < TS_X_MIN) ||
+			(tsi_data.x > TS_X_MAX) ||
+			(tsi_data.y < TS_Y_MIN) ||
+			(tsi_data.y > TS_Y_MAX)) {
+			/* Data beyond touchscreen boundaries */
+			/* reject this sample */
+			dev_err(&ts->idev->dev, "Sample rejected as\
+			it is beyond touch screen boundaries.\n");
+			continue;
+		}
+
+		input_report_abs(ts->idev, ABS_X, tsi_data.x);
+		input_report_abs(ts->idev, ABS_Y, tsi_data.y);
+		input_report_abs(ts->idev, ABS_Z, tsi_data.z);
+		input_sync(ts->idev);
+
+		memset(&tsi_data, 0, sizeof(tsi_data));
+	}
+}
+
+static void da9052_penup_event(struct da9052_ts_priv *ts)
+{
+	s32 ret;
+
+	ret = da9052_config_auto_mode(ts, DISABLE);
+	if (ret) {
+		ts->tsi_conf.auto_cont.tsi_cont_a.auto_tsi_en = RESET;
+		return;
+	}
+
+	ret = da9052_config_power_supply(ts, DISABLE);
+	if (ret) {
+		ts->tsi_conf.ldo9_en = RESET;
+		return;
+	}
+
+	ret = da9052_tsi_enable_irq(ts, TSI_PEN_DWN);
+	if (ret) {
+		ts->tsi_conf.tsi_pendown_irq_mask = RESET;
+		return;
+	}
+
+	ts->tsi_state =  WAIT_FOR_PEN_DOWN;
+
+	ts->tsi_zero_data_cnt = 0;
+
+	input_report_key(ts->idev, BTN_TOUCH, 0);
+	input_sync(ts->idev);
+
+	ts->tsi_data_poll_interval = 0;
+	schedule_delayed_work(&ts->tsi_work,
+			msecs_to_jiffies(ts->tsi_data_poll_interval));
+	return;
+}
+
diff -urpN linux-2.6.34/drivers/input/touchscreen/Kconfig
linux-2.6.34_test/drivers/input/touchscreen/Kconfig
--- linux-2.6.34/drivers/input/touchscreen/Kconfig	2010-05-17
02:17:36.000000000 +0500
+++ linux-2.6.34_test/drivers/input/touchscreen/Kconfig	2010-07-01
18:21:04.000000000 +0500
@@ -594,4 +594,11 @@ config TOUCHSCREEN_PCAP

 	  To compile this driver as a module, choose M here: the
 	  module will be called pcap_ts.
+
+config TOUCHSCREEN_DA9052
+        tristate "Support Touchscreen on Dialog Semiconductor DA9052 PMIC"
+        depends on PMIC_DA9052
+        help
+          Say y here to support the touchscreen found on
+          Dialog Semiconductor DA9052 PMIC
 endif
diff -urpN linux-2.6.34/drivers/input/touchscreen/Makefile
linux-2.6.34_test/drivers/input/touchscreen/Makefile
--- linux-2.6.34/drivers/input/touchscreen/Makefile	2010-05-17
02:17:36.000000000 +0500
+++ linux-2.6.34_test/drivers/input/touchscreen/Makefile	2010-07-01
18:20:56.000000000 +0500
@@ -46,3 +46,5 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL)	+
 obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE)	+= mainstone-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE)	+= zylonite-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
+da9052-tsi-objs                   	 := da9052-ts.o da9052-ts-core.o
da9052-ts-process.o
+obj-$(CONFIG_TOUCHSCREEN_DA9052)      	 += da9052-tsi.o
diff -urpN linux-2.6.34/include/linux/mfd/da9052/tsi_cfg.h
linux-2.6.34_test/include/linux/mfd/da9052/tsi_cfg.h
--- linux-2.6.34/include/linux/mfd/da9052/tsi_cfg.h	1970-01-01
05:00:00.000000000 +0500
+++ linux-2.6.34_test/include/linux/mfd/da9052/tsi_cfg.h	2010-07-01
18:22:07.000000000 +0500
@@ -0,0 +1,72 @@
+/*
+ * Copyright(c) 2009 Dialog Semiconductor Ltd.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * da9052_tsi_cfg.h: tsi driver configuration file for DA9052
+ *
+ * This file defines configurations used for DA9052 TSI driver.
+ *
+*/
+
+#ifndef _DA9052_TSI_CFG_H
+#define _DA9052_TSI_CFG_H
+
+
+#define AUTO_MODE		0
+#define IDLE			5
+#define DEFAULT_TSI_STATE		AUTO_MODE
+
+/* da9052 TSI static configuration */
+/* TSI slot skip possible configurations are [0, 2, 5, 10, 30, 80, 130, 330]*/
+/* the TSI_SLOT_SKIP equal value [0, 1, 2, 3, 4, 5, 6, 7] */
+#define TSI_SLOT_SKIP_VALUE		0
+
+/* TSI delay possible configurations are [0, 1, 2, 4] */
+/* TSI_DELAY value is [0, 1, 2, 3] */
+#define TSI_DELAY_VALUE			3
+
+/* TSI Mode XYZP Mode = 0 and XP mode is 1 */
+#define TSI_MODE_VALUE			0
+
+/* TSI sampling mode Economy mode = 0; Fast mode =1*/
+#define TSI_ECONOMY_MODE		0
+#define TSI_FAST_MODE			1
+/* set default TSI mode from above two modes */
+#define DEFAULT_TSI_SAMPLING_MODE	TSI_FAST_MODE
+
+/* TSI penup detecting interval in msec*/
+#define TS_PENUP_DETECT_INTERVEL	50
+
+/* Calibartion  Enable(1) / Disable(0) */
+#define TSI_USE_CALIBRATION		1
+
+/* Touchscreen panel dimensions */
+#define TS_X_MIN	(0)
+#define TS_X_MAX	(1023)
+#define TS_Y_MIN	(0)
+#define TS_Y_MAX	(1023)
+
+/* Display panel dimensions */
+#define DISPLAY_X_MIN	(0)
+#define DISPLAY_X_MAX	(1023)
+#define DISPLAY_Y_MIN	(0)
+#define DISPLAY_Y_MAX	(1023)
+
+/* interval at which raw data is processed in msec */
+#define TSI_FAST_MODE_DATA_PROCESSING_INTERVAL	25
+#define TSI_ECO_MODE_DATA_PROCESSING_INTERVAL	100
+
+/* Macro holds value to be assigned for raw data processing interval */
+#if DEFAULT_TSI_SAMPLING_MODE
+#define DEFAULT_RAW_DATA_PROCESSING_INTERVAL \
+TSI_FAST_MODE_DATA_PROCESSING_INTERVAL
+#else
+#define DEFAULT_RAW_DATA_PROCESSING_INTERVAL \
+TSI_ECO_MODE_DATA_PROCESSING_INTERVAL
+#endif
+
+#endif
diff -urpN linux-2.6.34/include/linux/mfd/da9052/tsi_filter.h
linux-2.6.34_test/include/linux/mfd/da9052/tsi_filter.h
--- linux-2.6.34/include/linux/mfd/da9052/tsi_filter.h	1970-01-01
05:00:00.000000000 +0500
+++ linux-2.6.34_test/include/linux/mfd/da9052/tsi_filter.h	2010-07-01
18:22:07.000000000 +0500
@@ -0,0 +1,24 @@
+#ifndef _TSI_FILTER_H_
+#define _TSI_FILTER_H_
+
+#include <linux/mfd/da9052/tsi.h>
+
+/* State for TSI thread */
+#define	ACTIVE		0
+#define	INACTIVE	1
+
+struct tsi_data {
+	s16	x;
+	s16	y;
+	s16	z;
+};
+
+struct tsi_thread_type{
+	u8			pid;
+	u8			state;
+	struct completion	notifier;
+};
+
+void da9052_tsi_work(struct work_struct *work);
+
+#endif	/*_TS_FILTER_H_ */
diff -urpN linux-2.6.34/include/linux/mfd/da9052/tsi.h
linux-2.6.34_test/include/linux/mfd/da9052/tsi.h
--- linux-2.6.34/include/linux/mfd/da9052/tsi.h	1970-01-01
05:00:00.000000000 +0500
+++ linux-2.6.34_test/include/linux/mfd/da9052/tsi.h	2010-07-01
18:22:07.000000000 +0500
@@ -0,0 +1,214 @@
+/*
+ * Copyright(c) 2009 Dialog Semiconductor Ltd.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * da9052_tsi.h: tsi driver file for DA9052
+ *
+*/
+#ifndef _TSI_H
+#define _TSI_H
+
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/freezer.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/tsi_cfg.h>
+#include <linux/mfd/da9052/tsi_filter.h>
+
+#define ENABLE		1
+#define DISABLE		0
+#define SET		1
+#define	RESET		0
+#define	CLEAR		0
+
+/* Following macros define TSI control regsiter bit values */
+#define DA9052_TCA_AUTO_TSI_ENABLE		(1<<0)
+#define DA9052_TCA_PEN_DET_ENABLE		(1<<1)
+#define DA9052_TCA_TSI_XP_MODE_ENABLE		(1<<2)
+
+#define DA9052_TCA_TSI_DELAY_0SLOTS		(0<<6)
+#define DA9052_TCA_TSI_DELAY_2SLOTS		(2<<6)
+#define DA9052_TCA_TSI_DELAY_4SLOTS		(3<<6)
+
+#define DA9052_EVETN_B_E_PEN_DOWN		(1<<6)
+#define DA9052_EVENT_B_E_TSI_READY		(1<<7)
+
+#define DA9052_IRQMASK_B_PENDOWN_MASK		(1<<6)
+#define DA9052_IRQMASK_B_TSI_READY_MASK		(1<<7)
+
+#define X_LSB_SHIFT	(0)
+#define Y_LSB_SHIFT	(2)
+#define Z_LSB_SHIFT	(4)
+#define X_MSB_SHIFT	(2)
+#define Y_MSB_SHIFT	(2)
+#define Z_MSB_SHIFT	(2)
+#define  X_LSB_MASK	(11 << X_LSB_SHIFT)
+#define  Y_LSB_MASK	(11 << Y_LSB_SHIFT)
+#define  Z_LSB_MASK	(11 << Z_LSB_SHIFT)
+#define  PEN_DET_MASK	(11 << PEN_DET_SHIFT)
+
+#define DRIVER_NAME			"da9052-tsi"
+#define TSI_INPUT_DEVICE_OFF		0
+#define DA9052_VENDOR_ID		0xAAAA
+#define DA9052_PRODUCT_ID		0x5555
+#define DA9052_TSI_INPUT_DEV		DRIVER_NAME
+#define TSI_VERSION			0x0101
+
+
+#define TSI_DELAY_BIT_SHIFT		6
+
+#define TSI_SKIP_BIT_SHIFT		3
+
+#define NUM_TSI_RESULT_REGISTERS	4
+
+#define DA9052_TSI_SUPPLY_VOLTAGE	2500
+
+#define MAX_TSI_DELAY			TSI_DELAY_4SLOTS
+
+#define MAX_TSI_SKIP_SLOT		TSI_SKIP_330SLOTS
+
+#define DA9052_TSI_REF_SOURCE		DA9052_LDO9
+
+#define TSI_FIFO_SIZE			128
+
+
+#define WAIT_FOR_PEN_DOWN		0
+#define WAIT_FOR_SAMPLING		1
+#define SAMPLING_ACTIVE			2
+
+#define incr_with_wrap(x)	\
+		if (++x >= TSI_FIFO_SIZE) \
+			x = 0
+
+#define DA9052_LDO9_VOLT_UPPER		3650
+#define DA9052_LDO9_VOLT_LOWER		1250
+#define LDO9_VOLT_STEP			50
+#define DA9052_LDO9			9
+
+enum ADC_MODE {
+	ECONOMY_MODE = 0,
+	FAST_MODE = 1
+};
+
+enum TSI_DELAY {
+	TSI_DELAY_0SLOTS = 0,
+	TSI_DELAY_1SLOTS = 1,
+	TSI_DELAY_2SLOTS = 2,
+	TSI_DELAY_4SLOTS = 3
+};
+
+enum TSI_SLOT_SKIP{
+	TSI_SKIP_0SLOTS = 0,
+	TSI_SKIP_2SLOTS = 1,
+	TSI_SKIP_5SLOTS = 2,
+	TSI_SKIP_10SLOTS = 3,
+	TSI_SKIP_30SLOTS = 4,
+	TSI_SKIP_80SLOTS = 5,
+	TSI_SKIP_130SLOTS = 6,
+	TSI_SKIP_330SLOTS = 7
+};
+
+enum TSI_MUX_SEL{
+	TSI_MUX_XPLUS	= 0,
+	TSI_MUX_YPLUS	= 1,
+	TSI_MUX_XMINUS	= 2,
+	TSI_MUX_YMINUS	= 3
+};
+
+enum TSI_IRQ{
+	TSI_PEN_DWN,
+	TSI_DATA_RDY
+};
+
+enum TSI_COORDINATE{
+	X_COORDINATE,
+	Y_COORDINATE,
+	Z_COORDINATE
+};
+
+enum TSI_MEASURE_SEQ{
+	XYZP_MODE,
+	XP_MODE
+};
+
+enum TSI_STATE {
+	TSI_AUTO_MODE,
+	TSI_IDLE
+};
+
+union da9052_tsi_cont_reg {
+	unsigned char da9052_tsi_cont_a;
+	struct{
+		unsigned char auto_tsi_en:1;
+		unsigned char pen_det_en:1;
+		unsigned char tsi_mode:1;
+		unsigned char tsi_skip:3;
+		unsigned char tsi_delay:2;
+	} tsi_cont_a;
+};
+
+struct da9052_tsi_conf{
+	union da9052_tsi_cont_reg	auto_cont;
+	unsigned char			tsi_adc_sample_intervel:1;
+	enum TSI_STATE			state;
+	unsigned char			ldo9_en:1;
+	unsigned char			ldo9_conf:1;
+	unsigned char			tsi_ready_irq_mask:1;
+	unsigned char			tsi_pendown_irq_mask:1;
+};
+
+struct da9052_tsi_reg {
+	unsigned char	x_msb;
+	unsigned char	y_msb;
+	unsigned char	z_msb;
+	unsigned char	lsb;
+};
+
+struct da9052_ldo_config {
+	u16	ldo_volt;
+	u8	ldo_num;
+	u8	ldo_conf:1;
+	u8	ldo_pd:1;
+};
+
+
+struct da9052_ts_priv {
+	struct input_dev		*idev;
+	struct da9052			*da9052;
+	struct da9052_tsi_conf		tsi_conf;
+	struct da9052_eh_nb		eh_data;
+	struct delayed_work		tsi_work;
+	struct mutex			tsi_fifo_lock;
+	struct da9052_ldo_config	ldo_config;
+	struct da9052_tsi_reg		tsi_data[TSI_FIFO_SIZE];
+	unsigned int			fifo_start;
+	unsigned int			fifo_end;
+	unsigned int			tsi_data_poll_interval;
+	unsigned int			tsi_penup_count;
+	unsigned int			tsi_zero_data_cnt;
+	unsigned char			tsi_state;
+	unsigned char			tsi_auto_mode;
+	unsigned char			pen_dwn_event;
+	unsigned char			tsi_rdy_event;
+	unsigned char			pd_reg_status;
+	unsigned char			dr_reg_status;
+};
+
+int da9052_config_gpio(struct da9052 *da9052);
+int da9052_config_pen_detect(struct da9052_ts_priv *ts, unsigned char flag);
+int da9052_config_auto_mode(struct da9052_ts_priv *ts, unsigned char state);
+int da9052_config_power_supply(struct da9052_ts_priv *ts, unsigned char state);
+int da9052_tsi_enable_irq(struct da9052_ts_priv *ts, enum TSI_IRQ tsi_irq);
+int da9052_tsi_disable_irq(struct da9052_ts_priv *ts, enum TSI_IRQ tsi_irq);
+int da9052_tsi_reg_pendwn_event(struct da9052_ts_priv *ts);
+int da9052_tsi_reg_datardy_event(struct da9052_ts_priv *ts);
+int da9052_config_measure_seq(struct da9052_ts_priv *ts,
+				enum TSI_MEASURE_SEQ seq);
+int da9052_config_skip_slots(struct da9052_ts_priv *ts,
+				enum TSI_SLOT_SKIP skip);
+int da9052_config_delay(struct da9052_ts_priv *ts, enum TSI_DELAY delay);
+int da9052_set_sampling_mode(struct da9052_ts_priv *ts, unsigned char mode);
+
+#endif /* _TSI_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ