1===================== 2HID Sensors Framework 3===================== 4HID sensor framework provides necessary interfaces to implement sensor drivers, 5which are connected to a sensor hub. The sensor hub is a HID device and it provides 6a report descriptor conforming to HID 1.12 sensor usage tables. 7 8Description from the HID 1.12 "HID Sensor Usages" specification: 9"Standardization of HID usages for sensors would allow (but not require) sensor 10hardware vendors to provide a consistent Plug And Play interface at the USB boundary, 11thereby enabling some operating systems to incorporate common device drivers that 12could be reused between vendors, alleviating any need for the vendors to provide 13the drivers themselves." 14 15This specification describes many usage IDs, which describe the type of sensor 16and also the individual data fields. Each sensor can have variable number of 17data fields. The length and order is specified in the report descriptor. For 18example a part of report descriptor can look like:: 19 20 INPUT(1)[INPUT] 21 .. 22 Field(2) 23 Physical(0020.0073) 24 Usage(1) 25 0020.045f 26 Logical Minimum(-32767) 27 Logical Maximum(32767) 28 Report Size(8) 29 Report Count(1) 30 Report Offset(16) 31 Flags(Variable Absolute) 32 .. 33 .. 34 35The report is indicating "sensor page (0x20)" contains an accelerometer-3D (0x73). 36This accelerometer-3D has some fields. Here for example field 2 is motion intensity 37(0x045f) with a logical minimum value of -32767 and logical maximum of 32767. The 38order of fields and length of each field is important as the input event raw 39data will use this format. 40 41 42Implementation 43============== 44 45This specification defines many different types of sensors with different sets of 46data fields. It is difficult to have a common input event to user space applications, 47for different sensors. For example an accelerometer can send X,Y and Z data, whereas 48an ambient light sensor can send illumination data. 49So the implementation has two parts: 50 51- Core hid driver 52- Individual sensor processing part (sensor drivers) 53 54Core driver 55----------- 56The core driver registers (hid-sensor-hub) registers as a HID driver. It parses 57report descriptors and identifies all the sensors present. It adds an MFD device 58with name HID-SENSOR-xxxx (where xxxx is usage id from the specification). 59 60For example: 61 62HID-SENSOR-200073 is registered for an Accelerometer 3D driver. 63 64So if any driver with this name is inserted, then the probe routine for that 65function will be called. So an accelerometer processing driver can register 66with this name and will be probed if there is an accelerometer-3D detected. 67 68The core driver provides a set of APIs which can be used by the processing 69drivers to register and get events for that usage id. Also it provides parsing 70functions, which get and set each input/feature/output report. 71 72Individual sensor processing part (sensor drivers) 73-------------------------------------------------- 74 75The processing driver will use an interface provided by the core driver to parse 76the report and get the indexes of the fields and also can get events. This driver 77can use IIO interface to use the standard ABI defined for a type of sensor. 78 79 80Core driver Interface 81===================== 82 83Callback structure:: 84 85 Each processing driver can use this structure to set some callbacks. 86 int (*suspend)(..): Callback when HID suspend is received 87 int (*resume)(..): Callback when HID resume is received 88 int (*capture_sample)(..): Capture a sample for one of its data fields 89 int (*send_event)(..): One complete event is received which can have 90 multiple data fields. 91 92Registration functions:: 93 94 int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, 95 u32 usage_id, 96 struct hid_sensor_hub_callbacks *usage_callback): 97 98Registers callbacks for an usage id. The callback functions are not allowed 99to sleep:: 100 101 102 int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev, 103 u32 usage_id): 104 105Removes callbacks for an usage id. 106 107 108Parsing function:: 109 110 int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev, 111 u8 type, 112 u32 usage_id, u32 attr_usage_id, 113 struct hid_sensor_hub_attribute_info *info); 114 115A processing driver can look for some field of interest and check if it exists 116in a report descriptor. If it exists it will store necessary information 117so that fields can be set or get individually. 118These indexes avoid searching every time and getting field index to get or set. 119 120 121Set Feature report:: 122 123 int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, 124 u32 field_index, s32 value); 125 126This interface is used to set a value for a field in feature report. For example 127if there is a field report_interval, which is parsed by a call to 128sensor_hub_input_get_attribute_info before, then it can directly set that 129individual field:: 130 131 132 int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, 133 u32 field_index, s32 *value); 134 135This interface is used to get a value for a field in input report. For example 136if there is a field report_interval, which is parsed by a call to 137sensor_hub_input_get_attribute_info before, then it can directly get that 138individual field value:: 139 140 141 int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, 142 u32 usage_id, 143 u32 attr_usage_id, u32 report_id); 144 145This is used to get a particular field value through input reports. For example 146accelerometer wants to poll X axis value, then it can call this function with 147the usage id of X axis. HID sensors can provide events, so this is not necessary 148to poll for any field. If there is some new sample, the core driver will call 149registered callback function to process the sample. 150 151 152---------- 153 154HID Custom and generic Sensors 155------------------------------ 156 157 158HID Sensor specification defines two special sensor usage types. Since they 159don't represent a standard sensor, it is not possible to define using Linux IIO 160type interfaces. 161The purpose of these sensors is to extend the functionality or provide a 162way to obfuscate the data being communicated by a sensor. Without knowing the 163mapping between the data and its encapsulated form, it is difficult for 164an application/driver to determine what data is being communicated by the sensor. 165This allows some differentiating use cases, where vendor can provide applications. 166Some common use cases are debug other sensors or to provide some events like 167keyboard attached/detached or lid open/close. 168 169To allow application to utilize these sensors, here they are exported uses sysfs 170attribute groups, attributes and misc device interface. 171 172An example of this representation on sysfs:: 173 174 /sys/devices/pci0000:00/INT33C2:00/i2c-0/i2c-INT33D1:00/0018:8086:09FA.0001/HID-SENSOR-2000e1.6.auto$ tree -R 175 . 176 │ ├── enable_sensor 177 │ │ ├── feature-0-200316 178 │ │ │ ├── feature-0-200316-maximum 179 │ │ │ ├── feature-0-200316-minimum 180 │ │ │ ├── feature-0-200316-name 181 │ │ │ ├── feature-0-200316-size 182 │ │ │ ├── feature-0-200316-unit-expo 183 │ │ │ ├── feature-0-200316-units 184 │ │ │ ├── feature-0-200316-value 185 │ │ ├── feature-1-200201 186 │ │ │ ├── feature-1-200201-maximum 187 │ │ │ ├── feature-1-200201-minimum 188 │ │ │ ├── feature-1-200201-name 189 │ │ │ ├── feature-1-200201-size 190 │ │ │ ├── feature-1-200201-unit-expo 191 │ │ │ ├── feature-1-200201-units 192 │ │ │ ├── feature-1-200201-value 193 │ │ ├── input-0-200201 194 │ │ │ ├── input-0-200201-maximum 195 │ │ │ ├── input-0-200201-minimum 196 │ │ │ ├── input-0-200201-name 197 │ │ │ ├── input-0-200201-size 198 │ │ │ ├── input-0-200201-unit-expo 199 │ │ │ ├── input-0-200201-units 200 │ │ │ ├── input-0-200201-value 201 │ │ ├── input-1-200202 202 │ │ │ ├── input-1-200202-maximum 203 │ │ │ ├── input-1-200202-minimum 204 │ │ │ ├── input-1-200202-name 205 │ │ │ ├── input-1-200202-size 206 │ │ │ ├── input-1-200202-unit-expo 207 │ │ │ ├── input-1-200202-units 208 │ │ │ ├── input-1-200202-value 209 210Here there is a custom sensors with four fields, two feature and two inputs. 211Each field is represented by a set of attributes. All fields except the "value" 212are read only. The value field is a RW field. 213 214Example:: 215 216 /sys/bus/platform/devices/HID-SENSOR-2000e1.6.auto/feature-0-200316$ grep -r . * 217 feature-0-200316-maximum:6 218 feature-0-200316-minimum:0 219 feature-0-200316-name:property-reporting-state 220 feature-0-200316-size:1 221 feature-0-200316-unit-expo:0 222 feature-0-200316-units:25 223 feature-0-200316-value:1 224 225How to enable such sensor? 226^^^^^^^^^^^^^^^^^^^^^^^^^^ 227 228By default sensor can be power gated. To enable sysfs attribute "enable" can be 229used:: 230 231 $ echo 1 > enable_sensor 232 233Once enabled and powered on, sensor can report value using HID reports. 234These reports are pushed using misc device interface in a FIFO order:: 235 236 /dev$ tree | grep HID-SENSOR-2000e1.6.auto 237 │ │ │ ├── 10:53 -> ../HID-SENSOR-2000e1.6.auto 238 │ ├── HID-SENSOR-2000e1.6.auto 239 240Each reports can be of variable length preceded by a header. This header 241consist of a 32 bit usage id, 64 bit time stamp and 32 bit length field of raw 242data. 243