【IoT】高通LCD背光控制软件简析

简介: LCD驱动

背光控制驱动分析

1,Wled backlight

在driver/leds/目录下存放着系统背光以及LED灯的驱动程序,通常需要在驱动程序中构造好struct led_classdev结构体,用来描述当前的led设备

structled_classdev {

const char     *name;                                                                                                                                               

int         brightness; 

int         max_brightness;

int         flags;

   …..

/* Set LED brightness level */

/* Must not sleep, use a workqueue ifneeded */                                

void       (*brightness_set)(struct led_classdev *led_cdev,                   

                  enum led_brightnessbrightness);                              

/* Get LED brightness level */                                                 

enum led_brightness(*brightness_get)(struct led_classdev *led_cdev);          

   const char      *default_trigger;

   …

};

name: 用来表述设备的名称,在注册到ledclass上之后将在sys/leds/目录下创建一个class

其中还需要注意的是设置背光brightness_set的实现必须是不能睡眠的,通常使用一个工作队列,在工作队列中实现设置的动作。

default_trigger是一个字符串,用来匹配由链表中哪个节点的ledclass_dev作为触发控制背光,实际是在链表中添加一个node,trigger_event的时候,根据给定的name与default匹配使用那一个节点的ledclass device作为触发。

以我们项目中的leds-qpnp驱动来分析,在probe中构造ledclass_dev结构体

led->cdev.brightness_set = qpnp_led_set; //设置背光

led->cdev.brightness_get = qpnp_led_get; //获取背光

。。。

led->cdev.name= “wled:backlight”;

最后使用led_classdev_register(&spmi->dev, &led->cdev);注册到ledclass驱动上去。

static voidqpnp_led_set(struct led_classdev *led_cdev, enum led_brightness value)

{

   if (value >led->cdev.max_brightness)

          value =led->cdev.max_brightness;

   led->cdev.brightness = value;

   schedule_work(&led->work);   //schedule work

}

实际上由__qpnp_led_work()函数去设置背光。

2,LCD backlight

LCDbacklight是android的背光控制接口,它是一个通用的驱动,最终会调用到WLED的背光控制驱动设置背光。

mdss_fb.c中通过led_classdev_register注册一个led classdev,同样的先需要构造一个ledclass dev结构体,与wled不同的是它的backlight level是0~255,而wled则由panel决定。

staticstruct led_classdev backlight_led = {

.name           = "lcd-backlight",

.brightness     = MDSS_MAX_BL_BRIGHTNESS,  //255

.brightness_set =mdss_fb_set_bl_brightness,

};

那么显然续作一个数据数量的转换。比如我们项目中wled的背光是0~4095,因此需要在代码中转换。在probe同样需要注册ledclass device。代码如下:

if (!lcd_backlight_registered) {



    backlight_led.brightness =mfd->panel_info->brightness_max;                                                                                                      

    backlight_led.max_brightness =mfd->panel_info->brightness_max;

    if(led_classdev_register(&pdev->dev, &backlight_led))

        pr_err("led_classdev_registerfailed\n");

    else

        lcd_backlight_registered = 1;

}   

那么,用户层设定背光lcd_backlight是怎么调用到wled backlight驱动中去的呢?首先背光level数量级不同,需要做转换,将android的backlevel转换成背光驱动需要的backlevel。通过如下的宏实现:

defineMDSS_BRIGHT_TO_BL(out, v, bl_max, max_bright) do {\

                out = (2 * (v) * (bl_max) +max_bright)\

                / (2 * max_bright);\

                } while (0)

从软件框图的执行流程来看,最终backlevel是从pdata->set_backlight(pdata, temp);这条语句设置下去的。

到了这里,需要提到上面的default_trigger,它是一座桥梁,过渡到wled驱动。

DEFINE_LED_TRIGGER(bl_led_trigger);实际上这个宏的作用定义了一个struct led_trigger类型的指针变量bl_led_trigger.然后在初始化的时候将defualt trigger对应的字符串注册到trigger驱动中去,实际上就是添加到对应的链表中。并返回初始化好的bl_led_trigger

led_trigger_register_simple("bkl-trigger", & bl_led_trigger);

在drivers/video/msm/mdss/mdss_dsi_panel.c中初始化时候将mdss_dsi_panel_bl_ctrl挂在函数指针上面:

ctrl_pdata->panel_data.set_backlight= mdss_dsi_panel_bl_ctrl;在这个函数中遍历链表找到对应的ledcass dev节点,led_set_brightness去设置背光。

staticinline void led_set_brightness(struct led_classdev *led_cdev, enum led_brightness value)

{

if (value >led_cdev->max_brightness)                                            

    value =led_cdev->max_brightness;                                           

led_cdev->brightness = value;                                                   

if (!(led_cdev->flags &LED_SUSPENDED))                                          

    led_cdev->brightness_set(led_cdev,value);                                  

}

卫朋

人人都是产品经理受邀专栏作家,CSDN 嵌入式领域新星创作者、资深技术博主。2020 年 8 月开始写产品相关内容,截至目前,人人都是产品经理单渠道阅读 56 万+,鸟哥笔记单渠道阅读200 万+,CSDN 单渠道阅读 210 万+,51CTO单渠道阅读 180 万+。

卫朋入围2021/2022年人人都是产品经理平台年度作者,光环国际学习社区首批原创者、知识合作伙伴,商业新知 2021 年度产品十佳创作者,腾讯调研云2022年达人榜第三名。

文章被人人都是产品经理、CSDN、华为云、运营派、产品壹佰、鸟哥笔记、光环国际、商业新知、腾讯调研云等头部垂直类媒体转载。文章见仁见智,各位看官可策略性选择对于自己有用的部分。

相关文章
|
传感器 编解码 安全
|
3月前
|
物联网 数据管理 Apache
拥抱IoT浪潮,Apache IoTDB如何成为你的智能数据守护者?解锁物联网新纪元的数据管理秘籍!
【8月更文挑战第22天】随着物联网技术的发展,数据量激增对数据库提出新挑战。Apache IoTDB凭借其面向时间序列数据的设计,在IoT领域脱颖而出。相较于传统数据库,IoTDB采用树形数据模型高效管理实时数据,具备轻量级结构与高并发能力,并集成Hadoop/Spark支持复杂分析。在智能城市等场景下,IoTDB能处理如交通流量等数据,为决策提供支持。IoTDB还提供InfluxDB协议适配器简化迁移过程,并支持细致的权限管理确保数据安全。综上所述,IoTDB在IoT数据管理中展现出巨大潜力与竞争力。
106 1
|
13天前
|
安全 物联网 网络安全
智能设备的安全隐患:物联网(IoT)安全指南
智能设备的安全隐患:物联网(IoT)安全指南
41 12
|
11天前
|
传感器 监控 安全
物联网(IoT):定义、影响与未来
物联网(IoT):定义、影响与未来
30 3
|
20天前
|
存储 JSON 运维
智能物联网平台:Azure IoT Hub在设备管理中的实践
【10月更文挑战第26天】随着物联网技术的发展,Azure IoT Hub成为企业管理和连接数百万台设备的强大平台。本文介绍Azure IoT Hub的设备管理功能,包括设备注册、设备孪生、直接方法和监控诊断,并通过示例代码展示其应用。
24 4