From f8b98a6a8afd6a95812781d83d67378735d11d28 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 23 Jul 2008 21:31:34 -0700 Subject: [PATCH] --- yaml --- r: 105551 b: refs/heads/master c: 968910bd03b226ed410d092c2da59dffe5bfe8de h: refs/heads/master i: 105549: 7004b8fcb0f14b51fb2eb9cf893d77f2a05bc948 105547: e3dda7e5483f8b89b91c7501dc5d0d663a8b73d1 105543: ba8f66196931acf45c0ea0af0e3291cabf4e5651 105535: 16a3840973a3772911e152efc38d89c795c53270 v: v3 --- [refs] | 2 +- trunk/drivers/video/atmel_lcdfb.c | 35 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 89ecd0b27416..fff87328f8eb 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 84c41ce83e9b2987ccef352f28ba0055b26c8f8e +refs/heads/master: 968910bd03b226ed410d092c2da59dffe5bfe8de diff --git a/trunk/drivers/video/atmel_lcdfb.c b/trunk/drivers/video/atmel_lcdfb.c index d335bb96b03b..5b3a15dffb5f 100644 --- a/trunk/drivers/video/atmel_lcdfb.c +++ b/trunk/drivers/video/atmel_lcdfb.c @@ -256,6 +256,20 @@ static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) return 0; } +static const struct fb_videomode *atmel_lcdfb_choose_mode(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct fb_videomode varfbmode; + const struct fb_videomode *fbmode = NULL; + + fb_var_to_videomode(&varfbmode, var); + fbmode = fb_find_nearest_mode(&varfbmode, &info->modelist); + if (fbmode) + fb_videomode_to_var(var, fbmode); + return fbmode; +} + + /** * atmel_lcdfb_check_var - Validates a var passed in. * @var: frame buffer variable screen structure @@ -289,6 +303,15 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; dev_dbg(dev, "%s:\n", __func__); + + if (!(var->pixclock && var->bits_per_pixel)) { + /* choose a suitable mode if possible */ + if (!atmel_lcdfb_choose_mode(var, info)) { + dev_err(dev, "needed value not specified\n"); + return -EINVAL; + } + } + dev_dbg(dev, " resolution: %ux%u\n", var->xres, var->yres); dev_dbg(dev, " pixclk: %lu KHz\n", PICOS2KHZ(var->pixclock)); dev_dbg(dev, " bpp: %u\n", var->bits_per_pixel); @@ -299,6 +322,13 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, return -EINVAL; } + /* Do not allow to have real resoulution larger than virtual */ + if (var->xres > var->xres_virtual) + var->xres_virtual = var->xres; + + if (var->yres > var->yres_virtual) + var->yres_virtual = var->yres; + /* Force same alignment for each line */ var->xres = (var->xres + 3) & ~3UL; var->xres_virtual = (var->xres_virtual + 3) & ~3UL; @@ -740,6 +770,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) struct fb_info *info; struct atmel_lcdfb_info *sinfo; struct atmel_lcdfb_info *pdata_sinfo; + struct fb_videomode fbmode; struct resource *regs = NULL; struct resource *map = NULL; int ret; @@ -906,6 +937,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) goto free_cmap; } + /* add selected videomode to modelist */ + fb_var_to_videomode(&fbmode, &info->var); + fb_add_videomode(&fbmode, &info->modelist); + /* Power up the LCDC screen */ if (sinfo->atmel_lcdfb_power_control) sinfo->atmel_lcdfb_power_control(1);