1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
24 #include "backlight-target.h"
25 #include "backlight.h"
27 #include "sc606-meg-fx.h"
30 #define BUTTONLIGHT_MENU (SC606_LED_B1)
31 #define BUTTONLIGHT_ALL (SC606_LED_B1 | SC606_LED_B2 | \
32 SC606_LED_C1 | SC606_LED_C2)
34 /* Dummy value at index 0, 1-12 used. */
35 static const unsigned char log_brightness
[13] =
36 {0,0,1,2,3,5,7,10,15,22,31,44,63};
39 static void led_control_service(void);
41 static enum sc606_states
49 #endif /* BOOTLOADER */
51 static enum backlight_states
53 BACKLIGHT_CONTROL_IDLE
,
54 BACKLIGHT_CONTROL_OFF
,
56 BACKLIGHT_CONTROL_SET
,
57 BACKLIGHT_CONTROL_FADE
60 enum buttonlight_states
62 BUTTONLIGHT_CONTROL_IDLE
,
63 BUTTONLIGHT_CONTROL_OFF
,
64 BUTTONLIGHT_CONTROL_ON
,
65 BUTTONLIGHT_CONTROL_SET
,
66 BUTTONLIGHT_CONTROL_FADE
,
67 } buttonlight_control
;
69 static unsigned char _backlight_brightness
;
70 static unsigned char buttonlight_brightness
;
71 static unsigned char backlight_target
;
72 static unsigned char buttonlight_target
;
74 static unsigned short buttonlight_trigger_now
;
76 /* Assumes that the backlight has been initialized */
77 void _backlight_set_brightness(int brightness
)
79 /* stop the interrupt from messing us up */
80 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
81 _backlight_brightness
= log_brightness
[brightness
];
82 backlight_control
= BACKLIGHT_CONTROL_SET
;
85 /* only works if the buttonlight mode is set to triggered mode */
86 void __buttonlight_trigger(void)
88 buttonlight_trigger_now
= 1;
91 /* map the mode from the command into the state machine entries */
92 void __buttonlight_mode(enum buttonlight_mode mode
)
94 /* choose stop to setup mode */
95 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
97 /* which mode to use */
100 case BUTTONLIGHT_OFF
:
101 buttonlight_control
= BUTTONLIGHT_CONTROL_OFF
;
105 buttonlight_control
= BUTTONLIGHT_CONTROL_ON
;
108 case BUTTONLIGHT_FOLLOW
:
109 buttonlight_control
= BUTTONLIGHT_CONTROL_FADE
;
113 return; /* unknown mode */
117 /* led_control_service runs in interrupt context - be brief!
118 * This service is called once per interrupt timer tick - 100 times a second.
120 * There should be at most only one i2c operation per call - if more are need
121 * the calls should be spread across calls.
123 * Putting all led servicing in one thread means that we wont step on any
124 * i2c operations - they are all serialized here in the ISR tick. It also
125 * insures that we get called at equal timing for good visual effect.
128 static void led_control_service(void)
131 sc606regAval
=DEFAULT_BRIGHTNESS_SETTING
,
134 sc606regCONFval
=0x03;
136 static bool sc606_changed
=false, sc606_CONF_changed
=false;
138 if(sc606_changed
==false)
140 switch (backlight_control
)
142 case BACKLIGHT_CONTROL_IDLE
:
143 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
145 case BACKLIGHT_CONTROL_OFF
:
147 sc606_CONF_changed
=true;
148 sc606regCONFval
&= ~0x03;
150 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
152 case BACKLIGHT_CONTROL_ON
:
154 sc606_CONF_changed
=true;
155 sc606regCONFval
|= 0x03;
156 sc606regAval
=_backlight_brightness
;
157 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
159 case BACKLIGHT_CONTROL_SET
:
160 if(!(sc606regCONFval
&0x03))
163 sc606regAval
= _backlight_brightness
;
164 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
166 case BACKLIGHT_CONTROL_FADE
:
167 /* Was this mode set while the backlight is already on/off? */
168 if(backlight_target
==sc606regAval
)
170 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
174 if(!(sc606regCONFval
&0x03))
176 sc606_CONF_changed
=true;
177 sc606regCONFval
|= 0x03;
179 if(backlight_target
>sc606regAval
)
182 if(backlight_target
==sc606regAval
)
183 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
189 backlight_control
= BACKLIGHT_CONTROL_OFF
;
190 else if (backlight_target
==sc606regAval
)
191 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
196 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
199 switch (buttonlight_control
)
201 case BUTTONLIGHT_CONTROL_IDLE
:
202 buttonlight_control
=BUTTONLIGHT_CONTROL_IDLE
;
204 case BUTTONLIGHT_CONTROL_OFF
:
206 sc606_CONF_changed
=true;
207 sc606regCONFval
&= ~BUTTONLIGHT_ALL
;
208 sc606regBval
=sc606regCval
=0;
209 buttonlight_control
=BUTTONLIGHT_CONTROL_IDLE
;
211 case BUTTONLIGHT_CONTROL_ON
:
213 sc606_CONF_changed
=true;
214 sc606regCONFval
|= BUTTONLIGHT_ALL
;
215 sc606regBval
=sc606regCval
=buttonlight_brightness
;
216 buttonlight_control
=BUTTONLIGHT_CONTROL_IDLE
;
218 case BUTTONLIGHT_CONTROL_SET
:
219 if(!(sc606regCONFval
&BUTTONLIGHT_ALL
))
222 sc606regBval
=sc606regCval
=buttonlight_brightness
;
223 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
225 case BUTTONLIGHT_CONTROL_FADE
:
226 /* Was this mode set while the button light is already on? */
227 if(buttonlight_target
==sc606regBval
)
229 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
233 if(!(sc606regCONFval
&BUTTONLIGHT_ALL
))
235 sc606_CONF_changed
=true;
236 sc606regCONFval
|= BUTTONLIGHT_ALL
;
238 if(buttonlight_target
>sc606regBval
)
240 sc606regCval
=++sc606regBval
;
241 if(buttonlight_target
==sc606regBval
)
242 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
246 sc606regCval
=--sc606regBval
;
248 buttonlight_control
= BUTTONLIGHT_CONTROL_OFF
;
249 else if (buttonlight_target
==sc606regBval
)
250 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
255 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
260 switch (sc606_control
)
262 case SC606_CONTROL_IDLE
:
264 sc606_control
=SC606_CONTROL_A12
;
266 sc606_control
=SC606_CONTROL_IDLE
;
269 case SC606_CONTROL_A12
:
270 sc606_write(SC606_REG_A
, sc606regAval
);
271 sc606_control
=SC606_CONTROL_B12
;
274 case SC606_CONTROL_B12
:
275 sc606_write(SC606_REG_B
, sc606regBval
);
276 sc606_control
=SC606_CONTROL_C12
;
279 case SC606_CONTROL_C12
:
280 sc606_write(SC606_REG_C
, sc606regCval
);
281 if(sc606_CONF_changed
!=true)
284 if(backlight_control
!= BACKLIGHT_CONTROL_IDLE
||
285 buttonlight_control
!= BUTTONLIGHT_CONTROL_IDLE
)
287 sc606_control
=SC606_CONTROL_A12
;
291 sc606_control
=SC606_CONTROL_IDLE
;
296 sc606_control
=SC606_CONTROL_CONF
;
300 case SC606_CONTROL_CONF
:
301 sc606_write(SC606_REG_CONF
, sc606regCONFval
);
303 sc606_CONF_changed
=false;
304 if(backlight_control
!= BACKLIGHT_CONTROL_IDLE
||
305 buttonlight_control
!= BUTTONLIGHT_CONTROL_IDLE
)
307 sc606_control
=SC606_CONTROL_A12
;
311 sc606_control
=SC606_CONTROL_IDLE
;
316 sc606_control
=SC606_CONTROL_IDLE
;
320 #endif /* BOOTLOADER */
322 static void __backlight_dim(bool dim_now
)
324 /* dont let the interrupt tick happen */
325 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
326 backlight_target
= dim_now
? 0 : _backlight_brightness
;
327 if(backlight_target
==0 && _backlight_brightness
==0)
330 backlight_control
= BACKLIGHT_CONTROL_ON
;
332 backlight_control
= BACKLIGHT_CONTROL_OFF
;
335 backlight_control
= BACKLIGHT_CONTROL_FADE
;
338 void _backlight_on(void)
340 #ifdef HAVE_LCD_ENABLE
341 lcd_enable(true); /* power on lcd + visible display */
343 __backlight_dim(false);
346 void _backlight_off(void)
348 __backlight_dim(true);
351 static inline void __buttonlight_on(void)
353 buttonlight_control
= BUTTONLIGHT_CONTROL_ON
;
356 static inline void __buttonlight_off(void)
358 buttonlight_control
= BUTTONLIGHT_CONTROL_OFF
;
361 static void __buttonlight_dim(bool dim_now
)
363 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
364 buttonlight_target
= dim_now
? 0 : buttonlight_brightness
;
365 if(buttonlight_target
==0 && buttonlight_brightness
==0)
368 buttonlight_control
= BUTTONLIGHT_CONTROL_ON
;
370 buttonlight_control
= BUTTONLIGHT_CONTROL_OFF
;
373 buttonlight_control
= BUTTONLIGHT_CONTROL_FADE
;
376 void _buttonlight_on(void)
378 __buttonlight_dim(false);
381 void _buttonlight_off(void)
384 if(buttonlight_get_current_timeout() > 0)
385 __buttonlight_dim(true);
391 void _buttonlight_set_brightness(int brightness
)
393 /* stop the interrupt from messing us up */
394 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
395 buttonlight_brightness
= log_brightness
[brightness
];
396 buttonlight_control
= BUTTONLIGHT_CONTROL_SET
;
399 bool _backlight_init(void)
401 unsigned char brightness
= log_brightness
[DEFAULT_BRIGHTNESS_SETTING
];
402 buttonlight_brightness
= brightness
;
403 _backlight_brightness
= brightness
;
405 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
406 backlight_control
= BACKLIGHT_CONTROL_ON
;
408 /* Set the backlight up in a known state */
410 sc606_write(SC606_REG_A
, brightness
);
411 sc606_write(SC606_REG_B
, 0);
412 sc606_write(SC606_REG_C
, 0);
413 sc606_write(SC606_REG_CONF
, 0x03);
415 /* put the led control on the tick list */
416 tick_add_task(led_control_service
);