• 【分析笔记】Linux 4.9 backlight 子系统分析


    相关信息

    内核版本:Linux version 4.9.56
    驱动文件:lichee\linux-4.9\drivers\video\backlight\backlight.c

    驱动作用

    1. 对上,面对应用层提供统一的设备节点入口
    2. 同级,面对驱动层提供设备驱动加载卸载通知事件,以及背光控制接口。
    3. 对下,面对硬件层提供背光控制调节的回调接口
    4. 监听 frambuffer 事件, 实现清屏联动背光控制
    5. 监听系统休眠唤醒,实现休眠唤醒背光联动控制

    控制背光的来源:应用访问、事件联动、休眠唤醒

    在这里插入图片描述

    源码分析

    一、驱动初始化

    1. 完成背光设备逻辑类的创建
    2. 初始化用于通知背光设备驱动加载卸载的事件
    3. 为该逻辑类设定五个背光控制相关的设备节点
    /sys/class/backlight/xxx/type
    /sys/class/backlight/xxx/bl_power
    /sys/class/backlight/xxx/brightness
    /sys/class/backlight/xxx/max_brightness
    /sys/class/backlight/xxx/actual_brightness
    
    • 1
    • 2
    • 3
    • 4
    • 5
    代码解析
    static int __init backlight_class_init(void)
    {
       
    	// 创建背光设备逻辑类: /sys/class/backlight
    	backlight_class = class_create(THIS_MODULE, "backlight");
    	if (IS_ERR(backlight_class)) {
       
    		pr_warn("Unable to create backlight class; errno = %ld\n", PTR_ERR(backlight_class));
    		return PTR_ERR(backlight_class);
    	}
    
    	// 面对应用层提供统一的设备节点入口(预先设置好节点名称和可读写权限)
    	backlight_class->dev_groups = bl_device_groups;
    	// 监听系统的休眠唤醒回调
    	backlight_class->pm = &backlight_class_dev_pm_ops;
    
    	// 初始化背光设备链表,用于被外部驱动查询获取
    	INIT_LIST_HEAD(&backlight_dev_list);
    	mutex_init(&backlight_dev_list_mutex);
    	
    	// 初始化内核通知链, 用于通知驱动层背光设备注册或卸载事件
    	BLOCKING_INIT_NOTIFIER_HEAD(&backlight_notifier);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    ATTRIBUTE_GROUPS 宏定义解析:

    直接搜索源码是找不到 bl_device_groups 关键词的,实际该变量是通过宏进行定义

    static struct attribute *bl_device_attrs[] = {
       
    	&dev_attr_bl_power.attr,
    	&dev_attr_brightness.attr,
    	&dev_attr_actual_brightness.attr,
    	&dev_attr_max_brightness.attr,
    	&dev_attr_type.attr,
    	NULL,
    };
    ATTRIBUTE_GROUPS(bl_device);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    宏定义:include\linux\sysfs.h

    #define __ATTRIBUTE_GROUPS(_name)				\
    static const struct attribute_group *_name##_groups[] = {
         	\
    	&_name##_group,						\
    	NULL,							\
    }
    
    #define ATTRIBUTE_GROUPS(_name)					\
    static const struct attribute_group _name##_group = {
         		\
    	.attrs = _name##_attrs,					\
    };								\
    __ATTRIBUTE_GROUPS(_name)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    宏定义展开:ATTRIBUTE_GROUPS(bl_device)

    #define __ATTRIBUTE_GROUPS(bl_device)				\
    static const struct attribute_group *bl_device_groups[] = {
         	\
    	&bl_device_group,						\
    	NULL,							\
    }
    
    #define ATTRIBUTE_GROUPS(bl_device)					\
    static const struct attribute_group bl_device_group = {
         		\
    	.attrs = bl_device_attrs,					\
    };								\
    __ATTRIBUTE_GROUPS(bl_device)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    宏替换后的效果

    static struct attribute *bl_device_attrs[
    • 相关阅读:
      quarkus(二) 初识
      bootStrap常用样式
      HBase (二) --------- HBase 安装
      Python基础
      快团团对接,供货商对接团长如何做到只吸引不打扰?
      深度学习:多模态与跨模态
      [BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)
      PyCharm运行bash脚本
      shell 字符串变量
      上位机通过Modbus转Profinet网关与CGV300变频器通讯配置案例
    • 原文地址:https://blog.csdn.net/lovemengx/article/details/127913251