diff options
Diffstat (limited to 'firmware/drivers/button.c')
-rw-r--r-- | firmware/drivers/button.c | 106 |
1 files changed, 71 insertions, 35 deletions
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c index d47a486b43..fe9040cef8 100644 --- a/firmware/drivers/button.c +++ b/firmware/drivers/button.c | |||
@@ -371,21 +371,75 @@ static void button_tick(void) | |||
371 | } | 371 | } |
372 | 372 | ||
373 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 373 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
374 | static bool button_boosted = false; | ||
375 | static long button_unboost_tick; | ||
376 | #define BUTTON_UNBOOST_TMO HZ | ||
377 | |||
374 | static void button_boost(bool state) | 378 | static void button_boost(bool state) |
375 | { | 379 | { |
376 | static bool boosted = false; | 380 | if (state) |
377 | |||
378 | if (state && !boosted) | ||
379 | { | 381 | { |
380 | cpu_boost(true); | 382 | button_unboost_tick = current_tick + BUTTON_UNBOOST_TMO; |
381 | boosted = true; | 383 | |
384 | if (!button_boosted) | ||
385 | { | ||
386 | button_boosted = true; | ||
387 | cpu_boost(true); | ||
388 | } | ||
382 | } | 389 | } |
383 | else if (!state && boosted) | 390 | else if (!state && button_boosted) |
384 | { | 391 | { |
392 | button_boosted = false; | ||
385 | cpu_boost(false); | 393 | cpu_boost(false); |
386 | boosted = false; | ||
387 | } | 394 | } |
388 | } | 395 | } |
396 | |||
397 | static void button_queue_wait(struct queue_event *evp, int timeout) | ||
398 | { | ||
399 | /* Loop once after wait time if boosted in order to unboost and wait the | ||
400 | full remaining time */ | ||
401 | do | ||
402 | { | ||
403 | int ticks = timeout; | ||
404 | |||
405 | if (ticks == 0) /* TIMEOUT_NOBLOCK */ | ||
406 | ; | ||
407 | else if (ticks > 0) | ||
408 | { | ||
409 | if (button_boosted && ticks > BUTTON_UNBOOST_TMO) | ||
410 | ticks = BUTTON_UNBOOST_TMO; | ||
411 | |||
412 | timeout -= ticks; | ||
413 | } | ||
414 | else /* TIMEOUT_BLOCK (ticks < 0) */ | ||
415 | { | ||
416 | if (button_boosted) | ||
417 | ticks = BUTTON_UNBOOST_TMO; | ||
418 | } | ||
419 | |||
420 | queue_wait_w_tmo(&button_queue, evp, ticks); | ||
421 | if (evp->id != SYS_TIMEOUT) | ||
422 | { | ||
423 | /* GUI boost build gets immediate kick, otherwise at least 3 | ||
424 | messages had to be there */ | ||
425 | #ifndef HAVE_GUI_BOOST | ||
426 | if (queue_count(&button_queue) >= 2) | ||
427 | #endif | ||
428 | button_boost(true); | ||
429 | |||
430 | break; | ||
431 | } | ||
432 | |||
433 | if (button_boosted && TIME_AFTER(current_tick, button_unboost_tick)) | ||
434 | button_boost(false); | ||
435 | } | ||
436 | while (timeout); | ||
437 | } | ||
438 | #else /* ndef HAVE_ADJUSTABLE_CPU_FREQ */ | ||
439 | static inline void button_queue_wait(struct queue_event *evp, int timeout) | ||
440 | { | ||
441 | queue_wait_w_timeout(&button_queue, evp, timeout); | ||
442 | } | ||
389 | #endif /* HAVE_ADJUSTABLE_CPU_FREQ */ | 443 | #endif /* HAVE_ADJUSTABLE_CPU_FREQ */ |
390 | 444 | ||
391 | int button_queue_count( void ) | 445 | int button_queue_count( void ) |
@@ -396,44 +450,26 @@ int button_queue_count( void ) | |||
396 | long button_get(bool block) | 450 | long button_get(bool block) |
397 | { | 451 | { |
398 | struct queue_event ev; | 452 | struct queue_event ev; |
399 | int pending_count = queue_count(&button_queue); | 453 | button_queue_wait(&ev, block ? TIMEOUT_BLOCK : TIMEOUT_NOBLOCK); |
400 | 454 | ||
401 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 455 | if (ev.id == SYS_TIMEOUT) |
402 | /* Control the CPU boost trying to keep queue empty. */ | 456 | ev.id = BUTTON_NONE; |
403 | if (pending_count == 0) | 457 | else |
404 | button_boost(false); | ||
405 | else if (pending_count > 2) | ||
406 | button_boost(true); | ||
407 | #endif | ||
408 | |||
409 | if ( block || pending_count ) | ||
410 | { | ||
411 | queue_wait(&button_queue, &ev); | ||
412 | |||
413 | button_data = ev.data; | 458 | button_data = ev.data; |
414 | return ev.id; | 459 | |
415 | } | 460 | return ev.id; |
416 | |||
417 | return BUTTON_NONE; | ||
418 | } | 461 | } |
419 | 462 | ||
420 | long button_get_w_tmo(int ticks) | 463 | long button_get_w_tmo(int ticks) |
421 | { | 464 | { |
422 | struct queue_event ev; | 465 | struct queue_event ev; |
423 | 466 | button_queue_wait(&ev, ticks); | |
424 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 467 | |
425 | /* Be sure to keep boosted state. */ | ||
426 | if (!queue_empty(&button_queue)) | ||
427 | return button_get(true); | ||
428 | |||
429 | button_boost(false); | ||
430 | #endif | ||
431 | |||
432 | queue_wait_w_tmo(&button_queue, &ev, ticks); | ||
433 | if (ev.id == SYS_TIMEOUT) | 468 | if (ev.id == SYS_TIMEOUT) |
434 | ev.id = BUTTON_NONE; | 469 | ev.id = BUTTON_NONE; |
435 | else | 470 | else |
436 | button_data = ev.data; | 471 | button_data = ev.data; |
472 | |||
437 | return ev.id; | 473 | return ev.id; |
438 | } | 474 | } |
439 | 475 | ||