一、前言

mtk平台为了方便光距感驱动的兼容和统一管理,将所有的光距感驱动程序都放置在alsps框架中;
本文以MT8183平台alsps框架下的光距感ltr559为例进行分析;

 涉及文件及目录:设备树:   kernel-4.4/arch/arm64/boot/dts/mediatek/mt6771.dts   kernel-4.4/arch/arm64/boot/dts/mediatek/k71v1_64_bsp.dtsalsps架构:kernel-4.4/drivers/misc/mediatek/sensors-1.0/alsps/alsps.ckernel-4.4/drivers/misc/mediatek/sensors-1.0/hwmon/sensor_attributes/sensor_attr.c光距感驱动:kernel-4.4/drivers/misc/mediatek/sensors-1.0/alsps/LTR559/ltr559.c

二、alsps框架分析

1、驱动加载顺序

ltr599.c和alsps.c驱动程序在内核初始化过程中的调用顺序跟两者选择加载入口函数的方式有关;
ltr599.c:module_init(ltr559_init);
alsps.c:late_initcall(alsps_init);
从kernel-4.4/include/linux/init.h文件中可以获取启动顺序的宏列表和排序;

#define early_initcall(fn)       __define_initcall(fn, early)
#define pure_initcall(fn)       __define_initcall(fn, 0)
#define core_initcall(fn)       __define_initcall(fn, 1)
#define core_initcall_sync(fn)      __define_initcall(fn, 1s)
#define postcore_initcall(fn)       __define_initcall(fn, 2)
#define postcore_initcall_sync(fn)  __define_initcall(fn, 2s)
#define arch_initcall(fn)       __define_initcall(fn, 3)
#define arch_initcall_sync(fn)      __define_initcall(fn, 3s)
#define subsys_initcall(fn)     __define_initcall(fn, 4)
#define subsys_initcall_sync(fn)    __define_initcall(fn, 4s)
#define fs_initcall(fn)         __define_initcall(fn, 5)
#define fs_initcall_sync(fn)        __define_initcall(fn, 5s)
#define rootfs_initcall(fn)     __define_initcall(fn, rootfs)
#define device_initcall(fn)     __define_initcall(fn, 6)
#define device_initcall_sync(fn)    __define_initcall(fn, 6s)
#define late_initcall(fn)       __define_initcall(fn, 7)
#define late_initcall_sync(fn)      __define_initcall(fn, 7s

module_init对应默认的device_initcall,比late_initcall数字小,数字越小的优先级越高;所以内核初始化调用顺序是先调用ltr559.c入口函数后调用alsps.c的入口函数

2、sensor内核初始化驱动流程

机器刚开始启动进入kernel初始化阶段时,光距感sensor驱动流程:

先调用ltr559.c文件中的ltr559_init,在alsps_driver_add函数中先向内核平台总线注册一个als_ps_driver结构体的设备驱动:platform_driver_register(&als_ps_driver)),之后将所有加载过的光距感驱动程序通过调用alsps_driver_add(obj);函数,将alsps_init_list[MAX_CHOOSE_ALSPS_NUM]数组中的成员都指向对应的obj

//ltr599.c
static struct alsps_init_info ltr559_init_info = {.name = LTR559_DEV_NAME,.init = alsps_local_init,.uninit = alsps_remove,};
static int __init ltr559_init(void)
{alsps_driver_add(&ltr559_init_info);return 0;
}
//mt6771.dts
//配置alsps架构下的device信息
alsps:als_ps@0 {compatible = "mediatek,als_ps";
};
//alsps.c
static const struct of_device_id als_ps_of_match[] = {{.compatible = "mediatek,als_ps",},
};
static struct platform_driver als_ps_driver = {.probe = als_ps_probe,.remove = als_ps_remove,.driver = {.name = "als_ps",.of_match_table = als_ps_of_match,}
};
int alsps_driver_add(struct alsps_init_info *obj)
{int err = 0;int i = 0;for (i = 0; i < MAX_CHOOSE_ALSPS_NUM; i++) {  //MAX_CHOOSE_ALSPS_NUM = 5if ((i == 0) && (alsps_init_list[0] == NULL))   if (platform_driver_register(&als_ps_driver))if (alsps_init_list[i] == NULL) {obj->platform_diver_addr = &als_ps_driver;alsps_init_list[i] = obj; break;}}//光距感驱动遍历数量超过5(MAX_CHOOSE_ALSPS_NUM)个时会报错if (i >= MAX_CHOOSE_ALSPS_NUM) {pr_err("ALSPS driver add err\n");err = -1;}return err;
}

当alsps_init_list数组成员与所有的光距感obj绑定后,开始运行alsps.c中alsps_init->alsps_probe->alsps_real_driver_init->alsps_init_list[i]->init();, 通过操作alsps_init_list数组成员的init函数指针来运行对应光距感驱动程序中的obj结构体init指针函数,如ltr559.c中的alsps_local_init函数;

之后的流程就很熟悉了,向i2c平台注册了ltr559_i2c_driver,当alsps_of_match中的compatible与dts中compatible的属性保持一致就会调用ltr559_i2c_probe;

//k71v1_64_bsp.dts
&i2c1 {alsps1@3b{compatible = "mediatek,alsps559";reg = <0x3b>;};
}
//ltr559.c
static const struct of_device_id alsps_of_match[] = {{.compatible = "mediatek,alsps559"},{},
};
static struct i2c_driver ltr559_i2c_driver = { .probe      = ltr559_i2c_probe, .of_match_table = alsps_of_match, ...
};
static int alsps_local_init(void)
{i2c_add_driver(&ltr559_i2c_driver); //注册i2c总线下的platform_driver
}

以光感为例,在ltr559_i2c_probe函数中会执行以下内容:
1、完成光感硬件初始化(不涉及alsps架构,第三章节再讲);
2、完成光感功能控制,注册光感设备,创建设备节点:als_register_control_path;
3、添加与alsps框架文件中的数据传输函数:als_register_data_path;

2.1 分析als_register_control_path函数

als_register_control_path函数中实现了两个功能:
1、alsps.c中alsps架构下的通用功能函数与ltr559.c中的als_ctl结构体成员绑定,通过这个联系在alsps.c中可以控制ltr559光感的使能开关,同时也可以读到ltr559.c文件是否选择alsps架构的数据上报功能等;

//ltr559.c
static int ltr559_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{struct als_control_path als_ctl={0};als_ctl.open_report_data= als_open_report_data;//没用到als_ctl.enable_nodata = ltr559_als_power; //是否使能ltr559光感 ...als_ctl.is_report_input_direct = false;//false表示不直接上报数据,走alsps架构流程als_register_control_path(&als_ctl);
}//alsps.c
int als_register_control_path(struct als_control_path *ctl)
{cxt = alsps_context_obj;//1、功能函数绑定cxt->als_ctl.open_report_data = ctl->open_report_data; cxt->als_ctl.enable_nodata = ctl->enable_nodata;...cxt->als_ctl.is_report_input_direct = ctl->is_report_input_direct;//2、注册设备节点als_misc_init(alsps_context_obj);sysfs_create_group(&alsps_context_obj->als_mdev.this_device->kobj,&als_attribute_group);kobject_uevent(&alsps_context_obj->als_mdev.this_device->kobj,KOBJ_ADD); return 0;
}

2、创建注册光感设备节点:/dev/m_als_misc,提供给上层获取数据的fops结构体;

#mermaid-svg-2QkKSS3rdUDlobBc .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-2QkKSS3rdUDlobBc .label text{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc .node rect,#mermaid-svg-2QkKSS3rdUDlobBc .node circle,#mermaid-svg-2QkKSS3rdUDlobBc .node ellipse,#mermaid-svg-2QkKSS3rdUDlobBc .node polygon,#mermaid-svg-2QkKSS3rdUDlobBc .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-2QkKSS3rdUDlobBc .node .label{text-align:center;fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc .node.clickable{cursor:pointer}#mermaid-svg-2QkKSS3rdUDlobBc .arrowheadPath{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-2QkKSS3rdUDlobBc .flowchart-link{stroke:#333;fill:none}#mermaid-svg-2QkKSS3rdUDlobBc .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-2QkKSS3rdUDlobBc .edgeLabel rect{opacity:0.9}#mermaid-svg-2QkKSS3rdUDlobBc .edgeLabel span{color:#333}#mermaid-svg-2QkKSS3rdUDlobBc .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-2QkKSS3rdUDlobBc .cluster text{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-2QkKSS3rdUDlobBc .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-2QkKSS3rdUDlobBc text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-2QkKSS3rdUDlobBc .actor-line{stroke:grey}#mermaid-svg-2QkKSS3rdUDlobBc .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-2QkKSS3rdUDlobBc .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-2QkKSS3rdUDlobBc #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-2QkKSS3rdUDlobBc .sequenceNumber{fill:#fff}#mermaid-svg-2QkKSS3rdUDlobBc #sequencenumber{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc #crosshead path{fill:#333;stroke:#333}#mermaid-svg-2QkKSS3rdUDlobBc .messageText{fill:#333;stroke:#333}#mermaid-svg-2QkKSS3rdUDlobBc .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-2QkKSS3rdUDlobBc .labelText,#mermaid-svg-2QkKSS3rdUDlobBc .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-2QkKSS3rdUDlobBc .loopText,#mermaid-svg-2QkKSS3rdUDlobBc .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-2QkKSS3rdUDlobBc .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-2QkKSS3rdUDlobBc .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-2QkKSS3rdUDlobBc .noteText,#mermaid-svg-2QkKSS3rdUDlobBc .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-2QkKSS3rdUDlobBc .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-2QkKSS3rdUDlobBc .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-2QkKSS3rdUDlobBc .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-2QkKSS3rdUDlobBc .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc .section{stroke:none;opacity:0.2}#mermaid-svg-2QkKSS3rdUDlobBc .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-2QkKSS3rdUDlobBc .section2{fill:#fff400}#mermaid-svg-2QkKSS3rdUDlobBc .section1,#mermaid-svg-2QkKSS3rdUDlobBc .section3{fill:#fff;opacity:0.2}#mermaid-svg-2QkKSS3rdUDlobBc .sectionTitle0{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc .sectionTitle1{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc .sectionTitle2{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc .sectionTitle3{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-2QkKSS3rdUDlobBc .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc .grid path{stroke-width:0}#mermaid-svg-2QkKSS3rdUDlobBc .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-2QkKSS3rdUDlobBc .task{stroke-width:2}#mermaid-svg-2QkKSS3rdUDlobBc .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc .taskText:not([font-size]){font-size:11px}#mermaid-svg-2QkKSS3rdUDlobBc .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-2QkKSS3rdUDlobBc .task.clickable{cursor:pointer}#mermaid-svg-2QkKSS3rdUDlobBc .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-2QkKSS3rdUDlobBc .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-2QkKSS3rdUDlobBc .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-2QkKSS3rdUDlobBc .taskText0,#mermaid-svg-2QkKSS3rdUDlobBc .taskText1,#mermaid-svg-2QkKSS3rdUDlobBc .taskText2,#mermaid-svg-2QkKSS3rdUDlobBc .taskText3{fill:#fff}#mermaid-svg-2QkKSS3rdUDlobBc .task0,#mermaid-svg-2QkKSS3rdUDlobBc .task1,#mermaid-svg-2QkKSS3rdUDlobBc .task2,#mermaid-svg-2QkKSS3rdUDlobBc .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-2QkKSS3rdUDlobBc .taskTextOutside0,#mermaid-svg-2QkKSS3rdUDlobBc .taskTextOutside2{fill:#000}#mermaid-svg-2QkKSS3rdUDlobBc .taskTextOutside1,#mermaid-svg-2QkKSS3rdUDlobBc .taskTextOutside3{fill:#000}#mermaid-svg-2QkKSS3rdUDlobBc .active0,#mermaid-svg-2QkKSS3rdUDlobBc .active1,#mermaid-svg-2QkKSS3rdUDlobBc .active2,#mermaid-svg-2QkKSS3rdUDlobBc .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-2QkKSS3rdUDlobBc .activeText0,#mermaid-svg-2QkKSS3rdUDlobBc .activeText1,#mermaid-svg-2QkKSS3rdUDlobBc .activeText2,#mermaid-svg-2QkKSS3rdUDlobBc .activeText3{fill:#000 !important}#mermaid-svg-2QkKSS3rdUDlobBc .done0,#mermaid-svg-2QkKSS3rdUDlobBc .done1,#mermaid-svg-2QkKSS3rdUDlobBc .done2,#mermaid-svg-2QkKSS3rdUDlobBc .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-2QkKSS3rdUDlobBc .doneText0,#mermaid-svg-2QkKSS3rdUDlobBc .doneText1,#mermaid-svg-2QkKSS3rdUDlobBc .doneText2,#mermaid-svg-2QkKSS3rdUDlobBc .doneText3{fill:#000 !important}#mermaid-svg-2QkKSS3rdUDlobBc .crit0,#mermaid-svg-2QkKSS3rdUDlobBc .crit1,#mermaid-svg-2QkKSS3rdUDlobBc .crit2,#mermaid-svg-2QkKSS3rdUDlobBc .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-2QkKSS3rdUDlobBc .activeCrit0,#mermaid-svg-2QkKSS3rdUDlobBc .activeCrit1,#mermaid-svg-2QkKSS3rdUDlobBc .activeCrit2,#mermaid-svg-2QkKSS3rdUDlobBc .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-2QkKSS3rdUDlobBc .doneCrit0,#mermaid-svg-2QkKSS3rdUDlobBc .doneCrit1,#mermaid-svg-2QkKSS3rdUDlobBc .doneCrit2,#mermaid-svg-2QkKSS3rdUDlobBc .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-2QkKSS3rdUDlobBc .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-2QkKSS3rdUDlobBc .milestoneText{font-style:italic}#mermaid-svg-2QkKSS3rdUDlobBc .doneCritText0,#mermaid-svg-2QkKSS3rdUDlobBc .doneCritText1,#mermaid-svg-2QkKSS3rdUDlobBc .doneCritText2,#mermaid-svg-2QkKSS3rdUDlobBc .doneCritText3{fill:#000 !important}#mermaid-svg-2QkKSS3rdUDlobBc .activeCritText0,#mermaid-svg-2QkKSS3rdUDlobBc .activeCritText1,#mermaid-svg-2QkKSS3rdUDlobBc .activeCritText2,#mermaid-svg-2QkKSS3rdUDlobBc .activeCritText3{fill:#000 !important}#mermaid-svg-2QkKSS3rdUDlobBc .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-2QkKSS3rdUDlobBc g.classGroup text .title{font-weight:bolder}#mermaid-svg-2QkKSS3rdUDlobBc g.clickable{cursor:pointer}#mermaid-svg-2QkKSS3rdUDlobBc g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-2QkKSS3rdUDlobBc g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-2QkKSS3rdUDlobBc .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-2QkKSS3rdUDlobBc .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-2QkKSS3rdUDlobBc .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-2QkKSS3rdUDlobBc .dashed-line{stroke-dasharray:3}#mermaid-svg-2QkKSS3rdUDlobBc #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2QkKSS3rdUDlobBc #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2QkKSS3rdUDlobBc #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-2QkKSS3rdUDlobBc #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-2QkKSS3rdUDlobBc #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2QkKSS3rdUDlobBc #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2QkKSS3rdUDlobBc #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2QkKSS3rdUDlobBc #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2QkKSS3rdUDlobBc .commit-id,#mermaid-svg-2QkKSS3rdUDlobBc .commit-msg,#mermaid-svg-2QkKSS3rdUDlobBc .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-2QkKSS3rdUDlobBc g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-2QkKSS3rdUDlobBc g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-2QkKSS3rdUDlobBc g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-2QkKSS3rdUDlobBc .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-2QkKSS3rdUDlobBc .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-2QkKSS3rdUDlobBc .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-2QkKSS3rdUDlobBc .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-2QkKSS3rdUDlobBc .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-2QkKSS3rdUDlobBc .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-2QkKSS3rdUDlobBc .edgeLabel text{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2QkKSS3rdUDlobBc .node circle.state-start{fill:black;stroke:black}#mermaid-svg-2QkKSS3rdUDlobBc .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-2QkKSS3rdUDlobBc #statediagram-barbEnd{fill:#9370db}#mermaid-svg-2QkKSS3rdUDlobBc .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-2QkKSS3rdUDlobBc .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-2QkKSS3rdUDlobBc .statediagram-state .divider{stroke:#9370db}#mermaid-svg-2QkKSS3rdUDlobBc .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-2QkKSS3rdUDlobBc .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-2QkKSS3rdUDlobBc .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-2QkKSS3rdUDlobBc .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-2QkKSS3rdUDlobBc .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-2QkKSS3rdUDlobBc .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-2QkKSS3rdUDlobBc .note-edge{stroke-dasharray:5}#mermaid-svg-2QkKSS3rdUDlobBc .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-2QkKSS3rdUDlobBc .error-icon{fill:#522}#mermaid-svg-2QkKSS3rdUDlobBc .error-text{fill:#522;stroke:#522}#mermaid-svg-2QkKSS3rdUDlobBc .edge-thickness-normal{stroke-width:2px}#mermaid-svg-2QkKSS3rdUDlobBc .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-2QkKSS3rdUDlobBc .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-2QkKSS3rdUDlobBc .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-2QkKSS3rdUDlobBc .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-2QkKSS3rdUDlobBc .marker{fill:#333}#mermaid-svg-2QkKSS3rdUDlobBc .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-2QkKSS3rdUDlobBc {color: rgba(0, 0, 0, 0.75);font: ;}

sensor_attr.c
alsps.c
ltr599.c
device_create
als_misc_init
sensor_attr_register
ltr559_i2c_probe
als_register_control_path
//alsps.c
static const struct file_operations light_fops = {.owner = THIS_MODULE,.open = light_open,.read = light_read,.poll = light_poll,
};
#define ALS_MISC_DEV_NAME "m_als_misc"
static int als_misc_init(struct alsps_context *cxt)
{cxt->als_mdev.minor = ID_LIGHT;cxt->als_mdev.name = ALS_MISC_DEV_NAME;cxt->als_mdev.fops = &light_fops;sensor_attr_register(&cxt->als_mdev);}
//sensor_attr.c
int sensor_attr_register(struct sensor_attr_t *misc)
{list_for_each_entry(c, &sensor_attr_list, list) //主设备号:sensor_attr_major; 次设备号:misc->minordev = MKDEV(sensor_attr_major, misc->minor);//根据dev生成的设备号,创建光距感字符设备节点:/dev/m_als_miscmisc->this_device = device_create(sensor_attr_class, misc->parent, dev,misc, "%s", misc->name);  //misc->name = "m_als_misc"list_add(&misc->list, &sensor_attr_list);  //将misc->list放入内核sensor_attr_list链表中;sensor_event_register(misc->minor);  //后续再分析
}

2.2 分析als_register_data_path函数

als_register_data_path函数的功能主要是在alsps.c文件中通过操作get_data函数指针可以获取ltr559.c文件中的光感值;

//ltr559.c
static int ltr559_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{als_data.get_data = ltr559_als_read; //ltr559_als_read函数的功能就是将光感芯片感应到的数据通过i2c方式读取出来,然后将该函数的参数指向这个获取值;als_data.vender_div = 100;als_register_data_path(&als_data);
}//alsps.c
int als_register_data_path(struct als_data_path *data)
{struct alsps_context *cxt = NULL;cxt = alsps_context_obj;cxt->als_data.get_data = data->get_data;//get_data为获取光感函数指针cxt->als_data.vender_div = data->vender_div;if (cxt->als_data.get_data == NULL) return -1;return 0;
}

3、alsps框架下sys节点控制sensor操作流程

光距感的使能开关和数据上报都是hal层通过操作sys节点来控制的,下面以光感als为例进行分析;

3.1 初始化读取光感数据的定时器timer_als

alsps初始化时定义一个光感定时器timer_als(这个定时器初始化阶段没有启动),当定时器启动时先获取光感值再将数据上报,并每隔一段时间(默认为200ms)循环采集和上报数据;

//alsps.c
/*当timer_als定时器被触发后,超时后会调用工作队列中的als_work_func函数;
功能:1、获取ltr559.c中感应到的光感值;2、将光感值放置缓存buffer中,等待应用层读取;3、修改定时器时间,保证定时器循环不断超时触发;
*/
static void als_work_func(struct work_struct *work)
{cxt->als_data.get_data(&value, &status);  //获取ltr559.c文件中读取到的光感值;als_data_report(cxt->drv_data.als_data.values[0],cxt->drv_data.als_data.status);//上报数据mod_timer(&cxt->timer_als,jiffies + atomic_read(&cxt->delay_als) / (1000 / HZ));//修改定时器时间间隔(&cxt->delay_als)ms并启动
}
//当定时器timer_als超时时会调用als_poll函数
static void als_poll(unsigned long data)
{//将任务提交到工作队列中schedule_work(&obj->report_als);
}static struct alsps_context *alsps_context_alloc_object(void)
{atomic_set(&obj->delay_als, 200);  //obj->delay_als = 200INIT_WORK(&obj->report_als, als_work_func); //初始化工作队列init_timer(&obj->timer_als);//初始化timer_als定时器obj->timer_als.expires  = jiffies + atomic_read(&obj->delay_als)/(1000/HZ);obj->timer_als.function  = als_poll;obj->timer_als.data  = (unsigned long)obj;//下面这些参数值会作为是否启动定时器的先决条件判断obj->is_als_first_data_after_enable = false;obj->is_als_polling_run = false;obj->is_als_batch_enable = false;obj->als_power = 0;obj->als_enable = 0;obj->als_delay_ns = -1;obj->als_rgb_delay_ns = -1;obj->als_latency_ns = -1;
}

3.2 触发定时器timer_als的流程

#mermaid-svg-WDm3ieju43yYm1VA .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-WDm3ieju43yYm1VA .label text{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA .node rect,#mermaid-svg-WDm3ieju43yYm1VA .node circle,#mermaid-svg-WDm3ieju43yYm1VA .node ellipse,#mermaid-svg-WDm3ieju43yYm1VA .node polygon,#mermaid-svg-WDm3ieju43yYm1VA .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-WDm3ieju43yYm1VA .node .label{text-align:center;fill:#333}#mermaid-svg-WDm3ieju43yYm1VA .node.clickable{cursor:pointer}#mermaid-svg-WDm3ieju43yYm1VA .arrowheadPath{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-WDm3ieju43yYm1VA .flowchart-link{stroke:#333;fill:none}#mermaid-svg-WDm3ieju43yYm1VA .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-WDm3ieju43yYm1VA .edgeLabel rect{opacity:0.9}#mermaid-svg-WDm3ieju43yYm1VA .edgeLabel span{color:#333}#mermaid-svg-WDm3ieju43yYm1VA .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-WDm3ieju43yYm1VA .cluster text{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-WDm3ieju43yYm1VA .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-WDm3ieju43yYm1VA text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-WDm3ieju43yYm1VA .actor-line{stroke:grey}#mermaid-svg-WDm3ieju43yYm1VA .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-WDm3ieju43yYm1VA .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-WDm3ieju43yYm1VA #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-WDm3ieju43yYm1VA .sequenceNumber{fill:#fff}#mermaid-svg-WDm3ieju43yYm1VA #sequencenumber{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA #crosshead path{fill:#333;stroke:#333}#mermaid-svg-WDm3ieju43yYm1VA .messageText{fill:#333;stroke:#333}#mermaid-svg-WDm3ieju43yYm1VA .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-WDm3ieju43yYm1VA .labelText,#mermaid-svg-WDm3ieju43yYm1VA .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-WDm3ieju43yYm1VA .loopText,#mermaid-svg-WDm3ieju43yYm1VA .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-WDm3ieju43yYm1VA .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-WDm3ieju43yYm1VA .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-WDm3ieju43yYm1VA .noteText,#mermaid-svg-WDm3ieju43yYm1VA .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-WDm3ieju43yYm1VA .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-WDm3ieju43yYm1VA .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-WDm3ieju43yYm1VA .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-WDm3ieju43yYm1VA .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA .section{stroke:none;opacity:0.2}#mermaid-svg-WDm3ieju43yYm1VA .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-WDm3ieju43yYm1VA .section2{fill:#fff400}#mermaid-svg-WDm3ieju43yYm1VA .section1,#mermaid-svg-WDm3ieju43yYm1VA .section3{fill:#fff;opacity:0.2}#mermaid-svg-WDm3ieju43yYm1VA .sectionTitle0{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA .sectionTitle1{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA .sectionTitle2{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA .sectionTitle3{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-WDm3ieju43yYm1VA .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA .grid path{stroke-width:0}#mermaid-svg-WDm3ieju43yYm1VA .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-WDm3ieju43yYm1VA .task{stroke-width:2}#mermaid-svg-WDm3ieju43yYm1VA .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA .taskText:not([font-size]){font-size:11px}#mermaid-svg-WDm3ieju43yYm1VA .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-WDm3ieju43yYm1VA .task.clickable{cursor:pointer}#mermaid-svg-WDm3ieju43yYm1VA .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WDm3ieju43yYm1VA .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WDm3ieju43yYm1VA .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WDm3ieju43yYm1VA .taskText0,#mermaid-svg-WDm3ieju43yYm1VA .taskText1,#mermaid-svg-WDm3ieju43yYm1VA .taskText2,#mermaid-svg-WDm3ieju43yYm1VA .taskText3{fill:#fff}#mermaid-svg-WDm3ieju43yYm1VA .task0,#mermaid-svg-WDm3ieju43yYm1VA .task1,#mermaid-svg-WDm3ieju43yYm1VA .task2,#mermaid-svg-WDm3ieju43yYm1VA .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-WDm3ieju43yYm1VA .taskTextOutside0,#mermaid-svg-WDm3ieju43yYm1VA .taskTextOutside2{fill:#000}#mermaid-svg-WDm3ieju43yYm1VA .taskTextOutside1,#mermaid-svg-WDm3ieju43yYm1VA .taskTextOutside3{fill:#000}#mermaid-svg-WDm3ieju43yYm1VA .active0,#mermaid-svg-WDm3ieju43yYm1VA .active1,#mermaid-svg-WDm3ieju43yYm1VA .active2,#mermaid-svg-WDm3ieju43yYm1VA .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-WDm3ieju43yYm1VA .activeText0,#mermaid-svg-WDm3ieju43yYm1VA .activeText1,#mermaid-svg-WDm3ieju43yYm1VA .activeText2,#mermaid-svg-WDm3ieju43yYm1VA .activeText3{fill:#000 !important}#mermaid-svg-WDm3ieju43yYm1VA .done0,#mermaid-svg-WDm3ieju43yYm1VA .done1,#mermaid-svg-WDm3ieju43yYm1VA .done2,#mermaid-svg-WDm3ieju43yYm1VA .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-WDm3ieju43yYm1VA .doneText0,#mermaid-svg-WDm3ieju43yYm1VA .doneText1,#mermaid-svg-WDm3ieju43yYm1VA .doneText2,#mermaid-svg-WDm3ieju43yYm1VA .doneText3{fill:#000 !important}#mermaid-svg-WDm3ieju43yYm1VA .crit0,#mermaid-svg-WDm3ieju43yYm1VA .crit1,#mermaid-svg-WDm3ieju43yYm1VA .crit2,#mermaid-svg-WDm3ieju43yYm1VA .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-WDm3ieju43yYm1VA .activeCrit0,#mermaid-svg-WDm3ieju43yYm1VA .activeCrit1,#mermaid-svg-WDm3ieju43yYm1VA .activeCrit2,#mermaid-svg-WDm3ieju43yYm1VA .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-WDm3ieju43yYm1VA .doneCrit0,#mermaid-svg-WDm3ieju43yYm1VA .doneCrit1,#mermaid-svg-WDm3ieju43yYm1VA .doneCrit2,#mermaid-svg-WDm3ieju43yYm1VA .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-WDm3ieju43yYm1VA .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-WDm3ieju43yYm1VA .milestoneText{font-style:italic}#mermaid-svg-WDm3ieju43yYm1VA .doneCritText0,#mermaid-svg-WDm3ieju43yYm1VA .doneCritText1,#mermaid-svg-WDm3ieju43yYm1VA .doneCritText2,#mermaid-svg-WDm3ieju43yYm1VA .doneCritText3{fill:#000 !important}#mermaid-svg-WDm3ieju43yYm1VA .activeCritText0,#mermaid-svg-WDm3ieju43yYm1VA .activeCritText1,#mermaid-svg-WDm3ieju43yYm1VA .activeCritText2,#mermaid-svg-WDm3ieju43yYm1VA .activeCritText3{fill:#000 !important}#mermaid-svg-WDm3ieju43yYm1VA .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-WDm3ieju43yYm1VA g.classGroup text .title{font-weight:bolder}#mermaid-svg-WDm3ieju43yYm1VA g.clickable{cursor:pointer}#mermaid-svg-WDm3ieju43yYm1VA g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-WDm3ieju43yYm1VA g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-WDm3ieju43yYm1VA .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-WDm3ieju43yYm1VA .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-WDm3ieju43yYm1VA .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-WDm3ieju43yYm1VA .dashed-line{stroke-dasharray:3}#mermaid-svg-WDm3ieju43yYm1VA #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WDm3ieju43yYm1VA #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WDm3ieju43yYm1VA #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-WDm3ieju43yYm1VA #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-WDm3ieju43yYm1VA #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WDm3ieju43yYm1VA #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WDm3ieju43yYm1VA #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WDm3ieju43yYm1VA #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WDm3ieju43yYm1VA .commit-id,#mermaid-svg-WDm3ieju43yYm1VA .commit-msg,#mermaid-svg-WDm3ieju43yYm1VA .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-WDm3ieju43yYm1VA g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-WDm3ieju43yYm1VA g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-WDm3ieju43yYm1VA g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-WDm3ieju43yYm1VA .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-WDm3ieju43yYm1VA .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-WDm3ieju43yYm1VA .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-WDm3ieju43yYm1VA .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-WDm3ieju43yYm1VA .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-WDm3ieju43yYm1VA .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-WDm3ieju43yYm1VA .edgeLabel text{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WDm3ieju43yYm1VA .node circle.state-start{fill:black;stroke:black}#mermaid-svg-WDm3ieju43yYm1VA .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-WDm3ieju43yYm1VA #statediagram-barbEnd{fill:#9370db}#mermaid-svg-WDm3ieju43yYm1VA .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-WDm3ieju43yYm1VA .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-WDm3ieju43yYm1VA .statediagram-state .divider{stroke:#9370db}#mermaid-svg-WDm3ieju43yYm1VA .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-WDm3ieju43yYm1VA .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-WDm3ieju43yYm1VA .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-WDm3ieju43yYm1VA .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-WDm3ieju43yYm1VA .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-WDm3ieju43yYm1VA .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-WDm3ieju43yYm1VA .note-edge{stroke-dasharray:5}#mermaid-svg-WDm3ieju43yYm1VA .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-WDm3ieju43yYm1VA .error-icon{fill:#522}#mermaid-svg-WDm3ieju43yYm1VA .error-text{fill:#522;stroke:#522}#mermaid-svg-WDm3ieju43yYm1VA .edge-thickness-normal{stroke-width:2px}#mermaid-svg-WDm3ieju43yYm1VA .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-WDm3ieju43yYm1VA .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-WDm3ieju43yYm1VA .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-WDm3ieju43yYm1VA .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-WDm3ieju43yYm1VA .marker{fill:#333}#mermaid-svg-WDm3ieju43yYm1VA .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-WDm3ieju43yYm1VA {color: rgba(0, 0, 0, 0.75);font: ;}

alsps.c
满足条件A
满足条件B
als_store_active
als_store_batch
als_enable_and_batch
mod_timer<&cxt->timer_als>
del_timer_sync<&cxt->timer_als>

timer_als定时器触发是通过alsps.c文件中alsactivealsbatch两个节点的写函数来控制的:als_store_activeals_store_batch

3.2.1 在als_enable_and_batch函数中启动timer_als定时器的满足条件A:

1、cxt->als_power == 0 && cxt->als_enable == 1
==>cxt->als_power默认初始值为0,cxt->als_enable在als_store_active函数有设置;
2、cxt->als_delay_ns >= 0
==>在als_store_batch函数中有设置
3、cxt->als_ctl.is_report_input_direct == false
==>根据ltr559.c中的ctl->is_report_input_direct的变量决定的;
4、cxt->is_als_polling_run == false
==>默认初始值为false,满足条件;

在ltr559.c中的is_report_input_direct默认设置为false的情况下:
echo 4,0,200000000,0 > /sys/class/sensor/m_als_misc/alsbatch,设置als_delay_ns=200000000 //200ms
echo 4,1 > /sys/class/sensor/m_als_misc/alsactive,设置als_enable =1;
满足条件A,打开定时器上报数据;

3.2.2 在als_enable_and_batch函数中取消timer_als定时器的满足条件B:

1、cxt->als_power == 1 && cxt->als_enable == 0
2、cxt->als_ctl.is_report_input_direct == false && cxt->is_als_polling_run == true

当timer_als定时器打开时,第二个条件已经满足了,只需要将als_enable =0就能关闭定时器;
echo 4,0 > /sys/class/sensor/m_als_misc/alsactive

//alsps.c
static ssize_t als_store_active(struct device *dev,struct device_attribute *attr, const char *buf,size_t count)
{sscanf(buf, "%d,%d", &handle, &en);if (handle == ID_LIGHT) { //ID_LIGHT = 4if (en) {cxt->als_enable = 1;last_als_report_data = -1;} else if (!en) {cxt->als_enable = 0;}als_enable_and_batch();
}
//alsps.c
static ssize_t als_store_batch(struct device *dev,struct device_attribute *attr, const char *buf,size_t count)
{sscanf(buf, "%d,%d,%lld,%lld", &handle, &flag, &delay_ns, &latency_ns);if (handle == ID_LIGHT) { //ID_LIGHT = 4cxt->als_delay_ns = delay_ns;cxt->als_latency_ns = latency_ns;err = als_enable_and_batch();} else if (handle == ID_RGBW) { //ID_RGBW = 69cxt->als_rgb_delay_ns = delay_ns;cxt->rgbw_latency_ns = latency_ns;}
}
DEVICE_ATTR(alsactive,      S_IWUSR | S_IRUGO, als_show_active, als_store_active);
DEVICE_ATTR(alsbatch,       S_IWUSR | S_IRUGO, als_show_batch,  als_store_batch);
//alsps.c
static int als_enable_and_batch(void)
{mod_timer(&cxt->timer_als,jiffies +atomic_read(&cxt->delay_als) /(1000 / HZ));
}static int als_enable_and_batch(void)
{/* als_power on -> power off */if (cxt->als_power == 1 && cxt->als_enable == 0) {if (cxt->als_ctl.is_report_input_direct == false &&cxt->is_als_polling_run == true) {del_timer_sync(&cxt->timer_als);  //删除timer_als光感定时器cancel_work_sync(&cxt->report_als);cxt->drv_data.als_data.values[0] = ALSPS_INVALID_VALUE;cxt->is_als_polling_run = false;}cxt->als_ctl.enable_nodata(0);cxt->als_power = 0;cxt->als_delay_ns = -1;return 0;}/* als_power off -> power on */if (cxt->als_power == 0 && cxt->als_enable == 1) {cxt->als_ctl.enable_nodata(1);cxt->als_power = 1;}if (cxt->als_power == 1 && cxt->als_delay_ns >= 0) {     if (cxt->als_ctl.is_support_batch)cxt->als_ctl.batch(0, cxt->als_delay_ns,cxt->als_latency_ns);elsecxt->als_ctl.batch(0, cxt->als_delay_ns, 0);           if (cxt->als_ctl.is_report_input_direct == false) {int mdelay = cxt->als_delay_ns;do_div(mdelay, 1000000);atomic_set(&cxt->delay_als, mdelay);if (cxt->is_als_polling_run == false) {mod_timer(&cxt->timer_als,jiffies +atomic_read(&cxt->delay_als) /(1000 / HZ));//设置timer_als光感定时器的时间间隔并启动cxt->is_als_polling_run = true;cxt->is_als_first_data_after_enable = true;}}}return 0;
}

注:mtk平台重感accel框架和光距感的alsps框架流程是类似的,想要分析重感accel框架可以在kernel-4.4/drivers/misc/mediatek/sensors-1.0/accelerometer/accel.c浏览;

mtk平台sensor分析一:alsps框架下的光距感驱动流程相关推荐

  1. MTK 平台sensor arch 介绍-hal

    MTK 平台sensor arch 介绍-hal 一:整体框架 二:具体流程简介 AP-HAL: (1)init & control flow 我们以前文的originchannel 的 ac ...

  2. MTK 平台sensor arch 介绍-kernel

    MTK 平台sensor arch 介绍-kernel AP-kernel 1.文件相关介绍 1.进入到(core) 2.进入到(mtk_nanohub) 3.(lsm6dsm_secondary)是 ...

  3. 基于Lua框架下Air103使用U8g2库驱动I2C OLED图像显示

    基于Lua框架下Air103使用U8g2库驱动I2C OLED屏幕图像演示

  4. MTK 平台sensor arch 介绍-scp

    架构介绍 路径:vendor/mediatek/proprietary/tinysys/scp 1.[build]编译相关 2.[driver]scp 的driver,I2C,power,eint 3 ...

  5. MTK平台功耗分析总结

    1.MTK平台各个场景功耗数据测试方法 很多功耗问题都是因为测试手法不对,列出一些常用场景功耗测试手法.  测试功耗数据之前,请先确认以下配置:  1.关闭 WIFI/BT/GPS,关闭数据连接,设置 ...

  6. mtk android 笔记,Android驱动笔记(9)——MTK平台Sensor Bring Up

    sensor的img位于scp.img 9.1.在成熟的平台Bring Up 在已知的平台上驱动并验证一个器件是很常见的工作.因为管脚等基本不需要重新配置.所以只需要按照一般步骤驱动即可.驱动代码位置 ...

  7. MTK平台AEE_AED分析

    /vendor/mediatek/proprietary/external/aee/config_external/init.aee.customer.vendor.rc里添加 on init set ...

  8. 【android睡眠唤醒 二】MTK平台唤醒框架分解

    在文章MTK 唤醒时间分析中分析了内核中的主要的亮屏重要阶段,此篇文章结合上层的log一起来分析下整个系统的亮屏流程.整个流程可以分为如下几个部分: (1)power键(home键)产生并上报(在in ...

  9. php封装公共方法,TP框架下封装公共函数详解

    本篇文章讲述了如何在TP框架下封装公共函数,大家对TP框架下封装公共函数不了解的话或者对TP框架下封装公共函数感兴趣的话那么我们就一起来看看本篇文章吧, 好了废话少说进入正题吧 当我们需要在控制层调用 ...

  10. MTK平台闪光灯驱动分析

    MTK平台闪光灯驱动分析   以前没写过博客,总想写着来着,把之前学到的做过的东西都记录下来,但是一直没有时间也没那么大的决心.这次趁着刚换工作,正在学习熟悉平台不是太忙的机会,把自己总结的文档写下来 ...

最新文章

  1. python 点云las、laz文件的读取、写入、压缩
  2. 普华永道:2018 AI预测报告 将回答关于数据的重大问题
  3. 手机webapp meta标签 (全屏)
  4. FileChannel应用实例——拷贝文件transferFrom方法
  5. (一)Windows环境下汇编编程读书笔记
  6. Hibernate之悲观锁与乐观锁
  7. 有关文档碎片(document fragment)的用法
  8. 文件怎么更新_干货!Win10更新总失败?学会这三招搞定它
  9. 计算机基础视频教程百度云,计算机应用基础视频教程
  10. 创建物理卷报错Can't open /dev/sdb5 exclusively. Mounted filesystem的问题解决过程记录
  11. c语言编程百分比,c – 计算百分比
  12. 姓名签名设计手写简单自己名字怎么写
  13. java合成图片并添加文字
  14. 输出1-1000内 所有 7 的倍数或个位是7的整数。
  15. Ubuntu 安装MinGW32出现Unable to locate package mingw32找不到安装包的解决方法和思路
  16. AndroidX初识
  17. 丁香医生vue开发项目,接口用的主要是官方开放的Api接口,无后端
  18. 武铁机械电子工程_机械电子工程
  19. 11项关键先进制造技术解读!
  20. 【PTA】7-14 福到了

热门文章

  1. 图像相似度对比分析软件,图像相似度计算方法
  2. 使用phpQuery获取数组
  3. 嵌入式中的 C 语言
  4. 淘宝闲鱼等电商平台数据采集软件
  5. 简单使用Java实现微信公众号推送模板消息
  6. 关于永洪BI Kerberos机制的详细介绍
  7. java定时任务 时间_java 定时任务的执行时间表示-
  8. Code::Blocks下载及其汉化教程
  9. 基于Matlab高斯光束前向与后向传播的模拟
  10. C#汉字转拼音的实现方法