fix red
[kugel-rb.git] / firmware / backlight.c
blob9c153e885add0a07a01155e3ba951d652d23ae1d
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"
39 #ifdef HAVE_REMOTE_LCD
40 #include "lcd-remote.h"
41 #endif
42 #ifndef SIMULATOR
43 #include "backlight-target.h"
44 #endif
46 #if !defined(BOOTLOADER)
47 /* The whole driver should be built */
48 #define BACKLIGHT_FULL_INIT
49 #endif
51 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
52 int backlight_brightness = DEFAULT_BRIGHTNESS_SETTING;
53 #endif
55 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
56 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
57 #include "backlight-sw-fading.h"
58 #endif
59 #ifdef SIMULATOR
60 /* TODO: find a better way to do it but we need a kernel thread somewhere to
61 handle this */
62 extern void screen_dump(void);
64 static inline void _backlight_on(void)
66 sim_backlight(100);
69 static inline void _backlight_off(void)
71 sim_backlight(0);
74 static inline void _backlight_set_brightness(int val)
76 (void)val;
79 static inline void _buttonlight_on(void)
83 static inline void _buttonlight_off(void)
87 static inline void _buttonlight_set_brightness(int val)
89 (void)val;
91 #ifdef HAVE_REMOTE_LCD
92 static inline void _remote_backlight_on(void)
94 sim_remote_backlight(100);
97 static inline void _remote_backlight_off(void)
99 sim_remote_backlight(0);
101 #endif /* HAVE_REMOTE_LCD */
103 #endif /* SIMULATOR */
105 #if defined(HAVE_BACKLIGHT) && defined(BACKLIGHT_FULL_INIT)
107 enum {
108 BACKLIGHT_ON,
109 BACKLIGHT_OFF,
110 #ifdef HAVE_REMOTE_LCD
111 REMOTE_BACKLIGHT_ON,
112 REMOTE_BACKLIGHT_OFF,
113 #endif
114 #if defined(_BACKLIGHT_FADE_BOOST) || defined(_BACKLIGHT_FADE_ENABLE)
115 BACKLIGHT_FADE_FINISH,
116 #endif
117 #ifdef HAVE_LCD_SLEEP
118 LCD_SLEEP,
119 #endif
120 #ifdef HAVE_BUTTON_LIGHT
121 BUTTON_LIGHT_ON,
122 BUTTON_LIGHT_OFF,
123 #endif
124 #ifdef BACKLIGHT_DRIVER_CLOSE
125 BACKLIGHT_QUIT,
126 #endif
129 static void backlight_thread(void);
130 static long backlight_stack[DEFAULT_STACK_SIZE/sizeof(long)];
131 static const char backlight_thread_name[] = "backlight";
132 static struct event_queue backlight_queue;
133 #ifdef BACKLIGHT_DRIVER_CLOSE
134 static unsigned int backlight_thread_id = 0;
135 #endif
137 static int backlight_timer SHAREDBSS_ATTR;
138 static int backlight_timeout SHAREDBSS_ATTR;
139 static int backlight_timeout_normal = 5*HZ;
140 #if CONFIG_CHARGING
141 static int backlight_timeout_plugged = 5*HZ;
142 #endif
143 #ifdef HAS_BUTTON_HOLD
144 static int backlight_on_button_hold = 0;
145 #endif
147 #ifdef HAVE_BUTTON_LIGHT
148 static int buttonlight_timer;
149 int _buttonlight_timeout = 5*HZ;
151 /* Update state of buttonlight according to timeout setting */
152 static void buttonlight_update_state(void)
154 buttonlight_timer = _buttonlight_timeout;
156 /* Buttonlight == OFF in the setting? */
157 if (buttonlight_timer < 0)
159 buttonlight_timer = 0; /* Disable the timeout */
160 _buttonlight_off();
162 else
163 _buttonlight_on();
166 /* external interface */
167 void buttonlight_on(void)
169 queue_remove_from_head(&backlight_queue, BUTTON_LIGHT_ON);
170 queue_post(&backlight_queue, BUTTON_LIGHT_ON, 0);
173 void buttonlight_off(void)
175 queue_post(&backlight_queue, BUTTON_LIGHT_OFF, 0);
178 void buttonlight_set_timeout(int value)
180 _buttonlight_timeout = HZ * value;
181 buttonlight_update_state();
184 #endif /* HAVE_BUTTON_LIGHT */
186 #ifdef HAVE_REMOTE_LCD
187 static int remote_backlight_timer;
188 static int remote_backlight_timeout;
189 static int remote_backlight_timeout_normal = 5*HZ;
190 #if CONFIG_CHARGING
191 static int remote_backlight_timeout_plugged = 5*HZ;
192 #endif
193 #ifdef HAS_REMOTE_BUTTON_HOLD
194 static int remote_backlight_on_button_hold = 0;
195 #endif
196 #endif /* HAVE_REMOTE_LCD */
198 #ifdef HAVE_LCD_SLEEP
199 #ifdef HAVE_LCD_SLEEP_SETTING
200 const signed char lcd_sleep_timeout_value[10] =
202 -1, 0, 5, 10, 15, 20, 30, 45, 60, 90
204 static int lcd_sleep_timeout = 10*HZ;
205 #else
206 /* Target defines needed value */
207 static const int lcd_sleep_timeout = LCD_SLEEP_TIMEOUT;
208 #endif
210 static int lcd_sleep_timer = 0;
212 void backlight_lcd_sleep_countdown(bool start)
214 if (!start)
216 /* Cancel the LCD sleep countdown */
217 lcd_sleep_timer = 0;
218 return;
221 /* Start LCD sleep countdown */
222 if (lcd_sleep_timeout < 0)
224 lcd_sleep_timer = 0; /* Setting == Always */
225 lcd_sleep();
227 else
229 lcd_sleep_timer = lcd_sleep_timeout;
232 #endif /* HAVE_LCD_SLEEP */
234 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
235 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
236 static int backlight_fading_type = (FADING_UP|FADING_DOWN);
237 static int backlight_fading_state = NOT_FADING;
238 #endif
241 /* backlight fading */
242 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM)
243 #define BL_PWM_INTERVAL 5 /* Cycle interval in ms */
244 #define BL_PWM_BITS 8
245 #define BL_PWM_COUNT (1<<BL_PWM_BITS)
247 /* s15.16 fixed point variables */
248 static int32_t bl_fade_in_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16)/300;
249 static int32_t bl_fade_out_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16)/2000;
250 static int32_t bl_dim_fraction = 0;
252 static int bl_dim_target = 0;
253 static int bl_dim_current = 0;
254 static enum {DIM_STATE_START, DIM_STATE_MAIN} bl_dim_state = DIM_STATE_START;
255 static bool bl_timer_active = false;
257 static void backlight_isr(void)
259 int timer_period = (TIMER_FREQ*BL_PWM_INTERVAL/1000);
260 bool idle = false;
262 switch (bl_dim_state)
264 /* New cycle */
265 case DIM_STATE_START:
266 bl_dim_current = bl_dim_fraction >> 16;
268 if (bl_dim_current > 0 && bl_dim_current < BL_PWM_COUNT)
270 _backlight_on_isr();
271 timer_period = (timer_period * bl_dim_current) >> BL_PWM_BITS;
272 bl_dim_state = DIM_STATE_MAIN;
274 else
276 if (bl_dim_current)
277 _backlight_on_isr();
278 else
279 _backlight_off_isr();
280 if (bl_dim_current == bl_dim_target)
281 idle = true;
283 if (bl_dim_current < bl_dim_target)
285 bl_dim_fraction = MIN(bl_dim_fraction + bl_fade_in_step,
286 (BL_PWM_COUNT<<16));
288 else if (bl_dim_current > bl_dim_target)
290 bl_dim_fraction = MAX(bl_dim_fraction - bl_fade_out_step, 0);
292 break;
294 /* Dim main screen */
295 case DIM_STATE_MAIN:
296 _backlight_off_isr();
297 timer_period = (timer_period * (BL_PWM_COUNT - bl_dim_current))
298 >> BL_PWM_BITS;
299 bl_dim_state = DIM_STATE_START;
300 break ;
302 if (idle)
304 #if defined(_BACKLIGHT_FADE_BOOST) || defined(_BACKLIGHT_FADE_ENABLE)
305 queue_post(&backlight_queue, BACKLIGHT_FADE_FINISH, 0);
306 #endif
307 timer_unregister();
308 bl_timer_active = false;
310 else
311 timer_set_period(timer_period);
314 static void backlight_switch(void)
316 if (bl_dim_target > (BL_PWM_COUNT/2))
318 _backlight_on_normal();
319 bl_dim_fraction = (BL_PWM_COUNT<<16);
321 else
323 _backlight_off_normal();
324 bl_dim_fraction = 0;
328 static void backlight_release_timer(void)
330 #ifdef _BACKLIGHT_FADE_BOOST
331 cpu_boost(false);
332 #endif
333 timer_unregister();
334 bl_timer_active = false;
335 backlight_switch();
338 static void backlight_dim(int value)
340 /* protect from extraneous calls with the same target value */
341 if (value == bl_dim_target)
342 return;
344 bl_dim_target = value;
346 if (bl_timer_active)
347 return ;
349 if (timer_register(0, backlight_release_timer, 2, 0, backlight_isr
350 IF_COP(, CPU)))
352 #ifdef _BACKLIGHT_FADE_BOOST
353 /* Prevent cpu frequency changes while dimming. */
354 cpu_boost(true);
355 #endif
356 bl_timer_active = true;
358 else
359 backlight_switch();
362 static void _backlight_on(void)
364 #ifdef HAVE_LCD_SLEEP
365 backlight_lcd_sleep_countdown(false);
366 #endif
368 if (bl_fade_in_step > 0)
370 #ifdef _BACKLIGHT_FADE_ENABLE
371 _backlight_hw_enable(true);
372 #endif
373 backlight_dim(BL_PWM_COUNT);
375 else
377 bl_dim_target = BL_PWM_COUNT;
378 bl_dim_fraction = (BL_PWM_COUNT<<16);
379 _backlight_on_normal();
383 static void _backlight_off(void)
385 if (bl_fade_out_step > 0)
387 backlight_dim(0);
389 else
391 bl_dim_target = bl_dim_fraction = 0;
392 _backlight_off_normal();
395 #ifdef HAVE_LCD_SLEEP
396 backlight_lcd_sleep_countdown(true);
397 #endif
400 void backlight_set_fade_in(int value)
402 if (value > 0)
403 bl_fade_in_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16) / value;
404 else
405 bl_fade_in_step = 0;
408 void backlight_set_fade_out(int value)
410 if (value > 0)
411 bl_fade_out_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16) / value;
412 else
413 bl_fade_out_step = 0;
416 #elif (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
417 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
419 void backlight_set_fade_out(bool value)
421 if(value) /* on */
422 backlight_fading_type |= FADING_DOWN;
423 else
424 backlight_fading_type &= FADING_UP;
427 void backlight_set_fade_in(bool value)
429 if(value) /* on */
430 backlight_fading_type |= FADING_UP;
431 else
432 backlight_fading_type &= FADING_DOWN;
435 static void backlight_setup_fade_up(void)
437 if (backlight_fading_type & FADING_UP)
439 if (backlight_fading_state == NOT_FADING)
441 /* make sure the backlight is at lowest level */
442 _backlight_on();
444 backlight_fading_state = FADING_UP;
446 else
448 backlight_fading_state = NOT_FADING;
449 _backlight_fade_update_state(backlight_brightness);
450 _backlight_on();
451 _backlight_set_brightness(backlight_brightness);
455 static void backlight_setup_fade_down(void)
457 if (backlight_fading_type & FADING_DOWN)
459 backlight_fading_state = FADING_DOWN;
461 else
463 backlight_fading_state = NOT_FADING;
464 _backlight_fade_update_state(MIN_BRIGHTNESS_SETTING-1);
465 _backlight_off();
466 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
467 /* write the lowest brightness level to the hardware so that
468 * fading up is glitch free */
469 _backlight_set_brightness(MIN_BRIGHTNESS_SETTING);
470 #endif
473 #endif /* CONFIG_BACKLIGHT_FADING */
475 /* Update state of backlight according to timeout setting */
476 static void backlight_update_state(void)
478 #ifdef HAS_BUTTON_HOLD
479 if ((backlight_on_button_hold != 0)
480 #ifdef HAVE_REMOTE_LCD_AS_MAIN
481 && remote_button_hold()
482 #else
483 && button_hold()
484 #endif
486 backlight_timeout = (backlight_on_button_hold == 2) ? 0 : -1;
487 /* always on or always off */
488 else
489 #endif
490 #if CONFIG_CHARGING
491 if (power_input_present())
492 backlight_timeout = backlight_timeout_plugged;
493 else
494 #endif
495 backlight_timeout = backlight_timeout_normal;
497 /* Backlight == OFF in the setting? */
498 if (UNLIKELY(backlight_timeout < 0))
500 backlight_timer = 0; /* Disable the timeout */
501 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
502 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
503 backlight_setup_fade_down();
504 /* necessary step to issue fading down when the setting is selected */
505 queue_post(&backlight_queue, SYS_TIMEOUT, 0);
506 #else
507 _backlight_off();
508 #endif
510 else
512 backlight_timer = backlight_timeout;
513 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
514 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
515 backlight_setup_fade_up();
516 #else
517 _backlight_on();
518 #endif
522 #ifdef HAVE_REMOTE_LCD
523 /* Update state of remote backlight according to timeout setting */
524 static void remote_backlight_update_state(void)
526 #ifdef HAS_REMOTE_BUTTON_HOLD
527 if (remote_button_hold() && (remote_backlight_on_button_hold != 0))
528 remote_backlight_timeout = (remote_backlight_on_button_hold == 2)
529 ? 0 : -1; /* always on or always off */
530 else
531 #endif
532 #if CONFIG_CHARGING
533 if (power_input_present())
534 remote_backlight_timeout = remote_backlight_timeout_plugged;
535 else
536 #endif
537 remote_backlight_timeout = remote_backlight_timeout_normal;
539 /* Backlight == OFF in the setting? */
540 if (remote_backlight_timeout < 0)
542 remote_backlight_timer = 0; /* Disable the timeout */
543 _remote_backlight_off();
545 else
547 remote_backlight_timer = remote_backlight_timeout;
548 _remote_backlight_on();
551 #endif /* HAVE_REMOTE_LCD */
553 void backlight_thread(void)
555 struct queue_event ev;
556 bool locked = false;
558 while(1)
560 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
561 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
562 if (backlight_fading_state)
563 queue_wait_w_tmo(&backlight_queue, &ev, FADE_DELAY);
564 else
565 #endif
566 queue_wait(&backlight_queue, &ev);
567 switch(ev.id)
568 { /* These events must always be processed */
569 #ifdef _BACKLIGHT_FADE_BOOST
570 case BACKLIGHT_FADE_FINISH:
571 cpu_boost(false);
572 break;
573 #endif
574 #ifdef _BACKLIGHT_FADE_ENABLE
575 case BACKLIGHT_FADE_FINISH:
576 _backlight_hw_enable((bl_dim_current|bl_dim_target) != 0);
577 break;
578 #endif
580 #ifndef SIMULATOR
581 /* Here for now or else the aggressive init messes up scrolling */
582 #ifdef HAVE_REMOTE_LCD
583 case SYS_REMOTE_PLUGGED:
584 lcd_remote_on();
585 lcd_remote_update();
586 break;
588 case SYS_REMOTE_UNPLUGGED:
589 lcd_remote_off();
590 break;
591 #elif defined HAVE_REMOTE_LCD_AS_MAIN
592 case SYS_REMOTE_PLUGGED:
593 lcd_on();
594 lcd_update();
595 break;
597 case SYS_REMOTE_UNPLUGGED:
598 lcd_off();
599 break;
600 #endif /* HAVE_REMOTE_LCD/ HAVE_REMOTE_LCD_AS_MAIN */
601 #endif /* !SIMULATOR */
602 #ifdef SIMULATOR
603 /* This one here too for lack of a better place */
604 case SYS_SCREENDUMP:
605 screen_dump();
606 break;
607 #endif
608 case SYS_USB_CONNECTED:
609 /* Tell the USB thread that we are safe */
610 DEBUGF("backlight_thread got SYS_USB_CONNECTED\n");
611 usb_acknowledge(SYS_USB_CONNECTED_ACK);
612 break;
614 case SYS_USB_DISCONNECTED:
615 usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
616 break;
618 #ifdef BACKLIGHT_DRIVER_CLOSE
619 /* Get out of here */
620 case BACKLIGHT_QUIT:
621 return;
622 #endif
624 if (locked)
625 continue;
627 switch(ev.id)
628 { /* These events are only processed if backlight isn't locked */
629 #ifdef HAVE_REMOTE_LCD
630 case REMOTE_BACKLIGHT_ON:
631 remote_backlight_update_state();
632 break;
634 case REMOTE_BACKLIGHT_OFF:
635 remote_backlight_timer = 0; /* Disable the timeout */
636 _remote_backlight_off();
637 break;
638 #endif /* HAVE_REMOTE_LCD */
640 case BACKLIGHT_ON:
641 backlight_update_state();
642 break;
644 case BACKLIGHT_OFF:
645 backlight_timer = 0; /* Disable the timeout */
646 #if (CONFIG_BACKLIGHT_FADING != BACKLIGHT_FADING_SW_SETTING) \
647 && (CONFIG_BACKLIGHT_FADING != BACKLIGHT_FADING_SW_HW_REG)
648 _backlight_off();
649 #else
650 backlight_setup_fade_down();
651 #endif /* CONFIG_BACKLIGHT_FADING */
652 break;
653 #ifdef HAVE_LCD_SLEEP
654 case LCD_SLEEP:
655 lcd_sleep();
656 break;
657 #endif
658 #ifdef HAVE_BUTTON_LIGHT
659 case BUTTON_LIGHT_ON:
660 buttonlight_update_state();
661 break;
663 case BUTTON_LIGHT_OFF:
664 buttonlight_timer = 0;
665 _buttonlight_off();
666 break;
667 #endif
669 case SYS_POWEROFF: /* Lock backlight on poweroff so it doesn't */
670 locked = true; /* go off before power is actually cut. */
671 /* fall through */
672 #if CONFIG_CHARGING
673 case SYS_CHARGER_CONNECTED:
674 case SYS_CHARGER_DISCONNECTED:
675 #endif
676 backlight_update_state();
677 #ifdef HAVE_REMOTE_LCD
678 remote_backlight_update_state();
679 #endif
680 break;
681 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
682 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
683 case SYS_TIMEOUT:
684 if ((_backlight_fade_step(backlight_fading_state)))
685 backlight_fading_state = NOT_FADING; /* finished fading */
686 break;
687 #endif /* CONFIG_BACKLIGHT_FADING */
689 } /* end while */
692 static void backlight_tick(void)
694 if(backlight_timer)
696 if(--backlight_timer == 0)
698 backlight_off();
701 #ifdef HAVE_LCD_SLEEP
702 else if(lcd_sleep_timer)
704 if(--lcd_sleep_timer == 0)
706 /* Queue on bl thread or freeze! */
707 queue_post(&backlight_queue, LCD_SLEEP, 0);
710 #endif /* HAVE_LCD_SLEEP */
711 #ifdef HAVE_REMOTE_LCD
712 if(remote_backlight_timer)
714 if(--remote_backlight_timer == 0)
716 remote_backlight_off();
719 #endif /* HAVE_REMOVE_LCD */
720 #ifdef HAVE_BUTTON_LIGHT
721 if (buttonlight_timer)
723 if (--buttonlight_timer == 0)
725 buttonlight_off();
728 #endif /* HAVE_BUTTON_LIGHT */
731 void backlight_init(void)
733 queue_init(&backlight_queue, true);
735 #ifndef SIMULATOR
736 if (_backlight_init())
738 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM)
739 /* If backlight is already on, don't fade in. */
740 bl_dim_target = BL_PWM_COUNT;
741 bl_dim_fraction = (BL_PWM_COUNT<<16);
742 #endif
744 #endif
745 /* Leave all lights as set by the bootloader here. The settings load will
746 * call the appropriate backlight_set_*() functions, only changing light
747 * status if necessary. */
748 #ifdef BACKLIGHT_DRIVER_CLOSE
749 backlight_thread_id =
750 #endif
751 create_thread(backlight_thread, backlight_stack,
752 sizeof(backlight_stack), 0, backlight_thread_name
753 IF_PRIO(, PRIORITY_USER_INTERFACE)
754 IF_COP(, CPU));
755 tick_add_task(backlight_tick);
758 #ifdef BACKLIGHT_DRIVER_CLOSE
759 void backlight_close(void)
761 unsigned int thread = backlight_thread_id;
763 /* Wait for thread to exit */
764 if (thread == 0)
765 return;
767 backlight_thread_id = 0;
769 queue_post(&backlight_queue, BACKLIGHT_QUIT, 0);
770 thread_wait(thread);
772 #endif /* BACKLIGHT_DRIVER_CLOSE */
774 void backlight_on(void)
776 queue_remove_from_head(&backlight_queue, BACKLIGHT_ON);
777 queue_post(&backlight_queue, BACKLIGHT_ON, 0);
780 void backlight_off(void)
782 queue_post(&backlight_queue, BACKLIGHT_OFF, 0);
785 /* returns true when the backlight is on,
786 * and optionally when it's set to always off. */
787 bool is_backlight_on(bool ignore_always_off)
789 return (backlight_timer > 0) /* countdown */
790 || (backlight_timeout == 0) /* always on */
791 || ((backlight_timeout < 0) && !ignore_always_off);
794 /* return value in ticks; 0 means always on, <0 means always off */
795 int backlight_get_current_timeout(void)
797 return backlight_timeout;
800 void backlight_set_timeout(int value)
802 backlight_timeout_normal = HZ * value;
803 backlight_update_state();
806 #if CONFIG_CHARGING
807 void backlight_set_timeout_plugged(int value)
809 backlight_timeout_plugged = HZ * value;
810 backlight_update_state();
812 #endif /* CONFIG_CHARGING */
814 #ifdef HAS_BUTTON_HOLD
815 /* Hold button change event handler. */
816 void backlight_hold_changed(bool hold_button)
818 if (!hold_button || (backlight_on_button_hold > 0))
819 /* if unlocked or override in effect */
820 backlight_on();
823 void backlight_set_on_button_hold(int index)
825 if ((unsigned)index >= 3)
826 /* if given a weird value, use default */
827 index = 0;
829 backlight_on_button_hold = index;
830 backlight_update_state();
832 #endif /* HAS_BUTTON_HOLD */
834 #ifdef HAVE_LCD_SLEEP_SETTING
835 void lcd_set_sleep_after_backlight_off(int index)
837 if ((unsigned)index >= sizeof(lcd_sleep_timeout_value))
838 /* if given a weird value, use default */
839 index = 3;
841 lcd_sleep_timeout = HZ * lcd_sleep_timeout_value[index];
843 if (backlight_timer > 0 || backlight_get_current_timeout() == 0)
844 /* Timer will be set when bl turns off or bl set to on. */
845 return;
847 /* Backlight is Off */
848 if (lcd_sleep_timeout < 0)
849 lcd_sleep_timer = 1; /* Always - sleep next tick */
850 else
851 lcd_sleep_timer = lcd_sleep_timeout; /* Never, other */
853 #endif /* HAVE_LCD_SLEEP_SETTING */
855 #ifdef HAVE_REMOTE_LCD
856 void remote_backlight_on(void)
858 queue_post(&backlight_queue, REMOTE_BACKLIGHT_ON, 0);
861 void remote_backlight_off(void)
863 queue_post(&backlight_queue, REMOTE_BACKLIGHT_OFF, 0);
866 void remote_backlight_set_timeout(int value)
868 remote_backlight_timeout_normal = HZ * value;
869 remote_backlight_update_state();
872 #if CONFIG_CHARGING
873 void remote_backlight_set_timeout_plugged(int value)
875 remote_backlight_timeout_plugged = HZ * value;
876 remote_backlight_update_state();
878 #endif /* CONFIG_CHARGING */
880 #ifdef HAS_REMOTE_BUTTON_HOLD
881 /* Remote hold button change event handler. */
882 void remote_backlight_hold_changed(bool rc_hold_button)
884 if (!rc_hold_button || (remote_backlight_on_button_hold > 0))
885 /* if unlocked or override */
886 remote_backlight_on();
889 void remote_backlight_set_on_button_hold(int index)
891 if ((unsigned)index >= 3)
892 /* if given a weird value, use default */
893 index = 0;
895 remote_backlight_on_button_hold = index;
896 remote_backlight_update_state();
898 #endif /* HAS_REMOTE_BUTTON_HOLD */
900 /* return value in ticks; 0 means always on, <0 means always off */
901 int remote_backlight_get_current_timeout(void)
903 return remote_backlight_timeout;
906 /* returns true when the backlight is on, and
907 * optionally when it's set to always off */
908 bool is_remote_backlight_on(bool ignore_always_off)
910 return (remote_backlight_timer > 0) /* countdown */
911 || (remote_backlight_timeout == 0) /* always on */
912 || ((remote_backlight_timeout < 0) && !ignore_always_off);
915 #endif /* HAVE_REMOTE_LCD */
917 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
918 void backlight_set_brightness(int val)
920 if (val < MIN_BRIGHTNESS_SETTING)
921 val = MIN_BRIGHTNESS_SETTING;
922 else if (val > MAX_BRIGHTNESS_SETTING)
923 val = MAX_BRIGHTNESS_SETTING;
925 backlight_brightness = val;
926 _backlight_set_brightness(val);
927 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
928 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
929 /* receive backlight brightness */
930 _backlight_fade_update_state(val);
931 #endif
933 #endif /* HAVE_BACKLIGHT_BRIGHTNESS */
935 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
936 void buttonlight_set_brightness(int val)
938 if (val < MIN_BRIGHTNESS_SETTING)
939 val = MIN_BRIGHTNESS_SETTING;
940 else if (val > MAX_BRIGHTNESS_SETTING)
941 val = MAX_BRIGHTNESS_SETTING;
943 _buttonlight_set_brightness(val);
945 #endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
947 #else /* !defined(HAVE_BACKLIGHT) || !defined(BACKLIGHT_FULL_INIT)
948 -- no backlight, empty dummy functions */
950 #if defined(HAVE_BACKLIGHT) && !defined(BACKLIGHT_FULL_INIT)
951 void backlight_init(void)
953 (void)_backlight_init();
954 _backlight_on();
956 #endif
958 void backlight_on(void) {}
959 void backlight_off(void) {}
960 void buttonlight_on(void) {}
961 void backlight_set_timeout(int value) {(void)value;}
963 bool is_backlight_on(bool ignore_always_off)
965 (void)ignore_always_off;
966 return true;
968 #ifdef HAVE_REMOTE_LCD
969 void remote_backlight_on(void) {}
970 void remote_backlight_off(void) {}
971 void remote_backlight_set_timeout(int value) {(void)value;}
973 bool is_remote_backlight_on(bool ignore_always_off)
975 (void)ignore_always_off;
976 return true;
978 #endif /* HAVE_REMOTE_LCD */
979 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
980 void backlight_set_brightness(int val) { (void)val; }
981 #endif
982 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
983 void buttonlight_set_brightness(int val) { (void)val; }
984 #endif
985 #endif /* defined(HAVE_BACKLIGHT) && defined(BACKLIGHT_FULL_INIT) */