blob: 3acc89c27c0f8bbf5e77f2bdee37fc6142f0c80c [file] [log] [blame]
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
Steve Bavinf6847262008-11-26 08:26:13 +000011 * Additional work by Martin Ritter (2007) and Thomas Martitz (2008)
12 * for backlight thread fading
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +000013 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000014 * 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.
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +000018 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include "config.h"
24#include <stdlib.h>
Linus Nielsen Feltzingeb5463d2004-10-07 08:38:51 +000025#include "cpu.h"
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +000026#include "kernel.h"
27#include "thread.h"
28#include "i2c.h"
29#include "debug.h"
30#include "rtc.h"
Linus Nielsen Feltzing392f3852002-06-29 23:01:10 +000031#include "usb.h"
Daniel Stenbergb95fe1a2002-10-01 10:59:36 +000032#include "power.h"
Jörg Hohensohn75bab492003-11-06 01:34:50 +000033#include "system.h"
Rani Hodc9f59e62006-08-08 22:03:56 +000034#include "button.h"
Jens Arnolde44372e2005-07-26 20:01:11 +000035#include "timer.h"
Jens Arnoldb51f7df2005-11-21 23:55:39 +000036#include "backlight.h"
Jens Arnold8e664912008-03-19 00:34:56 +000037#include "lcd.h"
Jens Arnold11ad7b42009-02-10 23:43:37 +000038#include "screendump.h"
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +000039
Christian Gmeinercf2b8212005-04-15 13:51:19 +000040#ifdef HAVE_REMOTE_LCD
41#include "lcd-remote.h"
42#endif
Thomas Martitz35e8b142010-06-21 16:53:00 +000043
Jens Arnold47bf6c52007-04-12 22:12:13 +000044#ifndef SIMULATOR
Udo Schläpferdbabd0d2015-02-02 21:44:29 +010045/*
46 Device specific implementation:
47 bool backlight_hw_init(void);
48 void backlight_hw_on(void);
49 void backlight_hw_off(void);
50 void backlight_hw_brightness(int brightness);
51*/
Linus Nielsen Feltzing13618002006-03-22 14:17:45 +000052#include "backlight-target.h"
Thomas Martitz0a5beba2009-04-26 02:27:11 +000053#else
54#include "backlight-sim.h"
Linus Nielsen Feltzing13618002006-03-22 14:17:45 +000055#endif
Christian Gmeinercf2b8212005-04-15 13:51:19 +000056
Thomas Martitz4e26db32010-06-21 17:26:50 +000057#if defined(HAVE_BACKLIGHT) && defined(BACKLIGHT_FULL_INIT)
Thomas Martitz63701052010-06-21 17:10:22 +000058
Thomas Martitz12a0ed32009-01-26 23:21:49 +000059#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
60 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
Thomas Martitz81df9532009-01-22 10:50:11 +000061#include "backlight-sw-fading.h"
Steve Bavinf6847262008-11-26 08:26:13 +000062#endif
Thom Johansen3c7278f2006-03-19 17:42:58 +000063
Thomas Martitz14731bc2009-04-28 08:57:38 +000064#define BACKLIGHT_FADE_IN_THREAD \
65 (CONFIG_BACKLIGHT_FADING & (BACKLIGHT_FADING_SW_SETTING \
66 |BACKLIGHT_FADING_SW_HW_REG \
67 |BACKLIGHT_FADING_PWM) )
68
Thomas Martitzc40af942009-04-26 00:47:35 +000069#define BACKLIGHT_THREAD_TIMEOUT HZ
70
Jens Arnoldef12b3b2007-11-12 18:49:53 +000071enum {
72 BACKLIGHT_ON,
73 BACKLIGHT_OFF,
Thomas Martitzb0ac9442009-04-24 08:54:10 +000074 BACKLIGHT_TMO_CHANGED,
Boris Gjenerof4943b92009-05-01 03:18:20 +000075#ifdef HAVE_BACKLIGHT_BRIGHTNESS
76 BACKLIGHT_BRIGHTNESS_CHANGED,
77#endif
Jens Arnoldef12b3b2007-11-12 18:49:53 +000078#ifdef HAVE_REMOTE_LCD
79 REMOTE_BACKLIGHT_ON,
80 REMOTE_BACKLIGHT_OFF,
Thomas Martitzb0ac9442009-04-24 08:54:10 +000081 REMOTE_BACKLIGHT_TMO_CHANGED,
Jens Arnoldef12b3b2007-11-12 18:49:53 +000082#endif
83#if defined(_BACKLIGHT_FADE_BOOST) || defined(_BACKLIGHT_FADE_ENABLE)
84 BACKLIGHT_FADE_FINISH,
85#endif
Rani Hodc9f59e62006-08-08 22:03:56 +000086#ifdef HAVE_LCD_SLEEP
Jens Arnoldef12b3b2007-11-12 18:49:53 +000087 LCD_SLEEP,
Rani Hodc9f59e62006-08-08 22:03:56 +000088#endif
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +000089#ifdef HAVE_BUTTON_LIGHT
Jens Arnoldef12b3b2007-11-12 18:49:53 +000090 BUTTON_LIGHT_ON,
91 BUTTON_LIGHT_OFF,
Thomas Martitzb0ac9442009-04-24 08:54:10 +000092 BUTTON_LIGHT_TMO_CHANGED,
Boris Gjenerof4943b92009-05-01 03:18:20 +000093#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
94 BUTTON_LIGHT_BRIGHTNESS_CHANGED,
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +000095#endif
Boris Gjenerof4943b92009-05-01 03:18:20 +000096#endif /* HAVE_BUTTON_LIGHT */
Michael Sevakis80278e42008-05-10 18:00:11 +000097#ifdef BACKLIGHT_DRIVER_CLOSE
98 BACKLIGHT_QUIT,
99#endif
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000100};
Thom Johansen3c7278f2006-03-19 17:42:58 +0000101
102static void backlight_thread(void);
103static long backlight_stack[DEFAULT_STACK_SIZE/sizeof(long)];
104static const char backlight_thread_name[] = "backlight";
Michael Sevakisb15aa472011-02-14 11:27:45 +0000105static struct event_queue backlight_queue SHAREDBSS_ATTR;
William Wilgusdc87e9e2016-11-22 06:21:31 +0100106static bool ignore_backlight_on = false;
107static int backlight_ignored_timer = 0;
Michael Sevakis80278e42008-05-10 18:00:11 +0000108#ifdef BACKLIGHT_DRIVER_CLOSE
Michael Sevakis8cfbd362008-12-10 08:57:10 +0000109static unsigned int backlight_thread_id = 0;
Michael Sevakis80278e42008-05-10 18:00:11 +0000110#endif
Thom Johansen3c7278f2006-03-19 17:42:58 +0000111
Thomas Martitz0017dfb2009-04-25 18:15:50 +0000112#ifdef HAVE_BACKLIGHT_BRIGHTNESS
113int backlight_brightness = DEFAULT_BRIGHTNESS_SETTING;
114#endif
Jens Arnold94c6e6f2008-04-06 15:15:44 +0000115static int backlight_timer SHAREDBSS_ATTR;
Jens Arnoldffeaea62007-08-10 21:55:48 +0000116static int backlight_timeout_normal = 5*HZ;
Jonathan Gordon9a6f4192007-02-18 05:32:06 +0000117#if CONFIG_CHARGING
Thom Johansen3c7278f2006-03-19 17:42:58 +0000118static int backlight_timeout_plugged = 5*HZ;
119#endif
Rani Hodc9f59e62006-08-08 22:03:56 +0000120#ifdef HAS_BUTTON_HOLD
121static int backlight_on_button_hold = 0;
122#endif
Thomas Martitzc40af942009-04-26 00:47:35 +0000123static void backlight_timeout_handler(void);
Thom Johansen3c7278f2006-03-19 17:42:58 +0000124
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000125#ifdef HAVE_BUTTON_LIGHT
Jens Arnold5f1ec302007-10-07 15:02:02 +0000126static int buttonlight_timer;
Thomas Martitz0017dfb2009-04-25 18:15:50 +0000127static int buttonlight_timeout = 5*HZ;
William Wilgusdc87e9e2016-11-22 06:21:31 +0100128static bool ignore_buttonlight_on = false;
129static int buttonlight_ignored_timer = 0;
Karl Kurbjun1fc2d912007-05-10 03:08:47 +0000130
131/* Update state of buttonlight according to timeout setting */
132static void buttonlight_update_state(void)
133{
Thomas Martitz0017dfb2009-04-25 18:15:50 +0000134 buttonlight_timer = buttonlight_timeout;
Karl Kurbjun1fc2d912007-05-10 03:08:47 +0000135
136 /* Buttonlight == OFF in the setting? */
Jens Arnold5f1ec302007-10-07 15:02:02 +0000137 if (buttonlight_timer < 0)
Karl Kurbjun1fc2d912007-05-10 03:08:47 +0000138 {
Jens Arnold5f1ec302007-10-07 15:02:02 +0000139 buttonlight_timer = 0; /* Disable the timeout */
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100140 buttonlight_hw_off();
Karl Kurbjun1fc2d912007-05-10 03:08:47 +0000141 }
142 else
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100143 buttonlight_hw_on();
Karl Kurbjun1fc2d912007-05-10 03:08:47 +0000144}
145
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000146/* external interface */
William Wilgusdc87e9e2016-11-22 06:21:31 +0100147
Jens Arnold5f1ec302007-10-07 15:02:02 +0000148void buttonlight_on(void)
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000149{
William Wilgusdc87e9e2016-11-22 06:21:31 +0100150 if(!ignore_buttonlight_on)
151 {
152 queue_remove_from_head(&backlight_queue, BUTTON_LIGHT_ON);
153 queue_post(&backlight_queue, BUTTON_LIGHT_ON, 0);
154 }
155}
156
157void buttonlight_on_ignore(bool value, int timeout)
158{
159 ignore_buttonlight_on = value;
160 buttonlight_ignored_timer = timeout;
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000161}
162
Jens Arnold5f1ec302007-10-07 15:02:02 +0000163void buttonlight_off(void)
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000164{
165 queue_post(&backlight_queue, BUTTON_LIGHT_OFF, 0);
166}
167
Jens Arnoldd490f442007-11-25 17:36:21 +0000168void buttonlight_set_timeout(int value)
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000169{
Thomas Martitz0017dfb2009-04-25 18:15:50 +0000170 buttonlight_timeout = HZ * value;
Thomas Martitzb0ac9442009-04-24 08:54:10 +0000171 queue_post(&backlight_queue, BUTTON_LIGHT_TMO_CHANGED, 0);
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000172}
173
Thomas Martitz0017dfb2009-04-25 18:15:50 +0000174int buttonlight_get_current_timeout(void)
175{
176 return buttonlight_timeout;
177}
178
Michael Sevakis80278e42008-05-10 18:00:11 +0000179#endif /* HAVE_BUTTON_LIGHT */
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000180
Thom Johansen3c7278f2006-03-19 17:42:58 +0000181#ifdef HAVE_REMOTE_LCD
182static int remote_backlight_timer;
Jens Arnoldffeaea62007-08-10 21:55:48 +0000183static int remote_backlight_timeout_normal = 5*HZ;
Jonathan Gordon9a6f4192007-02-18 05:32:06 +0000184#if CONFIG_CHARGING
Thom Johansen3c7278f2006-03-19 17:42:58 +0000185static int remote_backlight_timeout_plugged = 5*HZ;
186#endif
Michael Sevakis3d2e10b2006-09-10 02:00:40 +0000187#ifdef HAS_REMOTE_BUTTON_HOLD
188static int remote_backlight_on_button_hold = 0;
189#endif
Michael Sevakis80278e42008-05-10 18:00:11 +0000190#endif /* HAVE_REMOTE_LCD */
Thom Johansen3c7278f2006-03-19 17:42:58 +0000191
Rani Hodc9f59e62006-08-08 22:03:56 +0000192#ifdef HAVE_LCD_SLEEP
Michael Sevakis009cebe2008-05-14 19:29:25 +0000193#ifdef HAVE_LCD_SLEEP_SETTING
Michael Sevakis009cebe2008-05-14 19:29:25 +0000194static int lcd_sleep_timeout = 10*HZ;
195#else
196/* Target defines needed value */
Thomas Martitz0017dfb2009-04-25 18:15:50 +0000197#define lcd_sleep_timeout LCD_SLEEP_TIMEOUT
Rani Hodc9f59e62006-08-08 22:03:56 +0000198#endif
199
Boris Gjenerod50d1df2009-04-21 21:49:29 +0000200static int lcd_sleep_timer SHAREDDATA_ATTR = 0;
Michael Sevakis009cebe2008-05-14 19:29:25 +0000201
Thomas Martitz6abae1f2009-04-26 01:23:39 +0000202static void backlight_lcd_sleep_countdown(bool start)
Michael Sevakis009cebe2008-05-14 19:29:25 +0000203{
204 if (!start)
205 {
206 /* Cancel the LCD sleep countdown */
207 lcd_sleep_timer = 0;
208 return;
209 }
210
211 /* Start LCD sleep countdown */
212 if (lcd_sleep_timeout < 0)
213 {
214 lcd_sleep_timer = 0; /* Setting == Always */
Boris Gjenerod50d1df2009-04-21 21:49:29 +0000215 /* Ensure lcd_sleep() is called from backlight_thread() */
Thomas Martitz6abae1f2009-04-26 01:23:39 +0000216#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM)
Boris Gjenerod50d1df2009-04-21 21:49:29 +0000217 queue_post(&backlight_queue, LCD_SLEEP, 0);
218#else
Michael Sevakis009cebe2008-05-14 19:29:25 +0000219 lcd_sleep();
Boris Gjenerod50d1df2009-04-21 21:49:29 +0000220#endif
Michael Sevakis009cebe2008-05-14 19:29:25 +0000221 }
222 else
223 {
224 lcd_sleep_timer = lcd_sleep_timeout;
225 }
226}
227#endif /* HAVE_LCD_SLEEP */
228
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000229#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
230 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
Steve Bavinf6847262008-11-26 08:26:13 +0000231static int backlight_fading_type = (FADING_UP|FADING_DOWN);
232static int backlight_fading_state = NOT_FADING;
233#endif
234
235
Thom Johansen3c7278f2006-03-19 17:42:58 +0000236/* backlight fading */
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000237#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM)
Jens Arnold09a78612007-11-26 23:10:20 +0000238#define BL_PWM_INTERVAL 5 /* Cycle interval in ms */
239#define BL_PWM_BITS 8
240#define BL_PWM_COUNT (1<<BL_PWM_BITS)
Thom Johansen3c7278f2006-03-19 17:42:58 +0000241
Jens Arnold09a78612007-11-26 23:10:20 +0000242/* s15.16 fixed point variables */
243static int32_t bl_fade_in_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16)/300;
244static int32_t bl_fade_out_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16)/2000;
William Wilgusdc87e9e2016-11-22 06:21:31 +0100245static int32_t bl_dim_fraction = 0;
Jens Arnold09a78612007-11-26 23:10:20 +0000246
Miika Pekkarinen73cd9f32007-01-12 20:26:23 +0000247static int bl_dim_target = 0;
Jens Arnold09a78612007-11-26 23:10:20 +0000248static int bl_dim_current = 0;
Thom Johansen3c7278f2006-03-19 17:42:58 +0000249static enum {DIM_STATE_START, DIM_STATE_MAIN} bl_dim_state = DIM_STATE_START;
Jens Arnold09a78612007-11-26 23:10:20 +0000250static bool bl_timer_active = false;
Thom Johansen3c7278f2006-03-19 17:42:58 +0000251
252static void backlight_isr(void)
253{
Jens Arnold09a78612007-11-26 23:10:20 +0000254 int timer_period = (TIMER_FREQ*BL_PWM_INTERVAL/1000);
Thom Johansen3c7278f2006-03-19 17:42:58 +0000255 bool idle = false;
Antoine Cellerier6f13f4c2007-07-27 17:53:43 +0000256
Antoine Cellerier6f13f4c2007-07-27 17:53:43 +0000257 switch (bl_dim_state)
Thom Johansen3c7278f2006-03-19 17:42:58 +0000258 {
259 /* New cycle */
260 case DIM_STATE_START:
Jens Arnold09a78612007-11-26 23:10:20 +0000261 bl_dim_current = bl_dim_fraction >> 16;
Antoine Cellerier6f13f4c2007-07-27 17:53:43 +0000262
Thom Johansen3c7278f2006-03-19 17:42:58 +0000263 if (bl_dim_current > 0 && bl_dim_current < BL_PWM_COUNT)
264 {
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000265 _backlight_on_isr();
Jens Arnold09a78612007-11-26 23:10:20 +0000266 timer_period = (timer_period * bl_dim_current) >> BL_PWM_BITS;
Thom Johansen3c7278f2006-03-19 17:42:58 +0000267 bl_dim_state = DIM_STATE_MAIN;
Antoine Cellerier6f13f4c2007-07-27 17:53:43 +0000268 }
Thom Johansen3c7278f2006-03-19 17:42:58 +0000269 else
270 {
271 if (bl_dim_current)
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000272 _backlight_on_isr();
Thom Johansen3c7278f2006-03-19 17:42:58 +0000273 else
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000274 _backlight_off_isr();
Thom Johansen3c7278f2006-03-19 17:42:58 +0000275 if (bl_dim_current == bl_dim_target)
276 idle = true;
277 }
Jens Arnold09a78612007-11-26 23:10:20 +0000278 if (bl_dim_current < bl_dim_target)
279 {
280 bl_dim_fraction = MIN(bl_dim_fraction + bl_fade_in_step,
281 (BL_PWM_COUNT<<16));
282 }
283 else if (bl_dim_current > bl_dim_target)
284 {
285 bl_dim_fraction = MAX(bl_dim_fraction - bl_fade_out_step, 0);
286 }
287 break;
Antoine Cellerier6f13f4c2007-07-27 17:53:43 +0000288
Thom Johansen3c7278f2006-03-19 17:42:58 +0000289 /* Dim main screen */
290 case DIM_STATE_MAIN:
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000291 _backlight_off_isr();
Jens Arnold09a78612007-11-26 23:10:20 +0000292 timer_period = (timer_period * (BL_PWM_COUNT - bl_dim_current))
293 >> BL_PWM_BITS;
Thom Johansen3c7278f2006-03-19 17:42:58 +0000294 bl_dim_state = DIM_STATE_START;
Thom Johansen3c7278f2006-03-19 17:42:58 +0000295 break ;
296 }
Antoine Cellerier6f13f4c2007-07-27 17:53:43 +0000297 if (idle)
Thom Johansen3c7278f2006-03-19 17:42:58 +0000298 {
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000299#if defined(_BACKLIGHT_FADE_BOOST) || defined(_BACKLIGHT_FADE_ENABLE)
300 queue_post(&backlight_queue, BACKLIGHT_FADE_FINISH, 0);
Thom Johansen3c7278f2006-03-19 17:42:58 +0000301#endif
302 timer_unregister();
303 bl_timer_active = false;
Boris Gjenerod50d1df2009-04-21 21:49:29 +0000304
305#ifdef HAVE_LCD_SLEEP
306 if (bl_dim_current == 0)
307 backlight_lcd_sleep_countdown(true);
308#endif
Thom Johansen3c7278f2006-03-19 17:42:58 +0000309 }
310 else
311 timer_set_period(timer_period);
312}
313
314static void backlight_switch(void)
315{
316 if (bl_dim_target > (BL_PWM_COUNT/2))
317 {
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000318 _backlight_on_normal();
Jens Arnold09a78612007-11-26 23:10:20 +0000319 bl_dim_fraction = (BL_PWM_COUNT<<16);
Thom Johansen3c7278f2006-03-19 17:42:58 +0000320 }
321 else
322 {
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000323 _backlight_off_normal();
Jens Arnold09a78612007-11-26 23:10:20 +0000324 bl_dim_fraction = 0;
Boris Gjenerod50d1df2009-04-21 21:49:29 +0000325
326#ifdef HAVE_LCD_SLEEP
327 backlight_lcd_sleep_countdown(true);
328#endif
Thom Johansen3c7278f2006-03-19 17:42:58 +0000329 }
330}
331
332static void backlight_release_timer(void)
333{
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000334#ifdef _BACKLIGHT_FADE_BOOST
Miika Pekkarinen1ff76522006-12-05 20:21:11 +0000335 cpu_boost(false);
Thom Johansen3c7278f2006-03-19 17:42:58 +0000336#endif
337 timer_unregister();
338 bl_timer_active = false;
339 backlight_switch();
340}
341
342static void backlight_dim(int value)
343{
344 /* protect from extraneous calls with the same target value */
345 if (value == bl_dim_target)
346 return;
347
348 bl_dim_target = value;
349
350 if (bl_timer_active)
351 return ;
352
Rafaël Carré89ccd5c2009-06-29 14:29:46 +0000353 if (timer_register(0, backlight_release_timer, 2, backlight_isr
Jens Arnoldac9b9272008-04-04 19:38:46 +0000354 IF_COP(, CPU)))
Thom Johansen3c7278f2006-03-19 17:42:58 +0000355 {
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000356#ifdef _BACKLIGHT_FADE_BOOST
Thom Johansen3c7278f2006-03-19 17:42:58 +0000357 /* Prevent cpu frequency changes while dimming. */
Miika Pekkarinen1ff76522006-12-05 20:21:11 +0000358 cpu_boost(true);
Thom Johansen3c7278f2006-03-19 17:42:58 +0000359#endif
360 bl_timer_active = true;
361 }
362 else
363 backlight_switch();
364}
365
Thomas Martitz14731bc2009-04-28 08:57:38 +0000366static void backlight_setup_fade_up(void)
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000367{
Jens Arnold09a78612007-11-26 23:10:20 +0000368 if (bl_fade_in_step > 0)
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000369 {
370#ifdef _BACKLIGHT_FADE_ENABLE
371 _backlight_hw_enable(true);
372#endif
373 backlight_dim(BL_PWM_COUNT);
374 }
375 else
376 {
Jens Arnold09a78612007-11-26 23:10:20 +0000377 bl_dim_target = BL_PWM_COUNT;
378 bl_dim_fraction = (BL_PWM_COUNT<<16);
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000379 _backlight_on_normal();
380 }
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000381}
382
Thomas Martitz14731bc2009-04-28 08:57:38 +0000383static void backlight_setup_fade_down(void)
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000384{
Jens Arnold09a78612007-11-26 23:10:20 +0000385 if (bl_fade_out_step > 0)
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000386 {
387 backlight_dim(0);
388 }
389 else
390 {
Jens Arnold09a78612007-11-26 23:10:20 +0000391 bl_dim_target = bl_dim_fraction = 0;
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000392 _backlight_off_normal();
Thomas Martitz14731bc2009-04-28 08:57:38 +0000393#ifdef HAVE_LCD_SLEEP
394 backlight_lcd_sleep_countdown(true);
395#endif
Boris Gjenerod50d1df2009-04-21 21:49:29 +0000396 }
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000397}
398
Jens Arnold09a78612007-11-26 23:10:20 +0000399void backlight_set_fade_in(int value)
Thom Johansen3c7278f2006-03-19 17:42:58 +0000400{
Jens Arnold09a78612007-11-26 23:10:20 +0000401 if (value > 0)
402 bl_fade_in_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16) / value;
403 else
404 bl_fade_in_step = 0;
Thom Johansen3c7278f2006-03-19 17:42:58 +0000405}
406
Jens Arnold09a78612007-11-26 23:10:20 +0000407void backlight_set_fade_out(int value)
Thom Johansen3c7278f2006-03-19 17:42:58 +0000408{
Jens Arnold09a78612007-11-26 23:10:20 +0000409 if (value > 0)
410 bl_fade_out_step = ((BL_PWM_INTERVAL*BL_PWM_COUNT)<<16) / value;
411 else
412 bl_fade_out_step = 0;
Thom Johansen3c7278f2006-03-19 17:42:58 +0000413}
Thom Johansen3c7278f2006-03-19 17:42:58 +0000414
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000415#elif (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
416 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
Steve Bavinf6847262008-11-26 08:26:13 +0000417
418void backlight_set_fade_out(bool value)
419{
420 if(value) /* on */
421 backlight_fading_type |= FADING_DOWN;
422 else
423 backlight_fading_type &= FADING_UP;
424}
425
426void backlight_set_fade_in(bool value)
427{
428 if(value) /* on */
429 backlight_fading_type |= FADING_UP;
430 else
431 backlight_fading_type &= FADING_DOWN;
432}
433
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000434static void backlight_setup_fade_up(void)
Steve Bavinf6847262008-11-26 08:26:13 +0000435{
436 if (backlight_fading_type & FADING_UP)
437 {
438 if (backlight_fading_state == NOT_FADING)
439 {
440 /* make sure the backlight is at lowest level */
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100441 backlight_hw_on();
Steve Bavinf6847262008-11-26 08:26:13 +0000442 }
443 backlight_fading_state = FADING_UP;
444 }
445 else
446 {
447 backlight_fading_state = NOT_FADING;
448 _backlight_fade_update_state(backlight_brightness);
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100449 backlight_hw_on();
450 backlight_hw_brightness(backlight_brightness);
Steve Bavinf6847262008-11-26 08:26:13 +0000451 }
452}
453
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000454static void backlight_setup_fade_down(void)
Steve Bavinf6847262008-11-26 08:26:13 +0000455{
456 if (backlight_fading_type & FADING_DOWN)
457 {
458 backlight_fading_state = FADING_DOWN;
459 }
460 else
461 {
462 backlight_fading_state = NOT_FADING;
463 _backlight_fade_update_state(MIN_BRIGHTNESS_SETTING-1);
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100464 backlight_hw_off();
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000465#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
466 /* write the lowest brightness level to the hardware so that
467 * fading up is glitch free */
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100468 backlight_hw_brightness(MIN_BRIGHTNESS_SETTING);
Steve Bavinf6847262008-11-26 08:26:13 +0000469#endif
Thomas Martitz14731bc2009-04-28 08:57:38 +0000470#ifdef HAVE_LCD_SLEEP
471 backlight_lcd_sleep_countdown(true);
472#endif
Steve Bavinf6847262008-11-26 08:26:13 +0000473 }
474}
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000475#endif /* CONFIG_BACKLIGHT_FADING */
Steve Bavinf6847262008-11-26 08:26:13 +0000476
Thomas Martitz14731bc2009-04-28 08:57:38 +0000477static inline void do_backlight_off(void)
478{
479 backlight_timer = 0;
480#if BACKLIGHT_FADE_IN_THREAD
481 backlight_setup_fade_down();
482#else
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100483 backlight_hw_off();
Thomas Martitz14731bc2009-04-28 08:57:38 +0000484 /* targets that have fading need to start the countdown when done with
485 * fading */
486#ifdef HAVE_LCD_SLEEP
487 backlight_lcd_sleep_countdown(true);
488#endif
489#endif
490}
491
Rani Hodc9f59e62006-08-08 22:03:56 +0000492/* Update state of backlight according to timeout setting */
493static void backlight_update_state(void)
494{
Thomas Martitz5b316af2009-04-25 21:11:16 +0000495
496 int timeout = backlight_get_current_timeout();
Rani Hodc9f59e62006-08-08 22:03:56 +0000497
498 /* Backlight == OFF in the setting? */
Thomas Martitz5b316af2009-04-25 21:11:16 +0000499 if (UNLIKELY(timeout < 0))
Rani Hodc9f59e62006-08-08 22:03:56 +0000500 {
Thomas Martitz14731bc2009-04-28 08:57:38 +0000501 do_backlight_off();
Rob Purchase0b30eb72009-11-23 23:30:55 +0000502#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000503 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
Rob Purchase0b30eb72009-11-23 23:30:55 +0000504 /* necessary step to issue fading down when the setting is selected */
505 if (queue_empty(&backlight_queue))
506 queue_post(&backlight_queue, SYS_TIMEOUT, 0);
Steve Bavinf6847262008-11-26 08:26:13 +0000507#endif
Rani Hodc9f59e62006-08-08 22:03:56 +0000508 }
509 else
510 {
Thomas Martitz5b316af2009-04-25 21:11:16 +0000511 backlight_timer = timeout;
Thomas Martitz6abae1f2009-04-26 01:23:39 +0000512
513#ifdef HAVE_LCD_SLEEP
514 backlight_lcd_sleep_countdown(false); /* wake up lcd */
515#endif
516
Thomas Martitz14731bc2009-04-28 08:57:38 +0000517#if BACKLIGHT_FADE_IN_THREAD
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000518 backlight_setup_fade_up();
Steve Bavinf6847262008-11-26 08:26:13 +0000519#else
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100520 backlight_hw_on();
Steve Bavinf6847262008-11-26 08:26:13 +0000521#endif
Rani Hodc9f59e62006-08-08 22:03:56 +0000522 }
523}
524
525#ifdef HAVE_REMOTE_LCD
526/* Update state of remote backlight according to timeout setting */
527static void remote_backlight_update_state(void)
528{
Thomas Martitz5b316af2009-04-25 21:11:16 +0000529 int timeout = remote_backlight_get_current_timeout();
Rani Hodc9f59e62006-08-08 22:03:56 +0000530 /* Backlight == OFF in the setting? */
Thomas Martitz5b316af2009-04-25 21:11:16 +0000531 if (timeout < 0)
Rani Hodc9f59e62006-08-08 22:03:56 +0000532 {
533 remote_backlight_timer = 0; /* Disable the timeout */
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100534 remote_backlight_hw_off();
Rani Hodc9f59e62006-08-08 22:03:56 +0000535 }
536 else
537 {
Thomas Martitz5b316af2009-04-25 21:11:16 +0000538 remote_backlight_timer = timeout;
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100539 remote_backlight_hw_on();
Rani Hodc9f59e62006-08-08 22:03:56 +0000540 }
541}
542#endif /* HAVE_REMOTE_LCD */
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000543
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000544void backlight_thread(void)
545{
Michael Sevakisa9b2fb52007-10-16 01:25:17 +0000546 struct queue_event ev;
Jens Arnold671f5d42007-08-12 11:18:52 +0000547 bool locked = false;
Rani Hodc9f59e62006-08-08 22:03:56 +0000548
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000549 while(1)
550 {
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000551#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
552 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
Thomas Martitzc40af942009-04-26 00:47:35 +0000553 if (backlight_fading_state != NOT_FADING)
Steve Bavinf6847262008-11-26 08:26:13 +0000554 queue_wait_w_tmo(&backlight_queue, &ev, FADE_DELAY);
555 else
556#endif
Thomas Martitzc40af942009-04-26 00:47:35 +0000557 queue_wait_w_tmo(&backlight_queue, &ev, BACKLIGHT_THREAD_TIMEOUT);
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000558 switch(ev.id)
Jens Arnold671f5d42007-08-12 11:18:52 +0000559 { /* These events must always be processed */
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000560#ifdef _BACKLIGHT_FADE_BOOST
561 case BACKLIGHT_FADE_FINISH:
Jens Arnold671f5d42007-08-12 11:18:52 +0000562 cpu_boost(false);
563 break;
564#endif
Jens Arnoldef12b3b2007-11-12 18:49:53 +0000565#ifdef _BACKLIGHT_FADE_ENABLE
566 case BACKLIGHT_FADE_FINISH:
567 _backlight_hw_enable((bl_dim_current|bl_dim_target) != 0);
568 break;
569#endif
Jens Arnold671f5d42007-08-12 11:18:52 +0000570
Jens Arnold8e664912008-03-19 00:34:56 +0000571#ifndef SIMULATOR
Jens Arnold671f5d42007-08-12 11:18:52 +0000572 /* Here for now or else the aggressive init messes up scrolling */
Jens Arnold8e664912008-03-19 00:34:56 +0000573#ifdef HAVE_REMOTE_LCD
Jens Arnold671f5d42007-08-12 11:18:52 +0000574 case SYS_REMOTE_PLUGGED:
575 lcd_remote_on();
576 lcd_remote_update();
577 break;
578
579 case SYS_REMOTE_UNPLUGGED:
580 lcd_remote_off();
581 break;
Jens Arnold8e664912008-03-19 00:34:56 +0000582#elif defined HAVE_REMOTE_LCD_AS_MAIN
Jens Arnold1f4bcc82008-03-25 19:57:23 +0000583 case SYS_REMOTE_PLUGGED:
Jens Arnold8e664912008-03-19 00:34:56 +0000584 lcd_on();
585 lcd_update();
586 break;
587
588 case SYS_REMOTE_UNPLUGGED:
589 lcd_off();
590 break;
591#endif /* HAVE_REMOTE_LCD/ HAVE_REMOTE_LCD_AS_MAIN */
592#endif /* !SIMULATOR */
Jens Arnold671f5d42007-08-12 11:18:52 +0000593 case SYS_USB_CONNECTED:
Jens Arnold671f5d42007-08-12 11:18:52 +0000594 usb_acknowledge(SYS_USB_CONNECTED_ACK);
595 break;
596
Michael Sevakis80278e42008-05-10 18:00:11 +0000597#ifdef BACKLIGHT_DRIVER_CLOSE
598 /* Get out of here */
599 case BACKLIGHT_QUIT:
600 return;
601#endif
Jens Arnold671f5d42007-08-12 11:18:52 +0000602 }
603 if (locked)
604 continue;
605
606 switch(ev.id)
607 { /* These events are only processed if backlight isn't locked */
Linus Nielsen Feltzing19631f42005-04-15 16:16:26 +0000608#ifdef HAVE_REMOTE_LCD
Thomas Martitzb056f062009-04-24 09:08:43 +0000609 case REMOTE_BACKLIGHT_TMO_CHANGED:
Linus Nielsen Feltzing19631f42005-04-15 16:16:26 +0000610 case REMOTE_BACKLIGHT_ON:
Rani Hodc9f59e62006-08-08 22:03:56 +0000611 remote_backlight_update_state();
Linus Nielsen Feltzing19631f42005-04-15 16:16:26 +0000612 break;
613
614 case REMOTE_BACKLIGHT_OFF:
Rani Hodc9f59e62006-08-08 22:03:56 +0000615 remote_backlight_timer = 0; /* Disable the timeout */
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100616 remote_backlight_hw_off();
Linus Nielsen Feltzing19631f42005-04-15 16:16:26 +0000617 break;
Michael Sevakis3d2e10b2006-09-10 02:00:40 +0000618#endif /* HAVE_REMOTE_LCD */
619
Thomas Martitzb0ac9442009-04-24 08:54:10 +0000620 case BACKLIGHT_TMO_CHANGED:
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000621 case BACKLIGHT_ON:
Rani Hodc9f59e62006-08-08 22:03:56 +0000622 backlight_update_state();
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000623 break;
Rani Hodc9f59e62006-08-08 22:03:56 +0000624
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000625 case BACKLIGHT_OFF:
Thomas Martitzc40af942009-04-26 00:47:35 +0000626 do_backlight_off();
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000627 break;
Boris Gjenerof4943b92009-05-01 03:18:20 +0000628#ifdef HAVE_BACKLIGHT_BRIGHTNESS
629 case BACKLIGHT_BRIGHTNESS_CHANGED:
630 backlight_brightness = (int)ev.data;
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100631 backlight_hw_brightness((int)ev.data);
Boris Gjenerof4943b92009-05-01 03:18:20 +0000632#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
633 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
634 /* receive backlight brightness */
635 _backlight_fade_update_state((int)ev.data);
636#endif
637 break;
638#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
Rani Hodc9f59e62006-08-08 22:03:56 +0000639#ifdef HAVE_LCD_SLEEP
640 case LCD_SLEEP:
641 lcd_sleep();
642 break;
643#endif
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000644#ifdef HAVE_BUTTON_LIGHT
Thomas Martitzb0ac9442009-04-24 08:54:10 +0000645 case BUTTON_LIGHT_TMO_CHANGED:
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000646 case BUTTON_LIGHT_ON:
Karl Kurbjun1fc2d912007-05-10 03:08:47 +0000647 buttonlight_update_state();
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000648 break;
Jens Arnold671f5d42007-08-12 11:18:52 +0000649
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000650 case BUTTON_LIGHT_OFF:
Jens Arnold5f1ec302007-10-07 15:02:02 +0000651 buttonlight_timer = 0;
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100652 buttonlight_hw_off();
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000653 break;
Boris Gjenerof4943b92009-05-01 03:18:20 +0000654#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
William Wilgusdc87e9e2016-11-22 06:21:31 +0100655 case BUTTON_LIGHT_BRIGHTNESS_CHANGED:
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100656 buttonlight_hw_brightness((int)ev.data);
Boris Gjenerof4943b92009-05-01 03:18:20 +0000657 break;
658#endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
659#endif /* HAVE_BUTTON_LIGHT */
Rani Hodc9f59e62006-08-08 22:03:56 +0000660
Jens Arnold671f5d42007-08-12 11:18:52 +0000661 case SYS_POWEROFF: /* Lock backlight on poweroff so it doesn't */
662 locked = true; /* go off before power is actually cut. */
663 /* fall through */
Jens Arnoldffeaea62007-08-10 21:55:48 +0000664#if CONFIG_CHARGING
665 case SYS_CHARGER_CONNECTED:
666 case SYS_CHARGER_DISCONNECTED:
Jens Arnold671f5d42007-08-12 11:18:52 +0000667#endif
Jens Arnoldffeaea62007-08-10 21:55:48 +0000668 backlight_update_state();
669#ifdef HAVE_REMOTE_LCD
670 remote_backlight_update_state();
671#endif
672 break;
Thomas Martitzc40af942009-04-26 00:47:35 +0000673 case SYS_TIMEOUT:
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000674#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_SETTING) \
675 || (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG)
Thomas Martitzc40af942009-04-26 00:47:35 +0000676 if (backlight_fading_state != NOT_FADING)
677 {
678 if ((_backlight_fade_step(backlight_fading_state)))
Thomas Martitz6abae1f2009-04-26 01:23:39 +0000679 { /* finished fading */
680#ifdef HAVE_LCD_SLEEP
681 if (backlight_fading_state == FADING_DOWN)
682 { /* start sleep countdown */
683 backlight_lcd_sleep_countdown(true);
684 }
685#endif
686 backlight_fading_state = NOT_FADING;
687 }
Thomas Martitzc40af942009-04-26 00:47:35 +0000688 }
689 else
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000690#endif /* CONFIG_BACKLIGHT_FADING */
Thomas Martitzc40af942009-04-26 00:47:35 +0000691 backlight_timeout_handler();
692 break;
Jens Arnold671f5d42007-08-12 11:18:52 +0000693 }
Rani Hodc9f59e62006-08-08 22:03:56 +0000694 } /* end while */
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000695}
696
Thomas Martitzc40af942009-04-26 00:47:35 +0000697static void backlight_timeout_handler(void)
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000698{
Thomas Martitzc40af942009-04-26 00:47:35 +0000699 if(backlight_timer > 0)
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000700 {
Thomas Martitzc40af942009-04-26 00:47:35 +0000701 backlight_timer -= BACKLIGHT_THREAD_TIMEOUT;
702 if(backlight_timer <= 0)
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000703 {
Thomas Martitzc40af942009-04-26 00:47:35 +0000704 do_backlight_off();
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000705 }
706 }
Rani Hodc9f59e62006-08-08 22:03:56 +0000707#ifdef HAVE_LCD_SLEEP
Thomas Martitzc40af942009-04-26 00:47:35 +0000708 else if(lcd_sleep_timer > 0)
Rani Hodc9f59e62006-08-08 22:03:56 +0000709 {
Thomas Martitzc40af942009-04-26 00:47:35 +0000710 lcd_sleep_timer -= BACKLIGHT_THREAD_TIMEOUT;
711 if(lcd_sleep_timer <= 0)
Rani Hodc9f59e62006-08-08 22:03:56 +0000712 {
Thomas Martitzc40af942009-04-26 00:47:35 +0000713 lcd_sleep();
Rani Hodc9f59e62006-08-08 22:03:56 +0000714 }
715 }
716#endif /* HAVE_LCD_SLEEP */
Linus Nielsen Feltzing19631f42005-04-15 16:16:26 +0000717#ifdef HAVE_REMOTE_LCD
Thomas Martitzc40af942009-04-26 00:47:35 +0000718 if(remote_backlight_timer > 0)
Linus Nielsen Feltzing19631f42005-04-15 16:16:26 +0000719 {
Thomas Martitzc40af942009-04-26 00:47:35 +0000720 remote_backlight_timer -= BACKLIGHT_THREAD_TIMEOUT;
721 if(remote_backlight_timer <= 0)
Linus Nielsen Feltzing19631f42005-04-15 16:16:26 +0000722 {
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100723 remote_backlight_hw_off();
Linus Nielsen Feltzing19631f42005-04-15 16:16:26 +0000724 }
725 }
Rani Hodc9f59e62006-08-08 22:03:56 +0000726#endif /* HAVE_REMOVE_LCD */
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000727#ifdef HAVE_BUTTON_LIGHT
Thomas Martitzc40af942009-04-26 00:47:35 +0000728 if (buttonlight_timer > 0)
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000729 {
Thomas Martitzc40af942009-04-26 00:47:35 +0000730 buttonlight_timer -= BACKLIGHT_THREAD_TIMEOUT;
731 if (buttonlight_timer <= 0)
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000732 {
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100733 buttonlight_hw_off();
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000734 }
735 }
William Wilgusdc87e9e2016-11-22 06:21:31 +0100736 if (buttonlight_ignored_timer > 0)
737 {
738 buttonlight_ignored_timer -= BACKLIGHT_THREAD_TIMEOUT;
739 if (buttonlight_ignored_timer <= 0)
740 ignore_buttonlight_on = false;
741 }
Jonathan Gordon4b1d1b42007-04-22 13:02:24 +0000742#endif /* HAVE_BUTTON_LIGHT */
William Wilgusdc87e9e2016-11-22 06:21:31 +0100743 if (backlight_ignored_timer > 0)
744 {
745 backlight_ignored_timer -= BACKLIGHT_THREAD_TIMEOUT;
746 if (backlight_ignored_timer <= 0)
747 ignore_backlight_on = false;
748 }
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000749}
750
751void backlight_init(void)
752{
Miika Pekkarinena85044b2006-09-16 16:18:11 +0000753 queue_init(&backlight_queue, true);
Antoine Cellerier6f13f4c2007-07-27 17:53:43 +0000754
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100755 if (backlight_hw_init())
Miika Pekkarinen73cd9f32007-01-12 20:26:23 +0000756 {
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000757#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM)
Miika Pekkarinen73cd9f32007-01-12 20:26:23 +0000758 /* If backlight is already on, don't fade in. */
Miika Pekkarinen73cd9f32007-01-12 20:26:23 +0000759 bl_dim_target = BL_PWM_COUNT;
Jens Arnold09a78612007-11-26 23:10:20 +0000760 bl_dim_fraction = (BL_PWM_COUNT<<16);
Thomas Martitz12a0ed32009-01-26 23:21:49 +0000761#endif
Miika Pekkarinen73cd9f32007-01-12 20:26:23 +0000762 }
Jens Arnoldf265ee92007-09-12 22:24:58 +0000763 /* Leave all lights as set by the bootloader here. The settings load will
764 * call the appropriate backlight_set_*() functions, only changing light
765 * status if necessary. */
Michael Sevakis80278e42008-05-10 18:00:11 +0000766#ifdef BACKLIGHT_DRIVER_CLOSE
Michael Sevakis8cfbd362008-12-10 08:57:10 +0000767 backlight_thread_id =
Michael Sevakis80278e42008-05-10 18:00:11 +0000768#endif
Miika Pekkarinen73cd9f32007-01-12 20:26:23 +0000769 create_thread(backlight_thread, backlight_stack,
Michael Sevakisa9b2fb52007-10-16 01:25:17 +0000770 sizeof(backlight_stack), 0, backlight_thread_name
Michael Giacomelli2d8cd812008-03-07 00:51:36 +0000771 IF_PRIO(, PRIORITY_USER_INTERFACE)
Michael Sevakisa9b2fb52007-10-16 01:25:17 +0000772 IF_COP(, CPU));
Linus Nielsen Feltzing2a4de232002-06-24 13:48:42 +0000773}
Jörg Hohensohn76994fb2004-09-10 13:56:54 +0000774
Michael Sevakis80278e42008-05-10 18:00:11 +0000775#ifdef BACKLIGHT_DRIVER_CLOSE
776void backlight_close(void)
777{
Michael Sevakis8cfbd362008-12-10 08:57:10 +0000778 unsigned int thread = backlight_thread_id;
Michael Sevakis80278e42008-05-10 18:00:11 +0000779
780 /* Wait for thread to exit */
Michael Sevakis8cfbd362008-12-10 08:57:10 +0000781 if (thread == 0)
Michael Sevakis80278e42008-05-10 18:00:11 +0000782 return;
783
Michael Sevakis8cfbd362008-12-10 08:57:10 +0000784 backlight_thread_id = 0;
Michael Sevakis80278e42008-05-10 18:00:11 +0000785
786 queue_post(&backlight_queue, BACKLIGHT_QUIT, 0);
787 thread_wait(thread);
788}
789#endif /* BACKLIGHT_DRIVER_CLOSE */
790
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000791void backlight_on(void)
792{
William Wilgusdc87e9e2016-11-22 06:21:31 +0100793 if(!ignore_backlight_on)
794 {
795 queue_remove_from_head(&backlight_queue, BACKLIGHT_ON);
796 queue_post(&backlight_queue, BACKLIGHT_ON, 0);
797 }
798}
799
800void backlight_on_ignore(bool value, int timeout)
801{
802 ignore_backlight_on = value;
803 backlight_ignored_timer = timeout;
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000804}
805
806void backlight_off(void)
807{
Michael Sevakis4b902672006-12-19 16:50:07 +0000808 queue_post(&backlight_queue, BACKLIGHT_OFF, 0);
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000809}
810
Jens Arnold5c87a982008-04-02 22:16:14 +0000811/* returns true when the backlight is on,
812 * and optionally when it's set to always off. */
813bool is_backlight_on(bool ignore_always_off)
Björn Stenbergda5fb182006-03-24 13:47:24 +0000814{
Thomas Martitz5b316af2009-04-25 21:11:16 +0000815 int timeout = backlight_get_current_timeout();
Jens Arnold5c87a982008-04-02 22:16:14 +0000816 return (backlight_timer > 0) /* countdown */
Thomas Martitz5b316af2009-04-25 21:11:16 +0000817 || (timeout == 0) /* always on */
818 || ((timeout < 0) && !ignore_always_off);
Björn Stenbergda5fb182006-03-24 13:47:24 +0000819}
820
Jens Arnolda6d409d2005-11-23 20:12:33 +0000821/* return value in ticks; 0 means always on, <0 means always off */
822int backlight_get_current_timeout(void)
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000823{
Thomas Martitz5b316af2009-04-25 21:11:16 +0000824#ifdef HAS_BUTTON_HOLD
825 if ((backlight_on_button_hold != 0)
826#ifdef HAVE_REMOTE_LCD_AS_MAIN
827 && remote_button_hold()
828#else
829 && button_hold()
830#endif
831 )
832 return (backlight_on_button_hold == 2) ? 0 : -1;
833 /* always on or always off */
834 else
835#endif
836#if CONFIG_CHARGING
837 if (power_input_present())
838 return backlight_timeout_plugged;
839 else
840#endif
841 return backlight_timeout_normal;
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000842}
843
Jens Arnoldd490f442007-11-25 17:36:21 +0000844void backlight_set_timeout(int value)
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000845{
Jens Arnoldd490f442007-11-25 17:36:21 +0000846 backlight_timeout_normal = HZ * value;
Thomas Martitzb0ac9442009-04-24 08:54:10 +0000847 queue_post(&backlight_queue, BACKLIGHT_TMO_CHANGED, 0);
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000848}
849
Jonathan Gordon9a6f4192007-02-18 05:32:06 +0000850#if CONFIG_CHARGING
Jens Arnoldd490f442007-11-25 17:36:21 +0000851void backlight_set_timeout_plugged(int value)
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000852{
Jens Arnoldd490f442007-11-25 17:36:21 +0000853 backlight_timeout_plugged = HZ * value;
Thomas Martitzb0ac9442009-04-24 08:54:10 +0000854 queue_post(&backlight_queue, BACKLIGHT_TMO_CHANGED, 0);
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000855}
Rani Hodc9f59e62006-08-08 22:03:56 +0000856#endif /* CONFIG_CHARGING */
857
858#ifdef HAS_BUTTON_HOLD
859/* Hold button change event handler. */
860void backlight_hold_changed(bool hold_button)
861{
Jens Arnoldffeaea62007-08-10 21:55:48 +0000862 if (!hold_button || (backlight_on_button_hold > 0))
William Wilgusdc87e9e2016-11-22 06:21:31 +0100863 {
Jens Arnoldffeaea62007-08-10 21:55:48 +0000864 /* if unlocked or override in effect */
William Wilgusdc87e9e2016-11-22 06:21:31 +0100865
866 /*backlight_on(); REMOVED*/
867 queue_remove_from_head(&backlight_queue, BACKLIGHT_ON);
868 queue_post(&backlight_queue, BACKLIGHT_ON, 0);
869 }
Rani Hodc9f59e62006-08-08 22:03:56 +0000870}
871
872void backlight_set_on_button_hold(int index)
873{
874 if ((unsigned)index >= 3)
875 /* if given a weird value, use default */
876 index = 0;
877
Rani Hodc9f59e62006-08-08 22:03:56 +0000878 backlight_on_button_hold = index;
Thomas Martitzb0ac9442009-04-24 08:54:10 +0000879 queue_post(&backlight_queue, BACKLIGHT_TMO_CHANGED, 0);
Rani Hodc9f59e62006-08-08 22:03:56 +0000880}
881#endif /* HAS_BUTTON_HOLD */
882
Michael Sevakis009cebe2008-05-14 19:29:25 +0000883#ifdef HAVE_LCD_SLEEP_SETTING
William Wilgusa06d9c82018-12-17 22:27:55 -0600884void lcd_set_sleep_after_backlight_off(int timeout_seconds)
Rani Hodc9f59e62006-08-08 22:03:56 +0000885{
William Wilgusa06d9c82018-12-17 22:27:55 -0600886 lcd_sleep_timeout = HZ * timeout_seconds;
Rani Hodc9f59e62006-08-08 22:03:56 +0000887
Thomas Martitzcbe67dc2009-04-26 01:35:19 +0000888 if (is_backlight_on(true))
William Wilgusa06d9c82018-12-17 22:27:55 -0600889 /* Timer will be set when bl turns off or bl set to on. */
Rani Hodc9f59e62006-08-08 22:03:56 +0000890 return;
891
892 /* Backlight is Off */
Michael Sevakis009cebe2008-05-14 19:29:25 +0000893 if (lcd_sleep_timeout < 0)
William Wilgusa06d9c82018-12-17 22:27:55 -0600894 lcd_sleep_timer = 0; /* Never */
895 else if (lcd_sleep_timeout == 0)
Michael Sevakis009cebe2008-05-14 19:29:25 +0000896 lcd_sleep_timer = 1; /* Always - sleep next tick */
Rani Hodc9f59e62006-08-08 22:03:56 +0000897 else
William Wilgusa06d9c82018-12-17 22:27:55 -0600898 lcd_sleep_timer = lcd_sleep_timeout; /* other */
Rani Hodc9f59e62006-08-08 22:03:56 +0000899}
Michael Sevakis009cebe2008-05-14 19:29:25 +0000900#endif /* HAVE_LCD_SLEEP_SETTING */
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000901
902#ifdef HAVE_REMOTE_LCD
903void remote_backlight_on(void)
904{
Michael Sevakis4b902672006-12-19 16:50:07 +0000905 queue_post(&backlight_queue, REMOTE_BACKLIGHT_ON, 0);
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000906}
907
908void remote_backlight_off(void)
909{
Michael Sevakis4b902672006-12-19 16:50:07 +0000910 queue_post(&backlight_queue, REMOTE_BACKLIGHT_OFF, 0);
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000911}
912
Jens Arnoldd490f442007-11-25 17:36:21 +0000913void remote_backlight_set_timeout(int value)
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000914{
Jens Arnoldd490f442007-11-25 17:36:21 +0000915 remote_backlight_timeout_normal = HZ * value;
Thomas Martitzb0ac9442009-04-24 08:54:10 +0000916 queue_post(&backlight_queue, REMOTE_BACKLIGHT_TMO_CHANGED, 0);
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000917}
918
Jonathan Gordon9a6f4192007-02-18 05:32:06 +0000919#if CONFIG_CHARGING
Jens Arnoldd490f442007-11-25 17:36:21 +0000920void remote_backlight_set_timeout_plugged(int value)
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000921{
Jens Arnoldd490f442007-11-25 17:36:21 +0000922 remote_backlight_timeout_plugged = HZ * value;
Thomas Martitzb0ac9442009-04-24 08:54:10 +0000923 queue_post(&backlight_queue, REMOTE_BACKLIGHT_TMO_CHANGED, 0);
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000924}
Rani Hodc9f59e62006-08-08 22:03:56 +0000925#endif /* CONFIG_CHARGING */
Hristo Kovacheva70c6b92006-03-25 19:16:45 +0000926
Michael Sevakis3d2e10b2006-09-10 02:00:40 +0000927#ifdef HAS_REMOTE_BUTTON_HOLD
928/* Remote hold button change event handler. */
929void remote_backlight_hold_changed(bool rc_hold_button)
930{
Jens Arnoldffeaea62007-08-10 21:55:48 +0000931 if (!rc_hold_button || (remote_backlight_on_button_hold > 0))
932 /* if unlocked or override */
Michael Sevakis3d2e10b2006-09-10 02:00:40 +0000933 remote_backlight_on();
Michael Sevakis3d2e10b2006-09-10 02:00:40 +0000934}
935
936void remote_backlight_set_on_button_hold(int index)
937{
938 if ((unsigned)index >= 3)
939 /* if given a weird value, use default */
940 index = 0;
941
Michael Sevakis3d2e10b2006-09-10 02:00:40 +0000942 remote_backlight_on_button_hold = index;
Thomas Martitzb0ac9442009-04-24 08:54:10 +0000943 queue_post(&backlight_queue, REMOTE_BACKLIGHT_TMO_CHANGED, 0);
Michael Sevakis3d2e10b2006-09-10 02:00:40 +0000944}
945#endif /* HAS_REMOTE_BUTTON_HOLD */
946
Hristo Kovacheva70c6b92006-03-25 19:16:45 +0000947/* return value in ticks; 0 means always on, <0 means always off */
948int remote_backlight_get_current_timeout(void)
949{
Thomas Martitz5b316af2009-04-25 21:11:16 +0000950#ifdef HAS_REMOTE_BUTTON_HOLD
951 if (remote_button_hold() && (remote_backlight_on_button_hold != 0))
952 return (remote_backlight_on_button_hold == 2)
953 ? 0 : -1; /* always on or always off */
954 else
955#endif
956#if CONFIG_CHARGING
957 if (power_input_present())
958 return remote_backlight_timeout_plugged;
959 else
960#endif
961 return remote_backlight_timeout_normal;
Hristo Kovacheva70c6b92006-03-25 19:16:45 +0000962}
963
Jens Arnold5c87a982008-04-02 22:16:14 +0000964/* returns true when the backlight is on, and
965 * optionally when it's set to always off */
966bool is_remote_backlight_on(bool ignore_always_off)
Hristo Kovacheva70c6b92006-03-25 19:16:45 +0000967{
Thomas Martitz5b316af2009-04-25 21:11:16 +0000968 int timeout = remote_backlight_get_current_timeout();
Jens Arnold5c87a982008-04-02 22:16:14 +0000969 return (remote_backlight_timer > 0) /* countdown */
Thomas Martitz5b316af2009-04-25 21:11:16 +0000970 || (timeout == 0) /* always on */
971 || ((timeout < 0) && !ignore_always_off);
Hristo Kovacheva70c6b92006-03-25 19:16:45 +0000972}
973
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000974#endif /* HAVE_REMOTE_LCD */
975
Michael Sevakis58825f62006-11-10 18:47:41 +0000976#ifdef HAVE_BACKLIGHT_BRIGHTNESS
977void backlight_set_brightness(int val)
978{
979 if (val < MIN_BRIGHTNESS_SETTING)
980 val = MIN_BRIGHTNESS_SETTING;
981 else if (val > MAX_BRIGHTNESS_SETTING)
982 val = MAX_BRIGHTNESS_SETTING;
983
Boris Gjenerof4943b92009-05-01 03:18:20 +0000984 queue_post(&backlight_queue, BACKLIGHT_BRIGHTNESS_CHANGED, val);
Michael Sevakis58825f62006-11-10 18:47:41 +0000985}
986#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
987
Karl Kurbjun6f95ab72007-05-08 06:45:38 +0000988#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
989void buttonlight_set_brightness(int val)
990{
991 if (val < MIN_BRIGHTNESS_SETTING)
992 val = MIN_BRIGHTNESS_SETTING;
993 else if (val > MAX_BRIGHTNESS_SETTING)
994 val = MAX_BRIGHTNESS_SETTING;
995
Boris Gjenerof4943b92009-05-01 03:18:20 +0000996 queue_post(&backlight_queue, BUTTON_LIGHT_BRIGHTNESS_CHANGED, val);
Karl Kurbjun6f95ab72007-05-08 06:45:38 +0000997}
998#endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
999
Thomas Martitz4e26db32010-06-21 17:26:50 +00001000#else /* !defined(HAVE_BACKLIGHT) || !defined(BACKLIGHT_FULL_INIT)
Rani Hodc9f59e62006-08-08 22:03:56 +00001001 -- no backlight, empty dummy functions */
Thomas Martitz4e26db32010-06-21 17:26:50 +00001002
1003#if defined(HAVE_BACKLIGHT) && !defined(BACKLIGHT_FULL_INIT)
Jens Arnold80426402005-11-22 01:39:41 +00001004void backlight_init(void)
1005{
Marcin Bukat89ba7e82015-01-09 00:22:40 +01001006 (void)backlight_hw_init();
1007 backlight_hw_on();
Jens Arnold80426402005-11-22 01:39:41 +00001008}
Thomas Martitz4e26db32010-06-21 17:26:50 +00001009#endif
Jens Arnold80426402005-11-22 01:39:41 +00001010
Jörg Hohensohn76994fb2004-09-10 13:56:54 +00001011void backlight_on(void) {}
1012void backlight_off(void) {}
Jens Arnoldd490f442007-11-25 17:36:21 +00001013void backlight_set_timeout(int value) {(void)value;}
Jens Arnoldd5f37b22008-04-02 22:28:08 +00001014
1015bool is_backlight_on(bool ignore_always_off)
1016{
1017 (void)ignore_always_off;
1018 return true;
1019}
Linus Nielsen Feltzing19631f42005-04-15 16:16:26 +00001020#ifdef HAVE_REMOTE_LCD
1021void remote_backlight_on(void) {}
1022void remote_backlight_off(void) {}
Jens Arnoldd490f442007-11-25 17:36:21 +00001023void remote_backlight_set_timeout(int value) {(void)value;}
Jens Arnoldd5f37b22008-04-02 22:28:08 +00001024
Jens Arnoldac9b9272008-04-04 19:38:46 +00001025bool is_remote_backlight_on(bool ignore_always_off)
Jens Arnoldd5f37b22008-04-02 22:28:08 +00001026{
1027 (void)ignore_always_off;
1028 return true;
1029}
Michael Sevakis58825f62006-11-10 18:47:41 +00001030#endif /* HAVE_REMOTE_LCD */
1031#ifdef HAVE_BACKLIGHT_BRIGHTNESS
1032void backlight_set_brightness(int val) { (void)val; }
Linus Nielsen Feltzing19631f42005-04-15 16:16:26 +00001033#endif
Bertrik Sikken3a8e7e62010-08-01 10:07:05 +00001034
Bertrik Sikken38caf2c2010-08-01 10:17:17 +00001035#ifdef HAVE_BUTTON_LIGHT
Bertrik Sikken3a8e7e62010-08-01 10:07:05 +00001036void buttonlight_on(void) {}
Karl Kurbjun6f95ab72007-05-08 06:45:38 +00001037#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
1038void buttonlight_set_brightness(int val) { (void)val; }
1039#endif
Bertrik Sikken38caf2c2010-08-01 10:17:17 +00001040#endif /* HAVE_BUTTON_LIGHT */
Bertrik Sikken3a8e7e62010-08-01 10:07:05 +00001041
Thomas Martitz4e26db32010-06-21 17:26:50 +00001042#endif /* defined(HAVE_BACKLIGHT) && defined(BACKLIGHT_FULL_INIT) */