Index: firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c =================================================================== --- firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c (revision 19121) +++ firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c (working copy) @@ -65,28 +65,74 @@ }; #endif /* HAVE_BACKLIGHT_BRIGHTNESS */ +#define MC13783_LED_CONTROL0_BITS \ + (MC13783_LEDEN | MC13783_BOOSTEN | MC13783_ABMODE_MONCH_LEDMD1234 | \ + MC13783_ABREF_400MV) + +static int backlight_brightness; +static bool backlight_on_status = true; + bool _backlight_init(void) { - mc13783_write(MC13783_LED_CONTROL0, - MC13783_LEDEN | - MC13783_LEDMDRAMPUP | - MC13783_LEDMDRAMPDOWN | - MC13783_BOOSTEN | - MC13783_ABMODE_MONCH_LEDMD1234 | - MC13783_ABREF_400MV); + /* 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_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]; + + /* Set/clear LEDRAMPUP bit, clear LEDRAMPDOWN bit */ + data[0] = MC13783_LED_CONTROL0_BITS | + (backlight_on_status ? 0 : MC13783_LEDMDRAMPUP); + + backlight_on_status = true; + + /* Specify final PWM setting */ + data[1] = mc13783_read(MC13783_LED_CONTROL2); + + if (data[1] == (uint32_t)-1) + return; + + data[1] &= ~MC13783_LEDMDDC; + data[1] |= MC13783_LEDMDDCw(led_md_pwm_table[backlight_brightness].pwm); + + /* Write regs within 30uS of each other (requires single xfer) */ + mc13783_write_regset(regs, data, 2); } void _backlight_off(void) { - /* LEDEN=0 */ - mc13783_clear(MC13783_LED_CONTROL0, MC13783_LEDEN); + uint32_t ctrl0 = MC13783_LED_CONTROL0_BITS | + (backlight_on_status ? MC13783_LEDMDRAMPDOWN : 0); + uint32_t ctrl2 = mc13783_read(MC13783_LED_CONTROL2); + + backlight_on_status = false; + + if (ctrl2 == (uint32_t)-1) + return; + + ctrl2 = (ctrl2 & ~MC13783_LEDMDDC) | MC13783_LEDMDDCw(0); + + /* 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(MC13783_LED_CONTROL2, ctrl2); } #ifdef HAVE_BACKLIGHT_BRIGHTNESS @@ -103,6 +149,8 @@ if (data == (uint32_t)-1) return; + backlight_brightness = brightness; + md = led_md_pwm_table[brightness].md; pwm = led_md_pwm_table[brightness].pwm;