linux/drivers/video/fbdev/arcfb.c

/*
 * linux/drivers/video/arcfb.c -- FB driver for Arc monochrome LCD board
 *
 * Copyright (C) 2005, Jaya Kumar <[email protected]>
 *
 * 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)
#define floorXres(a,xres)
#define iceil8(a)
#define ceil64(a)
#define ceilXres(a,xres)

/* ks108 chipset specific defines and code */

#define KS_SET_DPY_START_LINE
#define KS_SET_PAGE_NUM
#define KS_SET_X
#define KS_CEHI
#define KS_CELO
#define KS_SEL_CMD
#define KS_SEL_DATA
#define KS_DPY_ON
#define KS_DPY_OFF
#define KS_INTACK
#define KS_CLRINT

struct arcfb_par {};

static const struct fb_fix_screeninfo arcfb_fix =;

static const struct fb_var_screeninfo arcfb_var =;

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)
{}

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

static unsigned char ks108_readb_ctl2(struct arcfb_par *par)
{}

static void ks108_writeb_data(struct arcfb_par *par,
				unsigned int chipindex, unsigned char value)
{}

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

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

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

static void ks108_clear_lcd(struct arcfb_par *par, unsigned int chipindex)
{}

/* main arcfb functions */

static int arcfb_open(struct fb_info *info, int user)
{}

static int arcfb_release(struct fb_info *info, int user)
{}

static int arcfb_pan_display(struct fb_var_screeninfo *var,
				struct fb_info *info)
{}

static irqreturn_t arcfb_interrupt(int vec, void *dev_instance)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * 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)
{}

static int arcfb_ioctl(struct fb_info *info,
			  unsigned int cmd, unsigned long arg)
{}

static void arcfb_damage_range(struct fb_info *info, off_t off, size_t len)
{}

static void arcfb_damage_area(struct fb_info *info, u32 x, u32 y,
			      u32 width, u32 height)
{}

FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(arcfb,
				   arcfb_damage_range,
				   arcfb_damage_area)

static const struct fb_ops arcfb_ops =;

static int arcfb_probe(struct platform_device *dev)
{}

static void arcfb_remove(struct platform_device *dev)
{}

static struct platform_driver arcfb_driver =;

static struct platform_device *arcfb_device;

static int __init arcfb_init(void)
{}

static void __exit arcfb_exit(void)
{}

module_param(num_cols, ulong, 0);
MODULE_PARM_DESC();
module_param(num_rows, ulong, 0);
MODULE_PARM_DESC();
module_param(nosplash, uint, 0);
MODULE_PARM_DESC();
module_param(arcfb_enable, uint, 0);
MODULE_PARM_DESC();
module_param_hw(dio_addr, ulong, ioport, 0);
MODULE_PARM_DESC();
module_param_hw(cio_addr, ulong, ioport, 0);
MODULE_PARM_DESC();
module_param_hw(c2io_addr, ulong, ioport, 0);
MODULE_PARM_DESC();
module_param(splashval, ulong, 0);
MODULE_PARM_DESC();
module_param(tuhold, ulong, 0);
MODULE_PARM_DESC();
module_param_hw(irq, uint, irq, 0);
MODULE_PARM_DESC();

module_init();
module_exit(arcfb_exit);

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();