HID 传感器框架¶
HID 传感器框架提供必要的接口来实现连接到传感器集线器的传感器驱动程序。传感器集线器是一个 HID 设备,它提供符合 HID 1.12 传感器使用表的报告描述符。
来自 HID 1.12 “HID 传感器使用”规范的描述:“传感器 HID 使用的标准化将允许(但不要求)传感器硬件供应商在 USB 边界提供一致的即插即用接口,从而使某些操作系统能够合并可以在供应商之间重用的通用设备驱动程序,从而减轻供应商自己提供驱动程序的任何需要。”
该规范描述了许多使用 ID,这些 ID 描述了传感器的类型以及各个数据字段。每个传感器可以有可变数量的数据字段。长度和顺序在报告描述符中指定。例如,报告描述符的一部分可能如下所示
INPUT(1)[INPUT]
..
Field(2)
Physical(0020.0073)
Usage(1)
0020.045f
Logical Minimum(-32767)
Logical Maximum(32767)
Report Size(8)
Report Count(1)
Report Offset(16)
Flags(Variable Absolute)
..
..
该报告表示“传感器页面 (0x20)”包含一个加速度计-3D (0x73)。此加速度计-3D 具有一些字段。例如,此处字段 2 是运动强度 (0x045f),逻辑最小值为 -32767,逻辑最大值为 32767。字段的顺序和每个字段的长度很重要,因为输入事件原始数据将使用此格式。
实现¶
该规范定义了许多不同类型的传感器,具有不同的数据集字段。对于不同的传感器,很难为用户空间应用程序提供通用的输入事件。例如,加速度计可以发送 X、Y 和 Z 数据,而环境光传感器可以发送照明数据。因此,该实现分为两个部分
核心 HID 驱动程序
各个传感器处理部分(传感器驱动程序)
核心驱动程序¶
核心驱动程序 (hid-sensor-hub) 注册为 HID 驱动程序。它解析报告描述符并识别所有存在的传感器。它添加一个名为 HID-SENSOR-xxxx 的 MFD 设备(其中 xxxx 是规范中的使用 ID)。
例如
HID-SENSOR-200073 注册用于加速度计 3D 驱动程序。
因此,如果插入任何具有此名称的驱动程序,则将调用该功能的探测例程。因此,加速度计处理驱动程序可以使用此名称注册,如果检测到加速度计-3D,则将进行探测。
核心驱动程序提供一组 API,处理驱动程序可以使用这些 API 来注册并获取该使用 ID 的事件。它还提供解析函数,用于获取和设置每个输入/功能/输出报告。
各个传感器处理部分(传感器驱动程序)¶
处理驱动程序将使用核心驱动程序提供的接口来解析报告并获取字段的索引,还可以获取事件。此驱动程序可以使用 IIO 接口来使用为传感器类型定义的标准 ABI。
核心驱动程序接口¶
回调结构
Each processing driver can use this structure to set some callbacks.
int (*suspend)(..): Callback when HID suspend is received
int (*resume)(..): Callback when HID resume is received
int (*capture_sample)(..): Capture a sample for one of its data fields
int (*send_event)(..): One complete event is received which can have
multiple data fields.
注册函数
int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
u32 usage_id,
struct hid_sensor_hub_callbacks *usage_callback):
注册使用 ID 的回调函数。不允许回调函数休眠
int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
u32 usage_id):
删除使用 ID 的回调函数。
解析函数
int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
u8 type,
u32 usage_id, u32 attr_usage_id,
struct hid_sensor_hub_attribute_info *info);
处理驱动程序可以查找报告描述符中存在的某些感兴趣的字段。如果存在,它将存储必要的信息,以便可以单独设置或获取字段。这些索引避免了每次搜索并获取字段索引来获取或设置。
设置功能报告
int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
u32 field_index, s32 value);
此接口用于设置功能报告中字段的值。例如,如果有一个字段 report_interval,该字段在之前通过调用 sensor_hub_input_get_attribute_info 进行了解析,那么它可以直接设置该单个字段
int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
u32 field_index, s32 *value);
此接口用于获取输入报告中字段的值。例如,如果有一个字段 report_interval,该字段在之前通过调用 sensor_hub_input_get_attribute_info 进行了解析,那么它可以直接获取该单个字段值
int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
u32 usage_id,
u32 attr_usage_id, u32 report_id);
这用于通过输入报告获取特定字段值。例如,加速度计想要轮询 X 轴值,那么它可以调用此函数并使用 X 轴的使用 ID。HID 传感器可以提供事件,因此不需要轮询任何字段。如果有任何新样本,核心驱动程序将调用注册的回调函数来处理该样本。
HID 自定义和通用传感器¶
HID 传感器规范定义了两种特殊的传感器使用类型。由于它们不代表标准传感器,因此无法使用 Linux IIO 类型接口进行定义。这些传感器的目的是扩展功能或提供一种混淆传感器所通信数据的方式。在不知道数据与其封装形式之间的映射的情况下,应用程序/驱动程序很难确定传感器正在通信什么数据。这允许一些差异化的用例,其中供应商可以提供应用程序。一些常见的用例是调试其他传感器或提供一些事件,如键盘连接/断开或盖子打开/关闭。
为了允许应用程序利用这些传感器,此处使用 sysfs 属性组、属性和杂项设备接口导出它们。
sysfs 上此表示形式的示例
/sys/devices/pci0000:00/INT33C2:00/i2c-0/i2c-INT33D1:00/0018:8086:09FA.0001/HID-SENSOR-2000e1.6.auto$ tree -R
.
│ ├── enable_sensor
│ │ ├── feature-0-200316
│ │ │ ├── feature-0-200316-maximum
│ │ │ ├── feature-0-200316-minimum
│ │ │ ├── feature-0-200316-name
│ │ │ ├── feature-0-200316-size
│ │ │ ├── feature-0-200316-unit-expo
│ │ │ ├── feature-0-200316-units
│ │ │ ├── feature-0-200316-value
│ │ ├── feature-1-200201
│ │ │ ├── feature-1-200201-maximum
│ │ │ ├── feature-1-200201-minimum
│ │ │ ├── feature-1-200201-name
│ │ │ ├── feature-1-200201-size
│ │ │ ├── feature-1-200201-unit-expo
│ │ │ ├── feature-1-200201-units
│ │ │ ├── feature-1-200201-value
│ │ ├── input-0-200201
│ │ │ ├── input-0-200201-maximum
│ │ │ ├── input-0-200201-minimum
│ │ │ ├── input-0-200201-name
│ │ │ ├── input-0-200201-size
│ │ │ ├── input-0-200201-unit-expo
│ │ │ ├── input-0-200201-units
│ │ │ ├── input-0-200201-value
│ │ ├── input-1-200202
│ │ │ ├── input-1-200202-maximum
│ │ │ ├── input-1-200202-minimum
│ │ │ ├── input-1-200202-name
│ │ │ ├── input-1-200202-size
│ │ │ ├── input-1-200202-unit-expo
│ │ │ ├── input-1-200202-units
│ │ │ ├── input-1-200202-value
这里有一个自定义传感器,具有四个字段:两个功能和两个输入。每个字段都由一组属性表示。除“值”之外的所有字段都是只读的。“值”字段是读写字段。
示例
/sys/bus/platform/devices/HID-SENSOR-2000e1.6.auto/feature-0-200316$ grep -r . *
feature-0-200316-maximum:6
feature-0-200316-minimum:0
feature-0-200316-name:property-reporting-state
feature-0-200316-size:1
feature-0-200316-unit-expo:0
feature-0-200316-units:25
feature-0-200316-value:1
如何启用此类传感器?¶
默认情况下,传感器可以断电。可以使用 sysfs 属性“enable”来启用
$ echo 1 > enable_sensor
一旦启用并通电,传感器可以使用 HID 报告报告值。这些报告使用杂项设备接口按 FIFO 顺序推送
/dev$ tree | grep HID-SENSOR-2000e1.6.auto
│ │ │ ├── 10:53 -> ../HID-SENSOR-2000e1.6.auto
│ ├── HID-SENSOR-2000e1.6.auto
每个报告的长度可以变化,前面都有一个标头。此标头由一个 32 位使用 ID、一个 64 位时间戳和一个 32 位原始数据长度字段组成。