Subject: [@num@/@total@] touch: mc13783 driver
From: Juergen Beisert <j.beisert@pengutronix.de>

This patch adds mc13783 based touch support. It depends on i.MX27 master
SPI support and basic PMIC support.

Note: This patch is not finished yet. It needs additional clean up and
doxygen comment removement. We also have to check if the PMIC support is
a multi function device and might fit better there.

NOT FOR MAINLINE YET.

Signed-off-by: Juergen Beisert <j.beisert@pengutronix.de>
Signed-off-by: N.N. (FIXME: get a sign from freescale)

---

 Kconfig  |   12 +++++++
 Makefile |    1
 mxc_ts.c |  103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)

Index: linux-2.6.24-rc5/drivers/input/touchscreen/Kconfig
===================================================================
--- linux-2.6.24-rc5.orig/drivers/input/touchscreen/Kconfig
+++ linux-2.6.24-rc5/drivers/input/touchscreen/Kconfig
@@ -210,6 +210,18 @@ config TOUCHSCREEN_USB_COMPOSITE
 	  To compile this driver as a module, choose M here: the
 	  module will be called usbtouchscreen.
 
+config TOUCHSCREEN_MXC
+	tristate "MXC touchscreen input driver"
+	depends on MXC_MC13783_ADC
+	help
+	  Say Y here if you have an MXC based board with touchscreen
+	  attached to it.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mxc_ts.
+
 config TOUCHSCREEN_USB_EGALAX
 	default y
 	bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
Index: linux-2.6.24-rc5/drivers/input/touchscreen/Makefile
===================================================================
--- linux-2.6.24-rc5.orig/drivers/input/touchscreen/Makefile
+++ linux-2.6.24-rc5/drivers/input/touchscreen/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)	+= pe
 obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
 obj-$(CONFIG_TOUCHSCREEN_UCB1400)	+= ucb1400_ts.o
+obj-$(CONFIG_TOUCHSCREEN_MXC)		+= mxc_ts.o
\ No newline at end of file
Index: linux-2.6.24-rc5/drivers/input/touchscreen/mxc_ts.c
===================================================================
--- /dev/null
+++ linux-2.6.24-rc5/drivers/input/touchscreen/mxc_ts.c
@@ -0,0 +1,107 @@
+/*
+ * Driver for the Freescale Semiconductor MXC touchscreen.
+ *
+ * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * The touchscreen driver is designed as a standard input driver which is a
+ * wrapper over low level PMIC driver. Most of the hardware configuration and
+ * touchscreen functionality is implemented in the low level PMIC driver. During
+ * initialization, this driver creates a kernel thread. This thread then calls
+ * PMIC driver to obtain touchscreen values continously. These values are then
+ * passed to the input susbsystem.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/arch/pmic_external.h>
+#include <asm/arch/pmic_adc.h>
+
+#include "linux/freezer.h"
+
+#define MXC_TS_NAME	"mxc_ts"
+
+static struct input_dev *mxc_inputdev = NULL;
+static u32 input_ts_installed;
+
+static int ts_thread(void *arg)
+{
+	t_touch_screen ts_sample;
+	s32 wait = 0;
+	daemonize("mxc_ts");
+	while (input_ts_installed) {
+		try_to_freeze();
+		memset(&ts_sample, 0, sizeof(t_touch_screen));
+		pmic_adc_get_touch_sample(&ts_sample, !wait);
+
+		input_report_abs(mxc_inputdev, ABS_X, ts_sample.x_position);
+		input_report_abs(mxc_inputdev, ABS_Y, ts_sample.y_position);
+		input_report_abs(mxc_inputdev, ABS_PRESSURE,
+				 ts_sample.contact_resistance);
+		input_sync(mxc_inputdev);
+
+		wait = ts_sample.contact_resistance;
+		msleep(20);
+	}
+
+	return 0;
+}
+
+static int __init mxc_ts_init(void)
+{
+	mxc_inputdev = input_allocate_device();
+	if (!mxc_inputdev) {
+		printk(KERN_ERR
+		       "mxc_ts_init: not enough memory for input device\n");
+		return -ENOMEM;
+	}
+
+	mxc_inputdev->name = MXC_TS_NAME;
+	mxc_inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	mxc_inputdev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	mxc_inputdev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+					BIT_MASK(ABS_PRESSURE);
+#if 0
+	input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0);
+	input_set_abs_params(tw->dev, ABS_Y, TW_MIN_YC, TW_MAX_YC, 0, 0);
+#endif
+	if (input_register_device(mxc_inputdev) != 0) {
+		printk(KERN_ERR "Registering touch failed!\n");
+		return -ENOMEM;	/* FIXME */
+	}
+
+	input_ts_installed = 1;
+	kernel_thread(ts_thread, NULL, CLONE_VM | CLONE_FS);
+	printk("mxc input touchscreen loaded\n");
+	return 0;
+}
+
+static void __exit mxc_ts_exit(void)
+{
+	input_ts_installed = 0;
+	input_unregister_device(mxc_inputdev);
+
+	if (mxc_inputdev) {
+		input_free_device(mxc_inputdev);
+		mxc_inputdev = NULL;
+	}
+}
+
+late_initcall(mxc_ts_init);
+module_exit(mxc_ts_exit);
+
+MODULE_DESCRIPTION("MXC input touchscreen driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
