Commit | Line | Data |
---|---|---|
cca47861 | 1 | ===================== |
620c7892 | 2 | HID Sensors Framework |
cca47861 | 3 | ===================== |
620c7892 | 4 | HID sensor framework provides necessary interfaces to implement sensor drivers, |
5 | which are connected to a sensor hub. The sensor hub is a HID device and it provides | |
6 | a report descriptor conforming to HID 1.12 sensor usage tables. | |
7 | ||
8 | Description from the HID 1.12 "HID Sensor Usages" specification: | |
9 | "Standardization of HID usages for sensors would allow (but not require) sensor | |
10 | hardware vendors to provide a consistent Plug And Play interface at the USB boundary, | |
11 | thereby enabling some operating systems to incorporate common device drivers that | |
12 | could be reused between vendors, alleviating any need for the vendors to provide | |
13 | the drivers themselves." | |
14 | ||
15 | This specification describes many usage IDs, which describe the type of sensor | |
16 | and also the individual data fields. Each sensor can have variable number of | |
17 | data fields. The length and order is specified in the report descriptor. For | |
cca47861 MCC |
18 | example 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 | .. | |
620c7892 | 34 | |
35 | The report is indicating "sensor page (0x20)" contains an accelerometer-3D (0x73). | |
36 | This 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 | |
38 | order of fields and length of each field is important as the input event raw | |
39 | data will use this format. | |
40 | ||
41 | ||
42 | Implementation | |
cca47861 | 43 | ============== |
620c7892 | 44 | |
45 | This specification defines many different types of sensors with different sets of | |
46 | data fields. It is difficult to have a common input event to user space applications, | |
47 | for different sensors. For example an accelerometer can send X,Y and Z data, whereas | |
48 | an ambient light sensor can send illumination data. | |
49 | So the implementation has two parts: | |
cca47861 | 50 | |
620c7892 | 51 | - Core hid driver |
52 | - Individual sensor processing part (sensor drivers) | |
53 | ||
54 | Core driver | |
55 | ----------- | |
56 | The core driver registers (hid-sensor-hub) registers as a HID driver. It parses | |
57 | report descriptors and identifies all the sensors present. It adds an MFD device | |
58 | with name HID-SENSOR-xxxx (where xxxx is usage id from the specification). | |
cca47861 MCC |
59 | |
60 | For example: | |
61 | ||
620c7892 | 62 | HID-SENSOR-200073 is registered for an Accelerometer 3D driver. |
cca47861 | 63 | |
620c7892 | 64 | So if any driver with this name is inserted, then the probe routine for that |
65 | function will be called. So an accelerometer processing driver can register | |
66 | with this name and will be probed if there is an accelerometer-3D detected. | |
67 | ||
68 | The core driver provides a set of APIs which can be used by the processing | |
69 | drivers to register and get events for that usage id. Also it provides parsing | |
70 | functions, which get and set each input/feature/output report. | |
71 | ||
72 | Individual sensor processing part (sensor drivers) | |
cca47861 MCC |
73 | -------------------------------------------------- |
74 | ||
620c7892 | 75 | The processing driver will use an interface provided by the core driver to parse |
76 | the report and get the indexes of the fields and also can get events. This driver | |
77 | can use IIO interface to use the standard ABI defined for a type of sensor. | |
78 | ||
79 | ||
80 | Core driver Interface | |
81 | ===================== | |
82 | ||
cca47861 MCC |
83 | Callback structure:: |
84 | ||
85 | Each processing driver can use this structure to set some callbacks. | |
620c7892 | 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 | ||
cca47861 MCC |
92 | Registration functions:: |
93 | ||
94 | int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, | |
620c7892 | 95 | u32 usage_id, |
96 | struct hid_sensor_hub_callbacks *usage_callback): | |
97 | ||
98 | Registers callbacks for an usage id. The callback functions are not allowed | |
cca47861 | 99 | to sleep:: |
620c7892 | 100 | |
101 | ||
cca47861 | 102 | int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev, |
620c7892 | 103 | u32 usage_id): |
104 | ||
105 | Removes callbacks for an usage id. | |
106 | ||
107 | ||
cca47861 MCC |
108 | Parsing function:: |
109 | ||
110 | int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev, | |
620c7892 | 111 | u8 type, |
112 | u32 usage_id, u32 attr_usage_id, | |
113 | struct hid_sensor_hub_attribute_info *info); | |
114 | ||
115 | A processing driver can look for some field of interest and check if it exists | |
116 | in a report descriptor. If it exists it will store necessary information | |
117 | so that fields can be set or get individually. | |
118 | These indexes avoid searching every time and getting field index to get or set. | |
119 | ||
120 | ||
cca47861 MCC |
121 | Set Feature report:: |
122 | ||
123 | int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, | |
620c7892 | 124 | u32 field_index, s32 value); |
125 | ||
126 | This interface is used to set a value for a field in feature report. For example | |
127 | if there is a field report_interval, which is parsed by a call to | |
cca47861 MCC |
128 | sensor_hub_input_get_attribute_info before, then it can directly set that |
129 | individual field:: | |
620c7892 | 130 | |
131 | ||
cca47861 | 132 | int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, |
620c7892 | 133 | u32 field_index, s32 *value); |
134 | ||
135 | This interface is used to get a value for a field in input report. For example | |
136 | if there is a field report_interval, which is parsed by a call to | |
cca47861 MCC |
137 | sensor_hub_input_get_attribute_info before, then it can directly get that |
138 | individual field value:: | |
620c7892 | 139 | |
140 | ||
cca47861 | 141 | int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, |
620c7892 | 142 | u32 usage_id, |
143 | u32 attr_usage_id, u32 report_id); | |
144 | ||
145 | This is used to get a particular field value through input reports. For example | |
146 | accelerometer wants to poll X axis value, then it can call this function with | |
147 | the usage id of X axis. HID sensors can provide events, so this is not necessary | |
148 | to poll for any field. If there is some new sample, the core driver will call | |
149 | registered callback function to process the sample. | |
b2eafd72 SP |
150 | |
151 | ||
152 | ---------- | |
153 | ||
154 | HID Custom and generic Sensors | |
cca47861 MCC |
155 | ------------------------------ |
156 | ||
b2eafd72 SP |
157 | |
158 | HID Sensor specification defines two special sensor usage types. Since they | |
159 | don't represent a standard sensor, it is not possible to define using Linux IIO | |
160 | type interfaces. | |
161 | The purpose of these sensors is to extend the functionality or provide a | |
162 | way to obfuscate the data being communicated by a sensor. Without knowing the | |
163 | mapping between the data and its encapsulated form, it is difficult for | |
164 | an application/driver to determine what data is being communicated by the sensor. | |
165 | This allows some differentiating use cases, where vendor can provide applications. | |
166 | Some common use cases are debug other sensors or to provide some events like | |
167 | keyboard attached/detached or lid open/close. | |
168 | ||
169 | To allow application to utilize these sensors, here they are exported uses sysfs | |
170 | attribute groups, attributes and misc device interface. | |
171 | ||
cca47861 MCC |
172 | An 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 | |
b2eafd72 SP |
209 | |
210 | Here there is a custom sensors with four fields, two feature and two inputs. | |
211 | Each field is represented by a set of attributes. All fields except the "value" | |
212 | are read only. The value field is a RW field. | |
cca47861 MCC |
213 | |
214 | Example:: | |
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 | |
b2eafd72 SP |
224 | |
225 | How to enable such sensor? | |
cca47861 MCC |
226 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
227 | ||
b2eafd72 | 228 | By default sensor can be power gated. To enable sysfs attribute "enable" can be |
cca47861 MCC |
229 | used:: |
230 | ||
231 | $ echo 1 > enable_sensor | |
b2eafd72 SP |
232 | |
233 | Once enabled and powered on, sensor can report value using HID reports. | |
cca47861 MCC |
234 | These 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 | |
b2eafd72 SP |
239 | |
240 | Each reports can be of variable length preceded by a header. This header | |
241 | consist of a 32 bit usage id, 64 bit time stamp and 32 bit length field of raw | |
242 | data. |