Add hardware backlight fading on Gigabeat S with fade up and down options in LCD Settings. USE_BACKLIGHT_CUSTOM_FADING_BOOL is used to specify the setting type needed but leave the fading code itself implementation-defined.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19237 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sevakis 2008-11-26 21:26:22 +00:00
parent 5b0d74a7d3
commit 495115b84a
8 changed files with 115 additions and 30 deletions

View file

@ -24,6 +24,8 @@ backlight_brightness
backlight_fade_pwm backlight_fade_pwm
#elif defined(USE_BACKLIGHT_SW_FADING) #elif defined(USE_BACKLIGHT_SW_FADING)
backlight_fade_sw backlight_fade_sw
#elif defined(USE_BACKLIGHT_CUSTOM_FADING_BOOL)
backlight_fade_custom_bool
#endif #endif
#if BATTERY_TYPES_COUNT > 1 #if BATTERY_TYPES_COUNT > 1

View file

@ -92,7 +92,8 @@ MENUITEM_SETTING(backlight_on_button_hold,
#endif #endif
MENUITEM_SETTING(caption_backlight, &global_settings.caption_backlight, NULL); MENUITEM_SETTING(caption_backlight, &global_settings.caption_backlight, NULL);
#if (defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)) || \ #if (defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)) || \
defined(USE_BACKLIGHT_SW_FADING) defined(USE_BACKLIGHT_SW_FADING) || \
defined(USE_BACKLIGHT_CUSTOM_FADING_BOOL)
MENUITEM_SETTING(backlight_fade_in, &global_settings.backlight_fade_in, NULL); MENUITEM_SETTING(backlight_fade_in, &global_settings.backlight_fade_in, NULL);
MENUITEM_SETTING(backlight_fade_out, &global_settings.backlight_fade_out, NULL); MENUITEM_SETTING(backlight_fade_out, &global_settings.backlight_fade_out, NULL);
#endif #endif
@ -132,7 +133,8 @@ MAKE_MENU(lcd_settings,ID2P(LANG_LCD_MENU),
# endif # endif
,&caption_backlight ,&caption_backlight
#if (defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)) || \ #if (defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)) || \
defined(USE_BACKLIGHT_SW_FADING) defined(USE_BACKLIGHT_SW_FADING) || \
defined(USE_BACKLIGHT_CUSTOM_FADING_BOOL)
,&backlight_fade_in, &backlight_fade_out ,&backlight_fade_in, &backlight_fade_out
#endif #endif
,&bl_filter_first_keypress ,&bl_filter_first_keypress

View file

@ -769,7 +769,8 @@ void settings_apply(bool read_disk)
backlight_set_timeout_plugged(global_settings.backlight_timeout_plugged); backlight_set_timeout_plugged(global_settings.backlight_timeout_plugged);
#endif #endif
#if (defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)) \ #if (defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)) \
|| defined(USE_BACKLIGHT_SW_FADING) || defined(USE_BACKLIGHT_SW_FADING) \
|| defined(USE_BACKLIGHT_CUSTOM_FADING_BOOL)
backlight_set_fade_in(global_settings.backlight_fade_in); backlight_set_fade_in(global_settings.backlight_fade_in);
backlight_set_fade_out(global_settings.backlight_fade_out); backlight_set_fade_out(global_settings.backlight_fade_out);
#endif #endif

View file

@ -424,7 +424,8 @@ struct user_settings
#if defined(HAVE_BACKLIGHT_PWM_FADING) #if defined(HAVE_BACKLIGHT_PWM_FADING)
int backlight_fade_in; /* backlight fade in timing: 0..3 */ int backlight_fade_in; /* backlight fade in timing: 0..3 */
int backlight_fade_out; /* backlight fade in timing: 0..7 */ int backlight_fade_out; /* backlight fade in timing: 0..7 */
#elif defined(USE_BACKLIGHT_SW_FADING) #elif defined(USE_BACKLIGHT_SW_FADING) \
|| defined(USE_BACKLIGHT_CUSTOM_FADING_BOOL)
bool backlight_fade_in; bool backlight_fade_in;
bool backlight_fade_out; bool backlight_fade_out;
#endif #endif

View file

@ -679,7 +679,8 @@ const struct settings_list settings[] = {
UNIT_MS, formatter_unit_0_is_off, getlang_unit_0_is_off, UNIT_MS, formatter_unit_0_is_off, getlang_unit_0_is_off,
backlight_set_fade_out, 10, backlight_set_fade_out, 10,
0,100,200,300,500,1000,2000,3000,5000,10000), 0,100,200,300,500,1000,2000,3000,5000,10000),
#elif defined(USE_BACKLIGHT_SW_FADING) #elif defined(USE_BACKLIGHT_SW_FADING) \
|| defined(USE_BACKLIGHT_CUSTOM_FADING_BOOL)
OFFON_SETTING(0, backlight_fade_in, LANG_BACKLIGHT_FADE_IN, OFFON_SETTING(0, backlight_fade_in, LANG_BACKLIGHT_FADE_IN,
true, "backlight fade in", backlight_set_fade_in), true, "backlight fade in", backlight_set_fade_in),
OFFON_SETTING(0, backlight_fade_out, LANG_BACKLIGHT_FADE_OUT, OFFON_SETTING(0, backlight_fade_out, LANG_BACKLIGHT_FADE_OUT,

View file

@ -38,7 +38,8 @@ int backlight_get_current_timeout(void);
void backlight_set_fade_in(int value); void backlight_set_fade_in(int value);
void backlight_set_fade_out(int value); void backlight_set_fade_out(int value);
#endif #endif
#ifdef USE_BACKLIGHT_SW_FADING #if defined(USE_BACKLIGHT_SW_FADING) \
|| defined(USE_BACKLIGHT_CUSTOM_FADING_BOOL)
void backlight_set_fade_in(bool value); void backlight_set_fade_in(bool value);
void backlight_set_fade_out(bool value); void backlight_set_fade_out(bool value);
#endif #endif

View file

@ -94,6 +94,9 @@
#ifndef SIMULATOR #ifndef SIMULATOR
/* Implementation-defined fading type with bool settings */
#define USE_BACKLIGHT_CUSTOM_FADING_BOOL
/* The LCD on a Gigabeat is 240x320 - it is portrait */ /* The LCD on a Gigabeat is 240x320 - it is portrait */
#define HAVE_PORTRAIT_LCD #define HAVE_PORTRAIT_LCD

View file

@ -65,50 +65,124 @@ static const struct
}; };
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */ #endif /* HAVE_BACKLIGHT_BRIGHTNESS */
/* Bits always combined with ramping bits */
#define MC13783_LED_CONTROL0_BITS \
(MC13783_LEDEN | MC13783_BOOSTEN | MC13783_ABMODE_MONCH_LEDMD1234 | \
MC13783_ABREF_400MV)
static struct mutex backlight_mutex; /* Block brightness change while
* setting up fading */
static bool backlight_on_status = true; /* Is on or off? */
static uint32_t backlight_pwm_bits; /* Final PWM setting for fade-in */
/* Backlight ramping settings */
static uint32_t led_ramp_mask = MC13783_LEDMDRAMPDOWN | MC13783_LEDMDRAMPUP;
bool _backlight_init(void) bool _backlight_init(void)
{ {
mc13783_write(MC13783_LED_CONTROL0, mutex_init(&backlight_mutex);
MC13783_LEDEN |
MC13783_LEDMDRAMPUP | /* Set default LED register value */
MC13783_LEDMDRAMPDOWN | mc13783_write(MC13783_LED_CONTROL0, MC13783_LED_CONTROL0_BITS);
MC13783_BOOSTEN |
MC13783_ABMODE_MONCH_LEDMD1234 | /* Our PWM and I-Level is different than retailos (but same apparent
MC13783_ABREF_400MV); * brightness), so init to our default. */
_backlight_set_brightness(DEFAULT_BRIGHTNESS_SETTING);
return true; return true;
} }
void backlight_set_fade_out(bool value)
{
if (value)
led_ramp_mask |= MC13783_LEDMDRAMPDOWN;
else
led_ramp_mask &= ~MC13783_LEDMDRAMPDOWN;
}
void backlight_set_fade_in(bool value)
{
if (value)
led_ramp_mask |= MC13783_LEDMDRAMPUP;
else
led_ramp_mask &= ~MC13783_LEDMDRAMPUP;
}
void _backlight_on(void) void _backlight_on(void)
{ {
/* LEDEN=1 */ static const char regs[2] =
mc13783_set(MC13783_LED_CONTROL0, MC13783_LEDEN); {
MC13783_LED_CONTROL0,
MC13783_LED_CONTROL2
};
uint32_t data[2];
mutex_lock(&backlight_mutex);
/* Set/clear LEDRAMPUP bit, clear LEDRAMPDOWN bit */
data[0] = MC13783_LED_CONTROL0_BITS;
if (!backlight_on_status)
data[0] |= led_ramp_mask & MC13783_LEDMDRAMPUP;
backlight_on_status = true;
/* Specify final PWM setting */
data[1] = mc13783_read(MC13783_LED_CONTROL2);
if (data[1] != MC13783_DATA_ERROR)
{
data[1] &= ~MC13783_LEDMDDC;
data[1] |= backlight_pwm_bits;
/* Write regs within 30us of each other (requires single xfer) */
mc13783_write_regset(regs, data, 2);
}
mutex_unlock(&backlight_mutex);
} }
void _backlight_off(void) void _backlight_off(void)
{ {
/* LEDEN=0 */ uint32_t ctrl0 = MC13783_LED_CONTROL0_BITS;
mc13783_clear(MC13783_LED_CONTROL0, MC13783_LEDEN);
mutex_lock(&backlight_mutex);
if (backlight_on_status)
ctrl0 |= led_ramp_mask & MC13783_LEDMDRAMPDOWN;
backlight_on_status = false;
/* Set/clear LEDRAMPDOWN bit, clear LEDRAMPUP bit */
mc13783_write(MC13783_LED_CONTROL0, ctrl0);
/* Wait 100us - 500ms */
sleep(HZ/100);
/* Write final PWM setting */
mc13783_write_masked(MC13783_LED_CONTROL2, MC13783_LEDMDDCw(0),
MC13783_LEDMDDC);
mutex_unlock(&backlight_mutex);
} }
#ifdef HAVE_BACKLIGHT_BRIGHTNESS #ifdef HAVE_BACKLIGHT_BRIGHTNESS
/* Assumes that the backlight has been initialized */ /* Assumes that the backlight has been initialized - parameter should
* already be range-checked in public interface. */
void _backlight_set_brightness(int brightness) void _backlight_set_brightness(int brightness)
{ {
uint32_t data, md, pwm; uint32_t md;
if ((unsigned)brightness >= ARRAYLEN(led_md_pwm_table)) mutex_lock(&backlight_mutex);
brightness = DEFAULT_BRIGHTNESS_SETTING;
data = mc13783_read(MC13783_LED_CONTROL2);
if (data == (uint32_t)-1)
return;
md = led_md_pwm_table[brightness].md; md = led_md_pwm_table[brightness].md;
pwm = led_md_pwm_table[brightness].pwm; backlight_pwm_bits = backlight_on_status ?
MC13783_LEDMDDCw(led_md_pwm_table[brightness].pwm) : 0;
data &= ~(MC13783_LEDMD | MC13783_LEDMDDC); mc13783_write_masked(MC13783_LED_CONTROL2,
data |= MC13783_LEDMDw(md) | MC13783_LEDMDDCw(pwm); MC13783_LEDMDw(md) | backlight_pwm_bits,
MC13783_LEDMD | MC13783_LEDMDDC);
mc13783_write(MC13783_LED_CONTROL2, data); mutex_unlock(&backlight_mutex);
} }
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */ #endif /* HAVE_BACKLIGHT_BRIGHTNESS */