[prev in list] [next in list] [prev in thread] [next in thread] 

List:       rockbox-cvs
Subject:    [Fuze+][Touchpad] Improve touchpad power managment
From:       gerrit () rockbox ! org
Date:       2013-08-19 11:38:02
Message-ID: 201308191138.r7JBc2ZS020469 () giant ! haxx ! se
[Download RAW message or body]

commit 8d2e4f9b7d33f2d086d6e6a555739ffe0f51ca9c
Author: Jean-Louis Biasini <jlbiasini@gmail.com>
Date:   Tue Jul 30 00:29:04 2013 +0300

    [Fuze+][Touchpad] Improve touchpad power managment
    
    - take advantage of the new rmi power function implemented to:
    1) lower usual power_mode to low_power as it seems to be enough and might save
    some battery
    2) implement a system that lower that state to very_low_power
    after 1 minute of inactivity.
    3) implement touchdev_enable(bool) that can be use later to disable the
    touchpad when needed
    4) improve the debug screen report of the current power state and
    changing the power state using volume keys
    
    Change-Id: I0b372696d4b2bef5360c778d0500870fd9badee1
    Reviewed-on: http://gerrit.rockbox.org/525
    Reviewed-by: Amaury Pouly <amaury.pouly@gmail.com>

diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c \
b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c index 1474e06..afabdd3 \
                100644
--- a/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
@@ -42,7 +42,7 @@ bool button_debug_screen(void)
     int sensor_resol = rmi_read_single(RMI_2D_SENSOR_RESOLUTION(0));
     int min_dist = rmi_read_single(RMI_2D_MIN_DIST);
     int gesture_settings = rmi_read_single(RMI_2D_GESTURE_SETTINGS);
-    int sensibility_counter = 0;
+    int volkeys_delay_counter = 0;
     union
     {
         unsigned char data;
@@ -72,6 +72,7 @@ bool button_debug_screen(void)
     
     while(1)
     {
+        unsigned char sleep_mode = rmi_read_single(RMI_DEVICE_CONTROL) & \
RMI_SLEEP_MODE_BM;  lcd_set_viewport(NULL);
         lcd_clear_display();
         int btns = button_read_device();
@@ -84,7 +85,7 @@ bool button_debug_screen(void)
             rmi_read_single(RMI_INTERRUPT_REQUEST));
         lcd_putsf(0, 4, "sensi: %d min_dist: %d", (int)sensitivity.value, min_dist);
         lcd_putsf(0, 5, "gesture: %x", gesture_settings);
-        
+
         union
         {
             unsigned char data[10];
@@ -100,12 +101,13 @@ bool button_debug_screen(void)
         int nr_fingers = u.s.absolute.misc & 7;
         bool gesture = (u.s.absolute.misc & 8) == 8;
         int palm_width = u.s.absolute.misc >> 4;
+
         rmi_read(RMI_DATA_REGISTER(0), 10, u.data);
         lcd_putsf(0, 6, "abs: %d %d %d", absolute_x, absolute_y, \
                (int)u.s.absolute.z);
         lcd_putsf(0, 7, "rel: %d %d", (int)u.s.relative.x, (int)u.s.relative.y);
         lcd_putsf(0, 8, "gesture: %x %x", u.s.gesture.misc, u.s.gesture.flick);
         lcd_putsf(0, 9, "misc: w=%d g=%d f=%d", palm_width, gesture, nr_fingers);
-
+        lcd_putsf(30, 7, "sleep_mode: %d", 1 - sleep_mode);
         lcd_set_viewport(&report_vp);
         lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0xff, 0, 0), LCD_BLACK);
         lcd_drawrect(0, 0, zone_w, zone_h);
@@ -153,21 +155,22 @@ bool button_debug_screen(void)
             }
         }
         lcd_update();
-        
         if(btns & BUTTON_POWER)
             break;
-        if(btns & BUTTON_VOL_DOWN || btns & BUTTON_VOL_UP)
+        if(btns & (BUTTON_VOL_DOWN|BUTTON_VOL_UP))
         {
-            if(btns & BUTTON_VOL_UP)
-                sensibility_counter++;
-            if(btns & BUTTON_VOL_DOWN)
-                sensibility_counter--;
-            if((sensibility_counter == -15) || (sensibility_counter == 15))
+            volkeys_delay_counter++;
+            if(volkeys_delay_counter == 15)
             {
-                sensitivity.value += (sensibility_counter / 15);
-                sensibility_counter = 0;
+                if(btns & BUTTON_VOL_UP)
+                    if(sleep_mode > RMI_SLEEP_MODE_FORCE_FULLY_AWAKE)
+                        sleep_mode--;
+                if(btns & BUTTON_VOL_DOWN)
+                    if(sleep_mode < RMI_SLEEP_MODE_SENSOR_SLEEP)
+                        sleep_mode++;
+                rmi_set_sleep_mode(sleep_mode);
+                volkeys_delay_counter = 0;
             }
-            rmi_write(RMI_2D_SENSITIVITY_ADJ, 1, &sensitivity.data); 
         }
         
         yield();
@@ -200,11 +203,16 @@ static struct button_area_t button_areas[] =
 
 #define RMI_INTERRUPT       1
 #define RMI_SET_SENSITIVITY 2
+#define RMI_SET_SLEEP_MODE  3
+/* timeout before lowering touchpad power from lack of activity */
+#define ACTIVITY_TMO (5 * HZ)
 
 static int touchpad_btns = 0;
 static long rmi_stack [DEFAULT_STACK_SIZE/sizeof(long)];
 static const char rmi_thread_name[] = "rmi";
 static struct event_queue rmi_queue;
+static unsigned last_activity = 0;
+static bool t_enable = true;
 
 static int find_button(int x, int y)
 {
@@ -233,6 +241,45 @@ static void rmi_attn_cb(int bank, int pin, intptr_t user)
     queue_post(&rmi_queue, RMI_INTERRUPT, 0);
 }
 
+static void do_interrupt(void)
+{
+    /* rmi_set_sleep_mode() does not do anything if the value
+     * it is given is already the one setted */
+    rmi_set_sleep_mode(RMI_SLEEP_MODE_LOW_POWER);
+    last_activity = current_tick;
+    /* clear interrupt */
+    rmi_read_single(RMI_INTERRUPT_REQUEST);
+    /* read data */
+    union
+    {
+        unsigned char data[10];
+        struct
+        {
+            struct rmi_2d_absolute_data_t absolute;
+            struct rmi_2d_relative_data_t relative;
+            struct rmi_2d_gesture_data_t gesture;
+        }s;
+    }u;
+    rmi_read(RMI_DATA_REGISTER(0), 10, u.data);
+    int absolute_x = u.s.absolute.x_msb << 8 | u.s.absolute.x_lsb;
+    int absolute_y = u.s.absolute.y_msb << 8 | u.s.absolute.y_lsb;
+    int nr_fingers = u.s.absolute.misc & 7;
+
+    if(nr_fingers == 1)
+        touchpad_btns = find_button(absolute_x, absolute_y);
+    else
+        touchpad_btns = 0;
+
+    /* enable interrupt */
+    imx233_pinctrl_setup_irq(0, 27, true, true, false, &rmi_attn_cb, 0);
+}
+
+void touchdev_enable(bool en)
+{
+    t_enable = en;
+    queue_post(&rmi_queue, RMI_SET_SLEEP_MODE, en ? RMI_SLEEP_MODE_LOW_POWER : \
RMI_SLEEP_MODE_SENSOR_SLEEP); +}
+
 void touchpad_set_sensitivity(int level)
 {
     queue_post(&rmi_queue, RMI_SET_SENSITIVITY, level);
@@ -244,47 +291,36 @@ static void rmi_thread(void)
     
     while(1)
     {
-        queue_wait(&rmi_queue, &ev);
+        /* make sure to timeout often enough for the activity timeout to take place \
*/ +        queue_wait_w_tmo(&rmi_queue, &ev, HZ);
         /* handle usb connect and ignore all messages except rmi interrupts */
-        if(ev.id == SYS_USB_CONNECTED)
-        {
-            usb_acknowledge(SYS_USB_CONNECTED_ACK);
-            continue;
-        }
-        else if(ev.id == RMI_SET_SENSITIVITY)
+        switch(ev.id)
         {
-            /* handle negative values as well ! */
-            rmi_write_single(RMI_2D_SENSITIVITY_ADJ, (unsigned \
                char)(int8_t)ev.data);
-            continue;
+            case SYS_USB_CONNECTED:
+                usb_acknowledge(SYS_USB_CONNECTED_ACK);
+                break;
+            case RMI_SET_SENSITIVITY:
+                /* handle negative values as well ! */
+                rmi_write_single(RMI_2D_SENSITIVITY_ADJ, (unsigned \
char)(int8_t)ev.data); +                break;
+            case RMI_SET_SLEEP_MODE:
+                /* reset activity */
+                last_activity = current_tick;
+                rmi_set_sleep_mode(ev.data);
+                break;
+            case RMI_INTERRUPT:
+                do_interrupt();
+                break;
+            default:
+                /* activity timeout */
+                if(TIME_AFTER(current_tick, last_activity + ACTIVITY_TMO))
+                {
+                    /* don't change power mode if touchpad is disabled, it's already \
in sleep mode */ +                    if(t_enable)
+                        rmi_set_sleep_mode(RMI_SLEEP_MODE_VERY_LOW_POWER);
+                }
+                break;
         }
-        else if(ev.id != RMI_INTERRUPT)
-            continue;
-        /* clear interrupt */
-        rmi_read_single(RMI_INTERRUPT_REQUEST);
-        /* read data */
-        union
-        {
-            unsigned char data[10];
-            struct
-            {
-                struct rmi_2d_absolute_data_t absolute;
-                struct rmi_2d_relative_data_t relative;
-                struct rmi_2d_gesture_data_t gesture;
-            }s;
-        }u;
-        rmi_read(RMI_DATA_REGISTER(0), 10, u.data);
-        int absolute_x = u.s.absolute.x_msb << 8 | u.s.absolute.x_lsb;
-        int absolute_y = u.s.absolute.y_msb << 8 | u.s.absolute.y_lsb;
-        int nr_fingers = u.s.absolute.misc & 7;
-
-
-        if(nr_fingers == 1)
-            touchpad_btns = find_button(absolute_x, absolute_y);
-        else
-            touchpad_btns = 0;
-        
-        /* enable interrupt */
-        imx233_pinctrl_setup_irq(0, 27, true, true, false, &rmi_attn_cb, 0);
     }
 }
 
@@ -337,6 +373,8 @@ void button_init_device(void)
     queue_init(&rmi_queue, true);
     create_thread(rmi_thread, rmi_stack, sizeof(rmi_stack), 0,
             rmi_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
+    /* low power mode seems to be enough for normal use */
+    rmi_set_sleep_mode(RMI_SLEEP_MODE_LOW_POWER);
     /* enable interrupt */
     imx233_pinctrl_acquire(0, 27, "touchpad int");
     imx233_pinctrl_set_function(0, 27, PINCTRL_FUNCTION_GPIO);
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h \
b/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h index 58e8d31..1c94b76 \
                100644
--- a/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h
@@ -24,6 +24,7 @@
 #include <stdbool.h>
 bool button_debug_screen(void);
 void touchpad_set_sensitivity(int level);
+void touchdev_enable(bool en);
 
 /* Main unit's buttons */
 #define BUTTON_POWER                0x00000001
_______________________________________________
rockbox-cvs mailing list
rockbox-cvs@cool.haxx.se
http://cool.haxx.se/cgi-bin/mailman/listinfo/rockbox-cvs


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic