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