diff options
author | Jean-Louis Biasini <jlbiasini@gmail.com> | 2013-07-30 00:29:04 +0300 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2013-08-19 13:37:57 +0200 |
commit | 8d2e4f9b7d33f2d086d6e6a555739ffe0f51ca9c (patch) | |
tree | 587e2a73be84fd137dcac7d541c7a95edae91bd9 /firmware/target/arm/imx233 | |
parent | ce714cb023c6f50bf46b5dd8a056660acaf647f1 (diff) | |
download | rockbox-8d2e4f9b7d33f2d086d6e6a555739ffe0f51ca9c.tar.gz rockbox-8d2e4f9b7d33f2d086d6e6a555739ffe0f51ca9c.zip |
[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>
Diffstat (limited to 'firmware/target/arm/imx233')
-rw-r--r-- | firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c | 140 | ||||
-rw-r--r-- | firmware/target/arm/imx233/sansa-fuzeplus/button-target.h | 1 |
2 files changed, 90 insertions, 51 deletions
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c index 1474e067c1..afabdd3bc3 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) | |||
42 | int sensor_resol = rmi_read_single(RMI_2D_SENSOR_RESOLUTION(0)); | 42 | int sensor_resol = rmi_read_single(RMI_2D_SENSOR_RESOLUTION(0)); |
43 | int min_dist = rmi_read_single(RMI_2D_MIN_DIST); | 43 | int min_dist = rmi_read_single(RMI_2D_MIN_DIST); |
44 | int gesture_settings = rmi_read_single(RMI_2D_GESTURE_SETTINGS); | 44 | int gesture_settings = rmi_read_single(RMI_2D_GESTURE_SETTINGS); |
45 | int sensibility_counter = 0; | 45 | int volkeys_delay_counter = 0; |
46 | union | 46 | union |
47 | { | 47 | { |
48 | unsigned char data; | 48 | unsigned char data; |
@@ -72,6 +72,7 @@ bool button_debug_screen(void) | |||
72 | 72 | ||
73 | while(1) | 73 | while(1) |
74 | { | 74 | { |
75 | unsigned char sleep_mode = rmi_read_single(RMI_DEVICE_CONTROL) & RMI_SLEEP_MODE_BM; | ||
75 | lcd_set_viewport(NULL); | 76 | lcd_set_viewport(NULL); |
76 | lcd_clear_display(); | 77 | lcd_clear_display(); |
77 | int btns = button_read_device(); | 78 | int btns = button_read_device(); |
@@ -84,7 +85,7 @@ bool button_debug_screen(void) | |||
84 | rmi_read_single(RMI_INTERRUPT_REQUEST)); | 85 | rmi_read_single(RMI_INTERRUPT_REQUEST)); |
85 | lcd_putsf(0, 4, "sensi: %d min_dist: %d", (int)sensitivity.value, min_dist); | 86 | lcd_putsf(0, 4, "sensi: %d min_dist: %d", (int)sensitivity.value, min_dist); |
86 | lcd_putsf(0, 5, "gesture: %x", gesture_settings); | 87 | lcd_putsf(0, 5, "gesture: %x", gesture_settings); |
87 | 88 | ||
88 | union | 89 | union |
89 | { | 90 | { |
90 | unsigned char data[10]; | 91 | unsigned char data[10]; |
@@ -100,12 +101,13 @@ bool button_debug_screen(void) | |||
100 | int nr_fingers = u.s.absolute.misc & 7; | 101 | int nr_fingers = u.s.absolute.misc & 7; |
101 | bool gesture = (u.s.absolute.misc & 8) == 8; | 102 | bool gesture = (u.s.absolute.misc & 8) == 8; |
102 | int palm_width = u.s.absolute.misc >> 4; | 103 | int palm_width = u.s.absolute.misc >> 4; |
104 | |||
103 | rmi_read(RMI_DATA_REGISTER(0), 10, u.data); | 105 | rmi_read(RMI_DATA_REGISTER(0), 10, u.data); |
104 | lcd_putsf(0, 6, "abs: %d %d %d", absolute_x, absolute_y, (int)u.s.absolute.z); | 106 | lcd_putsf(0, 6, "abs: %d %d %d", absolute_x, absolute_y, (int)u.s.absolute.z); |
105 | lcd_putsf(0, 7, "rel: %d %d", (int)u.s.relative.x, (int)u.s.relative.y); | 107 | lcd_putsf(0, 7, "rel: %d %d", (int)u.s.relative.x, (int)u.s.relative.y); |
106 | lcd_putsf(0, 8, "gesture: %x %x", u.s.gesture.misc, u.s.gesture.flick); | 108 | lcd_putsf(0, 8, "gesture: %x %x", u.s.gesture.misc, u.s.gesture.flick); |
107 | lcd_putsf(0, 9, "misc: w=%d g=%d f=%d", palm_width, gesture, nr_fingers); | 109 | lcd_putsf(0, 9, "misc: w=%d g=%d f=%d", palm_width, gesture, nr_fingers); |
108 | 110 | lcd_putsf(30, 7, "sleep_mode: %d", 1 - sleep_mode); | |
109 | lcd_set_viewport(&report_vp); | 111 | lcd_set_viewport(&report_vp); |
110 | lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0xff, 0, 0), LCD_BLACK); | 112 | lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0xff, 0, 0), LCD_BLACK); |
111 | lcd_drawrect(0, 0, zone_w, zone_h); | 113 | lcd_drawrect(0, 0, zone_w, zone_h); |
@@ -153,21 +155,22 @@ bool button_debug_screen(void) | |||
153 | } | 155 | } |
154 | } | 156 | } |
155 | lcd_update(); | 157 | lcd_update(); |
156 | |||
157 | if(btns & BUTTON_POWER) | 158 | if(btns & BUTTON_POWER) |
158 | break; | 159 | break; |
159 | if(btns & BUTTON_VOL_DOWN || btns & BUTTON_VOL_UP) | 160 | if(btns & (BUTTON_VOL_DOWN|BUTTON_VOL_UP)) |
160 | { | 161 | { |
161 | if(btns & BUTTON_VOL_UP) | 162 | volkeys_delay_counter++; |
162 | sensibility_counter++; | 163 | if(volkeys_delay_counter == 15) |
163 | if(btns & BUTTON_VOL_DOWN) | ||
164 | sensibility_counter--; | ||
165 | if((sensibility_counter == -15) || (sensibility_counter == 15)) | ||
166 | { | 164 | { |
167 | sensitivity.value += (sensibility_counter / 15); | 165 | if(btns & BUTTON_VOL_UP) |
168 | sensibility_counter = 0; | 166 | if(sleep_mode > RMI_SLEEP_MODE_FORCE_FULLY_AWAKE) |
167 | sleep_mode--; | ||
168 | if(btns & BUTTON_VOL_DOWN) | ||
169 | if(sleep_mode < RMI_SLEEP_MODE_SENSOR_SLEEP) | ||
170 | sleep_mode++; | ||
171 | rmi_set_sleep_mode(sleep_mode); | ||
172 | volkeys_delay_counter = 0; | ||
169 | } | 173 | } |
170 | rmi_write(RMI_2D_SENSITIVITY_ADJ, 1, &sensitivity.data); | ||
171 | } | 174 | } |
172 | 175 | ||
173 | yield(); | 176 | yield(); |
@@ -200,11 +203,16 @@ static struct button_area_t button_areas[] = | |||
200 | 203 | ||
201 | #define RMI_INTERRUPT 1 | 204 | #define RMI_INTERRUPT 1 |
202 | #define RMI_SET_SENSITIVITY 2 | 205 | #define RMI_SET_SENSITIVITY 2 |
206 | #define RMI_SET_SLEEP_MODE 3 | ||
207 | /* timeout before lowering touchpad power from lack of activity */ | ||
208 | #define ACTIVITY_TMO (5 * HZ) | ||
203 | 209 | ||
204 | static int touchpad_btns = 0; | 210 | static int touchpad_btns = 0; |
205 | static long rmi_stack [DEFAULT_STACK_SIZE/sizeof(long)]; | 211 | static long rmi_stack [DEFAULT_STACK_SIZE/sizeof(long)]; |
206 | static const char rmi_thread_name[] = "rmi"; | 212 | static const char rmi_thread_name[] = "rmi"; |
207 | static struct event_queue rmi_queue; | 213 | static struct event_queue rmi_queue; |
214 | static unsigned last_activity = 0; | ||
215 | static bool t_enable = true; | ||
208 | 216 | ||
209 | static int find_button(int x, int y) | 217 | static int find_button(int x, int y) |
210 | { | 218 | { |
@@ -233,6 +241,45 @@ static void rmi_attn_cb(int bank, int pin, intptr_t user) | |||
233 | queue_post(&rmi_queue, RMI_INTERRUPT, 0); | 241 | queue_post(&rmi_queue, RMI_INTERRUPT, 0); |
234 | } | 242 | } |
235 | 243 | ||
244 | static void do_interrupt(void) | ||
245 | { | ||
246 | /* rmi_set_sleep_mode() does not do anything if the value | ||
247 | * it is given is already the one setted */ | ||
248 | rmi_set_sleep_mode(RMI_SLEEP_MODE_LOW_POWER); | ||
249 | last_activity = current_tick; | ||
250 | /* clear interrupt */ | ||
251 | rmi_read_single(RMI_INTERRUPT_REQUEST); | ||
252 | /* read data */ | ||
253 | union | ||
254 | { | ||
255 | unsigned char data[10]; | ||
256 | struct | ||
257 | { | ||
258 | struct rmi_2d_absolute_data_t absolute; | ||
259 | struct rmi_2d_relative_data_t relative; | ||
260 | struct rmi_2d_gesture_data_t gesture; | ||
261 | }s; | ||
262 | }u; | ||
263 | rmi_read(RMI_DATA_REGISTER(0), 10, u.data); | ||
264 | int absolute_x = u.s.absolute.x_msb << 8 | u.s.absolute.x_lsb; | ||
265 | int absolute_y = u.s.absolute.y_msb << 8 | u.s.absolute.y_lsb; | ||
266 | int nr_fingers = u.s.absolute.misc & 7; | ||
267 | |||
268 | if(nr_fingers == 1) | ||
269 | touchpad_btns = find_button(absolute_x, absolute_y); | ||
270 | else | ||
271 | touchpad_btns = 0; | ||
272 | |||
273 | /* enable interrupt */ | ||
274 | imx233_pinctrl_setup_irq(0, 27, true, true, false, &rmi_attn_cb, 0); | ||
275 | } | ||
276 | |||
277 | void touchdev_enable(bool en) | ||
278 | { | ||
279 | t_enable = en; | ||
280 | queue_post(&rmi_queue, RMI_SET_SLEEP_MODE, en ? RMI_SLEEP_MODE_LOW_POWER : RMI_SLEEP_MODE_SENSOR_SLEEP); | ||
281 | } | ||
282 | |||
236 | void touchpad_set_sensitivity(int level) | 283 | void touchpad_set_sensitivity(int level) |
237 | { | 284 | { |
238 | queue_post(&rmi_queue, RMI_SET_SENSITIVITY, level); | 285 | queue_post(&rmi_queue, RMI_SET_SENSITIVITY, level); |
@@ -244,47 +291,36 @@ static void rmi_thread(void) | |||
244 | 291 | ||
245 | while(1) | 292 | while(1) |
246 | { | 293 | { |
247 | queue_wait(&rmi_queue, &ev); | 294 | /* make sure to timeout often enough for the activity timeout to take place */ |
295 | queue_wait_w_tmo(&rmi_queue, &ev, HZ); | ||
248 | /* handle usb connect and ignore all messages except rmi interrupts */ | 296 | /* handle usb connect and ignore all messages except rmi interrupts */ |
249 | if(ev.id == SYS_USB_CONNECTED) | 297 | switch(ev.id) |
250 | { | ||
251 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | ||
252 | continue; | ||
253 | } | ||
254 | else if(ev.id == RMI_SET_SENSITIVITY) | ||
255 | { | 298 | { |
256 | /* handle negative values as well ! */ | 299 | case SYS_USB_CONNECTED: |
257 | rmi_write_single(RMI_2D_SENSITIVITY_ADJ, (unsigned char)(int8_t)ev.data); | 300 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
258 | continue; | 301 | break; |
302 | case RMI_SET_SENSITIVITY: | ||
303 | /* handle negative values as well ! */ | ||
304 | rmi_write_single(RMI_2D_SENSITIVITY_ADJ, (unsigned char)(int8_t)ev.data); | ||
305 | break; | ||
306 | case RMI_SET_SLEEP_MODE: | ||
307 | /* reset activity */ | ||
308 | last_activity = current_tick; | ||
309 | rmi_set_sleep_mode(ev.data); | ||
310 | break; | ||
311 | case RMI_INTERRUPT: | ||
312 | do_interrupt(); | ||
313 | break; | ||
314 | default: | ||
315 | /* activity timeout */ | ||
316 | if(TIME_AFTER(current_tick, last_activity + ACTIVITY_TMO)) | ||
317 | { | ||
318 | /* don't change power mode if touchpad is disabled, it's already in sleep mode */ | ||
319 | if(t_enable) | ||
320 | rmi_set_sleep_mode(RMI_SLEEP_MODE_VERY_LOW_POWER); | ||
321 | } | ||
322 | break; | ||
259 | } | 323 | } |
260 | else if(ev.id != RMI_INTERRUPT) | ||
261 | continue; | ||
262 | /* clear interrupt */ | ||
263 | rmi_read_single(RMI_INTERRUPT_REQUEST); | ||
264 | /* read data */ | ||
265 | union | ||
266 | { | ||
267 | unsigned char data[10]; | ||
268 | struct | ||
269 | { | ||
270 | struct rmi_2d_absolute_data_t absolute; | ||
271 | struct rmi_2d_relative_data_t relative; | ||
272 | struct rmi_2d_gesture_data_t gesture; | ||
273 | }s; | ||
274 | }u; | ||
275 | rmi_read(RMI_DATA_REGISTER(0), 10, u.data); | ||
276 | int absolute_x = u.s.absolute.x_msb << 8 | u.s.absolute.x_lsb; | ||
277 | int absolute_y = u.s.absolute.y_msb << 8 | u.s.absolute.y_lsb; | ||
278 | int nr_fingers = u.s.absolute.misc & 7; | ||
279 | |||
280 | |||
281 | if(nr_fingers == 1) | ||
282 | touchpad_btns = find_button(absolute_x, absolute_y); | ||
283 | else | ||
284 | touchpad_btns = 0; | ||
285 | |||
286 | /* enable interrupt */ | ||
287 | imx233_pinctrl_setup_irq(0, 27, true, true, false, &rmi_attn_cb, 0); | ||
288 | } | 324 | } |
289 | } | 325 | } |
290 | 326 | ||
@@ -337,6 +373,8 @@ void button_init_device(void) | |||
337 | queue_init(&rmi_queue, true); | 373 | queue_init(&rmi_queue, true); |
338 | create_thread(rmi_thread, rmi_stack, sizeof(rmi_stack), 0, | 374 | create_thread(rmi_thread, rmi_stack, sizeof(rmi_stack), 0, |
339 | rmi_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU)); | 375 | rmi_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU)); |
376 | /* low power mode seems to be enough for normal use */ | ||
377 | rmi_set_sleep_mode(RMI_SLEEP_MODE_LOW_POWER); | ||
340 | /* enable interrupt */ | 378 | /* enable interrupt */ |
341 | imx233_pinctrl_acquire(0, 27, "touchpad int"); | 379 | imx233_pinctrl_acquire(0, 27, "touchpad int"); |
342 | imx233_pinctrl_set_function(0, 27, PINCTRL_FUNCTION_GPIO); | 380 | 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 58e8d3179c..1c94b76cdc 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 @@ | |||
24 | #include <stdbool.h> | 24 | #include <stdbool.h> |
25 | bool button_debug_screen(void); | 25 | bool button_debug_screen(void); |
26 | void touchpad_set_sensitivity(int level); | 26 | void touchpad_set_sensitivity(int level); |
27 | void touchdev_enable(bool en); | ||
27 | 28 | ||
28 | /* Main unit's buttons */ | 29 | /* Main unit's buttons */ |
29 | #define BUTTON_POWER 0x00000001 | 30 | #define BUTTON_POWER 0x00000001 |