243 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| =====================
 | |
| 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 (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 a 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 a 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.
 | |
| 
 | |
| 
 | |
| ----------
 | |
| 
 | |
| HID Custom and generic Sensors
 | |
| ------------------------------
 | |
| 
 | |
| 
 | |
| HID Sensor specification defines two special sensor usage types. Since they
 | |
| don't represent a standard sensor, it is not possible to define using Linux IIO
 | |
| type interfaces.
 | |
| The purpose of these sensors is to extend the functionality or provide a
 | |
| way to obfuscate the data being communicated by a sensor. Without knowing the
 | |
| mapping between the data and its encapsulated form, it is difficult for
 | |
| an application/driver to determine what data is being communicated by the sensor.
 | |
| This allows some differentiating use cases, where vendor can provide applications.
 | |
| Some common use cases are debug other sensors or to provide some events like
 | |
| keyboard attached/detached or lid open/close.
 | |
| 
 | |
| To allow application to utilize these sensors, here they are exported using sysfs
 | |
| attribute groups, attributes and misc device interface.
 | |
| 
 | |
| An example of this representation on 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
 | |
| 
 | |
| Here there is a custom sensor with four fields: two feature and two inputs.
 | |
| Each field is represented by a set of attributes. All fields except the "value"
 | |
| are read only. The value field is a read-write field.
 | |
| 
 | |
| Example::
 | |
| 
 | |
|   /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
 | |
| 
 | |
| How to enable such sensor?
 | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
 | |
| 
 | |
| By default sensor can be power gated. To enable sysfs attribute "enable" can be
 | |
| used::
 | |
| 
 | |
| 	$ echo 1 > enable_sensor
 | |
| 
 | |
| Once enabled and powered on, sensor can report value using HID reports.
 | |
| These reports are pushed using misc device interface in a FIFO order::
 | |
| 
 | |
| 	/dev$ tree | grep HID-SENSOR-2000e1.6.auto
 | |
| 	│   │   │   ├── 10:53 -> ../HID-SENSOR-2000e1.6.auto
 | |
| 	│   ├──  HID-SENSOR-2000e1.6.auto
 | |
| 
 | |
| Each report can be of variable length preceded by a header. This header
 | |
| consists of a 32-bit usage id, 64-bit time stamp and 32-bit length field of raw
 | |
| data.
 |