diff -Nur linux-2.6.10-rc3/drivers/input/touchscreen/Kconfig linux-2.6.10-rc3-e/drivers/input/touchscreen/Kconfig
--- linux-2.6.10-rc3/drivers/input/touchscreen/Kconfig	2004-12-04 00:53:47.000000000 +0300
+++ linux-2.6.10-rc3-e/drivers/input/touchscreen/Kconfig	2004-12-19 01:55:18.000000000 +0300
@@ -22,6 +22,17 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called h3600_ts_input.
 
+config TOUCHSCREEN_S3C2410
+	tristate "S3C2410 touchscreen"
+	depends on ARCH_S3C2410 && INPUT && INPUT_TOUCHSCREEN
+	help
+	  Say Y here if you have the S3C2410 touchscreen.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called s3c2410ts_input.
+
 config TOUCHSCREEN_GUNZE
 	tristate "Gunze AHL-51S touchscreen"
 	depends on INPUT && INPUT_TOUCHSCREEN
diff -Nur linux-2.6.10-rc3/drivers/input/touchscreen/Makefile linux-2.6.10-rc3-e/drivers/input/touchscreen/Makefile
--- linux-2.6.10-rc3/drivers/input/touchscreen/Makefile	2004-12-04 00:54:43.000000000 +0300
+++ linux-2.6.10-rc3-e/drivers/input/touchscreen/Makefile	2004-12-19 01:56:09.000000000 +0300
@@ -5,4 +5,5 @@
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_TOUCHSCREEN_BITSY)	+= h3600_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_S3C2410)	+= s3c2410ts.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)	+= gunze.o
diff -Nur linux-2.6.10-rc3/drivers/input/touchscreen/s3c2410ts.c linux-2.6.10-rc3-e/drivers/input/touchscreen/s3c2410ts.c
--- linux-2.6.10-rc3/drivers/input/touchscreen/s3c2410ts.c	1970-01-01 03:00:00.000000000 +0300
+++ linux-2.6.10-rc3-e/drivers/input/touchscreen/s3c2410ts.c	2004-12-17 20:05:47.000000000 +0300
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
+ * S3C2410 touchscreen support
+ *
+ * ChangeLog
+ *
+ * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
+ *	- added clock (de-)allocation code
+ *
+ * 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.
+ *
+ * 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
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-adc.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/hardware/clock.h>
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("S3C2410 touchscreen driver");
+MODULE_LICENSE("GPL");
+
+#undef	KERN_DEBUG
+#define	KERN_DEBUG	"ts: "
+
+/*
+ * Definitions & global arrays.
+ */
+static char *s3c2410ts_name = "S3C2410 TouchScreen";
+static struct clk *adc_clock;
+
+/*
+ * Per-touchscreen data.
+ */
+struct s3c2410ts {
+	struct input_dev dev;
+	unsigned xp;
+	unsigned yp;
+	char phys[32];
+};
+
+static struct s3c2410ts ts;
+
+static irqreturn_t stylus_down(int irq, void *dev_id, struct pt_regs *regs)
+{
+	disable_irq(IRQ_TC);
+	
+	printk(KERN_DEBUG "Stylus down\n");
+
+	/* Start sequential X/Y conversion */
+	__raw_writel(S3C2410_YM_SEN | S3C2410_YP_SEN | S3C2410_XP_SEN | S3C2410_PULL_UP_DIS |
+		     S3C2410_AUTO_PST | S3C2410_XY_PST(0), S3C2410_ADCTSC);
+	__raw_writel(__raw_readl(S3C2410_ADCCON) | S3C2410_ENABLE_START, S3C2410_ADCCON);
+
+	enable_irq(IRQ_TC);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t stylus_action(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned data0;
+	unsigned data1;
+	
+	disable_irq(IRQ_ADC);
+
+	__raw_writel(S3C2410_YM_SEN | S3C2410_YP_SEN | S3C2410_XP_SEN | S3C2410_XY_PST(3),
+		     S3C2410_ADCTSC);
+
+	data0 = __raw_readl(S3C2410_ADCDAT0);
+	data1 = __raw_readl(S3C2410_ADCDAT1);
+
+	/* If stylus down, start sequential X/Y conversion */
+	if(!((data0 & data1) & S3C2410_DAT_UPDOWN)) {
+		__raw_writel(S3C2410_YM_SEN | S3C2410_YP_SEN | S3C2410_XP_SEN | S3C2410_PULL_UP_DIS |
+			     S3C2410_AUTO_PST | S3C2410_XY_PST(0), S3C2410_ADCTSC);
+		__raw_writel(__raw_readl(S3C2410_ADCCON) | S3C2410_ENABLE_START, S3C2410_ADCCON);
+		ts.xp = ((data0 & 0x3FF) * CONFIG_INPUT_TSDEV_SCREEN_X) / 1024;
+		ts.yp = ((data1 & 0x3FF) * CONFIG_INPUT_TSDEV_SCREEN_Y) / 1024;
+		printk(KERN_DEBUG "X: %03u, Y: %03u\n", ts.xp, ts.yp);
+		input_report_abs(&ts.dev, ABS_X, ts.xp);
+		input_report_abs(&ts.dev, ABS_Y, ts.yp);
+		input_report_key(&ts.dev, BTN_TOUCH, 1);
+		input_sync(&ts.dev);
+	}
+	else
+		printk(KERN_DEBUG "Stylus up\n");
+
+	enable_irq(IRQ_ADC);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+int __init s3c2410ts_init(void)
+{
+	adc_clock = clk_get(NULL, "adc");
+	if (!adc_clock) {
+		printk(KERN_ERR "failed to get adc clock source\n");
+		return -ENOENT;
+	}
+	clk_use(adc_clock);
+	clk_enable(adc_clock);
+	printk(KERN_DEBUG "got and enabled clock\n");
+
+	/* Initialise registers */
+	s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);
+	__raw_writel(S3C2410_PRSCEN | S3C2410_PRSCVL(24), S3C2410_ADCCON);
+	__raw_writel(S3C2410_YM_SEN | S3C2410_YP_SEN | S3C2410_XP_SEN | S3C2410_XY_PST(3),
+		     S3C2410_ADCTSC);
+	__raw_writel(S3C2410_DELAY(16384), S3C2410_ADCDLY);
+
+	memset(&ts, 0, sizeof(struct s3c2410ts));
+
+	init_input_dev(&ts.dev);
+	ts.dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	ts.dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_set_abs_params(&ts.dev, ABS_X, 0, CONFIG_INPUT_TSDEV_SCREEN_X / 2, 0, 0);
+	input_set_abs_params(&ts.dev, ABS_Y, 0, CONFIG_INPUT_TSDEV_SCREEN_Y / 2, 0, 0);
+
+	strcpy(ts.phys, "ts0");
+
+	ts.dev.private = &ts;
+	ts.dev.name = s3c2410ts_name;
+	ts.dev.phys = ts.phys;
+	ts.dev.id.bustype = BUS_RS232;
+	ts.dev.id.vendor  = 0xDEAD;
+	ts.dev.id.product = 0xBEEF;
+	ts.dev.id.version = 0x0100;
+
+	if (request_irq(IRQ_ADC, stylus_action, SA_SAMPLE_RANDOM,
+		"s3c2410_action", &ts.dev)) {
+		printk(KERN_ERR "s3c2410ts.c: Could not allocate IRQ_ADC!\n");
+		return -EIO;
+	}
+	if (request_irq(IRQ_TC, stylus_down, SA_SAMPLE_RANDOM,
+			"s3c2410_action", &ts.dev)) {
+		printk(KERN_ERR "s3c2410ts.c: Could not allocate IRQ_TC!\n");
+		return -EIO;
+	}
+
+	printk(KERN_DEBUG "input: %s on ts0\n", s3c2410ts_name);
+
+	input_register_device(&ts.dev);
+	return 0;
+}
+
+void __exit s3c2410ts_exit(void)
+{
+	disable_irq(IRQ_ADC);
+	disable_irq(IRQ_TC);
+	free_irq(IRQ_TC, &ts.dev);
+	free_irq(IRQ_ADC, &ts.dev);
+
+	if (adc_clock) {
+		clk_disable(adc_clock);
+		clk_unuse(adc_clock);
+		clk_put(adc_clock);
+		adc_clock = NULL;
+	}
+	
+	input_unregister_device(&ts.dev);
+}
+
+module_init(s3c2410ts_init);
+module_exit(s3c2410ts_exit);
diff -Nur linux-2.6.10-rc3/include/asm-arm/arch-s3c2410/regs-adc.h linux-2.6.10-rc3-e/include/asm-arm/arch-s3c2410/regs-adc.h
--- linux-2.6.10-rc3/include/asm-arm/arch-s3c2410/regs-adc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc3-e/include/asm-arm/arch-s3c2410/regs-adc.h	2004-09-20 19:06:11.000000000 +0200
@@ -0,0 +1,33 @@
+#ifndef __ASM_ARCH_REGS_ADC_H
+#define __ASM_ARCH_REGS_ADC_H
+
+#define S3C2410_ADCREG(x)	((x) + S3C2410_VA_ADC)
+
+#define S3C2410_ADCCON		S3C2410_ADCREG(0x00)
+#define S3C2410_ECFLG		(1<<15)
+#define S3C2410_PRSCEN		(1<<14)
+#define S3C2410_PRSCVL(x)	((x)<<6)
+#define S3C2410_SEL_MUX(x)	((x)<<3)
+#define S3C2410_STDBM		(1<<2)
+#define S3C2410_READ_START	(1<<1)
+#define S3C2410_ENABLE_START	(1<<0)
+
+#define S3C2410_ADCTSC		S3C2410_ADCREG(0x04)
+#define S3C2410_YM_SEN		(1<<7)
+#define S3C2410_YP_SEN		(1<<6)
+#define S3C2410_XM_SEN		(1<<5)
+#define S3C2410_XP_SEN		(1<<4)
+#define S3C2410_PULL_UP_DIS	(1<<3)
+#define S3C2410_AUTO_PST	(1<<2)
+#define S3C2410_XY_PST(x)	(x)
+
+#define S3C2410_ADCDLY		S3C2410_ADCREG(0x08)
+#define S3C2410_DELAY(x)	(x)
+
+#define S3C2410_ADCDAT0	S3C2410_ADCREG(0x0C)
+#define S3C2410_ADCDAT1	S3C2410_ADCREG(0x10)
+#define S3C2410_DAT_UPDOWN	(1<<15)
+#define S3C2410_DAT_AUTO_PST	(1<<14)
+#define S3C2410_DAT_XY_PST(x)	((x)<<12)
+
+#endif
