/*
 *
 * Copyright (c) 2009 Nuvoton technology corporation
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 *  Description:
 *    Nuvoton LCD Controller Driver
 *  Author:
 *    Wang Qiang (rurality.linux@gmail.com) 2009/12/11
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/wait.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/io.h>
#include <linux/pm.h>
#include <linux/device.h>

#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-ldm.h>
#include <linux/platform_data/video-nuc900fb.h>

#include "nuc900fb.h"


/*
 *  Initialize the nuc900 video (dual) buffer address
 */
static void nuc900fb_set_lcdaddr(struct fb_info *info)
{
	struct nuc900fb_info *fbi = info->par;
	void __iomem *regs = fbi->io;
	unsigned long vbaddr1, vbaddr2;

	vbaddr1  = info->fix.smem_start;
	vbaddr2  = info->fix.smem_start;
	vbaddr2 += info->fix.line_length * info->var.yres;

	/* set frambuffer start phy addr*/
	writel(vbaddr1, regs + REG_LCM_VA_BADDR0);
	writel(vbaddr2, regs + REG_LCM_VA_BADDR1);

	writel(fbi->regs.lcd_va_fbctrl, regs + REG_LCM_VA_FBCTRL);
	writel(fbi->regs.lcd_va_scale, regs + REG_LCM_VA_SCALE);
}

/*
 *	calculate divider for lcd div
 */
static unsigned int nuc900fb_calc_pixclk(struct nuc900fb_info *fbi,
					 unsigned long pixclk)
{
	unsigned long clk = fbi->clk_rate;
	unsigned long long div;

	/* pixclk is in picseconds. our clock is in Hz*/
	/* div = (clk * pixclk)/10^12 */
	div = (unsigned long long)clk * pixclk;
	div >>= 12;
	do_div(div, 625 * 625UL * 625);

	dev_dbg(fbi->dev, "pixclk %ld, divisor is %lld\n", pixclk, div);

	return div;
}

/*
 *	Check the video params of 'var'.
 */
static int nuc900fb_check_var(struct fb_var_screeninfo *var,
			       struct fb_info *info)
{
	struct nuc900fb_info *fbi = info->par;
	struct nuc900fb_mach_info *mach_info = dev_get_platdata(fbi->dev);
	struct nuc900fb_display *display = NULL;
	struct nuc900fb_display *default_display = mach_info->displays +
						   mach_info->default_display;
	int i;

	dev_dbg(fbi->dev, "check_var(var=%p, info=%p)\n", var, info);

	/* validate x/y resolution */
	/* choose default mode if possible */
	if (var->xres == default_display->xres &&
	    var->yres == default_display->yres &&
	    var->bits_per_pixel == default_display->bpp)
		display = default_display;
	else
		for (i = 0; i < mach_info->num_displays; i++)
			if (var->xres == mach_info->displays[i].xres &&
			    var->yres == mach_info->displays[i].yres &&
			    var->bits_per_pixel == mach_info->displays[i].bpp) {
				display = mach_info->displays + i;
				break;
			}

	if (display == NULL) {
		printk(KERN_ERR "wrong resolution or depth %dx%d at %d bit per pixel\n",
			var->xres, var->yres, var->bits_per_pixel);
		return -EINVAL;
	}

	/* it should be the same size as the display */
	var->xres_virtual	= display->xres;
	var->yres_virtual	= display->yres;
	var->height		= display->height;
	var->width		= display->width;

	/* copy lcd settings */
	var->pixclock		= display->pixclock;
	var->left_margin	= display->left_margin;
	var->right_margin	= display->right_margin;
	var->upper_margin	= display->upper_margin;
	var->lower_margin	= display->lower_margin;
	var->vsync_len		= display->vsync_len;
	var->hsync_len		= display->hsync_len;

	var->transp.offset	= 0;
	var->transp.length	= 0;

	fbi->regs.lcd_dccs = display->dccs;
	fbi->regs.lcd_device_ctrl = display->devctl;
	fbi->regs.lcd_va_fbctrl = display->fbctrl;
	fbi->regs.lcd_va_scale = display->scale;

	/* set R/G/B possions */
	switch (var->bits_per_pixel) {
	case 1:
	case 2:
	case 4:
	case 8:
	default:
		var->red.offset 	= 0;
		var->red.length 	= var->bits_per_pixel;
		var->green 		= var->red;
		var->blue		= var->red;
		break;
	case 12:
		var->red.length		= 4;
		var->green.length	= 4;
		var->blue.length	= 4;
		var->red.offset		= 8;
		var->green.offset	= 4;
		var->blue.offset	= 0;
		break;
	case 16:
		var->red.length		= 5;
		var->green.length	= 6;
		var->blue.length	= 5;
		var->red.offset		= 11;
		var->green.offset	= 5;
		var->blue.offset	= 0;
		break;
	case 18:
		var->red.length		= 6;
		var->green.length	= 6;
		var->blue.length	= 6;
		var->red.offset		= 12;
		var->green.offset	= 6;
		var->blue.offset	= 0;
		break;
	case 32:
		var->red.length		= 8;
		var->green.length	= 8;
		var->blue.length	= 8;
		var->red.offset		= 16;
		var->green.offset	= 8;
		var->blue.offset	= 0;
		break;
	}

	return 0;
}

/*
 *	Calculate lcd register values from var setting & save into hw
 */
static void nuc900fb_calculate_lcd_regs(const struct fb_info *info,
					struct nuc900fb_hw *regs)
{
	const struct fb_var_screeninfo *var = &info->var;
	int vtt = var->height + var->upper_margin + var->lower_margin;
	int htt = var->width + var->left_margin + var->right_margin;
	int hsync = var->width + var->right_margin;
	int vsync = var->height + var->lower_margin;

	regs->lcd_crtc_size = LCM_CRTC_SIZE_VTTVAL(vtt) |
			      LCM_CRTC_SIZE_HTTVAL(htt);
	regs->lcd_crtc_dend = LCM_CRTC_DEND_VDENDVAL(var->height) |
			      LCM_CRTC_DEND_HDENDVAL(var->width);
	regs->lcd_crtc_hr = LCM_CRTC_HR_EVAL(var->width + 5) |
			    LCM_CRTC_HR_SVAL(var->width + 1);
	regs->lcd_crtc_hsync = LCM_CRTC_HSYNC_EVAL(hsync + var->hsync_len) |
			       LCM_CRTC_HSYNC_SVAL(hsync);
	regs->lcd_crtc_vr = LCM_CRTC_VR_EVAL(vsync + var->vsync_len) |
			    LCM_CRTC_VR_SVAL(vsync);

}

/*
 *	Activate (set) the controller from the given framebuffer
 *	information
 */
static void nuc900fb_activate_var(struct fb_info *info)
{
	struct nuc900fb_info *fbi = info->par;
	void __iomem *regs = fbi->io;
	struct fb_var_screeninfo *var = &info->var;
	int clkdiv;

	clkdiv = nuc900fb_calc_pixclk(fbi, var->pixclock) - 1;
	if (clkdiv < 0)
		clkdiv = 0;

	nuc900fb_calculate_lcd_regs(info, &fbi->regs);

	/* set the new lcd registers*/

	dev_dbg(fbi->dev, "new lcd register set:\n");
	dev_dbg(fbi->dev, "dccs       = 0x%08x\n", fbi->regs.lcd_dccs);
	dev_dbg(fbi->dev, "dev_ctl    = 0x%08x\n", fbi->regs.lcd_device_ctrl);
	dev_dbg(fbi->dev, "crtc_size  = 0x%08x\n", fbi->regs.lcd_crtc_size);
	dev_dbg(fbi->dev, "crtc_dend  = 0x%08x\n", fbi->regs.lcd_crtc_dend);
	dev_dbg(fbi->dev, "crtc_hr    = 0x%08x\n", fbi->regs.lcd_crtc_hr);
	dev_dbg(fbi->dev, "crtc_hsync = 0x%08x\n", fbi->regs.lcd_crtc_hsync);
	dev_dbg(fbi->dev, "crtc_vr    = 0x%08x\n", fbi->regs.lcd_crtc_vr);

	writel(fbi->regs.lcd_device_ctrl, regs + REG_LCM_DEV_CTRL);
	writel(fbi->regs.lcd_crtc_size, regs + REG_LCM_CRTC_SIZE);
	writel(fbi->regs.lcd_crtc_dend, regs + REG_LCM_CRTC_DEND);
	writel(fbi->regs.lcd_crtc_hr, regs + REG_LCM_CRTC_HR);
	writel(fbi->regs.lcd_crtc_hsync, regs + REG_LCM_CRTC_HSYNC);
	writel(fbi->regs.lcd_crtc_vr, regs + REG_LCM_CRTC_VR);

	/* set lcd address pointers */
	nuc900fb_set_lcdaddr(info);

	writel(fbi->regs.lcd_dccs, regs + REG_LCM_DCCS);
}

/*
 *      Alters the hardware state.
 *
 */
static int nuc900fb_set_par(struct fb_info *info)
{
	struct fb_var_screeninfo *var = &info->var;

	switch (var->bits_per_pixel) {
	case 32:
	case 24:
	case 18:
	case 16:
	case 12:
		info->fix.visual = FB_VISUAL_TRUECOLOR;
		break;
	case 1:
		info->fix.visual = FB_VISUAL_MONO01;
		break;
	default:
		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
		break;
	}

	info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;

	/* activate this new configuration */
	nuc900fb_activate_var(info);
	return 0;
}

static inline unsigned int chan_to_field(unsigned int chan,
					 struct fb_bitfield *bf)
{
	chan &= 0xffff;
	chan >>= 16 - bf->length;
	return chan << bf->offset;
}

static int nuc900fb_setcolreg(unsigned regno,
			       unsigned red, unsigned green, unsigned blue,
			       unsigned transp, struct fb_info *info)
{
	unsigned int val;

	switch (info->fix.visual) {
	case FB_VISUAL_TRUECOLOR:
		/* true-colour, use pseuo-palette */
		if (regno < 16) {
			u32 *pal = info->pseudo_palette;

			val  = chan_to_field(red, &info->var.red);
			val |= chan_to_field(green, &info->var.green);
			val |= chan_to_field(blue, &info->var.blue);
			pal[regno] = val;
		}
		break;

	default:
		return 1;   /* unknown type */
	}
	return 0;
}

/**
 *      nuc900fb_blank
 *
 */
static int nuc900fb_blank(int blank_mode, struct fb_info *info)
{

	return 0;
}

static struct fb_ops nuc900fb_ops = {
	.owner			= THIS_MODULE,
	.fb_check_var		= nuc900fb_check_var,
	.fb_set_par		= nuc900fb_set_par,
	.fb_blank		= nuc900fb_blank,
	.fb_setcolreg		= nuc900fb_setcolreg,
	.fb_fillrect		= cfb_fillrect,
	.fb_copyarea		= cfb_copyarea,
	.fb_imageblit		= cfb_imageblit,
};


static inline void modify_gpio(void __iomem *reg,
			       unsigned long set, unsigned long mask)
{
	unsigned long tmp;
	tmp = readl(reg) & ~mask;
	writel(tmp | set, reg);
}

/*
 * Initialise LCD-related registers
 */
static int nuc900fb_init_registers(struct fb_info *info)
{
	struct nuc900fb_info *fbi = info->par;
	struct nuc900fb_mach_info *mach_info = dev_get_platdata(fbi->dev);
	void __iomem *regs = fbi->io;

	/*reset the display engine*/
	writel(0, regs + REG_LCM_DCCS);
	writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_ENG_RST,
	       regs + REG_LCM_DCCS);
	ndelay(100);
	writel(readl(regs + REG_LCM_DCCS) & (~LCM_DCCS_ENG_RST),
	       regs + REG_LCM_DCCS);
	ndelay(100);

	writel(0, regs + REG_LCM_DEV_CTRL);

	/* config gpio output */
	modify_gpio(W90X900_VA_GPIO + 0x54, mach_info->gpio_dir,
		    mach_info->gpio_dir_mask);
	modify_gpio(W90X900_VA_GPIO + 0x58, mach_info->gpio_data,
		    mach_info->gpio_data_mask);

	return 0;
}


/*
 *    Alloc the SDRAM region of NUC900 for the frame buffer.
 *    The buffer should be a non-cached, non-buffered, memory region
 *    to allow palette and pixel writes without flushing the cache.
 */
static int nuc900fb_map_video_memory(struct fb_info *info)
{
	struct nuc900fb_info *fbi = info->par;
	dma_addr_t map_dma;
	unsigned long map_size = PAGE_ALIGN(info->fix.smem_len);

	dev_dbg(fbi->dev, "nuc900fb_map_video_memory(fbi=%p) map_size %lu\n",
		fbi, map_size);

	info->screen_base = dma_alloc_writecombine(fbi->dev, map_size,
							&map_dma, GFP_KERNEL);

	if (!info->screen_base)
		return -ENOMEM;

	memset(info->screen_base, 0x00, map_size);
	info->fix.smem_start = map_dma;

	return 0;
}

static inline void nuc900fb_unmap_video_memory(struct fb_info *info)
{
	struct nuc900fb_info *fbi = info->par;
	dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
			      info->screen_base, info->fix.smem_start);
}

static irqreturn_t nuc900fb_irqhandler(int irq, void *dev_id)
{
	struct nuc900fb_info *fbi = dev_id;
	void __iomem *regs = fbi->io;
	void __iomem *irq_base = fbi->irq_base;
	unsigned long lcdirq = readl(regs + REG_LCM_INT_CS);

	if (lcdirq & LCM_INT_CS_DISP_F_STATUS) {
		writel(readl(irq_base) | 1<<30, irq_base);

		/* wait VA_EN low */
		if ((readl(regs + REG_LCM_DCCS) &
		    LCM_DCCS_SINGLE) == LCM_DCCS_SINGLE)
			while ((readl(regs + REG_LCM_DCCS) &
			       LCM_DCCS_VA_EN) == LCM_DCCS_VA_EN)
				;
		/* display_out-enable */
		writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_DISP_OUT_EN,
			regs + REG_LCM_DCCS);
		/* va-enable*/
		writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_VA_EN,
			regs + REG_LCM_DCCS);
	} else if (lcdirq & LCM_INT_CS_UNDERRUN_INT) {
		writel(readl(irq_base) | LCM_INT_CS_UNDERRUN_INT, irq_base);
	} else if (lcdirq & LCM_INT_CS_BUS_ERROR_INT) {
		writel(readl(irq_base) | LCM_INT_CS_BUS_ERROR_INT, irq_base);
	}

	return IRQ_HANDLED;
}

#ifdef CONFIG_CPU_FREQ

static int nuc900fb_cpufreq_transition(struct notifier_block *nb,
				       unsigned long val, void *data)
{
	struct nuc900fb_info *info;
	struct fb_info *fbinfo;
	long delta_f;
	info = container_of(nb, struct nuc900fb_info, freq_transition);
	fbinfo = platform_get_drvdata(to_platform_device(info->dev));

	delta_f = info->clk_rate - clk_get_rate(info->clk);

	if ((val == CPUFREQ_POSTCHANGE && delta_f > 0) ||
	   (val == CPUFREQ_PRECHANGE && delta_f < 0)) {
		info->clk_rate = clk_get_rate(info->clk);
		nuc900fb_activate_var(fbinfo);
	}

	return 0;
}

static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi)
{
	fbi->freq_transition.notifier_call = nuc900fb_cpufreq_transition;
	return cpufreq_register_notifier(&fbi->freq_transition,
				  CPUFREQ_TRANSITION_NOTIFIER);
}

static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *fbi)
{
	cpufreq_unregister_notifier(&fbi->freq_transition,
				    CPUFREQ_TRANSITION_NOTIFIER);
}
#else
static inline int nuc900fb_cpufreq_transition(struct notifier_block *nb,
				       unsigned long val, void *data)
{
	return 0;
}

static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi)
{
	return 0;
}

static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *info)
{
}
#endif

static char driver_name[] = "nuc900fb";

static int nuc900fb_probe(struct platform_device *pdev)
{
	struct nuc900fb_info *fbi;
	struct nuc900fb_display *display;
	struct fb_info	   *fbinfo;
	struct nuc900fb_mach_info *mach_info;
	struct resource *res;
	int ret;
	int irq;
	int i;
	int size;

	dev_dbg(&pdev->dev, "devinit\n");
	mach_info = dev_get_platdata(&pdev->dev);
	if (mach_info == NULL) {
		dev_err(&pdev->dev,
			"no platform data for lcd, cannot attach\n");
		return -EINVAL;
	}

	if (mach_info->default_display > mach_info->num_displays) {
		dev_err(&pdev->dev,
			"default display No. is %d but only %d displays \n",
			mach_info->default_display, mach_info->num_displays);
		return -EINVAL;
	}


	display = mach_info->displays + mach_info->default_display;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "no irq for device\n");
		return -ENOENT;
	}

	fbinfo = framebuffer_alloc(sizeof(struct nuc900fb_info), &pdev->dev);
	if (!fbinfo)
		return -ENOMEM;

	platform_set_drvdata(pdev, fbinfo);

	fbi = fbinfo->par;
	fbi->dev = &pdev->dev;

#ifdef CONFIG_CPU_NUC950
	fbi->drv_type = LCDDRV_NUC950;
#endif

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	size = resource_size(res);
	fbi->mem = request_mem_region(res->start, size, pdev->name);
	if (fbi->mem == NULL) {
		dev_err(&pdev->dev, "failed to alloc memory region\n");
		ret = -ENOENT;
		goto free_fb;
	}

	fbi->io = ioremap(res->start, size);
	if (fbi->io == NULL) {
		dev_err(&pdev->dev, "ioremap() of lcd registers failed\n");
		ret = -ENXIO;
		goto release_mem_region;
	}

	fbi->irq_base = fbi->io + REG_LCM_INT_CS;


	/* Stop the LCD */
	writel(0, fbi->io + REG_LCM_DCCS);

	/* fill the fbinfo*/
	strcpy(fbinfo->fix.id, driver_name);
	fbinfo->fix.type		= FB_TYPE_PACKED_PIXELS;
	fbinfo->fix.type_aux		= 0;
	fbinfo->fix.xpanstep		= 0;
	fbinfo->fix.ypanstep		= 0;
	fbinfo->fix.ywrapstep		= 0;
	fbinfo->fix.accel		= FB_ACCEL_NONE;
	fbinfo->var.nonstd		= 0;
	fbinfo->var.activate		= FB_ACTIVATE_NOW;
	fbinfo->var.accel_flags		= 0;
	fbinfo->var.vmode		= FB_VMODE_NONINTERLACED;
	fbinfo->fbops			= &nuc900fb_ops;
	fbinfo->flags			= FBINFO_FLAG_DEFAULT;
	fbinfo->pseudo_palette		= &fbi->pseudo_pal;

	ret = request_irq(irq, nuc900fb_irqhandler, 0, pdev->name, fbi);
	if (ret) {
		dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n",
			irq, ret);
		ret = -EBUSY;
		goto release_regs;
	}

	fbi->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(fbi->clk)) {
		printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n");
		ret = PTR_ERR(fbi->clk);
		goto release_irq;
	}

	clk_enable(fbi->clk);
	dev_dbg(&pdev->dev, "got and enabled clock\n");

	fbi->clk_rate = clk_get_rate(fbi->clk);

	/* calutate the video buffer size */
	for (i = 0; i < mach_info->num_displays; i++) {
		unsigned long smem_len = mach_info->displays[i].xres;
		smem_len *= mach_info->displays[i].yres;
		smem_len *= mach_info->displays[i].bpp;
		smem_len >>= 3;
		if (fbinfo->fix.smem_len < smem_len)
			fbinfo->fix.smem_len = smem_len;
	}

	/* Initialize Video Memory */
	ret = nuc900fb_map_video_memory(fbinfo);
	if (ret) {
		printk(KERN_ERR "Failed to allocate video RAM: %x\n", ret);
		goto release_clock;
	}

	dev_dbg(&pdev->dev, "got video memory\n");

	fbinfo->var.xres = display->xres;
	fbinfo->var.yres = display->yres;
	fbinfo->var.bits_per_pixel = display->bpp;

	nuc900fb_init_registers(fbinfo);

	nuc900fb_check_var(&fbinfo->var, fbinfo);

	ret = nuc900fb_cpufreq_register(fbi);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to register cpufreq\n");
		goto free_video_memory;
	}

	ret = register_framebuffer(fbinfo);
	if (ret) {
		printk(KERN_ERR "failed to register framebuffer device: %d\n",
			ret);
		goto free_cpufreq;
	}

	fb_info(fbinfo, "%s frame buffer device\n", fbinfo->fix.id);

	return 0;

free_cpufreq:
	nuc900fb_cpufreq_deregister(fbi);
free_video_memory:
	nuc900fb_unmap_video_memory(fbinfo);
release_clock:
	clk_disable(fbi->clk);
	clk_put(fbi->clk);
release_irq:
	free_irq(irq, fbi);
release_regs:
	iounmap(fbi->io);
release_mem_region:
	release_mem_region(res->start, size);
free_fb:
	framebuffer_release(fbinfo);
	return ret;
}

/*
 * shutdown the lcd controller
 */
static void nuc900fb_stop_lcd(struct fb_info *info)
{
	struct nuc900fb_info *fbi = info->par;
	void __iomem *regs = fbi->io;

	writel((~LCM_DCCS_DISP_INT_EN) | (~LCM_DCCS_VA_EN) | (~LCM_DCCS_OSD_EN),
		regs + REG_LCM_DCCS);
}

/*
 *  Cleanup
 */
static int nuc900fb_remove(struct platform_device *pdev)
{
	struct fb_info *fbinfo = platform_get_drvdata(pdev);
	struct nuc900fb_info *fbi = fbinfo->par;
	int irq;

	nuc900fb_stop_lcd(fbinfo);
	msleep(1);

	unregister_framebuffer(fbinfo);
	nuc900fb_cpufreq_deregister(fbi);
	nuc900fb_unmap_video_memory(fbinfo);

	iounmap(fbi->io);

	irq = platform_get_irq(pdev, 0);
	free_irq(irq, fbi);

	release_resource(fbi->mem);
	kfree(fbi->mem);

	framebuffer_release(fbinfo);

	return 0;
}

#ifdef CONFIG_PM

/*
 *	suspend and resume support for the lcd controller
 */

static int nuc900fb_suspend(struct platform_device *dev, pm_message_t state)
{
	struct fb_info	   *fbinfo = platform_get_drvdata(dev);
	struct nuc900fb_info *info = fbinfo->par;

	nuc900fb_stop_lcd(fbinfo);
	msleep(1);
	clk_disable(info->clk);
	return 0;
}

static int nuc900fb_resume(struct platform_device *dev)
{
	struct fb_info	   *fbinfo = platform_get_drvdata(dev);
	struct nuc900fb_info *fbi = fbinfo->par;

	printk(KERN_INFO "nuc900fb resume\n");

	clk_enable(fbi->clk);
	msleep(1);

	nuc900fb_init_registers(fbinfo);
	nuc900fb_activate_var(fbinfo);

	return 0;
}

#else
#define nuc900fb_suspend NULL
#define nuc900fb_resume  NULL
#endif

static struct platform_driver nuc900fb_driver = {
	.probe		= nuc900fb_probe,
	.remove		= nuc900fb_remove,
	.suspend	= nuc900fb_suspend,
	.resume		= nuc900fb_resume,
	.driver		= {
		.name	= "nuc900-lcd",
		.owner	= THIS_MODULE,
	},
};

module_platform_driver(nuc900fb_driver);

MODULE_DESCRIPTION("Framebuffer driver for the NUC900");
MODULE_LICENSE("GPL");
