* LINUX/DRIVERS/VIDEO/FPGA_FB.C--FPGA Graphics adaptor frame buffer device
* Created Sep2011
* Based on DNFB.C
*
* History:
*
* This file was 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.
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <linux/clk.h>
#include <linux/fb.h>
#include <linux/module.h>
#define LCD_WIDTH 320
#define LCD_HEIGHT 240
#define DISPRAMBUFLSZ (LCD_WIDTH/8)
#define DISPRAMBUFSIZE (Disprambuflsz*lcd_height)
/* Display_ Video Definitions */
static void __iomem *io_data=null;
static void __iomem *io_cmd=null;
static void __iomem *io_ctrl=null;
static unsigned long ioo_data=0;
static unsigned char *rambuf_org = NULL;
static unsigned char *rambuf_cur = NULL;
/* Frame buffer operations */
Zydzfb_blank Control screen Switch
static int Zydzfb_blank (int blank, struct fb_info *info);
static struct Fb_ops Zydzfb_ops = {
. Owner = This_module,
. Fb_blank = Zydzfb_blank,
. Fb_fillrect = Cfb_fillrect,
. Fb_copyarea = Cfb_copyarea,
. Fb_imageblit = Cfb_imageblit,
};
struct Fb_var_screeninfo Zydzfb_var __devinitdata = {
. xres = 320,//actual x-axis resolution
. yres = 240,//actual y-axis resolution
. xres_virtual = 320,//Virtual X-axis resolution
. yres_virtual = 240,//Virtual Y-Axis Resolution
. bits_per_pixel= 1,//define how many bits each point represents
. Height =-1,
. width =-1,
. Vmode = fb_vmode_noninterlaced,
};
static struct Fb_fix_screeninfo Zydzfb_fix __devinitdata = {
. id = "ZYDZFB",//device name
. Type = Fb_type_packed_pixels,
. Visual = fb_visual_mono01,/* monochr. 1=black 0=white */
. line_length = Disprambuflsz,
};
/*
* Initialization
*/
static int __devinit zydzfb_probe (struct platform_device *dev)
{
struct Fb_info *info;
int err = 0;
info = framebuffer_alloc (0, &dev->dev);
if (!info)
Return-enomem;
Info->fbops = &zydzfb_ops;
Info->fix = Zydzfb_fix;
Info->fix.smem_start = Virt_to_phys (rambuf_cur);
Info->fix.smem_len = disprambufsize;
Info->var = Zydzfb_var;
/* Virtual Address */
Info->screen_base = Rambuf_cur;
Info->screen_size = disprambufsize;
Err = Fb_alloc_cmap (&info->cmap, 2, 0);
if (Err < 0) {
Framebuffer_release (info);
return err;
}
Err = Register_framebuffer (info);
if (Err < 0) {
Fb_dealloc_cmap (&INFO->CMAP);
Framebuffer_release (info);
return err;
}
Platform_set_drvdata (Dev, info);
/* Now we have registered we can safely setup the hardware * *
PRINTK ("Display_ frame buffer alive and kicking!\n");
return err;
}
void Disp_init ()
{
static int inited=0;
if (inited) return;
Io_data=ioremap_nocache (lcd_data_port,32);
Io_cmd=ioremap_nocache (lcd_ctrl_port,32);
Io_ctrl=ioremap_nocache (lcd_perh_port,32);
rambuf_org = Kmalloc (Disprambufsize,gfp_kernel);
Rambuf_cur = Kmalloc (Disprambufsize,gfp_kernel);
Lcd_reset ();
inited=1;
}
unsigned char re_uc (unsigned char x)
{
x = (x&0x0f) <<4 | (x&0xf0) >>4;
x = (x&0x33) <<2 | (X&0XCC) >>2;
x = (x&0x55) <<1 | (X&0XAA) >>1;
return x;
}
static struct timer_list timer_key;
void Fb_timer_func (unsigned long PA)
{
int i;
for (i=0;i<lcd_height*disprambuflsz;i++)
{
if (Rambuf_org[i]!=rambuf_cur[i])
{
Writelcdcmd (Srcset_cmd);
Writelcddata (i%0x100);
Writelcddata (i/0x100);
Writelcdcmd (Memwrite_cmd);
Writelcddata (Re_uc (rambuf_cur[i));
Rambuf_org[i]=rambuf_cur[i];
}
}
Mod_timer (&TIMER_KEY,JIFFIES+20);
}
static struct Platform_driver Zydzfb_driver = {
. Probe = Zydzfb_probe,
. Driver = {
. Name = "ZYDZFB",
},
};
static struct Platform_device Zydzfb_device = {
. Name = "ZYDZFB",
};
int __init zydzfb_init (void)
{
int ret,i,j;
Disp_init ();
ret = Platform_driver_register (&zydzfb_driver);
if (!ret) {
ret = Platform_device_register (&zydzfb_device);
if (ret)
Platform_driver_unregister (&zydzfb_driver);
}
Init_timer (&timer_key);
timer_key.function=&fb_timer_func;
timer_key.expires=jiffies+10;
Timer_key.data = 0;
Add_timer (&timer_key);
return ret;
}
static void __exit zydzfb_exit (void)
{
Del_timer (&timer_key);
Platform_device_unregister (&zydzfb_device);
Platform_driver_unregister (&zydzfb_driver);
if (rambuf_org)
Kfree (rambuf_org);
if (rambuf_cur)
Kfree (rambuf_cur);
}
Module_init (Zydzfb_init);
Module_exit (Zydzfb_exit);
Module_license ("GPL");
Linux-fpga-framebuff Drive