mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-04-24 10:49:54 +02:00
ce6bf2d9ee
Do basic editing & correction to hid-sensor.rst: - use HID consistently instead of hid - drop a duplicate word - change article adjective an -> a - fix grammar & punctuation - spell out RW -> read-write - hyphenate multi-word adjectives Signed-off-by: Randy Dunlap <rdunlap@infradead.org> Cc: Jiri Kosina <jikos@kernel.org> Cc: Jonathan Cameron <jic23@kernel.org> Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Cc: linux-input@vger.kernel.org Cc: linux-iio@vger.kernel.org Cc: Jonathan Corbet <corbet@lwn.net> Cc: linux-doc@vger.kernel.org Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
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.
|