1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Linus Nielsen Feltzing
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
22 #include "backlight-target.h"
23 #include "backlight.h"
25 #include "sc606-meg-fx.h"
28 #define BUTTONLIGHT_MENU (SC606_LED_B1)
29 #define BUTTONLIGHT_ALL (SC606_LED_B1 | SC606_LED_B2 | SC606_LED_C1 | SC606_LED_C2)
31 static const int log_brightness
[12] = {0,1,2,3,5,7,10,15,22,31,44,63};
34 static void led_control_service(void);
36 static enum sc606_states
44 #endif /* BOOTLOADER */
46 static enum backlight_states
48 BACKLIGHT_CONTROL_IDLE
,
49 BACKLIGHT_CONTROL_OFF
,
51 BACKLIGHT_CONTROL_SET
,
52 BACKLIGHT_CONTROL_FADE
55 enum buttonlight_states
57 BUTTONLIGHT_CONTROL_IDLE
,
58 BUTTONLIGHT_CONTROL_OFF
,
59 BUTTONLIGHT_CONTROL_ON
,
60 BUTTONLIGHT_CONTROL_SET
,
61 BUTTONLIGHT_CONTROL_FADE
,
62 } buttonlight_control
;
65 static unsigned char backlight_brightness
;
66 static unsigned char buttonlight_brightness
;
67 static unsigned char backlight_target
;
68 static unsigned char buttonlight_target
;
70 static unsigned short buttonlight_trigger_now
;
72 /* Assumes that the backlight has been initialized */
73 void _backlight_set_brightness(int brightness
)
75 /* clamp the brightness value */
76 brightness
= MAX(1, MIN(12, brightness
));
77 /* stop the interrupt from messing us up */
78 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
79 backlight_brightness
= log_brightness
[brightness
- 1];
80 backlight_control
= BACKLIGHT_CONTROL_SET
;
83 /* only works if the buttonlight mode is set to triggered mode */
84 void __buttonlight_trigger(void)
86 buttonlight_trigger_now
= 1;
89 /* map the mode from the command into the state machine entries */
90 void __buttonlight_mode(enum buttonlight_mode mode
)
92 /* choose stop to setup mode */
93 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
95 /* which mode to use */
99 buttonlight_control
= BUTTONLIGHT_CONTROL_OFF
;
103 buttonlight_control
= BUTTONLIGHT_CONTROL_ON
;
106 case BUTTONLIGHT_FOLLOW
:
107 buttonlight_control
= BUTTONLIGHT_CONTROL_FADE
;
111 return; /* unknown mode */
115 /* led_control_service runs in interrupt context - be brief!
116 * This service is called once per interrupt timer tick - 100 times a second.
118 * There should be at most only one i2c operation per call - if more are need
119 * the calls should be spread across calls.
121 * Putting all led servicing in one thread means that we wont step on any
122 * i2c operations - they are all serialized here in the ISR tick. It also
123 * insures that we get called at equal timing for good visual effect.
126 static void led_control_service(void)
129 sc606regAval
=DEFAULT_BRIGHTNESS_SETTING
,
132 sc606regCONFval
=0x03;
134 static bool sc606_changed
=false, sc606_CONF_changed
=false;
136 if(sc606_changed
==false)
138 switch (backlight_control
)
140 case BACKLIGHT_CONTROL_IDLE
:
141 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
143 case BACKLIGHT_CONTROL_OFF
:
145 sc606_CONF_changed
=true;
146 sc606regCONFval
&= ~0x03;
148 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
150 case BACKLIGHT_CONTROL_ON
:
152 sc606_CONF_changed
=true;
153 sc606regCONFval
|= 0x03;
154 sc606regAval
=backlight_brightness
;
155 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
157 case BACKLIGHT_CONTROL_SET
:
158 if(!(sc606regCONFval
&0x03))
161 sc606regAval
=backlight_brightness
;
162 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
164 case BACKLIGHT_CONTROL_FADE
:
165 /* Was this mode set while the backlight is already on/off? */
166 if(backlight_target
==sc606regAval
)
168 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
172 if(!(sc606regCONFval
&0x03))
174 sc606_CONF_changed
=true;
175 sc606regCONFval
|= 0x03;
177 if(backlight_target
>sc606regAval
)
180 if(backlight_target
==sc606regAval
)
181 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
187 backlight_control
= BACKLIGHT_CONTROL_OFF
;
188 else if (backlight_target
==sc606regAval
)
189 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
194 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
197 switch (buttonlight_control
)
199 case BUTTONLIGHT_CONTROL_IDLE
:
200 buttonlight_control
=BUTTONLIGHT_CONTROL_IDLE
;
202 case BUTTONLIGHT_CONTROL_OFF
:
204 sc606_CONF_changed
=true;
205 sc606regCONFval
&= ~BUTTONLIGHT_ALL
;
206 sc606regBval
=sc606regCval
=0;
207 buttonlight_control
=BUTTONLIGHT_CONTROL_IDLE
;
209 case BUTTONLIGHT_CONTROL_ON
:
211 sc606_CONF_changed
=true;
212 sc606regCONFval
|= BUTTONLIGHT_ALL
;
213 sc606regBval
=sc606regCval
=buttonlight_brightness
;
214 buttonlight_control
=BUTTONLIGHT_CONTROL_IDLE
;
216 case BUTTONLIGHT_CONTROL_SET
:
217 if(!(sc606regCONFval
&BUTTONLIGHT_ALL
))
220 sc606regBval
=sc606regCval
=buttonlight_brightness
;
221 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
223 case BUTTONLIGHT_CONTROL_FADE
:
224 /* Was this mode set while the button light is already on? */
225 if(buttonlight_target
==sc606regBval
)
227 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
231 if(!(sc606regCONFval
&BUTTONLIGHT_ALL
))
233 sc606_CONF_changed
=true;
234 sc606regCONFval
|= BUTTONLIGHT_ALL
;
236 if(buttonlight_target
>sc606regBval
)
238 sc606regCval
=++sc606regBval
;
239 if(buttonlight_target
==sc606regBval
)
240 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
244 sc606regCval
=--sc606regBval
;
246 buttonlight_control
= BUTTONLIGHT_CONTROL_OFF
;
247 else if (buttonlight_target
==sc606regBval
)
248 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
253 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
258 switch (sc606_control
)
260 case SC606_CONTROL_IDLE
:
262 sc606_control
=SC606_CONTROL_A12
;
264 sc606_control
=SC606_CONTROL_IDLE
;
267 case SC606_CONTROL_A12
:
268 sc606_write(SC606_REG_A
, sc606regAval
);
269 sc606_control
=SC606_CONTROL_B12
;
272 case SC606_CONTROL_B12
:
273 sc606_write(SC606_REG_B
, sc606regBval
);
274 sc606_control
=SC606_CONTROL_C12
;
277 case SC606_CONTROL_C12
:
278 sc606_write(SC606_REG_C
, sc606regCval
);
279 if(sc606_CONF_changed
!=true)
282 if(backlight_control
!= BACKLIGHT_CONTROL_IDLE
||
283 buttonlight_control
!= BUTTONLIGHT_CONTROL_IDLE
)
285 sc606_control
=SC606_CONTROL_A12
;
289 sc606_control
=SC606_CONTROL_IDLE
;
294 sc606_control
=SC606_CONTROL_CONF
;
298 case SC606_CONTROL_CONF
:
299 sc606_write(SC606_REG_CONF
, sc606regCONFval
);
301 sc606_CONF_changed
=false;
302 if(backlight_control
!= BACKLIGHT_CONTROL_IDLE
||
303 buttonlight_control
!= BUTTONLIGHT_CONTROL_IDLE
)
305 sc606_control
=SC606_CONTROL_A12
;
309 sc606_control
=SC606_CONTROL_IDLE
;
314 sc606_control
=SC606_CONTROL_IDLE
;
318 if(sc606regCONFval
&0x03)
323 #endif /* BOOTLOADER */
325 static void __backlight_dim(bool dim_now
)
327 /* dont let the interrupt tick happen */
328 backlight_control
= BACKLIGHT_CONTROL_IDLE
;
329 backlight_target
= (dim_now
== true) ? 0 : backlight_brightness
;
330 if(backlight_target
==0 && backlight_brightness
==0)
333 backlight_control
= BACKLIGHT_CONTROL_ON
;
335 backlight_control
= BACKLIGHT_CONTROL_OFF
;
338 backlight_control
= BACKLIGHT_CONTROL_FADE
;
341 void _backlight_on(void)
344 __backlight_dim(false);
347 void _backlight_off(void)
349 __backlight_dim(true);
352 static inline void __buttonlight_on(void)
354 buttonlight_control
= BUTTONLIGHT_CONTROL_ON
;
357 static inline void __buttonlight_off(void)
359 buttonlight_control
= BUTTONLIGHT_CONTROL_OFF
;
362 static void __buttonlight_dim(bool dim_now
)
364 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
365 buttonlight_target
= (dim_now
== true) ? 0 : buttonlight_brightness
;
366 if(buttonlight_target
==0 && buttonlight_brightness
==0)
369 buttonlight_control
= BUTTONLIGHT_CONTROL_ON
;
371 buttonlight_control
= BUTTONLIGHT_CONTROL_OFF
;
374 buttonlight_control
= BUTTONLIGHT_CONTROL_FADE
;
377 void _buttonlight_on(void)
379 __buttonlight_dim(false);
382 void _buttonlight_off(void)
385 if(_buttonlight_timeout
>0)
386 __buttonlight_dim(true);
392 void _buttonlight_set_brightness(int brightness
)
394 /* clamp the brightness value */
395 brightness
= MAX(1, MIN(12, brightness
));
396 /* stop the interrupt from messing us up */
397 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
398 buttonlight_brightness
= log_brightness
[brightness
- 1];
399 buttonlight_control
= BUTTONLIGHT_CONTROL_SET
;
402 bool _backlight_init(void)
404 buttonlight_brightness
= DEFAULT_BRIGHTNESS_SETTING
;
405 backlight_brightness
= DEFAULT_BRIGHTNESS_SETTING
;
407 buttonlight_control
= BUTTONLIGHT_CONTROL_IDLE
;
408 backlight_control
= BACKLIGHT_CONTROL_ON
;
410 /* Set the backlight up in a known state */
412 sc606_write(SC606_REG_A
, DEFAULT_BRIGHTNESS_SETTING
);
413 sc606_write(SC606_REG_B
, 0);
414 sc606_write(SC606_REG_C
, 0);
415 sc606_write(SC606_REG_CONF
, 0x03);
417 /* put the led control on the tick list */
418 tick_add_task(led_control_service
);