/*
 * linux/drivers/video/arcfb.c -- FB driver for Arc monochrome LCD board
 *
 * Copyright (C) 2005, Jaya Kumar <jayalk@intworks.biz>
 *
 * 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.
 *
 * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
 *
 * This driver was written to be used with the Arc LCD board. Arc uses a
 * set of KS108 chips that control individual 64x64 LCD matrices. The board
 * can be paneled in a variety of setups such as 2x1=128x64, 4x4=256x256 and
 * so on. The interface between the board and the host is TTL based GPIO. The
 * GPIO requirements are 8 writable data lines and 4+n lines for control. On a
 * GPIO-less system, the board can be tested by connecting the respective sigs
 * up to a parallel port connector. The driver requires the IO addresses for
 * data and control GPIO at load time. It is unable to probe for the
 * existence of the LCD so it must be told at load time whether it should
 * be enabled or not.
 *
 * Todo:
 * - testing with 4x4
 * - testing with interrupt hw
 *
 * General notes:
 * - User must set tuhold. It's in microseconds. According to the 108 spec,
 *   the hold time is supposed to be at least 1 microsecond.
 * - User must set num_cols=x num_rows=y, eg: x=2 means 128
 * - User must set arcfb_enable=1 to enable it
 * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/arcfb.h>
#include <linux/platform_device.h>

#include <linux/uaccess.h>

#define floor8(a) (a&(~0x07))
#define floorXres(a,xres) (a&(~(xres - 1)))
#define iceil8(a) (((int)((a+7)/8))*8)
#define ceil64(a) (a|0x3F)
#define ceilXres(a,xres) (a|(xres - 1))

/* ks108 chipset specific defines and code */

#define KS_SET_DPY_START_LINE 	0xC0
#define KS_SET_PAGE_NUM 	0xB8
#define KS_SET_X 		0x40
#define KS_CEHI 		0x01
#define KS_CELO 		0x00
#define KS_SEL_CMD 		0x08
#define KS_SEL_DATA 		0x00
#define KS_DPY_ON 		0x3F
#define KS_DPY_OFF 		0x3E
#define KS_INTACK 		0x40
#define KS_CLRINT		0x02

struct arcfb_par {
	unsigned long dio_addr;
	unsigned long cio_addr;
	unsigned long c2io_addr;
	atomic_t ref_count;
	unsigned char cslut[9];
	struct fb_info *info;
	unsigned int irq;
	spinlock_t lock;
};

static const struct fb_fix_screeninfo arcfb_fix = {
	.id =		"arcfb",
	.type =		FB_TYPE_PACKED_PIXELS,
	.visual =	FB_VISUAL_MONO01,
	.xpanstep =	0,
	.ypanstep =	1,
	.ywrapstep =	0,
	.accel =	FB_ACCEL_NONE,
};

static const struct fb_var_screeninfo arcfb_var = {
	.xres		= 128,
	.yres		= 64,
	.xres_virtual	= 128,
	.yres_virtual	= 64,
	.bits_per_pixel	= 1,
	.nonstd		= 1,
};

static unsigned long num_cols;
static unsigned long num_rows;
static unsigned long dio_addr;
static unsigned long cio_addr;
static unsigned long c2io_addr;
static unsigned long splashval;
static unsigned long tuhold;
static unsigned int nosplash;
static unsigned int arcfb_enable;
static unsigned int irq;

static DECLARE_WAIT_QUEUE_HEAD(arcfb_waitq);

static void ks108_writeb_ctl(struct arcfb_par *par,
				unsigned int chipindex, unsigned char value)
{
	unsigned char chipselval = par->cslut[chipindex];

	outb(chipselval|KS_CEHI|KS_SEL_CMD, par->cio_addr);
	outb(value, par->dio_addr);
	udelay(tuhold);
	outb(chipselval|KS_CELO|KS_SEL_CMD, par->cio_addr);
}

static void ks108_writeb_mainctl(struct arcfb_par *par, unsigned char value)
{

	outb(value, par->cio_addr);
	udelay(tuhold);
}

static unsigned char ks108_readb_ctl2(struct arcfb_par *par)
{
	return inb(par->c2io_addr);
}

static void ks108_writeb_data(struct arcfb_par *par,
				unsigned int chipindex, unsigned char value)
{
	unsigned char chipselval = par->cslut[chipindex];

	outb(chipselval|KS_CEHI|KS_SEL_DATA, par->cio_addr);
	outb(value, par->dio_addr);
	udelay(tuhold);
	outb(chipselval|KS_CELO|KS_SEL_DATA, par->cio_addr);
}

static void ks108_set_start_line(struct arcfb_par *par,
				unsigned int chipindex, unsigned char y)
{
	ks108_writeb_ctl(par, chipindex, KS_SET_DPY_START_LINE|y);
}

static void ks108_set_yaddr(struct arcfb_par *par,
				unsigned int chipindex, unsigned char y)
{
	ks108_writeb_ctl(par, chipindex, KS_SET_PAGE_NUM|y);
}

static void ks108_set_xaddr(struct arcfb_par *par,
				unsigned int chipindex, unsigned char x)
{
	ks108_writeb_ctl(par, chipindex, KS_SET_X|x);
}

static void ks108_clear_lcd(struct arcfb_par *par, unsigned int chipindex)
{
	int i,j;

	for (i = 0; i <= 8; i++) {
		ks108_set_yaddr(par, chipindex, i);
		ks108_set_xaddr(par, chipindex, 0);
		for (j = 0; j < 64; j++) {
			ks108_writeb_data(par, chipindex,
				(unsigned char) splashval);
		}
	}
}

/* main arcfb functions */

static int arcfb_open(struct fb_info *info, int user)
{
	struct arcfb_par *par = info->par;

	atomic_inc(&par->ref_count);
	return 0;
}

static int arcfb_release(struct fb_info *info, int user)
{
	struct arcfb_par *par = info->par;
	int count = atomic_read(&par->ref_count);

	if (!count)
		return -EINVAL;
	atomic_dec(&par->ref_count);
	return 0;
}

static int arcfb_pan_display(struct fb_var_screeninfo *var,
				struct fb_info *info)
{
	int i;
	struct arcfb_par *par = info->par;

	if ((var->vmode & FB_VMODE_YWRAP) && (var->yoffset < 64)
		&& (info->var.yres <= 64)) {
		for (i = 0; i < num_cols; i++) {
			ks108_set_start_line(par, i, var->yoffset);
		}
		info->var.yoffset = var->yoffset;
		return 0;
	}

	return -EINVAL;
}

static irqreturn_t arcfb_interrupt(int vec, void *dev_instance)
{
	struct fb_info *info = dev_instance;
	unsigned char ctl2status;
	struct arcfb_par *par = info->par;

	ctl2status = ks108_readb_ctl2(par);

	if (!(ctl2status & KS_INTACK)) /* not arc generated interrupt */
		return IRQ_NONE;

	ks108_writeb_mainctl(par, KS_CLRINT);

	spin_lock(&par->lock);
        if (waitqueue_active(&arcfb_waitq)) {
                wake_up(&arcfb_waitq);
        }
	spin_unlock(&par->lock);

	return IRQ_HANDLED;
}

/*
 * here we handle a specific page on the lcd. the complexity comes from
 * the fact that the fb is laidout in 8xX vertical columns. we extract
 * each write of 8 vertical pixels. then we shift out as we move along
 * X. That's what rightshift does. bitmask selects the desired input bit.
 */
static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper,
		unsigned int left, unsigned int right, unsigned int distance)
{
	unsigned char *src;
	unsigned int xindex, yindex, chipindex, linesize;
	int i;
	unsigned char val;
	unsigned char bitmask, rightshift;

	xindex = left >> 6;
	yindex = upper >> 6;
	chipindex = (xindex + (yindex*num_cols));

	ks108_set_yaddr(par, chipindex, upper/8);

	linesize = par->info->var.xres/8;
	src = (unsigned char *)par->info->screen_buffer + (left/8) +
		(upper * linesize);
	ks108_set_xaddr(par, chipindex, left);

	bitmask=1;
	rightshift=0;
	while (left <= right) {
		val = 0;
		for (i = 0; i < 8; i++) {
			if ( i > rightshift) {
				val |= (*(src + (i*linesize)) & bitmask)
						<< (i - rightshift);
			} else {
				val |= (*(src + (i*linesize)) & bitmask)
						 >> (rightshift - i);
			}
		}
		ks108_writeb_data(par, chipindex, val);
		left++;
		if (bitmask == 0x80) {
			bitmask = 1;
			src++;
			rightshift=0;
		} else {
			bitmask <<= 1;
			rightshift++;
		}
	}
}

/*
 * here we handle the entire vertical page of the update. we write across
 * lcd chips. update_page uses the upper/left values to decide which
 * chip to select for the right. upper is needed for setting the page
 * desired for the write.
 */
static void arcfb_lcd_update_vert(struct arcfb_par *par, unsigned int top,
		unsigned int bottom, unsigned int left, unsigned int right)
{
	unsigned int distance, upper, lower;

	distance = (bottom - top) + 1;
	upper = top;
	lower = top + 7;

	while (distance > 0) {
		distance -= 8;
		arcfb_lcd_update_page(par, upper, left, right, 8);
		upper = lower + 1;
		lower = upper + 7;
	}
}

/*
 * here we handle horizontal blocks for the update. update_vert will
 * handle spaning multiple pages. we break out each horizontal
 * block in to individual blocks no taller than 64 pixels.
 */
static void arcfb_lcd_update_horiz(struct arcfb_par *par, unsigned int left,
			unsigned int right, unsigned int top, unsigned int h)
{
	unsigned int distance, upper, lower;

	distance = h;
	upper = floor8(top);
	lower = min(upper + distance - 1, ceil64(upper));

	while (distance > 0) {
		distance -= ((lower - upper) + 1 );
		arcfb_lcd_update_vert(par, upper, lower, left, right);
		upper = lower + 1;
		lower = min(upper + distance - 1, ceil64(upper));
	}
}

/*
 * here we start the process of splitting out the fb update into
 * individual blocks of pixels. we end up splitting into 64x64 blocks
 * and finally down to 64x8 pages.
 */
static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx,
			unsigned int dy, unsigned int w, unsigned int h)
{
	unsigned int left, right, distance, y;

	/* align the request first */
	y = floor8(dy);
	h += dy - y;
	h = iceil8(h);

	distance = w;
	left = dx;
	right = min(left + w - 1, ceil64(left));

	while (distance > 0) {
		arcfb_lcd_update_horiz(par, left, right, y, h);
		distance -= ((right - left) + 1);
		left = right + 1;
		right = min(left + distance - 1, ceil64(left));
	}
}

static int arcfb_ioctl(struct fb_info *info,
			  unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	struct arcfb_par *par = info->par;
	unsigned long flags;

	switch (cmd) {
		case FBIO_WAITEVENT:
		{
			DEFINE_WAIT(wait);
			/* illegal to wait on arc if no irq will occur */
			if (!par->irq)
				return -EINVAL;

			/* wait until the Arc has generated an interrupt
			 * which will wake us up */
			spin_lock_irqsave(&par->lock, flags);
			prepare_to_wait(&arcfb_waitq, &wait,
					TASK_INTERRUPTIBLE);
			spin_unlock_irqrestore(&par->lock, flags);
			schedule();
			finish_wait(&arcfb_waitq, &wait);
		}
		fallthrough;

		case FBIO_GETCONTROL2:
		{
			unsigned char ctl2;

			ctl2 = ks108_readb_ctl2(info->par);
			if (copy_to_user(argp, &ctl2, sizeof(ctl2)))
				return -EFAULT;
			return 0;
		}
		default:
			return -EINVAL;
	}
}

static void arcfb_damage_range(struct fb_info *info, off_t off, size_t len)
{
	struct arcfb_par *par = info->par;
	unsigned int xres = info->var.xres;
	unsigned int bitppos, startpos, endpos, bitcount;
	unsigned int x, y, width, height;

	bitppos = off * 8;
	startpos = floorXres(bitppos, xres);
	endpos = ceilXres((bitppos + (len * 8)), xres);
	bitcount = endpos - startpos;

	x = startpos % xres;
	y = startpos / xres;
	width = xres;
	height = bitcount / xres;

	arcfb_lcd_update(par, x, y, width, height);
}

static void arcfb_damage_area(struct fb_info *info, u32 x, u32 y,
			      u32 width, u32 height)
{
	struct arcfb_par *par = info->par;

	/* update the physical lcd */
	arcfb_lcd_update(par, x, y, width, height);
}

FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(arcfb,
				   arcfb_damage_range,
				   arcfb_damage_area)

static const struct fb_ops arcfb_ops = {
	.owner		= THIS_MODULE,
	.fb_open	= arcfb_open,
	__FB_DEFAULT_DEFERRED_OPS_RDWR(arcfb),
	.fb_release	= arcfb_release,
	.fb_pan_display	= arcfb_pan_display,
	__FB_DEFAULT_DEFERRED_OPS_DRAW(arcfb),
	.fb_ioctl 	= arcfb_ioctl,
	// .fb_mmap reqires deferred I/O
};

static int arcfb_probe(struct platform_device *dev)
{
	struct fb_info *info;
	int retval = -ENOMEM;
	int videomemorysize;
	unsigned char *videomemory;
	struct arcfb_par *par;
	int i;

	videomemorysize = (((64*64)*num_cols)*num_rows)/8;

	/* We need a flat backing store for the Arc's
	   less-flat actual paged framebuffer */
	videomemory = vzalloc(videomemorysize);
	if (!videomemory)
		return retval;

	info = framebuffer_alloc(sizeof(struct arcfb_par), &dev->dev);
	if (!info)
		goto err_fb_alloc;

	info->flags |= FBINFO_VIRTFB;
	info->screen_buffer = videomemory;
	info->fbops = &arcfb_ops;

	info->var = arcfb_var;
	info->fix = arcfb_fix;
	par = info->par;
	par->info = info;

	if (!dio_addr || !cio_addr || !c2io_addr) {
		printk(KERN_WARNING "no IO addresses supplied\n");
		goto err_addr;
	}
	par->dio_addr = dio_addr;
	par->cio_addr = cio_addr;
	par->c2io_addr = c2io_addr;
	par->cslut[0] = 0x00;
	par->cslut[1] = 0x06;
	spin_lock_init(&par->lock);
	if (irq) {
		par->irq = irq;
		if (request_irq(par->irq, &arcfb_interrupt, IRQF_SHARED,
				"arcfb", info)) {
			printk(KERN_INFO
				"arcfb: Failed req IRQ %d\n", par->irq);
			retval = -EBUSY;
			goto err_addr;
		}
	}
	retval = register_framebuffer(info);
	if (retval < 0)
		goto err_register_fb;
	platform_set_drvdata(dev, info);
	fb_info(info, "Arc frame buffer device, using %dK of video memory\n",
		videomemorysize >> 10);

	/* this inits the lcd but doesn't clear dirty pixels */
	for (i = 0; i < num_cols * num_rows; i++) {
		ks108_writeb_ctl(par, i, KS_DPY_OFF);
		ks108_set_start_line(par, i, 0);
		ks108_set_yaddr(par, i, 0);
		ks108_set_xaddr(par, i, 0);
		ks108_writeb_ctl(par, i, KS_DPY_ON);
	}

	/* if we were told to splash the screen, we just clear it */
	if (!nosplash) {
		for (i = 0; i < num_cols * num_rows; i++) {
			fb_info(info, "splashing lcd %d\n", i);
			ks108_set_start_line(par, i, 0);
			ks108_clear_lcd(par, i);
		}
	}

	return 0;

err_register_fb:
	free_irq(par->irq, info);
err_addr:
	framebuffer_release(info);
err_fb_alloc:
	vfree(videomemory);
	return retval;
}

static void arcfb_remove(struct platform_device *dev)
{
	struct fb_info *info = platform_get_drvdata(dev);

	if (info) {
		unregister_framebuffer(info);
		if (irq)
			free_irq(((struct arcfb_par *)(info->par))->irq, info);
		vfree(info->screen_buffer);
		framebuffer_release(info);
	}
}

static struct platform_driver arcfb_driver = {
	.probe	= arcfb_probe,
	.remove_new = arcfb_remove,
	.driver	= {
		.name	= "arcfb",
	},
};

static struct platform_device *arcfb_device;

static int __init arcfb_init(void)
{
	int ret;

	if (!arcfb_enable)
		return -ENXIO;

	ret = platform_driver_register(&arcfb_driver);
	if (!ret) {
		arcfb_device = platform_device_alloc("arcfb", 0);
		if (arcfb_device) {
			ret = platform_device_add(arcfb_device);
		} else {
			ret = -ENOMEM;
		}
		if (ret) {
			platform_device_put(arcfb_device);
			platform_driver_unregister(&arcfb_driver);
		}
	}
	return ret;

}

static void __exit arcfb_exit(void)
{
	platform_device_unregister(arcfb_device);
	platform_driver_unregister(&arcfb_driver);
}

module_param(num_cols, ulong, 0);
MODULE_PARM_DESC(num_cols, "Num horiz panels, eg: 2 = 128 bit wide");
module_param(num_rows, ulong, 0);
MODULE_PARM_DESC(num_rows, "Num vert panels, eg: 1 = 64 bit high");
module_param(nosplash, uint, 0);
MODULE_PARM_DESC(nosplash, "Disable doing the splash screen");
module_param(arcfb_enable, uint, 0);
MODULE_PARM_DESC(arcfb_enable, "Enable communication with Arc board");
module_param_hw(dio_addr, ulong, ioport, 0);
MODULE_PARM_DESC(dio_addr, "IO address for data, eg: 0x480");
module_param_hw(cio_addr, ulong, ioport, 0);
MODULE_PARM_DESC(cio_addr, "IO address for control, eg: 0x400");
module_param_hw(c2io_addr, ulong, ioport, 0);
MODULE_PARM_DESC(c2io_addr, "IO address for secondary control, eg: 0x408");
module_param(splashval, ulong, 0);
MODULE_PARM_DESC(splashval, "Splash pattern: 0xFF is black, 0x00 is green");
module_param(tuhold, ulong, 0);
MODULE_PARM_DESC(tuhold, "Time to hold between strobing data to Arc board");
module_param_hw(irq, uint, irq, 0);
MODULE_PARM_DESC(irq, "IRQ for the Arc board");

module_init(arcfb_init);
module_exit(arcfb_exit);

MODULE_DESCRIPTION("fbdev driver for Arc monochrome LCD board");
MODULE_AUTHOR("Jaya Kumar");
MODULE_LICENSE("GPL");

