Iriver: Backlight fading is now configurable. Added a function to stop the backlight from using timer1, freeing it for usage in plugins. Grouped together some related settings functions.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6779 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/lang/deutsch.lang b/apps/lang/deutsch.lang
index c721c3c..4fbee51 100644
--- a/apps/lang/deutsch.lang
+++ b/apps/lang/deutsch.lang
@@ -3099,3 +3099,15 @@
 eng: "Crossfade"
 voice: "Überblenden"
 new: "Überblenden"
+
+id: LANG_BACKLIGHT_FADE_IN
+desc: in settings_menu
+eng: "Backlight fade in"
+voice: "Beleuchtung einblenden"
+new: "Beleuchtung einblenden"
+
+id: LANG_BACKLIGHT_FADE_OUT
+desc: in settings_menu
+eng: "Backlight fade out"
+voice: "Beleuchtung ausblenden"
+new: "Beleuchtung ausblenden"
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 2c54a9c..4549d6c 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -3093,3 +3093,15 @@
 eng: "Crossfade"
 voice: "Crossfade"
 new:
+
+id: LANG_BACKLIGHT_FADE_IN
+desc: in settings_menu
+eng: "Backlight fade in"
+voice: "Backlight fade in"
+new:
+
+id: LANG_BACKLIGHT_FADE_OUT
+desc: in settings_menu
+eng: "Backlight fade out"
+voice: "Backlight fade out"
+new:
diff --git a/apps/plugin.c b/apps/plugin.c
index a44482d..726a518 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -547,6 +547,8 @@
 
     if (prescale > 8 || cycles == 0 || prio < 1 || prio > 15)
         return 0; /* error, we can't do such period, bad argument */
+        
+    backlight_allow_timer(false); /* stop backlight from messing with the timer */
 #if CONFIG_CPU == SH7034
     and_b(~0x10, &TSTR); /* Stop the timer 4 */
     and_b(~0x10, &TSNC); /* No synchronization */
@@ -575,6 +577,7 @@
     IPRD = (IPRD & 0xFF0F); /* disable interrupt */
     pfn_timer = NULL;
 #endif
+    backlight_allow_timer(true);
 }
 
 #if CONFIG_CPU == SH7034
diff --git a/apps/settings.c b/apps/settings.c
index 6588a6e..c462ea0 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -393,7 +393,14 @@
 #if CONFIG_HWCODEC == MASNONE
     {1, S_O(crossfade), false, "crossfade", off_on},
 #endif
-    
+
+#if CONFIG_BACKLIGHT == BL_IRIVER
+    /* backlight fading */
+    {2, S_O(backlight_fade_in), 1, "backlight fade in", "off,500ms,1s,2s"},
+    {3, S_O(backlight_fade_out), 3, "backlight fade out",
+        "off,500ms,1s,2s,3s,4s,5s,10s"},
+#endif
+
     /* new stuff to be added at the end */
             
     /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */
@@ -765,6 +772,10 @@
 #endif
     backlight_set_timeout(global_settings.backlight_timeout);
     backlight_set_on_when_charging(global_settings.backlight_on_when_charging);
+#if CONFIG_BACKLIGHT == BL_IRIVER
+    backlight_set_fade_in(global_settings.backlight_fade_in);
+    backlight_set_fade_out(global_settings.backlight_fade_out);
+#endif
     ata_spindown(global_settings.disk_spindown);
 #if CONFIG_HWCODEC == MAS3507D
     dac_line_in(global_settings.line_in);
diff --git a/apps/settings.h b/apps/settings.h
index 2d4017c..7e0be44 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -202,6 +202,10 @@
                                1=always,
                                then according to timeout_values[] */
     bool backlight_on_when_charging;
+#if CONFIG_BACKLIGHT == BL_IRIVER
+    int backlight_fade_in;  /* backlight fade in timing: 0..3 */
+    int backlight_fade_out; /* backlight fade in timing: 0..7 */
+#endif
     int battery_capacity; /* in mAh */
     int battery_type;  /* for units which can take multiple types (Ondio). */
 
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index d8f440c..efca1a8 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -75,12 +75,12 @@
 }
 #endif
 
-static bool contrast(void)
+/**
+ * Menu to set icon visibility
+ */
+static bool show_icons(void)
 {
-    return set_int( str(LANG_CONTRAST), "", UNIT_INT,
-                    &global_settings.contrast, 
-                    lcd_set_contrast, 1, MIN_CONTRAST_SETTING,
-                    MAX_CONTRAST_SETTING );
+    return set_bool( str(LANG_SHOW_ICONS), &global_settings.show_icons );
 }
 
 #ifdef HAVE_REMOTE_LCD
@@ -122,14 +122,114 @@
 
     return rc;
 }
+
+#ifdef HAVE_CHARGING
+static bool backlight_on_when_charging(void)
+{
+    bool result = set_bool(str(LANG_BACKLIGHT_ON_WHEN_CHARGING),
+                           &global_settings.backlight_on_when_charging);
+    backlight_set_on_when_charging(global_settings.backlight_on_when_charging);
+    return result;
+}
 #endif
 
-/**
- * Menu to set icon visibility
- */
-static bool show_icons(void)
+static bool backlight_timer(void)
 {
-    return set_bool( str(LANG_SHOW_ICONS), &global_settings.show_icons );
+    static const struct opt_items names[] = {
+        { STR(LANG_OFF) },
+        { STR(LANG_ON) },
+        { "1s ", TALK_ID(1, UNIT_SEC) },
+        { "2s ", TALK_ID(2, UNIT_SEC) },
+        { "3s ", TALK_ID(3, UNIT_SEC) },
+        { "4s ", TALK_ID(4, UNIT_SEC) },
+        { "5s ", TALK_ID(5, UNIT_SEC) },
+        { "6s ", TALK_ID(6, UNIT_SEC) },
+        { "7s ", TALK_ID(7, UNIT_SEC) },
+        { "8s ", TALK_ID(8, UNIT_SEC) },
+        { "9s ", TALK_ID(9, UNIT_SEC) },
+        { "10s", TALK_ID(10, UNIT_SEC) },
+        { "15s", TALK_ID(15, UNIT_SEC) },
+        { "20s", TALK_ID(20, UNIT_SEC) },
+        { "25s", TALK_ID(25, UNIT_SEC) },
+        { "30s", TALK_ID(30, UNIT_SEC) },
+        { "45s", TALK_ID(45, UNIT_SEC) },
+        { "60s", TALK_ID(60, UNIT_SEC) },
+        { "90s", TALK_ID(90, UNIT_SEC) }
+    };
+    return set_option(str(LANG_BACKLIGHT), &global_settings.backlight_timeout,
+                      INT, names, 19, backlight_set_timeout );
+}
+
+#if CONFIG_BACKLIGHT == BL_IRIVER
+static bool backlight_fade_in(void)
+{
+    static const struct opt_items names[] = {
+        { STR(LANG_OFF) },
+        { "500ms", TALK_ID(500, UNIT_MS) },
+        { "1s", TALK_ID(1, UNIT_SEC) },
+        { "2s", TALK_ID(2, UNIT_SEC) },
+    };
+    return set_option(str(LANG_BACKLIGHT_FADE_IN),
+                      &global_settings.backlight_fade_in,
+                      INT, names, 4, backlight_set_fade_in );
+}
+
+static bool backlight_fade_out(void)
+{
+    static const struct opt_items names[] = {
+        { STR(LANG_OFF) },
+        { "500ms", TALK_ID(500, UNIT_MS) },
+        { "1s", TALK_ID(1, UNIT_SEC) },
+        { "2s", TALK_ID(2, UNIT_SEC) },
+        { "3s", TALK_ID(3, UNIT_SEC) },
+        { "4s", TALK_ID(4, UNIT_SEC) },
+        { "5s", TALK_ID(5, UNIT_SEC) },
+        { "10s", TALK_ID(10, UNIT_SEC) },
+    };
+    return set_option(str(LANG_BACKLIGHT_FADE_OUT),
+                      &global_settings.backlight_fade_out,
+                      INT, names, 8, backlight_set_fade_out );
+}
+#endif
+#endif /* CONFIG_BACKLIGHT */
+
+#ifdef HAVE_REMOTE_LCD
+
+static bool remote_backlight_timer(void)
+{
+    static const struct opt_items names[] = {
+        { STR(LANG_OFF) },
+        { STR(LANG_ON) },
+        { "1s ", TALK_ID(1, UNIT_SEC) },
+        { "2s ", TALK_ID(2, UNIT_SEC) },
+        { "3s ", TALK_ID(3, UNIT_SEC) },
+        { "4s ", TALK_ID(4, UNIT_SEC) },
+        { "5s ", TALK_ID(5, UNIT_SEC) },
+        { "6s ", TALK_ID(6, UNIT_SEC) },
+        { "7s ", TALK_ID(7, UNIT_SEC) },
+        { "8s ", TALK_ID(8, UNIT_SEC) },
+        { "9s ", TALK_ID(9, UNIT_SEC) },
+        { "10s", TALK_ID(10, UNIT_SEC) },
+        { "15s", TALK_ID(15, UNIT_SEC) },
+        { "20s", TALK_ID(20, UNIT_SEC) },
+        { "25s", TALK_ID(25, UNIT_SEC) },
+        { "30s", TALK_ID(30, UNIT_SEC) },
+        { "45s", TALK_ID(45, UNIT_SEC) },
+        { "60s", TALK_ID(60, UNIT_SEC) },
+        { "90s", TALK_ID(90, UNIT_SEC) }
+    };
+    return set_option(str(LANG_BACKLIGHT), &global_settings.remote_backlight_timeout,
+                      INT, names, 19, remote_backlight_set_timeout );
+}
+
+#endif /* HAVE_REMOTE_LCD */
+
+static bool contrast(void)
+{
+    return set_int( str(LANG_CONTRAST), "", UNIT_INT,
+                    &global_settings.contrast, 
+                    lcd_set_contrast, 1, MIN_CONTRAST_SETTING,
+                    MAX_CONTRAST_SETTING );
 }
 
 #ifdef HAVE_LCD_BITMAP
@@ -148,6 +248,20 @@
 }
 
 /**
+ * Menu to turn the display+buttons by 180 degrees
+ */
+static bool flip_display(void)
+{
+    bool rc = set_bool( str(LANG_FLIP_DISPLAY),
+                        &global_settings.flip_display);
+
+    button_set_flip(global_settings.flip_display);
+    lcd_set_flip(global_settings.flip_display);
+
+    return rc;
+}
+
+/**
  * Menu to set Line Selector Type (Pointer/Bar)
  */
 static bool invert_cursor(void)
@@ -160,20 +274,6 @@
 }
 
 /**
- * Menu to turn the display+buttons by 180 degrees
- */
-static bool flip_display(void)
-{
-    bool rc = set_bool( str(LANG_FLIP_DISPLAY),
-                        &global_settings.flip_display);
-    
-    button_set_flip(global_settings.flip_display);
-    lcd_set_flip(global_settings.flip_display);
-
-    return rc;
-}
-
-/**
  * Menu to configure the battery display on status bar
  */
 static bool battery_display(void)
@@ -613,76 +713,6 @@
                        names, 3, NULL );
 }
 
-#ifdef CONFIG_BACKLIGHT
-#ifdef HAVE_CHARGING
-static bool backlight_on_when_charging(void)
-{
-    bool result = set_bool(str(LANG_BACKLIGHT_ON_WHEN_CHARGING),
-                           &global_settings.backlight_on_when_charging);
-    backlight_set_on_when_charging(global_settings.backlight_on_when_charging);
-    return result;
-}
-#endif
-
-static bool backlight_timer(void)
-{
-    static const struct opt_items names[] = {
-        { STR(LANG_OFF) },
-        { STR(LANG_ON) },
-        { "1s ", TALK_ID(1, UNIT_SEC) },
-        { "2s ", TALK_ID(2, UNIT_SEC) },
-        { "3s ", TALK_ID(3, UNIT_SEC) },
-        { "4s ", TALK_ID(4, UNIT_SEC) },
-        { "5s ", TALK_ID(5, UNIT_SEC) },
-        { "6s ", TALK_ID(6, UNIT_SEC) },
-        { "7s ", TALK_ID(7, UNIT_SEC) },
-        { "8s ", TALK_ID(8, UNIT_SEC) },
-        { "9s ", TALK_ID(9, UNIT_SEC) },
-        { "10s", TALK_ID(10, UNIT_SEC) },
-        { "15s", TALK_ID(15, UNIT_SEC) },
-        { "20s", TALK_ID(20, UNIT_SEC) },
-        { "25s", TALK_ID(25, UNIT_SEC) },
-        { "30s", TALK_ID(30, UNIT_SEC) },
-        { "45s", TALK_ID(45, UNIT_SEC) },
-        { "60s", TALK_ID(60, UNIT_SEC) },
-        { "90s", TALK_ID(90, UNIT_SEC) }
-    };
-    return set_option(str(LANG_BACKLIGHT), &global_settings.backlight_timeout,
-                      INT, names, 19, backlight_set_timeout );
-}
-#endif /* CONFIG_BACKLIGHT */
-
-#ifdef HAVE_REMOTE_LCD
-
-static bool remote_backlight_timer(void)
-{
-    static const struct opt_items names[] = {
-        { STR(LANG_OFF) },
-        { STR(LANG_ON) },
-        { "1s ", TALK_ID(1, UNIT_SEC) },
-        { "2s ", TALK_ID(2, UNIT_SEC) },
-        { "3s ", TALK_ID(3, UNIT_SEC) },
-        { "4s ", TALK_ID(4, UNIT_SEC) },
-        { "5s ", TALK_ID(5, UNIT_SEC) },
-        { "6s ", TALK_ID(6, UNIT_SEC) },
-        { "7s ", TALK_ID(7, UNIT_SEC) },
-        { "8s ", TALK_ID(8, UNIT_SEC) },
-        { "9s ", TALK_ID(9, UNIT_SEC) },
-        { "10s", TALK_ID(10, UNIT_SEC) },
-        { "15s", TALK_ID(15, UNIT_SEC) },
-        { "20s", TALK_ID(20, UNIT_SEC) },
-        { "25s", TALK_ID(25, UNIT_SEC) },
-        { "30s", TALK_ID(30, UNIT_SEC) },
-        { "45s", TALK_ID(45, UNIT_SEC) },
-        { "60s", TALK_ID(60, UNIT_SEC) },
-        { "90s", TALK_ID(90, UNIT_SEC) }
-    };
-    return set_option(str(LANG_BACKLIGHT), &global_settings.remote_backlight_timeout,
-                      INT, names, 19, remote_backlight_set_timeout );
-}
-
-#endif /* HAVE_REMOTE_LCD */
-
 static bool poweroff_idle_timer(void)
 {
     static const struct opt_items names[] = {
@@ -1247,6 +1277,10 @@
         { ID2P(LANG_BACKLIGHT_ON_WHEN_CHARGING), backlight_on_when_charging },
 #endif
         { ID2P(LANG_CAPTION_BACKLIGHT), caption_backlight },
+#if CONFIG_BACKLIGHT == BL_IRIVER
+        { ID2P(LANG_BACKLIGHT_FADE_IN), backlight_fade_in },
+        { ID2P(LANG_BACKLIGHT_FADE_OUT), backlight_fade_out },
+#endif
 #endif /* CONFIG_BACKLIGHT */
         { ID2P(LANG_CONTRAST),        contrast },
 #ifdef HAVE_LCD_BITMAP
diff --git a/firmware/backlight.c b/firmware/backlight.c
index 699b3bf..e169209 100644
--- a/firmware/backlight.c
+++ b/firmware/backlight.c
@@ -60,34 +60,20 @@
 #endif
 
 #if CONFIG_BACKLIGHT == BL_IRIVER
+/* backlight fading */
+#define BL_PWM_INTERVAL 5000  /* Cycle interval in µs */
 #define BL_PWM_COUNT    100
-/* Cycle interval in ms */
-#define BL_PWM_INTERVAL      5000
-#define BL_DIM_SPEED    4
-#define __backlight_on __backlight_fade_in
-#define __backlight_off __backlight_fade_out
-
-#define DIM_STATE_START  0
-#define DIM_STATE_MAIN   1
-#define DIM_STATE_REMOTE 2
+static const char backlight_fade_value[8] = { 0, 1, 2, 4, 6, 8, 10, 20 };
+static int fade_in_count = 1;
+static int fade_out_count = 4;
+static bool timer_allowed = true;
 
 static bool bl_timer_active = false;
 static int bl_dim_current = BL_PWM_COUNT;
 static int bl_dim_target  = BL_PWM_COUNT;
 static int bl_pwm_counter = 0;
 static volatile int bl_cycle_counter = 0;
-
-/* Unfortunately we can't dim H1xx remote lcd :/ */
-#ifdef HAVE_REMOTE_LCD_DIMMABLE
-#define lcd_remote_backlight_on __backlight_fade_remote_in
-#define lcd_remote_backlight_off __backlight_fade_remote_out
-static int bl_dim_remote_current = BL_PWM_COUNT;
-static int bl_dim_remote_target = BL_PWM_COUNT;
-static int bl_pwm_remote_counter = 0;
-static bool bl_dim_next_interval;
-#endif
-
-static int bl_dim_state = 0;
+static enum {DIM_STATE_START, DIM_STATE_MAIN} bl_dim_state = DIM_STATE_START;
 
 void backlight_start_timer(void)
 {
@@ -116,123 +102,60 @@
 {
     int timer_period;
     bool idle = false;
-#ifdef HAVE_REMOTE_LCD_DIMMABLE
-    int new_timer_period;
-#endif
 
-    timer_period = FREQ/20000 * BL_PWM_INTERVAL / 100 / 32;
+    timer_period = FREQ / 2000 * BL_PWM_INTERVAL / 1000 / 32;
     switch (bl_dim_state) {
-    /* New cycle */
-    case DIM_STATE_START:
+      /* New cycle */
+      case DIM_STATE_START:
         bl_pwm_counter = 0;
         bl_cycle_counter++;
         
-        if (bl_dim_current > 0 && bl_dim_current < BL_PWM_COUNT) {
+        if (bl_dim_current > 0 && bl_dim_current < BL_PWM_COUNT) 
+        {
             GPIO1_OUT &= ~0x00020000;
             bl_pwm_counter = bl_dim_current;
             timer_period = timer_period * bl_pwm_counter / BL_PWM_COUNT;
             bl_dim_state = DIM_STATE_MAIN;
-        } else {
-            idle = true;
+        } 
+        else
+        {
             if (bl_dim_current)
                 GPIO1_OUT &= ~0x00020000;
             else
                 GPIO1_OUT |= 0x00020000;
+            if (bl_dim_current == bl_dim_target)
+                idle = true;
         }
         
-#ifdef HAVE_REMOTE_LCD_DIMMABLE
-        bl_dim_next_interval = 0;
-        bl_pwm_remote_counter = 0;
-        if (bl_dim_remote_current > 0 && 
-            bl_dim_remote_current < BL_PWM_COUNT) {
-            idle = false;
-            GPIO_OUT &= ~0x00000800;
-            bl_pwm_remote_counter = bl_dim_remote_current;
-            if (bl_dim_state == DIM_STATE_START) {
-                timer_period = timer_period * bl_pwm_remote_counter 
-                               / BL_PWM_COUNT;
-                bl_dim_state = DIM_STATE_REMOTE;
-                break ;
-            }
-            
-            new_timer_period = timer_period * bl_pwm_remote_counter
-                                / BL_PWM_COUNT;
-            if (new_timer_period < timer_period) {
-                bl_dim_next_interval = timer_period - new_timer_period;
-                timer_period = new_timer_period;
-                bl_dim_state = DIM_STATE_REMOTE;
-            } else {
-                bl_dim_next_interval = new_timer_period - timer_period;
-            }
-        } else {
-            if (bl_dim_remote_current)
-                GPIO_OUT &= ~0x00000800;
-            else
-                GPIO_OUT |= 0x00000800;
-        }
-#endif        
         break ;
         
-    /* Dim main screen */
-    case DIM_STATE_MAIN:
+      /* Dim main screen */
+      case DIM_STATE_MAIN:
         GPIO1_OUT |= 0x00020000;
-#ifdef HAVE_REMOTE_LCD_DIMMABLE
-        if (bl_dim_next_interval) {
-            timer_period = bl_dim_next_interval;
-            bl_dim_next_interval = 0;
-            bl_dim_state = DIM_STATE_REMOTE;
-            break ;
-        }
-#endif
         bl_dim_state = DIM_STATE_START;
         timer_period = timer_period * (BL_PWM_COUNT - bl_pwm_counter) / BL_PWM_COUNT;
         break ;
 
-#ifdef HAVE_REMOTE_LCD_DIMMABLE
-    /* Dim remote lcd */
-    case DIM_STATE_REMOTE:
-        GPIO_OUT |= 0x00000800;
-        if (bl_dim_next_interval) {
-            timer_period = bl_dim_next_interval;
-            bl_dim_next_interval = 0;
-            bl_dim_state = DIM_STATE_MAIN;
-            break ;
-        }
-    
-        bl_dim_state = DIM_STATE_START;
-        timer_period = timer_period * (BL_PWM_COUNT - bl_pwm_remote_counter) / BL_PWM_COUNT;
-        break ;
-#endif
     }
     
-    if (bl_cycle_counter >= BL_DIM_SPEED) {
-        if (bl_dim_target > bl_dim_current) {
-            bl_dim_current++;
-            idle = false;
-        }
-        else if (bl_dim_target < bl_dim_current) {
-            bl_dim_current--;
-            idle = false;
-        }
-#ifdef HAVE_REMOTE_LCD_DIMMABLE
-        if (bl_dim_remote_target > bl_dim_remote_current) {
-            bl_dim_remote_current++;
-            idle = false;
-        }
-        else if (bl_dim_remote_target < bl_dim_remote_current) {
-            bl_dim_remote_current--;
-            idle = false;
-        }
-#endif
+    if ((bl_dim_target > bl_dim_current) && (bl_cycle_counter >= fade_in_count))
+    {
+        bl_dim_current++;
         bl_cycle_counter = 0;
-        
-        /* Save CPU & battery when idle, stop timer */
-        if (idle) {
-            bl_timer_active = false;
-            TMR1 = 0;
-        }
     }
-    
+
+    if ((bl_dim_target < bl_dim_current) && (bl_cycle_counter >= fade_out_count))
+    {
+        bl_dim_current--;
+        bl_cycle_counter = 0;
+    }
+
+    if (idle) 
+    {
+        bl_timer_active = false;
+        TMR1 = 0;
+    }
+
     TRR1 = timer_period;
     TCN1 = 0;
     TER1 = 0xff; /* Clear all events */
@@ -244,38 +167,44 @@
     backlight_start_timer();
 }
 
-static void __backlight_fade_in(void)
+void backlight_allow_timer(bool on)
 {
-    __backlight_dim(BL_PWM_COUNT);
+    timer_allowed = on;
+
+    if (!timer_allowed && bl_timer_active)
+    {
+        bl_dim_current = bl_dim_target;
+        bl_timer_active = false;
+        TMR1 = 0;
+
+        if (bl_dim_current)
+            GPIO1_OUT &= ~0x00020000;
+        else
+            GPIO1_OUT |= 0x00020000;
+    }
 }
 
-static void __backlight_fade_out(void)
+void backlight_set_fade_in(int index)
 {
-    __backlight_dim(0);
+    fade_in_count = backlight_fade_value[index];
 }
 
-#ifdef HAVE_REMOTE_LCD_DIMMABLE
-static void __backlight_dim_remote(int value)
+void backlight_set_fade_out(int index)
 {
-    bl_dim_remote_target = value;
-}
-
-static void __backlight_fade_remote_in(void)
-{
-    __backlight_dim_remote(BL_PWM_COUNT);
-}
-
-static void __backlight_fade_remote_out(void)
-{
-    __backlight_dim_remote(0);
+    fade_out_count = backlight_fade_value[index];
 }
 #endif
 
-#else
 static void __backlight_off(void)
 {
 #if CONFIG_BACKLIGHT == BL_IRIVER
-    GPIO1_OUT  |= 0x00020000;
+    if (timer_allowed && (fade_out_count > 0))
+        __backlight_dim(0);
+    else
+    {
+        bl_dim_target = bl_dim_current = 0;
+        GPIO1_OUT  |= 0x00020000;
+    }
 #elif CONFIG_BACKLIGHT == BL_RTC
     /* Disable square wave */
     rtc_write(0x0a, rtc_read(0x0a) & ~0x40);
@@ -291,7 +220,13 @@
 static void __backlight_on(void)
 {
 #if CONFIG_BACKLIGHT == BL_IRIVER
-    GPIO1_OUT  &= ~0x00020000;
+    if (timer_allowed && (fade_in_count > 0))
+        __backlight_dim(BL_PWM_COUNT);
+    else
+    {
+        bl_dim_target = bl_dim_current = BL_PWM_COUNT;
+        GPIO1_OUT  &= ~0x00020000;
+    }
 #elif CONFIG_BACKLIGHT == BL_RTC
     /* Enable square wave */
     rtc_write(0x0a, rtc_read(0x0a) | 0x40);
@@ -304,7 +239,6 @@
     P1 |= 0x10;
 #endif
 }
-#endif
 
 void backlight_thread(void)
 {
diff --git a/firmware/export/backlight.h b/firmware/export/backlight.h
index ab1f905..8d1b56c 100644
--- a/firmware/export/backlight.h
+++ b/firmware/export/backlight.h
@@ -27,6 +27,13 @@
 void backlight_tick(void);
 int  backlight_get_timeout(void);
 void backlight_set_timeout(int index);
+#if CONFIG_BACKLIGHT == BL_IRIVER
+void backlight_set_fade_in(int index);
+void backlight_set_fade_out(int index);
+void backlight_allow_timer(bool on);
+#else
+#define backlight_allow_timer(on)
+#endif
 bool backlight_get_on_when_charging(void);
 void backlight_set_on_when_charging(bool yesno);
 void remote_backlight_on(void);