summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
diff options
context:
space:
mode:
authorJean-Louis Biasini <jlbiasini@gmail.com>2013-07-30 00:29:04 +0300
committerAmaury Pouly <amaury.pouly@gmail.com>2013-08-19 13:37:57 +0200
commit8d2e4f9b7d33f2d086d6e6a555739ffe0f51ca9c (patch)
tree587e2a73be84fd137dcac7d541c7a95edae91bd9 /firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
parentce714cb023c6f50bf46b5dd8a056660acaf647f1 (diff)
downloadrockbox-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/sansa-fuzeplus/button-fuzeplus.c')
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c140
1 files changed, 89 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
204static int touchpad_btns = 0; 210static int touchpad_btns = 0;
205static long rmi_stack [DEFAULT_STACK_SIZE/sizeof(long)]; 211static long rmi_stack [DEFAULT_STACK_SIZE/sizeof(long)];
206static const char rmi_thread_name[] = "rmi"; 212static const char rmi_thread_name[] = "rmi";
207static struct event_queue rmi_queue; 213static struct event_queue rmi_queue;
214static unsigned last_activity = 0;
215static bool t_enable = true;
208 216
209static int find_button(int x, int y) 217static 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
244static 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
277void 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
236void touchpad_set_sensitivity(int level) 283void 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);