diff -ruN linux-2.6.18-vanilla/arch/arm/mach-sa1100/cpu-sa1110.c linux-2.6.18/arch/arm/mach-sa1100/cpu-sa1110.c
--- linux-2.6.18-vanilla/arch/arm/mach-sa1100/cpu-sa1110.c	2006-09-20 03:42:06.000000000 +0000
+++ linux-2.6.18/arch/arm/mach-sa1100/cpu-sa1110.c	2006-10-03 22:58:39.000000000 +0000
@@ -82,6 +82,14 @@
 		.twr		= 9,
 		.refresh	= 64000,
 		.cas_latency	= 3,
+	}, {    /* Samsung K4s281632b-1h */
+	        .name           = "K4S281632B-1H",
+	        .rows           = 12,
+		.tck            = 10,
+		.trp            = 20,
+		.twr            = 10,
+		.refresh        = 64000,
+		.cas_latency    = 3,
 	}, {	/* Samsung KM416S4030CT */
 		.name		= "KM416S4030CT",
 		.rows		= 13,
@@ -366,6 +374,9 @@
 
 		if (machine_is_h3100())
 			name = "KM416S4030CT";
+
+	        if (machine_is_jornada720())
+		        name = "K4S281632B-1H";
 	}
 
 	sdram = sa1110_find_sdram(name);
diff -ruN linux-2.6.18-vanilla/arch/arm/mach-sa1100/jornada720.c linux-2.6.18/arch/arm/mach-sa1100/jornada720.c
--- linux-2.6.18-vanilla/arch/arm/mach-sa1100/jornada720.c	2006-09-20 03:42:06.000000000 +0000
+++ linux-2.6.18/arch/arm/mach-sa1100/jornada720.c	2006-10-03 22:58:39.000000000 +0000
@@ -22,11 +22,170 @@
 #include <asm/mach/map.h>
 #include <asm/mach/serial_sa1100.h>
 
+#include <asm/arch/jornada720.h>
+
+#include <linux/lcd.h>
+#include <linux/backlight.h>
+#include <linux/fb.h>
 #include "generic.h"
 
 
 #define JORTUCR_VAL	0x20000400
 
+/* Jornada 720 MCU functions */
+#define MCU_REVERSE(i) ((unsigned char)(((0x80 & i) >> 7) | ((0x40 & i) >> 5) \
+                       | ((0x20 & i) >> 3) | ((0x10 & i) >> 1) | ((0x08 & i) << 1) \
+		       | ((0x04 & i) << 3) | ((0x02 & i) << 5) | ((0x01 & i) << 7)))
+
+void jornada720_init_ser(void)
+{
+      int i;
+
+      GPSR = GPIO_GPIO25;
+      Ser4SSCR0 = 0x0307;
+      Ser4MCCR0 = 0;
+      Ser4SSCR1 = 0x18;
+      Ser4SSCR0 = 0x0387;
+      while (Ser4SSSR & SSSR_RNE)
+             i = Ser4SSDR;
+}
+
+int jornada720_mcu_byte(int arg_data)
+{
+      int i;
+
+      while ((Ser4SSSR & SSSR_TNF) == 0);
+      i = 0;
+      while ((GPLR & 0x400) && i++ < 400000);
+             /* wait for MCU */
+
+      if (i >= 400000) {
+               printk("jornada 720_mcu_byte: timed out\n");
+	       return -1;
+      }
+      Ser4SSDR = MCU_REVERSE(arg_data) << 8;
+      udelay(100);
+      while ((Ser4SSSR & SSSR_RNE) == 0);
+      i = Ser4SSDR;
+      if (i > 0xff)
+            printk("jornada720 mcu_byte: read %x\n", i);
+      return MCU_REVERSE(i & 0xff) & 0xff;
+}
+
+
+int jornada720_mcu_start(int arg_data)
+{
+      int i;
+
+      GPCR = GPIO_GPIO25;  /* clear -> enable */
+      udelay(100);
+      i = jornada720_mcu_byte(arg_data);
+      if (i != MCU_TxDummy)
+      {
+              printk("jornada720_mcu_start: sent %x got %x\n",  arg_data, i);
+	      for (i = 0; i < 256; i++)
+	          if (jornada720_mcu_read() == -1)
+		           break;
+
+	      jornada720_init_ser();
+	      return -1;
+      }
+
+      return 0;
+}
+
+
+void jornada720_mcu_end(void)
+{
+     udelay(100);
+     GPSR = GPIO_GPIO25; /* set */
+}
+
+void jornada720_mcu_init(void)
+{
+
+     /*int i;
+
+     if (state) {
+                 PPSR &= ~PPC_LDD1;
+                 PPDR &= PPC_LDD1;
+     }
+     else { */
+                 PPSR |= PPC_LDD1;
+     /*}
+     return 0;*/
+}
+
+/*static int jornada720_backlight_get_power(struct backlight_device *bd)
+{
+
+     return  ~(PPSR&PPC_LDD1);
+}*/
+
+static int jornada720_backlight_get_brightness(struct  backlight_device *bd)
+{
+     int brightness;
+     jornada720_mcu_start(MCU_GetBrightness);
+     brightness = jornada720_mcu_read();
+     jornada720_mcu_end();
+     return brightness;
+}
+
+static int jornada720_backlight_set_brightness(struct backlight_device *bd)
+{
+	/* TODO: should it be substracted? */
+     int brightness = 255 - bd->props->brightness;
+     jornada720_mcu_start(MCU_SetBrightness);
+     jornada720_mcu_byte(brightness);
+     jornada720_mcu_end();
+     return 0;
+}
+
+static struct backlight_properties jornada720_backlight_properties = {
+       .owner                   =  THIS_MODULE,
+       .get_brightness          =  jornada720_backlight_get_brightness,
+       .update_status           =  jornada720_backlight_set_brightness,
+       .max_brightness          =  255,
+};
+
+static int jornada720_lcd_set_power(struct lcd_device *ld, int power)
+{
+	return 0;
+}
+
+static int jornada720_lcd_get_power(struct lcd_device *ld)
+{
+	return 1;
+}
+
+static int jornada720_lcd_get_contrast(struct lcd_device *ld)
+{
+	int contrast;
+
+	jornada720_mcu_start(MCU_GetContrast);
+	contrast = jornada720_mcu_read();
+	jornada720_mcu_end();
+
+	return contrast;
+}
+
+static int jornada720_lcd_set_contrast(struct lcd_device *ld, int contrast)
+{
+	jornada720_mcu_start(MCU_SetContrast);
+	jornada720_mcu_byte(contrast);
+	jornada720_mcu_end();
+	return 0;
+}
+
+static struct lcd_properties jornada720_lcd_properties = {
+       .owner                   = THIS_MODULE,
+       .set_power               = jornada720_lcd_set_power,
+       .get_power               = jornada720_lcd_get_power,
+       .set_contrast            = jornada720_lcd_set_contrast,
+       .get_contrast            = jornada720_lcd_get_contrast,
+       .max_contrast            = 255,
+};
+
 static struct resource sa1111_resources[] = {
 	[0] = {
 		.start		= 0x40000000,
@@ -77,6 +236,10 @@
 		PPDR |= PPC_LDD3 | PPC_LDD4;
 
 		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+
+                jornada720_mcu_init();
+		backlight_device_register("e1356fb", 0, &jornada720_backlight_properties);
+		lcd_device_register("e1356fb", 0, &jornada720_lcd_properties);
 	}
 	return ret;
 }
diff -ruN linux-2.6.18-vanilla/drivers/input/keyboard/Kconfig linux-2.6.18/drivers/input/keyboard/Kconfig
--- linux-2.6.18-vanilla/drivers/input/keyboard/Kconfig	2006-09-20 03:42:06.000000000 +0000
+++ linux-2.6.18/drivers/input/keyboard/Kconfig	2006-10-03 22:58:39.000000000 +0000
@@ -183,4 +183,11 @@
 	  This driver implements support for HIL-keyboards attached
 	  to your machine, so normally you should say Y here.
 
+config KEYBOARD_JORNADA720
+        tristate "HP Jornada 720 Keyboard Support"
+	depends on SA1100_JORNADA720
+	default y
+	help
+	  Say Y to enable keyboard on the Hewlett Packard Jornada
+	  7xx(710/720/728) series of PDAs.
 endif
diff -ruN linux-2.6.18-vanilla/drivers/input/keyboard/Makefile linux-2.6.18/drivers/input/keyboard/Makefile
--- linux-2.6.18-vanilla/drivers/input/keyboard/Makefile	2006-09-20 03:42:06.000000000 +0000
+++ linux-2.6.18/drivers/input/keyboard/Makefile	2006-10-03 22:58:39.000000000 +0000
@@ -15,4 +15,4 @@
 obj-$(CONFIG_KEYBOARD_SPITZ)		+= spitzkbd.o
 obj-$(CONFIG_KEYBOARD_HIL)		+= hil_kbd.o
 obj-$(CONFIG_KEYBOARD_HIL_OLD)		+= hilkbd.o
-
+obj-$(CONFIG_KEYBOARD_JORNADA720)       += jornada720_kbd.o
diff -ruN linux-2.6.18-vanilla/drivers/input/keyboard/jornada720_kbd.c linux-2.6.18/drivers/input/keyboard/jornada720_kbd.c
--- linux-2.6.18-vanilla/drivers/input/keyboard/jornada720_kbd.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.18/drivers/input/keyboard/jornada720_kbd.c	2006-10-03 23:05:54.000000000 +0000
@@ -0,0 +1,102 @@
+/*
+ * Jornada 720 keyboard interface
+ */
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/jornada720.h>
+#include <asm/irq.h>
+
+MODULE_AUTHOR("Alex Lange <chicken@handhelds.org>");
+MODULE_DESCRIPTION("Jornada 720 keyboard driver");
+MODULE_LICENSE("GPL");
+
+static char jornada720_kbd_name[] = "Jornada 720 keyboard";
+
+static struct input_dev *dev;
+
+static unsigned char jornada720_normal_keymap[128] = {
+	0, 1, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 87, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE,
+	0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0,
+	0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 43, 14, 0, 0, 0,
+	0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, KEY_LEFTBRACE, KEY_RIGHTBRACE, 0, 0, 0,
+	0, 44, 45, 46, 47, 48, 49, 50, 51, 52, KEY_KPMINUS, 40, 28, 0, 0, 0,
+	0, 15, 0, 42, 0, 40, 0, 0, 0, 0, 103, 0, 54, 0, 0, 0,
+	0, 0, 0, 0, 0, 56, KEY_GRAVE, 0, 0, 105, 108, 106, 0, 0, 0, 0,
+	0, 55, 29, 0, 57, 0, 0, 0, 53, 111, 0, 0, 0, 0, 0, 116,
+};
+
+static irqreturn_t jornada720_keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int key, keycode;
+	int count, mcu_data=0;
+
+	jornada720_mcu_start(MCU_GetScanKeyCode);
+	count = jornada720_mcu_read();
+
+	while (count-- > 0) {
+		key = mcu_data = jornada720_mcu_read();
+
+		if (key > 128)
+			key = key - 128;
+
+		keycode = jornada720_normal_keymap[key];
+
+		if (mcu_data < 128) {
+			input_report_key(dev, keycode, 1);
+			input_sync(dev);
+		}
+		else {
+			input_report_key(dev, keycode, 0);
+			input_sync(dev);
+		}
+	}
+
+	jornada720_mcu_end();
+
+	return IRQ_HANDLED;
+}
+
+static int __init jornada720_kbd_init(void)
+{
+	int i,ret;
+	printk("jorada720_kbd: Jornada 720 keyboard\n");
+
+	/*init_input_dev(&dev);*/
+	dev = input_allocate_device();
+	dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	dev->keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
+
+	for ( i=0 ; i<=128 ; i++ ) {
+		if (!(jornada720_normal_keymap[i])) {
+		}
+		else
+			set_bit(jornada720_normal_keymap[i], dev->keybit);
+	}
+
+	dev->name = jornada720_kbd_name;
+
+	ret = request_irq(GPIO_JORNADA720_KEYBOARD_IRQ,
+	                  jornada720_keyboard_interrupt,
+			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+			  "Jornada720 Keyboard",NULL);
+	if (ret) {
+	        printk("Unable to grab Jornada 720 keyboard IRQ: %d\n", ret);
+		input_free_device(dev);
+		return ret;
+	}
+
+	input_register_device(dev);
+
+	return 0;
+}
+
+module_init(jornada720_kbd_init);
diff -ruN linux-2.6.18-vanilla/drivers/input/touchscreen/Kconfig linux-2.6.18/drivers/input/touchscreen/Kconfig
--- linux-2.6.18-vanilla/drivers/input/touchscreen/Kconfig	2006-09-20 03:42:06.000000000 +0000
+++ linux-2.6.18/drivers/input/touchscreen/Kconfig	2006-10-03 22:58:39.000000000 +0000
@@ -108,4 +108,11 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called hp680_ts_input.
 
+config TOUCHSCREEN_JORNADA720
+        tristate "HP Jornada 720 touchscreen support"
+	depends on SA1100_JORNADA720
+	help
+	  Say Y here if you are using a HP Jornada 710/720/728 handheld
+	  and want to use the touchscreen.
+
 endif
diff -ruN linux-2.6.18-vanilla/drivers/input/touchscreen/Makefile linux-2.6.18/drivers/input/touchscreen/Makefile
--- linux-2.6.18-vanilla/drivers/input/touchscreen/Makefile	2006-09-20 03:42:06.000000000 +0000
+++ linux-2.6.18/drivers/input/touchscreen/Makefile	2006-10-03 22:58:39.000000000 +0000
@@ -12,3 +12,4 @@
 obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
 obj-$(CONFIG_TOUCHSCREEN_MK712)	+= mk712.o
 obj-$(CONFIG_TOUCHSCREEN_HP600)	+= hp680_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_JORNADA720) += jornada720_ts.o
diff -ruN linux-2.6.18-vanilla/drivers/input/touchscreen/jornada720_ts.c linux-2.6.18/drivers/input/touchscreen/jornada720_ts.c
--- linux-2.6.18-vanilla/drivers/input/touchscreen/jornada720_ts.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.18/drivers/input/touchscreen/jornada720_ts.c	2006-10-03 23:07:32.000000000 +0000
@@ -0,0 +1,108 @@
+/*
+ * Jornada 720 touchscreen interface based on Jornada 56x interface
+ */
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/jornada720.h>
+#include <asm/irq.h>
+
+MODULE_AUTHOR("Alex Lange <chicken@handhelds.org>");
+MODULE_DESCRIPTION("Jornada 720 touchscreen driver");
+MODULE_LICENSE("GPL");
+
+static char jornada720_ts_name[] = "Jornada 720 touchscreen";
+
+static struct input_dev *dev;
+
+static irqreturn_t jornada720_mouse_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int down;
+	int X[3], Y[3], high_x, high_y, x, y;
+
+	udelay(1);
+
+	down = ( (GPLR & GPIO_JORNADA720_MOUSE) == 0);
+
+	if(!down) {
+		input_report_key(dev, BTN_TOUCH, down); /* report a pen up */
+		input_report_abs(dev, ABS_PRESSURE, 0);
+		input_sync(dev);
+		return IRQ_HANDLED;
+	}
+
+	/* read x & y data from mcu interface and pass it on */
+
+	jornada720_mcu_start(MCU_GetTouchSamples);
+	X[0] = jornada720_mcu_read();
+	X[1] = jornada720_mcu_read();
+	X[2] = jornada720_mcu_read();
+	Y[0] = jornada720_mcu_read();
+	Y[1] = jornada720_mcu_read();
+	Y[2] = jornada720_mcu_read();
+	high_x = jornada720_mcu_read(); /* msbs of samples */
+	high_y = jornada720_mcu_read();
+	jornada720_mcu_end();
+
+	X[0] |= (high_x & 3) << 8;
+	X[1] |= (high_x & 0xc) << 6;
+	X[2] |= (high_x & 0x30) << 4;
+
+	Y[0] |= (high_y & 3) << 8;
+	Y[1] |= (high_y & 0xc) << 6;
+	Y[2] |= (high_y & 0x30) << 4;
+
+        /* simple averaging filter */
+	x = (X[0] + X[1] + X[2])/3;
+	y = (Y[0] + Y[1] + Y[2])/3;
+
+	input_report_key(dev, BTN_TOUCH, down);
+	input_report_abs(dev, ABS_X, x);
+	input_report_abs(dev, ABS_Y, y);
+	input_report_abs(dev, ABS_PRESSURE, 1);
+	input_sync(dev);
+
+	return IRQ_HANDLED;
+
+}
+
+static int __init jornada720_ts_init(void)
+{
+	int ret;
+        printk("jornada720_ts: Jornada 720 touchscreen\n");
+
+	dev = input_allocate_device();
+	dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+	dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+
+	dev->absmin[ABS_X] = 270; dev->absmin[ABS_Y] = 180;
+	dev->absmax[ABS_X] = 3900;  dev->absmax[ABS_Y] = 3700;
+
+	dev->name = jornada720_ts_name;
+
+	ret = request_irq(GPIO_JORNADA720_MOUSE_IRQ,
+	                  jornada720_mouse_interrupt,
+			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+			  "Jornada720 Mouse",NULL);
+	if (ret) {
+	        printk("Unable to grab Jornada 720 Mouse/Touchscreen IRQ: %d\n", ret);
+                input_free_device(dev);
+		return ret;
+	}
+
+	input_register_device(dev);
+
+	return 0;
+}
+
+module_init(jornada720_ts_init);
+
diff -ruN linux-2.6.18-vanilla/drivers/video/Kconfig linux-2.6.18/drivers/video/Kconfig
--- linux-2.6.18-vanilla/drivers/video/Kconfig	2006-09-20 03:42:06.000000000 +0000
+++ linux-2.6.18/drivers/video/Kconfig	2006-10-03 22:58:39.000000000 +0000
@@ -680,6 +680,16 @@
 	  framebuffer.  Product specs at
 	  <http://www.erd.epson.com/vdc/html/products.htm>.
 
+config FB_EPSON1356
+        bool "Epson 1356 framebuffer support"
+	depends on FB && ARM && SA1100_JORNADA720
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	Support for the 1356 framebuffer device on the HP Jornada
+	710/720/728 hanheld pc.
+
 config FB_S1D13XXX
 	tristate "Epson S1D13XXX framebuffer support"
 	depends on FB
diff -ruN linux-2.6.18-vanilla/drivers/video/Makefile linux-2.6.18/drivers/video/Makefile
--- linux-2.6.18-vanilla/drivers/video/Makefile	2006-09-20 03:42:06.000000000 +0000
+++ linux-2.6.18/drivers/video/Makefile	2006-10-03 22:58:39.000000000 +0000
@@ -77,6 +77,7 @@
 obj-$(CONFIG_FB_SUN3)             += sun3fb.o
 obj-$(CONFIG_FB_HIT)              += hitfb.o
 obj-$(CONFIG_FB_EPSON1355)	  += epson1355fb.o
+obj-$(CONFIG_FB_EPSON1356)        += epson1356fb.o
 obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
 obj-$(CONFIG_FB_VOODOO1)          += sstfb.o
 obj-$(CONFIG_FB_ARMCLCD)	  += amba-clcd.o
diff -ruN linux-2.6.18-vanilla/drivers/video/epson1356fb.c linux-2.6.18/drivers/video/epson1356fb.c
--- linux-2.6.18-vanilla/drivers/video/epson1356fb.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.18/drivers/video/epson1356fb.c	2006-10-03 22:58:39.000000000 +0000
@@ -0,0 +1,345 @@
+/*
+ * linux/drivers/video/epson1356fb.c -- Epson 1356 LCD Controller Frame Buffer Device
+ *
+ *  Copyright (C) 2001 MIT
+ *
+ * Edited from sa1100fb.c
+ *  Copyright (C) 1999 Eric A. Thomas
+ *   Based on acornfb.c Copyright (C) Russell King.
+ *
+ * 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.
+ *
+ * 20050203: Ported to kernel 2.6. Very basic interface for the Jornada 720 (C) Alex Lange (chicken@handhelds.org)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/uaccess.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/jornada720.h>
+
+#include "console/fbcon.h"
+
+u32 pseudo_pal[16];
+
+struct fb_info fb_info;
+
+static int e1356fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			      unsigned blue, unsigned transp,
+			      struct fb_info *fb_info)
+{
+	int bpp, m = 0;
+
+	bpp = fb_info->var.bits_per_pixel;
+	m = (bpp <= 8) ? (1 << bpp) : 256;
+	if (regno >= m) {
+		printk("regno %d out of range (max %d)\n", regno, m);
+		return -EINVAL;
+	}
+	switch (bpp) {
+	case 8:
+		break;
+	case 16:
+		/* RGB 565 */
+		pseudo_pal[regno] = ((red & 0xF800) |
+					   ((green & 0xFC00) >> 5) |
+					   ((blue & 0xF800) >> 11));
+		break;
+	}
+
+	return 0;
+}
+
+static int e1356fb_blank(int blank, struct fb_info *info)
+{
+	switch (blank) {
+		case FB_BLANK_POWERDOWN:
+		case FB_BLANK_VSYNC_SUSPEND:
+		case FB_BLANK_HSYNC_SUSPEND:
+		case FB_BLANK_NORMAL:
+			PPSR &= ~PPC_LDD1;
+			PPDR |= PPC_LDD1;
+			break;
+
+		case FB_BLANK_UNBLANK:
+			PPSR |= PPC_LDD1;
+			mdelay(100);
+		}
+	return 0;
+}
+
+static struct fb_var_screeninfo e1356fb_screeninfo = {
+	.xres 		= 640,
+	.yres 		= 240,
+	.xres_virtual 	= 640,
+	.yres_virtual 	= 240,
+	.bits_per_pixel = 16,
+	.red.length	= 5,
+	.green.length	= 6,
+	.blue.length	= 5,
+	.transp.length	= 0,
+	.red.offset	= 11,
+	.green.offset	= 5,
+	.blue.offset	= 0,
+	.transp.offset	= 0,
+	.activate 	= FB_ACTIVATE_NOW,
+	.height 	= -1,
+	.width 		= -1,
+	.vmode 		= FB_VMODE_NONINTERLACED,
+	.accel_flags	= 0,
+	.nonstd		= 0,
+};
+
+static struct fb_ops e1356fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_setcolreg	= e1356fb_setcolreg,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
+	.fb_blank	= e1356fb_blank,
+};
+
+static struct fb_fix_screeninfo e1356fb_fix = {
+	.id 		= "e1356fb",
+	.smem_len 	= (MAX_XRES * MAX_YRES * MAX_BPP)/8,
+	.smem_start	= (unsigned long)DISP_MEM_OFFSET_PHYS,
+	.type 		= FB_TYPE_PACKED_PIXELS,
+	.visual 	= FB_VISUAL_TRUECOLOR,
+	.line_length 	= (640 * 16) / 8,
+	.accel		= FB_ACCEL_NONE,
+	.type_aux	= 0,
+	.ypanstep	= 0,
+	.ywrapstep	= 0,
+};
+
+unsigned char LUT8[256*3] = {
+	/* Primary and secondary colors */
+	0x00, 0x00, 0x00,  0x00, 0x00, 0xA0,  0x00, 0xA0, 0x00,  0x00, 0xA0, 0xA0,
+	0xA0, 0x00, 0x00,  0xA0, 0x00, 0xA0,  0xA0, 0xA0, 0x00,  0xA0, 0xA0, 0xA0,
+	0x50, 0x50, 0x50,  0x00, 0x00, 0xF0,  0x00, 0xF0, 0x00,  0x00, 0xF0, 0xF0,
+	0xF0, 0x00, 0x00,  0xF0, 0x00, 0xF0,  0xF0, 0xF0, 0x00,  0xF0, 0xF0, 0xF0
+};
+
+static char lut_base[] = {
+	/*red    green  blue   rinc   ginc   binc  */
+	  0x00,  0x00,  0x00,  0x10,  0x10,  0x10, /* Gray shades */
+	  0x00,  0x00,  0x00,  0x10,  0x00,  0x00, /* Black to red */
+	  0x00,  0x00,  0x00,  0x00,  0x10,  0x00, /* Black to green */
+	  0x00,  0x00,  0x00,  0x00,  0x00,  0x10, /* Black to blue */
+	  0x00,  0x00,  0xF0,  0x00,  0x10,  0x00, /* Blue to cyan (blue and green) */
+	  0x00,  0xf0,  0xf0,  0x00,  0x00, -0x10, /* Cyan (blue and green) to green */
+	  0x00,  0xf0,  0x00,  0x10,  0x00,  0x00, /* Green to yellow (red and green)*/
+	  0xf0,  0xf0,  0x00,  0x00, -0x10,  0x00, /* Yellow (red and green) to red */
+	  0xf0,  0x00,  0x00,  0x00,  0x00,  0x10, /* Red to magenta (blue and red) */
+	  0xf0,  0x00,  0xf0, -0x10,  0x00,  0x00, /* Magenta (blue and red) to blue */
+	  0x00,  0x00,  0x00,  0x10,  0x00,  0x10, /* Black to magenta (blue and red)*/
+	  0x00,  0x00,  0x00,  0x00,  0x10,  0x10, /* Black to cyan (blue and green) */
+	  0xf0,  0x00,  0x00,  0x00,  0x10,  0x10, /* Red to white */
+	  0x00,  0xf0,  0x00,  0x10,  0x00,  0x10, /* Green to white */
+	  0x00,  0x00,  0xf0,  0x10,  0x10,  0x00, /* Blue to white */
+};
+
+void e1356fb_init_hardware(void)
+{
+	unsigned char *pRegs = REGISTER_OFFSET;
+	unsigned char *pLUT = LUT8;
+	unsigned char *pseed = lut_base;
+	unsigned char plast[3];
+	int i, j, rgb;
+
+	/* Enable access to SED1356 by setting memory/register select bit to 0. */
+	pRegs[0x001] = 0;
+	udelay(2);
+	/* Disable display outputs during initialization) */
+	pRegs[0x1FC] = 0;
+
+	/* Set the GPIOs to input. Should GPIO bits in register [004] get switched
+	   then the GPIO outputs, according to register [008], are driven low. */
+	pRegs[0x004] = 0;
+	pRegs[0x008] = 0;
+
+	/* Program the LCD panel type and panel timing registers.
+	 *	The horizontal and vertical non-display times have been
+	 *	calculated for a 78 Hz frame rate.
+	 *                                                LCD PCLK
+	 *                          FrameRate = -----------------------------
+	 *                                      (HDP + HNDP) * (VDP/2 + VNDP)
+	 *
+	 *           20,000,000
+	 * = ---------------------------- = 78 Hz
+	 *   (640 + 256) * (480 / 2 + 45)
+	 */
+
+	pRegs[0x10] = 0x1;	/* Memory Clock Configuration Register */
+	pRegs[0x14] = 0x11;	/* LCD Pixel Clock Configuration Register */
+	pRegs[0x18] = 0x1;	/* CRT/TV Pixel Clock Configuration Register */
+	pRegs[0x1c] = 0x1;	/* MediaPlug Clock Configuration Register */
+	pRegs[0x1e] = 0x1;	/* CPU To Memory Wait State Select Register */
+	pRegs[0x20] = 0;	/* Memory Configuration Register */
+	pRegs[0x21] = 0x45;	/* DRAM Refresh Rate Register */
+	pRegs[0x2a] = 0x1;	/* DRAM Timings Control Register 0 */
+	pRegs[0x2b] = 0x1;	/* DRAM Timings Control Register 1 */
+	pRegs[0x30] = 0x1c;	/* Panel Type Register */
+	pRegs[0x31] = 0;	/* MOD Rate Register */
+	pRegs[0x32] = 0x4f;	/* LCD Horizontal Display Width Register */
+	pRegs[0x34] = 0x7;	/* LCD Horizontal Non-Display Period Register */
+	pRegs[0x35] = 0x1;	/* TFT FPLINE Start Position Register */
+	pRegs[0x36] = 0xb;	/* TFT FPLINE Pulse Width Register */
+	pRegs[0x38] = 0xef;	/* LCD Vertical Display Height Register 0 */
+	pRegs[0x39] = 0;	/* LCD Vertical Display Height Register 1 */
+	pRegs[0x3a] = 0x13;	/* LCD Vertical Non-Display Period Register */
+	pRegs[0x3b] = 0xb;	/* TFT FPFRAME Start Position Register */
+	pRegs[0x3c] = 0x1;	/* TFT FPFRAME Pulse Width Register */
+	pRegs[0x40] = 0x5;	/* LCD Display Mode Register */
+	pRegs[0x41] = 0;	/* LCD Miscellaneous Register */
+	pRegs[0x42] = 0;	/* LCD Display Start Address Register 0 */
+	pRegs[0x43] = 0;	/* LCD Display Start Address Register 1 */
+	pRegs[0x44] = 0;	/* LCD Display Start Address Register 2 */
+	pRegs[0x46] = 0x80;	/* LCD Memory Address Offset Register 0 */
+	pRegs[0x47] = 0x2;	/* LCD Memory Address Offset Register 1 */
+	pRegs[0x48] = 0;	/* LCD Pixel Panning Register */
+	pRegs[0x4a] = 0;	/* LCD Display FIFO High Threshold Control Register */
+	pRegs[0x4b] = 0;	/* LCD Display FIFO Low Threshold Control Register */
+	pRegs[0x50] = 0x4f;	/* CRT/TV Horizontal Display Width Register */
+	pRegs[0x52] = 0x13;	/* CRT/TV Horizontal Non-Display Period Register */
+	pRegs[0x53] = 0x1;	/* CRT/TV HRTC Start Position Register */
+	pRegs[0x54] = 0xb;	/* CRT/TV HRTC Pulse Width Register */
+	pRegs[0x56] = 0xdf;	/* CRT/TV Vertical Display Height Register 0 */
+	pRegs[0x57] = 0x1;	/* CRT/TV Vertical Display Height Register 1 */
+	pRegs[0x58] = 0x2b;	/* CRT/TV Vertical Non-Display Period Register */
+	pRegs[0x59] = 0x9;	/* CRT/TV VRTC Start Position Register */
+	pRegs[0x5a] = 0x1;	/* CRT/TV VRTC Pulse Width Register */
+	pRegs[0x5b] = 0x10;	/* TV Output Control Register */
+	pRegs[0x60] = 0x3;	/* CRT/TV Display Mode Register */
+	pRegs[0x62] = 0;	/* CRT/TV Display Start Address Register 0 */
+	pRegs[0x63] = 0;	/* CRT/TV Display Start Address Register 1 */
+	pRegs[0x64] = 0;	/* CRT/TV Display Start Address Register 2 */
+	pRegs[0x66] = 0x40;	/* CRT/TV Memory Address Offset Register 0 */
+	pRegs[0x67] = 0x1;	/* CRT/TV Memory Address Offset Register 1 */
+	pRegs[0x68] = 0;	/* CRT/TV Pixel Panning Register */
+	pRegs[0x6a] = 0;	/* CRT/TV Display FIFO High Threshold Control Register */
+	pRegs[0x6b] = 0;	/* CRT/TV Display FIFO Low Threshold Control Register */
+	pRegs[0x70] = 0;	/* LCD Ink/Cursor Control Register */
+	pRegs[0x71] = 0x1;	/* LCD Ink/Cursor Start Address Register */
+	pRegs[0x72] = 0;	/* LCD Cursor X Position Register 0 */
+	pRegs[0x73] = 0;	/* LCD Cursor X Position Register 1 */
+	pRegs[0x74] = 0;	/* LCD Cursor Y Position Register 0 */
+	pRegs[0x75] = 0;	/* LCD Cursor Y Position Register 1 */
+	pRegs[0x76] = 0;	/* LCD Ink/Cursor Blue Color 0 Register */
+	pRegs[0x77] = 0;	/* LCD Ink/Cursor Green Color 0 Register */
+	pRegs[0x78] = 0;	/* LCD Ink/Cursor Red Color 0 Register */
+	pRegs[0x7a] = 0x1f;	/* LCD Ink/Cursor Blue Color 1 Register */
+	pRegs[0x7b] = 0x3f;	/* LCD Ink/Cursor Green Color 1 Register */
+	pRegs[0x7c] = 0x1f;	/* LCD Ink/Cursor Red Color 1 Register */
+	pRegs[0x7e] = 0;	/* LCD Ink/Cursor FIFO Threshold Register */
+	pRegs[0x80] = 0;	/* CRT/TV Ink/Cursor Control Register */
+	pRegs[0x81] = 0x1;	/* CRT/TV Ink/Cursor Start Address Register */
+	pRegs[0x82] = 0;	/* CRT/TV Cursor X Position Register 0 */
+	pRegs[0x83] = 0;	/* CRT/TV Cursor X Position Register 1 */
+	pRegs[0x84] = 0;	/* CRT/TV Cursor Y Position Register 0 */
+	pRegs[0x85] = 0;	/* CRT/TV Cursor Y Position Register 1 */
+	pRegs[0x86] = 0;	/* CRT/TV Ink/Cursor Blue Color 0 Register */
+	pRegs[0x87] = 0;	/* CRT/TV Ink/Cursor Green Color 0 Register */
+	pRegs[0x88] = 0;	/* CRT/TV Ink/Cursor Red Color 0 Register */
+	pRegs[0x8a] = 0x1f;	/* CRT/TV Ink/Cursor Blue Color 1 Register */
+	pRegs[0x8b] = 0x3f;	/* CRT/TV Ink/Cursor Green Color 1 Register */
+	pRegs[0x8c] = 0x1f;	/* CRT/TV Ink/Cursor Red Color 1 Register */
+	pRegs[0x8e] = 0;	/* CRT/TV Ink/Cursor FIFO Threshold Register */
+
+	/* Set the 2D acceleration (BitBLT) registers to a known state */
+	for (i = 0x100; i <= 0x119; i++)
+		if (i != 0x107 && i != 0x10b && i != 0x10e && i != 0x10f && i != 0x117)
+			pRegs[i] = 0x00;
+
+	/* Program the look-up table to a known state.  */
+	pRegs[0x1E0] = 0x01;	/* Enable the LCD LUT for read/write. */
+	pRegs[0x1E2] = 0;	/* Reset the LUT address. */
+	for (i = 0; i < 16 * 3; i++)
+		pRegs[0x1E4] = *pLUT++;	/* non-regular color template */
+
+	for (i = 0; i < 15; i++) {
+		for (rgb = 0; rgb < 3; rgb++) {
+			plast[rgb] = *pseed++;		/* base color value */
+			pRegs[0x1E4] = plast[rgb];
+		}
+		for (j = 0; j < 15; j++)
+			for (rgb = 0; rgb < 3; rgb++) {
+				plast[rgb] += pseed[rgb];	/* increment through color values*/
+				pRegs[0x1E4] = plast[rgb];
+			}
+		pseed += 3;
+	}
+
+	pRegs[0x1e4] = 0;	/* Look-Up Table Data Register */
+	pRegs[0x1f0] = 0;	/* Power Save Configuration Register */
+	pRegs[0x1f1] = 0;	/* Power Save Status Register */
+	pRegs[0x1f4] = 0;	/* CPU-to-Memory Access Watchdog Timer Register */
+
+	PPSR |= PPC_LDD0;
+
+	mdelay(100);		/* Wait for 100ms */
+	pRegs[0x1F0] = 0;	/* Turn off power save mode */
+	pRegs[0x1F4] = 0;	/* Disable the watchdog timer */
+	pRegs[0x1FC] = 0x01;	/* Disable power save mode, enable display */
+}
+
+int __init e1356fb_init(void)
+{
+	if (fb_get_options("e1356fb", NULL))
+		return -ENODEV;
+
+	printk("Configuring the Jornada 720 screen...\n");
+
+	fb_info.screen_base = (u_char *) DISP_MEM_OFFSET;
+	fb_info.screen_size = ALLOCATED_FB_MEM_SIZE;
+	memset(&fb_info.var, 0, sizeof(fb_info.var));
+
+	PPSR &= ~(PPC_LDD0 | PPC_LDD1 | PPC_LDD2);
+	PPDR |= PPC_LDD0 | PPC_LDD1 | PPC_LDD2;
+	LCCR3 = 0;
+	LCCR2 = 0;
+	LCCR1 = 0;
+	LCCR0 = 0;
+	DBAR1 = 0;
+	DBAR2 = 0;
+
+	e1356fb_init_hardware();
+	memset ((unsigned char *)DISP_MEM_OFFSET, 0, ALLOCATED_FB_MEM_SIZE);
+
+	PPSR |= PPC_LDD1;
+	mdelay(100);	/* delay again */
+	PPSR |= PPC_LDD2;
+
+	fb_info.fbops		= &e1356fb_ops;
+	fb_info.var		= e1356fb_screeninfo;
+	fb_info.fix		= e1356fb_fix;
+	fb_info.flags		= FBINFO_DEFAULT;
+
+	fb_info.pseudo_palette	= &pseudo_pal;
+
+	if (register_framebuffer(&fb_info) < 0)
+		return 1;
+
+	return 0;
+}
+
+module_init(e1356fb_init);
+
diff -ruN linux-2.6.18-vanilla/include/asm-arm/arch-sa1100/jornada720.h linux-2.6.18/include/asm-arm/arch-sa1100/jornada720.h
--- linux-2.6.18-vanilla/include/asm-arm/arch-sa1100/jornada720.h	2006-09-20 03:42:06.000000000 +0000
+++ linux-2.6.18/include/asm-arm/arch-sa1100/jornada720.h	2006-10-03 22:58:39.000000000 +0000
@@ -11,6 +11,8 @@
 #error "include <asm/hardware.h> instead"
 #endif
 
+#define jornada720_mcu_read() jornada720_mcu_byte(MCU_TxDummy)
+
 #define SA1111_BASE             (0x40000000)
 
 #define GPIO_JORNADA720_KEYBOARD	GPIO_GPIO(0)
@@ -19,9 +21,38 @@
 #define GPIO_JORNADA720_KEYBOARD_IRQ	IRQ_GPIO0
 #define GPIO_JORNADA720_MOUSE_IRQ		IRQ_GPIO9
 
+/* Epson 1356 LCD controll parameters */
+#define REGISTER_OFFSET ((unsigned char *) 0xf0000000/* 0 */)
+#define DISP_MEM_OFFSET ((unsigned char *) 0xf1000000/* 0 */)
+#define DISP_MEM_OFFSET_PHYS ((unsigned char *) 0x48200000/* 0 filip wtf? */)
+#define ALLOCATED_FB_MEM_SIZE 0x80000 /* display memory size (512kb) */
+
+#define MAX_BPP              16
+#define MAX_XRES            640
+#define MAX_YRES            240
+#define MIN_XRES             64
+#define MIN_YRES             64
+
+/* MCU COMMANDS */
+#define MCU_GetBatteryData  0xc0
+#define MCU_GetScanKeyCode  0x90
+#define MCU_GetTouchSamples 0xa0
+#define MCU_GetContrast     0xD0
+#define MCU_SetContrast     0xD1
+#define MCU_GetBrightness   0xD2
+#define MCU_SetBrightness   0xD3
+#define MCU_ContrastOff     0xD8
+#define MCU_BrightnessOff   0xD9
+#define MCU_PWMOFF          0xDF
+#define MCU_TxDummy         0x11
+#define MCU_ErrorCode       0x00
+
 #ifndef __ASSEMBLY__
 
 void jornada720_mcu_init(void);
+int  jornada720_mcu_byte(int arg_data);
+int  jornada720_mcu_start(int arg_data);
+void jornada720_mcu_end(void);
 void jornada_contrast(int arg_contrast);
 void jornada720_battery(void);
 int jornada720_getkey(unsigned char *data, int size);