#include “linux/module.h“
#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/fb.h“
#include“linux/init.h“
#include“linux/dma-mapping.h“
#include“linux/interrupt.h“
#include“linux/workqueue.h“
#include“linux/wait.h“
#include“linux/platform_device.h“
#include“linux/clk.h“
#include“asm/io.h“
#include“asm/uaccess.h“
#include“asm/div64.h“
#include“asm/mach/map.h“
#include“asm/arch/regs-lcd.h“
#include“asm/arch/regs-gpio.h“
#include“asm/arch/fb.h“
static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,
unsigned int green, unsigned int blue,
unsigned int transp, struct fb_info *info);
struct lcd_regs {
unsigned long lcdcon1;
unsigned long lcdcon2;
unsigned long lcdcon3;
unsigned long lcdcon4;
unsigned long lcdcon5;
unsigned long lcdsaddr1;
unsigned long lcdsaddr2;
unsigned long lcdsaddr3;
unsigned long redlut;
unsigned long greenlut;
unsigned long bluelut;
unsigned long reserved[9];
unsigned long dithmode;
unsigned long tpal;
unsigned long lcdintpnd;
unsigned long lcdsrcpnd;
unsigned long lcdintmsk;
unsigned long lpcsel;
};
static struct fb_info *s3c_lcd;
static volatile unsigned long *gpbcon;
static volatile unsigned long *gpbdat;
static volatile unsigned long *gpccon;
static volatile unsigned long *gpdcon;
static volatile unsigned long *gpgcon;
static volatile struct lcd_regs* lcd_regs;
static u32 pseudo_palette[16];
static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{
chan &= 0xffff;
chan >>= 16 - bf->length;
return chan < bf->offset;
}
static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,
unsigned int green, unsigned int blue,
unsigned int transp, struct fb_info *info)
{
unsigned int val;
if (regno > 16)
return 1;
val = chan_to_field(red, &info->var.red);
val |= chan_to_field(green, &info->var.green);
val |= chan_to_field(blue, &info->var.blue);
//((u32 *)(info->pseudo_palette))[regno] = val;
pseudo_palette[regno] = val;
return 0;
}
static struct fb_ops s3c_lcdfb_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = s3c_lcdfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
};
static int lcd_init(void)
{
// 1. 分配一个fb_info
s3c_lcd = framebuffer_alloc(0, NULL);
// 2. 设置 //
// 2.1 设置固定的参数 //
strcpy(s3c_lcd->fix.id, "mylcd");
s3c_lcd->fix.smem_len = 240*320*16/8;
s3c_lcd->fix.type = FB_TYPE_PACKED_PIXELS;
s3c_lcd->fix.visual = FB_VISUAL_TRUECOLOR;
s3c_lcd->fix.line_length = 240*2;
// 2.2 设置可变的参数
s3c_lcd->var.xres = 240;
s3c_lcd->var.yres = 320;
s3c_lcd->var.xres_virtual = 240;
s3c_lcd->var.yres_virtual = 320;
s3c_lcd->var.bits_per_pixel = 16;
// RGB:565
s3c_lcd->var.red.offset = 11;
s3c_lcd->var.red.length = 5;
s3c_lcd->var.green.offset = 5;
s3c_lcd->var.green.length = 6;
s3c_lcd->var.blue.offset = 0;
s3c_lcd->var.blue.length = 5;
s3c_lcd->var.activate = FB_ACTIVATE_NOW;
// 2.3 设置操作函数
s3c_lcd->fbops = &s3c_lcdfb_ops;
// 2.4 其他的设置
s3c_lcd->pseudo_palette = pseudo_palette;
//s3c_lcd->screen_base = ; // 显存的虚拟地址
s3c_lcd->screen_size = 240*324*16/8;
// 3. 硬件相关的操作
// 3.1 配置GPIO用于LCD
gpbcon = ioremap(0x56000010, 8);