--- linux-2.6.17-vanilla/arch/arm/mach-sa1100/jornada720.c	2006-06-18 01:49:35.000000000 +0000
+++ linux-2.6.17/arch/arm/mach-sa1100/jornada720.c	2006-07-10 17:06:11.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;
 }