/*
 * Common code for AUO-K190X framebuffer drivers
 *
 * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/regulator/consumer.h>

#include <video/auo_k190xfb.h>

#include "auo_k190x.h"

struct panel_info {
	int w;
	int h;
};

/* table of panel specific parameters to be indexed into by the board drivers */
static struct panel_info panel_table[] = {
	/* standard 6" */
	[AUOK190X_RESOLUTION_800_600] = {
		.w = 800,
		.h = 600,
	},
	/* standard 9" */
	[AUOK190X_RESOLUTION_1024_768] = {
		.w = 1024,
		.h = 768,
	},
	[AUOK190X_RESOLUTION_600_800] = {
		.w = 600,
		.h = 800,
	},
	[AUOK190X_RESOLUTION_768_1024] = {
		.w = 768,
		.h = 1024,
	},
};

/*
 * private I80 interface to the board driver
 */

static void auok190x_issue_data(struct auok190xfb_par *par, u16 data)
{
	par->board->set_ctl(par, AUOK190X_I80_WR, 0);
	par->board->set_hdb(par, data);
	par->board->set_ctl(par, AUOK190X_I80_WR, 1);
}

static void auok190x_issue_cmd(struct auok190xfb_par *par, u16 data)
{
	par->board->set_ctl(par, AUOK190X_I80_DC, 0);
	auok190x_issue_data(par, data);
	par->board->set_ctl(par, AUOK190X_I80_DC, 1);
}

/**
 * Conversion of 16bit color to 4bit grayscale
 * does roughly (0.3 * R + 0.6 G + 0.1 B) / 2
 */
static inline int rgb565_to_gray4(u16 data, struct fb_var_screeninfo *var)
{
	return ((((data & 0xF800) >> var->red.offset) * 77 +
		 ((data & 0x07E0) >> (var->green.offset + 1)) * 151 +
		 ((data & 0x1F) >> var->blue.offset) * 28) >> 8 >> 1);
}

static int auok190x_issue_pixels_rgb565(struct auok190xfb_par *par, int size,
					u16 *data)
{
	struct fb_var_screeninfo *var = &par->info->var;
	struct device *dev = par->info->device;
	int i;
	u16 tmp;

	if (size & 7) {
		dev_err(dev, "issue_pixels: size %d must be a multiple of 8\n",
			size);
		return -EINVAL;
	}

	for (i = 0; i < (size >> 2); i++) {
		par->board->set_ctl(par, AUOK190X_I80_WR, 0);

		tmp  = (rgb565_to_gray4(data[4*i], var) & 0x000F);
		tmp |= (rgb565_to_gray4(data[4*i+1], var) << 4) & 0x00F0;
		tmp |= (rgb565_to_gray4(data[4*i+2], var) << 8) & 0x0F00;
		tmp |= (rgb565_to_gray4(data[4*i+3], var) << 12) & 0xF000;

		par->board->set_hdb(par, tmp);
		par->board->set_ctl(par, AUOK190X_I80_WR, 1);
	}

	return 0;
}

static int auok190x_issue_pixels_gray8(struct auok190xfb_par *par, int size,
				       u16 *data)
{
	struct device *dev = par->info->device;
	int i;
	u16 tmp;

	if (size & 3) {
		dev_err(dev, "issue_pixels: size %d must be a multiple of 4\n",
			size);
		return -EINVAL;
	}

	for (i = 0; i < (size >> 1); i++) {
		par->board->set_ctl(par, AUOK190X_I80_WR, 0);

		/* simple reduction of 8bit staticgray to 4bit gray
		 * combines 4 * 4bit pixel values into a 16bit value
		 */
		tmp  = (data[2*i] & 0xF0) >> 4;
		tmp |= (data[2*i] & 0xF000) >> 8;
		tmp |= (data[2*i+1] & 0xF0) << 4;
		tmp |= (data[2*i+1] & 0xF000);

		par->board->set_hdb(par, tmp);
		par->board->set_ctl(par, AUOK190X_I80_WR, 1);
	}

	return 0;
}

static int auok190x_issue_pixels(struct auok190xfb_par *par, int size,
				 u16 *data)
{
	struct fb_info *info = par->info;
	struct device *dev = par->info->device;

	if (info->var.bits_per_pixel == 8 && info->var.grayscale)
		auok190x_issue_pixels_gray8(par, size, data);
	else if (info->var.bits_per_pixel == 16)
		auok190x_issue_pixels_rgb565(par, size, data);
	else
		dev_err(dev, "unsupported color mode (bits: %d, gray: %d)\n",
			info->var.bits_per_pixel, info->var.grayscale);

	return 0;
}

static u16 auok190x_read_data(struct auok190xfb_par *par)
{
	u16 data;

	par->board->set_ctl(par, AUOK190X_I80_OE, 0);
	data = par->board->get_hdb(par);
	par->board->set_ctl(par, AUOK190X_I80_OE, 1);

	return data;
}

/*
 * Command interface for the controller drivers
 */

void auok190x_send_command_nowait(struct auok190xfb_par *par, u16 data)
{
	par->board->set_ctl(par, AUOK190X_I80_CS, 0);
	auok190x_issue_cmd(par, data);
	par->board->set_ctl(par, AUOK190X_I80_CS, 1);
}
EXPORT_SYMBOL_GPL(auok190x_send_command_nowait);

void auok190x_send_cmdargs_nowait(struct auok190xfb_par *par, u16 cmd,
				  int argc, u16 *argv)
{
	int i;

	par->board->set_ctl(par, AUOK190X_I80_CS, 0);
	auok190x_issue_cmd(par, cmd);

	for (i = 0; i < argc; i++)
		auok190x_issue_data(par, argv[i]);
	par->board->set_ctl(par, AUOK190X_I80_CS, 1);
}
EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_nowait);

int auok190x_send_command(struct auok190xfb_par *par, u16 data)
{
	int ret;

	ret = par->board->wait_for_rdy(par);
	if (ret)
		return ret;

	auok190x_send_command_nowait(par, data);
	return 0;
}
EXPORT_SYMBOL_GPL(auok190x_send_command);

int auok190x_send_cmdargs(struct auok190xfb_par *par, u16 cmd,
			   int argc, u16 *argv)
{
	int ret;

	ret = par->board->wait_for_rdy(par);
	if (ret)
		return ret;

	auok190x_send_cmdargs_nowait(par, cmd, argc, argv);
	return 0;
}
EXPORT_SYMBOL_GPL(auok190x_send_cmdargs);

int auok190x_read_cmdargs(struct auok190xfb_par *par, u16 cmd,
			   int argc, u16 *argv)
{
	int i, ret;

	ret = par->board->wait_for_rdy(par);
	if (ret)
		return ret;

	par->board->set_ctl(par, AUOK190X_I80_CS, 0);
	auok190x_issue_cmd(par, cmd);

	for (i = 0; i < argc; i++)
		argv[i] = auok190x_read_data(par);
	par->board->set_ctl(par, AUOK190X_I80_CS, 1);

	return 0;
}
EXPORT_SYMBOL_GPL(auok190x_read_cmdargs);

void auok190x_send_cmdargs_pixels_nowait(struct auok190xfb_par *par, u16 cmd,
				  int argc, u16 *argv, int size, u16 *data)
{
	int i;

	par->board->set_ctl(par, AUOK190X_I80_CS, 0);

	auok190x_issue_cmd(par, cmd);

	for (i = 0; i < argc; i++)
		auok190x_issue_data(par, argv[i]);

	auok190x_issue_pixels(par, size, data);

	par->board->set_ctl(par, AUOK190X_I80_CS, 1);
}
EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_pixels_nowait);

int auok190x_send_cmdargs_pixels(struct auok190xfb_par *par, u16 cmd,
				  int argc, u16 *argv, int size, u16 *data)
{
	int ret;

	ret = par->board->wait_for_rdy(par);
	if (ret)
		return ret;

	auok190x_send_cmdargs_pixels_nowait(par, cmd, argc, argv, size, data);

	return 0;
}
EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_pixels);

/*
 * fbdefio callbacks - common on both controllers.
 */

static void auok190xfb_dpy_first_io(struct fb_info *info)
{
	/* tell runtime-pm that we wish to use the device in a short time */
	pm_runtime_get(info->device);
}

/* this is called back from the deferred io workqueue */
static void auok190xfb_dpy_deferred_io(struct fb_info *info,
				struct list_head *pagelist)
{
	struct fb_deferred_io *fbdefio = info->fbdefio;
	struct auok190xfb_par *par = info->par;
	u16 line_length = info->fix.line_length;
	u16 yres = info->var.yres;
	u16 y1 = 0, h = 0;
	int prev_index = -1;
	struct page *cur;
	int h_inc;
	int threshold;

	if (!list_empty(pagelist))
		/* the device resume should've been requested through first_io,
		 * if the resume did not finish until now, wait for it.
		 */
		pm_runtime_barrier(info->device);
	else
		/* We reached this via the fsync or some other way.
		 * In either case the first_io function did not run,
		 * so we runtime_resume the device here synchronously.
		 */
		pm_runtime_get_sync(info->device);

	/* Do a full screen update every n updates to prevent
	 * excessive darkening of the Sipix display.
	 * If we do this, there is no need to walk the pages.
	 */
	if (par->need_refresh(par)) {
		par->update_all(par);
		goto out;
	}

	/* height increment is fixed per page */
	h_inc = DIV_ROUND_UP(PAGE_SIZE , line_length);

	/* calculate number of pages from pixel height */
	threshold = par->consecutive_threshold / h_inc;
	if (threshold < 1)
		threshold = 1;

	/* walk the written page list and swizzle the data */
	list_for_each_entry(cur, &fbdefio->pagelist, lru) {
		if (prev_index < 0) {
			/* just starting so assign first page */
			y1 = (cur->index << PAGE_SHIFT) / line_length;
			h = h_inc;
		} else if ((cur->index - prev_index) <= threshold) {
			/* page is within our threshold for single updates */
			h += h_inc * (cur->index - prev_index);
		} else {
			/* page not consecutive, issue previous update first */
			par->update_partial(par, y1, y1 + h);

			/* start over with our non consecutive page */
			y1 = (cur->index << PAGE_SHIFT) / line_length;
			h = h_inc;
		}
		prev_index = cur->index;
	}

	/* if we still have any pages to update we do so now */
	if (h >= yres)
		/* its a full screen update, just do it */
		par->update_all(par);
	else
		par->update_partial(par, y1, min((u16) (y1 + h), yres));

out:
	pm_runtime_mark_last_busy(info->device);
	pm_runtime_put_autosuspend(info->device);
}

/*
 * framebuffer operations
 */

/*
 * this is the slow path from userspace. they can seek and write to
 * the fb. it's inefficient to do anything less than a full screen draw
 */
static ssize_t auok190xfb_write(struct fb_info *info, const char __user *buf,
				size_t count, loff_t *ppos)
{
	struct auok190xfb_par *par = info->par;
	unsigned long p = *ppos;
	void *dst;
	int err = 0;
	unsigned long total_size;

	if (info->state != FBINFO_STATE_RUNNING)
		return -EPERM;

	total_size = info->fix.smem_len;

	if (p > total_size)
		return -EFBIG;

	if (count > total_size) {
		err = -EFBIG;
		count = total_size;
	}

	if (count + p > total_size) {
		if (!err)
			err = -ENOSPC;

		count = total_size - p;
	}

	dst = (void *)(info->screen_base + p);

	if (copy_from_user(dst, buf, count))
		err = -EFAULT;

	if  (!err)
		*ppos += count;

	par->update_all(par);

	return (err) ? err : count;
}

static void auok190xfb_fillrect(struct fb_info *info,
				   const struct fb_fillrect *rect)
{
	struct auok190xfb_par *par = info->par;

	sys_fillrect(info, rect);

	par->update_all(par);
}

static void auok190xfb_copyarea(struct fb_info *info,
				   const struct fb_copyarea *area)
{
	struct auok190xfb_par *par = info->par;

	sys_copyarea(info, area);

	par->update_all(par);
}

static void auok190xfb_imageblit(struct fb_info *info,
				const struct fb_image *image)
{
	struct auok190xfb_par *par = info->par;

	sys_imageblit(info, image);

	par->update_all(par);
}

static int auok190xfb_check_var(struct fb_var_screeninfo *var,
				   struct fb_info *info)
{
	struct device *dev = info->device;
	struct auok190xfb_par *par = info->par;
	struct panel_info *panel = &panel_table[par->resolution];
	int size;

	/*
	 * Color depth
	 */

	if (var->bits_per_pixel == 8 && var->grayscale == 1) {
		/*
		 * For 8-bit grayscale, R, G, and B offset are equal.
		 */
		var->red.length = 8;
		var->red.offset = 0;
		var->red.msb_right = 0;

		var->green.length = 8;
		var->green.offset = 0;
		var->green.msb_right = 0;

		var->blue.length = 8;
		var->blue.offset = 0;
		var->blue.msb_right = 0;

		var->transp.length = 0;
		var->transp.offset = 0;
		var->transp.msb_right = 0;
	} else if (var->bits_per_pixel == 16) {
		var->red.length = 5;
		var->red.offset = 11;
		var->red.msb_right = 0;

		var->green.length = 6;
		var->green.offset = 5;
		var->green.msb_right = 0;

		var->blue.length = 5;
		var->blue.offset = 0;
		var->blue.msb_right = 0;

		var->transp.length = 0;
		var->transp.offset = 0;
		var->transp.msb_right = 0;
	} else {
		dev_warn(dev, "unsupported color mode (bits: %d, grayscale: %d)\n",
			info->var.bits_per_pixel, info->var.grayscale);
		return -EINVAL;
	}

	/*
	 * Dimensions
	 */

	switch (var->rotate) {
	case FB_ROTATE_UR:
	case FB_ROTATE_UD:
		var->xres = panel->w;
		var->yres = panel->h;
		break;
	case FB_ROTATE_CW:
	case FB_ROTATE_CCW:
		var->xres = panel->h;
		var->yres = panel->w;
		break;
	default:
		dev_dbg(dev, "Invalid rotation request\n");
		return -EINVAL;
	}

	var->xres_virtual = var->xres;
	var->yres_virtual = var->yres;

	/*
	 *  Memory limit
	 */

	size = var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8;
	if (size > info->fix.smem_len) {
		dev_err(dev, "Memory limit exceeded, requested %dK\n",
			size >> 10);
		return -ENOMEM;
	}

	return 0;
}

static int auok190xfb_set_fix(struct fb_info *info)
{
	struct fb_fix_screeninfo *fix = &info->fix;
	struct fb_var_screeninfo *var = &info->var;

	fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;

	fix->type = FB_TYPE_PACKED_PIXELS;
	fix->accel = FB_ACCEL_NONE;
	fix->visual = (var->grayscale) ? FB_VISUAL_STATIC_PSEUDOCOLOR
				       : FB_VISUAL_TRUECOLOR;
	fix->xpanstep = 0;
	fix->ypanstep = 0;
	fix->ywrapstep = 0;

	return 0;
}

static int auok190xfb_set_par(struct fb_info *info)
{
	struct auok190xfb_par *par = info->par;

	par->rotation = info->var.rotate;
	auok190xfb_set_fix(info);

	/* reinit the controller to honor the rotation */
	par->init(par);

	/* wait for init to complete */
	par->board->wait_for_rdy(par);

	return 0;
}

static struct fb_ops auok190xfb_ops = {
	.owner		= THIS_MODULE,
	.fb_read	= fb_sys_read,
	.fb_write	= auok190xfb_write,
	.fb_fillrect	= auok190xfb_fillrect,
	.fb_copyarea	= auok190xfb_copyarea,
	.fb_imageblit	= auok190xfb_imageblit,
	.fb_check_var	= auok190xfb_check_var,
	.fb_set_par     = auok190xfb_set_par,
};

/*
 * Controller-functions common to both K1900 and K1901
 */

static int auok190x_read_temperature(struct auok190xfb_par *par)
{
	struct device *dev = par->info->device;
	u16 data[4];
	int temp;

	pm_runtime_get_sync(dev);

	mutex_lock(&(par->io_lock));

	auok190x_read_cmdargs(par, AUOK190X_CMD_READ_VERSION, 4, data);

	mutex_unlock(&(par->io_lock));

	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);

	/* sanitize and split of half-degrees for now */
	temp = ((data[0] & AUOK190X_VERSION_TEMP_MASK) >> 1);

	/* handle positive and negative temperatures */
	if (temp >= 201)
		return (255 - temp + 1) * (-1);
	else
		return temp;
}

static void auok190x_identify(struct auok190xfb_par *par)
{
	struct device *dev = par->info->device;
	u16 data[4];

	pm_runtime_get_sync(dev);

	mutex_lock(&(par->io_lock));

	auok190x_read_cmdargs(par, AUOK190X_CMD_READ_VERSION, 4, data);

	mutex_unlock(&(par->io_lock));

	par->epd_type = data[1] & AUOK190X_VERSION_TEMP_MASK;

	par->panel_size_int = AUOK190X_VERSION_SIZE_INT(data[2]);
	par->panel_size_float = AUOK190X_VERSION_SIZE_FLOAT(data[2]);
	par->panel_model = AUOK190X_VERSION_MODEL(data[2]);

	par->tcon_version = AUOK190X_VERSION_TCON(data[3]);
	par->lut_version = AUOK190X_VERSION_LUT(data[3]);

	dev_dbg(dev, "panel %d.%din, model 0x%x, EPD 0x%x TCON-rev 0x%x, LUT-rev 0x%x",
		par->panel_size_int, par->panel_size_float, par->panel_model,
		par->epd_type, par->tcon_version, par->lut_version);

	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);
}

/*
 * Sysfs functions
 */

static ssize_t update_mode_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct fb_info *info = dev_get_drvdata(dev);
	struct auok190xfb_par *par = info->par;

	return sprintf(buf, "%d\n", par->update_mode);
}

static ssize_t update_mode_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct fb_info *info = dev_get_drvdata(dev);
	struct auok190xfb_par *par = info->par;
	int mode, ret;

	ret = kstrtoint(buf, 10, &mode);
	if (ret)
		return ret;

	par->update_mode = mode;

	/* if we enter a better mode, do a full update */
	if (par->last_mode > 1 && mode < par->last_mode)
		par->update_all(par);

	return count;
}

static ssize_t flash_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	struct fb_info *info = dev_get_drvdata(dev);
	struct auok190xfb_par *par = info->par;

	return sprintf(buf, "%d\n", par->flash);
}

static ssize_t flash_store(struct device *dev, struct device_attribute *attr,
			   const char *buf, size_t count)
{
	struct fb_info *info = dev_get_drvdata(dev);
	struct auok190xfb_par *par = info->par;
	int flash, ret;

	ret = kstrtoint(buf, 10, &flash);
	if (ret)
		return ret;

	if (flash > 0)
		par->flash = 1;
	else
		par->flash = 0;

	return count;
}

static ssize_t temp_show(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct fb_info *info = dev_get_drvdata(dev);
	struct auok190xfb_par *par = info->par;
	int temp;

	temp = auok190x_read_temperature(par);
	return sprintf(buf, "%d\n", temp);
}

static DEVICE_ATTR(update_mode, 0644, update_mode_show, update_mode_store);
static DEVICE_ATTR(flash, 0644, flash_show, flash_store);
static DEVICE_ATTR(temp, 0644, temp_show, NULL);

static struct attribute *auok190x_attributes[] = {
	&dev_attr_update_mode.attr,
	&dev_attr_flash.attr,
	&dev_attr_temp.attr,
	NULL
};

static const struct attribute_group auok190x_attr_group = {
	.attrs		= auok190x_attributes,
};

static int auok190x_power(struct auok190xfb_par *par, bool on)
{
	struct auok190x_board *board = par->board;
	int ret;

	if (on) {
		/* We should maintain POWER up for at least 80ms before set
		 * RST_N and SLP_N to high (TCON spec 20100803_v35 p59)
		 */
		ret = regulator_enable(par->regulator);
		if (ret)
			return ret;

		msleep(200);
		gpio_set_value(board->gpio_nrst, 1);
		gpio_set_value(board->gpio_nsleep, 1);
		msleep(200);
	} else {
		regulator_disable(par->regulator);
		gpio_set_value(board->gpio_nrst, 0);
		gpio_set_value(board->gpio_nsleep, 0);
	}

	return 0;
}

/*
 * Recovery - powercycle the controller
 */

static void auok190x_recover(struct auok190xfb_par *par)
{
	struct device *dev = par->info->device;

	auok190x_power(par, 0);
	msleep(100);
	auok190x_power(par, 1);

	/* after powercycling the device, it's always active */
	pm_runtime_set_active(dev);
	par->standby = 0;

	par->init(par);

	/* wait for init to complete */
	par->board->wait_for_rdy(par);
}

/*
 * Power-management
 */

#ifdef CONFIG_PM
static int auok190x_runtime_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct fb_info *info = platform_get_drvdata(pdev);
	struct auok190xfb_par *par = info->par;
	struct auok190x_board *board = par->board;
	u16 standby_param;

	/* take and keep the lock until we are resumed, as the controller
	 * will never reach the non-busy state when in standby mode
	 */
	mutex_lock(&(par->io_lock));

	if (par->standby) {
		dev_warn(dev, "already in standby, runtime-pm pairing mismatch\n");
		mutex_unlock(&(par->io_lock));
		return 0;
	}

	/* according to runtime_pm.txt runtime_suspend only means, that the
	 * device will not process data and will not communicate with the CPU
	 * As we hold the lock, this stays true even without standby
	 */
	if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
		dev_dbg(dev, "runtime suspend without standby\n");
		goto finish;
	} else if (board->quirks & AUOK190X_QUIRK_STANDBYPARAM) {
		/* for some TCON versions STANDBY expects a parameter (0) but
		 * it seems the real tcon version has to be determined yet.
		 */
		dev_dbg(dev, "runtime suspend with additional empty param\n");
		standby_param = 0;
		auok190x_send_cmdargs(par, AUOK190X_CMD_STANDBY, 1,
				      &standby_param);
	} else {
		dev_dbg(dev, "runtime suspend without param\n");
		auok190x_send_command(par, AUOK190X_CMD_STANDBY);
	}

	msleep(64);

finish:
	par->standby = 1;

	return 0;
}

static int auok190x_runtime_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct fb_info *info = platform_get_drvdata(pdev);
	struct auok190xfb_par *par = info->par;
	struct auok190x_board *board = par->board;

	if (!par->standby) {
		dev_warn(dev, "not in standby, runtime-pm pairing mismatch\n");
		return 0;
	}

	if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
		dev_dbg(dev, "runtime resume without standby\n");
	} else {
		/* when in standby, controller is always busy
		 * and only accepts the wakeup command
		 */
		dev_dbg(dev, "runtime resume from standby\n");
		auok190x_send_command_nowait(par, AUOK190X_CMD_WAKEUP);

		msleep(160);

		/* wait for the controller to be ready and release the lock */
		board->wait_for_rdy(par);
	}

	par->standby = 0;

	mutex_unlock(&(par->io_lock));

	return 0;
}

static int auok190x_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct fb_info *info = platform_get_drvdata(pdev);
	struct auok190xfb_par *par = info->par;
	struct auok190x_board *board = par->board;
	int ret;

	dev_dbg(dev, "suspend\n");
	if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
		/* suspend via powering off the ic */
		dev_dbg(dev, "suspend with broken standby\n");

		auok190x_power(par, 0);
	} else {
		dev_dbg(dev, "suspend using sleep\n");

		/* the sleep state can only be entered from the standby state.
		 * pm_runtime_get_noresume gets called before the suspend call.
		 * So the devices usage count is >0 but it is not necessarily
		 * active.
		 */
		if (!pm_runtime_status_suspended(dev)) {
			ret = auok190x_runtime_suspend(dev);
			if (ret < 0) {
				dev_err(dev, "auok190x_runtime_suspend failed with %d\n",
					ret);
				return ret;
			}
			par->manual_standby = 1;
		}

		gpio_direction_output(board->gpio_nsleep, 0);
	}

	msleep(100);

	return 0;
}

static int auok190x_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct fb_info *info = platform_get_drvdata(pdev);
	struct auok190xfb_par *par = info->par;
	struct auok190x_board *board = par->board;

	dev_dbg(dev, "resume\n");
	if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
		dev_dbg(dev, "resume with broken standby\n");

		auok190x_power(par, 1);

		par->init(par);
	} else {
		dev_dbg(dev, "resume from sleep\n");

		/* device should be in runtime suspend when we were suspended
		 * and pm_runtime_put_sync gets called after this function.
		 * So there is no need to touch the standby mode here at all.
		 */
		gpio_direction_output(board->gpio_nsleep, 1);
		msleep(100);

		/* an additional init call seems to be necessary after sleep */
		auok190x_runtime_resume(dev);
		par->init(par);

		/* if we were runtime-suspended before, suspend again*/
		if (!par->manual_standby)
			auok190x_runtime_suspend(dev);
		else
			par->manual_standby = 0;
	}

	return 0;
}
#endif

const struct dev_pm_ops auok190x_pm = {
	SET_RUNTIME_PM_OPS(auok190x_runtime_suspend, auok190x_runtime_resume,
			   NULL)
	SET_SYSTEM_SLEEP_PM_OPS(auok190x_suspend, auok190x_resume)
};
EXPORT_SYMBOL_GPL(auok190x_pm);

/*
 * Common probe and remove code
 */

int auok190x_common_probe(struct platform_device *pdev,
			  struct auok190x_init_data *init)
{
	struct auok190x_board *board = init->board;
	struct auok190xfb_par *par;
	struct fb_info *info;
	struct panel_info *panel;
	int videomemorysize, ret;
	unsigned char *videomemory;

	/* check board contents */
	if (!board->init || !board->cleanup || !board->wait_for_rdy
	    || !board->set_ctl || !board->set_hdb || !board->get_hdb
	    || !board->setup_irq)
		return -EINVAL;

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

	par = info->par;
	par->info = info;
	par->board = board;
	par->recover = auok190x_recover;
	par->update_partial = init->update_partial;
	par->update_all = init->update_all;
	par->need_refresh = init->need_refresh;
	par->init = init->init;

	/* init update modes */
	par->update_cnt = 0;
	par->update_mode = -1;
	par->last_mode = -1;
	par->flash = 0;

	par->regulator = regulator_get(info->device, "vdd");
	if (IS_ERR(par->regulator)) {
		ret = PTR_ERR(par->regulator);
		dev_err(info->device, "Failed to get regulator: %d\n", ret);
		goto err_reg;
	}

	ret = board->init(par);
	if (ret) {
		dev_err(info->device, "board init failed, %d\n", ret);
		goto err_board;
	}

	ret = gpio_request(board->gpio_nsleep, "AUOK190x sleep");
	if (ret) {
		dev_err(info->device, "could not request sleep gpio, %d\n",
			ret);
		goto err_gpio1;
	}

	ret = gpio_direction_output(board->gpio_nsleep, 0);
	if (ret) {
		dev_err(info->device, "could not set sleep gpio, %d\n", ret);
		goto err_gpio2;
	}

	ret = gpio_request(board->gpio_nrst, "AUOK190x reset");
	if (ret) {
		dev_err(info->device, "could not request reset gpio, %d\n",
			ret);
		goto err_gpio2;
	}

	ret = gpio_direction_output(board->gpio_nrst, 0);
	if (ret) {
		dev_err(info->device, "could not set reset gpio, %d\n", ret);
		goto err_gpio3;
	}

	ret = auok190x_power(par, 1);
	if (ret) {
		dev_err(info->device, "could not power on the device, %d\n",
			ret);
		goto err_gpio3;
	}

	mutex_init(&par->io_lock);

	init_waitqueue_head(&par->waitq);

	ret = par->board->setup_irq(par->info);
	if (ret) {
		dev_err(info->device, "could not setup ready-irq, %d\n", ret);
		goto err_irq;
	}

	/* wait for init to complete */
	par->board->wait_for_rdy(par);

	/*
	 * From here on the controller can talk to us
	 */

	/* initialise fix, var, resolution and rotation */

	strlcpy(info->fix.id, init->id, 16);
	info->var.bits_per_pixel = 8;
	info->var.grayscale = 1;

	panel = &panel_table[board->resolution];

	par->resolution = board->resolution;
	par->rotation = 0;

	/* videomemory handling */

	videomemorysize = roundup((panel->w * panel->h) * 2, PAGE_SIZE);
	videomemory = vmalloc(videomemorysize);
	if (!videomemory) {
		ret = -ENOMEM;
		goto err_irq;
	}

	memset(videomemory, 0, videomemorysize);
	info->screen_base = (char *)videomemory;
	info->fix.smem_len = videomemorysize;

	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
	info->fbops = &auok190xfb_ops;

	ret = auok190xfb_check_var(&info->var, info);
	if (ret)
		goto err_defio;

	auok190xfb_set_fix(info);

	/* deferred io init */

	info->fbdefio = devm_kzalloc(info->device,
				     sizeof(struct fb_deferred_io),
				     GFP_KERNEL);
	if (!info->fbdefio) {
		dev_err(info->device, "Failed to allocate memory\n");
		ret = -ENOMEM;
		goto err_defio;
	}

	dev_dbg(info->device, "targeting %d frames per second\n", board->fps);
	info->fbdefio->delay = HZ / board->fps;
	info->fbdefio->first_io = auok190xfb_dpy_first_io,
	info->fbdefio->deferred_io = auok190xfb_dpy_deferred_io,
	fb_deferred_io_init(info);

	/* color map */

	ret = fb_alloc_cmap(&info->cmap, 256, 0);
	if (ret < 0) {
		dev_err(info->device, "Failed to allocate colormap\n");
		goto err_cmap;
	}

	/* controller init */

	par->consecutive_threshold = 100;
	par->init(par);
	auok190x_identify(par);

	platform_set_drvdata(pdev, info);

	ret = register_framebuffer(info);
	if (ret < 0)
		goto err_regfb;

	ret = sysfs_create_group(&info->device->kobj, &auok190x_attr_group);
	if (ret)
		goto err_sysfs;

	dev_info(info->device, "fb%d: %dx%d using %dK of video memory\n",
		 info->node, info->var.xres, info->var.yres,
		 videomemorysize >> 10);

	/* increase autosuspend_delay when we use alternative methods
	 * for runtime_pm
	 */
	par->autosuspend_delay = (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN)
					? 1000 : 200;

	pm_runtime_set_active(info->device);
	pm_runtime_enable(info->device);
	pm_runtime_set_autosuspend_delay(info->device, par->autosuspend_delay);
	pm_runtime_use_autosuspend(info->device);

	return 0;

err_sysfs:
	unregister_framebuffer(info);
err_regfb:
	fb_dealloc_cmap(&info->cmap);
err_cmap:
	fb_deferred_io_cleanup(info);
err_defio:
	vfree((void *)info->screen_base);
err_irq:
	auok190x_power(par, 0);
err_gpio3:
	gpio_free(board->gpio_nrst);
err_gpio2:
	gpio_free(board->gpio_nsleep);
err_gpio1:
	board->cleanup(par);
err_board:
	regulator_put(par->regulator);
err_reg:
	framebuffer_release(info);

	return ret;
}
EXPORT_SYMBOL_GPL(auok190x_common_probe);

int  auok190x_common_remove(struct platform_device *pdev)
{
	struct fb_info *info = platform_get_drvdata(pdev);
	struct auok190xfb_par *par = info->par;
	struct auok190x_board *board = par->board;

	pm_runtime_disable(info->device);

	sysfs_remove_group(&info->device->kobj, &auok190x_attr_group);

	unregister_framebuffer(info);

	fb_dealloc_cmap(&info->cmap);

	fb_deferred_io_cleanup(info);

	vfree((void *)info->screen_base);

	auok190x_power(par, 0);

	gpio_free(board->gpio_nrst);
	gpio_free(board->gpio_nsleep);

	board->cleanup(par);

	regulator_put(par->regulator);

	framebuffer_release(info);

	return 0;
}
EXPORT_SYMBOL_GPL(auok190x_common_remove);

MODULE_DESCRIPTION("Common code for AUO-K190X controllers");
MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
MODULE_LICENSE("GPL");
