36 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/errno.h>
39 #include <linux/string.h>
51 #define floor8(a) (a&(~0x07))
52 #define floorXres(a,xres) (a&(~(xres - 1)))
53 #define iceil8(a) (((int)((a+7)/8))*8)
54 #define ceil64(a) (a|0x3F)
55 #define ceilXres(a,xres) (a|(xres - 1))
59 #define KS_SET_DPY_START_LINE 0xC0
60 #define KS_SET_PAGE_NUM 0xB8
64 #define KS_SEL_CMD 0x08
65 #define KS_SEL_DATA 0x00
66 #define KS_DPY_ON 0x3F
67 #define KS_DPY_OFF 0x3E
68 #define KS_INTACK 0x40
69 #define KS_CLRINT 0x02
101 static unsigned long num_cols;
102 static unsigned long num_rows;
103 static unsigned long dio_addr;
104 static unsigned long cio_addr;
105 static unsigned long c2io_addr;
106 static unsigned long splashval;
107 static unsigned long tuhold;
108 static unsigned int nosplash;
109 static unsigned int arcfb_enable;
110 static unsigned int irq;
114 static void ks108_writeb_ctl(
struct arcfb_par *par,
115 unsigned int chipindex,
unsigned char value)
117 unsigned char chipselval = par->
cslut[chipindex];
125 static void ks108_writeb_mainctl(
struct arcfb_par *par,
unsigned char value)
132 static unsigned char ks108_readb_ctl2(
struct arcfb_par *par)
137 static void ks108_writeb_data(
struct arcfb_par *par,
138 unsigned int chipindex,
unsigned char value)
140 unsigned char chipselval = par->
cslut[chipindex];
148 static void ks108_set_start_line(
struct arcfb_par *par,
149 unsigned int chipindex,
unsigned char y)
154 static void ks108_set_yaddr(
struct arcfb_par *par,
155 unsigned int chipindex,
unsigned char y)
160 static void ks108_set_xaddr(
struct arcfb_par *par,
161 unsigned int chipindex,
unsigned char x)
163 ks108_writeb_ctl(par, chipindex,
KS_SET_X|x);
166 static void ks108_clear_lcd(
struct arcfb_par *par,
unsigned int chipindex)
170 for (i = 0; i <= 8; i++) {
171 ks108_set_yaddr(par, chipindex, i);
172 ks108_set_xaddr(par, chipindex, 0);
173 for (j = 0; j < 64; j++) {
174 ks108_writeb_data(par, chipindex,
175 (
unsigned char) splashval);
208 && (info->
var.yres <= 64)) {
209 for (i = 0; i < num_cols; i++) {
210 ks108_set_start_line(par, i, var->
yoffset);
219 static irqreturn_t arcfb_interrupt(
int vec,
void *dev_instance)
221 struct fb_info *info = dev_instance;
222 unsigned char ctl2status;
225 ctl2status = ks108_readb_ctl2(par);
232 spin_lock(&par->
lock);
233 if (waitqueue_active(&arcfb_waitq)) {
236 spin_unlock(&par->
lock);
247 static void arcfb_lcd_update_page(
struct arcfb_par *par,
unsigned int upper,
248 unsigned int left,
unsigned int right,
unsigned int distance)
251 unsigned int xindex, yindex, chipindex, linesize;
254 unsigned char bitmask, rightshift;
258 chipindex = (xindex + (yindex*num_cols));
260 ks108_set_yaddr(par, chipindex, upper/8);
262 linesize = par->
info->var.xres/8;
263 src = (
unsigned char __force *) par->
info->screen_base + (left/8) +
265 ks108_set_xaddr(par, chipindex, left);
269 while (left <= right) {
271 for (i = 0; i < 8; i++) {
272 if ( i > rightshift) {
273 val |= (*(src + (i*linesize)) &
bitmask)
276 val |= (*(src + (i*linesize)) &
bitmask)
280 ks108_writeb_data(par, chipindex, val);
282 if (bitmask == 0x80) {
299 static void arcfb_lcd_update_vert(
struct arcfb_par *par,
unsigned int top,
300 unsigned int bottom,
unsigned int left,
unsigned int right)
302 unsigned int distance, upper, lower;
304 distance = (bottom -
top) + 1;
308 while (distance > 0) {
310 arcfb_lcd_update_page(par, upper, left, right, 8);
321 static void arcfb_lcd_update_horiz(
struct arcfb_par *par,
unsigned int left,
322 unsigned int right,
unsigned int top,
unsigned int h)
324 unsigned int distance, upper, lower;
328 lower =
min(upper + distance - 1,
ceil64(upper));
330 while (distance > 0) {
331 distance -= ((lower - upper) + 1 );
332 arcfb_lcd_update_vert(par, upper, lower, left, right);
334 lower =
min(upper + distance - 1,
ceil64(upper));
343 static void arcfb_lcd_update(
struct arcfb_par *par,
unsigned int dx,
344 unsigned int dy,
unsigned int w,
unsigned int h)
357 while (distance > 0) {
358 arcfb_lcd_update_horiz(par, left, right, y, h);
359 distance -= ((right -
left) + 1);
361 right =
min(left + distance - 1,
ceil64(left));
365 static void arcfb_fillrect(
struct fb_info *info,
376 static void arcfb_copyarea(
struct fb_info *info,
394 arcfb_lcd_update(par, image->
dx, image->
dy, image->
width,
398 static int arcfb_ioctl(
struct fb_info *info,
399 unsigned int cmd,
unsigned long arg)
418 spin_unlock_irqrestore(&par->
lock, flags);
426 ctl2 = ks108_readb_ctl2(info->
par);
442 size_t count, loff_t *ppos)
448 unsigned int fbmemlength,
x,
y,
w,
h, bitppos, startpos, endpos, bitcount;
454 xres = info->
var.xres;
455 fbmemlength = (xres * info->
var.yres)/8;
461 if ((count + p) > fbmemlength) {
462 count = fbmemlength -
p;
478 endpos =
ceilXres((bitppos + (count*8)), xres);
479 bitcount = endpos - startpos;
485 arcfb_lcd_update(par, x, y, w, h);
492 static struct fb_ops arcfb_ops = {
494 .fb_open = arcfb_open,
496 .fb_write = arcfb_write,
497 .fb_release = arcfb_release,
498 .fb_pan_display = arcfb_pan_display,
499 .fb_fillrect = arcfb_fillrect,
500 .fb_copyarea = arcfb_copyarea,
501 .fb_imageblit = arcfb_imageblit,
502 .fb_ioctl = arcfb_ioctl,
510 unsigned char *videomemory;
514 videomemorysize = (((64*64)*num_cols)*num_rows)/8;
518 videomemory =
vzalloc(videomemorysize);
527 info->
fbops = &arcfb_ops;
529 info->
var = arcfb_var;
530 info->
fix = arcfb_fix;
541 par->
cslut[0] = 0x00;
542 par->
cslut[1] = 0x06;
548 platform_set_drvdata(dev, info);
554 "arcfb: Failed req IRQ %d\n", par->
irq);
560 "fb%d: Arc frame buffer device, using %dK of video memory\n",
561 info->
node, videomemorysize >> 10);
564 for (i = 0; i < num_cols * num_rows; i++) {
566 ks108_set_start_line(par, i, 0);
567 ks108_set_yaddr(par, i, 0);
568 ks108_set_xaddr(par, i, 0);
574 for (i = 0; i < num_cols * num_rows; i++) {
577 ks108_set_start_line(par, i, 0);
578 ks108_clear_lcd(par, i);
592 struct fb_info *info = platform_get_drvdata(dev);
603 .probe = arcfb_probe,
612 static int __init arcfb_init(
void)
636 static void __exit arcfb_exit(
void)
657 MODULE_PARM_DESC(splashval,
"Splash pattern: 0xFF is black, 0x00 is green");
659 MODULE_PARM_DESC(tuhold,
"Time to hold between strobing data to Arc board");