Remove the calls to backlight_lcd_sleep_countdown from target specific code and move...
[kugel-rb/myfork.git] / firmware / backlight.c
blob07c55c6bca705c3d1f6c1504ad8823e55e68447d
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 * Additional work by Martin Ritter (2007) and Thomas Martitz (2008)
12 * for backlight thread fading
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
23 #include "config.h"
24 #include <stdlib.h>
25 #include "cpu.h"
26 #include "kernel.h"
27 #include "thread.h"
28 #include "i2c.h"
29 #include "debug.h"
30 #include "rtc.h"
31 #include "usb.h"
32 #include "power.h"
33 #include "system.h"
34 #include "button.h"
35 #include "timer.h"
36 #include "backlight.h"
37 #include "lcd.h"
38 #include "screendump.h"
40 #ifdef HAVE_REMOTE_LCD
41 #include "lcd-remote.h"
42 #endif
43 #ifndef SIMULATOR
44 #include "backlight-target.h"
45 #endif
47 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
48 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
49 #include "backlight-sw-fading.h"
50 #endif
51 #ifdef SIMULATOR
53 static inline void _backlight_on(void)
55 sim_backlight(100);
58 static inline void _backlight_off(void)
60 sim_backlight(0);
63 static inline void _backlight_set_brightness(int val)
65 (void)val;
68 static inline void _buttonlight_on(void)
72 static inline void _buttonlight_off(void)
76 static inline void _buttonlight_set_brightness(int val)
78 (void)val;
80 #ifdef HAVE_REMOTE_LCD
81 static inline void _remote_backlight_on(void)
83 sim_remote_backlight(100);
86 static inline void _remote_backlight_off(void)
88 sim_remote_backlight(0);
90 #endif /* HAVE_REMOTE_LCD */
92 #endif /* SIMULATOR */
94 #if defined(HAVE_BACKLIGHT) && defined(BACKLIGHT_FULL_INIT)
96 #define BACKLIGHT_THREAD_TIMEOUT HZ
98 enum {
99 BACKLIGHT_ON,
100 BACKLIGHT_OFF,
101 BACKLIGHT_TMO_CHANGED,
102 #ifdef HAVE_REMOTE_LCD
103 REMOTE_BACKLIGHT_ON,
104 REMOTE_BACKLIGHT_OFF,
105 REMOTE_BACKLIGHT_TMO_CHANGED,
106 #endif
107 #if defined(_BACKLIGHT_FADE_BOOST) || defined(_BACKLIGHT_FADE_ENABLE)
108 BACKLIGHT_FADE_FINISH,
109 #endif
110 #ifdef HAVE_LCD_SLEEP
111 LCD_SLEEP,
112 #endif
113 #ifdef HAVE_BUTTON_LIGHT
114 BUTTON_LIGHT_ON,
115 BUTTON_LIGHT_OFF,
116 BUTTON_LIGHT_TMO_CHANGED,
117 #endif
118 #ifdef BACKLIGHT_DRIVER_CLOSE
119 BACKLIGHT_QUIT,
120 #endif
123 static void backlight_thread(void);
124 static long backlight_stack[DEFAULT_STACK_SIZE/sizeof(long)];
125 static const char backlight_thread_name[] = "backlight";
126 static struct event_queue backlight_queue;
127 #ifdef BACKLIGHT_DRIVER_CLOSE
128 static unsigned int backlight_thread_id = 0;
129 #endif
131 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
132 int backlight_brightness = DEFAULT_BRIGHTNESS_SETTING;
133 #endif
134 static int backlight_timer SHAREDBSS_ATTR;
135 static int backlight_timeout_normal = 5*HZ;
136 #if CONFIG_CHARGING
137 static int backlight_timeout_plugged = 5*HZ;
138 #endif
139 #ifdef HAS_BUTTON_HOLD
140 static int backlight_on_button_hold = 0;
141 #endif
142 static void backlight_timeout_handler(void);
144 #ifdef HAVE_BUTTON_LIGHT
145 static int buttonlight_timer;
146 static int buttonlight_timeout = 5*HZ;
148 /* Update state of buttonlight according to timeout setting */
149 static void buttonlight_update_state(void)
151 buttonlight_timer = buttonlight_timeout;
153 /* Buttonlight == OFF in the setting? */
154 if (buttonlight_timer < 0)
156 buttonlight_timer = 0; /* Disable the timeout */
157 _buttonlight_off();
159 else
160 _buttonlight_on();
163 /* external interface */
164 void buttonlight_on(void)
166 queue_remove_from_head(&backlight_queue, BUTTON_LIGHT_ON);
167 queue_post(&backlight_queue, BUTTON_LIGHT_ON, 0);
170 void buttonlight_off(void)
172 queue_post(&backlight_queue, BUTTON_LIGHT_OFF, 0);
175 void buttonlight_set_timeout(int value)
177 buttonlight_timeout = HZ * value;
178 queue_post(&backlight_queue, BUTTON_LIGHT_TMO_CHANGED, 0);
181 int buttonlight_get_current_timeout(void)
183 return buttonlight_timeout;
186 #endif /* HAVE_BUTTON_LIGHT */
188 #ifdef HAVE_REMOTE_LCD
189 static int remote_backlight_timer;
190 static int remote_backlight_timeout_normal = 5*HZ;
191 #if CONFIG_CHARGING
192 static int remote_backlight_timeout_plugged = 5*HZ;
193 #endif
194 #ifdef HAS_REMOTE_BUTTON_HOLD
195 static int remote_backlight_on_button_hold = 0;
196 #endif
197 #endif /* HAVE_REMOTE_LCD */
199 #ifdef HAVE_LCD_SLEEP
200 #ifdef HAVE_LCD_SLEEP_SETTING
201 const signed char lcd_sleep_timeout_value[10] =
203 -1, 0, 5, 10, 15, 20, 30, 45, 60, 90
205 static int lcd_sleep_timeout = 10*HZ;
206 #else
207 /* Target defines needed value */
208 #define lcd_sleep_timeout LCD_SLEEP_TIMEOUT
209 #endif
211 static int lcd_sleep_timer SHAREDDATA_ATTR = 0;
213 static void backlight_lcd_sleep_countdown(bool start)
215 if (!start)
217 /* Cancel the LCD sleep countdown */
218 lcd_sleep_timer = 0;
219 return;
222 /* Start LCD sleep countdown */
223 if (lcd_sleep_timeout < 0)
225 lcd_sleep_timer = 0; /* Setting == Always */
226 /* Ensure lcd_sleep() is called from backlight_thread() */
227 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM)
228 queue_post(&backlight_queue, LCD_SLEEP, 0);
229 #else
230 lcd_sleep();
231 #endif
233 else
235 lcd_sleep_timer = lcd_sleep_timeout;
238 #endif /* HAVE_LCD_SLEEP */
240 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
241 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
242 static int backlight_fading_type = (FADING_UP|FADING_DOWN);
243 static int backlight_fading_state = NOT_FADING;
244 #endif
247 /* backlight fading */
248 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM)
249 #define BL_PWM_INTERVAL 5 /* Cycle interval in ms */
250 #define BL_PWM_BITS 8
251 #define BL_PWM_COUNT (1<<BL_PWM_BITS)
253 /* s15.16 fixed point variables */
254 static int32_t bl_fade_in_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16)/300;
255 static int32_t bl_fade_out_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16)/2000;
256 static int32_t bl_dim_fraction = 0;
258 static int bl_dim_target = 0;
259 static int bl_dim_current = 0;
260 static enum {DIM_STATE_START, DIM_STATE_MAIN} bl_dim_state = DIM_STATE_START;
261 static bool bl_timer_active = false;
263 static void backlight_isr(void)
265 int timer_period = (TIMER_FREQ*BL_PWM_INTERVAL/1000);
266 bool idle = false;
268 switch (bl_dim_state)
270 /* New cycle */
271 case DIM_STATE_START:
272 bl_dim_current = bl_dim_fraction >> 16;
274 if (bl_dim_current > 0 && bl_dim_current < BL_PWM_COUNT)
276 _backlight_on_isr();
277 timer_period = (timer_period * bl_dim_current) >> BL_PWM_BITS;
278 bl_dim_state = DIM_STATE_MAIN;
280 else
282 if (bl_dim_current)
283 _backlight_on_isr();
284 else
285 _backlight_off_isr();
286 if (bl_dim_current == bl_dim_target)
287 idle = true;
289 if (bl_dim_current < bl_dim_target)
291 bl_dim_fraction = MIN(bl_dim_fraction + bl_fade_in_step,
292 (BL_PWM_COUNT<<16));
294 else if (bl_dim_current > bl_dim_target)
296 bl_dim_fraction = MAX(bl_dim_fraction - bl_fade_out_step, 0);
298 break;
300 /* Dim main screen */
301 case DIM_STATE_MAIN:
302 _backlight_off_isr();
303 timer_period = (timer_period * (BL_PWM_COUNT - bl_dim_current))
304 >> BL_PWM_BITS;
305 bl_dim_state = DIM_STATE_START;
306 break ;
308 if (idle)
310 #if defined(_BACKLIGHT_FADE_BOOST) || defined(_BACKLIGHT_FADE_ENABLE)
311 queue_post(&backlight_queue, BACKLIGHT_FADE_FINISH, 0);
312 #endif
313 timer_unregister();
314 bl_timer_active = false;
316 #ifdef HAVE_LCD_SLEEP
317 if (bl_dim_current == 0)
318 backlight_lcd_sleep_countdown(true);
319 #endif
321 else
322 timer_set_period(timer_period);
325 static void backlight_switch(void)
327 if (bl_dim_target > (BL_PWM_COUNT/2))
329 _backlight_on_normal();
330 bl_dim_fraction = (BL_PWM_COUNT<<16);
332 else
334 _backlight_off_normal();
335 bl_dim_fraction = 0;
337 #ifdef HAVE_LCD_SLEEP
338 backlight_lcd_sleep_countdown(true);
339 #endif
343 static void backlight_release_timer(void)
345 #ifdef _BACKLIGHT_FADE_BOOST
346 cpu_boost(false);
347 #endif
348 timer_unregister();
349 bl_timer_active = false;
350 backlight_switch();
353 static void backlight_dim(int value)
355 /* protect from extraneous calls with the same target value */
356 if (value == bl_dim_target)
357 return;
359 bl_dim_target = value;
361 if (bl_timer_active)
362 return ;
364 if (timer_register(0, backlight_release_timer, 2, 0, backlight_isr
365 IF_COP(, CPU)))
367 #ifdef _BACKLIGHT_FADE_BOOST
368 /* Prevent cpu frequency changes while dimming. */
369 cpu_boost(true);
370 #endif
371 bl_timer_active = true;
373 else
374 backlight_switch();
377 static void _backlight_on(void)
379 #ifdef HAVE_LCD_SLEEP
380 backlight_lcd_sleep_countdown(false);
381 #endif
383 if (bl_fade_in_step > 0)
385 #ifdef _BACKLIGHT_FADE_ENABLE
386 _backlight_hw_enable(true);
387 #endif
388 backlight_dim(BL_PWM_COUNT);
390 else
392 bl_dim_target = BL_PWM_COUNT;
393 bl_dim_fraction = (BL_PWM_COUNT<<16);
394 _backlight_on_normal();
398 static void _backlight_off(void)
400 if (bl_fade_out_step > 0)
402 backlight_dim(0);
404 else
406 bl_dim_target = bl_dim_fraction = 0;
407 _backlight_off_normal();
409 #ifdef HAVE_LCD_SLEEP
410 backlight_lcd_sleep_countdown(true);
411 #endif
415 void backlight_set_fade_in(int value)
417 if (value > 0)
418 bl_fade_in_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16) / value;
419 else
420 bl_fade_in_step = 0;
423 void backlight_set_fade_out(int value)
425 if (value > 0)
426 bl_fade_out_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16) / value;
427 else
428 bl_fade_out_step = 0;
431 #elif (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
432 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
434 void backlight_set_fade_out(bool value)
436 if(value) /* on */
437 backlight_fading_type |= FADING_DOWN;
438 else
439 backlight_fading_type &= FADING_UP;
442 void backlight_set_fade_in(bool value)
444 if(value) /* on */
445 backlight_fading_type |= FADING_UP;
446 else
447 backlight_fading_type &= FADING_DOWN;
450 static void backlight_setup_fade_up(void)
452 if (backlight_fading_type & FADING_UP)
454 if (backlight_fading_state == NOT_FADING)
456 /* make sure the backlight is at lowest level */
457 _backlight_on();
459 backlight_fading_state = FADING_UP;
461 else
463 backlight_fading_state = NOT_FADING;
464 _backlight_fade_update_state(backlight_brightness);
465 _backlight_on();
466 _backlight_set_brightness(backlight_brightness);
470 static void backlight_setup_fade_down(void)
472 if (backlight_fading_type & FADING_DOWN)
474 backlight_fading_state = FADING_DOWN;
476 else
478 backlight_fading_state = NOT_FADING;
479 _backlight_fade_update_state(MIN_BRIGHTNESS_SETTING-1);
480 _backlight_off();
481 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
482 /* write the lowest brightness level to the hardware so that
483 * fading up is glitch free */
484 _backlight_set_brightness(MIN_BRIGHTNESS_SETTING);
485 #endif
488 #endif /* CONFIG_BACKLIGHT_FADING */
490 /* Update state of backlight according to timeout setting */
491 static void backlight_update_state(void)
494 int timeout = backlight_get_current_timeout();
496 /* Backlight == OFF in the setting? */
497 if (UNLIKELY(timeout < 0))
499 backlight_timer = 0; /* Disable the timeout */
500 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
501 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
502 backlight_setup_fade_down();
503 /* necessary step to issue fading down when the setting is selected */
504 queue_post(&backlight_queue, SYS_TIMEOUT, 0);
505 #else
506 _backlight_off();
507 #ifdef HAVE_LCD_SLEEP
508 backlight_lcd_sleep_countdown(true); /* start sleep countdown */
509 #endif
510 #endif
512 else
514 backlight_timer = timeout;
516 #ifdef HAVE_LCD_SLEEP
517 backlight_lcd_sleep_countdown(false); /* wake up lcd */
518 #endif
520 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
521 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
522 backlight_setup_fade_up();
523 #else
524 _backlight_on();
525 #endif
529 #ifdef HAVE_REMOTE_LCD
530 /* Update state of remote backlight according to timeout setting */
531 static void remote_backlight_update_state(void)
533 int timeout = remote_backlight_get_current_timeout();
534 /* Backlight == OFF in the setting? */
535 if (timeout < 0)
537 remote_backlight_timer = 0; /* Disable the timeout */
538 _remote_backlight_off();
540 else
542 remote_backlight_timer = timeout;
543 _remote_backlight_on();
546 #endif /* HAVE_REMOTE_LCD */
547 static inline void do_backlight_off(void)
549 backlight_timer = 0;
550 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
551 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
552 backlight_setup_fade_down();
553 #else
554 _backlight_off();
555 #endif /* CONFIG_BACKLIGHT_FADING */
558 void backlight_thread(void)
560 struct queue_event ev;
561 bool locked = false;
563 while(1)
565 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
566 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
567 if (backlight_fading_state != NOT_FADING)
568 queue_wait_w_tmo(&backlight_queue, &ev, FADE_DELAY);
569 else
570 #endif
571 queue_wait_w_tmo(&backlight_queue, &ev, BACKLIGHT_THREAD_TIMEOUT);
572 switch(ev.id)
573 { /* These events must always be processed */
574 #ifdef _BACKLIGHT_FADE_BOOST
575 case BACKLIGHT_FADE_FINISH:
576 cpu_boost(false);
577 break;
578 #endif
579 #ifdef _BACKLIGHT_FADE_ENABLE
580 case BACKLIGHT_FADE_FINISH:
581 _backlight_hw_enable((bl_dim_current|bl_dim_target) != 0);
582 break;
583 #endif
585 #ifndef SIMULATOR
586 /* Here for now or else the aggressive init messes up scrolling */
587 #ifdef HAVE_REMOTE_LCD
588 case SYS_REMOTE_PLUGGED:
589 lcd_remote_on();
590 lcd_remote_update();
591 break;
593 case SYS_REMOTE_UNPLUGGED:
594 lcd_remote_off();
595 break;
596 #elif defined HAVE_REMOTE_LCD_AS_MAIN
597 case SYS_REMOTE_PLUGGED:
598 lcd_on();
599 lcd_update();
600 break;
602 case SYS_REMOTE_UNPLUGGED:
603 lcd_off();
604 break;
605 #endif /* HAVE_REMOTE_LCD/ HAVE_REMOTE_LCD_AS_MAIN */
606 #endif /* !SIMULATOR */
607 case SYS_USB_CONNECTED:
608 usb_acknowledge(SYS_USB_CONNECTED_ACK);
609 break;
611 case SYS_USB_DISCONNECTED:
612 usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
613 break;
615 #ifdef BACKLIGHT_DRIVER_CLOSE
616 /* Get out of here */
617 case BACKLIGHT_QUIT:
618 return;
619 #endif
621 if (locked)
622 continue;
624 switch(ev.id)
625 { /* These events are only processed if backlight isn't locked */
626 #ifdef HAVE_REMOTE_LCD
627 case REMOTE_BACKLIGHT_TMO_CHANGED:
628 case REMOTE_BACKLIGHT_ON:
629 remote_backlight_update_state();
630 break;
632 case REMOTE_BACKLIGHT_OFF:
633 remote_backlight_timer = 0; /* Disable the timeout */
634 _remote_backlight_off();
635 break;
636 #endif /* HAVE_REMOTE_LCD */
638 case BACKLIGHT_TMO_CHANGED:
639 case BACKLIGHT_ON:
640 backlight_update_state();
641 break;
643 case BACKLIGHT_OFF:
644 do_backlight_off();
645 break;
646 #ifdef HAVE_LCD_SLEEP
647 case LCD_SLEEP:
648 lcd_sleep();
649 break;
650 #endif
651 #ifdef HAVE_BUTTON_LIGHT
652 case BUTTON_LIGHT_TMO_CHANGED:
653 case BUTTON_LIGHT_ON:
654 buttonlight_update_state();
655 break;
657 case BUTTON_LIGHT_OFF:
658 buttonlight_timer = 0;
659 _buttonlight_off();
660 break;
661 #endif
663 case SYS_POWEROFF: /* Lock backlight on poweroff so it doesn't */
664 locked = true; /* go off before power is actually cut. */
665 /* fall through */
666 #if CONFIG_CHARGING
667 case SYS_CHARGER_CONNECTED:
668 case SYS_CHARGER_DISCONNECTED:
669 #endif
670 backlight_update_state();
671 #ifdef HAVE_REMOTE_LCD
672 remote_backlight_update_state();
673 #endif
674 break;
675 case SYS_TIMEOUT:
676 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
677 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
678 if (backlight_fading_state != NOT_FADING)
680 if ((_backlight_fade_step(backlight_fading_state)))
681 { /* finished fading */
682 #ifdef HAVE_LCD_SLEEP
683 if (backlight_fading_state == FADING_DOWN)
684 { /* start sleep countdown */
685 backlight_lcd_sleep_countdown(true);
687 #endif
688 backlight_fading_state = NOT_FADING;
691 else
692 #endif /* CONFIG_BACKLIGHT_FADING */
693 backlight_timeout_handler();
694 break;
696 } /* end while */
699 static void backlight_timeout_handler(void)
701 if(backlight_timer > 0)
703 backlight_timer -= BACKLIGHT_THREAD_TIMEOUT;
704 if(backlight_timer <= 0)
706 do_backlight_off();
709 #ifdef HAVE_LCD_SLEEP
710 else if(lcd_sleep_timer > 0)
712 lcd_sleep_timer -= BACKLIGHT_THREAD_TIMEOUT;
713 if(lcd_sleep_timer <= 0)
715 lcd_sleep();
718 #endif /* HAVE_LCD_SLEEP */
719 #ifdef HAVE_REMOTE_LCD
720 if(remote_backlight_timer > 0)
722 remote_backlight_timer -= BACKLIGHT_THREAD_TIMEOUT;
723 if(remote_backlight_timer <= 0)
725 _remote_backlight_off();
728 #endif /* HAVE_REMOVE_LCD */
729 #ifdef HAVE_BUTTON_LIGHT
730 if (buttonlight_timer > 0)
732 buttonlight_timer -= BACKLIGHT_THREAD_TIMEOUT;
733 if (buttonlight_timer <= 0)
735 _buttonlight_off();
738 #endif /* HAVE_BUTTON_LIGHT */
741 void backlight_init(void)
743 queue_init(&backlight_queue, true);
745 #ifndef SIMULATOR
746 if (_backlight_init())
748 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM)
749 /* If backlight is already on, don't fade in. */
750 bl_dim_target = BL_PWM_COUNT;
751 bl_dim_fraction = (BL_PWM_COUNT<<16);
752 #endif
754 #endif
755 /* Leave all lights as set by the bootloader here. The settings load will
756 * call the appropriate backlight_set_*() functions, only changing light
757 * status if necessary. */
758 #ifdef BACKLIGHT_DRIVER_CLOSE
759 backlight_thread_id =
760 #endif
761 create_thread(backlight_thread, backlight_stack,
762 sizeof(backlight_stack), 0, backlight_thread_name
763 IF_PRIO(, PRIORITY_USER_INTERFACE)
764 IF_COP(, CPU));
767 #ifdef BACKLIGHT_DRIVER_CLOSE
768 void backlight_close(void)
770 unsigned int thread = backlight_thread_id;
772 /* Wait for thread to exit */
773 if (thread == 0)
774 return;
776 backlight_thread_id = 0;
778 queue_post(&backlight_queue, BACKLIGHT_QUIT, 0);
779 thread_wait(thread);
781 #endif /* BACKLIGHT_DRIVER_CLOSE */
783 void backlight_on(void)
785 queue_remove_from_head(&backlight_queue, BACKLIGHT_ON);
786 queue_post(&backlight_queue, BACKLIGHT_ON, 0);
789 void backlight_off(void)
791 queue_post(&backlight_queue, BACKLIGHT_OFF, 0);
794 /* returns true when the backlight is on,
795 * and optionally when it's set to always off. */
796 bool is_backlight_on(bool ignore_always_off)
798 int timeout = backlight_get_current_timeout();
799 return (backlight_timer > 0) /* countdown */
800 || (timeout == 0) /* always on */
801 || ((timeout < 0) && !ignore_always_off);
804 /* return value in ticks; 0 means always on, <0 means always off */
805 int backlight_get_current_timeout(void)
807 #ifdef HAS_BUTTON_HOLD
808 if ((backlight_on_button_hold != 0)
809 #ifdef HAVE_REMOTE_LCD_AS_MAIN
810 && remote_button_hold()
811 #else
812 && button_hold()
813 #endif
815 return (backlight_on_button_hold == 2) ? 0 : -1;
816 /* always on or always off */
817 else
818 #endif
819 #if CONFIG_CHARGING
820 if (power_input_present())
821 return backlight_timeout_plugged;
822 else
823 #endif
824 return backlight_timeout_normal;
827 void backlight_set_timeout(int value)
829 backlight_timeout_normal = HZ * value;
830 queue_post(&backlight_queue, BACKLIGHT_TMO_CHANGED, 0);
833 #if CONFIG_CHARGING
834 void backlight_set_timeout_plugged(int value)
836 backlight_timeout_plugged = HZ * value;
837 queue_post(&backlight_queue, BACKLIGHT_TMO_CHANGED, 0);
839 #endif /* CONFIG_CHARGING */
841 #ifdef HAS_BUTTON_HOLD
842 /* Hold button change event handler. */
843 void backlight_hold_changed(bool hold_button)
845 if (!hold_button || (backlight_on_button_hold > 0))
846 /* if unlocked or override in effect */
847 backlight_on();
850 void backlight_set_on_button_hold(int index)
852 if ((unsigned)index >= 3)
853 /* if given a weird value, use default */
854 index = 0;
856 backlight_on_button_hold = index;
857 queue_post(&backlight_queue, BACKLIGHT_TMO_CHANGED, 0);
859 #endif /* HAS_BUTTON_HOLD */
861 #ifdef HAVE_LCD_SLEEP_SETTING
862 void lcd_set_sleep_after_backlight_off(int index)
864 if ((unsigned)index >= sizeof(lcd_sleep_timeout_value))
865 /* if given a weird value, use default */
866 index = 3;
868 lcd_sleep_timeout = HZ * lcd_sleep_timeout_value[index];
870 if (backlight_timer > 0 || backlight_get_current_timeout() == 0)
871 /* Timer will be set when bl turns off or bl set to on. */
872 return;
874 /* Backlight is Off */
875 if (lcd_sleep_timeout < 0)
876 lcd_sleep_timer = 1; /* Always - sleep next tick */
877 else
878 lcd_sleep_timer = lcd_sleep_timeout; /* Never, other */
880 #endif /* HAVE_LCD_SLEEP_SETTING */
882 #ifdef HAVE_REMOTE_LCD
883 void remote_backlight_on(void)
885 queue_post(&backlight_queue, REMOTE_BACKLIGHT_ON, 0);
888 void remote_backlight_off(void)
890 queue_post(&backlight_queue, REMOTE_BACKLIGHT_OFF, 0);
893 void remote_backlight_set_timeout(int value)
895 remote_backlight_timeout_normal = HZ * value;
896 queue_post(&backlight_queue, REMOTE_BACKLIGHT_TMO_CHANGED, 0);
899 #if CONFIG_CHARGING
900 void remote_backlight_set_timeout_plugged(int value)
902 remote_backlight_timeout_plugged = HZ * value;
903 queue_post(&backlight_queue, REMOTE_BACKLIGHT_TMO_CHANGED, 0);
905 #endif /* CONFIG_CHARGING */
907 #ifdef HAS_REMOTE_BUTTON_HOLD
908 /* Remote hold button change event handler. */
909 void remote_backlight_hold_changed(bool rc_hold_button)
911 if (!rc_hold_button || (remote_backlight_on_button_hold > 0))
912 /* if unlocked or override */
913 remote_backlight_on();
916 void remote_backlight_set_on_button_hold(int index)
918 if ((unsigned)index >= 3)
919 /* if given a weird value, use default */
920 index = 0;
922 remote_backlight_on_button_hold = index;
923 queue_post(&backlight_queue, REMOTE_BACKLIGHT_TMO_CHANGED, 0);
925 #endif /* HAS_REMOTE_BUTTON_HOLD */
927 /* return value in ticks; 0 means always on, <0 means always off */
928 int remote_backlight_get_current_timeout(void)
930 #ifdef HAS_REMOTE_BUTTON_HOLD
931 if (remote_button_hold() && (remote_backlight_on_button_hold != 0))
932 return (remote_backlight_on_button_hold == 2)
933 ? 0 : -1; /* always on or always off */
934 else
935 #endif
936 #if CONFIG_CHARGING
937 if (power_input_present())
938 return remote_backlight_timeout_plugged;
939 else
940 #endif
941 return remote_backlight_timeout_normal;
944 /* returns true when the backlight is on, and
945 * optionally when it's set to always off */
946 bool is_remote_backlight_on(bool ignore_always_off)
948 int timeout = remote_backlight_get_current_timeout();
949 return (remote_backlight_timer > 0) /* countdown */
950 || (timeout == 0) /* always on */
951 || ((timeout < 0) && !ignore_always_off);
954 #endif /* HAVE_REMOTE_LCD */
956 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
957 void backlight_set_brightness(int val)
959 if (val < MIN_BRIGHTNESS_SETTING)
960 val = MIN_BRIGHTNESS_SETTING;
961 else if (val > MAX_BRIGHTNESS_SETTING)
962 val = MAX_BRIGHTNESS_SETTING;
964 backlight_brightness = val;
965 _backlight_set_brightness(val);
966 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
967 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
968 /* receive backlight brightness */
969 _backlight_fade_update_state(val);
970 #endif
972 #endif /* HAVE_BACKLIGHT_BRIGHTNESS */
974 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
975 void buttonlight_set_brightness(int val)
977 if (val < MIN_BRIGHTNESS_SETTING)
978 val = MIN_BRIGHTNESS_SETTING;
979 else if (val > MAX_BRIGHTNESS_SETTING)
980 val = MAX_BRIGHTNESS_SETTING;
982 _buttonlight_set_brightness(val);
984 #endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
986 #else /* !defined(HAVE_BACKLIGHT) || !defined(BACKLIGHT_FULL_INIT)
987 -- no backlight, empty dummy functions */
989 #if defined(HAVE_BACKLIGHT) && !defined(BACKLIGHT_FULL_INIT)
990 void backlight_init(void)
992 (void)_backlight_init();
993 _backlight_on();
995 #endif
997 void backlight_on(void) {}
998 void backlight_off(void) {}
999 void buttonlight_on(void) {}
1000 void backlight_set_timeout(int value) {(void)value;}
1002 bool is_backlight_on(bool ignore_always_off)
1004 (void)ignore_always_off;
1005 return true;
1007 #ifdef HAVE_REMOTE_LCD
1008 void remote_backlight_on(void) {}
1009 void remote_backlight_off(void) {}
1010 void remote_backlight_set_timeout(int value) {(void)value;}
1012 bool is_remote_backlight_on(bool ignore_always_off)
1014 (void)ignore_always_off;
1015 return true;
1017 #endif /* HAVE_REMOTE_LCD */
1018 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
1019 void backlight_set_brightness(int val) { (void)val; }
1020 #endif
1021 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
1022 void buttonlight_set_brightness(int val) { (void)val; }
1023 #endif
1024 #endif /* defined(HAVE_BACKLIGHT) && defined(BACKLIGHT_FULL_INIT) */