/*
 * linux/drivers/video/q40fb.c -- Q40 frame buffer device
 *
 * Copyright (C) 2001
 *
 *      Richard Zidlicky <rz@linux-m68k.org>
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License. See the file COPYING in the main directory of this archive for
 *  more details.
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>

#include <linux/uaccess.h>
#include <asm/setup.h>
#include <asm/q40_master.h>
#include <linux/fb.h>
#include <linux/module.h>

#define Q40_PHYS_SCREEN_ADDR 0xFE800000

static struct fb_fix_screeninfo q40fb_fix = {
	.id		= "Q40",
	.smem_len	= 1024*1024,
	.type		= FB_TYPE_PACKED_PIXELS,
	.visual		= FB_VISUAL_TRUECOLOR,
	.line_length	= 1024*2,
	.accel		= FB_ACCEL_NONE,
};

static const struct fb_var_screeninfo q40fb_var = {
	.xres		= 1024,
	.yres		= 512,
	.xres_virtual	= 1024,
	.yres_virtual	= 512,
	.bits_per_pixel	= 16,
    	.red		= {6, 5, 0},
	.green		= {11, 5, 0},
	.blue		= {0, 6, 0},
	.activate	= FB_ACTIVATE_NOW,
	.height		= 230,
	.width		= 300,
	.vmode		= FB_VMODE_NONINTERLACED,
};

static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green,
			   unsigned blue, unsigned transp,
			   struct fb_info *info)
{
    /*
     *  Set a single color register. The values supplied have a 16 bit
     *  magnitude.
     *  Return != 0 for invalid regno.
     */

    if (regno > 255)
	    return 1;
    red>>=11;
    green>>=11;
    blue>>=10;

    if (regno < 16) {
	((u32 *)info->pseudo_palette)[regno] = ((red & 31) <<6) |
					       ((green & 31) << 11) |
					       (blue & 63);
    }
    return 0;
}

static const struct fb_ops q40fb_ops = {
	.owner		= THIS_MODULE,
	.fb_setcolreg	= q40fb_setcolreg,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
};

static int q40fb_probe(struct platform_device *dev)
{
	struct fb_info *info;

	if (!MACH_IS_Q40)
		return -ENXIO;

	/* mapped in q40/config.c */
	q40fb_fix.smem_start = Q40_PHYS_SCREEN_ADDR;

	info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
	if (!info)
		return -ENOMEM;

	info->var = q40fb_var;
	info->fix = q40fb_fix;
	info->fbops = &q40fb_ops;
	info->flags = FBINFO_DEFAULT;  /* not as module for now */
	info->pseudo_palette = info->par;
	info->par = NULL;
	info->screen_base = (char *) q40fb_fix.smem_start;

	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
		framebuffer_release(info);
		return -ENOMEM;
	}

	master_outb(3, DISPLAY_CONTROL_REG);

	if (register_framebuffer(info) < 0) {
		printk(KERN_ERR "Unable to register Q40 frame buffer\n");
		fb_dealloc_cmap(&info->cmap);
		framebuffer_release(info);
		return -EINVAL;
	}

	fb_info(info, "Q40 frame buffer alive and kicking !\n");
	return 0;
}

static struct platform_driver q40fb_driver = {
	.probe	= q40fb_probe,
	.driver	= {
		.name	= "q40fb",
	},
};

static struct platform_device q40fb_device = {
	.name	= "q40fb",
};

int __init q40fb_init(void)
{
	int ret = 0;

	if (fb_get_options("q40fb", NULL))
		return -ENODEV;

	ret = platform_driver_register(&q40fb_driver);

	if (!ret) {
		ret = platform_device_register(&q40fb_device);
		if (ret)
			platform_driver_unregister(&q40fb_driver);
	}
	return ret;
}

module_init(q40fb_init);
MODULE_LICENSE("GPL");
