Browse Source

Commit for backup purpose

mlt 14 years ago
parent
commit
e3c7c1b8b5

+ 42 - 85
cybook.config

@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.21.5-cfs-v19
-# Tue Apr 27 14:38:50 2010
+# Mon May 24 20:53:14 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -139,6 +139,7 @@ CONFIG_ARCH_S3C2410=y
 CONFIG_PLAT_S3C=y
 CONFIG_PLAT_S3C24XX=y
 # CONFIG_PLAT_S3C64XX is not set
+# CONFIG_S3C2410_BOOT_WATCHDOG is not set
 # CONFIG_S3C2410_BOOT_ERROR_RESET is not set
 # CONFIG_S3C2410_PM_DEBUG is not set
 # CONFIG_S3C2410_PM_CHECK is not set
@@ -327,19 +328,12 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 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 is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_PNP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_ARPD is not set
@@ -349,9 +343,9 @@ CONFIG_IP_PNP_BOOTP=y
 # 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_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -537,26 +531,11 @@ CONFIG_NETDEVICES=y
 #
 # PHY device support
 #
-# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_SMC91X is not set
-CONFIG_DM9000=y
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_PCI=y
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
+# CONFIG_NET_ETHERNET is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -595,17 +574,20 @@ CONFIG_NET_WIRELESS=y
 # Wan interfaces
 #
 # CONFIG_WAN is not set
-CONFIG_PPP=y
+CONFIG_PPP=m
 CONFIG_PPP_MULTILINK=y
 CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_SYNC_TTY=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_MPPE=y
-CONFIG_PPPOE=y
-# CONFIG_SLIP is not set
-CONFIG_SLHC=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+# CONFIG_SLIP_COMPRESSED is not set
+CONFIG_SLHC=m
+# CONFIG_SLIP_SMART is not set
+# CONFIG_SLIP_MODE_SLIP6 is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -630,9 +612,7 @@ CONFIG_INPUT_MOUSEDEV=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_TSDEV=y
-CONFIG_INPUT_TSDEV_SCREEN_X=240
-CONFIG_INPUT_TSDEV_SCREEN_Y=320
+# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -662,7 +642,8 @@ CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
 # CONFIG_TOUCHSCREEN_UCB1400 is not set
-CONFIG_TOUCHSCREEN_IIC_QISDA=y
+CONFIG_TOUCHSCREEN_ORIZON=y
+# CONFIG_TOUCHSCREEN_IIC_QISDA is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_UINPUT is not set
 CONFIG_CYBOOK_ORIZON_TILT=y
@@ -670,9 +651,7 @@ CONFIG_CYBOOK_ORIZON_TILT=y
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -682,39 +661,12 @@ CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_SERIAL_NONSTANDARD=y
-# CONFIG_COMPUTONE is not set
-# CONFIG_ROCKETPORT is not set
-# CONFIG_CYCLADES is not set
-# CONFIG_DIGIEPCA is not set
-# CONFIG_MOXA_INTELLIO is not set
-# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_MOXA_SMARTIO_NEW is not set
-# CONFIG_SYNCLINKMP is not set
-# CONFIG_N_HDLC is not set
-# CONFIG_RISCOM8 is not set
-# CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
-# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
 
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=8
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-# CONFIG_SERIAL_8250_FOURPORT is not set
-# CONFIG_SERIAL_8250_ACCENT is not set
-# CONFIG_SERIAL_8250_BOCA is not set
-# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
+# CONFIG_SERIAL_8250 is not set
 
 #
 # Non-8250 serial port support
@@ -742,7 +694,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_S3C2410_WATCHDOG is not set
+CONFIG_S3C2410_WATCHDOG=m
 
 #
 # ISA-based Watchdog Cards
@@ -800,8 +752,8 @@ CONFIG_I2C_S3C2410=y
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
-CONFIG_QISDA_IIC=y
-CONFIG_TOUCH_PM=y
+# CONFIG_QISDA_IIC is not set
+# CONFIG_TOUCH_PM is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -1183,7 +1135,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
-# CONFIG_INOTIFY_USER is not set
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -1310,11 +1262,11 @@ CONFIG_NLS_UTF8=y
 #
 # Kernel hacking
 #
-# CONFIG_PRINTK_TIME is not set
+CONFIG_PRINTK_TIME=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_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
@@ -1323,7 +1275,8 @@ CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_SLAB=y
+CONFIG_DEBUG_SLAB_LEAK=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1333,14 +1286,18 @@ CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_LIST is not set
+CONFIG_DEBUG_VM=y
+CONFIG_DEBUG_LIST=y
 CONFIG_FRAME_POINTER=y
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_FAULT_INJECTION is not set
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAILSLAB=y
+# CONFIG_FAIL_PAGE_ALLOC is not set
+# CONFIG_FAIL_MAKE_REQUEST is not set
+# CONFIG_FAULT_INJECTION_DEBUG_FS is not set
 CONFIG_DEBUG_USER=y
-# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_ICEDCC is not set
 CONFIG_DEBUG_S3C2410_PORT=y
@@ -1405,6 +1362,6 @@ CONFIG_CRC_CCITT=y
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y

+ 4 - 1
drivers/char/s3c-adc.c

@@ -75,7 +75,7 @@
 #define BATTERY_FULL   4005  /*100%*/    /*4.1V*/  /*4005*/
 
 
-#define ADC_sample_count    100  //25  /*joey modify ADC read method to catch top 5 low value 2009/12/21*/
+#define ADC_sample_count    10 //100  //25  /*joey modify ADC read method to catch top 5 low value 2009/12/21*/
 #define ADC_jig_voltage     3700  /*joey for ENV ADC to voltage 2010/01/15*/
 
 #define ADC_READ_LEVEL_VAULE          _IOR('S', 0x01, unsigned long)
@@ -436,6 +436,9 @@ static int s3c_adc_ioctl(struct inode *inode, struct file *file,
              
              ret = 0;
         break;
+         /* case ((( 2U ) << ( ( ( 0 + 8 ) + 8 ) + 14 ) ) |
+          *       (( ( 'S' ) ) << ( 0 + 8 ) ) | (( ( 0x04 ) ) << 0 ) |
+          *       (( ( ((sizeof( unsigned long ) == sizeof( unsigned long [1]) && sizeof( unsigned long ) < (1 << 14 )) ? sizeof( unsigned long ) : __invalid_size_argument_for_IOC) ) ) << ( ( 0 + 8 ) + 8 ) )): */
         case ADC_READ_RAW_VAULE:
              for(i=0; i<ADC_sample_count ;i++)
              {   

+ 477 - 0
drivers/input/cyevent.c

@@ -0,0 +1,477 @@
+h
+// ===========================================================================
+// cyio.c
+// Copyright (C) 2008-2010 Bookeen - All rights reserved
+// ===========================================================================
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+#include <linux/proc_fs.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-gpioj.h>
+
+#include <cybook.h>
+
+#include <linux/cyevent.h>
+
+#define CYEV_MAX_EVENT 20
+#define CYEV_REPEAT_DELAY (HZ/2); /* ~500ms */
+#define CYEV_CURRENT_VERSION 0x10 /* 1.0 */
+enum { INVALID = 0, VALID };
+
+struct 
+{
+    char valid;
+    char wantRepeat;
+    char seen;
+    char unique;
+    int  repeatDelay;
+    CyEvent_t payload;
+} CyEv_PayList;
+
+CyEv_PayList *cyev_eventList[CYEV_MAX_EVENT];
+
+struct task_struct *openingTask = 0;
+
+/* TODO: Add a locking method for accessing the eventList */
+
+// ===========================================================================
+// List management
+void CyEv_ClearEventList(void)
+{
+   int i;
+   for (i = 0; i < CYEV_MAX_EVENT; i++)
+   {
+      cyev_eventList[i].wantRepeat = false;
+      cyev_eventList[i].seen = false;
+      cyev_eventList[i].unique = false;
+      cyev_eventList[i].repeatDelay = 0;   
+      cyev_eventList[i].valid = INVALID;
+   }
+}
+
+/* Get Next Event will invalidate the event if it is not marked as repeat */
+/* After the event is selected, it will point to the next one */
+/* We first start by the first event of the list then search for the first valid and return it */
+CyEvent_t *CyEv_GetNextEvent(void)
+{
+   static int listPos = 0;
+   int i;
+   CyEvent_t ret = NULL;
+
+   /* Scan the list starting from the last position stored */
+   for(i = listPos; i < (CYEV_MAX_EVENT + listPos); i++)
+   {
+      /* Stop on the first "VALID" event */
+      if (cyev_eventList[i % CYEV_MAX_EVENT].valid == VALID)
+      {
+         /* We already send this repeatable event. Did the delay occur ? 
+            if not, ignore it and go to the next one */
+         if ( (cyev_eventList[i % CYEV_MAX_EVENT].seen == true) &&
+              (cyev_eventList[i % CYEV_MAX_EVENT].wantRepeat == true) )
+         {
+             if (cyev_eventList[i % CYEV_MAX_EVENT].repeatDelay < jiffies) )
+             {
+                continue;
+             }
+             else /* if (cyev_eventList[i % CYEV_MAX_EVENT].repeatDelay >= jiffies) ) */
+             {
+                /* Set the Repeat flag to true */
+                cyev_eventList[i % CYEV_MAX_EVENT].payload.flags |= CYEVENT_FLAG_REPEATEVENT;
+             }
+         }
+         
+         cyev_eventList[i % CYEV_MAX_EVENT].seen = true;
+         
+         /* Return the event */
+         ret = &(cyev_eventList[i % CYEV_MAX_EVENT].payload);
+
+         /* If the event is not a repeatable event, invalidate it! */
+         if (cyev_eventList[i % CYEV_MAX_EVENT].wantRepeat == false)
+         {
+            cyev_eventList[i % CYEV_MAX_EVENT].valid = INVALID;
+         }
+         
+         /* Update the index for the next element to scan */
+         listPos = (listPos + i + 1) % CYEV_MAX_EVENT;
+         break;
+      }
+   }
+
+   return ret; /* We will return NULL if no valid payload */
+}
+
+int isEventNotDuplicate(CyEvent_t *CyEvent)
+{
+   int i;
+   CyEvent_t *cur:
+   for(i = 0; i < CYEV_MAX_EVENT; i++)
+   {
+      cur = &(cyev_eventList[i].payload);
+      if (cyev_eventList[i].unique == true)
+      {
+         if (cur->type == CyEvent->type) /* To be verified */
+            return false;
+      }
+   }
+   return true;
+}
+
+int CyEv_AddNewEvent(CyEvent_t *CyEvent, char wantRepeat, char wantUnique)
+{
+   /* Search for the first "invalid" event, then put the given CyEvent in it. */
+   /* If no slot is valid, return an error */
+   int i;
+   int ret = -EIO; /* TODO: find a better error code.*/
+
+   /* If wantUnique, first check that there is not another unique event */
+   if ((wantUnique) && !isEventNotDuplicate(CyEvent))
+      goto exit;
+   
+   /* Scan the list starting from the last position stored */
+   for(i = 0; i < CYEV_MAX_EVENT; i++)
+   {
+      /* Stop on the first "VALID" event */
+      if (cyev_eventList[i].valid == INVALID)
+      {
+         /* Store the event */
+         memcpy(&(cyev_eventList[i].payload), CyEvent, sizeof(CyEvent_t));
+
+         /* Force version in the structure */
+         cyev_eventList[i].payload.version = CYEV_CURRENT_VERSION;
+         cyev_eventList[i].valid = VALID;
+         if (wantUnique)
+            cyev_eventList[i].unique = true;
+           else
+             cyev_eventList[i].unique = false;
+         if (wantRepeat)
+         {
+            cyev_eventList[i].wantRepeat = true;
+            cyev_eventList[i].repeatDelay = jiffies + CYEV_REPEAT_DELAY;
+         }
+         else
+            cyev_eventList[i].wantRepeat = false;
+
+
+  			if (openingTask)
+            wake_up_process(openingTask);
+
+         ret = 0;
+         break;
+      }
+   }
+   
+exit:
+   return ret;
+}
+
+/* Return 0 if event found and updated, or anything else */
+/* We could ONLY update event that are declared as unique */
+int CyEv_UpdateUniqueEvent(CyEvent_t *CyEvent, char wantRepeat)
+{
+   int i;
+   int ret = -1;
+   
+   /* Search for the event */
+   for(i = 0; i < CYEV_MAX_EVENT; i++)
+   {
+      if ( (cyev_eventList[i].unique == true) &&
+           (cyev_eventList[i].payload.type == CyEvent.type) )
+      {  /* Found it ! Now update the fields */
+         memcpy(&(cyev_eventList[i].payload), CyEvent, sizeof(CyEvent_t));
+         
+         if (wantRepeat)
+         {
+            cyev_eventList[i].wantRepeat = true;
+            cyev_eventList[i].repeatDelay = jiffies + CYEV_REPEAT_DELAY;
+         }
+         else
+            cyev_eventList[i].wantRepeat = false;
+
+  			if (openingTask)
+            wake_up_process(openingTask);
+            
+         ret = 0;
+      }
+   }
+   return ret;
+}
+
+int CyEv_InvalidateRepeatableEvent(CyEvent_t *CyEvent)
+{
+	int i;
+	int ret = -1;
+	
+   /* Search for the event */
+   for(i = 0; i < CYEV_MAX_EVENT; i++)
+   {
+      if ( (cyev_eventList[i].wantRepeat == true) &&
+           (cyev_eventList[i].payload.type == CyEvent.type) )
+      {  /* Found it ! Now update the fields */
+      	
+      	/* In case the event has not been eaten, just remove the "repeat want"
+      	   ie: do not invalidate it */
+       	cyev_eventList[i].wantRepeat = false;
+
+         if (cyev_eventList[i].seen == true)
+         {
+         	/* set the event "end of repeat" flag */
+				cyev_eventList[i].payload.flags |= CYEVENT_FLAG_ENDOFREPEAT;         		
+         }
+         
+         if (openingTask)
+            wake_up_process(openingTask);
+            
+         ret = 0;
+         break;
+      }
+   }
+   
+   return ret;
+}
+
+// ===========================================================================
+
+
+// ===========================================================================
+// External event managment
+int CyEvent_PushNewEvent(CyEvent_t *CyEvent, char wantRepeat)
+{
+   if (wantRepeat)
+      return CyEv_AddNewEvent(CyEvent, wantRepeat, true);
+   else
+      return CyEv_AddNewEvent(CyEvent, wantRepeat, false);
+}
+EXPORT_SYMBOL(CyEvent_PushNewEvent);
+
+int CyEvent_PushOrUpdateUniqueEvent(CyEvent_t *CyEvent, char wantRepeat)
+{
+   int ret;
+   
+   /* For now a simple call to AddNewEvent */
+   ret = CyEv_UpdateUniqueEvent(CyEvent, wantRepeat);
+   
+   if (ret != 0) /* The event is not present */
+      ret = CyEv_AddNewEvent(CyEvent, wantRepeat, true);
+      
+   return ret;
+}
+EXPORT_SYMBOL(CyEvent_PushOrUpdateUniqueEvent);
+
+int CyEvent_InvalidateRepeatableEvent(CyEvent_t *CyEvent)
+{
+    ret = CyEv_InvalidateRepeatableEvent(CyEvent);
+}
+EXPORT_SYMBOL(CyEvent_InvalidateRepeatableEvent);
+
+// ===========================================================================
+static int ev_open(struct inode *inode, struct file *file)
+{
+  /* Clear pending event list... */
+  CyEv_ClearEventList();
+  
+  return 0;
+}
+// ---------------------------------------------------------------------------
+static int ev_release(struct inode *inode, struct file *file)
+{
+  /* Clear pending event list... */
+  CyEv_ClearEventList();
+  
+  return 0;
+}
+// ---------------------------------------------------------------------------
+ssize_t ev_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+  int nBytes = sizeof(CyEvent_t);
+  int ret = -EIO;
+  CyEvent_t *CyEvent = NULL;
+  
+  if (count < nBytes)
+  {
+    ret = -EINVAL;
+    goto exit;
+  }
+
+  while (1)
+  {
+    if ((CyEvent = CyEv_GetNextEvent()) != NULL)
+    {
+    	break;
+    }
+  
+    openingTask = current;
+    set_current_state(TASK_INTERRUPTIBLE);
+    schedule();
+    set_current_state(TASK_RUNNING);
+    openingTask = 0;
+
+    if (signal_pending(current))
+    {
+      ret = -ERESTARTSYS;
+      break;
+    }
+  }
+  
+  if (CyEvent != NULL)
+  {
+    nRes = copy_to_user(buf, &CyEvent, nBytes);
+    if (!nRes)
+      nRes = nBytes;
+  }
+
+  return ret;
+}
+// ---------------------------------------------------------------------------
+static int ev_ioctl(struct inode *inode, struct file *file,
+                     unsigned int cmd, unsigned long arg)
+{
+   int ret = -EINVAL;
+   unsigned long value;
+   switch(cmd)
+   {
+   default:
+      printk(KERN_ERR "Bad IOCTL\n");
+      break;
+ 	case CYIO_CTL_LED_CMD:
+      DBG("CYIO_CTL_LED_CMD arg[0x%03X]", arg);
+
+      if ((arg & 0x2) && (arg & 0x1)) /* Power LED */
+      {
+         MSG("\n----------------> POWER LED ON\n");
+         //GPH12
+         __raw_writel(__raw_readl(S3C2410_GPHDAT) | (1 << 12), S3C2410_GPHDAT);
+      }
+      else if (arg & 0x2)
+      {
+         MSG("\n----------------> POWER LED OFF\n");
+         __raw_writel(__raw_readl(S3C2410_GPHDAT) & ~(1 << 12), S3C2410_GPHDAT);
+      }
+
+      if ((arg & 0x20) && (arg & 0x10)) /* Wifi LED */
+      {
+         MSG("\n----------------> POWER WFI ON\n");
+         //GPK8
+         __raw_writel(__raw_readl(S3C2416_GPKDAT) | (1 << 8), S3C2416_GPKDAT);
+      }
+      else if (arg & 0x20)
+      {
+         MSG("\n----------------> POWER WFI OFF\n");
+         __raw_writel(__raw_readl(S3C2416_GPKDAT) & ~(1 << 8), S3C2416_GPKDAT);
+      }
+
+      if ((arg & 0x200) && (arg & 0x100)) /* Bluetooth LED */
+      {
+         MSG("\n----------------> POWER BTH ON\n");
+         //GPK9
+         __raw_writel(__raw_readl(S3C2416_GPKDAT) | (1 << 9), S3C2416_GPKDAT);
+      }
+      else if (arg & 0x200)
+      {
+         MSG("\n----------------> POWER BTH OFF\n");
+         __raw_writel(__raw_readl(S3C2416_GPKDAT) & ~(1 << 9), S3C2416_GPKDAT);
+      }
+
+      ret = 0;
+
+      break;
+      
+   case CYIO_CTL_USB_STATUS:
+      value = gpio_get_value(S3C2410_GPG1);
+
+      put_user(value, (unsigned long __user *)arg);
+      ret = 0;
+      break;
+
+   case CYIO_CTL_SD_STATUS:
+      value = gpio_get_value(S3C2410_GPF1);
+
+      put_user(value, (unsigned long __user *)arg);
+      ret = 0;
+      break;      
+   }
+   return ret;
+}
+// ===========================================================================
+static struct file_operations s_io_fops =
+{
+  owner:    THIS_MODULE,
+  read:     ev_read,
+  ioctl:    ev_ioctl,
+  open:     ev_open,
+  release:  ev_release,
+};
+
+gstatic struct miscdevice s_ev_dev =
+{
+   .minor = 250,
+   .name = "cyio",
+   .fops =  &s_ev_fops,
+};
+// ===========================================================================
+// ---------------------------------------------------------------------------
+static int io_probe(struct platform_device *dev)
+{
+  return 0;
+}
+// ---------------------------------------------------------------------------
+static int io_remove(struct platform_device *dev)
+{
+  misc_deregister(&s_ev_dev);
+  return 0;
+}
+// --------------------------------------------------------------------------
+static int io_resume(struct platform_device *dev)
+{
+  return 0;
+}
+
+// ---------------------------------------------------------------------------
+static struct platform_driver cyev_driver =
+{
+  .driver =
+  {
+    .name   = "cyevent",
+    .owner  = THIS_MODULE,
+  },
+  .probe    = ev_probe,
+  .remove   = ev_remove,
+  .suspend  = NULL,
+  .resume   = ev_resume,
+};
+// ---------------------------------------------------------------------------
+// ===========================================================================
+static int __init cyEv_init(void)
+{
+  if (misc_register(&s_ev_dev))
+    return -EBUSY;
+
+  platform_driver_register(&cyev_driver);
+
+  return 0;
+}
+// ---------------------------------------------------------------------------
+static void __exit cyEv_exit(void)
+{
+  platform_driver_unregister(&cyev_driver);
+
+  misc_deregister(&s_ev_dev);
+}
+
+// ---------------------------------------------------------------------------
+module_init(cyEv_init);
+module_exit(cyEv_exit);
+// ---------------------------------------------------------------------------
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Bookeen <developers@bookeen.com>");
+MODULE_DESCRIPTION("Cybook Event Manager");
+MODULE_VERSION("3.0");
+// ===========================================================================

+ 13 - 13
drivers/input/misc/orizon_tilt.c

@@ -24,8 +24,8 @@
 
 #include <linux/cyio.h>
 
-//#define DEBUG_MESSAGES
-//#define DEBUG_TRACEFUNC
+#define DEBUG_MESSAGES
+#define DEBUG_TRACEFUNC
 //#define DBG_IRQ
 
 #define MODULE_NAME "CYB_TILT"
@@ -225,20 +225,20 @@ static irqreturn_t orizontilt_interrupt(int irq, void *dev_id)
    switch(tmpReg)
    {
    case 0x00: /*  90 */
-         calcTilt =  90;
-         break;
+      calcTilt =  90;
+      break;
 
-      case 0x02: /*   0 */
-         calcTilt =   0;
-         break;
+   case 0x02: /*   0 */
+      calcTilt =   0;
+      break;
 
-      case 0x01: /* 180 */
-         calcTilt = 180;
-         break;
+   case 0x01: /* 180 */
+      calcTilt = 180;
+      break;
 
-      case 0x03: /* 270 */
-         calcTilt = 270;
-         break;
+   case 0x03: /* 270 */
+      calcTilt = 270;
+      break;
    }
    DBG("New Orientation is: %lu", calcTilt);
    if (calcTilt != OrizonTilt_CurrentDirection)

+ 32 - 11
drivers/input/touchscreen/orizon_ts.c

@@ -24,7 +24,7 @@
 #include <cybook.h>
 #include <linux/cyio.h>
 
-#define DEBUG_MESSAGES
+//#define DEBUG_MESSAGES
 //#define DEBUG_TRACEFUNC
 
 #define MODULE_NAME "ORIZON-TS"
@@ -299,12 +299,13 @@ static int ots_detect (struct i2c_adapter *adapter, int address, int kind)
       ots_setDeviceParameters(INT_MODE, X_SENS, Y_SENS);
       /* Now we are sure that the driver init successfully, then aquire the IRQ */
       set_irq_type(IRQ_EINT2, IRQT_FALLING);
-      
+
       if ( request_irq(IRQ_EINT2, ots_interrupt, SA_SHIRQ, "orizon_ts", &ots_client) )
       {
          printk(KERN_ERR "failed to  get interrupt resouce at IRQ_EINT2.\n");
          goto exit_kfree;
       }
+      enable_irq_wake(IRQ_EINT2);
    }
 
    goto exit;
@@ -352,25 +353,45 @@ static int ots_resume (struct device *dev)
 /******************************************************************************/
 /********************** Interrupt Related functions ***************************/
 /******************************************************************************/
+static int oldX = 0, oldY = 0;
+
 static void ots_checkWorkFunction (struct work_struct *work)
 {
    unsigned long x1, y1, x2, y2;
    FUNC_IN();
    
    /* Here do what the interrupt should... (ie read touch values) */
-   x1 = i2c_smbus_read_byte_data(ots_client, 0);
-   x1 |= i2c_smbus_read_byte_data(ots_client, 1) << 8;
 
-   y1 = i2c_smbus_read_byte_data(ots_client, 2);
-   y1 |= i2c_smbus_read_byte_data(ots_client, 3) << 8;
+   /* TODO: I reversed the X / Y axis to match old driver and revese the X value */
+   y1 = i2c_smbus_read_byte_data(ots_client, 0);
+   y1 |= i2c_smbus_read_byte_data(ots_client, 1) << 8;
 
-   x2 = i2c_smbus_read_byte_data(ots_client, 4);
-   x2 |= i2c_smbus_read_byte_data(ots_client, 5) << 8;
+   x1 = i2c_smbus_read_byte_data(ots_client, 2);
+   x1 |= i2c_smbus_read_byte_data(ots_client, 3) << 8;
 
-   y2 = i2c_smbus_read_byte_data(ots_client, 6);
-   y2 |= i2c_smbus_read_byte_data(ots_client, 7) << 8;
+   y2 = i2c_smbus_read_byte_data(ots_client, 4);
+   y2 |= i2c_smbus_read_byte_data(ots_client, 5) << 8;
 
-   DBG("x1: %lu\ty1: %lu\ty1: %lu\ty2: %lu", x1, y1, x2, y2);
+   x2 = i2c_smbus_read_byte_data(ots_client, 6);
+   x2 |= i2c_smbus_read_byte_data(ots_client, 7) << 8;
+
+   DBG("x1: %lu\ty1: %lu\tx2: %lu\ty2: %lu", x1, y1, x2, y2);
+
+   if ((x1 == 0) && (y1 == 0))
+   { /* We assume that this is a finger up event */
+      if ( Cyio_PushEvent('R', 1) >= 0 )
+      {
+         Cyio_PushEvent((oldX >> 8) & 0xFF, 0);
+          Cyio_PushEvent((oldX >> 0) & 0xFF, 0);
+          Cyio_PushEvent((oldY >> 8) & 0xFF, 0);
+          Cyio_PushEvent((oldY >> 0) & 0xFF, 0);
+      }
+   }
+   else
+   {
+      oldX = 600 - x1;
+      oldY = y1;
+   }
 
    /* Say I get the data */
    ots_ackInterrupt();

+ 46 - 3
drivers/mmc/card/block.c

@@ -40,6 +40,8 @@
 
 #include "queue.h"
 
+#include <cybook.h>
+
 /*
  * max 8 partitions per card
  */
@@ -48,6 +50,27 @@
 
 static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))];
 
+/* [MTR] Hackish, but needed:
+ * We need a way to not expose the last X MB of the MoviNand to protect the
+ * bootloader from unexpected erase. So we pass a parameter from the BL
+ * that will say that we allow us to access the BL partition
+ *
+ * TODO: This should be put somewhere else...
+ */
+static int __init get_movirestrict_mode(char *str)
+{
+   int ints[2];
+   str = get_options(str, 2, ints);
+   if (ints[1] == 0xd34db33f)
+   {
+      platform_capability |= PLAT_CAP_UNRESTRICT;
+   }
+   printk(KERN_ERR "movirest = 0x%08X", ints[1]);
+   return 1;
+}
+__setup("movirest=", get_movirestrict_mode);
+
+
 /*
  * There is one mmc_blk_data per slot.
  */
@@ -425,6 +448,9 @@ static inline int mmc_blk_readonly(struct mmc_card *card)
 	       !(card->csd.cmdclass & CCC_BLOCK_WRITE);
 }
 
+/* We will remove 10 MB of block, and block are 512 byte long */
+#define BLK_COUNT_REMOVE ((10 * 1024 * 1024) / 512)
+
 static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
 {
 	struct mmc_blk_data *md;
@@ -502,14 +528,31 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
 		 * The EXT_CSD sector count is in number or 512 byte
 		 * sectors.
 		 */
-		set_capacity(md->disk, card->ext_csd.sectors);
+        if ((devidx == 0) && (GET_CAPABILITY(PLAT_CAP_UNRESTRICT) != 0))
+           /* We are on the Movi Device and not booting in "full mode" */
+        { 
+           set_capacity(md->disk, card->ext_csd.sectors);
+        }
+        else /* remove 10MB to the sector counts */
+        {
+           set_capacity(md->disk, card->ext_csd.sectors - BLK_COUNT_REMOVE);
+        }
 	} else {
 		/*
 		 * The CSD capacity field is in units of read_blkbits.
 		 * set_capacity takes units of 512 bytes.
 		 */
-		set_capacity(md->disk,
+        if ((devidx == 0) && (GET_CAPABILITY(PLAT_CAP_UNRESTRICT) != 0))
+           /* We are on the Movi Device and not booting in "full mode" */
+        {
+           set_capacity(md->disk,
 			card->csd.capacity << (card->csd.read_blkbits - 9));
+        }
+        else /* remove 10MB to the sector counts */
+        {
+		set_capacity(md->disk,
+			(card->csd.capacity << (card->csd.read_blkbits - 9)) - BLK_COUNT_REMOVE);
+        }
 	}
 	return md;
 
@@ -566,7 +609,7 @@ static int mmc_blk_probe(struct mmc_card *card)
 	if (err)
 		goto out;
 
-	printk(KERN_INFO "%s: %s %s %lluKiB %s\n",
+	printk(KERN_INFO "%s: %s %s %lluKB %s\n",
 		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
 		(unsigned long long)(get_capacity(md->disk) >> 1),
 		md->read_only ? "(ro)" : "");

+ 1 - 0
drivers/mmc/host/s3c-hsmmc.c

@@ -2328,6 +2328,7 @@ static int s3c_hsmmc_probe (struct platform_device *pdev)
 		ret = request_irq(host->irq_cd, s3c_hsmmc_irq_cd, 0, DRIVER_NAME, host);
 		if (ret)
 			goto untasklet;
+          enable_irq_wake(host->irq_cd);
 	}
 #endif
 

+ 46 - 7
drivers/usb/gadget/file_storage.c

@@ -350,8 +350,10 @@ MODULE_LICENSE("Dual BSD/GPL");
 static struct {
 	char		*file[MAX_LUNS];
 	int		ro[MAX_LUNS];
+     int		status[MAX_LUNS];
 	int		num_filenames;
 	int		num_ros;
+     int		num_status;
 	unsigned int	nluns;
 
 	int		removable;
@@ -362,7 +364,8 @@ static struct {
 	unsigned short	vendor;
 	unsigned short	product;
 	unsigned short	release;
-	unsigned int	buflen;
+     char            serial[12];
+	unsigned int	 buflen;
 
 	int		transport_type;
 	char		*transport_name;
@@ -378,6 +381,7 @@ static struct {
 	.product		= DRIVER_PRODUCT_ID,
 	.release		= 0xffff,	// Use controller chip type
 	.buflen			= 16384,
+     .serial             = "CYBOR10",
 	};
 
 
@@ -388,6 +392,9 @@ MODULE_PARM_DESC(file, "names of backing files or devices");
 module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO);
 MODULE_PARM_DESC(ro, "true to force read-only");
 
+module_param_array_named(status, mod_data.status, int, &mod_data.num_status, S_IRUGO);
+MODULE_PARM_DESC(status, "get lun(s) status");
+
 module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
 MODULE_PARM_DESC(luns, "number of LUNs");
 
@@ -421,6 +428,9 @@ MODULE_PARM_DESC(release, "USB release number");
 module_param_named(buflen, mod_data.buflen, uint, S_IRUGO);
 MODULE_PARM_DESC(buflen, "I/O buffer size");
 
+module_param_named(serial, mod_data.serial, charp, S_IRUGO);
+MODULE_PARM_DESC(serial, "Device serial number");
+
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */
 
 
@@ -560,6 +570,8 @@ struct interrupt_data {
 
 
 struct lun {
+     u8             id;
+     
 	struct file	*filp;
 	loff_t		file_length;
 	loff_t		num_sectors;
@@ -569,6 +581,8 @@ struct lun {
 	unsigned int	registered : 1;
 	unsigned int	info_valid : 1;
 
+     unsigned int   status : 1;
+
 	u32		sense_data;
 	u32		sense_data_info;
 	u32		unit_attention_data;
@@ -2061,8 +2075,8 @@ static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 /* Qisda, howard.hsu, 2010/01/26, change usb device name { */
 	//static char vendor_id[] = "Linux   ";
 	//static char product_id[] = "File-Stor Gadget";
-	static char vendor_id[] = "e-Book ";
-	static char product_id[] = "Reader";
+	static char vendor_id[] = "Bookeen ";
+	static char product_id[] = "Cybook Orizon";
 /* } Qisda, howard.hsu, 2010/01/26, change usb device name */
 	if (!fsg->curlun) {		// Unsupported LUNs are okay
 		fsg->bad_lun_okay = 1;
@@ -2078,7 +2092,7 @@ static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 	buf[3] = 2;		// SCSI-2 INQUIRY data format
 	buf[4] = 31;		// Additional length
 				// No special options
-	sprintf(buf + 8, "%-8s%-16s%04x", vendor_id, product_id,
+	sprintf(buf + 8, "%-8s%-13s-%-2s%04x", vendor_id, product_id, (fsg->curlun->id==1)?"FD":"SD",
 			mod_data.release);
 	return 36;
 }
@@ -3625,6 +3639,12 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, char
 	return rc;
 }
 
+static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lun	*curlun = dev_to_lun(dev);
+
+	return sprintf(buf, "%d\n", curlun->status);
+}
 
 static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
@@ -3650,6 +3670,12 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const
 	return rc;
 }
 
+static ssize_t store_status(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+
+	return 0;
+}
+
 static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct lun	*curlun = dev_to_lun(dev);
@@ -3687,6 +3713,7 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, con
 /* The write permissions and store_xxx pointers are set in fsg_bind() */
 static DEVICE_ATTR(ro, 0444, show_ro, NULL);
 static DEVICE_ATTR(file, 0444, show_file, NULL);
+static DEVICE_ATTR(status, 0444, show_status, NULL);
 
 
 /*-------------------------------------------------------------------------*/
@@ -3722,6 +3749,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
 		if (curlun->registered) {
 			device_remove_file(&curlun->dev, &dev_attr_ro);
 			device_remove_file(&curlun->dev, &dev_attr_file);
+               device_remove_file(&curlun->dev, &dev_attr_status);
 			device_unregister(&curlun->dev);
 			curlun->registered = 0;
 		}
@@ -3862,8 +3890,10 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 
 	if (mod_data.removable) {	// Enable the store_xxx attributes
 		dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0644;
+          dev_attr_status.attr.mode = 0444;
 		dev_attr_ro.store = store_ro;
 		dev_attr_file.store = store_file;
+          dev_attr_status.store = store_status;
 	}
 
 	/* Find out how many LUNs there should be */
@@ -3902,10 +3932,13 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 		if ((rc = device_create_file(&curlun->dev,
 					&dev_attr_ro)) != 0 ||
 				(rc = device_create_file(&curlun->dev,
-					&dev_attr_file)) != 0) {
+					&dev_attr_file)) != 0 ||
+				(rc = device_create_file(&curlun->dev,
+					&dev_attr_status)) != 0) {
 			device_unregister(&curlun->dev);
 			goto out;
 		}
+          curlun->id = i;
 		curlun->registered = 1;
 		kref_get(&fsg->ref);
 
@@ -4001,15 +4034,21 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 	/* This should reflect the actual gadget power source */
 	usb_gadget_set_selfpowered(gadget);
 
+#if 0
 	snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
 			init_utsname()->sysname, init_utsname()->release,
 			gadget->name);
-
+#else
+     snprintf(manufacturer, sizeof manufacturer, "Bookeen");
+#endif
 	/* On a real device, serial[] would be loaded from permanent
 	 * storage.  We just encode it from the driver version string. */
 	for (i = 0; i < sizeof(serial) - 2; i += 2) {
+#if 0
 		unsigned char		c = DRIVER_VERSION[i / 2];
-
+#else
+          unsigned char		c = mod_data.serial[i / 2];
+#endif
 		if (!c)
 			break;
 		sprintf(&serial[i], "%02X", c);

+ 1 - 1
drivers/video/auofb.c

@@ -3642,7 +3642,7 @@ static struct sleep_save lcd_save[] = {
 
 static int auofb_suspend(struct platform_device *dev, pm_message_t state)
 {
-#if 0
+#if 1
 	if(is_Epaper_Write_Ready())
 	{
 		//Suspend LCD controller

+ 235 - 5
drivers/video/epaper.c

@@ -155,6 +155,11 @@
 #define PROGRESS_BAR_90_H		(60)
 #define PROGRESS_BAR_FRAME_LINE_W	8
 
+/* Compat tools */
+#define tcon_ndelay nDelay
+static int tcon_inPortraitMode = 0;
+#define tcon_set_write_to_data _SetWriteToData
+/*******/
 
 typedef enum {
 	EN_I80_NONE = -1,
@@ -218,6 +223,7 @@ static void __uDelay(unsigned long uTime)
 		nDelay(75);
 }
 
+void Epaper_Set_I80_Default_Speed(I80_HWE_SPEED_MODE i80_speed, unsigned short w, unsigned short h);
 
 void Epaper_Change_I80_Speed(I80_HWE_SPEED_MODE i80_speed, unsigned short w, unsigned short h)
 {
@@ -894,7 +900,10 @@ static inline void s3c2416_i80_write(int data)
 	tmp = __raw_readl(rSIFCCON0); // nWE enable
 	tmp |= SYS_WR_CON;
 	__raw_writel(tmp, rSIFCCON0);
-	
+
+      if ( !tcon_inPortraitMode )
+      tcon_ndelay(25);
+
 	__raw_writel(data, rSIFCCON1); //rSIFCCON1 = CMD;
 
 	tmp = __raw_readl(rSIFCCON0); // nWE disables
@@ -2263,9 +2272,8 @@ enum InfoLevel
 	INFO_VERBOSE,
 };
 
-
-//#define EPAPER_DEBUG
-//#define VERBOSE_LEVEL INFO_VERBOSE
+#define EPAPER_DEBUG
+#define VERBOSE_LEVEL INFO_VERBOSE
 
 
 #ifndef VERBOSE_LEVEL
@@ -2290,5 +2298,227 @@ static int _dbgFL = 0;
 #endif
 
 
-/* [/MTR] */
+//#define GET_COMMAND_PARAM_NUM(command) ((command >> 20) & 0x0F)
+//#define GET_COMMAND_HAVE_DATA(command) ((command >> 28) & 0x01)
+//#define GET_COMMAND_NEED_WAIT(command) ((command >> 29) & 0x01)
+/* On the i80 port,
+ * i80    TCON
+ * -----------
+ * RS  -> D/C
+ * CS0 -> CSEL
+ * nWE -> HWE
+ * OE  -> HRD
+ */
+static inline void _InitI80Interface(void)
+{
+   unsigned long tmp;
+   FUNC_IN();
+   tmp  = __raw_readl(rSYSIFCON0); //polarity of RS, set 1 for normal access
+   tmp |= (1<<2);
+   __raw_writel(tmp, rSYSIFCON0);
+
+   tmp  = __raw_readl(rSIFCCON0); // command mode enable
+   tmp |= (1<<0);
+   __raw_writel(tmp, rSIFCCON0);
+   FUNC_OUT();
+}
+
+static inline void _DeinitI80Interface(void)
+{
+   unsigned long tmp;
+   FUNC_IN();
+   tmp  = __raw_readl(rSIFCCON0); // command mode disable
+   tmp &= ~(1<<0);
+   __raw_writel(tmp, rSIFCCON0);
+   FUNC_OUT();
+}
 
+static inline void _SetWriteToData(void)
+{
+   unsigned long tmp;
+   FUNC_IN();
+   tmp  = __raw_readl(rSIFCCON0);
+   // RS high -> D/nC set Data mode
+   tmp |= (1<<1);
+   __raw_writel(tmp, rSIFCCON0);
+
+   __uDelay(1);
+   FUNC_OUT();
+}
+static inline void _SetWriteToCommand(void)
+{
+   unsigned long tmp;
+   FUNC_IN();
+   tmp = __raw_readl(rSIFCCON0);
+   // RS low -> D/nC set Command mode
+   tmp &= ~(1<<1);
+   __raw_writel(tmp, rSIFCCON0);
+
+   __uDelay(1);
+   FUNC_OUT();
+}
+static inline void _EnableWrite(void)
+{
+   unsigned long tmp;
+   FUNC_IN();
+   tmp = __raw_readl(rSIFCCON0);
+   // nWE -> HWE enable
+   tmp |= (1<<6);
+   __raw_writel(tmp, rSIFCCON0);
+
+   __uDelay(1);
+   FUNC_OUT();
+}
+static inline void _DisableWrite(void)
+{
+   unsigned long tmp;
+   FUNC_IN();
+   tmp = __raw_readl(rSIFCCON0);
+   // nWE -> HWE disable
+   tmp &= ~(1<<6);
+   __raw_writel(tmp, rSIFCCON0);
+   __uDelay(1);
+   FUNC_OUT();
+}
+static inline void _EnableRead(void)
+{
+   unsigned long tmp;
+   FUNC_IN();
+   tmp = __raw_readl(rSIFCCON0); // nRD enable
+   tmp |= SYS_OE_CON;
+   __raw_writel(tmp, rSIFCCON0);
+   __uDelay(1);
+   FUNC_OUT();
+}
+static inline void _DisableRead(void)
+{
+   unsigned long tmp;
+   FUNC_IN();
+   tmp = __raw_readl(rSIFCCON0); // nRD disable
+   tmp &= ~SYS_OE_CON;
+   __raw_writel(tmp, rSIFCCON0);
+   __uDelay(1);
+   FUNC_OUT();
+}
+static inline void _SelectChip(void)
+{
+   unsigned long tmp;
+   FUNC_IN();
+   tmp = __raw_readl(rSIFCCON0); // Chip Select
+   tmp |= (1<<8);
+   __raw_writel(tmp, rSIFCCON0);
+   __uDelay(1);
+   FUNC_OUT();
+}
+static inline void _UnselectChip(void)
+{
+   unsigned long tmp;
+   FUNC_IN();
+   tmp = __raw_readl(rSIFCCON0); // nCS0(Main) enable
+   tmp &= ~(1<<8);
+   __raw_writel(tmp, rSIFCCON0);
+   __uDelay(1);
+   FUNC_OUT();
+}
+
+#define tcon_i80bus_write s3c2416_i80_write
+
+
+int Epaper_sendCommandStart(sAUOCommand *cmd)
+{
+   FUNC_IN();
+   INFOL(INFO_VERBOSE,("cmd #%08lX", cmd->cmd));
+   /* First: verify that the K1900 is ready */
+
+   INFOL(INFO_VERBOSE, ("/* First: verify that the K1900 is ready */"));
+   if (GET_COMMAND_NEED_WAIT(cmd->cmd) != 0x00)
+   {
+      INFOL(INFO_VERBOSE, ("Wait for non BUSY..."));
+      is_Epaper_Write_Ready();
+   }
+
+   if (cmd->cmd == AUOCMD_INIT_SET)
+   {
+   	tcon_inPortraitMode = ~(cmd->params[0]) & (0x1 << 10);
+        if (tcon_inPortraitMode)
+           Epaper_Change_I80_Speed(EN_I80_PORTRAIT, 800, 600);
+        else
+           Epaper_Change_I80_Speed(EN_I80_LANDSCAPE, 600, 800);
+   	INFOL(INFO_VERBOSE, ("Rotation set to 0x%08X...", tcon_inPortraitMode));
+   }
+
+   /* Second: init the i80 interface */
+   INFOL(INFO_VERBOSE, ("/* Second: init the i80 interface */"));
+   //tcon_i80bus_init_interface();
+   
+   /* Third: Select the chip and set to Command mode */
+   INFOL(INFO_VERBOSE, ("/* Third: Select the chip and set to Command mode */"));
+   _SelectChip();
+   _SetWriteToCommand();
+
+   /* Fourth: Send command */
+   INFOL(INFO_VERBOSE, ("/* Fourth: Send command */"));
+   tcon_i80bus_write(cmd->cmd & 0xFFFF); /* This function already manage
+                                          * no need to do it here. */
+
+   /* Sixth: If parameters is needed, send them */
+   INFOL(INFO_VERBOSE, ("/* Sixth: If parameters is needed, send them */"));
+   if (GET_COMMAND_PARAM_NUM(cmd->cmd) > 0)
+   {
+      int i, paramNumbers = GET_COMMAND_PARAM_NUM(cmd->cmd);
+
+      INFOL(INFO_VERBOSE, ("YES! We have %d parameters", paramNumbers));
+
+      tcon_set_write_to_data();
+
+      for (i = 0; i < paramNumbers; i++)
+      {
+	      INFOL(INFO_VERBOSE, ("     parameter [%02d] = 0x%04X", i, cmd->params[i]));
+	      tcon_i80bus_write(cmd->params[i]);
+      }
+
+   }
+   FUNC_OUT();
+   return 0;
+}
+
+int Epaper_sendData(unsigned short *buffer, unsigned long bufferLen)
+{
+   /* Seventh: Send data if needed */
+   unsigned long i;
+   //FUNC_IN();
+
+   //INFOL(INFO_VERBOSE, ("Bufferlen: %ld", bufferLen));
+
+   tcon_set_write_to_data();
+
+   for (i = 0; i < bufferLen; i++)
+   {
+      tcon_i80bus_write(buffer[i]);
+   }
+   //FUNC_OUT();
+   return 0;
+}
+
+int Epaper_sendCommandEnd(sAUOCommand *cmd)
+{
+   FUNC_IN();
+
+	INFOL(INFO_VERBOSE,("cmd #%08lX START:[#%08X]", cmd->cmd, AUOCMD_DISPLAY_START));
+	if (cmd->cmd == AUOCMD_DISPLAY_START)
+	{
+		_SetWriteToCommand();
+		INFOL(INFO_VERBOSE, ("/* Eight: Send STOP command */"));
+         tcon_i80bus_write(AUOCMD_DISPLAY_STOP  & 0xFFFF);
+         _SetWriteToData();
+	}
+
+	INFOL(INFO_VERBOSE, ("/* Nineth: Close all */"));
+   _UnselectChip();
+   _DeinitI80Interface();
+   //tcon_i80bus_deinit_interface();
+
+   FUNC_OUT();
+   return 0;
+}
+/* [/MTR] */

+ 587 - 38
drivers/video/epaper/auo-tcon-k1900.c

@@ -37,12 +37,14 @@
 
 #include <cybook.h>
 
-#define DEBUG_MESSAGES
-#define DEBUG_TRACEFUNC
+//#define DEBUG_MESSAGES
+//#define DEBUG_TRACEFUNC
+//#define VERBOSE_LEVEL INFO_WARNING
+//#define DEBUG_SPI
 
 #define MODULE_NAME "AUO-TCON"
 
-#define BUSY_WAIT_TIMEOUT		(40*5*2)	//panel time out = 1s
+#define BUSY_WAIT_TIMEOUT     (40*5*2)	//panel time out = 1s
 #define SYS_WR_CON 			(1<<6)
 #define SYS_OE_CON 			(1<<7)
 
@@ -57,12 +59,12 @@ enum InfoLevel
 	INFO_ERROR = 0,
 	INFO_WARNING,
 	INFO_NORMAL,
-	INFO_DEBUG,
 	INFO_VERBOSE,
+   INFO_DEBUG,
 };
 
 # ifndef VERBOSE_LEVEL
-#  define VERBOSE_LEVEL INFO_VERBOSE
+#  define VERBOSE_LEVEL INFO_WARNING
 # endif
 
 # ifdef DEBUG_TRACEFUNC
@@ -168,7 +170,7 @@ static int _dbg_FunctionLevel = 0;
 #define VIDTCON2_LINEVAL_S			(11)
 
 static int tcon_inPortraitMode = 0;
-
+static int tcon_lastModeWas = 0;
 typedef enum Tcon_Speedclasses
 {
    EN_I80_NONE = -1,
@@ -186,6 +188,14 @@ typedef struct Tcon_SpeedclasseValue
    u8 wr_hold;
 } Tcon_SpeedclasseValue;
 
+typedef enum Tcon_PowerMode
+{
+   TCON_POWER_NORMALMODE,
+   TCON_POWER_STANDBYMODE,
+   TCON_POWER_SLEEPMODE,
+   TCON_POWER_OFF,
+} Tcon_PowerMode;
+
 static Tcon_SpeedclasseValue tcon_speedtable[] =
 {
    [EN_I80_LANDSCAPE] =
@@ -202,6 +212,7 @@ static Tcon_SpeedclasseValue tcon_speedtable[] =
       .wr_act   = 8,
       .wr_hold  = 3,
    },
+#if 1
    [EN_I80_LANDSCAPE_HANDWRITING] =
    {
       .cs_setup = 0,
@@ -216,10 +227,26 @@ static Tcon_SpeedclasseValue tcon_speedtable[] =
       .wr_act   = 6,
       .wr_hold  = 2,
    },
+#else
+   [EN_I80_PORTRAIT_HANDWRITING] =
+   {
+      .cs_setup = 0,
+      .wr_setup = 1,
+      .wr_act   = 1,
+      .wr_hold  = 0,
+   },
+   [EN_I80_LANDSCAPE_HANDWRITING] =
+   {
+      .cs_setup = 0,
+      .wr_setup = 2,
+      .wr_act   = 6,
+      .wr_hold  = 2,
+   },
+#endif   
 };
 
 static Tcon_Speedclasses tcon_currentSpeedClass = EN_I80_NONE;
-
+static Tcon_PowerMode tcon_currentPowerMode = TCON_POWER_NORMALMODE;
 // ===========================================================================
 // TCON Related functions
 // ===========================================================================
@@ -311,6 +338,8 @@ void tcon_i80bus_set_speed(Tcon_Speedclasses i80_speed,
 
    FUNC_IN();
 
+	INFOL(INFO_WARNING, ("speedclass: %d\n", i80_speed));
+
    if ( tcon_currentSpeedClass == EN_I80_NONE)
       set_clock = true;
 
@@ -318,7 +347,7 @@ void tcon_i80bus_set_speed(Tcon_Speedclasses i80_speed,
 
    if (set_clock == true)
    {
-      INFOL(INFO_VERBOSE, ("Will set clocks..."));
+      INFOL(INFO_DEBUG, ("Will set clocks..."));
 
       tmp = __raw_readl(S3C_VIDCON0);
       tmp = VIDCON0_S_CPU_IF_MAIN | VIDCON0_S_RGB_PAR | \
@@ -371,8 +400,12 @@ static inline void tcon_i80bus_write (int data)
    tmp |= SYS_WR_CON;
    __raw_writel(tmp, S3C_SIFCCON0);
 
-   if ( !tcon_inPortraitMode )
+   if (( !tcon_inPortraitMode ) && (tcon_lastModeWas != 4))
       tcon_ndelay(25);
+	else if (( tcon_inPortraitMode ) && (tcon_lastModeWas == 4))
+      tcon_ndelay(15);
+
+
 
    __raw_writel(data, S3C_SIFCCON1); //rSIFCCON1 = CMD;
 
@@ -381,6 +414,49 @@ static inline void tcon_i80bus_write (int data)
    __raw_writel(tmp, S3C_SIFCCON0);
 }
 
+static inline void tcon_i80bus_write_LUT(int data)
+{
+	int tmp;
+
+	tcon_delay(1);
+	tmp = __raw_readl(S3C_SIFCCON0); // nWE enable
+	tmp |= SYS_WR_CON;
+	__raw_writel(tmp, S3C_SIFCCON0);
+
+	tcon_delay(1);
+
+	__raw_writel(data, S3C_SIFCCON1); //rSIFCCON1 = CMD;
+
+	tcon_delay(1);
+
+	tmp = __raw_readl(S3C_SIFCCON0); // nWE disable
+	tmp &= ~SYS_WR_CON;
+	__raw_writel(tmp, S3C_SIFCCON0);
+
+
+}
+
+static inline void tcon_i80bus_read (unsigned short *data)
+{
+   int tmp;
+
+   tcon_delay(1);
+
+   tmp = __raw_readl(S3C_SIFCCON0); // nRD enable
+   tmp |= SYS_OE_CON;
+   __raw_writel(tmp, S3C_SIFCCON0);
+
+   tcon_delay(1);
+
+   *data = __raw_readl(S3C_SIFCCON2); //CMD = rSIFCCON2;
+
+   tcon_delay(1);
+
+   tmp = __raw_readl(S3C_SIFCCON0); // nRD disable
+   tmp &= ~SYS_OE_CON;
+   __raw_writel(tmp, S3C_SIFCCON0);
+}
+
 static inline void tcon_set_write_to_data(void)
 {
    unsigned long tmp;
@@ -469,55 +545,108 @@ static inline void tcon_unselect_chip(void)
    FUNC_OUT();
 }
 
+static inline void tcon_set_power_on(void)
+{
+   unsigned long tmp = __raw_readl(S3C2410_GPBDAT);
+   tmp |= (1 << 3);
+   __raw_writel(tmp, S3C2410_GPBDAT);
+
+   tcon_currentPowerMode = TCON_POWER_NORMALMODE;
+}
+
+static inline void tcon_set_power_off(void)
+{
+   unsigned long tmp = __raw_readl(S3C2410_GPBDAT);
+   tmp &= ~(1 << 3);
+   __raw_writel(tmp, S3C2410_GPBDAT);
+   
+   tcon_currentPowerMode = TCON_POWER_OFF;
+}
+
+
 int tcon_send_command_start(sAUOCommand *cmd)
 {
    FUNC_IN();
-   INFOL(INFO_VERBOSE,("cmd #%08lX", cmd->cmd));
+   INFOL(INFO_DEBUG,("cmd #%08lX", cmd->cmd));
    /* First: verify that the K1900 is ready */
 
-   INFOL(INFO_VERBOSE, ("/* First: verify that the K1900 is ready */"));
+   INFOL(INFO_DEBUG, ("/* First: verify that the K1900 is ready */"));
    if (GET_COMMAND_NEED_WAIT(cmd->cmd) != 0x00)
    {
-      INFOL(INFO_VERBOSE, ("Wait for non BUSY..."));
+      INFOL(INFO_DEBUG, ("Wait for non BUSY..."));
       tcon_wait_ready();
    }
 
-   if (cmd->cmd == AUOCMD_INIT_SET)
+   if (cmd->cmd == AUOCMD_STANDBY)
+      tcon_currentPowerMode = TCON_POWER_STANDBYMODE;
+   else if (cmd->cmd == AUOCMD_WAKEUP)
+      tcon_currentPowerMode = TCON_POWER_NORMALMODE;
+   else if (cmd->cmd == AUOCMD_INIT_SET)
    {
    	tcon_inPortraitMode = ~(cmd->params[0]) & (0x1 << 10);
-        if (tcon_inPortraitMode)
-           tcon_i80bus_set_speed(EN_I80_PORTRAIT, 800, 600, false);
-        else
-           tcon_i80bus_set_speed(EN_I80_LANDSCAPE, 600, 800, false);
-   	INFOL(INFO_VERBOSE, ("Rotation set to 0x%08X...", tcon_inPortraitMode));
+   	if (tcon_lastModeWas != 4)
+   	{
+	      if (tcon_inPortraitMode)
+   	      tcon_i80bus_set_speed(EN_I80_PORTRAIT, 800, 600, false);
+	      else
+	         tcon_i80bus_set_speed(EN_I80_LANDSCAPE, 600, 800, false);
+	   }
+	   else
+	   {
+   	   if (tcon_inPortraitMode)
+	         tcon_i80bus_set_speed(EN_I80_PORTRAIT_HANDWRITING, 800, 600, false);
+         else
+            tcon_i80bus_set_speed(EN_I80_LANDSCAPE_HANDWRITING, 600, 800, false);	   
+	   }
+   	INFOL(INFO_DEBUG, ("Rotation set to 0x%08X...", tcon_inPortraitMode));
+   }   
+   else if (cmd->cmd == AUOCMD_DISPLAY_START)
+   {
+    	INFOL(INFO_VERBOSE, ("Display Start (lastMode: %d)...", tcon_lastModeWas));
+   	if (((cmd->params[0] >> 12) & 0x07) == 4) /* Handwriting mode... */
+   	{
+ 	   	INFOL(INFO_VERBOSE, ("Mode 4"));
+   	   if (tcon_inPortraitMode)
+	         tcon_i80bus_set_speed(EN_I80_PORTRAIT_HANDWRITING, 800, 600, false);
+         else
+            tcon_i80bus_set_speed(EN_I80_LANDSCAPE_HANDWRITING, 600, 800, false);
+      }
+      else if (tcon_lastModeWas == 4)
+      {
+      	INFOL(INFO_VERBOSE, ("--- NOT --- mode 4 (%d)", ((cmd->params[0] >> 12) & 0x07)));
+         if (tcon_inPortraitMode)
+	         tcon_i80bus_set_speed(EN_I80_PORTRAIT, 800, 600, false);
+         else
+            tcon_i80bus_set_speed(EN_I80_LANDSCAPE, 600, 800, false);
+      }            
+      tcon_lastModeWas = ((cmd->params[0] >> 12) & 0x07);
    }
-
    /* Second: init the i80 interface */
-   INFOL(INFO_VERBOSE, ("/* Second: init the i80 interface */"));
+   INFOL(INFO_DEBUG, ("/* Second: init the i80 interface */"));
    tcon_i80bus_init_interface();
    /* Third: Select the chip and set to Command mode */
-   INFOL(INFO_VERBOSE, ("/* Third: Select the chip and set to Command mode */"));
+   INFOL(INFO_DEBUG, ("/* Third: Select the chip and set to Command mode */"));
    tcon_select_chip();
    tcon_set_write_to_command();
 
    /* Fourth: Send command */
-   INFOL(INFO_VERBOSE, ("/* Fourth: Send command */"));
+   INFOL(INFO_DEBUG, ("/* Fourth: Send command */"));
    tcon_i80bus_write(cmd->cmd & 0xFFFF); /* This function already manage
                                           * no need to do it here. */
 
    /* Sixth: If parameters is needed, send them */
-   INFOL(INFO_VERBOSE, ("/* Sixth: If parameters is needed, send them */"));
+   INFOL(INFO_DEBUG, ("/* Sixth: If parameters is needed, send them */"));
    if (GET_COMMAND_PARAM_NUM(cmd->cmd) > 0)
    {
       int i, paramNumbers = GET_COMMAND_PARAM_NUM(cmd->cmd);
 
-      INFOL(INFO_VERBOSE, ("YES! We have %d parameters", paramNumbers));
+      INFOL(INFO_DEBUG, ("YES! We have %d parameters", paramNumbers));
 
       tcon_set_write_to_data();
 
       for (i = 0; i < paramNumbers; i++)
       {
-	      INFOL(INFO_VERBOSE, ("     parameter [%02d] = 0x%04X", i, cmd->params[i]));
+	      INFOL(INFO_DEBUG, ("     parameter [%02d] = 0x%04X", i, cmd->params[i]));
 	      tcon_i80bus_write(cmd->params[i]);
       }
 
@@ -544,20 +673,60 @@ int tcon_send_data(unsigned short *buffer, unsigned long bufferLen)
    return 0;
 }
 
+int tcon_send_lut_data(unsigned short *buffer, unsigned long bufferLen)
+{
+   /* Seventh: Send data if needed */
+   unsigned long i;
+   FUNC_IN();
+
+   INFOL(INFO_DEBUG, ("Bufferlen: %ld", bufferLen));
+
+   tcon_set_write_to_data();
+
+   for (i = 0; i < bufferLen; i++)
+   {
+      tcon_delay(1);
+      tcon_wait_ready();
+      tcon_delay(1);
+      tcon_i80bus_write_LUT(buffer[i]);
+   }
+   INFOL(INFO_DEBUG, ("Done."));
+   FUNC_OUT();
+   return 0;
+}
+
+
+int tcon_read_data(unsigned short *buffer, unsigned long bufferLen)
+{
+   unsigned long i;
+   //FUNC_IN();
+
+   //INFOL(INFO_VERBOSE, ("Bufferlen: %ld", bufferLen));
+
+   tcon_set_write_to_data();
+
+   for (i = 0; i < bufferLen; i++)
+   {
+      tcon_i80bus_read(&(buffer[i]));
+   }
+   //FUNC_OUT();
+   return 0;
+}
+
 int tcon_send_command_end(sAUOCommand *cmd)
 {
    FUNC_IN();
 
-	INFOL(INFO_VERBOSE,("cmd #%08lX START:[#%08X]", cmd->cmd, AUOCMD_DISPLAY_START));
+	INFOL(INFO_DEBUG,("cmd #%08lX START:[#%08X]", cmd->cmd, AUOCMD_DISPLAY_START));
 	if (cmd->cmd == AUOCMD_DISPLAY_START)
 	{
 		tcon_set_write_to_command();
-		INFOL(INFO_VERBOSE, ("/* Eight: Send STOP command */"));
+		INFOL(INFO_DEBUG, ("/* Eight: Send STOP command */"));
                 tcon_i80bus_write(AUOCMD_DISPLAY_STOP  & 0xFFFF);
 		tcon_set_write_to_data();
 	}
 
-	INFOL(INFO_VERBOSE, ("/* Nineth: Close all */"));
+	INFOL(INFO_DEBUG, ("/* Nineth: Close all */"));
    tcon_unselect_chip();
    tcon_i80bus_deinit_interface();
 
@@ -565,6 +734,234 @@ int tcon_send_command_end(sAUOCommand *cmd)
    return 0;
 }
 
+// ===========================================================================
+// Bit Bang SPI Interface
+// ===========================================================================
+#define TCON_SPI_CLK S3C2410_GPE13
+#define TCON_SPI_DI S3C2410_GPE11
+#define TCON_SPI_DO S3C2410_GPE12
+#define TCON_SPI_CS S3C2410_GPL13
+
+static void tcon_spi_init(void)
+{
+   FUNC_IN();
+   /* First be sure that the Wifi is off */
+   /* GPK5 = PA 3.3V */
+   writel((readl(S3C2416_GPKDAT) & ~(1<<5)), S3C2416_GPKDAT);
+   /* GPK6 = PA 1.8V */
+   writel((readl(S3C2416_GPKDAT) & ~(1<<6)), S3C2416_GPKDAT);
+
+   /* Next, shutdown the TCON */
+   tcon_set_power_off();
+   mdelay(2000);
+
+   //GPD8, RESET
+   s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
+   s3c2410_gpio_setpin(S3C2410_GPD8, 0);
+   /* Next, Switch the SPI */
+   s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
+   s3c2410_gpio_setpin(S3C2410_GPH6, 1);
+   mdelay(200);
+
+   /* Next, init GPIOs */
+
+   /* GPL13 = SPI Chip Select */
+   s3c2410_gpio_cfgpin(S3C2410_GPL13, S3C2410_GPL13_OUTP);
+   s3c2410_gpio_setpin(S3C2410_GPL13, 1);
+
+   /* GPE11 = SPI DI */
+   s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_INP);
+   s3c2410_gpio_pullup(S3C2410_GPE11, 0);
+
+   /* GPE12 = SPI DO */
+   s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_OUTP);
+   s3c2410_gpio_setpin(S3C2410_GPE12, 1);
+
+   /* GPE13 = SPI CLK */
+   s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_OUTP);
+   s3c2410_gpio_setpin(S3C2410_GPE13, 0);
+ 
+   mdelay(50);
+
+   /* We are ready ! */
+   FUNC_OUT();
+}
+
+static void tcon_spi_deinit(void)
+{
+   FUNC_IN();
+   /* First, switch the SPI */
+   s3c2410_gpio_setpin(S3C2410_GPH6, 1);
+   
+   /* Then,  restore GPIOs */
+   s3c2410_gpio_cfgpin(S3C2410_GPL13, S3C2410_GPL13_SS0);
+   /* GPE11 = SPI DI */
+   s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_SPIMISO0);
+   /* GPE12 = SPI DO */
+   s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_SPIMOSI0);
+   /* GPE13 = SPI CLK */
+   s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_SPICLK0);
+   
+   /* Next, switch back on the TCON */
+   tcon_set_power_on();
+   s3c2410_gpio_setpin(S3C2410_GPD8, 1);
+   mdelay(100);
+   /* The calling must restore the TCON status, we only set it back on */
+   FUNC_OUT();
+}
+
+static inline unsigned char tcon_spi_read (void)
+{
+   unsigned char k,
+                 tmp_data = 0,
+                 i = 0;
+   u32           read_pin;
+#ifdef DEBUG_SPI
+   char strobe_str[9];
+   strobe_str[8] = 0;
+#endif
+   /* sure that the clock is low */
+   for ( k = 0; k < 8; k++ )
+   {
+      /* Strobe clock */
+      s3c2410_gpio_setpin(TCON_SPI_CLK, 1);
+      udelay(2);
+
+      /* Sample */
+      read_pin = s3c2410_gpio_getpin(TCON_SPI_DI);//(readl(S3C2410_GPEDAT) & (1 << 11));
+
+      if ( read_pin )
+      {
+         i = (0x80 >> k);
+         tmp_data = (tmp_data | i);
+      }
+
+#ifdef DEBUG_SPI
+      strobe_str[k] = (read_pin?'-':'_');
+#endif
+
+      /* ACK bit read */
+      s3c2410_gpio_setpin(TCON_SPI_CLK, 0);
+      udelay(2);
+   }
+
+#ifdef DEBUG_SPI
+   INFOL(INFO_VERBOSE, ("WFM:[%s] return %d", strobe_str, tmp_data));
+#endif
+
+   return (tmp_data);
+}
+
+static inline void tcon_spi_write(unsigned char value)
+{
+   unsigned char k;
+#ifdef DEBUG_SPI
+   char strobe_str[9];
+   strobe_str[8] = 0;
+#endif
+
+
+   for ( k = 0; k < 8; k++ )
+   {
+      if ( (value & 0x80) )
+         s3c2410_gpio_setpin(TCON_SPI_DO, 1);
+      else
+         s3c2410_gpio_setpin(TCON_SPI_DO, 0);
+
+#ifdef DEBUG_SPI
+      strobe_str[k] = ((value&0x80)?'-':'_');
+#endif
+
+      /* Strobe clock */
+      s3c2410_gpio_setpin(TCON_SPI_CLK, 1);
+      udelay(2);
+      s3c2410_gpio_setpin(TCON_SPI_CLK, 0);
+      udelay(2);
+
+      value = (value << 1);
+   }
+
+#ifdef DEBUG_SPI
+   INFOL(INFO_VERBOSE, ("WFM:[%s]", strobe_str));
+#endif
+}
+
+static unsigned char tcon_spi_flash_read(unsigned char value)
+{
+   unsigned char ret;
+   s3c2410_gpio_setpin(TCON_SPI_CS, 0);
+   udelay(50);
+
+   tcon_spi_write(value);
+   udelay(2);
+   ret = tcon_spi_read();
+
+   s3c2410_gpio_setpin(TCON_SPI_CS, 1);
+   udelay(50);
+   return ret;
+}
+
+static void tcon_spi_flash_write(unsigned char value)
+{
+   s3c2410_gpio_setpin(TCON_SPI_CS, 0);
+   udelay(50);
+
+   tcon_spi_write(value);
+   
+   s3c2410_gpio_setpin(TCON_SPI_CS, 1);
+   udelay(50);
+}
+
+static void tcon_spi_flash_waitready(void)
+{
+   unsigned char r_data;
+   FUNC_IN();
+   do
+   {
+      s3c2410_gpio_setpin(TCON_SPI_CS, 0);
+      udelay(50);
+      tcon_spi_write(0x05); //Write Read Status command
+      udelay(2);
+      r_data = tcon_spi_read();
+      udelay(50);
+      s3c2410_gpio_setpin(TCON_SPI_CS, 1);
+      INFOL(INFO_DEBUG, ("r_data: 0x%02x [SRWD:%c BP2:%d BP1:%d BP0:%d, WEL:%c, WIP:%c]\n", r_data,
+             (r_data & 0x80)?'E':'D',
+             (r_data & 0x10)?1:0,
+             (r_data & 0x08)?1:0,
+             (r_data & 0x04)?1:0,
+             (r_data & 0x02)?'E':'D',
+             (r_data & 0x01)?'W':'r'));
+      msleep(20);
+
+   } while ( r_data & 0x01 );
+   FUNC_OUT();
+}
+
+static void tcon_spi_flash_writepage(unsigned long addr, unsigned char *buffer, unsigned short buffer_len)
+{
+   int i;
+   FUNC_IN();
+   s3c2410_gpio_setpin(TCON_SPI_CS, 0);
+   udelay(50);
+
+   tcon_spi_write(0x02);	//Write Page Program command
+   tcon_spi_write( (addr & 0xFF0000) >> 16 );
+   tcon_spi_write( (addr & 0xFF00) >> 8 );
+   tcon_spi_write( (addr & 0xFF) );
+
+   for(i=0; i<buffer_len; i++)
+   {
+	 tcon_spi_write(buffer[i]);
+   }
+
+   s3c2410_gpio_setpin(TCON_SPI_CS, 1);
+   mdelay(10);
+
+   tcon_spi_flash_waitready();
+
+   FUNC_OUT();
+}
 
 // ===========================================================================
 // Device related functions
@@ -604,17 +1001,28 @@ int tcon_ioctl (struct inode *inode, struct file *file,
    unsigned char *user_buffer;
    unsigned long user_buflen, copysize, copysize16;
    unsigned short *ptr16;
+   unsigned long tmp;
    void __user *argp = (void __user *)arg;
+   int block_id = 0;
+   int flash_addr;
+   int ret = -EINVAL;
 
    FUNC_IN();
-
+   INFOL(INFO_VERBOSE, ("Receive IOTCL #08%X", ioctl_cmd));
    switch ( ioctl_cmd )
    {
-      /* [MTR]  */
    case IOCTL_AUO_SENDCOMMAND:
       if ( copy_from_user(&cmd, argp, sizeof (cmd)) )
          return -EFAULT;
 
+      /* Prevent to send command if the user don't provide a buffer */
+      if ((GET_COMMAND_READ_WRITE(cmd.cmd) != 0) && (cmd.datalen == 0))
+         return -EFAULT;
+
+      /* Prevent if we set data and data prt is NULL */
+      if (( GET_COMMAND_HAVE_DATA(cmd.cmd) != 0 ) && (cmd.datalen > 0) && (cmd.data == NULL))
+         return -EFAULT;
+      
       /* Now execute the command */
       tcon_send_command_start(&cmd);
 
@@ -631,16 +1039,30 @@ int tcon_ioctl (struct inode *inode, struct file *file,
 
             if ( user_buflen > sizeof (buffer) )
                copysize = sizeof (buffer);
-
-            if ( copy_from_user(buffer, user_buffer, copysize) )
-               return -EFAULT;
+            if (GET_COMMAND_READ_WRITE(cmd.cmd) == 0)
+            {  /* Write mode */
+               if ( copy_from_user(buffer, user_buffer, copysize) )
+                  return -EFAULT;
+            }
 
             copysize16 = (copysize + 1) / 2;
             //printk(KERN_ERR "cp16=%ld cp=%ld\n", copysize16, copysize);
 
             ptr16 = (unsigned short *)buffer;
-
-            tcon_send_data((unsigned short *)buffer, copysize16);
+            if (GET_COMMAND_READ_WRITE(cmd.cmd) == 0)
+            {  /* Write mode */
+               INFOL(INFO_DEBUG, ("Will send block %d", block_id++));
+               if (cmd.cmd == AUOCMD_LUT_START)
+                  tcon_send_lut_data((unsigned short *)buffer, copysize16);
+               else
+                  tcon_send_data((unsigned short *)buffer, copysize16);
+            }
+            else
+            {
+               tcon_read_data((unsigned short *)buffer, copysize16);
+               if ( copy_to_user(user_buffer, buffer, copysize) )
+                  return -EFAULT;
+            }
 
             user_buflen -= copysize;
             user_buffer += copysize;
@@ -649,12 +1071,134 @@ int tcon_ioctl (struct inode *inode, struct file *file,
 
 
       tcon_send_command_end(&cmd);
+      ret = 0;
+      break;
 
+   case IOCTL_AUO_RESET:
+      tmp = __raw_readl(S3C2410_GPDDAT); // RST_N goes to LOW
+      tmp &= ~(1 << 9);
+      __raw_writel(tmp, S3C2410_GPDDAT);
+
+      tcon_delay(5);
+
+      tmp = __raw_readl(S3C2410_GPDDAT); // RST_N goes to HIGH
+      tmp |= (1 << 9);
+      __raw_writel(tmp, S3C2410_GPDDAT);
+
+      // delay about 10ms
+      msleep(10);
+
+      tcon_i80bus_set_speed(EN_I80_PORTRAIT, 800, 600, false);
+
+      ret = 0;
+      break;
+
+   case IOCTL_AUO_SLEEP:
+      /* Only accept go to sleep if we are in standby, or else it will fail */
+      if (tcon_currentPowerMode == TCON_POWER_STANDBYMODE)
+      {
+         tcon_currentPowerMode = TCON_POWER_SLEEPMODE;
+
+         /* Set GPIO accordingly */
+         tmp = __raw_readl(S3C2410_GPBDAT);
+         tmp &= ~(1 << 1); //Set SLP_N to low
+         __raw_writel(tmp, S3C2410_GPBDAT);
+         msleep(10);
+
+         ret = 0;
+      }
+      else
+         ret = -ENAVAIL;
+
+      break;
+
+   case IOCTL_AUO_WAKEUP:
+      /* Only accept go to sleep if we are in standby, or else it will fail */
+      if (tcon_currentPowerMode == TCON_POWER_SLEEPMODE)
+      {
+         tcon_currentPowerMode = TCON_POWER_STANDBYMODE;
+         /* Set GPIO accordingly */
+         tmp = __raw_readl(S3C2410_GPBDAT);
+         tmp |= (1 << 1); //Set SLP_N to high
+         __raw_writel(tmp, S3C2410_GPBDAT);
+         msleep(10);
+         ret = 0;
+      }
+      else
+         ret = -ENAVAIL;
+      break;
+
+      
+   case IOCTL_AUO_UPDATEFW:
+      INFOL(INFO_VERBOSE, ("Starting update of TCON firmware..."));
+      if ( copy_from_user(&cmd, argp, sizeof (cmd)) )
+      {
+         INFOL(INFO_ERROR, ("Copy from User error..."));
+         return -EFAULT;
+      }
+
+      INFOL(INFO_VERBOSE, ("Starting update of TCON firmware..."));
+
+      if ((cmd.data == NULL) || (cmd.datalen == 0))
+      {
+         INFOL(INFO_ERROR, ("Parameters error..."));
+         return -EFAULT;
+      }
+
+      /* First init SPI */
+      INFOL(INFO_VERBOSE, ("Will init BitBang SPI..."));
+      tcon_spi_init();
+
+      mdelay(3000);
+      
+      flash_addr = 0;
+      INFOL(INFO_VERBOSE, ("Erasing SPI flash..."));
+      /* Erase Flash */
+      tcon_spi_flash_write(0x06);	//Setting Write Enable Latch bit
+      tcon_spi_flash_write(0x60);	//Write Chip Erase command
+      msleep(100);
+
+      tcon_spi_flash_waitready();
+
+
+
+      user_buflen = cmd.datalen;
+      user_buffer = (unsigned char *)cmd.data;
+      INFOL(INFO_VERBOSE, ("Will start write of TCON firmware..."));
+      /* Now, Write new Flash content */
+      while ( user_buflen != 0 )
+      {
+         copysize = user_buflen;
+         INFOL(INFO_DEBUG, ("Flash page @ addr 0x%08X", flash_addr));
+
+         if ( user_buflen > 256 )
+            copysize = 256;
+
+         if ( copy_from_user(buffer, user_buffer, copysize) )
+               return -EFAULT;
+
+         /* Send Buffer data */
+         tcon_spi_flash_write(0x06); /* Enable write... */
+         tcon_spi_flash_writepage(flash_addr, buffer, copysize);
+
+         flash_addr += copysize;
+         user_buflen -= copysize;
+         user_buffer += copysize;
+      }
+
+      /* Restore SPI */
+      tcon_spi_deinit();
+      break;
+
+
+   default:
+      printk(KERN_WARNING "Invalid ioctl");
+      ret = -EINVAL;
       break;
    }
 
    FUNC_OUT();
-   return -EINVAL;
+   return ret;
 }
 // ===========================================================================
 static struct file_operations s_tcon_fops =
@@ -733,13 +1277,13 @@ static int tcon_probe (struct platform_device *dev)
       tmp |= (1 << 9);
       __raw_writel(tmp, S3C2410_GPDDAT);
 
-      tmp = __raw_readl(S3C2410_GPDDAT); // goes to LOW
+      tmp = __raw_readl(S3C2410_GPDDAT); // RST_N goes to LOW
       tmp &= ~(1 << 9);
       __raw_writel(tmp, S3C2410_GPDDAT);
 
       tcon_delay(5);
 
-      tmp = __raw_readl(S3C2410_GPDDAT); // goes to HIGH
+      tmp = __raw_readl(S3C2410_GPDDAT); // RST_N goes to HIGH
       tmp |= (1 << 9);
       __raw_writel(tmp, S3C2410_GPDDAT);
 
@@ -769,6 +1313,11 @@ static int tcon_resume (struct platform_device *dev)
 {
    FUNC_IN();
 
+   if (tcon_inPortraitMode)
+      tcon_i80bus_set_speed(EN_I80_PORTRAIT, 800, 600, true);
+   else
+      tcon_i80bus_set_speed(EN_I80_LANDSCAPE, 600, 800, true);
+
    FUNC_OUT();
    return 0;
 }

+ 1 - 1
include/asm-arm/arch-s3c2410/hardware.h

@@ -119,7 +119,7 @@ extern unsigned int s3c_gpio_getpin(unsigned int pin);
  *    s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);
 */
 
-extern void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
+    extern void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
 
 extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
 

+ 84 - 0
include/asm-arm/arch-s3c2410/regs-gpio.h

@@ -27,8 +27,12 @@
 #define S3C2410_GPIO_BANKH   (32*7)
 
 #define S3C2410_GPIO_BANKJ   (32*13)
+
+#define S3C2410_GPIO_BANKK   (32*14)
+
 #define S3C2410_GPIO_BANKL   (32*15)
 
+
 #ifdef CONFIG_CPU_S3C2400
 #define S3C24XX_GPIO_BASE(x)  S3C2400_GPIO_BASE(x)
 #define S3C24XX_MISCCR        S3C2400_MISCCR
@@ -1104,6 +1108,86 @@
 #define S3C2410_GPL14_SS1 (0x02 << 28)
 
 
+
+/* Port L consists of14 SPI1/Misc pins
+ *
+ * GPLCON has 2 bits for each of the input pins on port L
+ *   00 = 0 input, 1 output,
+ *
+ * pull up works like all other ports.
+*/
+
+#define S3C2410_GPLCON	   S3C2410_GPIOREG(0xf0)
+#define S3C2410_GPLDAT	   S3C2410_GPIOREG(0xf4)
+#define S3C2410_GPLUP	   S3C2410_GPIOREG(0xf8)
+
+#define S3C2450_GPLSEL	   S3C2410_GPIOREG(0xfC)
+
+#define S3C2410_GPK0        S3C2410_GPIONO(S3C2410_GPIO_BANKK, 0)
+#define S3C2410_GPK0_INP    (0x00 << 0)
+#define S3C2410_GPK0_OUTP   (0x01 << 0)
+
+#define S3C2410_GPK1        S3C2410_GPIONO(S3C2410_GPIO_BANKK, 1)
+#define S3C2410_GPK1_INP    (0x00 << 2)
+#define S3C2410_GPK1_OUTP   (0x01 << 2)
+
+#define S3C2410_GPK2        S3C2410_GPIONO(S3C2410_GPIO_BANKK, 2)
+#define S3C2410_GPK2_INP    (0x00 << 4)
+#define S3C2410_GPK2_OUTP   (0x01 << 4)
+
+#define S3C2410_GPK3        S3C2410_GPIONO(S3C2410_GPIO_BANKK, 3)
+#define S3C2410_GPK3_INP    (0x00 << 6)
+#define S3C2410_GPK3_OUTP   (0x01 << 6)
+
+#define S3C2410_GPK4        S3C2410_GPIONO(S3C2410_GPIO_BANKK, 4)
+#define S3C2410_GPK4_INP    (0x00 << 8)
+#define S3C2410_GPK4_OUTP   (0x01 << 8)
+
+#define S3C2410_GPK5        S3C2410_GPIONO(S3C2410_GPIO_BANKK, 5)
+#define S3C2410_GPK5_INP    (0x00 << 10)
+#define S3C2410_GPK5_OUTP   (0x01 << 10)
+
+#define S3C2410_GPK6        S3C2410_GPIONO(S3C2410_GPIO_BANKK, 6)
+#define S3C2410_GPK6_INP    (0x00 << 12)
+#define S3C2410_GPK6_OUTP   (0x01 << 12)
+
+#define S3C2410_GPK7        S3C2410_GPIONO(S3C2410_GPIO_BANKK, 7)
+#define S3C2410_GPK7_INP    (0x00 << 14)
+#define S3C2410_GPK7_OUTP   (0x01 << 14)
+
+#define S3C2410_GPK8        S3C2410_GPIONO(S3C2410_GPIO_BANKK, 8)
+#define S3C2410_GPK8_INP    (0x00 << 16)
+#define S3C2410_GPK8_OUTP   (0x01 << 16)
+
+#define S3C2410_GPK9          S3C2410_GPIONO(S3C2410_GPIO_BANKK, 9)
+#define S3C2410_GPK9_INP      (0x00 << 18)
+#define S3C2410_GPK9_OUTP     (0x01 << 18)
+
+#define S3C2410_GPK10         S3C2410_GPIONO(S3C2410_GPIO_BANKK, 10)
+#define S3C2410_GPK10_INP     (0x00 << 20)
+#define S3C2410_GPK10_OUTP    (0x01 << 20)
+
+#define S3C2410_GPK11         S3C2410_GPIONO(S3C2410_GPIO_BANKK, 11)
+#define S3C2410_GPK11_INP     (0x00 << 22)
+#define S3C2410_GPK11_OUTP    (0x01 << 22)
+
+#define S3C2410_GPK12         S3C2410_GPIONO(S3C2410_GPIO_BANKK, 12)
+#define S3C2410_GPK12_INP     (0x00 << 24)
+#define S3C2410_GPK12_OUTP    (0x01 << 24)
+
+#define S3C2410_GPK13         S3C2410_GPIONO(S3C2410_GPIO_BANKK, 13)
+#define S3C2410_GPK13_INP     (0x00 << 26)
+#define S3C2410_GPK13_OUTP    (0x01 << 26)
+
+#define S3C2410_GPK14         S3C2410_GPIONO(S3C2410_GPIO_BANKK, 14)
+#define S3C2410_GPK14_INP     (0x00 << 28)
+#define S3C2410_GPK14_OUTP    (0x01 << 28)
+
+#define S3C2410_GPK15         S3C2410_GPIONO(S3C2410_GPIO_BANKK, 15)
+#define S3C2410_GPK15_INP     (0x00 << 30)
+#define S3C2410_GPK15_OUTP    (0x01 << 30)
+
+
 /*2009/7/17,Qisda Leo SJ Yang Set GPK3 for enabling SD_POWER{*/
 #define S3C2416_GPLCON      S3C2410_GPIOREG(0xF0)
 #define S3C2416_GPLDAT      S3C2410_GPIOREG(0xF4)

+ 6 - 1
include/cybook.h

@@ -20,7 +20,9 @@ extern unsigned int platform_type;
 /* 3322 2222 2222 1111 1111 1100 0000 0000 
  * 1098 7654 3210 9876 5432 1098 7654 3210 
  * ---------------------------------------
- *                          FFFG GGVV VSSS
+ * D                        FFFG GGVV VSSS
+ *
+ * D   = Dev Mode
  *
  * FFF = Form Factor
  * GGG = GSensor mode
@@ -49,6 +51,9 @@ extern unsigned long platform_capability;
 #define PLAT_CAP_OPUSFORM   (1 << 9)
 #define PLAT_CAP_ORIZONFORM (2 << 9)
 
+#define PLAT_CAP_DEVMODE    (1 << 31)
+#define PLAT_CAP_UNRESTRICT (1 << 30)
+
 //#define PLAT_CAP_
 
 #define GET_CAPABILITY(CAPAB) (platform_capability & (CAPAB))

+ 63 - 14
include/linux/auofb_ioctl.h

@@ -21,6 +21,8 @@
 #ifndef AUOFB_IOCTL_H
 #define AUOFB_IOCTL_H
 
+#define AUO_FIRMWARE_VERSION 33
+
 #pragma pack(1)
 typedef struct sAUOCommand_t
 {
@@ -37,23 +39,71 @@ typedef struct sAUOCommand_t
 #define IOCTL_AUO_PREFIX      ('A' << 8)
 #define IOCTL_AUO_SENDCOMMAND (IOCTL_AUO_PREFIX | 0x01)
 
+#define IOCTL_AUO_RESET       (IOCTL_AUO_PREFIX | 0x02)
+#define IOCTL_AUO_SLEEP       (IOCTL_AUO_PREFIX | 0x03)
+#define IOCTL_AUO_WAKEUP      (IOCTL_AUO_PREFIX | 0x04)
+#define IOCTL_AUO_POWERON     (IOCTL_AUO_PREFIX | 0x05)
+#define IOCTL_AUO_POWEROFF    (IOCTL_AUO_PREFIX | 0x06)
+#define IOCTL_AUO_UPDATEFW    (IOCTL_AUO_PREFIX | 0x07)
+
 /* Command definition                                                          *
  * 3322 2222 2222 1111 1111 1100 0000 0000                                     *
  * 1098 7654 3210 9876 5432 1098 7654 3210                                     *
  * ---------------------------------------                                     *
- *   WD      pppp      CCCC CCCC CCCC CCCC                                     *
+ *  RWD      pppp      CCCC CCCC CCCC CCCC                                     *
  *
+ * R = 'Read Command' (0 mean write, 1 mean read)
  * W = 'need_wait'
  * D = 'have_data'
  * p = 'nb_param'
  * C = "command"
  */
-#define SET_AUO_COMMAND(command, nb_param, have_data, need_wait) \
-                                                ( ((need_wait & 0x01) << 29) |\
-                                                  ((have_data & 0x01) << 28) |\
-                                                  ((nb_param  & 0x0F) << 20) |\
-                                                   (command & 0xFFFF) )
- 
+#define SET_AUO_COMMAND_EXT(command, nb_param, have_data, need_wait, read_write) \
+                                                  ( ((need_wait & 0x01) << 29)  |\
+                                                    ((have_data & 0x01) << 28)  |\
+                                                    ((nb_param  & 0x0F) << 20)  |\
+                                                    ((read_write & 0x01) << 30) |\
+                                                     (command & 0xFFFF) )
+#define SET_AUO_WRITE_COMMAND(command, nb_param, have_data, need_wait) SET_AUO_COMMAND_EXT(command, nb_param, have_data, need_wait, 0)
+#define SET_AUO_COMMAND SET_AUO_WRITE_COMMAND
+#define SET_AUO_READ_COMMAND(command, nb_param, have_data, need_wait) SET_AUO_COMMAND_EXT(command, nb_param, have_data, need_wait, 1)
+
+#if (AUO_FIRMWARE_VERSION == 33) /* Command set for TCON firmware v33 */
+
+/* Initialisation commands */
+#define AUOCMD_INIT_SET          SET_AUO_COMMAND(0x0000, 1, 0, 1)
+#define AUOCMD_TCON_RESET        SET_AUO_COMMAND(0x0003, 1, 0, 0)
+#define AUOCMD_VCOM_FRAMERATE    SET_AUO_COMMAND(0x0004, 1, 0, 0)
+
+/* Power management */
+#define AUOCMD_STANDBY           SET_AUO_COMMAND(0x0001, 0, 0, 1)
+#define AUOCMD_WAKEUP            SET_AUO_COMMAND(0x0002, 0, 0, 0)
+
+/* Display commands */
+#define AUOCMD_DISPLAY_START     SET_AUO_COMMAND(0x1001, 4, 1, 1)
+#define AUOCMD_DISPLAY_STOP      SET_AUO_COMMAND(0x1002, 0, 0, 1)
+#define AUOCMD_DISPLAY_REFRESH   SET_AUO_COMMAND(0x1004, 0, 0, 1)
+#define AUOCMD_DISPLAY_RESET     SET_AUO_COMMAND(0x1005, 0, 0, 1)
+#define AUOCMD_PRE_DISPLAY_START SET_AUO_COMMAND(0x100D, 0, 1, 1)
+#define AUOCMD_PRE_DISPLAY_STOP  SET_AUO_COMMAND(0x100F, 0, 0, 1)
+
+/* LUT */
+#define AUOCMD_LUT_START         SET_AUO_WRITE_COMMAND(0x1003, 0, 1, 1)
+#define AUOCMD_LUT_STOP          SET_AUO_WRITE_COMMAND(0x1009, 0, 0, 1)
+#define AUOCMD_LUT_READ          SET_AUO_READ_COMMAND(0x4003, 0, 1, 1)
+
+/* Other commands */
+#define AUOCMD_READ_FUNC         SET_AUO_READ_COMMAND(0x4000, 0, 1, 1)
+#define AUOCMD_READ_STATUS       SET_AUO_READ_COMMAND(0x4001, 0, 1, 0)
+#define AUOCMD_LUMINANCE_BAL     SET_AUO_READ_COMMAND(0x5001, 0, 1, 1)
+
+/* Handwriting (MODE4) related commands */
+#define AUOCMD_HANDW_PARAM_SET   SET_AUO_WRITE_COMMAND(0x5002, 1, 0, 1)
+
+/*** TODO: We should add command parameters defined here */
+
+#else
+
 #define AUOCMD_INIT_SET          SET_AUO_COMMAND(0x0000, 1, 0, 1)
 #define AUOCMD_STANDBY           SET_AUO_COMMAND(0x0001, 0, 0, 1)
 #define AUOCMD_WAKEUP            SET_AUO_COMMAND(0x0002, 0, 0, 0)
@@ -61,10 +111,8 @@ typedef struct sAUOCommand_t
 #define AUOCMD_DISPLAY_STOP      SET_AUO_COMMAND(0x1002, 0, 0, 1)
 #define AUOCMD_DISPLAY_REFRESH   SET_AUO_COMMAND(0x1004, 0, 0, 1)
 #define AUOCMD_DISPLAY_RESET     SET_AUO_COMMAND(0x1005, 0, 0, 1)
-//#define AUOCMD_LUMINANCE_BALANCE SET_AUO_COMMAND(0x5001, 1, 0, 1)
-//#define AUOCMD_AGING_MODE        SET_AUO_COMMAND(0x6000, 0, 0, 1)
-//#define AUOCMD_AGING_MODE_EXIT   SET_AUO_COMMAND(0x6001, 0, 0, 1)
-//#define AUOCMD_POWER_CONTROL     SET_AUO_COMMAND(0x7000, 2, 0, 1)
+
+#endif
 
 #define AUO_DSPPARAM_FLASH (1 << 15)
 #define AUO_DSPPARAM_MODE_GRAYwFLASH (0x00 << 12) /* Mode 0: Gray 4bit With Flash */
@@ -100,8 +148,9 @@ typedef struct sAUOCommand_t
 int Epaper_sendCommand(sAUOCommand *cmd);
 
 /* Please, do not use these #define s */
-#define GET_COMMAND_PARAM_NUM(command) ((command >> 20) & 0x0F)
-#define GET_COMMAND_HAVE_DATA(command) ((command >> 28) & 0x01)
-#define GET_COMMAND_NEED_WAIT(command) ((command >> 29) & 0x01)
+#define GET_COMMAND_PARAM_NUM(command)  ((command >> 20) & 0x0F)
+#define GET_COMMAND_HAVE_DATA(command)  ((command >> 28) & 0x01)
+#define GET_COMMAND_NEED_WAIT(command)  ((command >> 29) & 0x01)
+#define GET_COMMAND_READ_WRITE(command) ((command >> 30) & 0x01)
 
 #endif /* AUOFB_IOCTL_H */

+ 108 - 0
include/linux/cyevent.h

@@ -0,0 +1,108 @@
+// ===========================================================================
+// cyio.h
+// Copyright (C) 2008-2010 Bookeen - All rights reserved
+// ===========================================================================
+
+#define CYIO_EVENT_VERSION 1
+
+typedef struct sCyEvent_t
+{
+    unsigned char type;
+    unsigned char flags;
+    unsigned char version; /*** Use for later compatibility */
+    union
+    {
+        unsigned char raw[13];
+        struct
+        {
+            unsigned short x1;
+            unsigned short y1;
+            unsigned short x2;
+            unsigned short y2;
+        } touch;
+        struct
+        {
+            unsigned char key_ascii;
+        } key;
+    } data;
+} CyEvent_t;
+
+enum
+{
+    CYEVENT_TYPE_KEY =                  'k',
+    CYEVENT_TYPE_TOUCH =                't',
+    CYEVENT_TYPE_ACCEL =                'a',
+    CYEVENT_TYPE_TIMER =                'z',
+    CYEVENT_TYPE_SYSTEM =               's',
+    //CYIO_EVENT_ = '',
+};
+
+// Key events
+#define CYEVENT_KEY_ENTER               'e'
+#define CYEVENT_KEY_RIGHT               'r'
+#define CYEVENT_KEY_DOWN                'd'
+#define CYEVENT_KEY_LEFT                'l'
+#define CYEVENT_KEY_UP                  'u'
+#define CYEVENT_KEY_F1                  '1'
+#define CYEVENT_KEY_F2                  '2'
+#define CYEVENT_KEY_F3                  '3'
+#define CYEVENT_KEY_F4                  '4'
+#define CYEVENT_KEY_OFF                 'o'
+#define CYEVENT_KEY_DSLP                's'
+#define CYEVENT_KEY_VOLP                '+'
+#define CYEVENT_KEY_VOLN                '-'
+#define CYEVENT_KEY_TOGGLE_ACCEL        'a'
+#define CYEVENT_KEY_FACTORY_RESET       'f'
+
+/* Flags definitions */
+/* Bit 7 to Bit 4 are event type dependent. If the event need more than 4 flags,
+ * it can use it's own "private" values
+ */
+
+/* Key event flags */
+#define CYEVENT_FLAG_KEY_CONTROL_CHARS  (1 << 7) /*** Signal that the current key is not a real key (ie not an ascii value) */
+
+/* Touch event flags */
+#define CYEVENT_FLAG_TOUCH_UP           (0x1 << 6)
+#define CYEVENT_FLAG_TOUCH_MOVE         (0x2 << 6)
+#define CYEVENT_FLAG_TOUCH_DOWN         (0x3 << 6)
+
+/* System Event */
+#define CYEVENT_FLAG_USB_STATE          (1 << 7) /*** If not set, the USB is unplugged */
+#define CYEVENT_FLAG_AC_STATE           (1 << 6) /*** If not set, the AC is unplugged */
+#define CYEVENT_FLAG_AC_STATE           (1 << 5) /*** If not set, the SD is unplugged */
+
+/* Timer event */
+#define CYEVENT_FLAG_TIMER_SCREEN       (1 << 7)
+#define CYEVENT_FLAG_TIMER_DEVICE       (1 << 6)
+
+/* Bit 3 to Bit 2 are reserved (v1) */
+#define CYEVENT_FLAG_ENDOFREPEAT        (1 << 1)
+#define CYEVENT_FLAG_REPEATEVENT        (1 << 0)
+
+
+// ===========================================================================
+/* Exported function of CyEvent */
+
+// ===========================================================================
+
+
+
+
+/* TODO: This part should be moved elsewhere... */
+// ===========================================================================
+/* Non directly CyIO related values, but used for the Accelerometer */
+#define G_SENSOR_ON                '1'
+#define G_SENSOR_OFF               '0'
+#define G_SENSOR_CAL               'C'
+enum
+{
+ CYGSENSOR_STATUS_ENABLED       = 0, /** The accelerometer is enabled */
+ CYGSENSOR_STATUS_DISABLED      = 1, /** The accelerometer is disabled */
+ CYGSENSOR_STATUS_NOTCALIB      = 2, /** Not calibrated, or invalid calibration data */
+ CYGSENSOR_STATUS_CALIBRATED    = 3, /** This status should never been read, but it could help to debug */
+ CYGSENSOR_STATUS_UNKNOWN       = 4, /** This status should never been read, but it could help to debug */
+ CYGSENSOR_STATUS_CHIPDETECTED  = 5, /** This status should never been read, used to say if we correctly detected the I²C accelerometer Chip */
+ CYGSENSOR_STATUS_CRITICALERROR = 6, /** If we are in this status, the G-Sensor is non working: possible cause, defective chip */
+ CYGSENSOR_STATUS_SUSPENDED	= 7, /** The GSENSOR was on, the device go to deepsleep, so we go in this state. */
+};

+ 67 - 85
include/linux/cyio.h

@@ -2,91 +2,53 @@
 // cyio.h
 // Copyright (C) 2008-2010 Bookeen - All rights reserved
 // ===========================================================================
-
-#define CYIO_EVENT_VERSION 1
-
-typedef struct sCyEvent_t
-{
-    unsigned char type;
-    unsigned char flags;
-    unsigned char version; /*** Use for later compatibility */
-    union
-    {
-        unsigned char raw[13];
-        struct
-        {
-            unsigned short x1;
-            unsigned short y1;
-            unsigned short x2;
-            unsigned short y2;
-        } touch;
-        struct
-        {
-            unsigned char key_ascii;
-        } key;
-    } data;
-} CyEvent_t;
-
-enum
-{
-    CYIO_EVENT_KEY =                    'k',
-    CYIO_EVENT_TOUCH =                  't',
-    CYIO_EVENT_SD =                     's',
-    CYIO_EVENT_ACCEL =                  'a',
-    CYIO_EVENT_TIMER =                  'z',
-    CYIO_EVENT_SYSTEM =                 'u',
-    //CYIO_EVENT_ = '',
-};
-
 // Key events
-#define CYEVENT_KEY_ENTER               'e'
-#define CYEVENT_KEY_RIGHT               'r'
-#define CYEVENT_KEY_DOWN                'd'
-#define CYEVENT_KEY_LEFT                'l'
-#define CYEVENT_KEY_UP                  'u'
-#define CYEVENT_KEY_F1                  '1'
-#define CYEVENT_KEY_F2                  '2'
-#define CYEVENT_KEY_F3                  '3'
-#define CYEVENT_KEY_F4                  '4'
-#define CYEVENT_KEY_OFF                 'o'
-#define CYEVENT_KEY_DSLP                's'
-#define CYEVENT_KEY_VOLP                '+'
-#define CYEVENT_KEY_VOLN                '-'
-#define CYEVENT_KEY_TOGGLE_ACCEL        'a'
-#define CYEVENT_KEY_FACTORY_RESET       'f'
-
-/* Flags definitions */
-/* Bit 7 to Bit 4 are event type dependent. If the event need more than 4 flags,
- * it can use it's own "private" values
- */
-
-/* Key event flags */
-#define CYEVENT_FLAG_KEY_REPEAT         (1 << 7) /*** Signal that this key is repeated */
-#define CYEVENT_FLAG_KEY_END_OF_REPEAT  (1 << 6) /*** Signal that the repeat is finished */
-#define CYEVENT_FLAG_KEY_CONTROL_CHARS  (1 << 5) /*** Signal that the current key is not a real key (ie not an ascii value) */
-
-/* Touch event flags */
-#define CYEVENT_FLAG_TOUCH_UP           (0x1 << 6)
-#define CYEVENT_FLAG_TOUCH_MOVE         (0x2 << 6)
-#define CYEVENT_FLAG_TOUCH_DOWN         (0x3 << 6)
-
-/* System Event */
-#define CYEVENT_FLAG_USB_STATE          (1 << 7) /*** If not set, the USB is unplugged */
-#define CYEVENT_FLAG_AC_STATE           (1 << 6) /*** If not set, the AC is unplugged */
-#define CYEVENT_FLAG_AC_STATE           (1 << 5) /*** If not set, the SD is unplugged */
-
-/* Timer event */
-#define CYEVENT_FLAG_TIMER_SCREEN       (1 << 7)
-#define CYEVENT_FLAG_TIMER_DEVICE       (1 << 6)
+#define CYEVENT_KEY_ENTER          'e'
+#define CYEVENT_KEY_RIGHT          'r'
+#define CYEVENT_KEY_DOWN           'd'
+#define CYEVENT_KEY_LEFT           'l'
+#define CYEVENT_KEY_UP             'u'
+#define CYEVENT_KEY_F1             '1'
+#define CYEVENT_KEY_F2             '2'
+#define CYEVENT_KEY_F3             '3'
+#define CYEVENT_KEY_F4             '4'
+#define CYEVENT_KEY_OFF            'o'
+#define CYEVENT_KEY_DSLP           'S'
+#define CYEVENT_KEY_VOLP           '+'
+#define CYEVENT_KEY_VOLN           '-'
+#define CYEVENT_KEY_REPEAT_FLAG    0x80
+#define CYEVENT_KEY_REPEAT_END     '0'
+// Physical events
+#define CYEVENT_USB_IN             'p'
+#define CYEVENT_USB_OUT            'q'
+#define CYEVENT_AC_IN              'a'
+#define CYEVENT_AC_OUT             'b'
+#define CYEVENT_ACN_IN             'j'
+#define CYEVENT_ACN_OUT            'k'
+#define CYEVENT_SD_IN              's'
+#define CYEVENT_SD_OUT             't'
+#define CYEVENT_SDN_IN             'u'
+#define CYEVENT_SDN_OUT            'v'
+
+#define CYEVENT_SPECIAL				  0xFE
+
+// G-Sensor events
+#define CYEVENT_ORIENTATIONCHANGED 'O'
+#define CYEVENT_G_ROT000           'A'
+#define CYEVENT_G_ROT090           'B'
+#define CYEVENT_G_ROT180           'C'
+#define CYEVENT_G_ROT270           'D'
+#define CYEVENT_TOGGLE_GSENSOR     'G'
+
+// Logical events
+// CYEVENT_KEY_OFF + CYEVENT_KEY_VOLN
+#define CYEVENT_FACTORY_OFF        'x'
+#define CYEVENT_SUSPEND_SCREEN     'y'
+#define CYEVENT_SUSPEND_DEVICE     'z'
+
+/* Normaly no more used... */
+//#define CYIO_KERNEL_2_6            1
 
-/* Bit 3 to Bit 1 are reserved (v1) */
-#define CYEVENT_FLAG_UNIQUEEVENT        (1 << 0) /*** Used internaly to prevent other event of the same type to be pushed */
-
-
-
-
-
-/* TODO: This part should be moved elsewhere... */
 // ===========================================================================
 /* Non directly CyIO related values, but used for the Accelerometer */
 #define G_SENSOR_ON                '1'
@@ -104,9 +66,29 @@ enum
  CYGSENSOR_STATUS_CRITICALERROR = 6, /** If we are in this status, the G-Sensor is non working: possible cause, defective chip */
  CYGSENSOR_STATUS_SUSPENDED	= 7, /** The GSENSOR was on, the device go to deepsleep, so we go in this state. */
 };
+
+
+#define SET_IOCTL(c, v) ((c << 8) | (v & 0xFF))
+
+#define CYIO_CTL_LED_CMD    SET_IOCTL('C', 'l')
+#define CYIO_CTL_USB_STATUS SET_IOCTL('C', 'u')
+#define CYIO_CTL_SD_STATUS  SET_IOCTL('C', 's')
+
+#define CYIO_CTL_PWRLED_CHANGE 0x002
+#define CYIO_CTL_WFILED_CHANGE 0x020
+#define CYIO_CTL_BTHLED_CHANGE 0x200
+
+#define CYIO_CTL_PWRLED_SETON (CYIO_CTL_PWRLED_CHANGE | 0x001)
+#define CYIO_CTL_WFILED_SETON (CYIO_CTL_WFILED_CHANGE | 0x010)
+#define CYIO_CTL_BTHLED_SETON (CYIO_CTL_BTHLED_CHANGE | 0x100)
+
+#define CYIO_CTL_PWRLED_SETOFF (CYIO_CTL_PWRLED_CHANGE | 0x000)
+#define CYIO_CTL_WFILED_SETOFF (CYIO_CTL_WFILED_CHANGE | 0x000)
+#define CYIO_CTL_BTHLED_SETOFF (CYIO_CTL_BTHLED_CHANGE | 0x000)
+
+
 // ===========================================================================
 /* Exported function of CyIO */
 void Cyio_ResetTimer(void);
-int __deprecated Cyio_PushEvent(char eventId, char unique); /* Old way */
-int Cyio_PushCyEvent(char eventId, char unique);
+int Cyio_PushEvent(char eventId, char unique);
 // ===========================================================================