diff options
author | Alex Deucher <alex@t41p.hsd1.va.comcast.net> | 2007-05-26 01:38:09 -0400 |
---|---|---|
committer | Alex Deucher <alex@t41p.hsd1.va.comcast.net> | 2007-05-26 01:38:09 -0400 |
commit | 3a61453efb4f04492cef823b6dd1273b55c6a785 (patch) | |
tree | caf2858bd88a30fb523ec678c5adcc5864093207 | |
parent | ceec3f62257bafe4771e75d3c4f1d2a517d7acf8 (diff) |
RADEON: implement backlight control for LVDS
This code is currently disabled as I'm not sure which
laptops actually use this method for backlight control.
My laptop seems to use another method as adjusting the
backlight level doesn't seem to touch LVDS_GEN_CNTL.
Maybe just macs?
-rw-r--r-- | src/radeon_output.c | 51 | ||||
-rw-r--r-- | src/radeon_reg.h | 3 |
2 files changed, 48 insertions, 6 deletions
diff --git a/src/radeon_output.c b/src/radeon_output.c index 0ea6d650..c65798d0 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -391,9 +391,32 @@ radeon_destroy (xf86OutputPtr output) xfree(output->driver_private); } +static void +radeon_set_backlight_level(xf86OutputPtr output, int level) +{ + ScrnInfoPtr pScrn = output->scrn; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONOutputPrivatePtr radeon_output = output->driver_private; + unsigned char * RADEONMMIO = info->MMIO; + CARD32 lvds_gen_cntl; + +#if 0 + lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL); + lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; + lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_LEVEL_MASK; + lvds_gen_cntl |= (level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & RADEON_LVDS_BL_MOD_LEVEL_MASK; + //usleep (radeon_output->PanelPwrDly * 1000); + OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); + lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN; + //usleep (radeon_output->PanelPwrDly * 1000); + OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); +#endif +} + static Atom backlight_atom; static Atom rmx_atom; static Atom monitor_type_atom; +#define RADEON_MAX_BACKLIGHT_LEVEL 255 static void radeon_create_resources(xf86OutputPtr output) @@ -409,7 +432,7 @@ radeon_create_resources(xf86OutputPtr output) backlight_atom = MAKE_ATOM("BACKLIGHT"); range[0] = 0; - range[1] = 255; // i830_lvds_get_max_backlight(pScrn); + range[1] = RADEON_MAX_BACKLIGHT_LEVEL; err = RRConfigureOutputProperty(output->randr_output, backlight_atom, FALSE, TRUE, FALSE, 2, range); if (err != 0) { @@ -417,7 +440,8 @@ radeon_create_resources(xf86OutputPtr output) "RRConfigureOutputProperty error, %d\n", err); } /* Set the current value of the backlight property */ - data = 127; //pI830->backlight_duty_cycle; + //data = (info->SavedReg.lvds_gen_cntl & RADEON_LVDS_BL_MOD_LEVEL_MASK) >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT; + data = RADEON_MAX_BACKLIGHT_LEVEL; err = RRChangeOutputProperty(output->randr_output, backlight_atom, XA_INTEGER, 32, PropModeReplace, 1, &data, FALSE, TRUE); @@ -433,7 +457,7 @@ radeon_create_resources(xf86OutputPtr output) rmx_atom = MAKE_ATOM("PANELSCALER"); range[0] = 0; - range[1] = 2; // i830_lvds_get_max_backlight(pScrn); + range[1] = 2; err = RRConfigureOutputProperty(output->randr_output, rmx_atom, FALSE, TRUE, FALSE, 2, range); if (err != 0) { @@ -441,7 +465,7 @@ radeon_create_resources(xf86OutputPtr output) "RRConfigureOutputProperty error, %d\n", err); } /* Set the current value of the backlight property */ - data = 0; //pI830->backlight_duty_cycle; + data = 0; err = RRChangeOutputProperty(output->randr_output, rmx_atom, XA_INTEGER, 32, PropModeReplace, 1, &data, FALSE, TRUE); @@ -490,11 +514,25 @@ radeon_set_property(xf86OutputPtr output, Atom property, if (property == backlight_atom) { - return TRUE; + if (value->type != XA_INTEGER || + value->format != 32 || + value->size != 1) { + return FALSE; + } + + val = *(INT32 *)value->data; + if (val < 0 || val > RADEON_MAX_BACKLIGHT_LEVEL) + return FALSE; + +#if defined(__powerpc__) + val = RADEON_MAX_BACKLIGHT_LEVEL - val; +#endif + + radeon_set_backlight_level(output, val); + } else if (property == rmx_atom) { return TRUE; } else if (property == monitor_type_atom) { - if (value->type != XA_INTEGER || value->format != 32 || value->size != 1) { @@ -732,6 +770,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) } output->driver_private = radeon_output; output->possible_crtcs = 1; + /* crtc2 can drive LVDS, it just doesn't have RMX */ if (radeon_output->type != OUTPUT_LVDS) output->possible_crtcs |= 2; diff --git a/src/radeon_reg.h b/src/radeon_reg.h index b8bff780..892e8d0b 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -876,6 +876,9 @@ # define RADEON_LVDS_PANEL_TYPE (1 << 2) # define RADEON_LVDS_PANEL_FORMAT (1 << 3) # define RADEON_LVDS_EN (1 << 7) +# define RADEON_LVDS_BL_MOD_LEVEL_SHIFT 8 +# define RADEON_LVDS_BL_MOD_LEVEL_MASK (0xff << 8) +# define RADEON_LVDS_BL_MOD_EN (1 << 16) # define RADEON_LVDS_DIGON (1 << 18) # define RADEON_LVDS_BLON (1 << 19) # define RADEON_LVDS_SEL_CRTC2 (1 << 23) |