Browse Source

Latest changes

mlt 13 years ago
parent
commit
db805e563c

+ 1 - 1
arch/arm/plat-s3c24xx/pm.c

@@ -907,7 +907,7 @@ static int s3c2410_pm_enter(suspend_state_t state)
 	/* check if we have anything to wake-up with... bad things seem
 	 * to happen if you suspend with no wakeup (system will often
 	 * require a full power-cycle)
-	*/
+ 	 */
 
 	if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
 	    !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {

+ 2 - 1
cybook.config

@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.21.5-cfs-v19
-# Mon May 24 20:53:14 2010
+# Mon Jun 28 18:41:53 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -602,6 +602,7 @@ CONFIG_SLHC=m
 # Input device support
 #
 CONFIG_INPUT=y
+CONFIG_CYBOOK_EVENT_MANAGER=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 
 #

+ 6 - 0
drivers/input/Kconfig

@@ -24,6 +24,12 @@ config INPUT
 
 if INPUT
 
+config CYBOOK_EVENT_MANAGER
+	bool "Cybook Event Manager"
+	default y
+	---help---
+	   Say Y if you use a Cybook 2416.
+
 config INPUT_FF_MEMLESS
 	tristate "Support for memoryless force-feedback devices"
 	default n

+ 1 - 0
drivers/input/Makefile

@@ -22,3 +22,4 @@ obj-$(CONFIG_INPUT_JOYSTICK)	+= joystick/
 obj-$(CONFIG_INPUT_TOUCHSCREEN)	+= touchscreen/
 obj-$(CONFIG_INPUT_MISC)	+= misc/
 
+obj-$(CONFIG_CYBOOK_EVENT_MANAGER) += cyevent.o

+ 530 - 154
drivers/input/cyevent.c

@@ -1,6 +1,5 @@
-h
 // ===========================================================================
-// cyio.c
+// Cybook Event Manager - cyevent.c
 // Copyright (C) 2008-2010 Bookeen - All rights reserved
 // ===========================================================================
 #include <linux/init.h>
@@ -14,132 +13,328 @@ h
 #include <linux/interrupt.h>
 #include <linux/pm.h>
 #include <linux/proc_fs.h>
-
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-irq.h>
+#include <asm-arm/arch-s3c2410/irqs.h>
+#include <asm-arm/arch-s3c2410/gpio.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-gpioj.h>
+#include <asm/io.h>
 
 #include <cybook.h>
-
 #include <linux/cyevent.h>
 
+// =============================================================================
+//#define DEBUG_MESSAGES
+//#define DEBUG_TRACEFUNC
+//#define VERBOSE_LEVEL INFO_DEBUG
+
+#define MODULE_NAME "CyEvent"
+// =============================================================================
 #define CYEV_MAX_EVENT 20
-#define CYEV_REPEAT_DELAY (HZ/2); /* ~500ms */
-#define CYEV_CURRENT_VERSION 0x10 /* 1.0 */
+#define CYEV_MAX_DEV 5
+#define CYEV_REPEAT_DELAY (HZ/2) /* ~500ms */
+// =============================================================================
 enum { INVALID = 0, VALID };
-
-struct 
+// =============================================================================
+typedef struct sCyEv_PayList
 {
     char valid;
     char wantRepeat;
     char seen;
+    char repeat;
     char unique;
-    int  repeatDelay;
+    unsigned long  repeatDelay;
     CyEvent_t payload;
 } CyEv_PayList;
 
-CyEv_PayList *cyev_eventList[CYEV_MAX_EVENT];
-
+CyEv_PayList cyev_eventList[CYEV_MAX_EVENT];
+// =============================================================================
+/* We should change this to a linked list... */
+struct cyevent_device *DevList[CYEV_MAX_DEV];
+// =============================================================================
 struct task_struct *openingTask = 0;
+static atomic_t waitingRepeat;
+// =============================================================================
+#ifdef DEBUG_MESSAGES
 
-/* TODO: Add a locking method for accessing the eventList */
+enum InfoLevel
+{
+   INFO_ERROR = 0,
+   INFO_WARNING,
+   INFO_NORMAL,
+   INFO_DEBUG,
+   INFO_VERBOSE,
+};
 
-// ===========================================================================
+# ifndef VERBOSE_LEVEL
+#  define VERBOSE_LEVEL INFO_WARNING
+# endif
+
+#   ifdef DEBUG_TRACEFUNC
+
+static int _dbg_FunctionLevel = 0;
+
+#      define MSG(str) {\
+   int __i;\
+   printk(KERN_ALERT "+");\
+   for (__i = 0; __i < _dbg_FunctionLevel; __i++)\
+      printk("-");\
+   printk("||" str "\n");\
+}
+
+#      define DBG(str, ...) {\
+   int __i;\
+   printk(KERN_ALERT "+");\
+   for (__i = 0; __i < _dbg_FunctionLevel; __i++)\
+      printk("-");\
+   printk("||" str "\n", __VA_ARGS__);\
+}
+
+#      define INFOL(level, s) do {\
+  if (level <= VERBOSE_LEVEL) {\
+    int __i;\
+    printk(KERN_ALERT "+");\
+    for (__i = 0; __i < _dbg_FunctionLevel; __i++)\
+       printk("-");\
+    printk("<%d>%s:%s(): ", level, __FILE__, __func__); printk s; printk("\n");\
+  }\
+ } while(0)
+
+#      define FUNC_IN() {\
+   int __i;\
+   _dbg_FunctionLevel++;\
+   printk(KERN_ALERT "+");\
+   for (__i = 0; __i < _dbg_FunctionLevel; __i++)\
+      printk("-");\
+   printk(">> %s() >>\n", __func__);\
+}
+
+#      define FUNC_OUT() {\
+   int __i;\
+   printk(KERN_ALERT "+");\
+   for (__i = 0; __i < _dbg_FunctionLevel; __i++)\
+      printk("-");\
+   printk("<< %s() <<\n", __func__);\
+   _dbg_FunctionLevel--;\
+}
+
+#      define FUNC_OUTR(val) {\
+   int __i;\
+   printk(KERN_ALERT "+");\
+   for (__i = 0; __i < _dbg_FunctionLevel; __i++)\
+      printk("-");\
+   printk("<< %s() = %d <<\n", __func__, val);\
+   _dbg_FunctionLevel--;\
+}
+#   else /* DEBUG_TRACEFUNC */
+
+#      define MSG(str) do {\
+   printk(KERN_ALERT MODULE_NAME ": " str "\n");\
+} while(0)
+
+#      define DBG(str, ...) do {\
+   printk(KERN_ALERT MODULE_NAME ": " str "\n", __VA_ARGS__);\
+} while(0)
+#      define FUNC_IN() do {\
+} while(0)
+
+#      define FUNC_OUT() do {\
+} while(0)
+
+#      define FUNC_OUTR(val) do {\
+   printk(KERN_ALERT MODULE_NAME ": %s() return %d\n", __func__, val);\
+} while(0)
+
+#      define INFOL(level, s) do {\
+  if (level <= VERBOSE_LEVEL) {\
+    printk("<%d>%s:%s(): ", level, __FILE__, __func__); printk s; printk("\n");\
+  }\
+ } while(0)
+
+#   endif /* DEBUG_TRACEFUNC */
+#else /* DEBUG_MESSAGES */
+#   define MSG(str)
+#   define DBG(str, ...)
+#   define FUNC_IN()
+#   define FUNC_OUT()
+#   define FUNC_OUTR(val)
+#   define INFOL(level, s)
+#   define INFO(s)
+#endif /* DEBUG_MESSAGES */
+
+#define DUMP_CYEVENT(lvl, ev) INFOL(lvl, ("Event: .type=%c, .flags=%02X, .version=%02X\n" \
+       ".data = { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X }",\
+       ev.type, ev.flags, ev.version, ev.data.raw[0], ev.data.raw[1], ev.data.raw[2], ev.data.raw[3], ev.data.raw[4], ev.data.raw[5],\
+       ev.data.raw[6], ev.data.raw[7], ev.data.raw[8], ev.data.raw[9], ev.data.raw[10], ev.data.raw[11], ev.data.raw[12]))
+#define DUMP_EVITEM(lvl, evi) INFOL(lvl, ("EvItem: .valid = %d, .wantRepeat = %d, .seen = %d, .repeat = %d, .unique = %d, .repeatDelay = %lu .payload:",\
+       evi.valid, evi.wantRepeat, evi.seen, evi.repeat, evi.unique, evi.repeatDelay)); DUMP_CYEVENT(lvl, evi.payload);
+// =============================================================================
+rwlock_t cyev_list_rwlock = RW_LOCK_UNLOCKED;
+// =============================================================================
+static void publish_read_event(unsigned char type);
+static void publish_empty_event(void);
+// =============================================================================
 // List management
 void CyEv_ClearEventList(void)
 {
    int i;
+   
+   FUNC_IN();
+   
+   atomic_set(&waitingRepeat, 0);
+   
+   write_lock(&cyev_list_rwlock);
+   
    for (i = 0; i < CYEV_MAX_EVENT; i++)
    {
       cyev_eventList[i].wantRepeat = false;
+      cyev_eventList[i].repeat = false;
       cyev_eventList[i].seen = false;
       cyev_eventList[i].unique = false;
       cyev_eventList[i].repeatDelay = 0;   
       cyev_eventList[i].valid = INVALID;
    }
+   
+   write_unlock(&cyev_list_rwlock);
+
+   
+   FUNC_OUT();
 }
+int listPos = 0;
 
 /* 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)
+CyEvent_t *CyEv_GetNextEvent(CyEvent_t *ret)
 {
-   static int listPos = 0;
    int i;
-   CyEvent_t ret = NULL;
-
+   char foundPayload = 0;
+	CyEv_PayList *cur;
+	
+	FUNC_IN();
+   
+   write_lock(&cyev_list_rwlock);
+   
    /* 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)
-      {
+      cur = &(cyev_eventList[i % CYEV_MAX_EVENT]);
+      //INFOL(INFO_VERBOSE, ("Position %d / %d", i % CYEV_MAX_EVENT, CYEV_MAX_EVENT));
+      if (cur->valid == VALID)
+      {   
+         DUMP_EVITEM(INFO_DEBUG, (*cur));
+         
          /* 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 ( (cur->seen == true) &&
+              (cur->wantRepeat == true) )
          {
-             if (cyev_eventList[i % CYEV_MAX_EVENT].repeatDelay < jiffies) )
+             if (cur->repeatDelay > jiffies)
              {
+                INFOL(INFO_DEBUG, ("Event delay not occured [%lu vs %lu (%lu)]...", 
+                      cur->repeatDelay, jiffies, cur->repeatDelay - jiffies));
                 continue;
              }
-             else /* if (cyev_eventList[i % CYEV_MAX_EVENT].repeatDelay >= jiffies) ) */
+             else /* if (cur->repeatDelay >= jiffies) */
              {
                 /* Set the Repeat flag to true */
-                cyev_eventList[i % CYEV_MAX_EVENT].payload.flags |= CYEVENT_FLAG_REPEATEVENT;
+                INFOL(INFO_DEBUG, ("Event repeating... (%d)", atomic_read(&waitingRepeat)));
+              	 if (cur->repeat == false)
+              	 {
+	                atomic_dec(&waitingRepeat); /* Ack the repeat event */
+	             }
+                INFOL(INFO_DEBUG, ("waiting (%d) (repeat:%d)", atomic_read(&waitingRepeat), cur->repeat));
+                cur->payload.flags |= CYEVENT_FLAG_REPEATEVENT;
+                cur->repeat = true;
              }
          }
          
-         cyev_eventList[i % CYEV_MAX_EVENT].seen = true;
+         cur->seen = true;
          
-         /* Return the event */
-         ret = &(cyev_eventList[i % CYEV_MAX_EVENT].payload);
-
+         /* Return the event and do not give real access to the list */
+         memcpy(ret, &(cur->payload), sizeof(CyEvent_t));              
+			foundPayload = 1;
          /* If the event is not a repeatable event, invalidate it! */
-         if (cyev_eventList[i % CYEV_MAX_EVENT].wantRepeat == false)
+         if (cur->wantRepeat == false)
          {
-            cyev_eventList[i % CYEV_MAX_EVENT].valid = INVALID;
+				INFOL(INFO_VERBOSE, ("Non-repeat event, will invalidate it"));
+            cur->valid = INVALID;
          }
          
          /* Update the index for the next element to scan */
-         listPos = (listPos + i + 1) % CYEV_MAX_EVENT;
+         listPos = (i + 1) % CYEV_MAX_EVENT;
+			INFOL(INFO_DEBUG, ("Next event slot: %d", listPos));
          break;
       }
    }
-
-   return ret; /* We will return NULL if no valid payload */
+   
+   write_unlock(&cyev_list_rwlock);
+   
+   FUNC_OUT();
+   if (foundPayload == 1)
+	   return ret; /* We will return NULL if no valid payload */
+	return NULL;
 }
 
-int isEventNotDuplicate(CyEvent_t *CyEvent)
+int isEventNotDuplicate(CyEvent_t *CyEvent, unsigned char flagMask)
 {
    int i;
-   CyEvent_t *cur:
+   int ret = true;
+   CyEvent_t *cur;
+   
+   FUNC_IN();
+   
+   read_lock(&cyev_list_rwlock);
+   
    for(i = 0; i < CYEV_MAX_EVENT; i++)
    {
       cur = &(cyev_eventList[i].payload);
-      if (cyev_eventList[i].unique == true)
+      /* The event must be valid to be treated as unique, else invalid event are ignored */
+      if ( (cyev_eventList[i].valid == VALID) &&         
+           (cyev_eventList[i].unique == true) )
       {
-         if (cur->type == CyEvent->type) /* To be verified */
-            return false;
+         if ( (cur->type == CyEvent->type) &&
+              ((cyev_eventList[i].payload.flags & flagMask) == (CyEvent->flags & flagMask)) )
+         {
+            ret = false;
+            goto exit;
+         }
       }
    }
-   return true;
+   
+exit:
+   read_unlock(&cyev_list_rwlock);
+   
+   FUNC_OUTR(ret);   
+   return ret;
 }
 
-int CyEv_AddNewEvent(CyEvent_t *CyEvent, char wantRepeat, char wantUnique)
+int CyEv_AddNewEvent(CyEvent_t *CyEvent, char wantRepeat, char wantUnique, unsigned char flagMask)
 {
    /* 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.*/
 
+	FUNC_IN();
+	
    /* If wantUnique, first check that there is not another unique event */
-   if ((wantUnique) && !isEventNotDuplicate(CyEvent))
+   if ((wantUnique) && !isEventNotDuplicate(CyEvent, flagMask))
       goto exit;
    
+   write_lock(&cyev_list_rwlock);
+   
    /* Scan the list starting from the last position stored */
-   for(i = 0; i < CYEV_MAX_EVENT; i++)
+   for(i = listPos; i < (CYEV_MAX_EVENT + listPos); i++)
    {
-      /* Stop on the first "VALID" event */
+      /* Stop on the first "INVALID" event */
       if (cyev_eventList[i].valid == INVALID)
       {
          /* Store the event */
@@ -148,12 +343,16 @@ int CyEv_AddNewEvent(CyEvent_t *CyEvent, char wantRepeat, char wantUnique)
          /* Force version in the structure */
          cyev_eventList[i].payload.version = CYEV_CURRENT_VERSION;
          cyev_eventList[i].valid = VALID;
+         cyev_eventList[i].seen = false;
+         cyev_eventList[i].repeat = false;
+         
          if (wantUnique)
             cyev_eventList[i].unique = true;
            else
              cyev_eventList[i].unique = false;
          if (wantRepeat)
          {
+            atomic_inc(&waitingRepeat);          
             cyev_eventList[i].wantRepeat = true;
             cyev_eventList[i].repeatDelay = jiffies + CYEV_REPEAT_DELAY;
          }
@@ -168,30 +367,42 @@ int CyEv_AddNewEvent(CyEvent_t *CyEvent, char wantRepeat, char wantUnique)
          break;
       }
    }
+   write_unlock(&cyev_list_rwlock);
    
 exit:
+   FUNC_OUTR(ret);
    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 CyEv_UpdateUniqueEvent(CyEvent_t *CyEvent, char wantRepeat, unsigned char flagMask)
 {
    int i;
    int ret = -1;
    
+   FUNC_IN();
+   
    /* Search for the event */
+   write_lock(&cyev_list_rwlock);
    for(i = 0; i < CYEV_MAX_EVENT; i++)
    {
-      if ( (cyev_eventList[i].unique == true) &&
-           (cyev_eventList[i].payload.type == CyEvent.type) )
+      if ( (cyev_eventList[i].valid == VALID) && 
+           (cyev_eventList[i].unique == true) &&
+           ((cyev_eventList[i].payload.flags & flagMask)  == (CyEvent->flags & flagMask)) &&
+           (cyev_eventList[i].payload.type == CyEvent->type) )
       {  /* Found it ! Now update the fields */
          memcpy(&(cyev_eventList[i].payload), CyEvent, sizeof(CyEvent_t));
          
+         cyev_eventList[i].seen = false;
+         
          if (wantRepeat)
          {
             cyev_eventList[i].wantRepeat = true;
+            cyev_eventList[i].repeat = false;
             cyev_eventList[i].repeatDelay = jiffies + CYEV_REPEAT_DELAY;
+           	if (cyev_eventList[i].repeat == true)
+         	   atomic_inc(&waitingRepeat);
          }
          else
             cyev_eventList[i].wantRepeat = false;
@@ -202,6 +413,35 @@ int CyEv_UpdateUniqueEvent(CyEvent_t *CyEvent, char wantRepeat)
          ret = 0;
       }
    }
+   write_unlock(&cyev_list_rwlock);   
+   FUNC_OUTR(ret);
+   return ret;
+}
+
+int CyEv_InvalidateUniqueEvent (CyEvent_t *CyEvent)
+{
+   int i;
+   int ret = -1;
+
+   FUNC_IN();
+
+   /* Search for the event */
+   write_lock(&cyev_list_rwlock);
+   for ( i = 0; i < CYEV_MAX_EVENT; i++ )
+   {
+      if ( (cyev_eventList[i].valid == VALID) &&
+           (cyev_eventList[i].unique == true) &&
+           (cyev_eventList[i].payload.type == CyEvent->type) )
+      { /* Found it ! Now update the fields */
+         INFOL(INFO_DEBUG, ("Found event..."));
+         cyev_eventList[i].valid = INVALID;
+         ret = 0;
+         break;
+      }
+   }
+   write_unlock(&cyev_list_rwlock);
+
+   FUNC_OUTR(ret);
    return ret;
 }
 
@@ -210,23 +450,40 @@ int CyEv_InvalidateRepeatableEvent(CyEvent_t *CyEvent)
 	int i;
 	int ret = -1;
 	
+	FUNC_IN();
+	
    /* Search for the event */
+   write_lock(&cyev_list_rwlock);
    for(i = 0; i < CYEV_MAX_EVENT; i++)
    {
-      if ( (cyev_eventList[i].wantRepeat == true) &&
-           (cyev_eventList[i].payload.type == CyEvent.type) )
+      if ( (cyev_eventList[i].valid == VALID) && 
+           (cyev_eventList[i].wantRepeat == true) &&
+           (cyev_eventList[i].payload.type == CyEvent->type) )
       {  /* Found it ! Now update the fields */
-      	
+      	INFOL(INFO_DEBUG, ("Found event..."));
       	/* 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)
+         if (cyev_eventList[i].repeat == true)
+         {
+            INFOL(INFO_DEBUG, ("Was repeating..."));
+            /* set the event "end of repeat" flag */
+            cyev_eventList[i].payload.flags |= CYEVENT_FLAG_ENDOFREPEAT;
+            cyev_eventList[i].payload.flags &= ~(CYEVENT_FLAG_REPEATEVENT);
+         }
+         else
          {
-         	/* set the event "end of repeat" flag */
-				cyev_eventList[i].payload.flags |= CYEVENT_FLAG_ENDOFREPEAT;         		
+            INFOL(INFO_DEBUG, ("Repeat not done...  (%d)", atomic_read(&waitingRepeat)));
+            atomic_dec(&waitingRepeat); /* One less waiting event... */
+            INFOL(INFO_DEBUG, ("waiting (%d)", atomic_read(&waitingRepeat)));
+            if (cyev_eventList[i].seen == true)
+	         	cyev_eventList[i].valid = INVALID;
          }
          
+         cyev_eventList[i].seen = false;        
+         cyev_eventList[i].repeat = false;
+         
          if (openingTask)
             wake_up_process(openingTask);
             
@@ -234,10 +491,11 @@ int CyEv_InvalidateRepeatableEvent(CyEvent_t *CyEvent)
          break;
       }
    }
-   
+   write_unlock(&cyev_list_rwlock);
+      
+   FUNC_OUTR(ret);  
    return ret;
 }
-
 // ===========================================================================
 
 
@@ -245,90 +503,168 @@ int CyEv_InvalidateRepeatableEvent(CyEvent_t *CyEvent)
 // External event managment
 int CyEvent_PushNewEvent(CyEvent_t *CyEvent, char wantRepeat)
 {
+   int ret = -1;
+	FUNC_IN();
+
    if (wantRepeat)
-      return CyEv_AddNewEvent(CyEvent, wantRepeat, true);
+      ret = CyEv_AddNewEvent(CyEvent, wantRepeat, true, 0);
    else
-      return CyEv_AddNewEvent(CyEvent, wantRepeat, false);
+      ret = CyEv_AddNewEvent(CyEvent, wantRepeat, false, 0);
+      
+   FUNC_OUTR(ret);
+   return ret;
 }
 EXPORT_SYMBOL(CyEvent_PushNewEvent);
 
+int CyEvent_PushNewUniqueEvent(CyEvent_t *CyEvent)
+{
+	return CyEv_AddNewEvent(CyEvent, false, true, 0);
+}
+EXPORT_SYMBOL(CyEvent_PushNewUniqueEvent);
+
+int CyEvent_PushOrUpdateUniqueEventFlaged(CyEvent_t *CyEvent, char wantRepeat, unsigned char flagMask)
+{
+   int ret;
+
+   FUNC_IN();
+
+   /* For now a simple call to AddNewEvent */
+   ret = CyEv_UpdateUniqueEvent(CyEvent, wantRepeat, flagMask);
+
+   if (ret != 0) /* The event is not present */
+      ret = CyEv_AddNewEvent(CyEvent, wantRepeat, true, flagMask);
+
+   FUNC_OUTR(ret);
+   return ret;
+}
+EXPORT_SYMBOL(CyEvent_PushOrUpdateUniqueEventFlaged);
+
 int CyEvent_PushOrUpdateUniqueEvent(CyEvent_t *CyEvent, char wantRepeat)
 {
    int ret;
    
+   FUNC_IN();
+   
    /* For now a simple call to AddNewEvent */
-   ret = CyEv_UpdateUniqueEvent(CyEvent, wantRepeat);
+   ret = CyEv_UpdateUniqueEvent(CyEvent, wantRepeat, 0);
    
    if (ret != 0) /* The event is not present */
-      ret = CyEv_AddNewEvent(CyEvent, wantRepeat, true);
-      
+      ret = CyEv_AddNewEvent(CyEvent, wantRepeat, true, 0);
+
+   FUNC_OUTR(ret);
    return ret;
 }
 EXPORT_SYMBOL(CyEvent_PushOrUpdateUniqueEvent);
 
+int CyEvent_InvalidateUniqueEvent(CyEvent_t *CyEvent)
+{
+   int ret;
+	FUNC_IN();
+
+   ret = CyEv_InvalidateUniqueEvent(CyEvent);
+
+   FUNC_OUTR(ret);
+   return ret;
+}
+EXPORT_SYMBOL(CyEvent_InvalidateUniqueEvent);
+
 int CyEvent_InvalidateRepeatableEvent(CyEvent_t *CyEvent)
 {
-    ret = CyEv_InvalidateRepeatableEvent(CyEvent);
+   int ret;
+	FUNC_IN();
+
+   ret = CyEv_InvalidateRepeatableEvent(CyEvent);
+   
+   FUNC_OUTR(ret);
+   return ret;
 }
 EXPORT_SYMBOL(CyEvent_InvalidateRepeatableEvent);
 
 // ===========================================================================
 static int ev_open(struct inode *inode, struct file *file)
 {
+  FUNC_IN();
+   
   /* Clear pending event list... */
   CyEv_ClearEventList();
   
+  FUNC_OUT();
   return 0;
 }
 // ---------------------------------------------------------------------------
 static int ev_release(struct inode *inode, struct file *file)
 {
+  FUNC_IN();
+  
   /* Clear pending event list... */
   CyEv_ClearEventList();
   
+  FUNC_OUT();
   return 0;
 }
 // ---------------------------------------------------------------------------
-ssize_t ev_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+
+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;
-  }
+   int nBytes = sizeof (CyEvent_t);
+   int ret = -EIO;
+   int waitCount;
+   CyEvent_t CyEvent;
 
-  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;
-  }
+   //FUNC_IN();
 
-  return ret;
+   if ( count < nBytes )
+   {
+      ret = -EINVAL;
+      goto exit;
+   }
+
+   while ( 1 )
+   {
+      //printk(KERN_ERR "CyEvent: Check new event...\n");
+      if ( CyEv_GetNextEvent(&CyEvent) != NULL )
+      {
+         break;
+      }
+      
+      waitCount = atomic_read(&waitingRepeat);
+
+      if (waitCount == 0) /* If there are some waiting event, the list is not empty */
+         publish_empty_event();
+
+      openingTask = current;
+      set_current_state(TASK_INTERRUPTIBLE);
+
+      /* If there are some waiting repeat, schedule with a timeout, or else,
+         just go out of the schedule queue */
+      INFOL(INFO_DEBUG, ("Waiting repeat: %d", waitCount));
+
+      if ( waitCount > 0 )
+         schedule_timeout(CYEV_REPEAT_DELAY / 10);
+      else
+         schedule();
+
+      set_current_state(TASK_RUNNING);
+      openingTask = 0;
+
+      if ( signal_pending(current) )
+      {
+         ret = -ERESTARTSYS;
+         break;
+      }
+   }
+
+   if ( ret != -ERESTARTSYS )
+   {
+      ret = copy_to_user(buf, &CyEvent, nBytes);
+      if ( !ret )
+         ret = nBytes;
+      publish_read_event(CyEvent.type);
+   }
+
+exit:
+   //FUNC_OUTR(ret);
+   return ret;
 }
 // ---------------------------------------------------------------------------
 static int ev_ioctl(struct inode *inode, struct file *file,
@@ -336,72 +672,90 @@ static int ev_ioctl(struct inode *inode, struct file *file,
 {
    int ret = -EINVAL;
    unsigned long value;
+   int i;
+   FUNC_IN();
+  
    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)
+      for (i = 0; i < CYEV_MAX_DEV; i++ )
       {
-         MSG("\n----------------> POWER LED OFF\n");
-         __raw_writel(__raw_readl(S3C2410_GPHDAT) & ~(1 << 12), S3C2410_GPHDAT);
+         if ((DevList[i] != NULL) && (DevList[i]->ioctl != NULL))
+         {
+            if (GET_IOCTL_PREFIX(cmd) == DevList[i]->ioctl_prefix)
+            {
+               ret = DevList[i]->ioctl(cmd, arg);
+               /* if the ioctl called didn't return 0, try to see if there is
+                  someone else for this one */
+               if (ret == 0)
+                  break;
+            }
+         }
       }
 
-      if ((arg & 0x20) && (arg & 0x10)) /* Wifi LED */
+      printk(KERN_ERR "Bad IOCTL\n");
+      break;
+   }
+   
+   FUNC_OUT();
+   return ret;
+}
+// =============================================================================
+int CyEvent_RegisterDevice(cyevent_device *dev)
+{
+   int i;
+   for (i = 0; i < CYEV_MAX_DEV; i++ )
+   {
+      if (DevList[i] == NULL)
       {
-         MSG("\n----------------> POWER WFI ON\n");
-         //GPK8
-         __raw_writel(__raw_readl(S3C2416_GPKDAT) | (1 << 8), S3C2416_GPKDAT);
+         DevList[i] = dev;
+         return 0;
       }
-      else if (arg & 0x20)
+   }
+
+   return -1; /* Too many devices... */
+}
+// -----------------------------------------------------------------------------
+int CyEvent_DeregisterDevice(cyevent_device *dev)
+{
+   int i;
+   for (i = 0; i < CYEV_MAX_DEV; i++ )
+   {
+      if (DevList[i] == dev)
       {
-         MSG("\n----------------> POWER WFI OFF\n");
-         __raw_writel(__raw_readl(S3C2416_GPKDAT) & ~(1 << 8), S3C2416_GPKDAT);
+         DevList[i] = NULL;
+         return 0;
       }
-
-      if ((arg & 0x200) && (arg & 0x100)) /* Bluetooth LED */
+   }
+   return -1; /* Not found...*/
+}
+// -----------------------------------------------------------------------------
+static void publish_read_event(unsigned char type)
+{
+   int i;
+   for (i = 0; i < CYEV_MAX_DEV; i++ )
+   {
+      if ((DevList[i] != NULL) && (DevList[i]->event_read != NULL))
       {
-         MSG("\n----------------> POWER BTH ON\n");
-         //GPK9
-         __raw_writel(__raw_readl(S3C2416_GPKDAT) | (1 << 9), S3C2416_GPKDAT);
+         if ((DevList[i]->event_read_listen == 0) || (type == DevList[i]->event_read_listen))
+            DevList[i]->event_read(type);
       }
-      else if (arg & 0x200)
+   }
+}
+// -----------------------------------------------------------------------------
+static void publish_empty_event(void)
+{
+   int i;
+   for (i = 0; i < CYEV_MAX_DEV; i++ )
+   {
+      if ((DevList[i] != NULL) && (DevList[i]->event_listempty != NULL))
       {
-         MSG("\n----------------> POWER BTH OFF\n");
-         __raw_writel(__raw_readl(S3C2416_GPKDAT) & ~(1 << 9), S3C2416_GPKDAT);
+            DevList[i]->event_listempty();
       }
-
-      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 =
+// =============================================================================
+static struct file_operations s_ev_fops =
 {
   owner:    THIS_MODULE,
   read:     ev_read,
@@ -410,7 +764,7 @@ static struct file_operations s_io_fops =
   release:  ev_release,
 };
 
-gstatic struct miscdevice s_ev_dev =
+static struct miscdevice s_ev_dev =
 {
    .minor = 250,
    .name = "cyio",
@@ -418,22 +772,38 @@ gstatic struct miscdevice s_ev_dev =
 };
 // ===========================================================================
 // ---------------------------------------------------------------------------
-static int io_probe(struct platform_device *dev)
+static int ev_probe(struct platform_device *dev)
 {
+  FUNC_IN();
+  FUNC_OUT();
   return 0;
 }
 // ---------------------------------------------------------------------------
-static int io_remove(struct platform_device *dev)
+static int ev_remove(struct platform_device *dev)
 {
+  FUNC_IN();
+ 
   misc_deregister(&s_ev_dev);
+  
+  FUNC_OUT();
   return 0;
 }
 // --------------------------------------------------------------------------
-static int io_resume(struct platform_device *dev)
+static int ev_suspend(struct platform_device *dev)
 {
+  FUNC_IN();
+
+  FUNC_OUT();
+  return 0;
+}
+// --------------------------------------------------------------------------
+static int ev_resume(struct platform_device *dev)
+{
+  FUNC_IN();
+  
+  FUNC_OUT();
   return 0;
 }
-
 // ---------------------------------------------------------------------------
 static struct platform_driver cyev_driver =
 {
@@ -444,28 +814,34 @@ static struct platform_driver cyev_driver =
   },
   .probe    = ev_probe,
   .remove   = ev_remove,
-  .suspend  = NULL,
+  .suspend  = NULL, //ev_suspend,
   .resume   = ev_resume,
 };
 // ---------------------------------------------------------------------------
 // ===========================================================================
 static int __init cyEv_init(void)
 {
+  FUNC_IN();
+  
   if (misc_register(&s_ev_dev))
     return -EBUSY;
 
   platform_driver_register(&cyev_driver);
 
+  FUNC_OUT();
   return 0;
 }
 // ---------------------------------------------------------------------------
 static void __exit cyEv_exit(void)
 {
+  FUNC_IN();
+  
   platform_driver_unregister(&cyev_driver);
 
   misc_deregister(&s_ev_dev);
+  
+  FUNC_OUT();
 }
-
 // ---------------------------------------------------------------------------
 module_init(cyEv_init);
 module_exit(cyEv_exit);

+ 1 - 0
drivers/input/keyboard/Kconfig

@@ -231,6 +231,7 @@ config KEYBOARD_GPIO
 
 config CYBOOK_CYIO
 	tristate "Cybook CyIO"
+	depends on CYBOOK_EVENT_MANAGER
 #	depends on MACH_CYBOOK_ORIZON
 	default y
 	help

File diff suppressed because it is too large
+ 122 - 879
drivers/input/keyboard/cyio.c


+ 7 - 6
drivers/input/misc/orizon_tilt.c

@@ -22,10 +22,10 @@
 
 #include <cybook.h>
 
-#include <linux/cyio.h>
+#include <linux/cyevent.h>
 
-#define DEBUG_MESSAGES
-#define DEBUG_TRACEFUNC
+//#define DEBUG_MESSAGES
+//#define DEBUG_TRACEFUNC
 //#define DBG_IRQ
 
 #define MODULE_NAME "CYB_TILT"
@@ -209,7 +209,7 @@ static irqreturn_t orizontilt_interrupt(int irq, void *dev_id)
    irqreturn_t ret = IRQ_HANDLED;
    unsigned long tmpReg;
    unsigned long calcTilt;
-
+	CyEvent_t event = NEW_CYEVENT(CYEVENT_TYPE_ORIENTATION);
    FUNC_IN();
 
    spin_lock(&suspendLock);
@@ -245,7 +245,8 @@ static irqreturn_t orizontilt_interrupt(int irq, void *dev_id)
    {
       MSG("Different from old one, push new event!");
       OrizonTilt_CurrentDirection = calcTilt;
-      Cyio_PushEvent(CYEVENT_ORIENTATIONCHANGED, true);
+      event.data.orientation = calcTilt / 90;
+      CyEvent_PushOrUpdateUniqueEvent(&event, false);
    }
 
    spin_lock(&suspendLock);
@@ -370,7 +371,7 @@ static int __init orizontilt_init(void)
       ioProcEntry->write_proc    = orizontilt_procWriteIo;
       ioProcEntry->owner         = THIS_MODULE;
   }
-
+   
   FUNC_OUT();
   return 0;
 }

+ 56 - 16
drivers/input/touchscreen/orizon_ts.c

@@ -22,7 +22,7 @@
 #include <linux/ctype.h>
 
 #include <cybook.h>
-#include <linux/cyio.h>
+#include <linux/cyevent.h>
 
 //#define DEBUG_MESSAGES
 //#define DEBUG_TRACEFUNC
@@ -189,8 +189,7 @@ static Ots_PowerModes ots_currentPowerMode = POWER_UNDEFINED;
 /****************************** i2c configuration *****************************/
 #define OTS_ADDR_I2C 0x5C
 
-static unsigned short normal_i2c[] = { OTS_ADDR_I2C,
-   I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { OTS_ADDR_I2C, I2C_CLIENT_END };
 
 /* Insmod parameters */
 I2C_CLIENT_INSMOD_1 (ots);
@@ -295,7 +294,7 @@ static int ots_detect (struct i2c_adapter *adapter, int address, int kind)
          goto exit_kfree;
       }
 
-      ots_setPowerMode(POWER_ONAUTOSTANDBY);
+      ots_setPowerMode(POWER_ON/*AUTOSTANDBY*/);
       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);
@@ -353,13 +352,19 @@ static int ots_resume (struct device *dev)
 /******************************************************************************/
 /********************** Interrupt Related functions ***************************/
 /******************************************************************************/
-static int oldX = 0, oldY = 0;
+static int oldX1 = 0, oldY1 = 0;
+static int oldX2 = 0, oldY2 = 0;
+
+enum { FINGER_UP = 0, FINGER_MOVE, FINGER_DOWN };
 
 static void ots_checkWorkFunction (struct work_struct *work)
 {
    unsigned long x1, y1, x2, y2;
-   FUNC_IN();
+   static int status = FINGER_UP;
+   CyEvent_t event = NEW_CYEVENT(CYEVENT_TYPE_TOUCH);
    
+   FUNC_IN();
+      
    /* Here do what the interrupt should... (ie read touch values) */
 
    /* TODO: I reversed the X / Y axis to match old driver and revese the X value */
@@ -377,22 +382,57 @@ static void ots_checkWorkFunction (struct work_struct *work)
 
    DBG("x1: %lu\ty1: %lu\tx2: %lu\ty2: %lu", x1, y1, x2, y2);
 
-   if ((x1 == 0) && (y1 == 0))
+   if ((x1 == 0) && (y1 == 0) && (x2 == 0) && (y2 == 0))
    { /* We assume that this is a finger up event */
-      if ( Cyio_PushEvent('R', 1) >= 0 )
+      if (status != FINGER_UP)
       {
-         Cyio_PushEvent((oldX >> 8) & 0xFF, 0);
-          Cyio_PushEvent((oldX >> 0) & 0xFF, 0);
-          Cyio_PushEvent((oldY >> 8) & 0xFF, 0);
-          Cyio_PushEvent((oldY >> 0) & 0xFF, 0);
+         event.flags |= CYEVENT_FLAG_TOUCH_UP;
+         status = FINGER_UP;
       }
+      else
+         goto exit; /* ignore the event   */
    }
    else
    {
-      oldX = 600 - x1;
-      oldY = y1;
+      oldX1 = 600 - x1;
+      oldY1 = y1;
+      
+      if ((x2 != 0) || (y2 != 0))
+      {
+          oldX2 = 600 - x2;
+      	oldY2 = y2;
+      	event.data.touch.fingers = 2;
+      }
+      else
+      {
+      	oldX2 = oldY2 = 0;
+      	event.data.touch.fingers = 1;
+      }
+      
+      if (status == FINGER_UP)
+      {
+         event.flags |= CYEVENT_FLAG_TOUCH_DOWN;
+         status = FINGER_DOWN;
+      }
+      else
+      {
+         event.flags |= CYEVENT_FLAG_TOUCH_MOVE;
+         status = FINGER_MOVE;
+      }
    }
+   
+   event.data.touch.x1 = oldX1;
+   event.data.touch.y1 = oldY1;
+   event.data.touch.x2 = oldX2;
+   event.data.touch.y2 = oldY2;
+   
+   if (status == FINGER_UP)
+      oldX1 = oldY1 = oldX2 = oldY2 = 0;
+
+   CyEvent_PushOrUpdateUniqueEventFlaged(&event, false, CYEVENT_FLASH_TOUCH_MASK);
 
+
+exit:
    /* Say I get the data */
    ots_ackInterrupt();
    
@@ -461,7 +501,7 @@ static void ots_setPowerMode (Ots_PowerModes power)
          ots_setPowerMode(POWER_ON); /* Set myself as Power ON before anything */
 
       //tmpReg = i2c_smbus_read_byte_data(ots_client, 0x24);
-      tmpReg = (((50) /* timeout in ms for auto sleep */ ) & 0x0F) << 4;
+      tmpReg = (((16) /* timeout in ms for auto sleep */ ) & 0x0F) << 4;
       tmpReg |= (1<< 2); /* Activate auto sleep mode */
       tmpReg |= 0x1; /* Set in "Sleep Mode" */
 
@@ -510,7 +550,7 @@ static void ots_setDeviceParameters (unsigned char int_mode,
    tmpReg = i2c_smbus_read_byte_data(ots_client, 0xBE); // TEST
    DBG("0xBE = %02X", tmpReg);
 
-   DBG("Firmware Version =0x%x\n", i2c_smbus_read_byte_data(ots_client, 0x77));
+   printk("TS Firmware Version = 0x%x\n", i2c_smbus_read_byte_data(ots_client, 0x77));
 
    /* Activate the device ! */
 

+ 13 - 9
drivers/mmc/host/s3c-hsmmc.c

@@ -55,6 +55,8 @@
 
 #include <asm/arch/hsmmc.h>
 
+#include <linux/cyevent.h>
+
 /*Qisda , wenny cheng , 20091224 , board id info {*/
 #include <../include/asm-arm/plat-s3c24xx/common-smdk.h>
 /*Qisda , wenny cheng , 20091224 , board id info }*/
@@ -1103,15 +1105,12 @@ out:
 	return result;
 }
 
-
-#include <linux/cyio.h>
-int Cyio_PushEvent(char eventId, char unique);
-
 static irqreturn_t s3c_hsmmc_irq_cd (int irq, void *dev_id)
 {
 	struct s3c_hsmmc_host *host = dev_id;
 	int ext_CD_int = 0;
-
+	CyEvent_t CyEvent = NEW_CYEVENT(CYEVENT_TYPE_SYSTEM);
+	CyEvent.flags |= CYEVENT_FLAG_SD_MESSAGE;
 #if defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
 	ext_CD_int = readl(S3C2410_GPFDAT);
 	ext_CD_int &= 0x2;	/* GPF1 */
@@ -1120,7 +1119,8 @@ static irqreturn_t s3c_hsmmc_irq_cd (int irq, void *dev_id)
 	ext_CD_int &= 0x2000;	/* GPN13 */
 #endif
 	//printk("\ns3c_hsmmc_irq_cd, ext_CD_int: %d, card_detect: %d, card_detect2: %d\n", ext_CD_int, card_detect, card_detect2);
-	if(ext_CD_int && card_detect) {
+	if(ext_CD_int && card_detect)
+	{
 		printk("s3c-hsmmc channel-0(EXT): card removed.\n");
 /*Qisda Qube for sd card detect20091124*/
 		//set_irq_type(host->irq_cd, IRQT_FALLING);
@@ -1133,10 +1133,12 @@ static irqreturn_t s3c_hsmmc_irq_cd (int irq, void *dev_id)
 		card_detect2 = 2;
 	
 		/* Send CyIO event */
-		Cyio_PushEvent(CYEVENT_SD_OUT, 1);
+		/* SD OUT */
+		CyEvent_PushNewUniqueEvent(&CyEvent);
 
 	}
-	else if(!ext_CD_int && !card_detect) {
+	else if(!ext_CD_int && !card_detect) 
+	{
 		printk("s3c-hsmmc channel-0(EXT): card inserted.\n");
 /*Qisda Qube for sd card detect20091124*/
 		//set_irq_type(host->irq_cd, IRQT_RISING);
@@ -1156,7 +1158,9 @@ static irqreturn_t s3c_hsmmc_irq_cd (int irq, void *dev_id)
 
 		}
 		/* Send CyIO event */
-		Cyio_PushEvent(CYEVENT_SD_IN, 1);
+		/* SD IN */
+		CyEvent.flags |= CYEVENT_FLAG_SYS_STATUS;
+		CyEvent_PushNewUniqueEvent(&CyEvent);
 		
 	}
 	//Qisda, Asaku Chen, 2009/11/03 {

+ 40 - 30
drivers/usb/gadget/file_storage.c

@@ -276,8 +276,8 @@ MODULE_LICENSE("Dual BSD/GPL");
  *
  * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
  * Instead:  allocate your own, using normal USB-IF procedures. */
-#define DRIVER_VENDOR_ID	0x0525	// NetChip
-#define DRIVER_PRODUCT_ID	0xa4a5	// Linux-USB File-backed Storage Gadget
+#define DRIVER_VENDOR_ID   0x0525	// NetChip
+#define DRIVER_PRODUCT_ID  0xa4a5	// Linux-USB File-backed Storage Gadget
 
 
 /*
@@ -286,9 +286,17 @@ MODULE_LICENSE("Dual BSD/GPL");
  * and endpoint addresses.
  */
 
+//#define DEBUG
+//#define VERBOSE
 
 /*-------------------------------------------------------------------------*/
 
+#if 0
+#undef dev_printk
+#define dev_printk(level, l, fmt, args...) \
+      printk(KERN_DEBUG DRIVER_NAME ": " fmt, ## args)
+#endif
+
 #define xprintk(f,level,fmt,args...) \
 	dev_printk(level , &(f)->gadget->dev , fmt , ## args)
 #define yprintk(l,level,fmt,args...) \
@@ -358,7 +366,8 @@ static struct {
 
 	int		removable;
 	int		can_stall;
-
+     int       hw_disk_status;
+     
 	char		*transport_parm;
 	char		*protocol_parm;
 	unsigned short	vendor;
@@ -373,18 +382,19 @@ static struct {
 	char		*protocol_name;
 
 } mod_data = {					// Default values
-	.transport_parm		= "BBB",
+	.transport_parm     = "BBB",
 	.protocol_parm		= "SCSI",
 	.removable		= 0,
 	.can_stall		= 1,
 	.vendor			= DRIVER_VENDOR_ID,
-	.product		= DRIVER_PRODUCT_ID,
-	.release		= 0xffff,	// Use controller chip type
+	.product            = DRIVER_PRODUCT_ID,
+	.release            = 0xffff,	// Use controller chip type
 	.buflen			= 16384,
      .serial             = "CYBOR10",
 	};
 
-
+#undef S_IRUGO
+#define S_IRUGO (0644)
 module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames,
 		S_IRUGO);
 MODULE_PARM_DESC(file, "names of backing files or devices");
@@ -404,6 +414,14 @@ MODULE_PARM_DESC(removable, "true to simulate removable media");
 module_param_named(stall, mod_data.can_stall, bool, S_IRUGO);
 MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
 
+module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO);
+MODULE_PARM_DESC(vendor, "USB Vendor ID");
+
+module_param_named(product, mod_data.product, ushort, S_IRUGO);
+MODULE_PARM_DESC(product, "USB Product ID");
+
+module_param_named(serial, mod_data.serial, charp, S_IRUGO);
+MODULE_PARM_DESC(serial, "Device serial number");
 
 /* In the non-TEST version, only the module parameters listed above
  * are available. */
@@ -416,21 +434,12 @@ module_param_named(protocol, mod_data.protocol_parm, charp, S_IRUGO);
 MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, "
 		"8070, or SCSI)");
 
-module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO);
-MODULE_PARM_DESC(vendor, "USB Vendor ID");
-
-module_param_named(product, mod_data.product, ushort, S_IRUGO);
-MODULE_PARM_DESC(product, "USB Product ID");
-
 module_param_named(release, mod_data.release, ushort, S_IRUGO);
 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 */
 
 
@@ -2072,12 +2081,9 @@ static int do_verify(struct fsg_dev *fsg)
 static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
 	u8	*buf = (u8 *) bh->buf;
-/* 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[] = "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;
 		memset(buf, 0, 36);
@@ -2263,7 +2269,6 @@ static int do_start_stop(struct fsg_dev *fsg)
 	loej = fsg->cmnd[4] & 0x02;
 	start = fsg->cmnd[4] & 0x01;
 
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
 	if ((fsg->cmnd[1] & ~0x01) != 0 ||		// Mask away Immed
 			(fsg->cmnd[4] & ~0x03) != 0) {	// Mask LoEj, Start
 		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
@@ -2273,11 +2278,13 @@ static int do_start_stop(struct fsg_dev *fsg)
 	if (!start) {
 
 		/* Are we allowed to unload the media? */
-		if (curlun->prevent_medium_removal) {
+#if 0 /* We can't prevent hardware removal */
+         if (curlun->prevent_medium_removal) {
 			LDBG(curlun, "unload attempt prevented\n");
 			curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED;
 			return -EINVAL;
 		}
+#endif
 		if (loej) {		// Simulate an unload/eject
 			up_read(&fsg->filesem);
 			down_write(&fsg->filesem);
@@ -2294,11 +2301,10 @@ static int do_start_stop(struct fsg_dev *fsg)
 			return -EINVAL;
 		}
 	}
-#endif
+
 	return 0;
 }
 
-
 static int do_prevent_allow(struct fsg_dev *fsg)
 {
 	struct lun	*curlun = fsg->curlun;
@@ -3682,11 +3688,13 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, con
 	struct fsg_dev	*fsg = dev_get_drvdata(dev);
 	int		rc = 0;
 
-	if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) {
-		LDBG(curlun, "eject attempt prevented\n");
-		return -EBUSY;				// "Door is locked"
-	}
-
+#if 0 /* Current hardware can't prevent remove */
+     if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) {
+        LDBG(curlun, "eject attempt prevented\n");
+        return -EBUSY;				// "Door is locked"
+     } /* If file[] is NULL, then the media has been physically removed, we can't allow access to it */
+#endif
+     LDBG(curlun, "Will try to mount floppy [%p] '%s'\n", buf, buf);
 	/* Remove a trailing newline */
 	if (count > 0 && buf[count-1] == '\n')
 		((char *) buf)[count-1] = 0;		// Ugh!
@@ -3694,12 +3702,14 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, con
 	/* Eject current medium */
 	down_write(&fsg->filesem);
 	if (backing_file_is_open(curlun)) {
+          LDBG(curlun, "There is currently a floppy.. Eject it before...\n");
 		close_backing_file(curlun);
 		curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
 	}
 
 	/* Load new medium */
 	if (count > 0 && buf[0]) {
+          LDBG(curlun, "File name is valide, now insert floppy...\n");
 		rc = open_backing_file(curlun, buf);
 		if (rc == 0)
 			curlun->unit_attention_data =
@@ -3889,7 +3899,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 		goto out;
 
 	if (mod_data.removable) {	// Enable the store_xxx attributes
-		dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0644;
+		dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0664;
           dev_attr_status.attr.mode = 0444;
 		dev_attr_ro.store = store_ro;
 		dev_attr_file.store = store_file;

+ 0 - 2
drivers/video/epaper.c

@@ -901,8 +901,6 @@ static inline void s3c2416_i80_write(int data)
 	tmp |= SYS_WR_CON;
 	__raw_writel(tmp, rSIFCCON0);
 
-      if ( !tcon_inPortraitMode )
-      tcon_ndelay(25);
 
 	__raw_writel(data, rSIFCCON1); //rSIFCCON1 = CMD;
 

File diff suppressed because it is too large
+ 361 - 184
drivers/video/epaper/auo-tcon-k1900.c


+ 7 - 6
include/linux/auofb_ioctl.h

@@ -21,7 +21,7 @@
 #ifndef AUOFB_IOCTL_H
 #define AUOFB_IOCTL_H
 
-#define AUO_FIRMWARE_VERSION 33
+#define AUO_FIRMWARE_VERSION 39
 
 #pragma pack(1)
 typedef struct sAUOCommand_t
@@ -45,6 +45,8 @@ typedef struct sAUOCommand_t
 #define IOCTL_AUO_POWERON     (IOCTL_AUO_PREFIX | 0x05)
 #define IOCTL_AUO_POWEROFF    (IOCTL_AUO_PREFIX | 0x06)
 #define IOCTL_AUO_UPDATEFW    (IOCTL_AUO_PREFIX | 0x07)
+#define IOCTL_AUO_PROGRESSBAR (IOCTL_AUO_PREFIX | 0x08)
+#define IOCTL_AUO_WAITBUSY    (IOCTL_AUO_PREFIX | 0x09)
 
 /* Command definition                                                          *
  * 3322 2222 2222 1111 1111 1100 0000 0000                                     *
@@ -68,7 +70,7 @@ typedef struct sAUOCommand_t
 #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 */
+#if (AUO_FIRMWARE_VERSION >= 33) /* Command set for TCON firmware v33 and more */
 
 /* Initialisation commands */
 #define AUOCMD_INIT_SET          SET_AUO_COMMAND(0x0000, 1, 0, 1)
@@ -76,7 +78,7 @@ typedef struct sAUOCommand_t
 #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_STANDBY           SET_AUO_COMMAND(0x0001, 1, 0, 1)
 #define AUOCMD_WAKEUP            SET_AUO_COMMAND(0x0002, 0, 0, 0)
 
 /* Display commands */
@@ -120,7 +122,6 @@ typedef struct sAUOCommand_t
 #define AUO_DSPPARAM_MODE_TEXT       (0x02 << 12) /* Mode 2: Text mode 2bit */
 #define AUO_DSPPARAM_MODE_HIGHSPEED  (0x03 << 12) /* Mode 3: Highspeed mode 1bit */
 #define AUO_DSPPARAM_MODE_HANDWRITE  (0x04 << 12) /* Mode 4: Handwriting mode 1bit */
-#define AUO_DSPPARAM_MODE_AUTOSELECT (0x05 << 12) /* Mode 5: Autoselect mode */
 
 /* INIT_SET command parameters */
 #define AUO_INITPARAM_OUT_DATA_ARR   (0x01 <<  5) /* Set to 0 (default) for normal, 1 for inverse byte order */
@@ -145,12 +146,12 @@ typedef struct sAUOCommand_t
 #define AUO_INITPARAM_DATA_FILTER    (0x01 << 12) /* Data filter (1: active, 0: inactive) */
 #define AUO_INITPARAM_TEMP_AVERAGE   (0x01 << 13) /* Temperature average (1: active, 0: inactive) */
 
-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_READ_WRITE(command) ((command >> 30) & 0x01)
 
+#define AUOCMD_EQUAL(c,v) (((c) & 0xFFFF) == ((v) & 0xFFFF))
+
 #endif /* AUOFB_IOCTL_H */

+ 79 - 24
include/linux/cyevent.h

@@ -1,10 +1,11 @@
 // ===========================================================================
-// cyio.h
+// Cybook Event Manager - cyevent.h
 // Copyright (C) 2008-2010 Bookeen - All rights reserved
 // ===========================================================================
 
-#define CYIO_EVENT_VERSION 1
+#define CYEV_CURRENT_VERSION 0x10 /* 1.0 */
 
+#pragma pack(1)
 typedef struct sCyEvent_t
 {
     unsigned char type;
@@ -19,19 +20,26 @@ typedef struct sCyEvent_t
             unsigned short y1;
             unsigned short x2;
             unsigned short y2;
-        } touch;
-        struct
-        {
-            unsigned char key_ascii;
-        } key;
+            unsigned char fingers;
+        } touch;     
+        unsigned char key;
+        unsigned char orientation;
+        unsigned char timer_type;
     } data;
 } CyEvent_t;
+#pragma pack()
+
+#define NEW_CYEVENT(evType) { \
+   .type = evType, \
+   .flags = 0, \
+   .version = CYEV_CURRENT_VERSION, \
+   .data.raw = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, }
 
 enum
 {
     CYEVENT_TYPE_KEY =                  'k',
     CYEVENT_TYPE_TOUCH =                't',
-    CYEVENT_TYPE_ACCEL =                'a',
+    CYEVENT_TYPE_ORIENTATION =          'o',
     CYEVENT_TYPE_TIMER =                'z',
     CYEVENT_TYPE_SYSTEM =               's',
     //CYIO_EVENT_ = '',
@@ -53,42 +61,69 @@ enum
 #define CYEVENT_KEY_VOLN                '-'
 #define CYEVENT_KEY_TOGGLE_ACCEL        'a'
 #define CYEVENT_KEY_FACTORY_RESET       'f'
+#define CYEVENT_KEY_USB_IN			       'p'
+#define CYEVENT_KEY_USB_OUT		       'P'
+
+/* Timer event */
+#define CYEVENT_TIMER_SCREEN            's'
+#define CYEVENT_TIMER_DEVICE            'd'
+
 
 /* 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) */
+#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)
+#define CYEVENT_FLASH_TOUCH_MASK        (0x3 << 6)
+#define CYEVENT_FLAG_TWO_FINGER_DOWN    (1 << 5)
 
 /* 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_FLAG_USB_MESSAGE        (0x0 << 6) /***< this is an USB event                         */
+//#define CYEVENT_FLAG_AC_MESSAGE         (0x1 << 6) /***< this is an AC event                          */
+#define CYEVENT_FLAG_SD_MESSAGE         (0x2 << 6) /***< this is a SD event                           */
+#define CYEVENT_FLAG_SYS_STATUS		(1 << 5)   /***< this event is a plug (1) or unplug (0) event */
 
+/* These bits are set by the implementation and should not be touched by the driver / receiver */
 /* Bit 3 to Bit 2 are reserved (v1) */
 #define CYEVENT_FLAG_ENDOFREPEAT        (1 << 1)
 #define CYEVENT_FLAG_REPEATEVENT        (1 << 0)
-
-
+// ===========================================================================
+#ifdef __KERNEL__
 // ===========================================================================
 /* Exported function of CyEvent */
-
+int CyEvent_PushNewEvent(CyEvent_t *CyEvent, char wantRepeat);
+int CyEvent_PushNewUniqueEvent(CyEvent_t *CyEvent);
+int CyEvent_PushOrUpdateUniqueEvent(CyEvent_t *CyEvent, char wantRepeat);
+int CyEvent_PushOrUpdateUniqueEventFlaged(CyEvent_t *CyEvent, char wantRepeat, unsigned char flagMask);
+int CyEvent_InvalidateUniqueEvent(CyEvent_t *CyEvent);
+int CyEvent_InvalidateRepeatableEvent(CyEvent_t *CyEvent);
+// ===========================================================================
+typedef void (*callback_func)(void);
+typedef void (*callback2_func)(unsigned char data);
+typedef int (*ioctl_func)(unsigned int cmd, unsigned long arg);
+typedef struct cyevent_device
+{
+    callback_func resume, suspend, deepsleep;
+    callback2_func event_read;
+    callback_func event_listempty;
+    ioctl_func ioctl;
+    unsigned int ioctl_prefix;
+    unsigned char event_read_listen; /* 0 here mean all events */
+} cyevent_device;
+#define NEW_CYDEV() { .resume = NULL, .suspend = NULL, .deepsleep = NULL .ioctl = NULL,\
+                      .event_listempty = NULL, .event_read = NULL, .event_read_listen = 0, }
+#define IOCTL_PFX(c) ((c & 0xFF) << 8)
+int CyEvent_RegisterDevice(cyevent_device *dev);
+int CyEvent_DeregisterDevice(cyevent_device *dev);
+// ===========================================================================
+#endif
 // ===========================================================================
-
-
-
-
 /* TODO: This part should be moved elsewhere... */
 // ===========================================================================
 /* Non directly CyIO related values, but used for the Accelerometer */
@@ -106,3 +141,23 @@ 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 & 0xFF) << 8) | (v & 0xFF))
+
+#define GET_IOCTL_PREFIX(c) (c & 0xFF00)
+
+#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)

Some files were not shown because too many files changed in this diff