* Karl Lessard <klessard@sunrisetelecom.com>
* <c.pellegrin@exadron.com>
*
+ * PM support added by Rodolfo Giometti <giometti@linux.it>
+ *
* Copyright 2002 MontaVista Software
* Author: MontaVista Software, Inc.
* ppopov@mvista.com or source@mvista.com
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
info->fix.visual = FB_VISUAL_TRUECOLOR;
info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */
- }
+ }
} else {
/* mono */
info->fix.visual = FB_VISUAL_MONO10;
}
info->screen_size = info->fix.line_length * info->var.yres_virtual;
+ info->var.rotate = ((fbdev->panel->control_base&LCD_CONTROL_SM_MASK) \
+ >> LCD_CONTROL_SM_BIT) * 90;
/* Determine BPP mode and format */
- fbdev->regs->lcd_control = fbdev->panel->control_base |
- ((info->var.rotate/90) << LCD_CONTROL_SM_BIT);
-
- fbdev->regs->lcd_intenable = 0;
- fbdev->regs->lcd_intstatus = 0;
-
+ fbdev->regs->lcd_control = fbdev->panel->control_base;
fbdev->regs->lcd_horztiming = fbdev->panel->horztiming;
-
fbdev->regs->lcd_verttiming = fbdev->panel->verttiming;
-
fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base;
-
+ fbdev->regs->lcd_intenable = 0;
+ fbdev->regs->lcd_intstatus = 0;
fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys);
if (panel_is_dual(fbdev->panel)) {
/* Resume controller */
fbdev->regs->lcd_control |= LCD_CONTROL_GO;
+ mdelay(10);
+ au1100fb_fb_blank(VESA_NO_BLANKING, info);
return 0;
}
return 0;
}
+#ifdef CONFIG_PM
+static u32 sys_clksrc;
+static struct au1100fb_regs fbregs;
+
int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
{
- /* TODO */
+ struct au1100fb_device *fbdev = dev_get_drvdata(dev);
+
+ if (!fbdev)
+ return 0;
+
+ /* Save the clock source state */
+ sys_clksrc = au_readl(SYS_CLKSRC);
+
+ /* Blank the LCD */
+ au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
+
+ /* Stop LCD clocking */
+ au_writel(sys_clksrc & ~SYS_CS_ML_MASK, SYS_CLKSRC);
+
+ memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs));
+
return 0;
}
int au1100fb_drv_resume(struct device *dev)
{
- /* TODO */
+ struct au1100fb_device *fbdev = dev_get_drvdata(dev);
+
+ if (!fbdev)
+ return 0;
+
+ memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs));
+
+ /* Restart LCD clocking */
+ au_writel(sys_clksrc, SYS_CLKSRC);
+
+ /* Unblank the LCD */
+ au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info);
+
return 0;
}
+#else
+#define au1100fb_drv_suspend NULL
+#define au1100fb_drv_resume NULL
+#endif
static struct device_driver au1100fb_driver = {
.name = "au1100-lcd",
{
driver_unregister(&au1100fb_driver);
- if (drv_info.opt_mode)
- kfree(drv_info.opt_mode);
+ kfree(drv_info.opt_mode);
}
module_init(au1100fb_init);