一、前言
本文主要分析mtk平台hal层如何获取alps框架下光距感数据和光距感的使能开关对应的hal层接口;
hal层涉及文件及目录
:
vendor/mediatek/proprietary/hardware/sensor/sensors-1.0/sensors.cpp
vendor/mediatek/proprietary/hardware/sensor/sensors-1.0/SensorContext.cpp
vendor/mediatek/proprietary/hardware/sensor/sensors-1.0/SensorEventReader.cpp
vendor/mediatek/proprietary/hardware/sensor/sensors-1.0/AmbienteLight.cpp
kernel层涉及文件
:
kernel-4.4/drivers/misc/mediatek/sensors-1.0/alsps/alsps.c
kernel-4.4/drivers/misc/mediatek/sensors-1.0/hwmon/sensor_event/sensor_event.c
二、光距感上报数据的流程
应用层获取光感数据的方式通过open “/dev/m_als_misc”
设备节点,调用read函数即可读取到alps架构下的光感数据;
参考第一章所讲的timer_als定时器触发流程,在机器开机的过程中,默认设置下hal层会操控/sys/class/sensor/m_als_misc/alsactive
节点,触发定时器,光感数据通过als_data_report->sensor_input_event函数将获取到的光感值添加到全局的缓存队列buffer中,同时唤醒sensor_event_poll函数中的client->wait等待队列;sensor_event_poll函数就会将对应应用层的休眠进程唤醒,表示这个设备有数据可读,最后调用对应的read函数来读取光感值;
//alsps.c
//light_fops
static int light_open(struct inode *inode, struct file *file)
{
nonseekable_open(inode, file); //在 open 方法中调用 nonseekable_open() 时,它会通知内核设备不支持 llseek
return 0;
}
static ssize_t light_read(struct file *file, char __user *buffer, size_t count,
loff_t *ppos)
{
ssize_t read_cnt = 0;
read_cnt = sensor_event_read(alsps_context_obj->als_mdev.minor, file,
buffer, count, ppos);
return read_cnt;
}
static unsigned int light_poll(struct file *file, poll_table *wait)
{
return sensor_event_poll(alsps_context_obj->als_mdev.minor, file, wait);
}
hal层中open ”/dev/m_als_misc“
获取fd文件描述符,根据fd,调用read函数来读取内核中的数据;sensor_event_read函数就是该节点对应的内核读取数据的具体实现;
//sensors-1.0\hwmon\sensor_event\sensor_event.c
ssize_t sensor_event_read(unsigned char handle, struct file *file, char __user *buffer,
size_t count, loff_t *ppos)
{
struct sensor_event_client *client = &event_obj->client[handle];
struct sensor_event event;
size_t read = 0;
if (count != 0 && count < sizeof(struct sensor_event)) {
SE_PR_ERR("sensor_event_read handle: %d err count(%d)\n", handle, (int)count);
return -EINVAL;
}
for (;;) {
if (client->head == client->tail) {
return 0;
}
if (count == 0) {
SE_LOG("sensor_event_read count: %d\n", (int)count);
break;
}
while (read + sizeof(struct sensor_event) <= count &&
sensor_event_fetch_next(client, &event)) {
if (copy_to_user(buffer + read, &event, sizeof(struct sensor_event)))
return -EFAULT;
read