700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > LCD背光驱动 --Backlight

LCD背光驱动 --Backlight

时间:2020-06-13 01:55:49

相关推荐

LCD背光驱动  --Backlight

显示屏按其显示原理大致可分为CRT(显像管)、LCD(液晶)及OLED三类,从市场应用看,手机中使用的显示屏主流是LCD,OLED只在翻盖机的小屏中占有少量份额,而CRT在手机中没有用到。

LCD本身不会发光,要想让其显示所要数据和图像,就必需使用白光背光源,手机中的白光背光源一般由数个侧发光白色LED灯组成,LED灯的个数由屏的大小尺寸决定,一般由2~6个不等。

【1】LCD 背光控制原理

在 fl2440开发板中,LCD 背光是通过CPU 的LCD_PWR 引脚来控制的,从原理图中可以看出,它对应于GPG4,如图

当LCD_PWR 输出为高电平“1”时,将打开背光;当输出为低电平“0”时,将关闭背光(注意:这里只是打开和关闭背光,而并没有背光亮度的调节作用)。

【2】 在内核中添加背光驱动程序

现在,我们需要增加一个简单的背光驱动,以便能够通过软件便可简单的控制背光的开关。我们要达到的目的是:在命令终端通过向背光设备发送偶数比如“0”便可关闭背光,发送奇数比如“1”便可打开背光,这样使用起来就方便多了,而不需要专门的应用程序控制它,正如在用户手册中所描述的方法(2.5.10 控制LCD 的背光):

提示:LCD 背光设备文件:/dev/backlight

在命令行种输入:echo 0 > /dev/backlight 可以关闭LCD 背光。

在命令行种输入:echo 1 > /dev/backlight 可以打开LCD 背光。

为了实现这点,我们在drivers/video/backlight 目录增加一个fl2440_backlight.c文件,内容如下:

#include <linux/errno.h>

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/slab.h>

#include <linux/input.h>

#include <linux/init.h>

#include <linux/serio.h>

#include <linux/delay.h>

#include <linux/clk.h>

#include <linux/miscdevice.h>

#include <asm/io.h>

#include <asm/irq.h>

#include <asm/uaccess.h>

#include <mach/regs-clock.h>

#include <plat/regs-timer.h>

#include <mach/regs-gpio.h>

#include <linux/cdev.h>

#include <mach/gpio.h>

#define DEVICE_NAME "backlight" //设备名称

#define DEVICE_MINOR 255 //次设备号自动申请,这里我们将设备注册为misc设备,这种设备的主设备号都为10

#defineS3C2410_GPG4S3C2410_GPG(4)

#defineS3C2410_GPG4_OUTP(0x01 << 8)

static long fl2440_backlight_ioctl(struct file *file,

unsigned int cmd,

unsigned long arg)

{

switch(cmd)

{

case 0:

//当接收的命令为0时,就将GPG4引脚设为低电平,关闭背光

s3c2410_gpio_setpin(S3C2410_GPG4, 0);

printk(DEVICE_NAME " turn off!\n");

return 0;

case 1:

//当接收的命令为1时,就将GPG4引脚设为高电平,开启背光

s3c2410_gpio_setpin(S3C2410_GPG4, 1);

printk(DEVICE_NAME " turn on!\n");

return 0;

default:

return -EINVAL;

}

}

static struct file_operations dev_fops =

{

.owner = THIS_MODULE,

.unlocked_ioctl = fl2440_backlight_ioctl, //这里只使用控制IO口的方式来控制背光

};

static struct miscdevice misc =

{

.minor = DEVICE_MINOR,

.name = DEVICE_NAME,

.fops = &dev_fops,

};

static int __init dev_init(void)

{

int ret;

ret = misc_register(&misc); //注册成misc设备

if(ret < 0)

{

printk("Register misc device fiald!");

return ret;

}

//将GPG4口配置成输出口,默认为点亮

s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_OUTP);

s3c2410_gpio_setpin(S3C2410_GPG4, 1);

return ret;

}

static void __exit dev_exit(void)

{

misc_deregister(&misc); //注销该misc设备

}

module_init(dev_init);

module_exit(dev_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("smart.zhao");

MODULE_DESCRIPTION("Backlight control for fl2440");

【3】把背光配置选项加入内核配置菜单

打开drivers/video/backlight/Kconfig,定位到1929行附近,加入如下代码:

#

# Backlight & LCD drivers configuration

#

menuconfig BACKLIGHT_LCD_SUPPORT

bool "Backlight & LCD device support"

help

Enable this to be able to choose the drivers for controlling the

backlight and the LCD panel on some platforms, for example on PDAs.

if BACKLIGHT_LCD_SUPPORT

config BACKLIGHT_FL2440

tristate "Backlight support for FL2440 from FriendlyARM"

depends on BACKLIGHT_LCD_SUPPORT

help

backlight driver for FL2440 from FriendlyARM

#

# LCD

#

config LCD_CLASS_DEVICE

再打开 drivers/video/backlight/Makefile,定位到文件末尾,根据配置定义加入驱动目标文件,如下:

obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o

obj-$(CONFIG_BACKLIGHT_FL2440) += fl2440_backlight.o

【4】在内核配置菜单中确认"Backlight support for mini2440 from FriendlyARM",被选中。

在内核源代码根目录执行:

make menuconfig,依次选择如下子菜单:

Device Drivers --->

Graphics support --->

[*] Backlight & LCD device support --->

就可以找到该配置选项,如图

在这里,如果没有被选中,按空格选中我们刚刚加入的mini2440 配置项,然后退出时保存内核配置菜单,在命令行执行:make uImage

将生成的arch/arm/boot/uImage复制到/nfsboot目录下,然后启动开发板,可以在启动时看到LCD屏显示的企鹅图像,这说明我们已经点亮了背光。

【5】编写测试程序linux-test/codetest/backlight_test.c,代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <sys/ioctl.h>

int main(int argc, char **argv)

{

int turn;

int fd;

//检测命令后面带的参数

if(argc == 1 || argc > 2)

{

printf("Usage: backlight_test on|off!\n");

exit(1);

}

//打开背光设备

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

if(fd < 0)

{

printf("Open Backlight Device Faild!\n");

exit(1);

}

//判断输入的参数

if(strcmp(argv[1], "on") == 0)

{

turn = 1;

}

else if(strcmp(argv[1], "off") == 0)

{

turn = 0;

}

else

{

printf("Usage: backlight_test on|off!\n");

exit(1);

}

//进行IO控制

ioctl(fd, turn);

//关闭背光设备

close(fd);

return 0;

}

编译程序,测试结果如下:

ANDROID里,自带的背光亮度调节,会调用哪个接口?

会调用

/sys/class/leds/lcd-backlight/brightness

而这个brightness节点,是如何声明的呢

请看LED驱动里的这么一句

static DEVICE_ATTR(brightness, /*NAME*/

0644, /*权限*/

led_brightness_show, /*Read Point*/

led_brightness_store); /*Write Point*/

这就是声明brightness的。

这里调用了led_brightness_store做为写背光函数,也就是调节时用到,它最终会调用到显示驱动里的PWM操作函数,实现背光调节。

分析:

在LED驱动中,led_classdev_register ()函数,调用device_create()创建了操作结构体空间leds_class,

led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,"%s", led_cdev->name);

关键是填充led_cdev结构体。

在led_brightness_store函数里,调用led_set_brightness设置背光亮度,最终是调用了

led_cdev->brightness_set(led_cdev, value);实现操作,这个操作,会调用哪里的函数呢?它是显示驱动里的brightness_set()函数。

请注意看,在显示驱动里(S3cfb_lte480wv.c),有这么一段代码,

static struct led_classdev smdk_backlight_led = {

.name = "lcd-backlight",

.brightness = SMDK_DEFAULT_BACKLIGHT_BRIGHTNESS,

.brightness_set = smdk_brightness_set,

};

把brightness_set指向了smdk_brightness_set()函数。这就有戏看了,终于找到真正操作函数了。

当然,LED驱动是如何与显示驱动关联起来的,这一套机制,得看一下

static int smdk_bl_probe(struct platform_device *pdev)

{

led_classdev_register(&pdev->dev, &smdk_backlight_led);

return 0;

}

原来使用了led_classdev_register(),它是由LEDS驱动提供的函数,

#include 传过来的。

这就把smdk_backlight_led 结构体指针传给了LEDS驱动,里面就有smdk_brightness_set函数的指针,所以,LEDS里的led_cdev->brightness_set能调用到这边来,呵呵。原来是这样。

注册背光的控制节点

/sys/class/leds/lcd-backlight/brightness

是在这个函数 platform_driver_register() à

smdk_bl_probe() à led_classdev_register(&pdev->dev, &smdk_backlight_led);

在smdk_backlight_led结构体里,设置了节点名称lcd-backlight和控制接口等。

而led_classdev_register()是led-class里的函数。最终调用了device_createp 这样的函数实现创建节点。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。