Index: linux-2.6.24/arch/arm/mach-s3c2440/Kconfig
===================================================================
--- linux-2.6.24.orig/arch/arm/mach-s3c2440/Kconfig	2008-02-03 18:19:34.000000000 +0100
+++ linux-2.6.24/arch/arm/mach-s3c2440/Kconfig	2008-02-03 18:20:37.000000000 +0100
@@ -67,6 +67,15 @@
 	default y if ARCH_S3C2440
 	select CPU_S3C2440
 
+config MACH_G500
+	bool "Eten G500"
+	select CPU_S3C2440
+	help
+	  Say Y here if you are using the Eten G500.
+
+	  See <http://www.pierrox.net/G500> or
+	  <http://www.handhelds.org/moin/moin.cgi/EtenG500Home> for more
+	  information on this project
 
 endmenu
 
Index: linux-2.6.24/arch/arm/mach-s3c2440/Makefile
===================================================================
--- linux-2.6.24.orig/arch/arm/mach-s3c2440/Makefile	2008-02-03 18:19:34.000000000 +0100
+++ linux-2.6.24/arch/arm/mach-s3c2440/Makefile	2008-02-03 18:20:37.000000000 +0100
@@ -21,3 +21,4 @@
 obj-$(CONFIG_MACH_RX3715)	+= mach-rx3715.o
 obj-$(CONFIG_ARCH_S3C2440)	+= mach-smdk2440.o
 obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
+obj-$(CONFIG_MACH_G500)		+= mach-g500.o
Index: linux-2.6.24/arch/arm/mach-s3c2440/mach-g500.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/arch/arm/mach-s3c2440/mach-g500.c	2008-02-03 18:20:50.000000000 +0100
@@ -0,0 +1,385 @@
+/* linux/arch/arm/mach-s3c2410/mach-g500.c
+ *
+ * Copyright (c) 2008 Pierre Hebert <pierrox@pierrox.net>
+ * http://www.pierrox.net/G500 or
+ * http://www.handhelds.org/moin/moin.cgi/EtenG500Home
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/fb.h>
+#include <asm/arch/lcd.h>
+#include <asm/arch/ts.h>
+#include <asm/arch/mmc.h>
+
+#include <asm/plat-s3c/regs-serial.h>
+#include <asm/plat-s3c/regs-timer.h>
+#include <asm/plat-s3c/nand.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/irq.h>
+#include <asm/plat-s3c24xx/pm.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/host.h>
+
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+
+#include <linux/leds.h>
+
+static struct map_desc g500_iodesc[] __initdata = {
+	/* nothing */
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg g500_uartcfgs[] = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = 0x9fc5,
+		.ulcon	     = 0x2b,
+		.ufcon	     = 0x11,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = 0x1c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x31,
+	},
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = 0x8245,
+		.ulcon	     = 0x43,
+		.ufcon	     = 0x00,
+	}
+};
+
+/* LCD driver info */
+
+static struct s3c2410fb_display g500_lcd_cfg __initdata = {
+	/*.lcdcon1	= S3C2410_LCDCON1_CLKVAL(0x04) |
+			S3C2410_LCDCON1_TFT |
+			S3C2410_LCDCON1_TFT16BPP,*/
+
+	/*.lcdcon2	= S3C2410_LCDCON2_VBPD(5 upper_margin) |
+			S3C2410_LCDCON2_LINEVAL(319 yres) |
+			S3C2410_LCDCON2_VFPD(6 lower_margin) |
+			S3C2410_LCDCON2_VSPW(1 vsync_len),*/
+
+	/*.lcdcon3	= S3C2410_LCDCON3_HBPD(4 right_margin) |
+			S3C2410_LCDCON3_HOZVAL(239 xres) |
+			S3C2410_LCDCON3_HFPD(7 left_margin),*/
+
+	/*.lcdcon4	= S3C2410_LCDCON4_MVAL(0) |
+			S3C2410_LCDCON4_HSPW(2 hsync_len),*/
+
+	.lcdcon5	= S3C2410_LCDCON5_FRM565 |
+			S3C2410_LCDCON5_INVVCLK |
+			S3C2410_LCDCON5_INVVLINE |
+			S3C2410_LCDCON5_INVVFRAME |
+			S3C2410_LCDCON5_INVVDEN |
+			S3C2410_LCDCON5_PWREN |
+			S3C2410_LCDCON5_HWSWP,
+
+	.type		= S3C2410_LCDCON1_TFT,
+
+	.width		= 240,
+	.height		= 320,
+
+	.pixclock	= 166667, /* HCLK 60 MHz, divisor 10 */
+	.xres		= 240,
+	.yres		= 320,
+	.bpp		= 16,
+
+	.left_margin	= 8,
+	.right_margin	= 5,
+	.hsync_len	= 3,
+	.upper_margin	= 6,
+	.lower_margin	= 7,
+	.vsync_len	= 2,
+};
+
+static struct s3c2410fb_mach_info g500_fb_info __initdata = {
+	.displays	= &g500_lcd_cfg,
+	.num_displays	= 1,
+	.default_display = 0,
+
+#if 0
+	/* currently setup by wince, TODO find exact values */
+	.gpccon		= 0xaa940659,
+	.gpccon_mask	= 0xffffffff,
+	.gpcup		= 0x0000ffff,
+	.gpcup_mask	= 0xffffffff,
+	.gpdcon		= 0xaa84aaa0,
+	.gpdcon_mask	= 0xffffffff,
+	.gpdup		= 0x0000faff,
+	.gpdup_mask	= 0xffffffff,
+#endif
+
+	.lpcsel		= 0xCE6,
+};
+
+static struct mtd_partition g500_nand_part[] = {
+	[0] = {
+		.name		= "Whole Flash",
+		.offset		= 0,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= MTD_WRITEABLE,
+	}
+};
+
+static struct s3c2410_nand_set g500_nand_sets[] = {
+	[0] = {
+		.name		= "Internal",
+		.nr_chips	= 1,
+		.nr_partitions	= ARRAY_SIZE(g500_nand_part),
+		.partitions	= g500_nand_part,
+	},
+};
+
+static struct s3c2410_platform_nand g500_nand_info = {
+	.tacls		= 20,
+	.twrph0		= 60,
+	.twrph1		= 20,
+	.nr_sets	= ARRAY_SIZE(g500_nand_sets),
+	.sets		= g500_nand_sets,
+};
+
+static struct s3c2410_ts_mach_info g500_ts_cfg = {
+	.delay = 10000,
+	.presc = 65,
+	.oversampling_shift = 5,
+};
+
+static void s3c2410_mmc_def_setpower(unsigned int to)
+{
+	s3c2410_gpio_cfgpin(S3C2410_GPA17, S3C2410_GPIO_OUTPUT);
+	s3c2410_gpio_setpin(S3C2410_GPA17, to);
+}
+
+static struct s3c24xx_mmc_platdata g500_mmc_cfg = {
+	.gpio_detect  = S3C2410_GPF6,
+	.set_power  = s3c2410_mmc_def_setpower,
+	.ocr_avail  = MMC_VDD_32_33,
+};
+
+static struct gpio_keys_button g500_buttons[] = {
+	{
+		.gpio		= S3C2410_GPF1,
+		.code	= KEY_POWER,
+    .type = EV_KEY,
+		.desc		= "Power",
+		.active_low	= 1,
+	},
+	{
+		.gpio		= S3C2410_GPG2,
+		.code	= KEY_CAMERA,
+    .type = EV_KEY,
+		.desc		= "Camera",
+		.active_low	= 1,
+	},
+	{
+		.gpio		= S3C2410_GPG3,
+		.code	= KEY_LEFT,
+    .type = EV_KEY,
+		.desc		= "Left",
+		.active_low	= 1,
+	},
+	{
+		.gpio		= S3C2410_GPG5,
+		.code	= KEY_RIGHT,
+    .type = EV_KEY,
+		.desc		= "Right",
+		.active_low	= 1,
+	},
+	{
+		.gpio		= S3C2410_GPG6,
+		.code	= KEY_REPLY,
+    .type = EV_KEY,
+		.desc		= "Pick-Up",
+		.active_low	= 1,
+	},
+};
+
+static struct gpio_keys_platform_data g500_button_data = {
+	.buttons	= g500_buttons,
+	.nbuttons	= ARRAY_SIZE(g500_buttons),
+};
+
+static struct platform_device g500_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &g500_button_data,
+	}
+};
+
+// currently only vibrator, blue and red leds control is unknown
+static struct gpio_led g500_leds[] = {
+	{
+		.name = "vibrator",
+		.gpio = S3C2410_GPA6,
+		.active_low = 0,
+		.default_trigger = NULL,
+	},
+};
+
+static struct gpio_led_platform_data g500_led_data = {
+	.num_leds =     ARRAY_SIZE(g500_leds),
+	.leds =         g500_leds,
+};
+
+static struct platform_device g500_gpio_leds = {
+	.name =         "leds-gpio",
+	.id =           -1,
+	.dev = {
+		.platform_data = &g500_led_data,
+	}
+};
+
+static void g500_backlight_power(int on)
+{
+	s3c2410_gpio_setpin(S3C2410_GPB0, 0);
+	s3c2410_gpio_pullup(S3C2410_GPB0, 0);
+
+	s3c2410_gpio_cfgpin(S3C2410_GPB0,
+			(on) ? S3C2410_GPB0_TOUT0 : S3C2410_GPB0_OUTP);
+}
+
+static void g500_lcd_power(int on)
+{
+	s3c2410_gpio_setpin(S3C2410_GPC0, on);
+}
+
+static void g500_set_brightness(int tcmpb0)
+{
+	unsigned long tcfg0;
+	unsigned long tcfg1;
+	unsigned long tcon;
+
+	/* configure power on/off */
+	g500_backlight_power(tcmpb0 ? 1 : 0);
+
+
+	tcfg0=readl(S3C2410_TCFG0);
+	tcfg1=readl(S3C2410_TCFG1);
+
+	tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
+	tcfg0 |= 0x18;
+
+	tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK;
+	tcfg1 |= S3C2410_TCFG1_MUX0_DIV2;
+
+	writel(tcfg0, S3C2410_TCFG0);
+	writel(tcfg1, S3C2410_TCFG1);
+	writel(0x31, S3C2410_TCNTB(0));
+
+	tcon = readl(S3C2410_TCON);
+	tcon &= ~0x0F;
+	tcon |= S3C2410_TCON_T0RELOAD;
+	tcon |= S3C2410_TCON_T0MANUALUPD;
+
+	writel(tcon, S3C2410_TCON);
+	writel(0x31, S3C2410_TCNTB(0));
+	writel(tcmpb0, S3C2410_TCMPB(0));
+
+	/* start the timer running */
+	tcon |= S3C2410_TCON_T0START;
+	tcon &= ~S3C2410_TCON_T0MANUALUPD;
+	writel(tcon, S3C2410_TCON);
+}
+
+static struct s3c2410_bl_mach_info g500_bl_cfg __initdata = {
+
+	.backlight_max          = 0x2c,
+	.backlight_default      = 0x16,
+	.backlight_power	= g500_backlight_power,
+	.set_brightness		= g500_set_brightness,
+	.backlight_power	= g500_backlight_power,
+	.lcd_power		= g500_lcd_power
+};
+
+static struct platform_device *g500_devices[] __initdata = {
+	&s3c_device_rtc,
+	&s3c_device_usb,
+	&s3c_device_lcd,
+	&s3c_device_wdt,
+	&s3c_device_i2c,
+	&s3c_device_iis,
+	&s3c_device_nand,
+	&s3c_device_usbgadget,
+	&s3c_device_ts,
+	&s3c_device_sdi,
+	&s3c_device_bl,
+};
+
+static void __init g500_map_io(void)
+{
+	s3c_device_nand.dev.platform_data = &g500_nand_info;
+	s3c24xx_init_io(g500_iodesc, ARRAY_SIZE(g500_iodesc));
+	s3c24xx_init_clocks(0);
+	s3c24xx_init_uarts(g500_uartcfgs, ARRAY_SIZE(g500_uartcfgs));
+}
+
+static void __init g500_init_machine(void)
+{
+	platform_add_devices(g500_devices, ARRAY_SIZE(g500_devices));
+
+	s3c24xx_fb_set_platdata(&g500_fb_info);
+	set_s3c2410ts_info(&g500_ts_cfg);
+	s3c_device_sdi.dev.platform_data = &g500_mmc_cfg;
+  platform_device_register(&g500_button_device);
+	platform_device_register(&g500_gpio_leds);
+	set_s3c2410bl_info(&g500_bl_cfg);
+
+	s3c2410_pm_init();
+
+  /* wake up source */
+  s3c_irq_wake(IRQ_EINT1, 1);
+}
+
+
+MACHINE_START(G500, "G500")
+	/* Maintainer: Pierre Hebert <pierrox@pierrox.net> */
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+
+	.init_irq	= s3c24xx_init_irq,
+	.map_io		= g500_map_io,
+	.init_machine	= g500_init_machine,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
Index: linux-2.6.24/drivers/usb/gadget/s3c2410_udc.c
===================================================================
--- linux-2.6.24.orig/drivers/usb/gadget/s3c2410_udc.c	2008-02-03 18:19:34.000000000 +0100
+++ linux-2.6.24/drivers/usb/gadget/s3c2410_udc.c	2008-02-03 18:20:38.000000000 +0100
@@ -845,6 +845,7 @@
 	u32			ep_csr1;
 	u32			idx;
 
+handle_ep_again:
 	if (likely (!list_empty(&ep->queue)))
 		req = list_entry(ep->queue.next,
 				struct s3c2410_request, queue);
@@ -884,6 +885,8 @@
 
 		if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) {
 			s3c2410_udc_read_fifo(ep,req);
+			if (s3c2410_udc_fifo_count_out())
+				goto handle_ep_again;
 		}
 	}
 }
Index: linux-2.6.24/arch/arm/plat-s3c24xx/devs.c
===================================================================
--- linux-2.6.24.orig/arch/arm/plat-s3c24xx/devs.c	2008-02-03 18:19:33.000000000 +0100
+++ linux-2.6.24/arch/arm/plat-s3c24xx/devs.c	2008-02-03 18:20:45.000000000 +0100
@@ -24,6 +24,8 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 #include <asm/arch/fb.h>
+#include <asm/arch/lcd.h>
+#include <asm/arch/ts.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -207,6 +209,23 @@
 
 EXPORT_SYMBOL(s3c_device_nand);
 
+/* Touchscreen */
+struct platform_device s3c_device_ts = {
+	.name		  = "s3c2410-ts",
+	.id		  = -1,
+};
+
+EXPORT_SYMBOL(s3c_device_ts);
+
+static struct s3c2410_ts_mach_info s3c2410ts_info;
+
+void set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
+{
+	memcpy(&s3c2410ts_info,hard_s3c2410ts_info,sizeof(struct s3c2410_ts_mach_info));
+	s3c_device_ts.dev.platform_data = &s3c2410ts_info;
+}
+EXPORT_SYMBOL(set_s3c2410ts_info);
+
 /* USB Device (Gadget)*/
 
 static struct resource s3c_usbgadget_resource[] = {
@@ -595,6 +614,25 @@
 
 EXPORT_SYMBOL(s3c_device_timer3);
 
+/* LCD backlight */
+
+struct platform_device s3c_device_bl = {
+	.name		  = "s3c2410-bl",
+	.id		  = -1,
+};
+
+EXPORT_SYMBOL(s3c_device_bl);
+
+static struct s3c2410_bl_mach_info s3c2410bl_info;
+
+void __init set_s3c2410bl_info(struct s3c2410_bl_mach_info *hard_s3c2410bl_info)
+{
+	memcpy(&s3c2410bl_info, hard_s3c2410bl_info, sizeof(struct s3c2410_bl_mach_info));
+	s3c_device_bl.dev.platform_data = &s3c2410bl_info;
+}
+
+EXPORT_SYMBOL(set_s3c2410bl_info);
+
 #ifdef CONFIG_CPU_S3C2440
 
 /* Camif Controller */
Index: linux-2.6.24/include/asm-arm/plat-s3c24xx/devs.h
===================================================================
--- linux-2.6.24.orig/include/asm-arm/plat-s3c24xx/devs.h	2008-02-03 18:19:33.000000000 +0100
+++ linux-2.6.24/include/asm-arm/plat-s3c24xx/devs.h	2008-02-03 18:20:45.000000000 +0100
@@ -42,6 +42,9 @@
 extern struct platform_device s3c_device_timer3;
 
 extern struct platform_device s3c_device_usbgadget;
+extern struct platform_device s3c_device_ts;
+
+extern struct platform_device s3c_device_bl;
 
 /* s3c2440 specific devices */
 
Index: linux-2.6.24/arch/arm/mach-s3c2410/mach-h1940.c
===================================================================
--- linux-2.6.24.orig/arch/arm/mach-s3c2410/mach-h1940.c	2008-02-03 18:19:33.000000000 +0100
+++ linux-2.6.24/arch/arm/mach-s3c2410/mach-h1940.c	2008-02-03 18:20:39.000000000 +0100
@@ -38,6 +38,7 @@
 #include <asm/arch/h1940.h>
 #include <asm/arch/h1940-latch.h>
 #include <asm/arch/fb.h>
+#include <asm/arch/tc.h>
 #include <asm/plat-s3c24xx/udc.h>
 
 #include <asm/plat-s3c24xx/clock.h>
@@ -129,6 +130,11 @@
 	.vbus_pin_inverted	= 1,
 };
 
+static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
+		.delay = 10000,
+		.presc = 49,
+		.oversampling_shift = 2,
+};
 
 /**
  * Set lcd on or off
@@ -186,6 +192,7 @@
 	&s3c_device_i2c,
 	&s3c_device_iis,
 	&s3c_device_usbgadget,
+	&s3c_device_ts,
 	&s3c_device_leds,
 	&s3c_device_bluetooth,
 };
@@ -214,6 +221,7 @@
 	u32 tmp;
 
 	s3c24xx_fb_set_platdata(&h1940_fb_info);
+	set_s3c2410ts_info(&h1940_ts_cfg);
  	s3c24xx_udc_set_platdata(&h1940_udc_cfg);
 
 	/* Turn off suspend on both USB ports, and switch the
Index: linux-2.6.24/drivers/input/touchscreen/Kconfig
===================================================================
--- linux-2.6.24.orig/drivers/input/touchscreen/Kconfig	2008-02-03 18:19:33.000000000 +0100
+++ linux-2.6.24/drivers/input/touchscreen/Kconfig	2008-02-03 18:20:39.000000000 +0100
@@ -67,6 +67,24 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called fujitsu-ts.
 
+config TOUCHSCREEN_S3C2410
+	tristate "Samsung S3C2410 touchscreen input driver"
+	depends on ARCH_S3C2410 && INPUT && INPUT_TOUCHSCREEN
+	select SERIO
+	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 s3c2410_ts.
+
+config TOUCHSCREEN_S3C2410_DEBUG
+	boolean "Samsung S3C2410 touchscreen debug messages"
+	depends on TOUCHSCREEN_S3C2410
+	help
+	  Select this if you want debug messages
+
 config TOUCHSCREEN_GUNZE
 	tristate "Gunze AHL-51S touchscreen"
 	select SERIO
Index: linux-2.6.24/drivers/input/touchscreen/Makefile
===================================================================
--- linux-2.6.24.orig/drivers/input/touchscreen/Makefile	2008-02-03 18:19:33.000000000 +0100
+++ linux-2.6.24/drivers/input/touchscreen/Makefile	2008-02-03 18:20:39.000000000 +0100
@@ -19,3 +19,4 @@
 obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
 obj-$(CONFIG_TOUCHSCREEN_UCB1400)	+= ucb1400_ts.o
+obj-$(CONFIG_TOUCHSCREEN_S3C2410)	+= s3c2410_ts.o
Index: linux-2.6.24/drivers/input/touchscreen/s3c2410_ts.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/drivers/input/touchscreen/s3c2410_ts.c	2008-02-03 18:20:39.000000000 +0100
@@ -0,0 +1,437 @@
+/*
+ * 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
+ *
+ * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
+ * iPAQ H1940 touchscreen support
+ *
+ * ChangeLog
+ *
+ * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
+ *	- added clock (de-)allocation code
+ *
+ * 2005-03-06: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *      - h1940_ -> s3c2410 (this driver is now also used on the n30
+ *        machines :P)
+ *      - Debug messages are now enabled with the config option
+ *        TOUCHSCREEN_S3C2410_DEBUG
+ *      - Changed the way the value are read
+ *      - Input subsystem should now work
+ *      - Use ioremap and readl/writel
+ *
+ * 2005-03-23: Arnaud Patard <arnaud.patard@rtp-net.org>
+ *      - Make use of some undocumented features of the touchscreen
+ *        controller
+ *
+ * 2007-05-23: Harald Welte <laforge@openmoko.org>
+ * 	- Add proper support for S32440
+ */
+
+#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 <linux/platform_device.h>
+#include <linux/clk.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/ts.h>
+
+#include <asm/plat-s3c/regs-adc.h>
+
+/* For ts.dev.id.version */
+#define S3C2410TSVERSION	0x0101
+
+#define TSC_SLEEP  (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))
+
+#define WAIT4INT(x)  (((x)<<8) | \
+		     S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
+		     S3C2410_ADCTSC_XY_PST(3))
+
+#define AUTOPST	     (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
+		     S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0))
+
+#define DEBUG_LVL    KERN_DEBUG
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("s3c2410 touchscreen driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+
+static char *s3c2410ts_name = "s3c2410 TouchScreen";
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct s3c2410ts {
+	struct input_dev *dev;
+	long xp;
+	long yp;
+	int count;
+	int shift;
+};
+
+static struct s3c2410ts ts;
+static void __iomem *base_addr;
+
+static inline void s3c2410_ts_connect(void)
+{
+	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);
+}
+
+static void touch_timer_fire(unsigned long data)
+{
+  	unsigned long data0;
+  	unsigned long data1;
+	int updown;
+
+  	data0 = readl(base_addr+S3C2410_ADCDAT0);
+  	data1 = readl(base_addr+S3C2410_ADCDAT1);
+
+ 	updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
+
+ 	if (updown) {
+ 		if (ts.count != 0) {
+ 			ts.xp >>= ts.shift;
+ 			ts.yp >>= ts.shift;
+
+#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
+ 			{
+ 				struct timeval tv;
+ 				do_gettimeofday(&tv);
+ 				printk(DEBUG_LVL "T: %06d, X: %03ld, Y: %03ld\n", (int)tv.tv_usec, ts.xp, ts.yp);
+ 			}
+#endif
+
+ 			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_report_abs(ts.dev, ABS_PRESSURE, 1);
+ 			input_sync(ts.dev);
+ 		}
+
+ 		ts.xp = 0;
+ 		ts.yp = 0;
+ 		ts.count = 0;
+
+ 		writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
+ 		writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
+ 	} else {
+ 		ts.count = 0;
+
+ 		input_report_key(ts.dev, BTN_TOUCH, 0);
+ 		input_report_abs(ts.dev, ABS_PRESSURE, 0);
+ 		input_sync(ts.dev);
+
+ 		writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
+ 	}
+}
+
+static struct timer_list touch_timer =
+		TIMER_INITIALIZER(touch_timer_fire, 0, 0);
+
+static irqreturn_t stylus_updown(int irq, void *dev_id)
+{
+	unsigned long data0;
+	unsigned long data1;
+	int updown;
+
+	data0 = readl(base_addr+S3C2410_ADCDAT0);
+	data1 = readl(base_addr+S3C2410_ADCDAT1);
+
+	updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
+
+	/* TODO we should never get an interrupt with updown set while
+	 * the timer is running, but maybe we ought to verify that the
+	 * timer isn't running anyways. */
+
+	if (updown)
+		touch_timer_fire(0);
+
+	return IRQ_HANDLED;
+}
+
+
+static irqreturn_t stylus_action(int irq, void *dev_id)
+{
+	unsigned long data0;
+	unsigned long data1;
+
+	data0 = readl(base_addr+S3C2410_ADCDAT0);
+	data1 = readl(base_addr+S3C2410_ADCDAT1);
+
+	ts.xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK;
+	ts.yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK;
+	ts.count++;
+
+        if (ts.count < (1<<ts.shift)) {
+		writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
+		writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
+	} else {
+		mod_timer(&touch_timer, jiffies+1);
+		writel(WAIT4INT(1), base_addr+S3C2410_ADCTSC);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct clk	*adc_clock;
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init s3c2410ts_probe(struct platform_device *pdev)
+{
+	int rc;
+	struct s3c2410_ts_mach_info *info;
+	struct input_dev *input_dev;
+
+	info = ( struct s3c2410_ts_mach_info *)pdev->dev.platform_data;
+
+	if (!info)
+	{
+		printk(KERN_ERR "Hm... too bad : no platform data for ts\n");
+		return -EINVAL;
+	}
+
+#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
+	printk(DEBUG_LVL "Entering s3c2410ts_init\n");
+#endif
+
+	adc_clock = clk_get(NULL, "adc");
+	if (!adc_clock) {
+		printk(KERN_ERR "failed to get adc clock source\n");
+		return -ENOENT;
+	}
+	clk_enable(adc_clock);
+
+#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
+	printk(DEBUG_LVL "got and enabled clock\n");
+#endif
+
+	base_addr = ioremap(S3C2410_PA_ADC,0x20);
+	if (base_addr == NULL) {
+		printk(KERN_ERR "Failed to remap register block\n");
+		return -ENOMEM;
+	}
+
+
+	/* If we acutally are a S3C2410: Configure GPIOs */
+	if (!strcmp(pdev->name, "s3c2410-ts"))
+		s3c2410_ts_connect();
+
+	if ((info->presc&0xff) > 0)
+		writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\
+			     base_addr+S3C2410_ADCCON);
+	else
+		writel(0,base_addr+S3C2410_ADCCON);
+
+
+	/* Initialise registers */
+	if ((info->delay&0xffff) > 0)
+		writel(info->delay & 0xffff,  base_addr+S3C2410_ADCDLY);
+
+	writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
+
+	/* Initialise input stuff */
+	memset(&ts, 0, sizeof(struct s3c2410ts));
+	input_dev = input_allocate_device();
+
+	if (!input_dev) {
+		printk(KERN_ERR "Unable to allocate the input device !!\n");
+		return -ENOMEM;
+	}
+
+	ts.dev = input_dev;
+	ts.dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) |
+			   BIT_MASK(EV_ABS);
+	ts.dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	input_set_abs_params(ts.dev, ABS_X, 0, 0x3FF, 0, 0);
+	input_set_abs_params(ts.dev, ABS_Y, 0, 0x3FF, 0, 0);
+	input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 1, 0, 0);
+
+	ts.dev->private = &ts;
+	ts.dev->name = s3c2410ts_name;
+	ts.dev->id.bustype = BUS_RS232;
+	ts.dev->id.vendor = 0xDEAD;
+	ts.dev->id.product = 0xBEEF;
+	ts.dev->id.version = S3C2410TSVERSION;
+
+	ts.shift = info->oversampling_shift;
+
+	/* Get irqs */
+	if (request_irq(IRQ_ADC, stylus_action, IRQF_SAMPLE_RANDOM,
+		"s3c2410_action", ts.dev)) {
+		printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_ADC !\n");
+		iounmap(base_addr);
+		return -EIO;
+	}
+	if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM,
+			"s3c2410_action", ts.dev)) {
+		printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_TC !\n");
+		free_irq(IRQ_ADC, ts.dev);
+		iounmap(base_addr);
+		return -EIO;
+	}
+
+	printk(KERN_INFO "%s successfully loaded\n", s3c2410ts_name);
+
+	/* All went ok, so register to the input system */
+	rc = input_register_device(ts.dev);
+	if (rc) {
+		free_irq(IRQ_TC, ts.dev);
+		free_irq(IRQ_ADC, ts.dev);
+		clk_disable(adc_clock);
+		iounmap(base_addr);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int s3c2410ts_remove(struct platform_device *pdev)
+{
+	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_put(adc_clock);
+		adc_clock = NULL;
+	}
+
+	input_unregister_device(ts.dev);
+	iounmap(base_addr);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c2410ts_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	writel(TSC_SLEEP, base_addr+S3C2410_ADCTSC);
+	writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_STDBM,
+	       base_addr+S3C2410_ADCCON);
+
+	disable_irq(IRQ_ADC);
+	disable_irq(IRQ_TC);
+
+	clk_disable(adc_clock);
+
+	return 0;
+}
+
+static int s3c2410ts_resume(struct platform_device *pdev)
+{
+	struct s3c2410_ts_mach_info *info =
+		( struct s3c2410_ts_mach_info *)pdev->dev.platform_data;
+
+	clk_enable(adc_clock);
+	msleep(1);
+
+	enable_irq(IRQ_ADC);
+	enable_irq(IRQ_TC);
+
+	if ((info->presc&0xff) > 0)
+		writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\
+			     base_addr+S3C2410_ADCCON);
+	else
+		writel(0,base_addr+S3C2410_ADCCON);
+
+	/* Initialise registers */
+	if ((info->delay&0xffff) > 0)
+		writel(info->delay & 0xffff,  base_addr+S3C2410_ADCDLY);
+
+	writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
+
+	return 0;
+}
+
+#else
+#define s3c2410ts_suspend NULL
+#define s3c2410ts_resume  NULL
+#endif
+
+static struct platform_driver s3c2410ts_driver = {
+       .driver         = {
+	       .name   = "s3c2410-ts",
+	       .owner  = THIS_MODULE,
+       },
+       .probe          = s3c2410ts_probe,
+       .remove         = s3c2410ts_remove,
+       .suspend        = s3c2410ts_suspend,
+       .resume         = s3c2410ts_resume,
+
+};
+
+static struct platform_driver s3c2440ts_driver = {
+       .driver         = {
+	       .name   = "s3c2440-ts",
+	       .owner  = THIS_MODULE,
+       },
+       .probe          = s3c2410ts_probe,
+       .remove         = s3c2410ts_remove,
+       .suspend        = s3c2410ts_suspend,
+       .resume         = s3c2410ts_resume,
+
+};
+
+static int __init s3c2410ts_init(void)
+{
+	int rc;
+
+	rc = platform_driver_register(&s3c2410ts_driver);
+	if (rc < 0)
+		return rc;
+
+	rc = platform_driver_register(&s3c2440ts_driver);
+	if (rc < 0)
+		platform_driver_unregister(&s3c2410ts_driver);
+
+	return rc;
+}
+
+static void __exit s3c2410ts_exit(void)
+{
+	platform_driver_unregister(&s3c2440ts_driver);
+	platform_driver_unregister(&s3c2410ts_driver);
+}
+
+module_init(s3c2410ts_init);
+module_exit(s3c2410ts_exit);
+
+/*
+    Local variables:
+        compile-command: "make ARCH=arm CROSS_COMPILE=/usr/local/arm/3.3.2/bin/arm-linux- -k -C ../../.."
+        c-basic-offset: 8
+    End:
+*/
Index: linux-2.6.24/include/asm-arm/arch-s3c2410/ts.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/include/asm-arm/arch-s3c2410/ts.h	2008-02-03 18:20:39.000000000 +0100
@@ -0,0 +1,28 @@
+/* linux/include/asm/arch-s3c2410/ts.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ *  Changelog:
+ *     24-Mar-2005     RTP     Created file
+ *     03-Aug-2005     RTP     Renamed to ts.h
+ */
+
+#ifndef __ASM_ARM_TS_H
+#define __ASM_ARM_TS_H
+
+struct s3c2410_ts_mach_info {
+       int             delay;
+       int             presc;
+       int             oversampling_shift;
+};
+
+void set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info);
+
+#endif /* __ASM_ARM_TS_H */
+
Index: linux-2.6.24/arch/arm/plat-s3c24xx/s3c244x.c
===================================================================
--- linux-2.6.24.orig/arch/arm/plat-s3c24xx/s3c244x.c	2008-02-03 18:19:33.000000000 +0100
+++ linux-2.6.24/arch/arm/plat-s3c24xx/s3c244x.c	2008-02-03 18:20:39.000000000 +0100
@@ -67,6 +67,7 @@
 
 	s3c_device_i2c.name  = "s3c2440-i2c";
 	s3c_device_nand.name = "s3c2440-nand";
+	s3c_device_ts.name = "s3c2440-ts";
 	s3c_device_usbgadget.name = "s3c2440-usbgadget";
 }
 
Index: linux-2.6.24/include/asm-arm/arch-s3c2410/mmc.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/include/asm-arm/arch-s3c2410/mmc.h	2008-02-03 18:20:41.000000000 +0100
@@ -0,0 +1,32 @@
+/* linux/include/asm-arm/arch-s3c2410/mmc.h
+ *
+ * (c) 2004-2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/SWLINUX/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX - MMC/SD platform data
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ *	26-Oct-2005 BJD  Created file
+*/
+
+#ifndef __ASM_ARCH_MMC_H
+#define __ASM_ARCH_MMC_H __FILE__
+
+struct s3c24xx_mmc_platdata {
+	unsigned int	gpio_detect;
+	unsigned int	gpio_wprotect;
+	unsigned int	detect_polarity;
+	unsigned int	wprotect_polarity;
+
+	unsigned long	f_max;
+	unsigned long	ocr_avail;
+
+	void		(*set_power)(unsigned int to);
+};
+
+#endif /* __ASM_ARCH_MMC_H */
Index: linux-2.6.24/include/asm-arm/arch-s3c2410/regs-sdi.h
===================================================================
--- linux-2.6.24.orig/include/asm-arm/arch-s3c2410/regs-sdi.h	2008-02-03 18:19:32.000000000 +0100
+++ linux-2.6.24/include/asm-arm/arch-s3c2410/regs-sdi.h	2008-02-03 18:20:41.000000000 +0100
@@ -13,6 +13,7 @@
 #ifndef __ASM_ARM_REGS_SDI
 #define __ASM_ARM_REGS_SDI "regs-sdi.h"
 
+#define S3C2410_SDIREG(x)       ((x) + S3C24XX_VA_SDI)
 #define S3C2410_SDICON                (0x00)
 #define S3C2410_SDIPRE                (0x04)
 #define S3C2410_SDICMDARG             (0x08)
@@ -31,18 +32,25 @@
 #define S3C2410_SDIDATA               (0x3C)
 #define S3C2410_SDIIMSK               (0x40)
 
+#define S3C2440_SDIDATA               (0x40)
+#define S3C2440_SDIIMSK               (0x3C)
+
+#define S3C2440_SDICON_SDRESET        (1<<8)
+#define S3C2440_SDICON_MMCCLOCK       (1<<5)
 #define S3C2410_SDICON_BYTEORDER      (1<<4)
 #define S3C2410_SDICON_SDIOIRQ        (1<<3)
 #define S3C2410_SDICON_RWAITEN        (1<<2)
 #define S3C2410_SDICON_FIFORESET      (1<<1)
 #define S3C2410_SDICON_CLOCKTYPE      (1<<0)
+#define S3C2440_SDICON_CLOCKENABLE    (1<<0)
 
 #define S3C2410_SDICMDCON_ABORT       (1<<12)
 #define S3C2410_SDICMDCON_WITHDATA    (1<<11)
 #define S3C2410_SDICMDCON_LONGRSP     (1<<10)
 #define S3C2410_SDICMDCON_WAITRSP     (1<<9)
 #define S3C2410_SDICMDCON_CMDSTART    (1<<8)
-#define S3C2410_SDICMDCON_INDEX       (0xff)
+#define S3C2410_SDICMDCON_SENDERHOST  (1<<6)
+#define S3C2410_SDICMDCON_INDEX       (0x3f)
 
 #define S3C2410_SDICMDSTAT_CRCFAIL    (1<<12)
 #define S3C2410_SDICMDSTAT_CMDSENT    (1<<11)
@@ -50,7 +58,11 @@
 #define S3C2410_SDICMDSTAT_RSPFIN     (1<<9)
 #define S3C2410_SDICMDSTAT_XFERING    (1<<8)
 #define S3C2410_SDICMDSTAT_INDEX      (0xff)
+#define S3C2410_SDICMDSTAT_ALLFLAGS   (0x1f00)
 
+#define S3C2440_SDIDCON_DS_BYTE       (0<<22)
+#define S3C2440_SDIDCON_DS_HALFWORD   (1<<22)
+#define S3C2440_SDIDCON_DS_WORD       (2<<22)
 #define S3C2410_SDIDCON_IRQPERIOD     (1<<21)
 #define S3C2410_SDIDCON_TXAFTERRESP   (1<<20)
 #define S3C2410_SDIDCON_RXAFTERCMD    (1<<19)
@@ -58,8 +70,11 @@
 #define S3C2410_SDIDCON_BLOCKMODE     (1<<17)
 #define S3C2410_SDIDCON_WIDEBUS       (1<<16)
 #define S3C2410_SDIDCON_DMAEN         (1<<15)
+#define S3C2440_SDIDCON_DATA_START    (1<<14)
 #define S3C2410_SDIDCON_STOP          (1<<14)
-#define S3C2410_SDIDCON_DATMODE	      (3<<12)
+#define S3C2440_SDIDCON_DATA_MODE_TX  (3<<12)
+#define S3C2410_SDIDCON_DATMODE       (3<<12)
+#define S3C2440_SDIDCON_DATA_MODE_RX  (2<<12)
 #define S3C2410_SDIDCON_BLKNUM        (0x7ff)
 
 /* constants for S3C2410_SDIDCON_DATMODE */
@@ -68,6 +83,7 @@
 #define S3C2410_SDIDCON_XFER_RXSTART  (2<<12)
 #define S3C2410_SDIDCON_XFER_TXSTART  (3<<12)
 
+#define S3C2410_SDIDCON_BLKNUM_MASK   (0xFFF)
 #define S3C2410_SDIDCNT_BLKNUM_SHIFT  (12)
 
 #define S3C2410_SDIDSTA_RDYWAITREQ    (1<<10)
@@ -82,6 +98,8 @@
 #define S3C2410_SDIDSTA_TXDATAON      (1<<1)
 #define S3C2410_SDIDSTA_RXDATAON      (1<<0)
 
+#define S3C2440_SDIFSTA_FIFORESET      (1<<16)
+#define S3C2440_SDIFSTA_FIFOFAIL       (3<<14)
 #define S3C2410_SDIFSTA_TFDET          (1<<13)
 #define S3C2410_SDIFSTA_RFDET          (1<<12)
 #define S3C2410_SDIFSTA_TXHALF         (1<<11)
@@ -91,6 +109,7 @@
 #define S3C2410_SDIFSTA_RFHALF         (1<<7)
 #define S3C2410_SDIFSTA_COUNTMASK      (0x7f)
 
+#define S3C2440_SDIIMSK_NOBUSY         (1<<18)
 #define S3C2410_SDIIMSK_RESPONSECRC    (1<<17)
 #define S3C2410_SDIIMSK_CMDSENT        (1<<16)
 #define S3C2410_SDIIMSK_CMDTIMEOUT     (1<<15)
@@ -110,4 +129,14 @@
 #define S3C2410_SDIIMSK_RXFIFOFULL     (1<<1)
 #define S3C2410_SDIIMSK_RXFIFOHALF     (1<<0)
 
+#define S3C2410_SDICMDCON_ABORT       (1<<12)
+#define S3C2410_SDICMDCON_WITHDATA    (1<<11)
+#define S3C2410_SDICMDCON_LONGRSP     (1<<10)
+#define S3C2410_SDICMDCON_WAITRSP     (1<<9)
+#define S3C2410_SDICMDCON_CMDSTART    (1<<8)
+#define S3C2410_SDICMDCON_SENDERHOST  (1<<6)
+
+#define S3C2410_SDIDCON_BLKNUM_MASK   (0xFFF)
+#define S3C2410_SDIDCNT_BLKNUM_SHIFT  (12)
+
 #endif /* __ASM_ARM_REGS_SDI */
Index: linux-2.6.24/drivers/mmc/host/Kconfig
===================================================================
--- linux-2.6.24.orig/drivers/mmc/host/Kconfig	2008-02-03 18:19:32.000000000 +0100
+++ linux-2.6.24/drivers/mmc/host/Kconfig	2008-02-03 18:20:41.000000000 +0100
@@ -130,3 +130,11 @@
 
 	  If unsure, or if your system has no SPI master driver, say N.
 
+config MMC_S3C2440
+	tristate "Samsung S3C2440 Multimedia Card Interface support"
+	depends on MMC && CPU_S3C2440
+	help
+	  This selects the Samsung S3C2440 Multimedia Card Interface
+	  support.
+
+	  If unsure, say N.
Index: linux-2.6.24/drivers/mmc/host/Makefile
===================================================================
--- linux-2.6.24.orig/drivers/mmc/host/Makefile	2008-02-03 18:19:32.000000000 +0100
+++ linux-2.6.24/drivers/mmc/host/Makefile	2008-02-03 18:20:41.000000000 +0100
@@ -17,4 +17,5 @@
 obj-$(CONFIG_MMC_AT91)		+= at91_mci.o
 obj-$(CONFIG_MMC_TIFM_SD)	+= tifm_sd.o
 obj-$(CONFIG_MMC_SPI)		+= mmc_spi.o
+obj-$(CONFIG_MMC_S3C2440)	+= s3c2440mci.o
 
Index: linux-2.6.24/drivers/mmc/host/s3c2440mci.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/drivers/mmc/host/s3c2440mci.c	2008-02-03 18:20:41.000000000 +0100
@@ -0,0 +1,832 @@
+/*
+ *  linux/drivers/mmc/s3c2440mci.c - Samsung S3C2410 SDI Interface driver
+ *
+ *  Copyright (C) 2004 Thomas Kleffel, All Rights Reserved.
+ *
+ * Hacked by Pierre Hebert for s3c2440. It is not clean, use with care.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/host.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+
+#include <asm/dma.h>
+#include <asm/dma-mapping.h>
+#include <asm/arch/dma.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/mmc.h>
+
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/mmc.h>
+
+#ifdef CONFIG_MMC_DEBUG
+#define DBG(x...)       printk(KERN_INFO x)
+#else
+#define DBG(x...)       do { } while (0)
+#endif
+
+#include "s3c2440mci.h"
+
+#define DRIVER_NAME "mmci-s3c2410"
+#define PFX DRIVER_NAME ": "
+
+#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
+
+static struct s3c2410_dma_client s3c2410sdi_dma_client = {
+	.name		= "s3c2410-sdi",
+};
+
+/*
+ * ISR for SDI Interface IRQ
+ * Communication between driver and ISR works as follows:
+ *   host->mrq 			points to current request
+ *   host->complete_what	tells the ISR when the request is considered done
+ *     COMPLETION_CMDSENT	  when the command was sent
+ *     COMPLETION_RSPFIN          when a response was received
+ *     COMPLETION_XFERFINISH	  when the data transfer is finished
+ *     COMPLETION_XFERFINISH_RSPFIN both of the above.
+ *   host->complete_request	is the completion-object the driver waits for
+ *
+ * 1) Driver sets up host->mrq and host->complete_what
+ * 2) Driver prepares the transfer
+ * 3) Driver enables interrupts
+ * 4) Driver starts transfer
+ * 5) Driver waits for host->complete_rquest
+ * 6) ISR checks for request status (errors and success)
+ * 6) ISR sets host->mrq->cmd->error and host->mrq->data->error
+ * 7) ISR completes host->complete_request
+ * 8) ISR disables interrupts
+ * 9) Driver wakes up and takes care of the request
+*/
+
+static irqreturn_t s3c2410sdi_irq(int irq, void *dev_id)
+{
+	struct s3c2410sdi_host *host;
+	u32 sdi_csta, sdi_fsta, sdi_dsta, sdi_dcnt;
+	u32 sdi_cclear, sdi_dclear;
+	unsigned long iflags;
+
+	host = (struct s3c2410sdi_host *)dev_id;
+
+
+	/* Check for things not supposed to happen */
+	if(!host) return IRQ_HANDLED;
+
+	sdi_csta 	= readl(host->base + S3C2410_SDICMDSTAT);
+	sdi_dsta 	= readl(host->base + S3C2410_SDIDSTA);
+	sdi_fsta 	= readl(host->base + S3C2410_SDIFSTA);
+	sdi_dcnt 	= readl(host->base + S3C2410_SDIDCNT);
+
+	DBG(PFX "[IRQ] csta=%08x dsta=%08x fsta=%08x dcnt=%08x\n", sdi_csta, sdi_dsta, sdi_fsta, sdi_dcnt);
+
+	spin_lock_irqsave( &host->complete_lock, iflags);
+
+	if( host->complete_what==COMPLETION_NONE ) {
+		goto clear_imask;
+	}
+
+	if(!host->mrq) {
+		goto clear_imask;
+	}
+
+
+	sdi_cclear	= 0;
+	sdi_dclear	= 0;
+
+
+	if(sdi_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
+		host->mrq->cmd->error = -ETIMEDOUT;
+		goto transfer_closed;
+	}
+
+	if(sdi_csta & S3C2410_SDICMDSTAT_CMDSENT) {
+		if(host->complete_what == COMPLETION_CMDSENT) {
+			host->mrq->cmd->error = 0;
+			goto transfer_closed;
+		}
+
+		sdi_cclear |= S3C2410_SDICMDSTAT_CMDSENT;
+	}
+
+	if(sdi_csta & S3C2410_SDICMDSTAT_CRCFAIL) {
+		if (host->mrq->cmd->flags & MMC_RSP_136) {
+			DBG(PFX "s3c2410 fixup : ignore CRC fail with long rsp\n");
+		}
+		else {
+			DBG(PFX "COMMAND CRC FAILED %x\n", sdi_csta);
+			if(host->mrq->cmd->flags & MMC_RSP_CRC) {
+				host->mrq->cmd->error = -EILSEQ;
+				goto transfer_closed;
+			}
+		}
+		sdi_cclear |= S3C2410_SDICMDSTAT_CRCFAIL;
+	}
+
+	if(sdi_csta & S3C2410_SDICMDSTAT_RSPFIN) {
+		if(host->complete_what == COMPLETION_RSPFIN) {
+			host->mrq->cmd->error = 0;
+			goto transfer_closed;
+		}
+
+		if(host->complete_what == COMPLETION_XFERFINISH_RSPFIN) {
+			host->mrq->cmd->error = 0;
+			host->complete_what = COMPLETION_XFERFINISH;
+		}
+
+		sdi_cclear |= S3C2410_SDICMDSTAT_RSPFIN;
+	}
+
+	if(host->mrq->data) {
+		if(sdi_fsta & S3C2440_SDIFSTA_FIFOFAIL) {
+			writel(sdi_fsta, host->base + S3C2410_SDIFSTA);
+			host->mrq->cmd->error = 0;
+			host->mrq->data->error = -EIO;
+			goto transfer_closed;
+		}
+
+		if(sdi_dsta & S3C2410_SDIDSTA_RXCRCFAIL) {
+			host->mrq->cmd->error = 0;
+			host->mrq->data->error = -EILSEQ;
+			goto transfer_closed;
+		}
+
+		/*if(sdi_dsta & S3C2410_SDIDSTA_CRCFAIL) {
+		  DBG(PFX "DATA CRC FAILED %u\n", sdi_csta);
+		  host->mrq->cmd->error = MMC_ERR_NONE;
+		  host->mrq->data->error = MMC_ERR_BADCRC;
+		  complete(&host->complete_dma);
+		  goto transfer_closed;
+		  }*/
+
+		/* I don't understand this CRC failure */
+		if(sdi_dsta & S3C2410_SDIDSTA_CRCFAIL) {
+			DBG(PFX "FIXME DATA CRC FAILED %u\n", sdi_csta);
+			host->mrq->cmd->error = 0;
+			host->mrq->data->error = 0;
+			complete(&host->complete_dma);
+			goto transfer_closed;
+		}
+
+		if(sdi_dsta & S3C2410_SDIDSTA_DATATIMEOUT) {
+			host->mrq->cmd->error = 0;
+			host->mrq->data->error = -ETIMEDOUT;
+			goto transfer_closed;
+		}
+
+		if(sdi_dsta & S3C2410_SDIDSTA_XFERFINISH) {
+			if(host->complete_what == COMPLETION_XFERFINISH) {
+				host->mrq->cmd->error = 0;
+				host->mrq->data->error = 0;
+				goto transfer_closed;
+			}
+
+			if(host->complete_what == COMPLETION_XFERFINISH_RSPFIN) {
+				host->mrq->data->error = 0;
+				host->complete_what = COMPLETION_RSPFIN;
+			}
+
+			sdi_dclear |= S3C2410_SDIDSTA_XFERFINISH;
+		}
+
+		if(sdi_fsta & S3C2410_SDIFSTA_RFLAST) {
+			writel(sdi_fsta, host->base + S3C2410_SDIFSTA);
+			host->mrq->cmd->error = 0;
+			host->mrq->data->error = 0;
+			goto transfer_closed;
+		}
+	}
+
+	// FIXME no dma for write operation
+	if(sdi_dsta & 2) {
+		while(sdi_fsta & S3C2410_SDIFSTA_TFDET && host->pio_words) {
+      //printk("write : %08x\n", *host->pio_ptr);
+			writel(*host->pio_ptr, host->base+S3C2440_SDIDATA);
+			(host->pio_ptr)++;
+			host->pio_words--;
+			sdi_fsta 	= readl(host->base + S3C2410_SDIFSTA);
+		}
+	}
+
+	spin_unlock_irqrestore( &host->complete_lock, iflags);
+	//DBG(PFX "IRQ still waiting.\n");
+	return IRQ_HANDLED;
+
+
+transfer_closed:
+	writel(sdi_cclear, host->base + S3C2410_SDICMDSTAT);
+	writel(sdi_dclear, host->base + S3C2410_SDIDSTA);
+	host->complete_what = COMPLETION_NONE;
+	complete(&host->complete_request);
+	writel(0, host->base + S3C2440_SDIIMSK);
+	spin_unlock_irqrestore( &host->complete_lock, iflags);
+	DBG(PFX "IRQ transfer closed.\n");
+	return IRQ_HANDLED;
+
+clear_imask:
+	writel(0, host->base + S3C2440_SDIIMSK);
+	spin_unlock_irqrestore( &host->complete_lock, iflags);
+	DBG(PFX "IRQ clear imask.\n");
+	return IRQ_HANDLED;
+
+}
+
+
+/*
+ * ISR for the CardDetect Pin
+*/
+
+static irqreturn_t s3c2410sdi_irq_cd(int irq, void *dev_id)
+{
+	struct s3c2410sdi_host *host = (struct s3c2410sdi_host *)dev_id;
+	mmc_detect_change(host->mmc, S3C2410SDI_CDLATENCY);
+
+	return IRQ_HANDLED;
+}
+
+
+
+static void s3c2410sdi_dma_done_callback(struct s3c2410_dma_chan *dma_ch, void *buf_id,
+	int size, enum s3c2410_dma_buffresult result)
+{	unsigned long iflags;
+	struct s3c2410sdi_host *host;
+	u32 sdi_dcnt;
+#ifdef CONFIG_MMC_DEBUG
+	u32 sdi_csta, sdi_dsta, sdi_fsta;
+#endif
+
+	host = (struct s3c2410sdi_host *)buf_id;
+	sdi_dcnt 	= readl(host->base + S3C2410_SDIDCNT);
+
+#ifdef CONFIG_MMC_DEBUG
+	sdi_csta 	= readl(host->base + S3C2410_SDICMDSTAT);
+	sdi_dsta 	= readl(host->base + S3C2410_SDIDSTA);
+	sdi_fsta 	= readl(host->base + S3C2410_SDIFSTA);
+
+	DBG(PFX "DMAD csta=0x%08x dsta=0x%08x fsta=%08x dcnt=0x%08x result:0x%08x\n", sdi_csta, sdi_dsta, sdi_fsta, sdi_dcnt, result);
+#endif
+
+
+	spin_lock_irqsave( &host->complete_lock, iflags);
+
+	if(!host->mrq) goto out;
+	if(!host->mrq->data) goto out;
+
+
+
+	if( result!=S3C2410_RES_OK ) {
+		goto fail_request;
+	}
+
+	if(host->mrq->data->flags & MMC_DATA_READ) {
+		if( sdi_dcnt>0 ) {
+			goto fail_request;
+		}
+	}
+
+out:
+	complete(&host->complete_dma);
+	spin_unlock_irqrestore( &host->complete_lock, iflags);
+	return;
+
+
+fail_request:
+	host->mrq->data->error = -EIO;
+	host->complete_what = COMPLETION_NONE;
+	complete(&host->complete_request);
+	writel(0, host->base + S3C2440_SDIIMSK);
+	goto out;
+
+}
+
+
+static void s3c2410sdi_dma_setup(struct s3c2410sdi_host *host, enum s3c2410_dmasrc source) {
+	s3c2410_dma_devconfig(host->dma, source, 3, host->mem->start + S3C2440_SDIDATA);
+	s3c2410_dma_config(host->dma, 4, (1<<23) | (2<<24));
+	s3c2410_dma_set_buffdone_fn(host->dma, s3c2410sdi_dma_done_callback);
+	s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART);
+}
+
+static void s3c2410sdi_request(struct mmc_host *mmc, struct mmc_request *mrq) {
+ 	struct s3c2410sdi_host *host = mmc_priv(mmc);
+	struct device *dev = mmc_dev(host->mmc);
+	struct platform_device *pdev = to_platform_device(dev);
+	u32 sdi_carg, sdi_ccon, sdi_timer;
+	u32 sdi_bsize, sdi_dcon, sdi_imsk;
+	int dma_len = 0;
+	int i, res;
+
+	DBG(KERN_DEBUG PFX "request: [CMD] opcode:0x%02x arg:0x%08x flags:%x retries:%u\n",
+		mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags, mrq->cmd->retries);
+
+	sdi_ccon = mrq->cmd->opcode & S3C2410_SDICMDCON_INDEX;
+	sdi_ccon|= S3C2410_SDICMDCON_SENDERHOST;
+	sdi_ccon|= S3C2410_SDICMDCON_CMDSTART;
+
+	sdi_carg = mrq->cmd->arg;
+
+	sdi_timer= 0x7FFFFF;
+
+	sdi_bsize= 0;
+	sdi_dcon = 0;
+	sdi_imsk = 0;
+
+	/* enable interrupts for transmission errors */
+	sdi_imsk |= S3C2410_SDIIMSK_RESPONSEND;
+	sdi_imsk |= S3C2410_SDIIMSK_CRCSTATUS;
+
+	host->complete_what = COMPLETION_CMDSENT;
+
+	if (mrq->cmd->flags & MMC_RSP_PRESENT) {
+		host->complete_what = COMPLETION_RSPFIN;
+
+		sdi_ccon |= S3C2410_SDICMDCON_WAITRSP;
+		sdi_imsk |= S3C2410_SDIIMSK_CMDTIMEOUT;
+
+	} else {
+		/* We need the CMDSENT-Interrupt only if we want are not waiting
+		 * for a response
+		 */
+		sdi_imsk |= S3C2410_SDIIMSK_CMDSENT;
+	}
+
+	if(mrq->cmd->flags & MMC_RSP_136) {
+		sdi_ccon|= S3C2410_SDICMDCON_LONGRSP;
+	}
+
+	if(mrq->cmd->flags & MMC_RSP_CRC) {
+			sdi_imsk |= S3C2410_SDIIMSK_RESPONSECRC;
+	}
+
+
+	if (mrq->data) {
+		host->complete_what = COMPLETION_XFERFINISH_RSPFIN;
+
+		sdi_bsize = mrq->data->blksz;
+		host->size = mrq->data->blksz;
+
+		sdi_dcon  = (mrq->data->blocks & S3C2410_SDIDCON_BLKNUM_MASK);
+		sdi_dcon |= S3C2440_SDIDCON_DATA_START;
+		sdi_dcon |= S3C2440_SDIDCON_DS_WORD;
+
+		sdi_imsk |= S3C2410_SDIIMSK_FIFOFAIL;
+		sdi_imsk |= S3C2410_SDIIMSK_DATACRC;
+		sdi_imsk |= S3C2410_SDIIMSK_DATATIMEOUT;
+		sdi_imsk |= S3C2410_SDIIMSK_DATAFINISH;
+		//sdi_imsk |= 0xFFFFFFE0;
+
+		DBG(PFX "request: [DAT] bsize:%u blocks:%u bytes:%u\n",
+			sdi_bsize, mrq->data->blocks, mrq->data->blocks * sdi_bsize);
+
+		if (host->bus_width == MMC_BUS_WIDTH_4) {
+			sdi_dcon |= S3C2410_SDIDCON_WIDEBUS;
+		}
+
+		if(!(mrq->data->flags & MMC_DATA_STREAM)) {
+			sdi_dcon |= S3C2410_SDIDCON_BLOCKMODE;
+		}
+
+		if(mrq->data->flags & MMC_DATA_WRITE) {
+			sdi_dcon |= S3C2410_SDIDCON_TXAFTERRESP;
+			sdi_dcon |= S3C2410_SDIDCON_XFER_TXSTART;
+		}
+
+		if(mrq->data->flags & MMC_DATA_READ) {
+			sdi_dcon |= S3C2410_SDIDCON_RXAFTERCMD;
+			sdi_dcon |= S3C2410_SDIDCON_XFER_RXSTART;
+		}
+
+		// FIXME no dma for write operation
+		if(!(mrq->data->flags & MMC_DATA_WRITE)) {
+			s3c2410sdi_dma_setup(host, mrq->data->flags & MMC_DATA_WRITE ? S3C2410_DMASRC_MEM : S3C2410_DMASRC_HW);
+			sdi_dcon |= S3C2410_SDIDCON_DMAEN;
+
+			/* see DMA-API.txt */
+			dma_len = dma_map_sg(&pdev->dev, mrq->data->sg, \
+					mrq->data->sg_len, \
+					mrq->data->flags & MMC_DATA_READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+
+			/* start DMA */
+			for(i=0; i<dma_len; i++) {
+				res=s3c2410_dma_enqueue(host->dma, (void *) host,
+						sg_dma_address(&mrq->data->sg[i]),
+						sg_dma_len(&mrq->data->sg[i]) );
+			}
+		}
+
+		// FIXME no dma for write operation
+		if(mrq->data->flags & MMC_DATA_WRITE)
+		{
+			struct scatterlist *sg;
+			sg = &mrq->data->sg[0];
+			host->pio_words = sdi_bsize>>2;
+			host->pio_ptr = page_address(sg_page(sg)) + sg->offset;
+		}
+
+		writel(sdi_dcon, host->base + S3C2410_SDIDCON);
+	}
+
+	host->mrq = mrq;
+
+	init_completion(&host->complete_request);
+	if(mrq->data) {
+		// FIXME no dma for write operation
+		if(!(mrq->data->flags & MMC_DATA_WRITE)) {
+			init_completion(&host->complete_dma);
+		}
+	}
+
+	writel(sdi_bsize,host->base + S3C2410_SDIBSIZE);
+	writel(0xFFFFFFFF, host->base + S3C2410_SDIFSTA);
+
+	/* Clear command and data status registers */
+	writel(0xFFFFFFFF, host->base + S3C2410_SDICMDSTAT);
+	writel(0xFFFFFFFF, host->base + S3C2410_SDIDSTA);
+
+	/* Setup SDI controller */
+	writel(sdi_timer,host->base + S3C2410_SDITIMER);
+	writel(sdi_imsk,host->base + S3C2440_SDIIMSK);
+
+	/* Setup SDI command argument and data control */
+	writel(sdi_carg, host->base + S3C2410_SDICMDARG);
+
+	/* This initiates transfer */
+	writel(sdi_ccon, host->base + S3C2410_SDICMDCON);
+
+	/* Wait for transfer to complete */
+	wait_for_completion(&host->complete_request);
+	DBG(PFX "[CMD] request complete.\n");
+	if(mrq->data) {
+		// FIXME no dma for write operation
+		if(!(mrq->data->flags & MMC_DATA_WRITE)) {
+			wait_for_completion(&host->complete_dma);
+			// FIXME time condition ?
+			if(mrq->data->blksz<512) printk("<512\n");
+			DBG(PFX "[DAT] DMA complete.\n");
+		}
+	}
+
+	/* Cleanup controller */
+	writel(0, host->base + S3C2410_SDICMDARG);
+	writel(0, host->base + S3C2410_SDIDCON);
+	writel(0, host->base + S3C2410_SDICMDCON);
+	writel(0, host->base + S3C2440_SDIIMSK);
+
+	/*  Read response */
+	mrq->cmd->resp[0] = readl(host->base + S3C2410_SDIRSP0);
+	mrq->cmd->resp[1] = readl(host->base + S3C2410_SDIRSP1);
+	mrq->cmd->resp[2] = readl(host->base + S3C2410_SDIRSP2);
+	mrq->cmd->resp[3] = readl(host->base + S3C2410_SDIRSP3);
+
+	host->mrq = NULL;
+
+	DBG(PFX "request done.\n");
+
+	/* If we have no data transfer we are finished here */
+	if (!mrq->data) goto request_done;
+
+	// FIXME no dma for write operation
+	if(!(mrq->data->flags & MMC_DATA_WRITE)) {
+		dma_unmap_sg(&pdev->dev, mrq->data->sg, dma_len, \
+				mrq->data->flags & MMC_DATA_READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+	}
+
+	/* Calulate the amout of bytes transfer, but only if there was
+	 * no error
+	 */
+	if(mrq->data->error == 0) {
+		mrq->data->bytes_xfered = mrq->data->blksz;
+	} else {
+		mrq->data->bytes_xfered = 0;
+	}
+
+	/* If we had an error while transfering data we flush the
+	 * DMA channel to clear out any garbage
+	 */
+	if(mrq->data->error != 0) {
+		s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
+		DBG(PFX "flushing DMA.\n");
+	}
+
+	if(mrq->data->stop) mmc_wait_for_cmd(mmc, mrq->data->stop, 3);
+
+request_done:
+
+	mrq->done(mrq);
+}
+
+static void s3c2410sdi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) {
+	struct s3c2410sdi_host *host = mmc_priv(mmc);
+	u32 sdi_psc, sdi_con;
+
+	/* Set power */
+	sdi_con = readl(host->base + S3C2410_SDICON);
+	switch(ios->power_mode) {
+		case MMC_POWER_ON:
+		case MMC_POWER_UP:
+			DBG(PFX "power on\n");
+			s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);
+			s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);
+			s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);
+			s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);
+			s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
+			s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
+
+			if (host->pdata->set_power)
+				(host->pdata->set_power)(1);
+
+			break;
+
+		case MMC_POWER_OFF:
+		default:
+			if (host->pdata->set_power)
+				(host->pdata->set_power)(0);
+			break;
+	}
+
+	/* Set clock */
+	for(sdi_psc=0;sdi_psc<255;sdi_psc++) {
+		if( (clk_get_rate(host->clk) / (2*(sdi_psc+1))) <= ios->clock) break;
+	}
+
+	if(sdi_psc > 255) sdi_psc = 255;
+	writel(sdi_psc, host->base + S3C2410_SDIPRE);
+
+	/* Set CLOCK_ENABLE */
+	if(ios->clock) 	sdi_con |= S3C2440_SDICON_CLOCKENABLE;
+	else		sdi_con &=~S3C2440_SDICON_CLOCKENABLE;
+
+  // use MMC type clock
+  sdi_con|=S3C2440_SDICON_MMCCLOCK;
+
+	writel(sdi_con, host->base + S3C2410_SDICON);
+
+	host->bus_width = ios->bus_width;
+
+}
+
+static struct mmc_host_ops s3c2410sdi_ops = {
+	.request	= s3c2410sdi_request,
+	.set_ios	= s3c2410sdi_set_ios,
+};
+
+static void s3c2410_mmc_def_setpower(unsigned int to)
+{
+	s3c2410_gpio_cfgpin(S3C2410_GPA17, S3C2410_GPIO_OUTPUT);
+	s3c2410_gpio_setpin(S3C2410_GPA17, to);
+}
+
+static struct s3c24xx_mmc_platdata s3c2410_mmc_defplat = {
+	.gpio_detect	= S3C2410_GPF2,
+	.set_power	= s3c2410_mmc_def_setpower,
+	.f_max		= 3000000,
+	.ocr_avail	= MMC_VDD_32_33,
+};
+
+static int s3c2410sdi_probe(struct platform_device *pdev)
+{
+	struct mmc_host 	*mmc;
+	s3c24xx_mmc_pdata_t	*pdata;
+	struct s3c2410sdi_host 	*host;
+
+
+	int ret;
+
+	mmc = mmc_alloc_host(sizeof(struct s3c2410sdi_host), &pdev->dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		goto probe_out;
+	}
+
+	host = mmc_priv(mmc);
+
+	spin_lock_init( &host->complete_lock );
+	host->complete_what 	= COMPLETION_NONE;
+	host->mmc 		= mmc;
+	host->dma		= S3C2410SDI_DMA;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		pdev->dev.platform_data = &s3c2410_mmc_defplat;
+		pdata = &s3c2410_mmc_defplat;
+	}
+
+	host->pdata = pdata;
+
+	host->irq_cd = s3c2410_gpio_getirq(pdata->gpio_detect);
+	s3c2410_gpio_cfgpin(pdata->gpio_detect, S3C2410_GPIO_IRQ);
+
+	host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!host->mem) {
+		printk(KERN_ERR PFX "failed to get io memory region resouce.\n");
+		ret = -ENOENT;
+		goto probe_free_host;
+	}
+
+	host->mem = request_mem_region(host->mem->start,
+		RESSIZE(host->mem), pdev->name);
+
+	if (!host->mem) {
+		printk(KERN_ERR PFX "failed to request io memory region.\n");
+		ret = -ENOENT;
+		goto probe_free_host;
+	}
+
+	host->base = ioremap(host->mem->start, RESSIZE(host->mem));
+	if (host->base == 0) {
+		printk(KERN_ERR PFX "failed to ioremap() io memory region.\n");
+		ret = -EINVAL;
+		goto probe_free_mem_region;
+	}
+
+	host->irq = platform_get_irq(pdev, 0);
+	if (host->irq == 0) {
+		printk(KERN_ERR PFX "failed to get interrupt resouce.\n");
+		ret = -EINVAL;
+		goto probe_iounmap;
+	}
+
+	if(request_irq(host->irq, s3c2410sdi_irq, 0, DRIVER_NAME, host)) {
+		printk(KERN_ERR PFX "failed to request sdi interrupt.\n");
+		ret = -ENOENT;
+		goto probe_iounmap;
+	}
+
+	set_irq_type(host->irq_cd, IRQT_BOTHEDGE);
+	if(request_irq(host->irq_cd, s3c2410sdi_irq_cd, 0, DRIVER_NAME, host)) {
+		printk(KERN_ERR PFX "failed to request card detect interrupt.\n" );
+		ret = -ENOENT;
+		goto probe_free_irq;
+	}
+
+	if(s3c2410_dma_request(S3C2410SDI_DMA, &s3c2410sdi_dma_client, NULL)) {
+		printk(KERN_ERR PFX "unable to get DMA channel.\n" );
+		ret = -EBUSY;
+		goto probe_free_irq_cd;
+	}
+
+	host->clk = clk_get(&pdev->dev, "sdi");
+	if (IS_ERR(host->clk)) {
+		printk(KERN_ERR PFX "failed to find clock source.\n");
+		ret = PTR_ERR(host->clk);
+		host->clk = NULL;
+		goto probe_free_host;
+	}
+
+	if((ret = clk_enable(host->clk))) {
+		printk(KERN_ERR PFX "failed to enable clock source.\n");
+		goto clk_unuse;
+	}
+
+
+	mmc->ops 	= &s3c2410sdi_ops;
+	mmc->ocr_avail	= pdata->ocr_avail;
+	mmc->f_min 	= clk_get_rate(host->clk) / 512;
+	mmc->f_max 	= clk_get_rate(host->clk) / 2;
+	mmc->caps	= MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;
+
+	if(pdata->f_max && (mmc->f_max>pdata->f_max))
+		mmc->f_max = pdata->f_max;
+
+	printk(KERN_INFO PFX "probe: mapped sdi_base=%p irq=%u irq_cd=%u \n",
+		host->base, host->irq, host->irq_cd);
+
+	if((ret = mmc_add_host(mmc))) {
+		printk(KERN_ERR PFX "failed to add mmc host.\n");
+		goto clk_disable;
+	}
+
+	platform_set_drvdata(pdev, mmc);
+
+	printk(KERN_INFO PFX "initialisation done.\n");
+	return 0;
+
+ clk_disable:
+	clk_disable(host->clk);
+
+ clk_unuse:
+	clk_put(host->clk);
+
+ probe_free_irq_cd:
+ 	free_irq(host->irq_cd, host);
+
+ probe_free_irq:
+ 	free_irq(host->irq, host);
+
+ probe_iounmap:
+	iounmap(host->base);
+
+ probe_free_mem_region:
+	release_mem_region(host->mem->start, RESSIZE(host->mem));
+
+ probe_free_host:
+	mmc_free_host(mmc);
+ probe_out:
+	return ret;
+}
+
+static int s3c2410sdi_remove(struct platform_device *pdev)
+{
+	struct mmc_host 	*mmc  = platform_get_drvdata(pdev);
+	struct s3c2410sdi_host 	*host = mmc_priv(mmc);
+
+	mmc_remove_host(mmc);
+	s3c2410_dma_free(S3C2410SDI_DMA, &s3c2410sdi_dma_client);
+	clk_disable(host->clk);
+	clk_put(host->clk);
+ 	free_irq(host->irq_cd, host);
+ 	free_irq(host->irq, host);
+	iounmap(host->base);
+	release_mem_region(host->mem->start, RESSIZE(host->mem));
+	mmc_free_host(mmc);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c2410mci_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	struct s3c2410sdi_host  *host;
+	int ret = 0;
+
+	if (mmc) {
+		host = mmc_priv(mmc);
+
+		ret = mmc_suspend_host(mmc, state);
+
+		clk_disable(host->clk);
+
+		disable_irq(host->irq_cd);
+		disable_irq(host->irq);
+	}
+
+	return ret;
+}
+
+static int s3c2410mci_resume(struct platform_device *dev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	struct s3c2410sdi_host  *host;
+	int ret = 0;
+
+	if (mmc) {
+		host = mmc_priv(mmc);
+
+		enable_irq(host->irq_cd);
+		enable_irq(host->irq);
+
+		clk_enable(host->clk);
+
+		ret = mmc_resume_host(mmc);
+	}
+
+	return ret;
+}
+#else
+#define s3c2410mci_suspend	NULL
+#define s3c2410mci_resume	NULL
+#endif
+
+static struct platform_driver s3c2410sdi_driver =
+{
+	.driver		= {
+        	.name	= "s3c2410-sdi",
+		.owner	= THIS_MODULE,
+	},
+        .probe          = s3c2410sdi_probe,
+        .remove         = s3c2410sdi_remove,
+	.suspend	= s3c2410mci_suspend,
+	.resume		= s3c2410mci_resume,
+};
+
+static int __init s3c2410sdi_init(void)
+{
+	return platform_driver_register(&s3c2410sdi_driver);
+}
+
+static void __exit s3c2410sdi_exit(void)
+{
+	platform_driver_unregister(&s3c2410sdi_driver);
+}
+
+module_init(s3c2410sdi_init);
+module_exit(s3c2410sdi_exit);
+
+MODULE_DESCRIPTION("Samsung S3C2410 Multimedia Card Interface driver");
+MODULE_LICENSE("GPL");
Index: linux-2.6.24/drivers/mmc/host/s3c2440mci.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/drivers/mmc/host/s3c2440mci.h	2008-02-03 18:20:41.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ *  linux/drivers/mmc/s3c2410mci.h - Samsung S3C2410 SDI Interface driver
+ *
+ *  Copyright (C) 2004 Thomas Kleffel, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+struct clk;
+
+#define S3C2410SDI_DMA 0
+
+#define S3C2410SDI_CDLATENCY 500
+
+enum s3c2410sdi_waitfor {
+	COMPLETION_NONE,
+	COMPLETION_CMDSENT,
+	COMPLETION_RSPFIN,
+	COMPLETION_XFERFINISH,
+	COMPLETION_XFERFINISH_RSPFIN,
+};
+
+typedef struct s3c24xx_mmc_platdata s3c24xx_mmc_pdata_t;
+
+struct s3c2410sdi_host {
+	struct mmc_host		*mmc;
+	s3c24xx_mmc_pdata_t	*pdata;
+
+	struct resource		*mem;
+	struct clk		*clk;
+	void __iomem		*base;
+	int			irq;
+	int			irq_cd;
+	int			dma;
+
+	struct scatterlist*	cur_sg;		/* Current SG entry */
+	unsigned int		num_sg;		/* Number of entries left */
+	void*			mapped_sg;	/* vaddr of mapped sg */
+
+	unsigned int		offset;		/* Offset into current entry */
+	unsigned int		remain;		/* Data left in curren entry */
+
+	int			size;		/* Total size of transfer */
+
+	struct mmc_request	*mrq;
+
+	unsigned char		bus_width;	/* Current bus width */
+
+	spinlock_t		complete_lock;
+	struct completion	complete_request;
+	struct completion	complete_dma;
+	enum s3c2410sdi_waitfor	complete_what;
+
+  long *pio_ptr;
+  u32 pio_words;
+};
Index: linux-2.6.24/include/asm/arch-s3c2410/lcd.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/include/asm/arch-s3c2410/lcd.h	2008-02-03 18:20:45.000000000 +0100
@@ -0,0 +1,33 @@
+/* linux/include/asm/arch-s3c2410/lcd.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ *  Changelog:
+ *     14-Mar-2005     RTP     Created file
+ *     07-Apr-2005     RTP     Renamed to s3c2410_lcd.h
+ *     03-Aug-2005     RTP     Renamed to lcd.h
+ */
+
+#ifndef __ASM_ARM_LCD_H
+#define __ASM_ARM_LCD_H
+
+struct s3c2410_bl_mach_info {
+	int		lcd_power_value;
+	int		backlight_power_value;
+	int		brightness_value;
+	int             backlight_max;
+	int             backlight_default;
+	void            (*backlight_power)(int);
+	void            (*set_brightness)(int);
+	void		(*lcd_power)(int);
+};
+
+void __init set_s3c2410bl_info(struct s3c2410_bl_mach_info *hard_s3c2410bl_info);
+
+#endif /* __ASM_ARM_LCD_H */
Index: linux-2.6.24/drivers/video/backlight/Kconfig
===================================================================
--- linux-2.6.24.orig/drivers/video/backlight/Kconfig	2008-02-03 18:19:31.000000000 +0100
+++ linux-2.6.24/drivers/video/backlight/Kconfig	2008-02-03 18:20:45.000000000 +0100
@@ -67,6 +67,14 @@
 	  If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
 	  enable the LCD/backlight driver.
 
+config BACKLIGHT_S3C2410
+	tristate "Samsung S3C2410 Backlight Driver"
+	depends on (BACKLIGHT_DEVICE || LCD_CLASS_DEVICE) && ARCH_S3C2410
+	default y
+	help
+	  If you have a backlight controler connected on a Samsung S3C2410,
+	  say y here to enable the driver.
+
 config BACKLIGHT_HP680
 	tristate "HP Jornada 680 Backlight Driver"
 	depends on BACKLIGHT_CLASS_DEVICE && SH_HP6XX
Index: linux-2.6.24/drivers/video/backlight/Makefile
===================================================================
--- linux-2.6.24.orig/drivers/video/backlight/Makefile	2008-02-03 18:19:31.000000000 +0100
+++ linux-2.6.24/drivers/video/backlight/Makefile	2008-02-03 18:20:45.000000000 +0100
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
 obj-$(CONFIG_BACKLIGHT_CORGI)	+= corgi_bl.o
+obj-$(CONFIG_BACKLIGHT_S3C2410)	+= s3c2410_lcd.o
 obj-$(CONFIG_BACKLIGHT_HP680)	+= hp680_bl.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO)	+= locomolcd.o
 obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
Index: linux-2.6.24/drivers/video/backlight/s3c2410_lcd.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/drivers/video/backlight/s3c2410_lcd.c	2008-02-03 18:20:45.000000000 +0100
@@ -0,0 +1,248 @@
+/*
+ * linux/drivers/video/backlight/s3c2410_lcd.c
+ * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ *	    S3C2410 LCD Controller Backlight Driver
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <asm/arch/lcd.h>
+#include <asm/arch/regs-gpio.h>
+
+struct s3c2410bl_devs {
+	struct backlight_device *bl;
+	struct lcd_device	*lcd;
+};
+
+static char suspended;
+
+static int s3c2410bl_get_lcd_power(struct lcd_device *lcd)
+{
+	struct s3c2410_bl_mach_info *info;
+
+	info = (struct s3c2410_bl_mach_info *)lcd_get_data(lcd);
+
+	if (info)
+		return info->lcd_power_value;
+
+	return 0;
+}
+
+static int s3c2410bl_set_lcd_power(struct lcd_device *lcd, int power)
+{
+	struct s3c2410_bl_mach_info *info;
+	int lcd_power = 1;
+
+	info = (struct s3c2410_bl_mach_info *)lcd_get_data(lcd);
+
+	if (info && info->lcd_power) {
+		info->lcd_power_value = power;
+		if (power != FB_BLANK_UNBLANK)
+			lcd_power = 0;
+		if (suspended)
+			lcd_power = 0;
+		info->lcd_power(lcd_power);
+	}
+
+	return 0;
+}
+static int s3c2410bl_get_bl_brightness(struct backlight_device *bl)
+{
+	struct s3c2410_bl_mach_info *info;
+
+	info = (struct s3c2410_bl_mach_info *)bl_get_data(bl);
+
+	if(info)
+		return info->brightness_value;
+
+	return 0;
+}
+
+static int s3c2410bl_set_bl_brightness(struct backlight_device *bl)
+{
+	struct s3c2410_bl_mach_info *info;
+	int brightness = bl->props.brightness;
+	int power = 1;
+
+	info = (struct s3c2410_bl_mach_info *)bl_get_data(bl);
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		power = 0;
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		power = 0;
+	if (suspended)
+		power = 0;
+
+	if (info && info->set_brightness) {
+		if ( brightness )
+		{
+			info->brightness_value = brightness;
+			info->set_brightness(brightness);
+		}
+		else
+			power = 0;
+	}
+	if (info && info->backlight_power) {
+		info->backlight_power_value = power;
+		info->backlight_power(power);
+	}
+
+	return 0;
+}
+
+static int is_s3c2410fb(struct fb_info *info)
+{
+	return (!strcmp(info->fix.id,"s3c2410fb"));
+}
+
+static struct backlight_ops s3c2410bl_ops = {
+	.get_brightness = s3c2410bl_get_bl_brightness,
+	.update_status	= s3c2410bl_set_bl_brightness,
+	.check_fb 	= is_s3c2410fb
+};
+static struct lcd_ops s3c2410lcd_ops = {
+	.get_power	= s3c2410bl_get_lcd_power,
+	.set_power	= s3c2410bl_set_lcd_power,
+	.check_fb	= is_s3c2410fb
+};
+
+static int __init s3c2410bl_probe(struct platform_device *pdev)
+{
+	struct s3c2410bl_devs *devs;
+	struct s3c2410_bl_mach_info *info;
+
+	suspended = 0;
+
+	info = (struct s3c2410_bl_mach_info *)pdev->dev.platform_data;
+
+	if (!info) {
+		printk(KERN_ERR "Hm... too bad : no platform data for bl\n");
+		return -EINVAL;
+	}
+
+	devs = (struct s3c2410bl_devs *)kmalloc(sizeof(*devs), GFP_KERNEL);
+	if (!devs) {
+		return -ENOMEM;
+	}
+
+	/* Register the backlight device */
+	devs->bl = backlight_device_register ("s3c2410-bl", &pdev->dev, info,
+		&s3c2410bl_ops);
+
+	if (IS_ERR (devs->bl)) {
+		kfree(devs);
+		return PTR_ERR (devs->bl);
+	}
+
+	devs->bl->props.max_brightness = info->backlight_max;
+
+	/* Set default brightness */
+	devs->bl->props.power = FB_BLANK_UNBLANK;
+	devs->bl->props.brightness = info->backlight_default;
+	s3c2410bl_set_bl_brightness(devs->bl);
+
+	devs->lcd = lcd_device_register("s3c2410-lcd", &pdev->dev, info, &s3c2410lcd_ops);
+
+	if (IS_ERR (devs->lcd)) {
+		backlight_device_unregister(devs->bl);
+		kfree(devs);
+		return PTR_ERR (devs->lcd);
+	}
+	platform_set_drvdata(pdev, devs);
+
+	printk(KERN_ERR "s3c2410 Backlight Driver Initialized.\n");
+	return 0;
+}
+
+static int s3c2410bl_remove(struct platform_device *pdev)
+{
+	struct s3c2410bl_devs *devs = platform_get_drvdata(pdev);
+
+	if (devs) {
+		if (devs->bl) {
+			devs->bl->props.power = FB_BLANK_POWERDOWN;
+			s3c2410bl_set_bl_brightness(devs->bl);
+			backlight_device_unregister(devs->bl);
+		}
+		if (devs->lcd) {
+			lcd_device_unregister(devs->lcd);
+		}
+		kfree(devs);
+	}
+
+	printk("s3c2410 Backlight Driver Unloaded\n");
+
+	return 0;
+
+}
+
+#ifdef CONFIG_PM
+static int s3c2410bl_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct s3c2410bl_devs *devs = platform_get_drvdata(pdev);
+	struct s3c2410_bl_mach_info *info = (struct s3c2410_bl_mach_info *)pdev->dev.platform_data;
+
+	if (devs) {
+		suspended = 1;
+		s3c2410bl_set_bl_brightness(devs->bl);
+		s3c2410bl_set_lcd_power(devs->lcd, info->lcd_power_value);
+	}
+
+	return 0;
+}
+
+static int s3c2410bl_resume(struct platform_device *pdev)
+{
+	struct s3c2410bl_devs *devs = platform_get_drvdata(pdev);
+	struct s3c2410_bl_mach_info *info = (struct s3c2410_bl_mach_info *)pdev->dev.platform_data;
+
+	if (devs) {
+		suspended = 0;
+		s3c2410bl_set_lcd_power(devs->lcd, info->lcd_power_value);
+		s3c2410bl_set_bl_brightness(devs->bl);
+	}
+	return 0;
+}
+#else
+#define s3c2410bl_suspend NULL
+#define s3c2410bl_resume  NULL
+#endif
+
+static struct platform_driver s3c2410bl_driver = {
+	.driver		= {
+		.name	= "s3c2410-bl",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= s3c2410bl_probe,
+	.remove		= s3c2410bl_remove,
+	.suspend        = s3c2410bl_suspend,
+	.resume         = s3c2410bl_resume,
+};
+
+
+
+static int __init s3c2410bl_init(void)
+{
+	return platform_driver_register(&s3c2410bl_driver);
+}
+
+static void __exit s3c2410bl_cleanup(void)
+{
+	platform_driver_unregister(&s3c2410bl_driver);
+}
+
+module_init(s3c2410bl_init);
+module_exit(s3c2410bl_cleanup);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("s3c2410 Backlight Driver");
+MODULE_LICENSE("GPL");
+
Index: linux-2.6.24/.config
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/.config	2008-02-03 18:20:51.000000000 +0100
@@ -0,0 +1,1182 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24
+# Sun Feb  3 18:07:54 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+CONFIG_NO_IOPORT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+CONFIG_ARCH_S3C2410=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+CONFIG_PLAT_S3C24XX=y
+CONFIG_CPU_S3C244X=y
+CONFIG_S3C2410_DMA=y
+# CONFIG_S3C2410_DMA_DEBUG is not set
+CONFIG_MACH_SMDK=y
+CONFIG_PLAT_S3C=y
+CONFIG_CPU_LLSERIAL_S3C2410=y
+CONFIG_CPU_LLSERIAL_S3C2440=y
+
+#
+# Boot options
+#
+# CONFIG_S3C_BOOT_ERROR_RESET is not set
+
+#
+# Power management
+#
+# CONFIG_S3C2410_PM_DEBUG is not set
+# CONFIG_S3C2410_PM_CHECK is not set
+CONFIG_S3C_LOWLEVEL_UART_PORT=0
+
+#
+# S3C2400 Machines
+#
+CONFIG_CPU_S3C2410=y
+CONFIG_CPU_S3C2410_DMA=y
+CONFIG_S3C2410_PM=y
+CONFIG_S3C2410_GPIO=y
+CONFIG_S3C2410_CLOCK=y
+
+#
+# S3C2410 Machines
+#
+CONFIG_ARCH_SMDK2410=y
+# CONFIG_ARCH_H1940 is not set
+# CONFIG_MACH_N30 is not set
+# CONFIG_ARCH_BAST is not set
+# CONFIG_MACH_OTOM is not set
+# CONFIG_MACH_AML_M5900 is not set
+# CONFIG_MACH_VR1000 is not set
+# CONFIG_MACH_QT2410 is not set
+
+#
+# S3C2412 Machines
+#
+# CONFIG_MACH_SMDK2413 is not set
+# CONFIG_MACH_SMDK2412 is not set
+# CONFIG_MACH_VSTMS is not set
+CONFIG_CPU_S3C2440=y
+CONFIG_S3C2440_DMA=y
+
+#
+# S3C2440 Machines
+#
+# CONFIG_MACH_ANUBIS is not set
+# CONFIG_MACH_OSIRIS is not set
+# CONFIG_MACH_RX3715 is not set
+# CONFIG_ARCH_S3C2440 is not set
+# CONFIG_MACH_NEXCODER_2440 is not set
+CONFIG_MACH_G500=y
+
+#
+# S3C2442 Machines
+#
+
+#
+# S3C2443 Machines
+#
+# CONFIG_MACH_SMDK2443 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+CONFIG_PREEMPT=y
+CONFIG_NO_IDLE_HZ=y
+CONFIG_HZ=200
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_SUSPEND=y
+# CONFIG_APM_EMULATION is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_S3C2410=y
+# CONFIG_MTD_NAND_S3C2410_DEBUG is not set
+CONFIG_MTD_NAND_S3C2410_HWECC=y
+CONFIG_MTD_NAND_S3C2410_CLKSTOP=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+CONFIG_TOUCHSCREEN_S3C2410=y
+# CONFIG_TOUCHSCREEN_S3C2410_DEBUG is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_S3C2410=y
+# CONFIG_SERIAL_S3C2410_CONSOLE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=32
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCF=y
+CONFIG_I2C_ALGOPCA=y
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+CONFIG_I2C_S3C2410=y
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_S3C24XX=y
+# CONFIG_SPI_S3C24XX_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_S3C2410=y
+# CONFIG_FB_S3C2410_DEBUG is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LTV350QV is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_S3C2410=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_MINI_4x6=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+
+#
+# SPI devices
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+CONFIG_SND_SOC=y
+CONFIG_SND_S3C24XX_SOC=y
+
+#
+# SoC Audio support for SuperH
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_S3C2410=y
+CONFIG_USB_S3C2410=y
+# CONFIG_USB_S3C2410_DEBUG is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+# CONFIG_USB_ETH_RNDIS is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SPI is not set
+CONFIG_MMC_S3C2440=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_S3C24XX is not set
+CONFIG_LEDS_GPIO=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_S3C=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+# CONFIG_INSTRUMENTATION is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_S3C_UART=0
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y

