summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-11-26 21:26:22 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-11-26 21:26:22 +0000
commit495115b84a71b900b27c55b899b68e12059434d4 (patch)
tree5514f2d3131bc20a341a020fe6382fd5df9fe532
parent5b0d74a7d3329ec3fc5818d9185aba7f29291ca7 (diff)
downloadrockbox-495115b84a71b900b27c55b899b68e12059434d4.tar.gz
rockbox-495115b84a71b900b27c55b899b68e12059434d4.tar.bz2
rockbox-495115b84a71b900b27c55b899b68e12059434d4.zip
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
-rw-r--r--apps/features.txt2
-rw-r--r--apps/menus/display_menu.c6
-rw-r--r--apps/settings.c3
-rw-r--r--apps/settings.h3
-rw-r--r--apps/settings_list.c3
-rw-r--r--firmware/export/backlight.h3
-rw-r--r--firmware/export/config-gigabeat-s.h3
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c122
8 files changed, 115 insertions, 30 deletions
diff --git a/apps/features.txt b/apps/features.txt
index 4f394d5eef..0ddccced3c 100644
--- a/apps/features.txt
+++ b/apps/features.txt
@@ -24,6 +24,8 @@ backlight_brightness
backlight_fade_pwm
#elif defined(USE_BACKLIGHT_SW_FADING)
backlight_fade_sw
+#elif defined(USE_BACKLIGHT_CUSTOM_FADING_BOOL)
+backlight_fade_custom_bool
#endif
#if BATTERY_TYPES_COUNT > 1
diff --git a/apps/menus/display_menu.c b/apps/menus/display_menu.c
index 744a9e9354..488b0ff570 100644
--- a/apps/menus/display_menu.c
+++ b/apps/menus/display_menu.c
@@ -92,7 +92,8 @@ MENUITEM_SETTING(backlight_on_button_hold,
#endif
MENUITEM_SETTING(caption_backlight, &global_settings.caption_backlight, NULL);
#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_out, &global_settings.backlight_fade_out, NULL);
#endif
@@ -132,7 +133,8 @@ MAKE_MENU(lcd_settings,ID2P(LANG_LCD_MENU),
# endif
,&caption_backlight
#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
#endif
,&bl_filter_first_keypress
diff --git a/apps/settings.c b/apps/settings.c
index 2cab26a4a1..609cb3f93f 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -769,7 +769,8 @@ void settings_apply(bool read_disk)
backlight_set_timeout_plugged(global_settings.backlight_timeout_plugged);
#endif
#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_out(global_settings.backlight_fade_out);
#endif
diff --git a/apps/settings.h b/apps/settings.h
index 56b7d3e80a..be83689368 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -424,7 +424,8 @@ struct user_settings
#if defined(HAVE_BACKLIGHT_PWM_FADING)
int backlight_fade_in; /* backlight fade in timing: 0..3 */
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_out;
#endif
diff --git a/apps/settings_list.c b/apps/settings_list.c
index f4519f5975..fe379ca229 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -679,7 +679,8 @@ const struct settings_list settings[] = {
UNIT_MS, formatter_unit_0_is_off, getlang_unit_0_is_off,
backlight_set_fade_out, 10,
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,
true, "backlight fade in", backlight_set_fade_in),
OFFON_SETTING(0, backlight_fade_out, LANG_BACKLIGHT_FADE_OUT,
diff --git a/firmware/export/backlight.h b/firmware/export/backlight.h
index 506a9f6b03..cb081a5301 100644
--- a/firmware/export/backlight.h
+++ b/firmware/export/backlight.h
@@ -38,7 +38,8 @@ int backlight_get_current_timeout(void);
void backlight_set_fade_in(int value);
void backlight_set_fade_out(int value);
#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_out(bool value);
#endif
diff --git a/firmware/export/config-gigabeat-s.h b/firmware/export/config-gigabeat-s.h
index e6fa6c9fc6..4359c90279 100644
--- a/firmware/export/config-gigabeat-s.h
+++ b/firmware/export/config-gigabeat-s.h
@@ -94,6 +94,9 @@
#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 */
#define HAVE_PORTRAIT_LCD
diff --git a/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c b/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c
index 535c0a0051..7e40b95437 100644
--- a/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c
@@ -65,50 +65,124 @@ static const struct
};
#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)
{
- mc13783_write(MC13783_LED_CONTROL0,
- MC13783_LEDEN |
- MC13783_LEDMDRAMPUP |
- MC13783_LEDMDRAMPDOWN |
- MC13783_BOOSTEN |
- MC13783_ABMODE_MONCH_LEDMD1234 |
- MC13783_ABREF_400MV);
+ mutex_init(&backlight_mutex);
+
+ /* Set default LED register value */
+ mc13783_write(MC13783_LED_CONTROL0, MC13783_LED_CONTROL0_BITS);
+
+ /* Our PWM and I-Level is different than retailos (but same apparent
+ * brightness), so init to our default. */
+ _backlight_set_brightness(DEFAULT_BRIGHTNESS_SETTING);
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)
{
- /* LEDEN=1 */
- mc13783_set(MC13783_LED_CONTROL0, MC13783_LEDEN);
+ static const char regs[2] =
+ {
+ 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)
{
- /* LEDEN=0 */
- mc13783_clear(MC13783_LED_CONTROL0, MC13783_LEDEN);
+ uint32_t ctrl0 = MC13783_LED_CONTROL0_BITS;
+
+ 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
-/* 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)
{
- uint32_t data, md, pwm;
-
- if ((unsigned)brightness >= ARRAYLEN(led_md_pwm_table))
- brightness = DEFAULT_BRIGHTNESS_SETTING;
-
- data = mc13783_read(MC13783_LED_CONTROL2);
+ uint32_t md;
- if (data == (uint32_t)-1)
- return;
+ mutex_lock(&backlight_mutex);
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);
- data |= MC13783_LEDMDw(md) | MC13783_LEDMDDCw(pwm);
+ mc13783_write_masked(MC13783_LED_CONTROL2,
+ MC13783_LEDMDw(md) | backlight_pwm_bits,
+ MC13783_LEDMD | MC13783_LEDMDDC);
- mc13783_write(MC13783_LED_CONTROL2, data);
+ mutex_unlock(&backlight_mutex);
}
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */