Fix no-backlight colours for H100 series and M3.
[kugel-rb.git] / firmware / backlight.c
blob513f643171736bdc96a106c09ea87660d591af8e
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 !defined(BOOTLOADER)
48 /* The whole driver should be built */
49 #define BACKLIGHT_FULL_INIT
50 #endif
52 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
53 int backlight_brightness = DEFAULT_BRIGHTNESS_SETTING;
54 #endif
56 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
57 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
58 #include "backlight-sw-fading.h"
59 #endif
60 #ifdef SIMULATOR
62 static inline void _backlight_on(void)
64 sim_backlight(100);
67 static inline void _backlight_off(void)
69 sim_backlight(0);
72 static inline void _backlight_set_brightness(int val)
74 (void)val;
77 static inline void _buttonlight_on(void)
81 static inline void _buttonlight_off(void)
85 static inline void _buttonlight_set_brightness(int val)
87 (void)val;
89 #ifdef HAVE_REMOTE_LCD
90 static inline void _remote_backlight_on(void)
92 sim_remote_backlight(100);
95 static inline void _remote_backlight_off(void)
97 sim_remote_backlight(0);
99 #endif /* HAVE_REMOTE_LCD */
101 #endif /* SIMULATOR */
103 #if defined(HAVE_BACKLIGHT) && defined(BACKLIGHT_FULL_INIT)
105 enum {
106 BACKLIGHT_ON,
107 BACKLIGHT_OFF,
108 #ifdef HAVE_REMOTE_LCD
109 REMOTE_BACKLIGHT_ON,
110 REMOTE_BACKLIGHT_OFF,
111 #endif
112 #if defined(_BACKLIGHT_FADE_BOOST) || defined(_BACKLIGHT_FADE_ENABLE)
113 BACKLIGHT_FADE_FINISH,
114 #endif
115 #ifdef HAVE_LCD_SLEEP
116 LCD_SLEEP,
117 #endif
118 #ifdef HAVE_BUTTON_LIGHT
119 BUTTON_LIGHT_ON,
120 BUTTON_LIGHT_OFF,
121 #endif
122 #ifdef BACKLIGHT_DRIVER_CLOSE
123 BACKLIGHT_QUIT,
124 #endif
127 static void backlight_thread(void);
128 static long backlight_stack[DEFAULT_STACK_SIZE/sizeof(long)];
129 static const char backlight_thread_name[] = "backlight";
130 static struct event_queue backlight_queue;
131 #ifdef BACKLIGHT_DRIVER_CLOSE
132 static unsigned int backlight_thread_id = 0;
133 #endif
135 static int backlight_timer SHAREDBSS_ATTR;
136 static int backlight_timeout SHAREDBSS_ATTR;
137 static int backlight_timeout_normal = 5*HZ;
138 #if CONFIG_CHARGING
139 static int backlight_timeout_plugged = 5*HZ;
140 #endif
141 #ifdef HAS_BUTTON_HOLD
142 static int backlight_on_button_hold = 0;
143 #endif
145 #ifdef HAVE_BUTTON_LIGHT
146 static int buttonlight_timer;
147 int _buttonlight_timeout = 5*HZ;
149 /* Update state of buttonlight according to timeout setting */
150 static void buttonlight_update_state(void)
152 buttonlight_timer = _buttonlight_timeout;
154 /* Buttonlight == OFF in the setting? */
155 if (buttonlight_timer < 0)
157 buttonlight_timer = 0; /* Disable the timeout */
158 _buttonlight_off();
160 else
161 _buttonlight_on();
164 /* external interface */
165 void buttonlight_on(void)
167 queue_remove_from_head(&backlight_queue, BUTTON_LIGHT_ON);
168 queue_post(&backlight_queue, BUTTON_LIGHT_ON, 0);
171 void buttonlight_off(void)
173 queue_post(&backlight_queue, BUTTON_LIGHT_OFF, 0);
176 void buttonlight_set_timeout(int value)
178 _buttonlight_timeout = HZ * value;
179 buttonlight_update_state();
182 #endif /* HAVE_BUTTON_LIGHT */
184 #ifdef HAVE_REMOTE_LCD
185 static int remote_backlight_timer;
186 static int remote_backlight_timeout;
187 static int remote_backlight_timeout_normal = 5*HZ;
188 #if CONFIG_CHARGING
189 static int remote_backlight_timeout_plugged = 5*HZ;
190 #endif
191 #ifdef HAS_REMOTE_BUTTON_HOLD
192 static int remote_backlight_on_button_hold = 0;
193 #endif
194 #endif /* HAVE_REMOTE_LCD */
196 #ifdef HAVE_LCD_SLEEP
197 #ifdef HAVE_LCD_SLEEP_SETTING
198 const signed char lcd_sleep_timeout_value[10] =
200 -1, 0, 5, 10, 15, 20, 30, 45, 60, 90
202 static int lcd_sleep_timeout = 10*HZ;
203 #else
204 /* Target defines needed value */
205 static const int lcd_sleep_timeout = LCD_SLEEP_TIMEOUT;
206 #endif
208 static int lcd_sleep_timer = 0;
210 void backlight_lcd_sleep_countdown(bool start)
212 if (!start)
214 /* Cancel the LCD sleep countdown */
215 lcd_sleep_timer = 0;
216 return;
219 /* Start LCD sleep countdown */
220 if (lcd_sleep_timeout < 0)
222 lcd_sleep_timer = 0; /* Setting == Always */
223 lcd_sleep();
225 else
227 lcd_sleep_timer = lcd_sleep_timeout;
230 #endif /* HAVE_LCD_SLEEP */
232 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
233 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
234 static int backlight_fading_type = (FADING_UP|FADING_DOWN);
235 static int backlight_fading_state = NOT_FADING;
236 #endif
239 /* backlight fading */
240 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM)
241 #define BL_PWM_INTERVAL 5 /* Cycle interval in ms */
242 #define BL_PWM_BITS 8
243 #define BL_PWM_COUNT (1<<BL_PWM_BITS)
245 /* s15.16 fixed point variables */
246 static int32_t bl_fade_in_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16)/300;
247 static int32_t bl_fade_out_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16)/2000;
248 static int32_t bl_dim_fraction = 0;
250 static int bl_dim_target = 0;
251 static int bl_dim_current = 0;
252 static enum {DIM_STATE_START, DIM_STATE_MAIN} bl_dim_state = DIM_STATE_START;
253 static bool bl_timer_active = false;
255 static void backlight_isr(void)
257 int timer_period = (TIMER_FREQ*BL_PWM_INTERVAL/1000);
258 bool idle = false;
260 switch (bl_dim_state)
262 /* New cycle */
263 case DIM_STATE_START:
264 bl_dim_current = bl_dim_fraction >> 16;
266 if (bl_dim_current > 0 && bl_dim_current < BL_PWM_COUNT)
268 _backlight_on_isr();
269 timer_period = (timer_period * bl_dim_current) >> BL_PWM_BITS;
270 bl_dim_state = DIM_STATE_MAIN;
272 else
274 if (bl_dim_current)
275 _backlight_on_isr();
276 else
277 _backlight_off_isr();
278 if (bl_dim_current == bl_dim_target)
279 idle = true;
281 if (bl_dim_current < bl_dim_target)
283 bl_dim_fraction = MIN(bl_dim_fraction + bl_fade_in_step,
284 (BL_PWM_COUNT<<16));
286 else if (bl_dim_current > bl_dim_target)
288 bl_dim_fraction = MAX(bl_dim_fraction - bl_fade_out_step, 0);
290 break;
292 /* Dim main screen */
293 case DIM_STATE_MAIN:
294 _backlight_off_isr();
295 timer_period = (timer_period * (BL_PWM_COUNT - bl_dim_current))
296 >> BL_PWM_BITS;
297 bl_dim_state = DIM_STATE_START;
298 break ;
300 if (idle)
302 #if defined(_BACKLIGHT_FADE_BOOST) || defined(_BACKLIGHT_FADE_ENABLE)
303 queue_post(&backlight_queue, BACKLIGHT_FADE_FINISH, 0);
304 #endif
305 timer_unregister();
306 bl_timer_active = false;
308 else
309 timer_set_period(timer_period);
312 static void backlight_switch(void)
314 if (bl_dim_target > (BL_PWM_COUNT/2))
316 _backlight_on_normal();
317 bl_dim_fraction = (BL_PWM_COUNT<<16);
319 else
321 _backlight_off_normal();
322 bl_dim_fraction = 0;
326 static void backlight_release_timer(void)
328 #ifdef _BACKLIGHT_FADE_BOOST
329 cpu_boost(false);
330 #endif
331 timer_unregister();
332 bl_timer_active = false;
333 backlight_switch();
336 static void backlight_dim(int value)
338 /* protect from extraneous calls with the same target value */
339 if (value == bl_dim_target)
340 return;
342 bl_dim_target = value;
344 if (bl_timer_active)
345 return ;
347 if (timer_register(0, backlight_release_timer, 2, 0, backlight_isr
348 IF_COP(, CPU)))
350 #ifdef _BACKLIGHT_FADE_BOOST
351 /* Prevent cpu frequency changes while dimming. */
352 cpu_boost(true);
353 #endif
354 bl_timer_active = true;
356 else
357 backlight_switch();
360 static void _backlight_on(void)
362 #ifdef HAVE_LCD_SLEEP
363 backlight_lcd_sleep_countdown(false);
364 #endif
366 if (bl_fade_in_step > 0)
368 #ifdef _BACKLIGHT_FADE_ENABLE
369 _backlight_hw_enable(true);
370 #endif
371 backlight_dim(BL_PWM_COUNT);
373 else
375 bl_dim_target = BL_PWM_COUNT;
376 bl_dim_fraction = (BL_PWM_COUNT<<16);
377 _backlight_on_normal();
381 static void _backlight_off(void)
383 if (bl_fade_out_step > 0)
385 backlight_dim(0);
387 else
389 bl_dim_target = bl_dim_fraction = 0;
390 _backlight_off_normal();
393 #ifdef HAVE_LCD_SLEEP
394 backlight_lcd_sleep_countdown(true);
395 #endif
398 void backlight_set_fade_in(int value)
400 if (value > 0)
401 bl_fade_in_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16) / value;
402 else
403 bl_fade_in_step = 0;
406 void backlight_set_fade_out(int value)
408 if (value > 0)
409 bl_fade_out_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16) / value;
410 else
411 bl_fade_out_step = 0;
414 #elif (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
415 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
417 void backlight_set_fade_out(bool value)
419 if(value) /* on */
420 backlight_fading_type |= FADING_DOWN;
421 else
422 backlight_fading_type &= FADING_UP;
425 void backlight_set_fade_in(bool value)
427 if(value) /* on */
428 backlight_fading_type |= FADING_UP;
429 else
430 backlight_fading_type &= FADING_DOWN;
433 static void backlight_setup_fade_up(void)
435 if (backlight_fading_type & FADING_UP)
437 if (backlight_fading_state == NOT_FADING)
439 /* make sure the backlight is at lowest level */
440 _backlight_on();
442 backlight_fading_state = FADING_UP;
444 else
446 backlight_fading_state = NOT_FADING;
447 _backlight_fade_update_state(backlight_brightness);
448 _backlight_on();
449 _backlight_set_brightness(backlight_brightness);
453 static void backlight_setup_fade_down(void)
455 if (backlight_fading_type & FADING_DOWN)
457 backlight_fading_state = FADING_DOWN;
459 else
461 backlight_fading_state = NOT_FADING;
462 _backlight_fade_update_state(MIN_BRIGHTNESS_SETTING-1);
463 _backlight_off();
464 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
465 /* write the lowest brightness level to the hardware so that
466 * fading up is glitch free */
467 _backlight_set_brightness(MIN_BRIGHTNESS_SETTING);
468 #endif
471 #endif /* CONFIG_BACKLIGHT_FADING */
473 /* Update state of backlight according to timeout setting */
474 static void backlight_update_state(void)
476 #ifdef HAS_BUTTON_HOLD
477 if ((backlight_on_button_hold != 0)
478 #ifdef HAVE_REMOTE_LCD_AS_MAIN
479 && remote_button_hold()
480 #else
481 && button_hold()
482 #endif
484 backlight_timeout = (backlight_on_button_hold == 2) ? 0 : -1;
485 /* always on or always off */
486 else
487 #endif
488 #if CONFIG_CHARGING
489 if (power_input_present())
490 backlight_timeout = backlight_timeout_plugged;
491 else
492 #endif
493 backlight_timeout = backlight_timeout_normal;
495 /* Backlight == OFF in the setting? */
496 if (UNLIKELY(backlight_timeout < 0))
498 backlight_timer = 0; /* Disable the timeout */
499 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
500 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
501 backlight_setup_fade_down();
502 /* necessary step to issue fading down when the setting is selected */
503 queue_post(&backlight_queue, SYS_TIMEOUT, 0);
504 #else
505 _backlight_off();
506 #endif
508 else
510 backlight_timer = backlight_timeout;
511 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
512 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
513 backlight_setup_fade_up();
514 #else
515 _backlight_on();
516 #endif
520 #ifdef HAVE_REMOTE_LCD
521 /* Update state of remote backlight according to timeout setting */
522 static void remote_backlight_update_state(void)
524 #ifdef HAS_REMOTE_BUTTON_HOLD
525 if (remote_button_hold() && (remote_backlight_on_button_hold != 0))
526 remote_backlight_timeout = (remote_backlight_on_button_hold == 2)
527 ? 0 : -1; /* always on or always off */
528 else
529 #endif
530 #if CONFIG_CHARGING
531 if (power_input_present())
532 remote_backlight_timeout = remote_backlight_timeout_plugged;
533 else
534 #endif
535 remote_backlight_timeout = remote_backlight_timeout_normal;
537 /* Backlight == OFF in the setting? */
538 if (remote_backlight_timeout < 0)
540 remote_backlight_timer = 0; /* Disable the timeout */
541 _remote_backlight_off();
543 else
545 remote_backlight_timer = remote_backlight_timeout;
546 _remote_backlight_on();
549 #endif /* HAVE_REMOTE_LCD */
551 void backlight_thread(void)
553 struct queue_event ev;
554 bool locked = false;
556 while(1)
558 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
559 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
560 if (backlight_fading_state)
561 queue_wait_w_tmo(&backlight_queue, &ev, FADE_DELAY);
562 else
563 #endif
564 queue_wait(&backlight_queue, &ev);
565 switch(ev.id)
566 { /* These events must always be processed */
567 #ifdef _BACKLIGHT_FADE_BOOST
568 case BACKLIGHT_FADE_FINISH:
569 cpu_boost(false);
570 break;
571 #endif
572 #ifdef _BACKLIGHT_FADE_ENABLE
573 case BACKLIGHT_FADE_FINISH:
574 _backlight_hw_enable((bl_dim_current|bl_dim_target) != 0);
575 break;
576 #endif
578 #ifndef SIMULATOR
579 /* Here for now or else the aggressive init messes up scrolling */
580 #ifdef HAVE_REMOTE_LCD
581 case SYS_REMOTE_PLUGGED:
582 lcd_remote_on();
583 lcd_remote_update();
584 break;
586 case SYS_REMOTE_UNPLUGGED:
587 lcd_remote_off();
588 break;
589 #elif defined HAVE_REMOTE_LCD_AS_MAIN
590 case SYS_REMOTE_PLUGGED:
591 lcd_on();
592 lcd_update();
593 break;
595 case SYS_REMOTE_UNPLUGGED:
596 lcd_off();
597 break;
598 #endif /* HAVE_REMOTE_LCD/ HAVE_REMOTE_LCD_AS_MAIN */
599 #endif /* !SIMULATOR */
600 #ifdef SIMULATOR
601 /* TODO: find a better way to do it but we need
602 * a kernel thread somewhere to handle this */
603 case SYS_SCREENDUMP:
604 screen_dump();
605 #ifdef HAVE_REMOTE_LCD
606 remote_screen_dump();
607 #endif
608 break;
609 #endif
610 case SYS_USB_CONNECTED:
611 /* Tell the USB thread that we are safe */
612 DEBUGF("backlight_thread got SYS_USB_CONNECTED\n");
613 usb_acknowledge(SYS_USB_CONNECTED_ACK);
614 break;
616 case SYS_USB_DISCONNECTED:
617 usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
618 break;
620 #ifdef BACKLIGHT_DRIVER_CLOSE
621 /* Get out of here */
622 case BACKLIGHT_QUIT:
623 return;
624 #endif
626 if (locked)
627 continue;
629 switch(ev.id)
630 { /* These events are only processed if backlight isn't locked */
631 #ifdef HAVE_REMOTE_LCD
632 case REMOTE_BACKLIGHT_ON:
633 remote_backlight_update_state();
634 break;
636 case REMOTE_BACKLIGHT_OFF:
637 remote_backlight_timer = 0; /* Disable the timeout */
638 _remote_backlight_off();
639 break;
640 #endif /* HAVE_REMOTE_LCD */
642 case BACKLIGHT_ON:
643 backlight_update_state();
644 break;
646 case BACKLIGHT_OFF:
647 backlight_timer = 0; /* Disable the timeout */
648 #if (CONFIG_BACKLIGHT_FADING != BACKLIGHT_FADING_SW_SETTING) \
649 && (CONFIG_BACKLIGHT_FADING != BACKLIGHT_FADING_SW_HW_REG)
650 _backlight_off();
651 #else
652 backlight_setup_fade_down();
653 #endif /* CONFIG_BACKLIGHT_FADING */
654 break;
655 #ifdef HAVE_LCD_SLEEP
656 case LCD_SLEEP:
657 lcd_sleep();
658 break;
659 #endif
660 #ifdef HAVE_BUTTON_LIGHT
661 case BUTTON_LIGHT_ON:
662 buttonlight_update_state();
663 break;
665 case BUTTON_LIGHT_OFF:
666 buttonlight_timer = 0;
667 _buttonlight_off();
668 break;
669 #endif
671 case SYS_POWEROFF: /* Lock backlight on poweroff so it doesn't */
672 locked = true; /* go off before power is actually cut. */
673 /* fall through */
674 #if CONFIG_CHARGING
675 case SYS_CHARGER_CONNECTED:
676 case SYS_CHARGER_DISCONNECTED:
677 #endif
678 backlight_update_state();
679 #ifdef HAVE_REMOTE_LCD
680 remote_backlight_update_state();
681 #endif
682 break;
683 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
684 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
685 case SYS_TIMEOUT:
686 if ((_backlight_fade_step(backlight_fading_state)))
687 backlight_fading_state = NOT_FADING; /* finished fading */
688 break;
689 #endif /* CONFIG_BACKLIGHT_FADING */
691 } /* end while */
694 static void backlight_tick(void)
696 if(backlight_timer)
698 if(--backlight_timer == 0)
700 backlight_off();
703 #ifdef HAVE_LCD_SLEEP
704 else if(lcd_sleep_timer)
706 if(--lcd_sleep_timer == 0)
708 /* Queue on bl thread or freeze! */
709 queue_post(&backlight_queue, LCD_SLEEP, 0);
712 #endif /* HAVE_LCD_SLEEP */
713 #ifdef HAVE_REMOTE_LCD
714 if(remote_backlight_timer)
716 if(--remote_backlight_timer == 0)
718 remote_backlight_off();
721 #endif /* HAVE_REMOVE_LCD */
722 #ifdef HAVE_BUTTON_LIGHT
723 if (buttonlight_timer)
725 if (--buttonlight_timer == 0)
727 buttonlight_off();
730 #endif /* HAVE_BUTTON_LIGHT */
733 void backlight_init(void)
735 queue_init(&backlight_queue, true);
737 #ifndef SIMULATOR
738 if (_backlight_init())
740 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM)
741 /* If backlight is already on, don't fade in. */
742 bl_dim_target = BL_PWM_COUNT;
743 bl_dim_fraction = (BL_PWM_COUNT<<16);
744 #endif
746 #endif
747 /* Leave all lights as set by the bootloader here. The settings load will
748 * call the appropriate backlight_set_*() functions, only changing light
749 * status if necessary. */
750 #ifdef BACKLIGHT_DRIVER_CLOSE
751 backlight_thread_id =
752 #endif
753 create_thread(backlight_thread, backlight_stack,
754 sizeof(backlight_stack), 0, backlight_thread_name
755 IF_PRIO(, PRIORITY_USER_INTERFACE)
756 IF_COP(, CPU));
757 tick_add_task(backlight_tick);
760 #ifdef BACKLIGHT_DRIVER_CLOSE
761 void backlight_close(void)
763 unsigned int thread = backlight_thread_id;
765 /* Wait for thread to exit */
766 if (thread == 0)
767 return;
769 backlight_thread_id = 0;
771 queue_post(&backlight_queue, BACKLIGHT_QUIT, 0);
772 thread_wait(thread);
774 #endif /* BACKLIGHT_DRIVER_CLOSE */
776 void backlight_on(void)
778 queue_remove_from_head(&backlight_queue, BACKLIGHT_ON);
779 queue_post(&backlight_queue, BACKLIGHT_ON, 0);
782 void backlight_off(void)
784 queue_post(&backlight_queue, BACKLIGHT_OFF, 0);
787 /* returns true when the backlight is on,
788 * and optionally when it's set to always off. */
789 bool is_backlight_on(bool ignore_always_off)
791 return (backlight_timer > 0) /* countdown */
792 || (backlight_timeout == 0) /* always on */
793 || ((backlight_timeout < 0) && !ignore_always_off);
796 /* return value in ticks; 0 means always on, <0 means always off */
797 int backlight_get_current_timeout(void)
799 return backlight_timeout;
802 void backlight_set_timeout(int value)
804 backlight_timeout_normal = HZ * value;
805 backlight_update_state();
808 #if CONFIG_CHARGING
809 void backlight_set_timeout_plugged(int value)
811 backlight_timeout_plugged = HZ * value;
812 backlight_update_state();
814 #endif /* CONFIG_CHARGING */
816 #ifdef HAS_BUTTON_HOLD
817 /* Hold button change event handler. */
818 void backlight_hold_changed(bool hold_button)
820 if (!hold_button || (backlight_on_button_hold > 0))
821 /* if unlocked or override in effect */
822 backlight_on();
825 void backlight_set_on_button_hold(int index)
827 if ((unsigned)index >= 3)
828 /* if given a weird value, use default */
829 index = 0;
831 backlight_on_button_hold = index;
832 backlight_update_state();
834 #endif /* HAS_BUTTON_HOLD */
836 #ifdef HAVE_LCD_SLEEP_SETTING
837 void lcd_set_sleep_after_backlight_off(int index)
839 if ((unsigned)index >= sizeof(lcd_sleep_timeout_value))
840 /* if given a weird value, use default */
841 index = 3;
843 lcd_sleep_timeout = HZ * lcd_sleep_timeout_value[index];
845 if (backlight_timer > 0 || backlight_get_current_timeout() == 0)
846 /* Timer will be set when bl turns off or bl set to on. */
847 return;
849 /* Backlight is Off */
850 if (lcd_sleep_timeout < 0)
851 lcd_sleep_timer = 1; /* Always - sleep next tick */
852 else
853 lcd_sleep_timer = lcd_sleep_timeout; /* Never, other */
855 #endif /* HAVE_LCD_SLEEP_SETTING */
857 #ifdef HAVE_REMOTE_LCD
858 void remote_backlight_on(void)
860 queue_post(&backlight_queue, REMOTE_BACKLIGHT_ON, 0);
863 void remote_backlight_off(void)
865 queue_post(&backlight_queue, REMOTE_BACKLIGHT_OFF, 0);
868 void remote_backlight_set_timeout(int value)
870 remote_backlight_timeout_normal = HZ * value;
871 remote_backlight_update_state();
874 #if CONFIG_CHARGING
875 void remote_backlight_set_timeout_plugged(int value)
877 remote_backlight_timeout_plugged = HZ * value;
878 remote_backlight_update_state();
880 #endif /* CONFIG_CHARGING */
882 #ifdef HAS_REMOTE_BUTTON_HOLD
883 /* Remote hold button change event handler. */
884 void remote_backlight_hold_changed(bool rc_hold_button)
886 if (!rc_hold_button || (remote_backlight_on_button_hold > 0))
887 /* if unlocked or override */
888 remote_backlight_on();
891 void remote_backlight_set_on_button_hold(int index)
893 if ((unsigned)index >= 3)
894 /* if given a weird value, use default */
895 index = 0;
897 remote_backlight_on_button_hold = index;
898 remote_backlight_update_state();
900 #endif /* HAS_REMOTE_BUTTON_HOLD */
902 /* return value in ticks; 0 means always on, <0 means always off */
903 int remote_backlight_get_current_timeout(void)
905 return remote_backlight_timeout;
908 /* returns true when the backlight is on, and
909 * optionally when it's set to always off */
910 bool is_remote_backlight_on(bool ignore_always_off)
912 return (remote_backlight_timer > 0) /* countdown */
913 || (remote_backlight_timeout == 0) /* always on */
914 || ((remote_backlight_timeout < 0) && !ignore_always_off);
917 #endif /* HAVE_REMOTE_LCD */
919 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
920 void backlight_set_brightness(int val)
922 if (val < MIN_BRIGHTNESS_SETTING)
923 val = MIN_BRIGHTNESS_SETTING;
924 else if (val > MAX_BRIGHTNESS_SETTING)
925 val = MAX_BRIGHTNESS_SETTING;
927 backlight_brightness = val;
928 _backlight_set_brightness(val);
929 #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
930 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
931 /* receive backlight brightness */
932 _backlight_fade_update_state(val);
933 #endif
935 #endif /* HAVE_BACKLIGHT_BRIGHTNESS */
937 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
938 void buttonlight_set_brightness(int val)
940 if (val < MIN_BRIGHTNESS_SETTING)
941 val = MIN_BRIGHTNESS_SETTING;
942 else if (val > MAX_BRIGHTNESS_SETTING)
943 val = MAX_BRIGHTNESS_SETTING;
945 _buttonlight_set_brightness(val);
947 #endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
949 #else /* !defined(HAVE_BACKLIGHT) || !defined(BACKLIGHT_FULL_INIT)
950 -- no backlight, empty dummy functions */
952 #if defined(HAVE_BACKLIGHT) && !defined(BACKLIGHT_FULL_INIT)
953 void backlight_init(void)
955 (void)_backlight_init();
956 _backlight_on();
958 #endif
960 void backlight_on(void) {}
961 void backlight_off(void) {}
962 void buttonlight_on(void) {}
963 void backlight_set_timeout(int value) {(void)value;}
965 bool is_backlight_on(bool ignore_always_off)
967 (void)ignore_always_off;
968 return true;
970 #ifdef HAVE_REMOTE_LCD
971 void remote_backlight_on(void) {}
972 void remote_backlight_off(void) {}
973 void remote_backlight_set_timeout(int value) {(void)value;}
975 bool is_remote_backlight_on(bool ignore_always_off)
977 (void)ignore_always_off;
978 return true;
980 #endif /* HAVE_REMOTE_LCD */
981 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
982 void backlight_set_brightness(int val) { (void)val; }
983 #endif
984 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
985 void buttonlight_set_brightness(int val) { (void)val; }
986 #endif
987 #endif /* defined(HAVE_BACKLIGHT) && defined(BACKLIGHT_FULL_INIT) */