Remove the calls to backlight_lcd_sleep_countdown from target specific code and move...
[kugel-rb.git] / firmware / target / arm / s3c2440 / gigabeat-fx / backlight-meg-fx.c
blob97372acdd5ed61f9fbdf30ff4aad27810cc53119
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
21 #include "config.h"
22 #include "cpu.h"
23 #include "system.h"
24 #include "backlight-target.h"
25 #include "backlight.h"
26 #include "lcd.h"
27 #include "sc606-meg-fx.h"
28 #include "power.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};
38 #ifndef BOOTLOADER
39 static void led_control_service(void);
41 static enum sc606_states
43 SC606_CONTROL_IDLE,
44 SC606_CONTROL_A12,
45 SC606_CONTROL_B12,
46 SC606_CONTROL_C12,
47 SC606_CONTROL_CONF
48 } sc606_control;
49 #endif /* BOOTLOADER */
51 static enum backlight_states
53 BACKLIGHT_CONTROL_IDLE,
54 BACKLIGHT_CONTROL_OFF,
55 BACKLIGHT_CONTROL_ON,
56 BACKLIGHT_CONTROL_SET,
57 BACKLIGHT_CONTROL_FADE
58 } backlight_control;
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 */
98 switch (mode)
100 case BUTTONLIGHT_OFF:
101 buttonlight_control = BUTTONLIGHT_CONTROL_OFF;
102 break;
104 case BUTTONLIGHT_ON:
105 buttonlight_control = BUTTONLIGHT_CONTROL_ON;
106 break;
108 case BUTTONLIGHT_FOLLOW:
109 buttonlight_control = BUTTONLIGHT_CONTROL_FADE;
110 break;
112 default:
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.
127 #ifndef BOOTLOADER
128 static void led_control_service(void)
130 static unsigned char
131 sc606regAval=DEFAULT_BRIGHTNESS_SETTING,
132 sc606regBval=0,
133 sc606regCval=0,
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;
144 break;
145 case BACKLIGHT_CONTROL_OFF:
146 sc606_changed=true;
147 sc606_CONF_changed=true;
148 sc606regCONFval &= ~0x03;
149 sc606regAval=0;
150 backlight_control = BACKLIGHT_CONTROL_IDLE;
151 break;
152 case BACKLIGHT_CONTROL_ON:
153 sc606_changed=true;
154 sc606_CONF_changed=true;
155 sc606regCONFval |= 0x03;
156 sc606regAval=_backlight_brightness;
157 backlight_control = BACKLIGHT_CONTROL_IDLE;
158 break;
159 case BACKLIGHT_CONTROL_SET:
160 if(!(sc606regCONFval&0x03))
161 break;
162 sc606_changed=true;
163 sc606regAval = _backlight_brightness;
164 backlight_control = BACKLIGHT_CONTROL_IDLE;
165 break;
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;
171 break;
173 sc606_changed=true;
174 if(!(sc606regCONFval&0x03))
176 sc606_CONF_changed=true;
177 sc606regCONFval |= 0x03;
179 if(backlight_target>sc606regAval)
181 sc606regAval++;
182 if(backlight_target==sc606regAval)
183 backlight_control = BACKLIGHT_CONTROL_IDLE;
185 else
187 sc606regAval--;
188 if(sc606regAval==0)
189 backlight_control = BACKLIGHT_CONTROL_OFF;
190 else if (backlight_target==sc606regAval)
191 backlight_control = BACKLIGHT_CONTROL_IDLE;
194 break;
195 default:
196 backlight_control = BACKLIGHT_CONTROL_IDLE;
197 break;
199 switch (buttonlight_control)
201 case BUTTONLIGHT_CONTROL_IDLE:
202 buttonlight_control=BUTTONLIGHT_CONTROL_IDLE;
203 break;
204 case BUTTONLIGHT_CONTROL_OFF:
205 sc606_changed=true;
206 sc606_CONF_changed=true;
207 sc606regCONFval &= ~BUTTONLIGHT_ALL;
208 sc606regBval=sc606regCval=0;
209 buttonlight_control=BUTTONLIGHT_CONTROL_IDLE;
210 break;
211 case BUTTONLIGHT_CONTROL_ON:
212 sc606_changed=true;
213 sc606_CONF_changed=true;
214 sc606regCONFval |= BUTTONLIGHT_ALL;
215 sc606regBval=sc606regCval=buttonlight_brightness;
216 buttonlight_control=BUTTONLIGHT_CONTROL_IDLE;
217 break;
218 case BUTTONLIGHT_CONTROL_SET:
219 if(!(sc606regCONFval&BUTTONLIGHT_ALL))
220 break;
221 sc606_changed=true;
222 sc606regBval=sc606regCval=buttonlight_brightness;
223 buttonlight_control = BUTTONLIGHT_CONTROL_IDLE;
224 break;
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;
230 break;
232 sc606_changed=true;
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;
244 else
246 sc606regCval=--sc606regBval;
247 if(sc606regBval==0)
248 buttonlight_control = BUTTONLIGHT_CONTROL_OFF;
249 else if (buttonlight_target==sc606regBval)
250 backlight_control = BACKLIGHT_CONTROL_IDLE;
253 break;
254 default:
255 buttonlight_control = BUTTONLIGHT_CONTROL_IDLE;
256 break;
260 switch (sc606_control)
262 case SC606_CONTROL_IDLE:
263 if(sc606_changed)
264 sc606_control=SC606_CONTROL_A12;
265 else
266 sc606_control=SC606_CONTROL_IDLE;
267 break;
269 case SC606_CONTROL_A12:
270 sc606_write(SC606_REG_A , sc606regAval);
271 sc606_control=SC606_CONTROL_B12;
272 break;
274 case SC606_CONTROL_B12:
275 sc606_write(SC606_REG_B , sc606regBval);
276 sc606_control=SC606_CONTROL_C12;
277 break;
279 case SC606_CONTROL_C12:
280 sc606_write(SC606_REG_C , sc606regCval);
281 if(sc606_CONF_changed!=true)
283 sc606_changed=false;
284 if(backlight_control != BACKLIGHT_CONTROL_IDLE ||
285 buttonlight_control != BUTTONLIGHT_CONTROL_IDLE)
287 sc606_control=SC606_CONTROL_A12;
289 else
291 sc606_control=SC606_CONTROL_IDLE;
294 else
296 sc606_control=SC606_CONTROL_CONF;
298 break;
300 case SC606_CONTROL_CONF:
301 sc606_write(SC606_REG_CONF , sc606regCONFval);
302 sc606_changed=false;
303 sc606_CONF_changed=false;
304 if(backlight_control != BACKLIGHT_CONTROL_IDLE ||
305 buttonlight_control != BUTTONLIGHT_CONTROL_IDLE)
307 sc606_control=SC606_CONTROL_A12;
309 else
311 sc606_control=SC606_CONTROL_IDLE;
313 break;
315 default:
316 sc606_control=SC606_CONTROL_IDLE;
317 break;
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 == true) ? 0 : _backlight_brightness;
327 if(backlight_target==0 && _backlight_brightness==0)
329 if(dim_now == false)
330 backlight_control = BACKLIGHT_CONTROL_ON;
331 else
332 backlight_control = BACKLIGHT_CONTROL_OFF;
334 else
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 */
342 #endif
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 == true) ? 0 : buttonlight_brightness;
365 if(buttonlight_target==0 && buttonlight_brightness==0)
367 if(dim_now == false)
368 buttonlight_control = BUTTONLIGHT_CONTROL_ON;
369 else
370 buttonlight_control = BUTTONLIGHT_CONTROL_OFF;
372 else
373 buttonlight_control = BUTTONLIGHT_CONTROL_FADE;
376 void _buttonlight_on(void)
378 __buttonlight_dim(false);
381 void _buttonlight_off(void)
383 #ifndef BOOTLOADER
384 if(buttonlight_get_current_timeout() > 0)
385 __buttonlight_dim(true);
386 else
387 #endif
388 __buttonlight_off();
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 */
409 sc606_init();
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);
414 #ifndef BOOTLOADER
415 /* put the led control on the tick list */
416 tick_add_task(led_control_service);
417 #endif
418 return true;