/*
* 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],