/*
 * fbsysfs.c - framebuffer device class and attributes
 *
 * Copyright (c) 2004 James Simmons <jsimmons@infradead.org>
 * 
 *	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.
 */

/*
 * Note:  currently there's only stubs for framebuffer_alloc and
 * framebuffer_release here.  The reson for that is that until all drivers
 * are converted to use it a sysfsification will open OOPSable races.
 */

#include <linux/kernel.h>
#include <linux/fb.h>
#include <linux/console.h>

/**
 * framebuffer_alloc - creates a new frame buffer info structure
 *
 * @size: size of driver private data, can be zero
 * @dev: pointer to the device for this fb, this can be NULL
 *
 * Creates a new frame buffer info structure. Also reserves @size bytes
 * for driver private data (info->par). info->par (if any) will be
 * aligned to sizeof(long).
 *
 * Returns the new structure, or NULL if an error occured.
 *
 */
struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
{
#define BYTES_PER_LONG (BITS_PER_LONG/8)
#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
	int fb_info_size = sizeof(struct fb_info);
	struct fb_info *info;
	char *p;

	if (size)
		fb_info_size += PADDING;

	p = kmalloc(fb_info_size + size, GFP_KERNEL);
	if (!p)
		return NULL;
	memset(p, 0, fb_info_size + size);
	info = (struct fb_info *) p;

	if (size)
		info->par = p + fb_info_size;

	info->device = dev;

	return info;
#undef PADDING
#undef BYTES_PER_LONG
}
EXPORT_SYMBOL(framebuffer_alloc);

/**
 * framebuffer_release - marks the structure available for freeing
 *
 * @info: frame buffer info structure
 *
 * Drop the reference count of the class_device embedded in the
 * framebuffer info structure.
 *
 */
void framebuffer_release(struct fb_info *info)
{
	kfree(info);
}
EXPORT_SYMBOL(framebuffer_release);

static int activate(struct fb_info *fb_info, struct fb_var_screeninfo *var)
{
	int err;

	var->activate |= FB_ACTIVATE_FORCE;
	acquire_console_sem();
	fb_info->flags |= FBINFO_MISC_USEREVENT;
	err = fb_set_var(fb_info, var);
	fb_info->flags &= ~FBINFO_MISC_USEREVENT;
	release_console_sem();
	if (err)
		return err;
	return 0;
}

static int mode_string(char *buf, unsigned int offset,
		       const struct fb_videomode *mode)
{
	char m = 'U';
	if (mode->flag & FB_MODE_IS_DETAILED)
		m = 'D';
	if (mode->flag & FB_MODE_IS_VESA)
		m = 'V';
	if (mode->flag & FB_MODE_IS_STANDARD)
		m = 'S';
	return snprintf(&buf[offset], PAGE_SIZE - offset, "%c:%dx%d-%d\n", m, mode->xres, mode->yres, mode->refresh);
}

static ssize_t store_mode(struct class_device *class_device, const char * buf,
			  size_t count)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	char mstr[100];
	struct fb_var_screeninfo var;
	struct fb_modelist *modelist;
	struct fb_videomode *mode;
	struct list_head *pos;
	size_t i;
	int err;

	memset(&var, 0, sizeof(var));

	list_for_each(pos, &fb_info->modelist) {
		modelist = list_entry(pos, struct fb_modelist, list);
		mode = &modelist->mode;
		i = mode_string(mstr, 0, mode);
		if (strncmp(mstr, buf, max(count, i)) == 0) {

			var = fb_info->var;
			fb_videomode_to_var(&var, mode);
			if ((err = activate(fb_info, &var)))
				return err;
			fb_info->mode = mode;
			return count;
		}
	}
	return -EINVAL;
}

static ssize_t show_mode(struct class_device *class_device, char *buf)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);

	if (!fb_info->mode)
		return 0;

	return mode_string(buf, 0, fb_info->mode);
}

static ssize_t store_modes(struct class_device *class_device, const char * buf,
			   size_t count)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	LIST_HEAD(old_list);
	int i = count / sizeof(struct fb_videomode);

	if (i * sizeof(struct fb_videomode) != count)
		return -EINVAL;

	acquire_console_sem();
	list_splice(&fb_info->modelist, &old_list);
	fb_videomode_to_modelist((struct fb_videomode *)buf, i,
				 &fb_info->modelist);
	if (fb_new_modelist(fb_info)) {
		fb_destroy_modelist(&fb_info->modelist);
		list_splice(&old_list, &fb_info->modelist);
	} else
		fb_destroy_modelist(&old_list);

	release_console_sem();

	return 0;
}

static ssize_t show_modes(struct class_device *class_device, char *buf)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	unsigned int i;
	struct list_head *pos;
	struct fb_modelist *modelist;
	const struct fb_videomode *mode;

	i = 0;
	list_for_each(pos, &fb_info->modelist) {
		modelist = list_entry(pos, struct fb_modelist, list);
		mode = &modelist->mode;
		i += mode_string(buf, i, mode);
	}
	return i;
}

static ssize_t store_bpp(struct class_device *class_device, const char * buf,
			 size_t count)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	struct fb_var_screeninfo var;
	char ** last = NULL;
	int err;

	var = fb_info->var;
	var.bits_per_pixel = simple_strtoul(buf, last, 0);
	if ((err = activate(fb_info, &var)))
		return err;
	return count;
}

static ssize_t show_bpp(struct class_device *class_device, char *buf)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel);
}

static ssize_t store_rotate(struct class_device *class_device, const char *buf,
			    size_t count)
{
	struct fb_info *fb_info = class_get_devdata(class_device);
	struct fb_var_screeninfo var;
	char **last = NULL;
	int err;

	var = fb_info->var;
	var.rotate = simple_strtoul(buf, last, 0);

	if ((err = activate(fb_info, &var)))
		return err;

	return count;
}


static ssize_t show_rotate(struct class_device *class_device, char *buf)
{
	struct fb_info *fb_info = class_get_devdata(class_device);

	return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate);
}

static ssize_t store_con_rotate(struct class_device *class_device,
				const char *buf, size_t count)
{
	struct fb_info *fb_info = class_get_devdata(class_device);
	int rotate;
	char **last = NULL;

	acquire_console_sem();
	rotate = simple_strtoul(buf, last, 0);
	fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE, &rotate);
	release_console_sem();
	return count;
}

static ssize_t store_con_rotate_all(struct class_device *class_device,
				const char *buf, size_t count)
{
	struct fb_info *fb_info = class_get_devdata(class_device);
	int rotate;
	char **last = NULL;

	acquire_console_sem();
	rotate = simple_strtoul(buf, last, 0);
	fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE_ALL, &rotate);
	release_console_sem();
	return count;
}

static ssize_t show_con_rotate(struct class_device *class_device, char *buf)
{
	struct fb_info *fb_info = class_get_devdata(class_device);
	int rotate;

	acquire_console_sem();
	rotate = fb_con_duit(fb_info, FB_EVENT_GET_CON_ROTATE, NULL);
	release_console_sem();
	return snprintf(buf, PAGE_SIZE, "%d\n", rotate);
}

static ssize_t store_virtual(struct class_device *class_device,
			     const char * buf, size_t count)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	struct fb_var_screeninfo var;
	char *last = NULL;
	int err;

	var = fb_info->var;
	var.xres_virtual = simple_strtoul(buf, &last, 0);
	last++;
	if (last - buf >= count)
		return -EINVAL;
	var.yres_virtual = simple_strtoul(last, &last, 0);

	if ((err = activate(fb_info, &var)))
		return err;
	return count;
}

static ssize_t show_virtual(struct class_device *class_device, char *buf)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual,
			fb_info->var.yres_virtual);
}

static ssize_t show_stride(struct class_device *class_device, char *buf)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length);
}

/* Format for cmap is "%02x%c%4x%4x%4x\n" */
/* %02x entry %c transp %4x red %4x blue %4x green \n */
/* 256 rows at 16 chars equals 4096, the normal page size */
/* the code will automatically adjust for different page sizes */
static ssize_t store_cmap(struct class_device *class_device, const char *buf,
			  size_t count)
{
	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
	int rc, i, start, length, transp = 0;

	if ((count > PAGE_SIZE) || ((count % 16) != 0))
		return -EINVAL;

	if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap)
		return -EINVAL;

	sscanf(buf, "%02x", &start);
	length = count / 16;

	for (i = 0; i < length; i++)
		if (buf[i * 16 + 2] != ' ')
			transp = 1;

	/* If we can batch, do it */
	if (fb_info->fbops->fb_setcmap && length > 1) {
		struct fb_cmap umap;

		memset(&umap, 0, sizeof(umap));
		if ((rc = fb_alloc_cmap(&umap, length, transp)))
			return rc;

		umap.start = start;
		for (i = 0; i < length; i++) {
			sscanf(&buf[i * 16 +  3], "%4hx", &umap.red[i]);
			sscanf(&buf[i * 16 +  7], "%4hx", &umap.blue[i]);
			sscanf(&buf[i * 16 + 11], "%4hx", &umap.green[i]);
			if (transp)
				umap.transp[i] = (buf[i * 16 +  2] != ' ');
		}
		rc = fb_info->fbops->fb_setcmap(&umap, fb_info);
		fb_copy_cmap(&umap, &fb_info->cmap);
		fb_dealloc_cmap(&umap);

		return rc;
	}
	for (i = 0; i < length; i++) {
		u16 red, blue, green, tsp;

		sscanf(&buf[i * 16 +  3], "%4hx", &red);
		sscanf(&buf[i * 16 +  7], "%4hx", &blue);
		sscanf(&buf[i * 16 + 11], "%4hx", &green);
		tsp = (buf[i * 16 +  2] != ' ');
		if ((rc = fb_info->fbops->fb_setcolreg(start++,
				      red, green, blue, tsp, fb_info)))
			return rc;

		fb_info->cmap.red[i] = red;
		fb_info->cmap.blue[i] = blue;
		fb_info->cmap.green[i] = green;
		if (transp)
			fb_info->cmap.transp[i] = tsp;
	}
	return 0;
}

static ssize_t show_cmap(struct class_device *class_device, char *buf)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	unsigned int i;

	if (!fb_info->cmap.red || !fb_info->cmap.blue ||
	   !fb_info->cmap.green)
		return -EINVAL;

	if (fb_info->cmap.len > PAGE_SIZE / 16)
		return -EINVAL;

	/* don't mess with the format, the buffer is PAGE_SIZE */
	/* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */
	for (i = 0; i < fb_info->cmap.len; i++) {
		snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start,
			((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '),
			fb_info->cmap.red[i], fb_info->cmap.blue[i],
			fb_info->cmap.green[i]);
	}
	return 16 * fb_info->cmap.len;
}

static ssize_t store_blank(struct class_device *class_device, const char * buf,
			   size_t count)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	char *last = NULL;
	int err;

	acquire_console_sem();
	fb_info->flags |= FBINFO_MISC_USEREVENT;
	err = fb_blank(fb_info, simple_strtoul(buf, &last, 0));
	fb_info->flags &= ~FBINFO_MISC_USEREVENT;
	release_console_sem();
	if (err < 0)
		return err;
	return count;
}

static ssize_t show_blank(struct class_device *class_device, char *buf)
{
//	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
	return 0;
}

static ssize_t store_console(struct class_device *class_device,
			     const char * buf, size_t count)
{
//	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
	return 0;
}

static ssize_t show_console(struct class_device *class_device, char *buf)
{
//	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
	return 0;
}

static ssize_t store_cursor(struct class_device *class_device,
			    const char * buf, size_t count)
{
//	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
	return 0;
}

static ssize_t show_cursor(struct class_device *class_device, char *buf)
{
//	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
	return 0;
}

static ssize_t store_pan(struct class_device *class_device, const char * buf,
			 size_t count)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	struct fb_var_screeninfo var;
	char *last = NULL;
	int err;

	var = fb_info->var;
	var.xoffset = simple_strtoul(buf, &last, 0);
	last++;
	if (last - buf >= count)
		return -EINVAL;
	var.yoffset = simple_strtoul(last, &last, 0);

	acquire_console_sem();
	err = fb_pan_display(fb_info, &var);
	release_console_sem();

	if (err < 0)
		return err;
	return count;
}

static ssize_t show_pan(struct class_device *class_device, char *buf)
{
	struct fb_info *fb_info =
		(struct fb_info *)class_get_devdata(class_device);
	return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset,
			fb_info->var.xoffset);
}

static ssize_t show_name(struct class_device *class_device, char *buf)
{
	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);

	return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id);
}

static struct class_device_attribute class_device_attrs[] = {
	__ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
	__ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
	__ATTR(color_map, S_IRUGO|S_IWUSR, show_cmap, store_cmap),
	__ATTR(console, S_IRUGO|S_IWUSR, show_console, store_console),
	__ATTR(cursor, S_IRUGO|S_IWUSR, show_cursor, store_cursor),
	__ATTR(mode, S_IRUGO|S_IWUSR, show_mode, store_mode),
	__ATTR(modes, S_IRUGO|S_IWUSR, show_modes, store_modes),
	__ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan),
	__ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
	__ATTR(name, S_IRUGO, show_name, NULL),
	__ATTR(stride, S_IRUGO, show_stride, NULL),
	__ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
	__ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate),
	__ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all),
};

int fb_init_class_device(struct fb_info *fb_info)
{
	unsigned int i;
	class_set_devdata(fb_info->class_device, fb_info);

	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
		class_device_create_file(fb_info->class_device,
					 &class_device_attrs[i]);
	return 0;
}

void fb_cleanup_class_device(struct fb_info *fb_info)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
		class_device_remove_file(fb_info->class_device,
					 &class_device_attrs[i]);
}


