HAL层使用sensor2.0,kernel使用sensor AP侧驱动
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、makefile与Kconfig
- 二、AP侧驱动+配置
- 1.makefile与Kconfig
- 2.AP侧驱动 + 注册
- 三、HAL层修改
前言
上层使用sensor2.0,其中使用hf manager控制,驱动使用sensor1.0会出现数据不通的情况,一般适配2.0的sensorhub,但是产品需要使用AP侧的驱动,因此需要在ap侧驱动注册相关的hf manager sensor。
提示:以下是本篇文章正文内容,下面案例可供参考
一、makefile与Kconfig
kernel-5.10/drivers/misc/mediatek/sensor/2.0/Makefile
+source"drivers/misc/mediatek/sensor/2.0/stk3x1x/Kconfig"kernel-5.10/drivers/misc/mediatek/sensor/2.0/Kconfig
+obj-y+=stk3x1x/昨晚上述两步即可,
至于相关的hf_manager的配置,这里就不描述了,正常打开即可
二、AP侧驱动+配置
1.makefile与Kconfig
kernel-5.10/drivers/misc/mediatek/sensor/2.0/stk3x1x/Makefile
ccflags-y+=-I$(srctree)/drivers/misc/mediatek/sensor/2.0/core obj-$(CONFIG_MTK_SENSOR_SUPPORT)+=stk3x1x.okernel-5.10/drivers/misc/mediatek/sensor/2.0/stk3x1x/Kconfig
config MTK_STK3X1X_NEW bool"STK3X1X for MediaTek package"help It support different type sensor in this platform.If this option is set,it will support ambient and light sensor STK3X1X.2.AP侧驱动 + 注册
这里头文件就不列出来了,主要关注AP侧驱动的内容
kernel-5.10/drivers/misc/mediatek/sensor/2.0/stk3x1x/stk3x1x.c
// SPDX-License-Identifier: GPL-2.0/* * Copyright (c) 2020 MediaTek Inc. */#include<linux/of.h>#include<linux/of_address.h>#include<linux/of_irq.h>#include<linux/gpio.h>#include<linux/interrupt.h>#include<linux/i2c.h>#include<linux/slab.h>#include<linux/irq.h>#include<linux/miscdevice.h>#include<linux/uaccess.h>#include<linux/delay.h>#include<linux/input.h>#include<linux/workqueue.h>#include<linux/kobject.h>#include<linux/platform_device.h>#include<linux/atomic.h>#include<linux/version.h>#include<linux/fs.h>#include<linux/io.h>#include<linux/module.h>#include<linux/pm_wakeup.h>#include"cust_alsps.h"#include"stk3x1x.h"#include"hf_manager.h"//这个头文件需要添加#defineDRIVER_VERSION"3.9.2 20180403"/* * configuration */#definestk3x1x_DEV_NAME"stk3x1x"//这里去掉一些不必要的内容。。。/* * hf manager属性的设置,这里先声明 */staticstructsensor_infosupport_sensors[SENSOR_TYPE_SENSOR_MAX];structworkqueue_struct*stk_sample_workq;structwork_structkick_stk_work;/* * 这里是使能传感器,传感器的驱动active放到这里即可 */staticintlight_enable(structhf_device*hfdev,intsensor_type,inten){interr=0;if(en){stk3x1x_enable(1);//这个是enable sensor,一般是上电、初始化sensor寄存器}else{stk3x1x_enable(0);//这个就是disable sensor}returnerr;}/* * 这个不用管,一般是做打印 */staticintlight_batch(structhf_device*hfdev,intsensor_type,int64_tdelay,int64_tlatency){pr_debug("%s id:%d delay:%lld latency:%lld\n",__func__,sensor_type,delay,latency);return0;}/* * 工作函数 */staticvoidstk_kick_work(structwork_struct*work){interr;structstk3x1x_priv*obj=stk3x1x_obj;/* * 读取光感数据 */err=stk3x1x_read_als(&obj->als);//这个就是sample执行主要执行的内容if(err){printk("%s stk3x1x_read_als failed %d\n",__func__,err);}}/* * 这个是做上报数据,及开启传感器后,获取到的数据,在这里上报 */staticintlight_sample(structhf_device*hfdev){//这里使用工作队列,是因为HAL层是定时sample,不能直接获取数据,需要使用workerqueue_work(stk_sample_workq,&kick_stk_work);data=obj->als;//工作队列里,执行sensor的read raw data得到的数据memset(&event,0,sizeof(structhf_manager_event));event.timestamp=ktime_to_ns(ktime_get_boottime());event.sensor_type=SENSOR_TYPE_LIGHT;//添加上报的sensor信息event.accurancy=SENSOR_ACCURANCY_HIGH;event.action=DATA_ACTION;event.word[0]=data;manager->report(manager,&event);//上报manager->complete(manager);//完成return0;}/* * 把这个驱动注册到df manager里 */intlight_hf_register(void){interr=0;structstk3x1x_priv*obj=stk3x1x_obj;//这个是驱动的私有属性,里面包含了struct hf_device hf_dev;charm_name[16]="stk3321";//这个要与HAL层注册的信息一致,不然HAL层HF_MANAGER会出现找不到驱动的情况charm_vendor[16]="stk";inti=0;//定义需要注册的 sensor 信息support_sensors[0].sensor_type=SENSOR_TYPE_LIGHT;//这个是光感support_sensors[0].gain=1;//这个是增益,kernel这计算是没有小数点的,根据实际需要修改for(i=0;i<16;i++){support_sensors[0].name[i]=m_name[i];support_sensors[0].vendor[i]=m_vendor[i];}obj->hf_dev.dev_name=stk3x1x_DEV_NAME;obj->hf_dev.device_poll=HF_DEVICE_IO_POLLING;//采用轮询的方式获取数据obj->hf_dev.device_bus=HF_DEVICE_IO_ASYNC;obj->hf_dev.support_list=support_sensors;//这里就对上述sensor信息进行赋值obj->hf_dev.support_size=1;//这个看具体数量,这里只有1个,所以为1obj->hf_dev.enable=light_enable;//这个是Sensor的使能回调,hal层的使能就是走这obj->hf_dev.batch=light_batch;//这个demo里是打印obj->hf_dev.sample=light_sample;//这个是采样,上层会定时调用这个回调err=hf_device_register_manager_create(&obj->hf_dev);//这个就是注册if(err<0){pr_err("%s hf_manager_create fail\n",__func__);err=-1;}return0;}staticintstk3x1x_i2c_probe(structi2c_client*client,conststructi2c_device_id*id){...//一般放到最后,确认sensor i2c可通讯 再注册light_hf_register();//注册工作队列,是因为上层定时调用sample,sensor获取数据的api带锁,会出现问题stk_sample_workq=create_singlethread_workqueue("stk_sample_workq");INIT_WORK(&kick_stk_work,stk_kick_work);...}三、HAL层修改
/vendor/mediatek/proprietary/hardware/sensor/2.0/hal/SensorListV2.cpp
voidSensorListV2::initSensorList(void){structsensor_tsensor;//这个找一个SENSOR_TYPE_LIGHT 抄上,后面有很多memset(&sensor,0,sizeof(structsensor_t));sensor.name="stk3321";sensor.vendor="stk";sensor.version=1;sensor.handle=SENSOR_TYPE_LIGHT;sensor.type=SENSOR_TYPE_LIGHT;sensor.maxRange=65535.0f;sensor.resolution=1.0f;sensor.power=0;sensor.minDelay=0;sensor.fifoReservedEventCount=0;sensor.fifoMaxEventCount=0;sensor.stringType=SENSOR_STRING_TYPE_LIGHT;sensor.maxDelay=1000000;sensor.flags=SENSOR_FLAG_ON_CHANGE_MODE;mSensorList.push_back(sensor);。。。}