对于,不想逐一检查内核自带驱动,想自己编写驱动。

1,make menuconfig 去掉 编译到内核,改为 M 编译为 模块(因为要用到里面的3个.ko 驱动)

Device Drivers --->
    Graphics support --->
        Support for frame buffer devices --->
            <M> S3C2410 LCD framebuffer support

2,make uImage && make modules 生成新内核  和 模块文件

烧写新内核或使用 nfs bootm 使用编译为 M 模块的内核启动。

复制 3个 ko 文件到 文件系统,这里用的是 NFS 网络文件系统。

cp drivers/video/fbdev/core/cfb*.ko /nfs_root/new_fs  (新的 4.1 内核是在这里,以前没有 这个 core 目录)

3, 使用原来的 2.6.22 的内核下的驱动程序,修改头文件后,编译为 .ko 文件放到 NFS 文件系统里,启动,如图所示

图忘拍了,有时是白屏,有时是竖的细彩线。

比较内核自带驱动 s3c2410fb.c 发现有个 usleep_range(1000, 1100);

而原来的 2.6.22 的驱动里面,是没有启用 clk 的。添加上这部分后,重新编译,试机成功。

最后是完整的驱动源码:

 #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> #include <asm/mach/map.h>
#include <mach/regs-lcd.h>
#include <mach/regs-gpio.h>
#include <mach/fb.h> //参数定义
#define LCD_WIDTH 480
#define LCD_HEIGHT 272
#define LCD_BIT 16 #define LCD_CLKVAL 4
#define LCD_TFT 3
#define LCD_24BBP 0xd
#define LCD_16BBP 0xc
#define LCD_EN_OFF 0
#define LCD_EN_ON 1
#define LCD_VBPD 1
#define LCD_LINEVAL (LCD_HEIGHT - 1)
#define LCD_VFPD 1
#define LCD_VSPW 9
#define LCD_HBPD 1
#define LCD_HOZVAL (LCD_WIDTH - 1)
#define LCD_HFPD 1
#define LCD_HSPW 40
#define LCD_INVVLINE 1
#define LCD_INVVFRAME 1
//调色板 u32 = unsigned int
static u32 pseudo_palette[]; /* from pxafb.c */
static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{
//只取16bit 数据
chan &= 0xffff;
//如 r = 16-5 = 11 : 右移去掉不要的位
chan >>= ( - bf->length);
//在移到高位去 就是右边补0
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)
{ if( > regno)
{
unsigned int val;
val = chan_to_field(red, &info->var.red);
val |= chan_to_field(green, &info->var.green);
val |= chan_to_field(blue, &info->var.blue);
pseudo_palette[regno] = val;
return ;
}
return ;
} static struct fb_ops s3c_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = s3c_lcdfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
}; //定义GPIO
static volatile unsigned long *gpb_con;
static volatile unsigned long *gpc_con;
static volatile unsigned long *gpd_con;
static volatile unsigned long *gpg_con; static volatile unsigned long *gpb_dat;
static volatile unsigned long *gpc_dat;
static volatile unsigned long *gpd_dat;
static volatile unsigned long *gpg_dat; 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[];
unsigned long dithmode;
unsigned long tpal;
unsigned long lcdintpnd;
unsigned long lcdsrcpnd;
unsigned long lcdintmsk;
unsigned long lpcsel;
}; static volatile struct lcd_regs * lcd_reg; //定义fb_info
static struct fb_info * s3c_lcd;
static int lcd_init(void)
{
//1,分配一个fb_info
s3c_lcd = framebuffer_alloc(, NULL); struct clk *clk;
clk = clk_get(NULL, "lcd");
if (IS_ERR(clk)) {
printk("failed to get lcd clock source\n");
} clk_prepare_enable(clk);
printk("got and enabled clock\n"); usleep_range(, ); //2,设置
//2,1 设置固定的参数
strcpy(s3c_lcd->fix.id, "mylcd");
s3c_lcd->fix.smem_len = LCD_WIDTH * LCD_HEIGHT * LCD_BIT / ;
s3c_lcd->fix.type = FB_TYPE_PACKED_PIXELS;
s3c_lcd->fix.visual = FB_VISUAL_TRUECOLOR;
s3c_lcd->fix.line_length = LCD_WIDTH * LCD_BIT / ; //单位 bytes
//物理地址由 dma_alloc_writecombine 函数分配
//s3c_lcd->fix.smem_start = LCD_FRAMEBUFFER;
//s3c_lcd->fix.mmio_len = LCD_WIDTH * LCD_HEIGHT * LCD_BIT / 8; //2,2 设置可变的参数
s3c_lcd->var.width = LCD_WIDTH;
s3c_lcd->var.height = LCD_HEIGHT;
s3c_lcd->var.xres = LCD_WIDTH;
s3c_lcd->var.yres = LCD_HEIGHT;
s3c_lcd->var.xres_virtual = LCD_WIDTH;
s3c_lcd->var.yres_virtual = LCD_HEIGHT;
s3c_lcd->var.bits_per_pixel = LCD_BIT;
//RGB 5 6 5
s3c_lcd->var.red.length = ;
s3c_lcd->var.red.offset = ;
s3c_lcd->var.green.length = ;
s3c_lcd->var.green.offset = ;
s3c_lcd->var.blue.length = ;
s3c_lcd->var.blue.offset = ;
s3c_lcd->var.activate = FB_ACTIVATE_NOW; s3c_lcd->var.pixclock = ; //2,3 设置操作函数
s3c_lcd->fbops = &s3c_ops; //2.4 其它的设置
s3c_lcd->screen_size = LCD_WIDTH * LCD_HEIGHT * LCD_BIT / ;
s3c_lcd->pseudo_palette = pseudo_palette; //3,硬件相关的操作
//3,1 配置GPIO
gpb_con = ioremap(0x56000010, );
gpb_dat = gpb_con + ; gpc_con = ioremap(0x56000020, );
gpc_dat = gpc_con + ; gpd_con = ioremap(0x56000030, );
gpc_dat = gpd_con + ; gpg_con = ioremap(0x56000060, );
gpg_dat = gpg_con + ; *gpc_con = 0xaaaaaaaa; // GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND
*gpd_con = 0xaaaaaaaa; // GPIO管脚用于VD[23:8] *gpb_con &= ~(); //配置背光引脚为输出
*gpb_con |= ;
*gpb_dat &= ; //默认输出低电平 *gpg_con &= ~(<<*); //GPGCON 4 配置为 LCD_POWER
*gpg_con |= (<<*); //3,2 配置lcdcon1 ~ lcdcon5
lcd_reg = ioremap(0x4d000000, sizeof(struct lcd_regs));
lcd_reg->lcdcon1 = LCD_CLKVAL<< | LCD_TFT<< | LCD_16BBP<< | LCD_EN_OFF;
lcd_reg->lcdcon2 = LCD_VBPD<< | LCD_LINEVAL<< | LCD_VFPD<< | LCD_VSPW;
lcd_reg->lcdcon3 = LCD_HBPD<< | LCD_HOZVAL<< | LCD_HFPD;
lcd_reg->lcdcon4 = LCD_HSPW;
lcd_reg->lcdcon5 = << | LCD_INVVLINE<< | LCD_INVVFRAME<< | ;
//屏幕宽度 * 16bit 颜色值 / words : 1 words = 2 byte
lcd_reg->lcdsaddr3 = LCD_WIDTH * / ; //3,3 设置显存 bramebuffer, 并把地址告诉lcd 控制器
s3c_lcd->screen_base = dma_alloc_writecombine(NULL, s3c_lcd->fix.smem_len, &s3c_lcd->fix.smem_start, GFP_KERNEL); lcd_reg->lcdsaddr1 = (s3c_lcd->fix.smem_start>>)<< | ((s3c_lcd->fix.smem_start>>) & 0x1fffff);
lcd_reg->lcdsaddr2 = ((s3c_lcd->fix.smem_start + s3c_lcd->fix.smem_len)>>) & 0x1fffff; unsigned long saddr1,saddr2,saddr3;
saddr1 = s3c_lcd->fix.smem_start >> ;
saddr2 = s3c_lcd->fix.smem_start;
saddr2 += s3c_lcd->fix.line_length * s3c_lcd->var.yres;
saddr2 >>= ;
saddr3 = S3C2410_OFFSIZE() |
S3C2410_PAGEWIDTH((s3c_lcd->fix.line_length / ) & 0x3ff); lcd_reg->lcdsaddr1 = saddr1;
lcd_reg->lcdsaddr2 = saddr2;
lcd_reg->lcdsaddr3 = saddr3; printk("fb %x \n", LCD_CLKVAL<< | LCD_TFT<< | LCD_16BBP<< | LCD_EN_OFF);
printk("fb %x \n", LCD_VBPD<< | LCD_LINEVAL<< | LCD_VFPD<< | LCD_VSPW);
printk("fb %x \n", LCD_HBPD<< | LCD_HOZVAL<< | LCD_HFPD);
printk("fb %x \n", LCD_HSPW);
printk("fb %x \n", << | LCD_INVVLINE<< | LCD_INVVFRAME<< | ); printk("fb %x \n", saddr1);
printk("fb %x \n", saddr2);
printk("fb %x \n", saddr3); //打开 LCD_POWER 背光
lcd_reg->lcdcon1 |= LCD_EN_ON;
*gpb_dat |= ;
lcd_reg->lcdcon5 &= ~(<<);
lcd_reg->lcdcon5 |= (<<); //4,注册
register_framebuffer(s3c_lcd);
return ;
} static void lcd_exit(void)
{
//关背光
*gpb_dat &= ;
lcd_reg->lcdcon5 &= ~(<<);
lcd_reg->lcdcon1 &= LCD_EN_OFF; //注销显存
dma_free_writecombine(NULL,s3c_lcd->fix.smem_len,s3c_lcd->screen_base,s3c_lcd->fix.smem_start); //注销
framebuffer_release(s3c_lcd); //注销framebuf
unregister_framebuffer(s3c_lcd); //取消map
iounmap(gpb_con);
iounmap(gpc_con);
iounmap(gpd_con);
iounmap(gpg_con);
iounmap(lcd_reg);
} module_init(lcd_init);
module_exit(lcd_exit);
MODULE_LICENSE("GPL");

试验的时候要先加载那3个 .ko

insmod cfbcopyarea.ko
insmod cfbfillrect.ko
insmod cfbimgblt.ko
insmod lcd.ko  编译出来的 lcd 驱动

s3c2440液晶屏驱动 (非内核自带) linux-4.1.24的更多相关文章

  1. s3c2440液晶屏驱动 (内核自带) linux-4.1.24

    自带有一部分驱动的配置信息,只要修改这部分就能支援 不同的液晶屏 - /arch/arm/mach-s3c24xx/mach-smdk2440.c 另一部分在 /drivers/video/fbdev ...

  2. 所谓的液晶屏驱动IC是单独的IC还是在屏内就集成

    所谓的液晶屏驱动IC是单独的IC还是在屏内就集成 时间:2016-12-05    作者:admin   其实无论什么液晶屏,想要正常工作必须包括两个人:玻璃屏+驱动IC:但是现在有一些液晶厂商他们不 ...

  3. Linux驱动之内核自带的S3C2440的LCD驱动分析

    先来看一下应用程序是怎么操作屏幕的:Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,Linux抽象出FrameBuffer这个设备来供用户 ...

  4. 联盛德 HLK-W806 (八): 4线SPI驱动SSD1306/SSD1315 128x64 OLED液晶屏

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  5. 单片机中不带字库LCD液晶屏显示少量汉字

    单片机中不带字库LCD液晶屏如何显示少量汉字,一般显示汉字的方法有1.使用带字库的LCD屏,2.通过SD 卡或者外挂spi flash存中文字库,3.直接将需要的汉字取模存入mcu的flash中. 第 ...

  6. 联盛德 HLK-W806 (六): I2C驱动SSD1306 128x64 OLED液晶屏

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  7. S3C2440上LCD驱动(FrameBuffer)实例开发讲解

    一.开发环境 主  机:VMWare--Fedora 9 开发板:Mini2440--64MB Nand, Kernel:2.6.30.4 编译器:arm-linux-gcc-4.3.2 二.背景知识 ...

  8. 18.Llinux-触摸屏驱动(详解)

    本节的触摸屏驱动也是使用之前的输入子系统 1.先来回忆之前第12节分析的输入子系统 其中输入子系统层次如下图所示, 其中事件处理层的函数都是通过input_register_handler()函数注册 ...

  9. 使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

    前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 本文介绍一下UP板的GPIO资源使用,以及一个使用Python演示一个简单的demo. 本文使用Markdown写成,为获得更好的 ...

随机推荐

  1. 表单验证:$tablePrefix(定义表前缀);$trueTableName = 'yonghu',找到真实表名(yonghu)表;create($attr,0)两个参数;批量验证(返回数组);ajax+动态验证表单

    *$tablePrefix是定义在Model中的,优先级大于配置文件中,如果项目中表前缀全部比如为"a_",并且在配置文件中定义了 'DB_PREFIX'=>'a_' 后期如 ...

  2. selenium定位页面元素的一件趣事

    PS:本博客selenium分类不会记载selenium打开浏览器,定位元素,操作页面元素,切换到iframe,处理alter.confirm和prompt对话框这些在网上随处可见的信息:本博客此分类 ...

  3. ElasticSearchwindow下搭建

    ElasticSearch是一个开源的分布式搜索引擎. 下载 下载地址: https://www.elastic.co/downloads/elasticsearch 当前版本:Elasticsear ...

  4. 通过href简单实现单击a链接跳转到页面指定位置

    在页面中点击a标签后,要使其跳到页面里面相应的地方,方法很简单,就是在a标签里面href中的内容和你要跳到这个区域的id同名即可,例如: <a href="#ppp" tar ...

  5. angularJs之http后台访问数据

    AngularJS  XMLHttpRequest $http  是AngularJS中的一个核心服务,用于读取远程服务器的数据. 读取JSON 文件 以下是存储在web服务器上的JSON 文件: h ...

  6. linux–nohup命令(转)

    在应用Unix/Linux时,我们一般想让某个程序在后台运行,于是我们将常会用 & 在程序结尾来让程序自动运行.比如我们要运行mysql在后台: /usr/local/mysql/bin/my ...

  7. win7下开启telnet命令

    win7下开启telnet命令 win7上telnet这条命令默认被关闭了. 开启telnet方法如下: 一,打开控制面版 二,选择程序 三,选择打开或关闭windows功能 在弹出窗口中把 Teln ...

  8. gitlab改用ssh操作

    1.配置ssh http://blog.csdn.net/xyzchenxiaolin/article/details/51853319http://blog.csdn.net/r8hzgemq/ar ...

  9. MQTT——java简单测试(二)

    服务端代码: package bsit.mqtt.demo.one_way; import org.eclipse.paho.client.mqttv3.MqttClient; import org. ...

  10. 使用Photoshop不改变图片尺寸,保存图片到30K以下的解决办法