diff options
Diffstat (limited to 'drivers/mfd/glamo/glamo-fb.c')
-rw-r--r-- | drivers/mfd/glamo/glamo-fb.c | 109 |
1 files changed, 48 insertions, 61 deletions
diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c index 3e4a30755ac..19dcd71f371 100644 --- a/drivers/mfd/glamo/glamo-fb.c +++ b/drivers/mfd/glamo/glamo-fb.c @@ -75,6 +75,7 @@ struct glamofb_handle { int cursor_on; u_int32_t pseudo_pal[16]; spinlock_t lock_cmd; + int angle; /* Current rotation angle */ }; /* 'sibling' spi device for lcm init */ @@ -255,11 +256,6 @@ static void reg_set_bit_mask(struct glamofb_handle *glamo, #define GLAMO_LCD_HV_RETR_DISP_START_MASK 0x03FF #define GLAMO_LCD_HV_RETR_DISP_END_MASK 0x03FF -enum orientation { - ORIENTATION_PORTRAIT, - ORIENTATION_LANDSCAPE -}; - /* the caller has to enxure lock_cmd is held and we are in cmd mode */ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation) @@ -275,17 +271,22 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation) switch (rotation) { case FB_ROTATE_UR: glamo_rot = GLAMO_LCD_ROT_MODE_0; + glamo->angle = 0; break; case FB_ROTATE_CW: glamo_rot = GLAMO_LCD_ROT_MODE_90; + glamo->angle = 90; break; case FB_ROTATE_UD: glamo_rot = GLAMO_LCD_ROT_MODE_180; + glamo->angle = 180; break; case FB_ROTATE_CCW: glamo_rot = GLAMO_LCD_ROT_MODE_270; + glamo->angle = 270; break; default: + glamo->angle = 0; glamo_rot = GLAMO_LCD_ROT_MODE_0; break; } @@ -301,38 +302,12 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation) GLAMO_LCD_MODE1_ROTATE_EN : 0); } -static enum orientation get_orientation(struct fb_var_screeninfo *var) -{ - if (var->xres <= var->yres) - return ORIENTATION_PORTRAIT; - - return ORIENTATION_LANDSCAPE; -} - -static int will_orientation_change(struct fb_var_screeninfo *var) -{ - enum orientation orient = get_orientation(var); - - switch (orient) { - case ORIENTATION_LANDSCAPE: - if (var->rotate == FB_ROTATE_UR || - var->rotate == FB_ROTATE_UD) - return 1; - break; - case ORIENTATION_PORTRAIT: - if (var->rotate == FB_ROTATE_CW || - var->rotate == FB_ROTATE_CCW) - return 1; - break; - } - return 0; -} - static void glamofb_update_lcd_controller(struct glamofb_handle *glamo, struct fb_var_screeninfo *var) { - int sync, bp, disp, fp, total, xres, yres, pitch, orientation_changing; + int sync, bp, disp, fp, total, pitch; unsigned long flags; + int width, height; if (!glamo || !var) return; @@ -355,31 +330,52 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo, GLAMO_ENGINE_LCD, var->pixclock); - xres = var->xres; - yres = var->yres; + if (glamo->angle == 90 || glamo->angle == 270) { + /* + * But if we are going back to portrait mode from here, + * we get inverted values from Xglamo + */ + if (!(var->rotate == FB_ROTATE_UR || + var->rotate == FB_ROTATE_UD)) { + width = var->yres; + height = var->xres; + } else { + width = var->xres; + height = var->yres; + } - /* figure out if orientation is going to change */ - orientation_changing = will_orientation_change(var); + } else { + width = var->xres; + height = var->yres; + } - /* adjust the pitch according to new orientation to come */ + /* Portrait ? */ + if (var->rotate == FB_ROTATE_UR || var->rotate == FB_ROTATE_UD) { + /* We don't need to set xres and yres in this particular case + * because Xglamo does it for us */ + if (!(glamo->angle == 90 || glamo->angle == 270)) { + var->xres = width;var->yres = height; + } - if (orientation_changing) { - pitch = var->yres * var->bits_per_pixel / 8; - } else { - pitch = var->xres * var->bits_per_pixel / 8; - } + var->xres_virtual = width * 2; + var->yres_virtual = height; + pitch = width * var->bits_per_pixel / 8; + } else { + var->xres = height; + var->yres = width; + var->xres_virtual = height; + var->yres_virtual = width * 2; + pitch = height * var->bits_per_pixel / 8; + } - /* - * set the desired LCD geometry - */ reg_set_bit_mask(glamo, GLAMO_REG_LCD_WIDTH, GLAMO_LCD_WIDTH_MASK, - xres); + width); reg_set_bit_mask(glamo, GLAMO_REG_LCD_HEIGHT, GLAMO_LCD_HEIGHT_MASK, - yres); + height); reg_set_bit_mask(glamo, GLAMO_REG_LCD_PITCH, GLAMO_LCD_PITCH_MASK, @@ -388,22 +384,11 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo, /* honour the rotation request */ __rotate_lcd(glamo, var->rotate); - /* update the reported geometry of the framebuffer. */ - if (orientation_changing) { - var->xres_virtual = var->xres = yres; - var->xres_virtual *= 2; - var->yres_virtual = var->yres = xres; - } else { - var->xres_virtual = var->xres = xres; - var->yres_virtual = var->yres = yres; - var->yres_virtual *= 2; - } - /* update scannout timings */ sync = 0; bp = sync + var->hsync_len; disp = bp + var->left_margin; - fp = disp + xres; + fp = disp + width; total = fp + var->right_margin; reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_TOTAL, @@ -420,7 +405,7 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo, sync = 0; bp = sync + var->vsync_len; disp = bp + var->upper_margin; - fp = disp + yres; + fp = disp + height; total = fp + var->lower_margin; reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_TOTAL, @@ -836,6 +821,8 @@ static int __init glamofb_probe(struct platform_device *pdev) glamofb->fb = fbinfo; glamofb->dev = &pdev->dev; + glamofb->angle = 0; + strcpy(fbinfo->fix.id, "SMedia Glamo"); glamofb->reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, |