linux lcd驱动文件夹,ARM在linux下LCD驱动文件注释

//#define LCD_GRAY_16

#define FBCON_HAS_CFB8

#include

#include

#include

#include

#include

#include

#ifdef LCD_GRAY_16

#include

#else

#include

#endif

#include

#include

#include

//声明一个结构体用于内核操作

static struct s3c44b0fb_info

{

struct

fb_info fb;

int currcon;

} *cfb;

#define CMAP_SIZE 256

static int s3c44b0fb_setcolreg(u_int regno, u_int red, u_int green,

u_int blue, u_int transp, struct fb_info *info)

{

//TODO

return 0;

}

static int s3c44b0fb_set_cmap(struct fb_cmap *cmap, int kspc, int

con,struct fb_info *info)

{

struct s3c44b0fb_info *cfb = (struct

s3c44b0fb_info *)info;// ?????

struct fb_cmap *dcmap =

&fb_display[con].cmap;//con?????

int err = 0;

if (!dcmap->len)

err = fb_alloc_cmap(dcmap,

CMAP_SIZE, 0);

if (!err &&

con == cfb->currcon)

{

err = fb_set_cmap(cmap, kspc,

s3c44b0fb_setcolreg,

&cfb->fb);

dcmap =

&cfb->fb.cmap;

}

if (!err)

fb_copy_cmap(cmap, dcmap, kspc

? 0 : 1);

return err;

}

static int s3c44b0fb_set_var(struct fb_var_screeninfo *var, int

con,struct fb_info *info)

{

struct display *display;

unsigned int lcdcon, syscon;

int chgvar = 0;

if (var->activate

& FB_ACTIVATE_TEST)

return 0;

if ((var->activate

& FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)

return -EINVAL;

if (cfb->fb.var.xres !=

var->xres)

chgvar = 1;

if (cfb->fb.var.yres !=

var->yres)

chgvar = 1;

if (cfb->fb.var.xres_virtual !=

var->xres_virtual)

chgvar = 1;

if (cfb->fb.var.yres_virtual !=

var->yres_virtual)

chgvar = 1;

if (cfb->fb.var.bits_per_pixel !=

var->bits_per_pixel)

chgvar = 1;

if (con < 0)

{

display =

cfb->fb.disp;

chgvar = 0;

}

else

{

display = fb_display +

con;

}

var->transp.msb_right =

0;

var->transp.offset =

0;

var->transp.length =

0;

var->red.msb_right =

0;

var->red.offset =

5;

var->red.length =

3;

var->green.msb_right =

0;

var->green.offset =

2;

var->green.length =

3;

var->blue.msb_right =

0;

var->blue.offset =

0;

var->blue.length =

2;

switch (var->bits_per_pixel)

{

#ifdef FBCON_HAS_MFB

case 1:

cfb->fb.fix.visual =

FB_VISUAL_MONO01;

display->dispsw =

&fbcon_mfb;

display->dispsw_data =

NULL;

break;

#endif

#ifdef FBCON_HAS_CFB2

case 2:

cfb->fb.fix.visual =

FB_VISUAL_PSEUDOCOLOR;

display->dispsw =

&fbcon_cfb2;

display->dispsw_data =

NULL;

break;

#endif

#ifdef FBCON_HAS_CFB4

case 4:

cfb->fb.fix.visual =

FB_VISUAL_PSEUDOCOLOR;

display->dispsw =

&fbcon_cfb4;

display->dispsw_data =

NULL;

break;

#endif

#ifdef FBCON_HAS_CFB8

case 8:

cfb->fb.fix.visual =

FB_VISUAL_TRUECOLOR;

display->dispsw =

&fbcon_cfb8;

display->dispsw_data =

NULL;

break;

#endif

default:

return -EINVAL;

}

display->next_line =

var->xres_virtual *

var->bits_per_pixel / 8;//

cfb->fb.fix.line_length =

display->next_line;//

display->screen_base =

cfb->fb.screen_base;

display->line_length =

cfb->fb.fix.line_length;

display->visual =

cfb->fb.fix.visual;

display->type =

cfb->fb.fix.type;

display->type_aux =

cfb->fb.fix.type_aux;

display->ypanstep =

cfb->fb.fix.ypanstep;

display->ywrapstep =

cfb->fb.fix.ywrapstep;

display->can_soft_blank = 1;

display->inverse =

0;

cfb->fb.var =

*var;

cfb->fb.var.activate &=

~FB_ACTIVATE_ALL;

display->var =

cfb->fb.var;

if (var->activate

& FB_ACTIVATE_ALL)

cfb->fb.disp->var

= cfb->fb.var;

if (chgvar &&

info &&

cfb->fb.changevar)

cfb->fb.changevar(con);

fb_set_cmap(&cfb->fb.cmap,

1, s3c44b0fb_setcolreg,

&cfb->fb);

return 0;

}

static int gen_get_cmap(struct fb_cmap *cmap, int kspc, int con,

struct fb_info *info)

{

fb_copy_cmap(&info->cmap,

cmap, kspc ? 0 : 2);

return 0;

}

static int gen_get_fix(struct fb_fix_screeninfo *fix, int con,

struct fb_info *info)

{

*fix = info->fix;

return 0;

}

static int gen_get_var(struct fb_var_screeninfo *var, int con,

struct fb_info *info)

{

*var = info->var;

return 0;

}

//函数注册

static struct fb_ops s3c44b0fb_ops =

{

owner: THIS_MODULE,

fb_set_var: s3c44b0fb_set_var,

fb_set_cmap: s3c44b0fb_set_cmap,

fb_get_fix: gen_get_fix,

fb_get_var: gen_get_var,

fb_get_cmap: gen_get_cmap,

};

static int s3c44b0fb_updatevar(int con, struct fb_info *info)

{

return -EINVAL;

}

static void s3c44b0fb_blank(int blank, struct fb_info *info)

{

//TODO

if (blank)

{

}

else

{

}

}

#define U8 __u8

#define U16 __u16 #define U32 __u32

#define MAX749_CTRL 0x80

#define MAX749_ADJ 0x40

#define Max749AdjHi() outl(inl(S3C44B0X_PDATC)|MAX749_ADJ,

S3C44B0X_PDATC) //背光调整

#define Max749AdjLo() outl(inl(S3C44B0X_PDATC)&~MAX749_ADJ,

S3C44B0X_PDATC) //液晶打开

#define Max749CtrlHi() outl(inl(S3C44B0X_PDATC)|MAX749_CTRL,

S3C44B0X_PDATC)

#define Max749CtrlLo() outl(inl(S3C44B0X_PDATC)&~MAX749_CTRL,

S3C44B0X_PDATC)

static void Max749Rst(void)

{

unsigned char i;

Max749AdjHi();

Max749CtrlLo();

i = 100;

while(i--); Max749CtrlHi();

}

static void Max749Up(U16 cnt)

{ unsigned char i;

Max749Rst();

for(; cnt; cnt--)

{

Max749AdjLo();

i = 10;

while(i--);

Max749AdjHi();

i = 10;

while(i--);

}

}

#define SCR_XSIZE 320 //虚拟的水平大小

#define SCR_YSIZE 240 //虚拟的垂直大小

#define LCD_XSIZE 320 //实际的水平大小

#define LCD_YSIZE 240 //实际的垂直大小

#ifdef LCD_GRAY_16 //LCD彩色和灰级度位16灰级度

#define LCD_DEPTH 4 //4 //每一个像素占4位

#define LCD_BUF_SIZE ((SCR_XSIZE*SCR_YSIZE)>>1) //320*240/2

#else

#define LCD_DEPTH 8 //每一个像素占8位

#define LCD_BUF_SIZE ((SCR_XSIZE*SCR_YSIZE)) //320*240大小

#endif

#define CLKVAL (10<<12) //VCLK

= MCLK/(2*CLKVAL) CLKVAL=10 VCLK=

#define WLH (1<<10) //16

clock

#define WDLY (1<<8) //16

clock

#define MMODE (0<<7) //VM

= ecah frame, not use MVAL

#define DISMODE (2<<5) ///4bit single scan

#define INVCLK (0<<4) //falling

edge fetch data

#define INVLINE (0<<3) //normal,

non inverse

#define INVFRAME (0<<2) //normal

#define INVVD (0<<1) //normal

#define ENVID 1

#define DSVID 0

#define LCD_MODE_DS (CLKVAL|WLH|WDLY|MMODE|DISMODE|INVCLK|INVLINE|INVFRAME|INVVD|DSVID)

#define LCD_MODE_EN (CLKVAL|WLH|WDLY|MMODE|DISMODE|INVCLK|INVLINE|INVFRAME|INVVD|ENVID)

#define LINEBLINK 10

#define SELFREF_EN 1

#define SELFREF_DS 0

#define MONO_MODE 0 //配置显示模式

#define G4_MODE 1 //

#define G16_MODE 2 //

#define C8_MODE 3 // #define BankOfDisMem(addr) (((U32)(addr)>>22)<<21) // 系统内存地址为图像缓存

#define BaseOfDisMem(addr) (((U32)(addr)>>1)&0x1fffff) //用于双扫描的上部地址或单扫描帧内存

/

#define BSWP_EN 1

#define BSWP_DS 0

#define MVAL 1 //如果MMODE位为1,表明VM的翻转速率

#define LCDBASEL 0 //双扫描下部帧地址

#define MONO_VS_SIZE (LCD_XSIZE/16)|(((SCR_XSIZE-LCD_XSIZE)/16)<<9)

#define G4_VS_SIZE (LCD_XSIZE/8)|(((SCR_XSIZE-LCD_XSIZE)/8)<<9)

#define G16_VS_SIZE (LCD_XSIZE/4)|(((SCR_XSIZE-LCD_XSIZE)/4)<<9)

#define C8_VS_SIZE (LCD_XSIZE/2)|(((SCR_XSIZE-LCD_XSIZE)/2)<<9)

//MONO_VS_SIZE G4_VS_SIZE G16_VS_SIZE C8_VS_SIZE

相当于LCDADDR3的值

//

//

//

//PAGEWIDTH=( 实际大小/扫描位数)/灰级度

//OFFSIZE=(虚拟大小-实际大小)/灰级度

//

//

//

int __init s3c44b0xfb_init(void)

{

int err = -ENOMEM;

char *fbuf;

cfb = kmalloc(sizeof(*cfb) + sizeof(struct

display), GFP_KERNEL);//内核开辟大小空间返回为开辟内存起始地址

if (!cfb)

goto out;

memset(cfb, 0, sizeof(*cfb) + sizeof(struct

display));// 向cfb里写0

fbuf = kmalloc(LCD_BUF_SIZE,

GFP_KERNEL); //开辟大小位LCD_BUF_SIZE的内存空间

if(!fbuf)

{

kfree(cfb);

goto out;

}

memset(fbuf, 0,

LCD_BUF_SIZE); //向fbuf中填写LCD_BUF_SIZE大小个0

cfb->currcon =

-1;

strcpy(cfb->fb.fix.id,

"s3c44b0"); //

cfb->fb.screen_base =

fbuf; cfb->fb.fix.smem_start =

fbuf; cfb->fb.fix.smem_len =

LCD_BUF_SIZE; cfb->fb.fix.type =

FB_TYPE_PACKED_PIXELS; cfb->fb.var.xres =

LCD_XSIZE; cfb->fb.var.xres_virtual = SCR_XSIZE; cfb->fb.var.yres = LCD_YSIZE; cfb->fb.var.yres_virtual = SCR_YSIZE;

cfb->fb.var.bits_per_pixel =

LCD_DEPTH; cfb->fb.var.grayscale =

1; cfb->fb.var.activate =

FB_ACTIVATE_NOW; cfb->fb.var.height =

-1; cfb->fb.var.width =

-1;

//

// //

cfb->fb.fbops =

&s3c44b0fb_ops; cfb->fb.changevar =

NULL; // cfb->fb.switch_con =

s3c44b0fb_switch; //

cfb->fb.updatevar =

s3c44b0fb_updatevar; cfb->fb.blank =

s3c44b0fb_blank; cfb->fb.flags =

FBINFO_FLAG_DEFAULT; //

cfb->fb.disp =

(struct display *)(cfb + 1); //?????????

fb_alloc_cmap(&cfb->fb.cmap,

CMAP_SIZE,

0); //颜色映射函数

#ifdef LCD_GRAY_16 Max749Up(23);

outl(0xaaaa,

S3C44B0X_PCOND); //VFRAME,VM,VLINE,VCLK,VD3-VD0

enable 16级灰度4位单扫描

outl(LCD_MODE_DS,

S3C44B0X_LCDCON1); // 向LCDCON1寄存器各位写相应的数据

outl((LINEBLINK<<21)|(((LCD_XSIZE>>2)-1)<<10)|(LCD_YSIZE-1),

S3C44B0X_LCDCON2); //

//((LCD_XSIZE>>2)-1)是根据HOZVAL=(水平显示实际宽度/扫描的位数)-1

outl((G16_MODE<<27)|BankOfDisMem(fbuf)|BaseOfDisMem(fbuf),

S3C44B0X_LCDSADDR1); //

//选择显示模式;指示视频缓冲区在系统存储器的段地址A[27:22];

outl((BSWP_EN<<29)|(MVAL<<21)|BaseOfDisMem((U32)fbuf+SCR_XSIZE*LCD_YSIZE/2),

S3C44B0X_LCDSADDR2); //

//允许扫描;VM以什么速率变化;双扫描LCD是的下帧存储区的起始地址A[21:1]

outl(G16_VS_SIZE,

S3C44B0X_LCDSADDR3); //

//虚拟屏幕偏移量(半字数量);虚拟屏幕宽度(半字数量级)

outl(inl(S3C44B0X_PDATC)&~0x100,

S3C44B0X_PDATC); // set GPC8 low

//

#else //其他类型的LCD

/

outl(inl(S3C44B0X_PCONC)&~0xff00,

S3C44B0X_PCONC);

outl(inl(S3C44B0X_PCONC)|0xff00,

S3C44B0X_PCONC); //GPC4-GPC7 as VD7-VD4

outl(0xaaaa,

S3C44B0X_PCOND); //VFRAME,VM,VLINE,VCLK,VD3-VD0

outl(inl(S3C44B0X_PDATC)|0x100,

S3C44B0X_PDATC); // set GPC8 low

//outl(0x4f40, S3C44B0X_LCDCON1);

outl(LCD_MODE_DS, S3C44B0X_LCDCON1);

outl((LINEBLINK<<21)|(((LCD_YSIZE>>1)-1)<<10)|(LCD_YSIZE-1),

S3C44B0X_LCDCON2);

outl((3<<27)|((int)fbuf>>1),

S3C44B0X_LCDSADDR1);

outl(((((int)fbuf+LCD_XSIZE*LCD_YSIZE)>>1)&0x1fffff)|(13<<21)|(1<<29),

S3C44B0X_LCDSADDR2);

outl(C8_VS_SIZE, S3C44B0X_LCDSADDR3);

outl(0xfdb96420, S3C44B0X_REDLUT);

outl(0xfdb96420, S3C44B0X_GREENLUT);

outl(0xfb40, S3C44B0X_BLUELUT);

#endif

outl(inl(S3C44B0X_LCDCON1)|ENVID,

S3C44B0X_LCDCON1);

printk("LCD buffer : %p\n", fbuf);

s3c44b0fb_set_var(&cfb->fb.var,

-1, &cfb->fb);

err =

register_framebuffer(&cfb->fb);

// printk("err=%d\n", err);

out: return err;

}

//使用unergister_framebuffer()函数进行帧缓冲设备的注销

static void __exit s3c44b0xfb_exit(void)

{

unregister_framebuffer(&cfb->fb);

kfree(cfb); //释放帧缓冲设备建立的空间

}

int __init s3c44b0xfb_setup(char *options)

{

return 0;

}

//动态加载需要设置的模块加载方式

#ifdef MODULE

module_init(s3c44b0xfb_init);

module_exit(s3c44b0xfb_exit);

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值