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 屬性組、屬性和 misc 裝置介面匯出。

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

這裡有一個自定義感測器,有四個欄位:兩個功能和兩個輸入。 每個欄位由一組屬性表示。 除了“value”之外的所有欄位都是隻讀的。 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 順序透過 misc 裝置介面推送。

/dev$ tree | grep HID-SENSOR-2000e1.6.auto
│   │   │   ├── 10:53 -> ../HID-SENSOR-2000e1.6.auto
│   ├──  HID-SENSOR-2000e1.6.auto

每個報告的長度可以是可變的,前面是報頭。 該報頭包含一個 32 位的使用 ID、一個 64 位的時間戳和一個 32 位的原始資料長度欄位。