141 lines
		
	
	
	
		
			5.5 KiB
			
		
	
	
	
		
			Text
		
	
	
	
	
	
		
		
			
		
	
	
			141 lines
		
	
	
	
		
			5.5 KiB
			
		
	
	
	
		
			Text
		
	
	
	
	
	
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HID Sensors Framework
							 | 
						||
| 
								 | 
							
								======================
							 | 
						||
| 
								 | 
							
								HID sensor framework provides necessary interfaces to implement sensor drivers,
							 | 
						||
| 
								 | 
							
								which are connected to a sensor hub. The sensor hub is a HID device and it provides
							 | 
						||
| 
								 | 
							
								a report descriptor conforming to HID 1.12 sensor usage tables.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Description from the HID 1.12 "HID Sensor Usages" specification:
							 | 
						||
| 
								 | 
							
								"Standardization of HID usages for sensors would allow (but not require) sensor
							 | 
						||
| 
								 | 
							
								hardware vendors to provide a consistent Plug And Play interface at the USB boundary,
							 | 
						||
| 
								 | 
							
								thereby enabling some operating systems to incorporate common device drivers that
							 | 
						||
| 
								 | 
							
								could be reused between vendors, alleviating any need for the vendors to provide
							 | 
						||
| 
								 | 
							
								the drivers themselves."
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This specification describes many usage IDs, which describe the type of sensor
							 | 
						||
| 
								 | 
							
								and also the individual data fields. Each sensor can have variable number of
							 | 
						||
| 
								 | 
							
								data fields. The length and order is specified in the report descriptor. For
							 | 
						||
| 
								 | 
							
								example a part of report descriptor can look like:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   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)
							 | 
						||
| 
								 | 
							
								..
							 | 
						||
| 
								 | 
							
								..
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The report is indicating "sensor page (0x20)" contains an accelerometer-3D (0x73).
							 | 
						||
| 
								 | 
							
								This accelerometer-3D has some fields. Here for example field 2 is motion intensity
							 | 
						||
| 
								 | 
							
								(0x045f) with a logical minimum value of -32767 and logical maximum of 32767. The
							 | 
						||
| 
								 | 
							
								order of fields and length of each field is important as the input event raw
							 | 
						||
| 
								 | 
							
								data will use this format.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Implementation
							 | 
						||
| 
								 | 
							
								=================
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This specification defines many different types of sensors with different sets of
							 | 
						||
| 
								 | 
							
								data fields. It is difficult to have a common input event to user space applications,
							 | 
						||
| 
								 | 
							
								for different sensors. For example an accelerometer can send X,Y and Z data, whereas
							 | 
						||
| 
								 | 
							
								an ambient light sensor can send illumination data.
							 | 
						||
| 
								 | 
							
								So the implementation has two parts:
							 | 
						||
| 
								 | 
							
								- Core hid driver
							 | 
						||
| 
								 | 
							
								- Individual sensor processing part (sensor drivers)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Core driver
							 | 
						||
| 
								 | 
							
								-----------
							 | 
						||
| 
								 | 
							
								The core driver registers (hid-sensor-hub) registers as a HID driver. It parses
							 | 
						||
| 
								 | 
							
								report descriptors and identifies all the sensors present. It adds an MFD device
							 | 
						||
| 
								 | 
							
								with name HID-SENSOR-xxxx (where xxxx is usage id from the specification).
							 | 
						||
| 
								 | 
							
								For example
							 | 
						||
| 
								 | 
							
								HID-SENSOR-200073 is registered for an Accelerometer 3D driver.
							 | 
						||
| 
								 | 
							
								So if any driver with this name is inserted, then the probe routine for that
							 | 
						||
| 
								 | 
							
								function will be called. So an accelerometer processing driver can register
							 | 
						||
| 
								 | 
							
								with this name and will be probed if there is an accelerometer-3D detected.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The core driver provides a set of APIs which can be used by the processing
							 | 
						||
| 
								 | 
							
								drivers to register and get events for that usage id. Also it provides parsing
							 | 
						||
| 
								 | 
							
								functions, which get and set each input/feature/output report.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Individual sensor processing part (sensor drivers)
							 | 
						||
| 
								 | 
							
								-----------
							 | 
						||
| 
								 | 
							
								The processing driver will use an interface provided by the core driver to parse
							 | 
						||
| 
								 | 
							
								the report and get the indexes of the fields and also can get events. This driver
							 | 
						||
| 
								 | 
							
								can use IIO interface to use the standard ABI defined for a type of sensor.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Core driver Interface
							 | 
						||
| 
								 | 
							
								=====================
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Callback structure:
							 | 
						||
| 
								 | 
							
								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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Registration functions:
							 | 
						||
| 
								 | 
							
								int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
							 | 
						||
| 
								 | 
							
											u32 usage_id,
							 | 
						||
| 
								 | 
							
											struct hid_sensor_hub_callbacks *usage_callback):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Registers callbacks for an usage id. The callback functions are not allowed
							 | 
						||
| 
								 | 
							
								to sleep.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
							 | 
						||
| 
								 | 
							
											u32 usage_id):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Removes callbacks for an usage id.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Parsing function:
							 | 
						||
| 
								 | 
							
								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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								A processing driver can look for some field of interest and check if it exists
							 | 
						||
| 
								 | 
							
								in a report descriptor. If it exists it will store necessary information
							 | 
						||
| 
								 | 
							
								so that fields can be set or get individually.
							 | 
						||
| 
								 | 
							
								These indexes avoid searching every time and getting field index to get or set.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Set Feature report
							 | 
						||
| 
								 | 
							
								int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
							 | 
						||
| 
								 | 
							
											u32 field_index, s32 value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This interface is used to set a value for a field in feature report. For example
							 | 
						||
| 
								 | 
							
								if there is a field report_interval, which is parsed by a call to
							 | 
						||
| 
								 | 
							
								sensor_hub_input_get_attribute_info before, then it can directly set that individual
							 | 
						||
| 
								 | 
							
								field.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
							 | 
						||
| 
								 | 
							
											u32 field_index, s32 *value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This interface is used to get a value for a field in input report. For example
							 | 
						||
| 
								 | 
							
								if there is a field report_interval, which is parsed by a call to
							 | 
						||
| 
								 | 
							
								sensor_hub_input_get_attribute_info before, then it can directly get that individual
							 | 
						||
| 
								 | 
							
								field value.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
							 | 
						||
| 
								 | 
							
											u32 usage_id,
							 | 
						||
| 
								 | 
							
											u32 attr_usage_id, u32 report_id);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This is used to get a particular field value through input reports. For example
							 | 
						||
| 
								 | 
							
								accelerometer wants to poll X axis value, then it can call this function with
							 | 
						||
| 
								 | 
							
								the usage id of X axis. HID sensors can provide events, so this is not necessary
							 | 
						||
| 
								 | 
							
								to poll for any field. If there is some new sample, the core driver will call
							 | 
						||
| 
								 | 
							
								registered callback function to process the sample.
							 |