Linux开发十五_lcd驱动

Linux开发十五

lcd驱动

象棋小子    1048272975

lcd能够支持彩色图像的显示和视频的播放,是一种很重要的输出设备,在一些嵌入式人机交互系统中,也往往需要lcd进行显示。Linux内核已经支持了s3c2416的lcd控制器。

1. lcd设备

lcd设备包含了名字、独有的资源等等一些驱动程序的硬件或自定义信息。通过platform_add_devices(platform_device_register)函数将定义的平台设备注册到内核中,用于匹配设备驱动。

内核在drivers\video\fbdev\s3c-fb.c中实现了s3c2416 lcd驱动,lcd设备平台代码如下。

static struct s3c_fb_pd_winhome2416_fb_win[] = {

       [0]= {

              .default_bpp  = 16,

              .max_bpp      = 32,

              .xres           = 800,

              .yres           = 480,

       },

};

 

static struct fb_videomodehome2416_lcd_timing = {

       .pixclock = 41094,

       .left_margin   = 19,

       .right_margin       = 37,

       .upper_margin     = 10,

       .lower_margin      = 26,

       .hsync_len     = 27,

       .vsync_len     = 13,

       .xres           = 800,

       .yres           = 480,

};

 

static voids3c2416_fb_gpio_setup_24bpp(void)

{

       unsignedint gpio;

 

       for(gpio = S3C2410_GPC(1); gpio <= S3C2410_GPC(4); gpio++) {

              s3c_gpio_cfgpin(gpio,S3C_GPIO_SFN(2));

              s3c_gpio_setpull(gpio,S3C_GPIO_PULL_NONE);

       }

 

       for(gpio = S3C2410_GPC(8); gpio <= S3C2410_GPC(15); gpio++) {

              s3c_gpio_cfgpin(gpio,S3C_GPIO_SFN(2));

              s3c_gpio_setpull(gpio,S3C_GPIO_PULL_NONE);

       }

 

       for(gpio = S3C2410_GPD(0); gpio <= S3C2410_GPD(15); gpio++) {

              s3c_gpio_cfgpin(gpio,S3C_GPIO_SFN(2));

              s3c_gpio_setpull(gpio,S3C_GPIO_PULL_NONE);

       }

}

 

static struct s3c_fb_platdatahome2416_fb_platdata = {

       .win[0]          = &home2416_fb_win[0],

       .vtiming  = &home2416_lcd_timing,

       .setup_gpio   = s3c2416_fb_gpio_setup_24bpp,

       .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,

       .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,

};

 

static struct resource s3c_fb_resource[]= {

       [0]= DEFINE_RES_MEM(S3C_PA_FB, SZ_16K),

       [1]= DEFINE_RES_IRQ(IRQ_LCD_VSYNC),

       [2]= DEFINE_RES_IRQ(IRQ_LCD_FIFO),

       [3]= DEFINE_RES_IRQ(IRQ_LCD_SYSTEM),

};

 

struct platform_device s3c_device_fb = {

       .name            = "s3c-fb",

       .id          = -1,

       .num_resources    = ARRAY_SIZE(s3c_fb_resource),

       .resource       = s3c_fb_resource,

       .dev        = {

              .dma_mask          = &samsung_device_dma_mask,

              .coherent_dma_mask  = DMA_BIT_MASK(32),

       },

};

 

void __init s3c_fb_set_platdata(structs3c_fb_platdata *pd)

{

       s3c_set_platdata(pd,sizeof(struct s3c_fb_platdata),

                      &s3c_device_fb);

}

在板级初始化函数home2416_machine_init()中加入lcd平台数据s3c_fb_set_platdata(&home2416_fb_platdata),在static struct platform_device *home2416_devices[]板级平台设备列表中加入&s3c_device_fb,使lcd设备能够注册到内核中。

内核在drivers\video\backlight\ pwm_bl.c中实现了基于pwm方式的lcd背光驱动,背光设备平台代码如下。

static int s3c2416_backlight_init(structdevice *dev)

{

       gpio_request(S3C2410_GPB(0),"Backlight");

 

       gpio_direction_output(S3C2410_GPB(0),0);

       s3c_gpio_setpull(S3C2410_GPB(0),S3C_GPIO_PULL_NONE);

       s3c_gpio_cfgpin(S3C2410_GPB(0),S3C2410_GPB0_TOUT0);

 

       return0;

}

 

static ints3c2416_backlight_notify(struct device *dev, int brightness)

{

       if(!brightness) {

              gpio_direction_output(S3C2410_GPB(0),0);

       }else {

              gpio_direction_output(S3C2410_GPB(0),0);

              s3c_gpio_setpull(S3C2410_GPB(0),S3C_GPIO_PULL_NONE);

              s3c_gpio_cfgpin(S3C2410_GPB(0),S3C2410_GPB0_TOUT0);

       }

       returnbrightness;

}

 

static voids3c2416_backlight_exit(struct device *dev)

{

       gpio_direction_output(S3C2410_GPB(0),0);

}

 

static structplatform_pwm_backlight_data backlight_data = {

       .max_brightness= 100,

       .dft_brightness= 50,

       .enable_gpio    = -1,

       .init           = s3c2416_backlight_init,

       .notify           = s3c2416_backlight_notify,

       .exit           = s3c2416_backlight_exit,

};

 

static struct platform_devices3c2416_backlight = {

       .name= "pwm-backlight",

       .dev  = {

              .parent= &samsung_device_pwm.dev,

              .platform_data= &backlight_data,

       },

       .id   = -1,

};

 

static struct pwm_lookups3c2416_pwm_lookup[] = {

       PWM_LOOKUP("samsung-pwm",0, "pwm-backlight", NULL, 36296,

                 PWM_POLARITY_NORMAL),

};

在板级初始化函数home2416_machine_init ()中把pwm背光映射到pwm设备表中pwm_add_table(s3c2416_pwm_lookup, ARRAY_SIZE(s3c2416_pwm_lookup)),在static struct platform_device *home2416_devices[]板级平台设备列表中加入&s3c2416_backlight,使背光设备能够注册到内核中。

修改drivers\tty\vt\vt.c,禁止lcd开机一段时间后自动关屏。

static int blankinterval = 0;

修改drivers/video/console/fbcon.c,禁止光标闪烁。

static int fbcon_cursor_noblink = 1;

2. 内核配置

Linux配置支持lcd设备驱动,选中Device Drivers->Graphics support->Framebuffer Devices->Samsumg S3C framebuffer support 。

Linux配置支持lcd背光驱动,选中DeviceDrivers->Graphics support->Backlight & LCD device support->GenericPWM based Backlight Driver。

Linux配置开机logo,DeviceDrivers->Graphics support->Bootup logo->Standard 224-color Linux logo。

3. lcd测试

cat /proc/devices可以知道lcd主设备号为29,次设备号为0,在/dev目录中创建fb0设备文件。

mknod  /dev/fb0  c  29  0

lcd显示黑屏。

mknod  /dev/zero  c  1  5

dd if=/dev/zero of=/dev/fb0

4. 应用编程

应用程序可以通过设备文件访问lcd,lcd纯色显示应用测试代码lcd_test.c如下。

#include "fcntl.h"

#include "unistd.h"

#include "stdio.h"

#include "stdlib.h"

#include "sys/mman.h"

 

void screen_clear(unsigned short*ppixel, unsigned short color)

{

       inti;

       for(i=0; i<800*480; i++)

              ppixel[i]= color;

}

 

int main(void)

{

       unsignedshort colors[] = {0xffff, 0x0000, 0xf800,

              0x07e0,0x001f, 0xffe0, 0xf81f, 0x7ff};

       intscreen_size;

       intfd;

       intindex;

       unsignedshort *ppixel;

       fd= open("/dev/fb0", O_RDWR);

       if(fd == -1) {

              printf("Openframebuffer failed\n");

              exit(1);

       }

       screen_size= 800*480*2;

       ppixel=(unsigned short *)mmap(0, screen_size,

              PROT_READ|PROT_WRITE,MAP_SHARED, fd,0);

       if(ppixel == (unsigned short *)-1) {

              printf("Mapframebuffer failed\n");

              exit(1);

       }

       while(1) {

              screen_clear(ppixel,colors[index]);

              index++;

              if(index >= sizeof(colors)/sizeof(colors[0]))

                     index= 0;

              sleep(2);

       }

       umap(ppixel,screen_size);

       close(fd);

       return0;

}

用arm-linux-gcc静态编译,使之生成arm cpu可执行的指令,并且可脱离任何库独立运行,arm-linux-gcc -static -o lcd_test lcd_test.c,生成lcd_test可执行文件。复制可执行文件到根文件系统,目标板启动后在目录输入./lcd_test即可执行。

5. 附录

https://pan.baidu.com/s/1slczwhJ

bootloader源码以及使用说明

https://pan.baidu.com/s/1eRDJtNs

Qt5.8官网源码

https://pan.baidu.com/s/1nuGmSqt

本系列例程的根文件系统

https://pan.baidu.com/s/1i5btLGT

opev3.2.0官网源码

https://pan.baidu.com/s/1pLpuHw3

yaffs官网源码 

https://pan.baidu.com/s/1bpkZynt

busybox-1.26.2官网源码

https://pan.baidu.com/s/1i4EtjfR

tslib官网源码

https://pan.baidu.com/s/1i5MGRhb

mplayer-1.3.0官网源码

https://pan.baidu.com/s/1sl0fXlr

基于S3C2416修改的linux-4.10.10源码

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值