分类:S5PXX(三星)linuxandroid嵌入式入门 704人阅读 评论(2) 收藏 举报

关键词:androidLCD TFTSN75LVDS83B TTL-LVDSLCD电压背光电压

平台信息:
内核:linux2.6/linux3.0
系统:android/android4.0
平台:samsungexynos4210、exynos4412、exynos5250

作者:xubin341719(欢迎转载,请注明作者)

下载链接:LCD规格书(404份),之前工作用用到的、LCD规格书00 、LCD规格书01 、 LCD测试图片,彩条灰阶等

Android LCD(一):LCD基本原理篇

Android LCD(二):LCD常用接口原理篇

Android LCD(三):Samsung LCD接口篇

Android LCD(四):LCD驱动调试篇


这篇我们以一个实例来说明,Samsung Exynos4412搭配TTL转LVDS芯片SN75LVDS83B、LVDS接口LCD为例说明。从硬件接口、驱动配置、背光PWM调节三部分说明。

下载:SN75LVDS83B规格书

一、LCD接口原理以及硬件电路

Samsung Exynos4412、SN75LVDS83B、LVDS接口LCD(24bit)为例说明,三者的关系如下:


如上图所示,我们在应用中我,主控(Exynos4412)输出RGB信号到TFT-LCD大体经过三部分:

1)、标号1部分,主控(Exynos4412)输出TTL信号;

2)、标号2部分,TTLRGB-LVDS转换芯片SN75LVDS83B,把TTL信号转换成LVDS信号,传输到显示器的LVDS接收端;这部分有SN75LVDS83B编码芯片自动完成,所以我们不需要程序控制;

3)、标号3部分,分两个小部分,LVDS转换成TTLTFT-LCD显示部分;我们前面说过,TFT-LCD其实只识别TTL信号,所以要有一个转换的过程,先把LVDS信号转换、解码成TTL信号,在TFT-LCD上显示。

有上面的过程,其实我们关心调试的部分只有标号1部分到标号2部分,后面标号2到标号3的部分是自动完成的,不需要我们程序上控制,把标号2部分、标号3部分合并:


标号二部分可以理解为一个TTLRGB)接口的LCD,如下图所示,标号一部分就是主控信号输出端,简化图如下所示:


其实最简单的做法就是找个TTL接口的TFT-LCD,这样直接接上就可以。下面我们看下硬件上的电路连接:这个和我们上篇用的相同。


有上面图可以看出:硬件连接

网络标号

说明

管脚

XvVD[0:23]

XvVDEN

XvVSYNC

XvHSYNC

XvVCLK

RGB数据、使能、行场同步、时钟信号

这是TTL信号输出

LCD_PWM

调节背光

XpwmTOUT1/LCD_PWM/GPD0_1

LCD_LED_EN

LCD电压(TFT电压)使能

GPC1_2

LED_BL_EN

LED背光使能

GPL2_4

上面可分为几部分,电路连接部分分析:

(1)、TTL数据部分

这张图有木有烂掉呀,哈哈,就是这些数据了。还有有木有想起来摄像头的数据(ITU接口)也是这样的??其实视频这种信号的原理是通用的,所以LCD通了,摄像头也就知道怎么回事了。


2)、PWM背光调节

PWM其实也是芯片的一个功能模块,看到他的管脚就是一个复用脚XpwmTOUT1/LCD_PWM/GPD0_1。上一篇我们粗略的了解了PWM,就是用到这里。但是有一个疑问,PWM是调节背光电压的,背光电压一般都是12V以上的,我们PWM只有0-3V的样子,Exynos4412IO只有1.8V。怎么调节电压???


其实这个PWM只是给LCDPWM控制部分,真正的电压还是通过LCD控制板上的电路实现。

3)、LED背光、LCD电压控制

a、背光:LED+

我们可以看到这个升压电路,通过SY7208VBATT升压到18V,供给LED背光。SY7208最大升压26V。这个电压是提供给我们前面讲的背光的,也就是CCFL灯管或者LED背光组的电压。


b、LCD电压

这个电压也就是给你我们TFT阵列组用的,控制LCD液晶元素。

这部分电路分析完成,我们就有比较清晰的思路出,要一个LCD工作,要完成两部分内容:LCD上电控制,背光、LCD电压;信号输出。

二、LCD 驱动部分调试

LCD这部分,像上篇我们说的frambuffer这些部分一般平台都是可以用的,除非你是芯片厂的要写这部分。一般公司拿到的demo板子这部分都是通的,只是针对自己的lCD换一些参数。

下面我们针对三星平台我们调试LCD的时时候程序方面的改动:

1、屏参数的配置

/kernel/drivers/video/Samsung/s3cfb_wa101s.c

[cpp] view plain copy
  1. staticstructs3cfb_lcdwa101={
  2. .width=1280,//LCD分辨率宽1280
  3. .height=800,//LCD分辨率高800
  4. .bpp=24,//CLD数据位24bit
  5. .freq=60,//LCD像素时钟60MHz
  6. .timing={//LCDporch无效值
  7. .h_fp=70,
  8. .h_bp=70,
  9. .h_sw=20,
  10. .v_fp=10,
  11. .v_fpe=0,
  12. .v_bp=10,
  13. .v_bpe=0,
  14. .v_sw=3,
  15. },
  16. .polarity={//时钟、行场的极性;
  17. .rise_vclk=1,
  18. .inv_hsync=1,
  19. .inv_vsync=1,
  20. .inv_vden=0,
  21. },
  22. };
  23. /*nameshouldbefixedas's3cfb_set_lcd_info'*/
  24. voids3cfb_set_lcd_info(structs3cfb_global*ctrl)//初始化结构体
  25. {
  26. wa101.init_ldi=NULL;
  27. ctrl->lcd=&wa101;
  28. #endif
  29. }
还能想起上一篇的如何阅读规格书中的那些参数不,把这些填入就可以。
2、数据管脚初始化


kernel/arch/arm/mach-exynos/setup-fb-s5p.c

[cpp] view plain copy
  1. voids3cfb_cfg_gpio(structplatform_device*pdev)
  2. {
  3. s3cfb_gpio_setup_24bpp(EXYNOS4_GPF0(0),8,S3C_GPIO_SFN(2),S5P_GPIO_DRVSTR_LV4);
  4. s3cfb_gpio_setup_24bpp(EXYNOS4_GPF1(0),8,S3C_GPIO_SFN(2),S5P_GPIO_DRVSTR_LV4);
  5. s3cfb_gpio_setup_24bpp(EXYNOS4_GPF2(0),8,S3C_GPIO_SFN(2),S5P_GPIO_DRVSTR_LV4);
  6. s3cfb_gpio_setup_24bpp(EXYNOS4_GPF3(0),4,S3C_GPIO_SFN(2),S5P_GPIO_DRVSTR_LV4);
  7. }

LCD数据脚初始化,驱动能力设为最高S5P_GPIO_DRVSTR_LV4;管脚驱动能力,S5P_GPIO_DRVSTR_LV1-4四个等级选择。

3、时钟控制部分

kernel/arch/arm/mach-exynos/setup-fb-s5p.c

[cpp] view plain copy
  1. ints3cfb_clk_on(structplatform_device*pdev,structclk**s3cfb_clk)
  2. {
  3. structclk*sclk=NULL;
  4. structclk*mout_mpll=NULL;
  5. structclk*lcd_clk=NULL;
  6. u32rate=0;
  7. intret=0;
  8. lcd_clk=clk_get(&pdev->dev,"lcd");
  9. if(IS_ERR(lcd_clk)){
  10. dev_err(&pdev->dev,"failedtogetoperationclkforfimd\n");
  11. gotoerr_clk0;
  12. }
  13. ret=clk_enable(lcd_clk);
  14. if(ret<0){
  15. dev_err(&pdev->dev,"failedtoclk_enableoflcdclkforfimd\n");
  16. gotoerr_clk0;
  17. }
  18. clk_put(lcd_clk);
  19. sclk=clk_get(&pdev->dev,"sclk_fimd");
  20. if(IS_ERR(sclk)){
  21. dev_err(&pdev->dev,"failedtogetsclkforfimd\n");
  22. gotoerr_clk1;
  23. }
  24. if(soc_is_exynos4210())
  25. mout_mpll=clk_get(&pdev->dev,"mout_mpll");
  26. else
  27. mout_mpll=clk_get(&pdev->dev,"mout_mpll_user");
  28. if(IS_ERR(mout_mpll)){
  29. dev_err(&pdev->dev,"failedtogetmout_mpllforfimd\n");
  30. gotoerr_clk2;
  31. }
  32. ret=clk_set_parent(sclk,mout_mpll);
  33. if(ret<0){
  34. dev_err(&pdev->dev,"failedtoclk_set_parentforfimd\n");
  35. gotoerr_clk2;
  36. }
  37. if((soc_is_exynos4412())&&(samsung_rev()>=EXYNOS4412_REV_2_0))
  38. ret=clk_set_rate(sclk,880000000);
  39. else
  40. ret=clk_set_rate(sclk,800000000);
  41. if(ret<0){
  42. dev_err(&pdev->dev,"failedtoclk_set_rateofsclkforfimd\n");
  43. gotoerr_clk2;
  44. }
  45. dev_dbg(&pdev->dev,"setfimdsclkrateto%d\n",rate);
  46. clk_put(mout_mpll);
  47. ret=clk_enable(sclk);
  48. if(ret<0){
  49. dev_err(&pdev->dev,"failedtoclk_enableofsclkforfimd\n");
  50. gotoerr_clk2;
  51. }
  52. *s3cfb_clk=sclk;
  53. return0;
  54. err_clk2:
  55. clk_put(mout_mpll);
  56. err_clk1:
  57. clk_put(sclk);
  58. err_clk0:
  59. clk_put(lcd_clk);
  60. return-EINVAL;
  61. }
  62. ints3cfb_clk_off(structplatform_device*pdev,structclk**clk)
  63. {
  64. structclk*lcd_clk=NULL;
  65. lcd_clk=clk_get(&pdev->dev,"lcd");
  66. if(IS_ERR(lcd_clk)){
  67. printk(KERN_ERR"failedtogetipclkforfimd0\n");
  68. gotoerr_clk0;
  69. }
  70. clk_disable(lcd_clk);
  71. clk_put(lcd_clk);
  72. clk_disable(*clk);
  73. clk_put(*clk);
  74. *clk=NULL;
  75. return0;
  76. err_clk0:
  77. clk_put(lcd_clk);
  78. return-EINVAL;
  79. }
  80. voids3cfb_get_clk_name(char*clk_name)
  81. {
  82. strcpy(clk_name,"sclk_fimd");
  83. }
4、背光、LCD电压的控制


LCD_LED_EN

LCD电压(TFT电压)使能

GPC1_2

LED_BL_EN

LED背光使能

GPL2_4


[cpp] view plain copy
  1. ints3cfb_backlight_on(structplatform_device*pdev)
  2. {
  3. interr;
  4. pwm_set();
  5. err=gpio_request_one(EXYNOS4_GPL2(4),GPIOF_OUT_INIT_HIGH,"GPL2_4");
  6. if(err){
  7. printk(KERN_ERR"failedtorequestGPL2for"
  8. "lcdbacklightcontrol\n");
  9. returnerr;
  10. }
  11. s3c_gpio_setpull(EXYNOS4_GPL2(4),S3C_GPIO_PULL_NONE);
  12. gpio_direction_output(EXYNOS4_GPL2(4),1);
  13. gpio_free(EXYNOS4_GPL2(4));
  14. mdelay(20);
  15. err=gpio_request_one(EXYNOS4_GPC1(2),GPIOF_OUT_INIT_HIGH,"GPC1_2");
  16. if(err){
  17. printk(KERN_ERR"failedtorequestGPC1for"
  18. "lcdbacklightcontrol\n");
  19. returnerr;
  20. }
  21. s3c_gpio_setpull(EXYNOS4_GPC1(2),S3C_GPIO_PULL_NONE);
  22. gpio_direction_output(EXYNOS4_GPC1(2),0);
  23. gpio_free(EXYNOS4_GPC1(2));
  24. mdelay(20);
  25. err=gpio_request(EXYNOS4_GPD0(1),"GPD0_1");
  26. if(err){
  27. printk(KERN_ERR"failedtorequestGPD0_1for"
  28. "lcdpwmcontrol\n");
  29. returnerr;
  30. }
  31. s3c_gpio_setpull(EXYNOS4_GPD0(1),S3C_GPIO_PULL_NONE);
  32. s5p_gpio_set_drvstr(EXYNOS4_GPD0(1),S5P_GPIO_DRVSTR_LV4);
  33. gpio_direction_output(EXYNOS4_GPD0(1),1);
  34. s3c_gpio_cfgpin(EXYNOS4_GPD0(1),EXYNOS4_GPD_0_1_TOUT_1);
  35. gpio_free(EXYNOS4_GPD0(1));
  36. mdelay(20);
  37. return0;
  38. return0;
  39. }
  40. ints3cfb_backlight_off(structplatform_device*pdev)
  41. {
  42. interr;
  43. err=gpio_request_one(EXYNOS4_GPL2(4),GPIOF_OUT_INIT_LOW,"GPL2_4");
  44. if(err){
  45. printk(KERN_ERR"failedtorequestGPL2for"
  46. "lcdbacklightcontrol\n");
  47. returnerr;
  48. }
  49. s3c_gpio_setpull(EXYNOS4_GPL2(4),S3C_GPIO_PULL_NONE);
  50. gpio_direction_output(EXYNOS4_GPL2(4),0);
  51. gpio_free(EXYNOS4_GPL2(4));
  52. err=gpio_request_one(EXYNOS4_GPC1(2),GPIOF_OUT_INIT_HIGH,"GPC1_2");
  53. if(err){
  54. printk(KERN_ERR"failedtorequestGPC1for"
  55. "lcdbacklightcontrol\n");
  56. returnerr;
  57. }
  58. gpio_free(EXYNOS4_GPC1(2));
  59. return0;
  60. }

5、PWM的设置

arch/arm/mach-exynos/mach-smdk4x12.c


[cpp] view plain copy
  1. Arch/arm/mach-exynos/mach-smdk4x12.c
  2. /*LCDBacklightdata*/
  3. staticstructsamsung_bl_gpio_infosmdk4x12_bl_gpio_info={
  4. .no=EXYNOS4_GPD0(1),//PWM管脚XpwmTOUT1/LCD_PWM/GPD0_1
  5. .func=S3C_GPIO_SFN(2),
  6. };
  7. staticstructplatform_pwm_backlight_datasmdk4x12_bl_data={
  8. .pwm_id=1,//PWMIDPWM编号为1号;
  9. .pwm_period_ns=90000,//22k
  10. };
  11. staticvoid__initsmdk4x12_machine_init(void)
  12. {
  13. ………………
  14. samsung_bl_set(&smdk4x12_bl_gpio_info,&smdk4x12_bl_data);//在初始化的时候把对应的结构体初始化
  15. ………………
  16. }

samsung_bl_set看下这个函数的实现:

kernel/arch/arm/palt-samsung/dev-backlight.c

[cpp] view plain copy
  1. voidsamsung_bl_set(structsamsung_bl_gpio_info*gpio_info,
  2. structplatform_pwm_backlight_data*bl_data)
  3. {
  4. intret=0;
  5. structplatform_device*samsung_bl_device;
  6. structplatform_pwm_backlight_data*samsung_bl_data;
  7. samsung_bl_device=kmemdup(&samsung_dfl_bl_device,
  8. sizeof(structplatform_device),GFP_KERNEL);//(1)、分配内存空间;
  9. if(!samsung_bl_device){
  10. printk(KERN_ERR"%s:nomemoryforplatformdev\n",__func__);
  11. return;
  12. }
  13. samsung_bl_data=s3c_set_platdata(&samsung_dfl_bl_data,
  14. sizeof(structplatform_pwm_backlight_data),samsung_bl_device);//(2)、
  15. if(!samsung_bl_data){
  16. printk(KERN_ERR"%s:nomemoryforplatformdev\n",__func__);
  17. gotoerr_data;
  18. }
  19. /*Copyboardspecificdataprovidedbyuser*/
  20. samsung_bl_data->pwm_id=bl_data->pwm_id;//(3)、把具体配置的数据给samsung_bl_data
  21. samsung_bl_device->dev.parent=
  22. &s3c_device_timer[samsung_bl_data->pwm_id].dev;
  23. if(bl_data->max_brightness)//(4)、对bl_data的结构体检查,如果没有复制则用default的值
  24. samsung_bl_data->max_brightness=bl_data->max_brightness;
  25. if(bl_data->dft_brightness)
  26. samsung_bl_data->dft_brightness=bl_data->dft_brightness;
  27. if(bl_data->lth_brightness)
  28. samsung_bl_data->lth_brightness=bl_data->lth_brightness;
  29. if(bl_data->pwm_period_ns)
  30. samsung_bl_data->pwm_period_ns=bl_data->pwm_period_ns;
  31. if(bl_data->init)
  32. samsung_bl_data->init=bl_data->init;
  33. if(bl_data->notify)
  34. samsung_bl_data->notify=bl_data->notify;
  35. if(bl_data->exit)
  36. samsung_bl_data->exit=bl_data->exit;
  37. if(bl_data->check_fb)
  38. samsung_bl_data->check_fb=bl_data->check_fb;
  39. /*KeeptheGPIOinfoforfutureuse*/
  40. s3c_device_timer[samsung_bl_data->pwm_id].dev.platform_data=gpio_info;
  41. /*RegisterthespecificPWMtimerdevforBacklightcontrol*/
  42. ret=platform_device_register(//(5)、注册PWM设备驱动;
  43. &s3c_device_timer[samsung_bl_data->pwm_id]);
  44. if(ret){
  45. printk(KERN_ERR"failedtoregisterpwmtimerforbacklight:%d\n",ret);
  46. gotoerr_plat_reg1;
  47. }
  48. /*RegistertheBacklightdev*/
  49. ret=platform_device_register(samsung_bl_device);//(6)、注册背光设备驱动;
  50. if(ret){
  51. printk(KERN_ERR"failedtoregisterbacklightdevice:%d\n",ret);
  52. gotoerr_plat_reg2;
  53. }
  54. return;
  55. err_plat_reg2://(7)、如果有异常的情况下退出;
  56. platform_device_unregister(&s3c_device_timer[samsung_bl_data->pwm_id]);
  57. err_plat_reg1:
  58. kfree(samsung_bl_data);
  59. err_data:
  60. kfree(samsung_bl_device);
  61. return;
  62. }

(1)、分配内存空间

[cpp] view plain copy
  1. samsung_bl_device=kmemdup(&samsung_dfl_bl_device,
  2. sizeof(structplatform_device),GFP_KERNEL);
  3. 其中:
  4. staticstructplatform_pwm_backlight_datasamsung_dfl_bl_data={
  5. .max_brightness=255,
  6. .dft_brightness=140,
  7. .pwm_period_ns=78770,
  8. .init=samsung_bl_init,
  9. .exit=samsung_bl_exit,
  10. };
  11. staticstructplatform_devicesamsung_dfl_bl_device={
  12. .name="pwm-backlight",
  13. };

(2)、

(3)、把具体配置的数据给samsung_bl_data

[cpp] view plain copy
  1. arch/arm/mach-exynos/mach-smdk4x12.c
  2. staticstructsamsung_bl_gpio_infosmdk4x12_bl_gpio_info={
  3. .no=EXYNOS4_GPD0(1),//PWM管脚XpwmTOUT1/LCD_PWM/GPD0_1
  4. .func=S3C_GPIO_SFN(2),
  5. };
  6. staticstructplatform_pwm_backlight_datasmdk4x12_bl_data={
  7. .pwm_id=1,//PWMIDPWM编号为1号;
  8. .pwm_period_ns=90000,//22k
  9. };

(4)、对bl_data的结构体检查,如果没有复制则用default的值

参考(1)中的那些值。

(5)、注册PWM设备驱动;

[cpp] view plain copy
  1. ret=platform_device_register(
  2. &s3c_device_timer[samsung_bl_data->pwm_id]);
其中s3c_device_timer[]这个结构体如下:

[cpp] view plain copy
  1. structplatform_devices3c_device_timer[]={
  2. [0]={DEFINE_S3C_TIMER(0,IRQ_TIMER0)},
  3. [1]={DEFINE_S3C_TIMER(1,IRQ_TIMER1)},
  4. [2]={DEFINE_S3C_TIMER(2,IRQ_TIMER2)},
  5. [3]={DEFINE_S3C_TIMER(3,IRQ_TIMER3)},
  6. [4]={DEFINE_S3C_TIMER(4,IRQ_TIMER4)},
我们饿samsung_bl_data->pwm_id=1;所以选择[1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },

(6)、注册背光设备驱动;

[cpp] view plain copy
  1. ret=platform_device_register(samsung_bl_device);
其中:samsung_bl_device

[cpp] view plain copy
  1. samsung_bl_data=s3c_set_platdata(&samsung_dfl_bl_data,
  2. sizeof(structplatform_pwm_backlight_data),samsung_bl_device);


(7)、如果有异常的情况下退出;

6、PWM_BL背光驱动分析:

Kernel/drivers/video/backlight/pwm_bl.c

1)、驱动注册:

[cpp] view plain copy
  1. staticstructplatform_driverpwm_backlight_driver={
  2. .driver={
  3. .name="pwm-backlight",
  4. .owner=THIS_MODULE,
  5. },
  6. .probe=pwm_backlight_probe,
  7. .remove=pwm_backlight_remove,
  8. .suspend=pwm_backlight_suspend,
  9. .resume=pwm_backlight_resume,
  10. };
  11. staticint__initpwm_backlight_init(void)
  12. {
  13. returnplatform_driver_register(&pwm_backlight_driver);
  14. }

2)、probe函数分析

[cpp] view plain copy
  1. staticintpwm_backlight_probe(structplatform_device*pdev)
  2. {
  3. structbacklight_propertiesprops;
  4. structplatform_pwm_backlight_data*data=pdev->dev.platform_data;
  5. structbacklight_device*bl;
  6. structpwm_bl_data*pb;
  7. intret;
  8. if(!data){
  9. dev_err(&pdev->dev,"failedtofindplatformdata\n");
  10. return-EINVAL;
  11. }
  12. if(data->init){
  13. ret=data->init(&pdev->dev);
  14. if(ret<0)
  15. returnret;
  16. }
  17. pb=kzalloc(sizeof(*pb),GFP_KERNEL);
  18. if(!pb){
  19. dev_err(&pdev->dev,"nomemoryforstate\n");
  20. ret=-ENOMEM;
  21. gotoerr_alloc;
  22. }
  23. global_pb=pb;
  24. INIT_DELAYED_WORK_DEFERRABLE(&key_event,key_event_work);//1)、任务队列初始化;
  25. pb->period=data->pwm_period_ns;//2)、pb结构体初始化;
  26. pb->notify=data->notify;
  27. pb->check_fb=data->check_fb;
  28. pb->lth_brightness=data->lth_brightness*
  29. (data->pwm_period_ns/data->max_brightness);
  30. pb->dev=&pdev->dev;
  31. pb->pwm=pwm_request(data->pwm_id,"backlight");
  32. if(IS_ERR(pb->pwm)){
  33. dev_err(&pdev->dev,"unabletorequestPWMforbacklight\n");
  34. ret=PTR_ERR(pb->pwm);
  35. gotoerr_pwm;
  36. }else
  37. dev_dbg(&pdev->dev,"gotpwmforbacklight\n");
  38. memset(&props,0,sizeof(structbacklight_properties));
  39. props.type=BACKLIGHT_RAW;
  40. props.max_brightness=data->max_brightness;
  41. bl=backlight_device_register(dev_name(&pdev->dev),&pdev->dev,pb,
  42. &pwm_backlight_ops,&props);
  43. if(IS_ERR(bl)){
  44. dev_err(&pdev->dev,"failedtoregisterbacklight\n");
  45. ret=PTR_ERR(bl);
  46. gotoerr_bl;
  47. }
  48. global_bl=bl;
  49. bl->props.brightness=data->dft_brightness;
  50. backlight_update_status(bl);//3)、更新背光状态;
  51. platform_set_drvdata(pdev,bl);
  52. return0;
  53. err_bl:
  54. pwm_free(pb->pwm);
  55. err_pwm:
  56. kfree(pb);
  57. err_alloc:
  58. if(data->exit)
  59. data->exit(&pdev->dev);
  60. returnret;
  61. }

1)、任务队列初始化;

key_event_work加入key_event队列,

[cpp] view plain copy
  1. INIT_DELAYED_WORK_DEFERRABLE(&key_event,key_event_work);

队列调度函数:

[cpp] view plain copy
  1. staticvoidkey_event_work(structwork_struct*work)
  2. {
  3. global_pb->period=90000;
  4. global_bl->props.brightness=global_brightness;
  5. backlight_update_status(global_bl);
  6. return;
  7. }
backlight_update_status

[cpp] view plain copy
  1. staticinlinevoidbacklight_update_status(structbacklight_device*bd)
  2. {
  3. mutex_lock(&bd->update_lock);
  4. if(bd->ops&&bd->ops->update_status)
  5. bd->ops->update_status(bd);
  6. mutex_unlock(&bd->update_lock);
  7. }

update_statuspwm_backlight_ops结构体重指定:

[cpp] view plain copy
  1. staticconststructbacklight_opspwm_backlight_ops={
  2. .update_status=pwm_backlight_update_status,
  3. …………}

pwm_backlight_update_status我们后面分析,这个其实就是我们PWM设定实现的具体实施过程。

2)、pb结构体初始化;

[cpp] view plain copy
  1. pb->period=data->pwm_period_ns;pb->notify=data->notify;
  2. pb->check_fb=data->check_fb;
  3. pb->lth_brightness=data->lth_brightness*
  4. (data->pwm_period_ns/data->max_brightness);
  5. pb->dev=&pdev->dev;
  6. pb->pwm=pwm_request(data->pwm_id,"backlight");

3)、更新背光状态

[cpp] view plain copy
  1. backlight_update_status(bl);

4)、PWM_SET

UI设置PWM时,会调用到驱动中的pwm_set(void)这个函数。这个函数主要在开机时使用。

[cpp] view plain copy
  1. intpwm_set(void)
  2. {
  3. interror;
  4. structbacklight_device*bl=global_bl;
  5. structpwm_bl_data*pb=global_pb;
  6. printk("%s__%d\n",__func__,pb->period);
  7. pb->period=410000;
  8. backlight_update_status(bl);
  9. schedule_delayed_work(&key_event,600);//调用队列,跟新亮度信息;
  10. return0;
  11. }

5)、pwm_backlight_update_status这个就是PWM变化的具体实现,当应用层调节时,会调用到这个函数,把改变的值填入寄存器。

[cpp] view plain copy
  1. staticintpwm_backlight_update_status(structbacklight_device*bl)
  2. {
  3. structpwm_bl_data*pb=dev_get_drvdata(&bl->dev);
  4. intbrightness=bl->props.brightness;
  5. intmax=bl->props.max_brightness;
  6. //if(brightness==0)
  7. //return0;
  8. //printk("#####%s#%d__%d\n",__func__,pb->period,brightness);
  9. global_brightness=brightness;
  10. if(bl->props.power!=FB_BLANK_UNBLANK)
  11. brightness=0;
  12. if(bl->props.fb_blank!=FB_BLANK_UNBLANK)
  13. brightness=0;
  14. if(pb->notify)
  15. brightness=pb->notify(pb->dev,brightness);
  16. if(brightness==0){
  17. pwm_config(pb->pwm,0,pb->period);
  18. pwm_disable(pb->pwm);
  19. }else{
  20. #if1
  21. brightness=pb->lth_brightness+
  22. (brightness*(pb->period-pb->lth_brightness)/max);
  23. #else
  24. brightness=pb->lth_brightness+
  25. (((pb->period-pb->lth_brightness)/max)*brightness);
  26. #endif
  27. pwm_config(pb->pwm,brightness,pb->period);//这里对PWM寄存器的具体操作;
  28. pwm_enable(pb->pwm);
  29. }
  30. return0;
  31. }


三、LCD UBOOT下的控制(待整理…………)
LCD UBOOT下的控制,这部分我们没做过,后面有机会做了再把这部分完善,或者找个机会把代码详细看看。

更多相关文章

  1. Android(安卓)自适应背光反应慢的修改
  2. 基于Android(安卓)P 背光流程
  3. 学 Win32 汇编[15]: LOOP 与标号
  4. FPGA设计笔记:QSPI Flash与DDR3L SDRAM采用同一I/O分区
  5. Android中背光系统架构
  6. [转载]Qt on Android:图文详解Hello World全过程
  7. WakeLock使用方法示例代码
  8. android平台6410背光修改
  9. 触摸屏(TP)乱跳原因总结

随机推荐

  1. Android(安卓)SDK 21.1 发布,Android(安卓
  2. Android(安卓)EditText属性总结
  3. Android深入浅出系列课程---Lesson3 AAF1
  4. 在eclipse中查看android SDK的源代码
  5. Android(安卓)5.0 MaterialDesign Ripple
  6. 编译Android内核
  7. android 动态壁纸 3 解决 动态壁纸列表界
  8. 使用Bottom Navigation Activity实现Andr
  9. 【Android】android:windowSoftInputMode
  10. This Android(安卓)SDK requires Android