MTK Android P Sensor架构(二)

不过不同的芯片平台,kernel层中的sensor框架是不同的,这里针对的是mt8167s平台。不过这里提醒一下,MTK平台应该从kernel 3.x版本后就不支持温湿度传感器的框架了,不过幸好他们还保留了框架的雏形在,我们需要自行解决一下编译问题。

正文

我们先看一下代码的具体目录:

cpp 复制代码
drivers/misc/mediatek/sensors-1.0$ ls
accelerometer/    alsps/      dummy.c     humidity/       magnetometer/  sensorHub/        accelgyro/
barometer/        geofence/   hwmon/      Makefile        situation/     activity_sensor/  
biometric/        gyroscope/  Kconfig     sensorfusion/   step_counter

目录结构很清晰,不同的sensor都有单独的目录,这篇文章我们还是以湿度传感器为例,所以这里单独研究一下humidity。还是先看一下代码目录结构:

cpp 复制代码
drivers/misc/mediatek/sensors-1.0/humidity$ ls
aht10/  hmdyhub/  humidity.c  humidity_factory.c  inc/  Kconfig  Makefile

humidity.c文件为不同型号的湿度传感器驱动提供一些公共的接口,也可以说是MTK为我们抽象一个有关humidity sensor的基本架构。在移植一个新型号的sensor时,只要将其通过公共接口注册进系统就可以了。

1、初始化

cpp 复制代码
static struct hmdy_init_info aht10_init_info = {
  .name = "aht10",
  .init = aht10_local_init,
  .uninit = aht10_local_uninit,
 
};
 
static int __init aht10_init(void)
{
 hmdy_driver_add(&aht10_init_info);
 AHT_FUN();   
 return 0;
}

在aht10驱动初始化的时候,通过hmdy_driver_add接口把我们的aht10驱动注册进系统

cpp 复制代码
int hmdy_driver_add(struct hmdy_init_info *obj)
{
 int err = 0;
 int i = 0;
 
 HMDY_FUN();
 if (!obj) {
  HMDY_PR_ERR("HMDY driver add fail, hmdy_init_info is NULL\n");
  return -1;
 }
 
 for (i = 0; i < MAX_CHOOSE_HMDY_NUM; i++) {
  if (i == 0) {
   HMDY_LOG("register humidity driver for the first time\n");
   if (platform_driver_register(&humidity_driver))
    HMDY_PR_ERR("failed to register gensor driver already exist\n");
  }
 
  if (humidity_init_list[i] == NULL) {
   obj->platform_diver_addr = &humidity_driver;
   humidity_init_list[i] = obj;
   break;
  }
 }
 if (i >= MAX_CHOOSE_HMDY_NUM) {
  HMDY_PR_ERR("HMDY driver add err\n");
  err = -1;
 }
 
 return err;
 
}

其实就是将我们自定义的struct hmdy_init_info aht10_init_info结构体保存到全局变量数组humidity_init_list中。然后在humidity驱动起来的时候,会通过hmdy_real_driver_init()接口调用已经注册的sensor的init函数:

cpp 复制代码
static int hmdy_real_driver_init(void)
{
 int i = 0;
 int err = 0;
 
 for (i = 0; i < MAX_CHOOSE_HMDY_NUM; i++) {
  if (humidity_init_list[i] != 0) {
   err = humidity_init_list[i]->init();
   if (err == 0) {
    break;
   }
  }
 }
 
 if (i == MAX_CHOOSE_HMDY_NUM) {
  err = -1;
 }
 return err;
 
}

这里的init()函数对应到我们sensor的aht10_local_init函数:

cpp 复制代码
static int aht10_local_init(void)
{
    if (i2c_add_driver(&aht10_i2c_driver)) {
  return -1;
 }
 if (-1 == aht10_init_flag) {
  return -1;
 }
 return 0;
}

到这里就是我们熟悉的I2C设备注册函数了i2c_add_driver()。假设我们的sensor设备也正常加入到系统,调用我们自定义的probe函数,这里面就需要我们进行三步重要的操作:

(1)设置设备资源 sensor框架为我们提供了接口get_hmdy_dts_func()去解析我们的设备资源,包含I2C的地址,是否支持设置采样率等等。

(2)struct hmdy_control_path 我们要设置自己的struct hmdy_control_path结构体初始值:

cpp 复制代码
struct hmdy_control_path hmdy_control_path = {0};
 
hmdy_control_path.is_use_common_factory = false;
hmdy_control_path.open_report_data = aht10_open_report_data; /* 作用未知,一般直接返回就好 */
hmdy_control_path.enable_nodata = aht10_enable_nodata; /* 上层在打开sensor设备的时候,会调用到这个函数 */
hmdy_control_path.set_delay = aht10_set_delay; /* 字面上是用来设置延时,不过如果不需要可以直接返回 */
hmdy_control_path.is_report_input_direct = false; 
hmdy_control_path.is_support_batch = dev_data->hw->is_batch_supported_hmdy; /* 是否支持设置采样率 */
 
ret = hmdy_register_control_path(&hmdy_control_path); /* 将前面设置好的struct hmdy_control_path结构体通过公共接口注册进系统 */
if (ret) {
 AHT_INFO("register hmdy control path err\n");
 goto exit_delete_attr;
}

(3)struct hmdy_data_path

cpp 复制代码
struct hmdy_data_path hmdy_data_path = {0};
hmdy_data_path.get_data = aht10_get_humidity_data;
hmdy_data_path.vender_div = 10;
ret = hmdy_register_data_path(&hmdy_data_path);
if (ret) {
 AHT_INFO("hmdy_register_data_path failed, ret = %d\n", ret);
 goto exit_delete_attr;
}

这个结构体才是重头戏,其中get_data接口就是用来获取sensor想要上报的数据:

cpp 复制代码
int (*get_data)(int *value, int *status);

其中,value就是上报的数据值,同时通过status上报sensor的状态。另外,上报的数据有时候需要调整一个百分比,那么就会用到vender_div值了,在调试过程中自行调整即可。设置完毕就可以通过接口hmdy_register_data_path()将我们自定义的结构体注册进系统了。

结语

kernel层框架的要点大概就这么多,不同的sensor,基本的驱动流程都类似,读完我这系列文章后应该就能一通百通了。

相关推荐
JMchen12337 分钟前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
crmscs1 小时前
剪映永久解锁版/电脑版永久会员VIP/安卓SVIP手机永久版下载
android·智能手机·电脑
localbob1 小时前
杀戮尖塔 v6 MOD整合版(Slay the Spire)安卓+PC端免安装中文版分享 卡牌肉鸽神作!杀戮尖塔中文版,电脑和手机都能玩!杀戮尖塔.exe 杀戮尖塔.apk
android·杀戮尖塔apk·杀戮尖塔exe·游戏分享
机建狂魔1 小时前
手机秒变电影机:Blackmagic Camera + LUT滤镜包的专业级视频解决方案
android·拍照·摄影·lut滤镜·拍摄·摄像·录像
hudawei9961 小时前
flutter和Android动画的对比
android·flutter·动画
lxysbly3 小时前
md模拟器安卓版带金手指2026
android
儿歌八万首4 小时前
硬核春节:用 Compose 打造“赛博鞭炮”
android·kotlin·compose·春节
消失的旧时光-19437 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
Jinkxs7 小时前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&7 小时前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin