← Documents Documentation/hid/intel-ish-hid.rst GitHub 원문 ↗

Linux 6.18.37 · HID

Intel Integrated Sensor Hub (ISH)

Intel ISH의 PCI·IPC·ISHTP 계층, client enumeration, HID transport, DMA와 host firmware loading을 설명합니다.

Source pathDocumentation/hid/intel-ish-hid.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

intel-ish-hid.rst:1-581

Intel Integrated Sensor Hub는 sensor polling과 algorithm 처리를 저전력 co-processor에 맡기고, custom IPC와 ISHTP bus를 통해 firmware client를 Linux HID·IIO 계층에 연결합니다.

이 문서는 doorbell register, connection credit, DMA ownership, host enumeration, HID descriptor 등록, Lunar Lake firmware loader, vendor image 선택과 IIO sysfs 예제를 하나의 end-to-end 구조로 설명합니다.

문서 범위
항목
SourceDocumentation/hid/intel-ish-hid.rst
분량581 source lines
TransportPCI · IPC · ISHTP
Upper stackHID Sensor Hub MFD · IIO
FirmwareBIOS bootloader · OS main firmware

Source와 구현 계층을 요약합니다.

전체 data path
ISH firmware client가 sensor report 생성IPC doorbell과 message register로 host에 전달ISHTP connection·flow control로 client message 처리HID over ISH client가 descriptor와 report를 HID core에 제공HID Sensor Hub MFD와 IIO driver가 userspace ABI 노출

Sensor firmware에서 userspace까지의 주 경로입니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 =================================
2 Intel Integrated Sensor Hub (ISH)
3 =================================
4
5 A sensor hub enables the ability to offload sensor polling and algorithm
6 processing to a dedicated low power co-processor. This allows the core
7 processor to go into low power modes more often, resulting in increased
8 battery life.
9
10 There are many vendors providing external sensor hubs conforming to HID
11 Sensor usage tables. These may be found in tablets, 2-in-1 convertible laptops
12 and embedded products. Linux has had this support since Linux 3.9.
13
14 Intel® introduced integrated sensor hubs as a part of the SoC starting from
15 Cherry Trail and now supported on multiple generations of CPU packages. There
16 are many commercial devices already shipped with Integrated Sensor Hubs (ISH).
17 These ISH also comply to HID sensor specification, but the difference is the
18 transport protocol used for communication. The current external sensor hubs
19 mainly use HID over I2C or USB. But ISH doesn't use either I2C or USB.
20
21 Overview
22 ========
23
24 Using a analogy with a usbhid implementation, the ISH follows a similar model
25 for a very high speed communication::
26
27 ----------------- ----------------------
28 | USB HID | --> | ISH HID |
29 ----------------- ----------------------
30 ----------------- ----------------------
31 | USB protocol | --> | ISH Transport |
32 ----------------- ----------------------
33 ----------------- ----------------------
34 | EHCI/XHCI | --> | ISH IPC |
35 ----------------- ----------------------
36 PCI PCI
37 ----------------- ----------------------
38 |Host controller| --> | ISH processor |
39 ----------------- ----------------------
40 USB Link
41 ----------------- ----------------------
42 | USB End points| --> | ISH Clients |
43 ----------------- ----------------------
44
45 Like USB protocol provides a method for device enumeration, link management
46 and user data encapsulation, the ISH also provides similar services. But it is
47 very light weight tailored to manage and communicate with ISH client
48 applications implemented in the firmware.
49
50 The ISH allows multiple sensor management applications executing in the
51 firmware. Like USB endpoints the messaging can be to/from a client. As part of
52 enumeration process, these clients are identified. These clients can be simple
53 HID sensor applications, sensor calibration applications or sensor firmware
54 update applications.
55
56 The implementation model is similar, like USB bus, ISH transport is also
57 implemented as a bus. Each client application executing in the ISH processor
58 is registered as a device on this bus. The driver, which binds each device
59 (ISH HID driver) identifies the device type and registers with the HID core.
60
61 ISH Implementation: Block Diagram
62 =================================
63
64 ::
65
66 ---------------------------
67 | User Space Applications |
68 ---------------------------
69
70 ----------------IIO ABI----------------
71 --------------------------
72 | IIO Sensor Drivers |
73 --------------------------
74 --------------------------
75 | IIO core |
76 --------------------------
77 --------------------------
78 | HID Sensor Hub MFD |
79 --------------------------
80 --------------------------
81 | HID Core |
82 --------------------------
83 --------------------------
84 | HID over ISH Client |
85 --------------------------
86 --------------------------
87 | ISH Transport (ISHTP) |
88 --------------------------
89 --------------------------
90 | IPC Drivers |
91 --------------------------
92 OS
93 ---------------- PCI -----------------
94 Hardware + Firmware
95 ----------------------------
96 | ISH Hardware/Firmware(FW) |
97 ----------------------------
98
99 High level processing in above blocks
100 =====================================
101
102 Hardware Interface
103 ------------------
104
105 The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI
106 product and vendor IDs are changed from different generations of processors. So
107 the source code which enumerates drivers needs to update from generation to
108 generation.
109
110 Inter Processor Communication (IPC) driver
111 ------------------------------------------
112
113 Location: drivers/hid/intel-ish-hid/ipc
114
115 The IPC message uses memory mapped I/O. The registers are defined in
116 hw-ish-regs.h.
117
118 IPC/FW message types
119 ^^^^^^^^^^^^^^^^^^^^
120
121 There are two types of messages, one for management of link and another for
122 messages to and from transport layers.
123
124 TX and RX of Transport messages
125 ...............................
126
127 A set of memory mapped register offers support of multi-byte messages TX and
128 RX (e.g. IPC_REG_ISH2HOST_MSG, IPC_REG_HOST2ISH_MSG). The IPC layer maintains
129 internal queues to sequence messages and send them in order to the firmware.
130 Optionally the caller can register handler to get notification of completion.
131 A doorbell mechanism is used in messaging to trigger processing in host and
132 client firmware side. When ISH interrupt handler is called, the ISH2HOST
133 doorbell register is used by host drivers to determine that the interrupt
134 is for ISH.
135
136 Each side has 32 32-bit message registers and a 32-bit doorbell. Doorbell
137 register has the following format::
138
139 Bits 0..6: fragment length (7 bits are used)
140 Bits 10..13: encapsulated protocol
141 Bits 16..19: management command (for IPC management protocol)
142 Bit 31: doorbell trigger (signal H/W interrupt to the other side)
143 Other bits are reserved, should be 0.
144
145 Transport layer interface
146 ^^^^^^^^^^^^^^^^^^^^^^^^^
147
148 To abstract HW level IPC communication, a set of callbacks is registered.
149 The transport layer uses them to send and receive messages.
150 Refer to struct ishtp_hw_ops for callbacks.
151
152 ISH Transport layer
153 -------------------
154
155 Location: drivers/hid/intel-ish-hid/ishtp/
156
157 A Generic Transport Layer
158 ^^^^^^^^^^^^^^^^^^^^^^^^^
159
160 The transport layer is a bi-directional protocol, which defines:
161 - Set of commands to start, stop, connect, disconnect and flow control
162 (see ishtp/hbm.h for details)
163 - A flow control mechanism to avoid buffer overflows
164
165 This protocol resembles bus messages described in the following document:
166 http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
167 specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"
168
169 Connection and Flow Control Mechanism
170 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
171
172 Each FW client and a protocol is identified by a UUID. In order to communicate
173 to a FW client, a connection must be established using connect request and
174 response bus messages. If successful, a pair (host_client_id and fw_client_id)
175 will identify the connection.
176
177 Once connection is established, peers send each other flow control bus messages
178 independently. Every peer may send a message only if it has received a
179 flow-control credit before. Once it has sent a message, it may not send another one
180 before receiving the next flow control credit.
181 Either side can send disconnect request bus message to end communication. Also
182 the link will be dropped if major FW reset occurs.
183
184 Peer to Peer data transfer
185 ^^^^^^^^^^^^^^^^^^^^^^^^^^
186
187 Peer to Peer data transfer can happen with or without using DMA. Depending on
188 the sensor bandwidth requirement DMA can be enabled by using module parameter
189 ishtp_use_dma under intel_ishtp.
190
191 Each side (host and FW) manages its DMA transfer memory independently. When an
192 ISHTP client from either host or FW side wants to send something, it decides
193 whether to send over IPC or over DMA; for each transfer the decision is
194 independent. The sending side sends DMA_XFER message when the message is in
195 the respective host buffer (TX when host client sends, RX when FW client
196 sends). The recipient of DMA message responds with DMA_XFER_ACK, indicating
197 the sender that the memory region for that message may be reused.
198
199 DMA initialization is started with host sending DMA_ALLOC_NOTIFY bus message
200 (that includes RX buffer) and FW responds with DMA_ALLOC_NOTIFY_ACK.
201 Additionally to DMA address communication, this sequence checks capabilities:
202 if the host doesn't support DMA, then it won't send DMA allocation, so FW can't
203 send DMA; if FW doesn't support DMA then it won't respond with
204 DMA_ALLOC_NOTIFY_ACK, in which case host will not use DMA transfers.
205 Here ISH acts as busmaster DMA controller. Hence when host sends DMA_XFER,
206 it's request to do host->ISH DMA transfer; when FW sends DMA_XFER, it means
207 that it already did DMA and the message resides at host. Thus, DMA_XFER
208 and DMA_XFER_ACK act as ownership indicators.
209
210 At initial state all outgoing memory belongs to the sender (TX to host, RX to
211 FW), DMA_XFER transfers ownership on the region that contains ISHTP message to
212 the receiving side, DMA_XFER_ACK returns ownership to the sender. A sender
213 need not wait for previous DMA_XFER to be ack'ed, and may send another message
214 as long as remaining continuous memory in its ownership is enough.
215 In principle, multiple DMA_XFER and DMA_XFER_ACK messages may be sent at once
216 (up to IPC MTU), thus allowing for interrupt throttling.
217 Currently, ISH FW decides to send over DMA if ISHTP message is more than 3 IPC
218 fragments and via IPC otherwise.
219
220 Ring Buffers
221 ^^^^^^^^^^^^
222
223 When a client initiates a connection, a ring of RX and TX buffers is allocated.
224 The size of ring can be specified by the client. HID client sets 16 and 32 for
225 TX and RX buffers respectively. On send request from client, the data to be
226 sent is copied to one of the send ring buffer and scheduled to be sent using
227 bus message protocol. These buffers are required because the FW may have not
228 have processed the last message and may not have enough flow control credits
229 to send. Same thing holds true on receive side and flow control is required.
230
231 Host Enumeration
232 ^^^^^^^^^^^^^^^^
233
234 The host enumeration bus command allows discovery of clients present in the FW.
235 There can be multiple sensor clients and clients for calibration function.
236
237 To ease implementation and allow independent drivers to handle each client,
238 this transport layer takes advantage of Linux Bus driver model. Each
239 client is registered as device on the transport bus (ishtp bus).
240
241 Enumeration sequence of messages:
242
243 - Host sends HOST_START_REQ_CMD, indicating that host ISHTP layer is up.
244 - FW responds with HOST_START_RES_CMD
245 - Host sends HOST_ENUM_REQ_CMD (enumerate FW clients)
246 - FW responds with HOST_ENUM_RES_CMD that includes bitmap of available FW
247 client IDs
248 - For each FW ID found in that bitmap host sends
249 HOST_CLIENT_PROPERTIES_REQ_CMD
250 - FW responds with HOST_CLIENT_PROPERTIES_RES_CMD. Properties include UUID,
251 max ISHTP message size, etc.
252 - Once host received properties for that last discovered client, it considers
253 ISHTP device fully functional (and allocates DMA buffers)
254
255 HID over ISH Client
256 -------------------
257
258 Location: drivers/hid/intel-ish-hid
259
260 The ISHTP client driver is responsible for:
261
262 - enumerate HID devices under FW ISH client
263 - Get Report descriptor
264 - Register with HID core as a LL driver
265 - Process Get/Set feature request
266 - Get input reports
267
268 HID Sensor Hub MFD and IIO sensor drivers
269 -----------------------------------------
270
271 The functionality in these drivers is the same as an external sensor hub.
272 Refer to
273 Documentation/hid/hid-sensor.rst for HID sensor
274 Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space.
275
276 End to End HID transport Sequence Diagram
277 -----------------------------------------
278
279 ::
280
281 HID-ISH-CLN ISHTP IPC HW
282 | | | |
283 | | |-----WAKE UP------------------>|
284 | | | |
285 | | |-----HOST READY--------------->|
286 | | | |
287 | | |<----MNG_RESET_NOTIFY_ACK----- |
288 | | | |
289 | |<----ISHTP_START------ | |
290 | | | |
291 | |<-----------------HOST_START_RES_CMD-------------------|
292 | | | |
293 | |------------------QUERY_SUBSCRIBER-------------------->|
294 | | | |
295 | |------------------HOST_ENUM_REQ_CMD------------------->|
296 | | | |
297 | |<-----------------HOST_ENUM_RES_CMD--------------------|
298 | | | |
299 | |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
300 | | | |
301 | |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
302 | Create new device on in ishtp bus | |
303 | | | |
304 | |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
305 | | | |
306 | |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
307 | Create new device on in ishtp bus | |
308 | | | |
309 | |--Repeat HOST_CLIENT_PROPERTIES_REQ_CMD-till last one--|
310 | | | |
311 probed()
312 |----ishtp_cl_connect--->|----------------- CLIENT_CONNECT_REQ_CMD-------------->|
313 | | | |
314 | |<----------------CLIENT_CONNECT_RES_CMD----------------|
315 | | | |
316 |register event callback | | |
317 | | | |
318 |ishtp_cl_send(
319 HOSTIF_DM_ENUM_DEVICES) |----------fill ishtp_msg_hdr struct write to HW----- >|
320 | | | |
321 | | |<-----IRQ(IPC_PROTOCOL_ISHTP---|
322 | | | |
323 |<--ENUM_DEVICE RSP------| | |
324 | | | |
325 for each enumerated device
326 |ishtp_cl_send(
327 HOSTIF_GET_HID_DESCRIPTOR|----------fill ishtp_msg_hdr struct write to HW----- >|
328 | | | |
329 ...Response
330 | | | |
331 for each enumerated device
332 |ishtp_cl_send(
333 HOSTIF_GET_REPORT_DESCRIPTOR|--------------fill ishtp_msg_hdr struct write to HW-- >|
334 | | | |
335 | | | |
336 hid_allocate_device
337 | | | |
338 hid_add_device | | |
339 | | | |
340
341
342 ISH Firmware Loading from Host Flow
343 -----------------------------------
344
345 Starting from the Lunar Lake generation, the ISH firmware has been divided into two components for better space optimization and increased flexibility. These components include a bootloader that is integrated into the BIOS, and a main firmware that is stored within the operating system's file system.
346
347 The process works as follows:
348
349 - Initially, the ISHTP driver sends a command, HOST_START_REQ_CMD, to the ISH bootloader. In response, the bootloader sends back a HOST_START_RES_CMD. This response includes the ISHTP_SUPPORT_CAP_LOADER bit. Subsequently, the ISHTP driver checks if this bit is set. If it is, the firmware loading process from the host begins.
350
351 - During this process, the ISHTP driver first invokes the request_firmware() function, followed by sending a LOADER_CMD_XFER_QUERY command. Upon receiving a response from the bootloader, the ISHTP driver sends a LOADER_CMD_XFER_FRAGMENT command. After receiving another response, the ISHTP driver sends a LOADER_CMD_START command. The bootloader responds and then proceeds to the Main Firmware.
352
353 - After the process concludes, the ISHTP driver calls the release_firmware() function.
354
355 For more detailed information, please refer to the flow descriptions provided below:
356
357 ::
358
359 +---------------+ +-----------------+
360 | ISHTP Driver | | ISH Bootloader |
361 +---------------+ +-----------------+
362 | |
363 |~~~Send HOST_START_REQ_CMD~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
364 | |
365 |<--Send HOST_START_RES_CMD(Includes ISHTP_SUPPORT_CAP_LOADER bit)----|
366 | |
367 ****************************************************************************************
368 * if ISHTP_SUPPORT_CAP_LOADER bit is set *
369 ****************************************************************************************
370 | |
371 |~~~start loading firmware from host process~~~+ |
372 | | |
373 |<---------------------------------------------+ |
374 | |
375 --------------------------- |
376 | Call request_firmware() | |
377 --------------------------- |
378 | |
379 |~~~Send LOADER_CMD_XFER_QUERY~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
380 | |
381 |<--Send response-----------------------------------------------------|
382 | |
383 |~~~Send LOADER_CMD_XFER_FRAGMENT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
384 | |
385 |<--Send response-----------------------------------------------------|
386 | |
387 |~~~Send LOADER_CMD_START~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
388 | |
389 |<--Send response-----------------------------------------------------|
390 | |
391 | |~~~Jump to Main Firmware~~~+
392 | | |
393 | |<--------------------------+
394 | |
395 --------------------------- |
396 | Call release_firmware() | |
397 --------------------------- |
398 | |
399 ****************************************************************************************
400 * end if *
401 ****************************************************************************************
402 | |
403 +---------------+ +-----------------+
404 | ISHTP Driver | | ISH Bootloader |
405 +---------------+ +-----------------+
406
407 Vendor Custom Firmware Loading
408 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
409
410 The firmware running inside ISH can be provided by Intel or developed by vendors using the Firmware Development Kit (FDK) provided by Intel.
411 Intel will upstream the Intel-built firmware to the ``linux-firmware.git`` repository, located under the path ``intel/ish/``. For the Lunar Lake platform, the Intel-built ISH firmware will be named ``ish_lnlm.bin``.
412 Vendors who wish to upstream their custom firmware should follow these guidelines for naming their firmware files:
413
414 - The firmware filename should use one of the following patterns:
415
416 - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin``
417 - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin``
418 - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.bin``
419 - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}.bin``
420
421 - ``${intel_plat_gen}`` indicates the Intel platform generation (e.g., ``lnlm`` for Lunar Lake) and must not exceed 8 characters in length.
422 - ``${SYS_VENDOR_CRC32}`` is the CRC32 checksum of the ``sys_vendor`` value from the DMI field ``DMI_SYS_VENDOR``.
423 - ``${PRODUCT_NAME_CRC32}`` is the CRC32 checksum of the ``product_name`` value from the DMI field ``DMI_PRODUCT_NAME``.
424 - ``${PRODUCT_SKU_CRC32}`` is the CRC32 checksum of the ``product_sku`` value from the DMI field ``DMI_PRODUCT_SKU``.
425
426 During system boot, the ISH Linux driver will attempt to load the firmware in the following order, prioritizing custom firmware with more precise matching patterns:
427
428 1. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin``
429 2. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin``
430 3. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.bin``
431 4. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}.bin``
432 5. ``intel/ish/ish_${intel_plat_gen}.bin``
433
434 The driver will load the first matching firmware and skip the rest. If no matching firmware is found, it will proceed to the next pattern in the specified order. If all searches fail, the default Intel firmware, listed last in the order above, will be loaded.
435
436 ISH Debugging
437 -------------
438
439 To debug ISH, event tracing mechanism is used. To enable debug logs::
440
441 echo 1 > /sys/kernel/tracing/events/intel_ish/enable
442 cat /sys/kernel/tracing/trace
443
444 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
445 -------------------------------------------------
446
447 ::
448
449 root@otcpl-ThinkPad-Yoga-260:~# tree -l /sys/bus/iio/devices/
450 /sys/bus/iio/devices/
451 ├── iio:device0 -> ../../../devices/0044:8086:22D8.0001/HID-SENSOR-200073.9.auto/iio:device0
452 │   ├── buffer
453 │   │   ├── enable
454 │   │   ├── length
455 │   │   └── watermark
456 ...
457 │   ├── in_accel_hysteresis
458 │   ├── in_accel_offset
459 │   ├── in_accel_sampling_frequency
460 │   ├── in_accel_scale
461 │   ├── in_accel_x_raw
462 │   ├── in_accel_y_raw
463 │   ├── in_accel_z_raw
464 │   ├── name
465 │   ├── scan_elements
466 │   │   ├── in_accel_x_en
467 │   │   ├── in_accel_x_index
468 │   │   ├── in_accel_x_type
469 │   │   ├── in_accel_y_en
470 │   │   ├── in_accel_y_index
471 │   │   ├── in_accel_y_type
472 │   │   ├── in_accel_z_en
473 │   │   ├── in_accel_z_index
474 │   │   └── in_accel_z_type
475 ...
476 │   │   ├── devices
477 │   │   │   │   ├── buffer
478 │   │   │   │   │   ├── enable
479 │   │   │   │   │   ├── length
480 │   │   │   │   │   └── watermark
481 │   │   │   │   ├── dev
482 │   │   │   │   ├── in_intensity_both_raw
483 │   │   │   │   ├── in_intensity_hysteresis
484 │   │   │   │   ├── in_intensity_offset
485 │   │   │   │   ├── in_intensity_sampling_frequency
486 │   │   │   │   ├── in_intensity_scale
487 │   │   │   │   ├── name
488 │   │   │   │   ├── scan_elements
489 │   │   │   │   │   ├── in_intensity_both_en
490 │   │   │   │   │   ├── in_intensity_both_index
491 │   │   │   │   │   └── in_intensity_both_type
492 │   │   │   │   ├── trigger
493 │   │   │   │   │   └── current_trigger
494 ...
495 │   │   │   │   ├── buffer
496 │   │   │   │   │   ├── enable
497 │   │   │   │   │   ├── length
498 │   │   │   │   │   └── watermark
499 │   │   │   │   ├── dev
500 │   │   │   │   ├── in_magn_hysteresis
501 │   │   │   │   ├── in_magn_offset
502 │   │   │   │   ├── in_magn_sampling_frequency
503 │   │   │   │   ├── in_magn_scale
504 │   │   │   │   ├── in_magn_x_raw
505 │   │   │   │   ├── in_magn_y_raw
506 │   │   │   │   ├── in_magn_z_raw
507 │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_raw
508 │   │   │   │   ├── in_rot_hysteresis
509 │   │   │   │   ├── in_rot_offset
510 │   │   │   │   ├── in_rot_sampling_frequency
511 │   │   │   │   ├── in_rot_scale
512 │   │   │   │   ├── name
513 ...
514 │   │   │   │   ├── scan_elements
515 │   │   │   │   │   ├── in_magn_x_en
516 │   │   │   │   │   ├── in_magn_x_index
517 │   │   │   │   │   ├── in_magn_x_type
518 │   │   │   │   │   ├── in_magn_y_en
519 │   │   │   │   │   ├── in_magn_y_index
520 │   │   │   │   │   ├── in_magn_y_type
521 │   │   │   │   │   ├── in_magn_z_en
522 │   │   │   │   │   ├── in_magn_z_index
523 │   │   │   │   │   ├── in_magn_z_type
524 │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_en
525 │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_index
526 │   │   │   │   │   └── in_rot_from_north_magnetic_tilt_comp_type
527 │   │   │   │   ├── trigger
528 │   │   │   │   │   └── current_trigger
529 ...
530 │   │   │   │   ├── buffer
531 │   │   │   │   │   ├── enable
532 │   │   │   │   │   ├── length
533 │   │   │   │   │   └── watermark
534 │   │   │   │   ├── dev
535 │   │   │   │   ├── in_anglvel_hysteresis
536 │   │   │   │   ├── in_anglvel_offset
537 │   │   │   │   ├── in_anglvel_sampling_frequency
538 │   │   │   │   ├── in_anglvel_scale
539 │   │   │   │   ├── in_anglvel_x_raw
540 │   │   │   │   ├── in_anglvel_y_raw
541 │   │   │   │   ├── in_anglvel_z_raw
542 │   │   │   │   ├── name
543 │   │   │   │   ├── scan_elements
544 │   │   │   │   │   ├── in_anglvel_x_en
545 │   │   │   │   │   ├── in_anglvel_x_index
546 │   │   │   │   │   ├── in_anglvel_x_type
547 │   │   │   │   │   ├── in_anglvel_y_en
548 │   │   │   │   │   ├── in_anglvel_y_index
549 │   │   │   │   │   ├── in_anglvel_y_type
550 │   │   │   │   │   ├── in_anglvel_z_en
551 │   │   │   │   │   ├── in_anglvel_z_index
552 │   │   │   │   │   └── in_anglvel_z_type
553 │   │   │   │   ├── trigger
554 │   │   │   │   │   └── current_trigger
555 ...
556 │   │   │   │   ├── buffer
557 │   │   │   │   │   ├── enable
558 │   │   │   │   │   ├── length
559 │   │   │   │   │   └── watermark
560 │   │   │   │   ├── dev
561 │   │   │   │   ├── in_anglvel_hysteresis
562 │   │   │   │   ├── in_anglvel_offset
563 │   │   │   │   ├── in_anglvel_sampling_frequency
564 │   │   │   │   ├── in_anglvel_scale
565 │   │   │   │   ├── in_anglvel_x_raw
566 │   │   │   │   ├── in_anglvel_y_raw
567 │   │   │   │   ├── in_anglvel_z_raw
568 │   │   │   │   ├── name
569 │   │   │   │   ├── scan_elements
570 │   │   │   │   │   ├── in_anglvel_x_en
571 │   │   │   │   │   ├── in_anglvel_x_index
572 │   │   │   │   │   ├── in_anglvel_x_type
573 │   │   │   │   │   ├── in_anglvel_y_en
574 │   │   │   │   │   ├── in_anglvel_y_index
575 │   │   │   │   │   ├── in_anglvel_y_type
576 │   │   │   │   │   ├── in_anglvel_z_en
577 │   │   │   │   │   ├── in_anglvel_z_index
578 │   │   │   │   │   └── in_anglvel_z_type
579 │   │   │   │   ├── trigger
580 │   │   │   │   │   └── current_trigger
581 ...
582

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

통합 Sensor Hub의 목적과 USB 대응 모델

1-60

Sensor hub는 sensor polling과 algorithm 처리를 전용 저전력 co-processor로 넘깁니다. 그 결과 core processor가 더 자주 low-power mode에 들어갈 수 있어 battery life가 늘어납니다.

여러 vendor가 HID Sensor usage table을 따르는 외장 sensor hub를 공급하며, tablet, 2-in-1 convertible laptop, embedded product에서 사용됩니다. Linux는 Linux 3.9부터 이러한 외장 hub를 지원합니다.

Intel은 Cherry Trail부터 SoC에 Integrated Sensor Hub(ISH)를 넣었고, 이후 여러 세대의 CPU package에서 지원했습니다. 이미 많은 상용 장치에 ISH가 탑재되어 있습니다. ISH도 HID sensor specification을 따르지만 통신 transport protocol이 다릅니다. 외장 sensor hub는 주로 HID over I2C 또는 USB를 쓰는 반면, ISH는 I2C와 USB 어느 쪽도 사용하지 않습니다.

ISH는 빠른 통신을 위해 usbhid와 비슷한 계층 모델을 사용합니다. `USB HID`에 `ISH HID`, `USB protocol`에 `ISH Transport`, `EHCI/XHCI`에 `ISH IPC`, `Host controller`에 `ISH processor`, `USB End points`에 `ISH Clients`가 각각 대응합니다. 양쪽 controller 계층은 PCI로 host에 연결됩니다.

USB protocol이 device enumeration, link management, user data encapsulation을 제공하듯 ISH도 같은 종류의 서비스를 제공합니다. 다만 firmware에 구현된 ISH client application을 관리하고 통신하는 데 맞춘 매우 가벼운 protocol입니다.

ISH firmware 안에서는 여러 sensor management application을 동시에 실행할 수 있습니다. USB endpoint처럼 각 client로 message를 보내거나 client에서 받을 수 있으며 enumeration 과정에서 client를 식별합니다. Client는 단순 HID sensor application, sensor calibration application 또는 sensor firmware update application일 수 있습니다.

구현 모델에서도 ISH transport는 USB bus처럼 bus로 구현됩니다. ISH processor에서 실행되는 각 client application은 이 bus의 device로 등록됩니다. 각 device에 bind하는 ISH HID driver가 device type을 판별하고 HID core에 등록합니다.

USB와 ISH 계층 대응
USB 모델ISH 모델역할
USB HIDISH HIDHID device 표현
USB protocolISH Transport열거·link 관리·data 캡슐화
EHCI/XHCIISH IPC저수준 message 전송
Host controllerISH processorPCI에 노출되는 controller
USB End pointsISH Clientsfirmware application별 통신 종단

원문의 비교 도식을 같은 역할끼리 정렬했습니다.

ISH client가 HID device가 되는 과정
ISH firmware에서 sensor·calibration·update client 실행ISH transport가 client를 enumeration각 client를 ishtp bus device로 등록ISH HID driver가 device type을 식별하고 bindHID core에 device 등록

Firmware client가 Linux HID 계층에 나타나는 경로입니다.

=================================
Intel Integrated Sensor Hub (ISH)
=================================

A sensor hub enables the ability to offload sensor polling and algorithm
processing to a dedicated low power co-processor. This allows the core
processor to go into low power modes more often, resulting in increased
battery life.

There are many vendors providing external sensor hubs conforming to HID
Sensor usage tables. These may be found in tablets, 2-in-1 convertible laptops
and embedded products. Linux has had this support since Linux 3.9.

Intel® introduced integrated sensor hubs as a part of the SoC starting from
Cherry Trail and now supported on multiple generations of CPU packages. There
are many commercial devices already shipped with Integrated Sensor Hubs (ISH).
These ISH also comply to HID sensor specification, but the difference is the
transport protocol used for communication. The current external sensor hubs
mainly use HID over I2C or USB. But ISH doesn't use either I2C or USB.

Overview
========

Using a analogy with a usbhid implementation, the ISH follows a similar model
for a very high speed communication::

        -----------------                ----------------------
        |    USB HID        |        -->        |    ISH HID             |
        -----------------                ----------------------
        -----------------                ----------------------
        |  USB protocol        |        -->        |    ISH Transport   |
        -----------------                ----------------------
        -----------------                ----------------------
        |  EHCI/XHCI        |        -->        |    ISH IPC             |
        -----------------                ----------------------
              PCI                                 PCI
        -----------------                ----------------------
        |Host controller|        -->        |    ISH processor   |
        -----------------                ----------------------
             USB Link
        -----------------                ----------------------
        | USB End points|        -->        |    ISH Clients     |
        -----------------                ----------------------

Like USB protocol provides a method for device enumeration, link management
and user data encapsulation, the ISH also provides similar services. But it is
very light weight tailored to manage and communicate with ISH client
applications implemented in the firmware.

The ISH allows multiple sensor management applications executing in the
firmware. Like USB endpoints the messaging can be to/from a client. As part of
enumeration process, these clients are identified. These clients can be simple
HID sensor applications, sensor calibration applications or sensor firmware
update applications.

The implementation model is similar, like USB bus, ISH transport is also
implemented as a bus. Each client application executing in the ISH processor
is registered as a device on this bus. The driver, which binds each device
(ISH HID driver) identifies the device type and registers with the HID core.

ISH software stack과 hardware interface

61-116

구현 stack의 맨 위에는 user space application이 있고 IIO ABI를 통해 IIO Sensor Driver와 통신합니다. 그 아래로 IIO core, HID Sensor Hub MFD, HID Core, HID over ISH Client, ISH Transport(ISHTP), IPC Driver가 차례로 놓입니다. OS와 hardware·firmware의 경계는 PCI이며, 최하단에는 ISH Hardware/Firmware(FW)가 있습니다.

Host에서 ISH는 `Non-VGA unclassified PCI device`로 노출됩니다. PCI product ID와 vendor ID는 processor generation에 따라 달라지므로 driver를 enumerate하는 source code도 세대가 바뀔 때마다 갱신해야 합니다.

Inter Processor Communication(IPC) driver는 `drivers/hid/intel-ish-hid/ipc`에 있습니다. IPC message는 memory-mapped I/O를 사용하고 관련 register는 `hw-ish-regs.h`에 정의됩니다.

ISH 구현 계층
영역계층책임
UserspaceUser Space Applications · IIO ABISensor data와 control interface 사용
Linux sensorIIO Sensor Drivers · IIO coreSensor별 IIO device와 ABI 제공
Linux HIDHID Sensor Hub MFD · HID CoreSensor hub 기능 분리와 HID 공통 처리
ISH clientHID over ISH ClientISH client protocol을 HID operation으로 연결
TransportISH Transport (ISHTP)Client enumeration·connection·flow control
Low levelIPC Drivers · PCIMMIO message와 interrupt 처리
DeviceISH Hardware/Firmware(FW)저전력 processor와 firmware client 실행

원문의 세로 block diagram을 userspace에서 hardware까지 정리했습니다.

Sensor data의 상향 경로
ISH Hardware/Firmware가 sensor report 생성PCI·IPC Driver가 message 수신ISHTP가 대상 firmware client 연결로 전달HID over ISH와 HID Core가 HID report 처리HID Sensor Hub MFD와 IIO driver가 sensor channel 구성IIO ABI를 통해 userspace application에 노출

ISH에서 userspace까지 data가 이동하는 계층입니다.

ISH Implementation: Block Diagram
=================================

::

         ---------------------------
        |  User Space Applications  |
         ---------------------------

  ----------------IIO ABI----------------
         --------------------------
        |  IIO Sensor Drivers          |
         --------------------------
         --------------------------
        |         IIO core          |
         --------------------------
         --------------------------
        |   HID Sensor Hub MFD          |
         --------------------------
         --------------------------
        |       HID Core          |
         --------------------------
         --------------------------
        |   HID over ISH Client   |
         --------------------------
         --------------------------
        |   ISH Transport (ISHTP) |
         --------------------------
         --------------------------
        |      IPC Drivers          |
         --------------------------
  OS
  ---------------- PCI -----------------
  Hardware + Firmware
         ----------------------------
        | ISH Hardware/Firmware(FW) |
         ----------------------------

High level processing in above blocks
=====================================

Hardware Interface
------------------

The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI
product and vendor IDs are changed from different generations of processors. So
the source code which enumerates drivers needs to update from generation to
generation.

Inter Processor Communication (IPC) driver
------------------------------------------

Location: drivers/hid/intel-ish-hid/ipc

The IPC message uses memory mapped I/O. The registers are defined in
hw-ish-regs.h.

IPC message, doorbell과 ISHTP flow control

117-182

IPC/FW message에는 두 종류가 있습니다. 하나는 link를 관리하는 message이고, 다른 하나는 transport layer로 오가는 data message입니다.

여러 byte의 transport message를 송수신하기 위해 `IPC_REG_ISH2HOST_MSG`, `IPC_REG_HOST2ISH_MSG` 같은 memory-mapped register 집합을 사용합니다. IPC layer는 internal queue로 message 순서를 유지하여 firmware에 전송하며, caller는 선택적으로 completion notification handler를 등록할 수 있습니다.

Message 처리를 host와 client firmware 쪽에서 시작시키는 데 doorbell mechanism을 씁니다. ISH interrupt handler가 호출되면 host driver는 ISH2HOST doorbell register를 확인해 그 interrupt가 ISH에서 온 것인지 판별합니다.

양쪽에는 각각 32개의 32-bit message register와 하나의 32-bit doorbell이 있습니다. Doorbell bit 0..6은 7-bit fragment length, 10..13은 encapsulated protocol, 16..19는 IPC management protocol의 management command, bit 31은 상대편에 hardware interrupt를 발생시키는 trigger입니다. 나머지 bit는 reserved이며 0이어야 합니다.

Hardware 수준 IPC를 추상화하기 위해 callback 집합을 등록하며 transport layer는 이 callback으로 message를 송수신합니다. Callback 정의는 `struct ishtp_hw_ops`를 참조합니다.

ISH transport layer는 `drivers/hid/intel-ish-hid/ishtp/`에 있습니다. 이 양방향 generic protocol은 start, stop, connect, disconnect, flow control command 집합과 buffer overflow를 막는 flow-control mechanism을 정의합니다. 자세한 command는 `ishtp/hbm.h`에 있으며, protocol 구조는 Intel DCMI 문서 Chapter 7의 Bus Message Layer와 비슷합니다.

각 FW client와 protocol은 UUID로 식별합니다. 통신하려면 connect request와 response bus message로 connection을 맺어야 하며, 성공하면 `(host_client_id, fw_client_id)` 쌍이 connection을 식별합니다.

Connection이 성립한 뒤 두 peer는 서로 독립적으로 flow-control bus message를 보냅니다. 각 peer는 미리 flow-control credit을 받은 경우에만 message 하나를 보낼 수 있고, 보낸 뒤에는 다음 credit을 받을 때까지 다른 message를 보낼 수 없습니다. 어느 쪽이든 disconnect request를 보내 통신을 끝낼 수 있으며 major FW reset이 발생해도 link가 끊깁니다.

32-bit doorbell format
Bit필드의미
0..6fragment length현재 fragment 길이, 7 bits
10..13encapsulated protocoldoorbell에 실린 protocol 종류
16..19management commandIPC management protocol command
31doorbell trigger상대편에 hardware interrupt 신호
그 밖의 bitreserved0으로 설정

Reserved bit는 항상 0으로 유지해야 합니다.

ISHTP connection과 credit
UUID로 FW client와 protocol 식별Connect request bus message 전송Connect response 성공 확인(host_client_id, fw_client_id) 쌍으로 connection 식별상대 peer에서 flow-control credit 수신Message 하나를 전송하고 credit 소비다음 credit을 기다리거나 disconnect·FW reset으로 종료

한 message마다 credit을 소비하는 흐름입니다.


IPC/FW message types
^^^^^^^^^^^^^^^^^^^^

There are two types of messages, one for management of link and another for
messages to and from transport layers.

TX and RX of Transport messages
...............................

A set of memory mapped register offers support of multi-byte messages TX and
RX (e.g. IPC_REG_ISH2HOST_MSG, IPC_REG_HOST2ISH_MSG). The IPC layer maintains
internal queues to sequence messages and send them in order to the firmware.
Optionally the caller can register handler to get notification of completion.
A doorbell mechanism is used in messaging to trigger processing in host and
client firmware side. When ISH interrupt handler is called, the ISH2HOST
doorbell register is used by host drivers to determine that the interrupt
is for ISH.

Each side has 32 32-bit message registers and a 32-bit doorbell. Doorbell
register has the following format::

  Bits 0..6: fragment length (7 bits are used)
  Bits 10..13: encapsulated protocol
  Bits 16..19: management command (for IPC management protocol)
  Bit 31: doorbell trigger (signal H/W interrupt to the other side)
  Other bits are reserved, should be 0.

Transport layer interface
^^^^^^^^^^^^^^^^^^^^^^^^^

To abstract HW level IPC communication, a set of callbacks is registered.
The transport layer uses them to send and receive messages.
Refer to struct ishtp_hw_ops for callbacks.

ISH Transport layer
-------------------

Location: drivers/hid/intel-ish-hid/ishtp/

A Generic Transport Layer
^^^^^^^^^^^^^^^^^^^^^^^^^

The transport layer is a bi-directional protocol, which defines:
- Set of commands to start, stop, connect, disconnect and flow control
(see ishtp/hbm.h for details)
- A flow control mechanism to avoid buffer overflows

This protocol resembles bus messages described in the following document:
http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"

Connection and Flow Control Mechanism
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Each FW client and a protocol is identified by a UUID. In order to communicate
to a FW client, a connection must be established using connect request and
response bus messages. If successful, a pair (host_client_id and fw_client_id)
will identify the connection.

Once connection is established, peers send each other flow control bus messages
independently. Every peer may send a message only if it has received a
flow-control credit before. Once it has sent a message, it may not send another one
before receiving the next flow control credit.
Either side can send disconnect request bus message to end communication. Also
the link will be dropped if major FW reset occurs.

Peer-to-peer DMA와 ring buffer

183-229

Peer-to-peer data transfer는 DMA를 사용하거나 사용하지 않고 수행할 수 있습니다. Sensor bandwidth 요구에 따라 `intel_ishtp`의 module parameter `ishtp_use_dma`로 DMA를 활성화합니다.

Host와 FW는 각자 DMA transfer memory를 독립적으로 관리합니다. 어느 쪽의 ISHTP client든 전송할 때마다 IPC와 DMA 중 하나를 독립적으로 선택합니다. Sender는 message가 해당 host buffer에 있을 때 `DMA_XFER`를 보냅니다. Host client가 보낼 때는 TX buffer, FW client가 보낼 때는 RX buffer입니다. Recipient는 `DMA_XFER_ACK`로 응답하여 그 memory region을 sender가 다시 써도 된다고 알립니다.

DMA 초기화는 host가 RX buffer 정보를 포함한 `DMA_ALLOC_NOTIFY` bus message를 보내고 FW가 `DMA_ALLOC_NOTIFY_ACK`로 응답하면서 시작됩니다. 이 교환은 DMA address뿐 아니라 capability도 확인합니다. Host가 DMA를 지원하지 않으면 allocation message를 보내지 않아 FW가 DMA를 쓸 수 없습니다. FW가 지원하지 않으면 ACK하지 않으므로 host도 DMA transfer를 사용하지 않습니다.

여기서 ISH는 busmaster DMA controller입니다. Host가 `DMA_XFER`를 보내면 host에서 ISH로 DMA하라는 request이고, FW가 보내면 이미 DMA를 수행하여 message가 host에 있다는 뜻입니다. 따라서 `DMA_XFER`와 `DMA_XFER_ACK`는 memory ownership indicator로 작동합니다.

초기에는 모든 outgoing memory가 sender 소유입니다. Host의 TX는 host가, FW의 RX는 FW가 소유합니다. `DMA_XFER`가 ISHTP message를 담은 region의 ownership을 receiver로 넘기고, `DMA_XFER_ACK`가 sender에게 돌려줍니다. Sender가 소유한 연속 memory가 다음 message를 담기에 충분하면 이전 XFER의 ACK를 기다리지 않고 다음 message를 보낼 수 있습니다.

원칙적으로 IPC MTU까지 여러 `DMA_XFER`와 `DMA_XFER_ACK`를 한 번에 보내 interrupt를 줄일 수 있습니다. 현재 ISH FW는 ISHTP message가 IPC fragment 3개보다 크면 DMA를, 그렇지 않으면 IPC를 선택합니다.

Client가 connection을 시작하면 RX·TX buffer ring을 할당하며 ring size는 client가 지정할 수 있습니다. HID client는 TX 16개와 RX 32개를 사용합니다. Send request의 data는 send ring buffer 하나에 복사된 뒤 bus message protocol 전송 대상으로 schedule됩니다. FW가 이전 message를 아직 처리하지 않았거나 flow-control credit이 부족할 수 있으므로 이런 buffer가 필요합니다. Receive 쪽도 같은 이유로 buffer와 flow control이 필요합니다.

DMA message와 ownership
Message방향·시점결과
DMA_ALLOC_NOTIFYHost → FW, 초기화RX buffer와 DMA capability 통지
DMA_ALLOC_NOTIFY_ACKFW → HostFW의 DMA 지원 확인
DMA_XFERSender → RecipientMessage region ownership을 recipient로 이전
DMA_XFER_ACKRecipient → SenderRegion을 sender가 재사용하도록 ownership 반환
IPC 직접 전송3 fragment 이하인 현재 FW 정책DMA ownership 교환 없이 전송

각 message가 memory 소유권에 미치는 영향을 정리했습니다.

DMA transfer 수명주기
Host가 DMA_ALLOC_NOTIFY로 RX buffer 통지FW가 DMA_ALLOC_NOTIFY_ACK로 지원 확인Transfer마다 IPC와 DMA 중 하나 선택DMA_XFER로 region ownership 이전Recipient가 data 처리DMA_XFER_ACK로 ownership 반환연속 소유 memory가 충분하면 여러 transfer를 pipeline

Capability 협상부터 buffer 재사용까지의 순서입니다.


Peer to Peer data transfer
^^^^^^^^^^^^^^^^^^^^^^^^^^

Peer to Peer data transfer can happen with or without using DMA. Depending on
the sensor bandwidth requirement DMA can be enabled by using module parameter
ishtp_use_dma under intel_ishtp.

Each side (host and FW) manages its DMA transfer memory independently. When an
ISHTP client from either host or FW side wants to send something, it decides
whether to send over IPC or over DMA; for each transfer the decision is
independent. The sending side sends DMA_XFER message when the message is in
the respective host buffer (TX when host client sends, RX when FW client
sends). The recipient of DMA message responds with DMA_XFER_ACK, indicating
the sender that the memory region for that message may be reused.

DMA initialization is started with host sending DMA_ALLOC_NOTIFY bus message
(that includes RX buffer) and FW responds with DMA_ALLOC_NOTIFY_ACK.
Additionally to DMA address communication, this sequence checks capabilities:
if the host doesn't support DMA, then it won't send DMA allocation, so FW can't
send DMA; if FW doesn't support DMA then it won't respond with
DMA_ALLOC_NOTIFY_ACK, in which case host will not use DMA transfers.
Here ISH acts as busmaster DMA controller. Hence when host sends DMA_XFER,
it's request to do host->ISH DMA transfer; when FW sends DMA_XFER, it means
that it already did DMA and the message resides at host. Thus, DMA_XFER
and DMA_XFER_ACK act as ownership indicators.

At initial state all outgoing memory belongs to the sender (TX to host, RX to
FW), DMA_XFER transfers ownership on the region that contains ISHTP message to
the receiving side, DMA_XFER_ACK returns ownership to the sender. A sender
need not wait for previous DMA_XFER to be ack'ed, and may send another message
as long as remaining continuous memory in its ownership is enough.
In principle, multiple DMA_XFER and DMA_XFER_ACK messages may be sent at once
(up to IPC MTU), thus allowing for interrupt throttling.
Currently, ISH FW decides to send over DMA if ISHTP message is more than 3 IPC
fragments and via IPC otherwise.

Ring Buffers
^^^^^^^^^^^^

When a client initiates a connection, a ring of RX and TX buffers is allocated.
The size of ring can be specified by the client. HID client sets 16 and 32 for
TX and RX buffers respectively. On send request from client, the data to be
sent is copied to one of the send ring buffer and scheduled to be sent using
bus message protocol. These buffers are required because the FW may have not
have processed the last message and may not have enough flow control credits
to send. Same thing holds true on receive side and flow control is required.

Host enumeration과 HID over ISH client

230-275

Host enumeration bus command는 FW에 존재하는 client를 발견합니다. 여러 sensor client와 calibration 기능 client가 함께 존재할 수 있습니다.

각 client를 독립 driver가 쉽게 처리하도록 transport layer는 Linux Bus driver model을 이용합니다. 발견한 client마다 ISHTP bus의 device로 등록합니다.

Enumeration은 host가 ISHTP layer 준비를 알리는 `HOST_START_REQ_CMD`를 보내면서 시작합니다. FW가 `HOST_START_RES_CMD`로 응답하면 host는 FW client 열거를 요청하는 `HOST_ENUM_REQ_CMD`를 보내고, FW는 사용 가능한 FW client ID bitmap을 담은 `HOST_ENUM_RES_CMD`로 응답합니다.

Host는 bitmap에서 찾은 FW ID마다 `HOST_CLIENT_PROPERTIES_REQ_CMD`를 보냅니다. FW의 `HOST_CLIENT_PROPERTIES_RES_CMD`에는 UUID, 최대 ISHTP message size 등의 property가 들어 있습니다. 마지막 client의 property까지 받으면 host는 ISHTP device가 완전히 동작한다고 판단하고 DMA buffer를 할당합니다.

HID over ISH client driver의 위치는 `drivers/hid/intel-ish-hid`입니다. 이 driver는 FW ISH client 아래의 HID device를 열거하고 Report descriptor를 가져오며, HID core에 low-level driver로 등록합니다. 또한 Get/Set feature request와 input report 수신을 처리합니다.

HID Sensor Hub MFD와 IIO sensor driver의 기능은 외장 sensor hub에서와 같습니다. HID sensor 설명은 `Documentation/hid/hid-sensor.rst`, userspace용 IIO ABI는 `Documentation/ABI/testing/sysfs-bus-iio`를 참조합니다.

Host enumeration command
순서Command내용
1HOST_START_REQ_CMDHost ISHTP layer 준비 통지
2HOST_START_RES_CMDFirmware 시작 응답
3HOST_ENUM_REQ_CMDFW client 열거 요청
4HOST_ENUM_RES_CMD사용 가능한 client ID bitmap
5HOST_CLIENT_PROPERTIES_REQ_CMDBitmap의 각 FW ID property 요청
6HOST_CLIENT_PROPERTIES_RES_CMDUUID·최대 message size 등 응답

Firmware client가 bus device가 될 때까지의 command입니다.

Firmware client 등록
Start request·response로 ISHTP 시작Enumeration response의 client ID bitmap 해석각 client의 UUID와 최대 message size 조회Client별 ishtp bus device 생성마지막 client 뒤 DMA buffer 할당HID over ISH driver가 bind하고 HID core에 등록

마지막 property 응답 뒤 transport가 정상 동작합니다.


Host Enumeration
^^^^^^^^^^^^^^^^

The host enumeration bus command allows discovery of clients present in the FW.
There can be multiple sensor clients and clients for calibration function.

To ease implementation and allow independent drivers to handle each client,
this transport layer takes advantage of Linux Bus driver model. Each
client is registered as device on the transport bus (ishtp bus).

Enumeration sequence of messages:

- Host sends HOST_START_REQ_CMD, indicating that host ISHTP layer is up.
- FW responds with HOST_START_RES_CMD
- Host sends HOST_ENUM_REQ_CMD (enumerate FW clients)
- FW responds with HOST_ENUM_RES_CMD that includes bitmap of available FW
  client IDs
- For each FW ID found in that bitmap host sends
  HOST_CLIENT_PROPERTIES_REQ_CMD
- FW responds with HOST_CLIENT_PROPERTIES_RES_CMD. Properties include UUID,
  max ISHTP message size, etc.
- Once host received properties for that last discovered client, it considers
  ISHTP device fully functional (and allocates DMA buffers)

HID over ISH Client
-------------------

Location: drivers/hid/intel-ish-hid

The ISHTP client driver is responsible for:

- enumerate HID devices under FW ISH client
- Get Report descriptor
- Register with HID core as a LL driver
- Process Get/Set feature request
- Get input reports

HID Sensor Hub MFD and IIO sensor drivers
-----------------------------------------

The functionality in these drivers is the same as an external sensor hub.
Refer to
Documentation/hid/hid-sensor.rst for HID sensor
Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space.

End-to-end HID transport sequence

276-340

전체 sequence에는 HID-ISH-CLN, ISHTP, IPC, HW 네 참여자가 있습니다. 먼저 IPC가 HW에 `WAKE UP`과 `HOST READY`를 보내고, HW는 `MNG_RESET_NOTIFY_ACK`를 돌려줍니다. IPC는 ISHTP에 `ISHTP_START`를 알리고, HW에서 ISHTP로 `HOST_START_RES_CMD`가 도착합니다.

ISHTP는 HW에 `QUERY_SUBSCRIBER`와 `HOST_ENUM_REQ_CMD`를 보내고 `HOST_ENUM_RES_CMD`를 받습니다. 이어 `HOST_CLIENT_PROPERTIES_REQ_CMD`와 `HOST_CLIENT_PROPERTIES_RES_CMD`를 client마다 반복합니다. 각 property 응답 뒤 ishtp bus에 새 device를 만들고 마지막 client까지 이 과정을 계속합니다.

생성된 HID-ISH client driver의 `probed()`가 실행되면 `ishtp_cl_connect`가 ISHTP에 연결을 요청합니다. ISHTP는 HW에 `CLIENT_CONNECT_REQ_CMD`를 보내고 `CLIENT_CONNECT_RES_CMD`를 받은 뒤 client가 event callback을 등록합니다.

Client는 `ishtp_cl_send(HOSTIF_DM_ENUM_DEVICES)`로 firmware 아래 HID device를 열거합니다. ISHTP는 `ishtp_msg_hdr` 구조체를 채워 hardware에 쓰고, HW interrupt `IRQ(IPC_PROTOCOL_ISHTP)`가 IPC에 전달된 다음 `ENUM_DEVICE RSP`가 client로 돌아옵니다.

열거된 각 device에 대해 client가 `HOSTIF_GET_HID_DESCRIPTOR`를 보내 HID descriptor와 response를 받고, 다시 `HOSTIF_GET_REPORT_DESCRIPTOR`를 보내 report descriptor를 받습니다. 필요한 descriptor를 모두 확보하면 `hid_allocate_device`와 `hid_add_device`를 실행해 Linux HID device를 완성합니다.

End-to-end phase
단계주요 message·함수결과
Hardware 준비WAKE UP · HOST READY · MNG_RESET_NOTIFY_ACKIPC와 ISH HW 준비
Transport 시작ISHTP_START · HOST_START_RES_CMDISHTP 시작 확인
Client 발견QUERY_SUBSCRIBER · HOST_ENUM_REQ_CMD/RES_CMDFW client ID 확보
Property 반복HOST_CLIENT_PROPERTIES_REQ_CMD/RES_CMDishtp bus device 생성
Client 연결ishtp_cl_connect · CLIENT_CONNECT_REQ_CMD/RES_CMDEvent callback 등록 가능
HID 열거HOSTIF_DM_ENUM_DEVICES · ENUM_DEVICE RSPFW 아래 HID device 목록 확보
DescriptorHOSTIF_GET_HID_DESCRIPTOR · HOSTIF_GET_REPORT_DESCRIPTORHID metadata 확보
등록hid_allocate_device · hid_add_deviceLinux HID device 생성

원문의 네 열 sequence diagram을 단계별로 정리했습니다.

HID device 완성 경로
IPC가 ISH hardware를 깨우고 host ready 통지ISHTP를 시작하고 firmware client 열거각 client property로 ishtp bus device 생성HID-ISH client가 connect하고 callback 등록HOSTIF_DM_ENUM_DEVICES로 HID device 열거HID descriptor와 report descriptor 조회hid_allocate_device와 hid_add_device 실행

Hardware wake-up에서 HID core 등록까지 이어집니다.

End to End HID transport Sequence Diagram
-----------------------------------------

::

  HID-ISH-CLN                    ISHTP                    IPC                             HW
          |                        |                       |                               |
          |                        |                       |-----WAKE UP------------------>|
          |                        |                       |                               |
          |                        |                       |-----HOST READY--------------->|
          |                        |                       |                               |
          |                        |                       |<----MNG_RESET_NOTIFY_ACK----- |
          |                        |                       |                               |
          |                        |<----ISHTP_START------ |                               |
          |                        |                       |                               |
          |                        |<-----------------HOST_START_RES_CMD-------------------|
          |                        |                       |                               |
          |                        |------------------QUERY_SUBSCRIBER-------------------->|
          |                        |                       |                               |
          |                        |------------------HOST_ENUM_REQ_CMD------------------->|
          |                        |                       |                               |
          |                        |<-----------------HOST_ENUM_RES_CMD--------------------|
          |                        |                       |                               |
          |                        |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
          |                        |                       |                               |
          |                        |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
          |       Create new device on in ishtp bus        |                               |
          |                        |                       |                               |
          |                        |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
          |                        |                       |                               |
          |                        |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
          |       Create new device on in ishtp bus        |                               |
          |                        |                       |                               |
          |                        |--Repeat HOST_CLIENT_PROPERTIES_REQ_CMD-till last one--|
          |                        |                       |                               |
       probed()
          |----ishtp_cl_connect--->|----------------- CLIENT_CONNECT_REQ_CMD-------------->|
          |                        |                       |                               |
          |                        |<----------------CLIENT_CONNECT_RES_CMD----------------|
          |                        |                       |                               |
          |register event callback |                       |                               |
          |                        |                       |                               |
          |ishtp_cl_send(
          HOSTIF_DM_ENUM_DEVICES)  |----------fill ishtp_msg_hdr struct write to HW-----  >|
          |                        |                       |                               |
          |                        |                       |<-----IRQ(IPC_PROTOCOL_ISHTP---|
          |                        |                       |                               |
          |<--ENUM_DEVICE RSP------|                       |                               |
          |                        |                       |                               |
  for each enumerated device
          |ishtp_cl_send(
          HOSTIF_GET_HID_DESCRIPTOR|----------fill ishtp_msg_hdr struct write to HW-----  >|
          |                        |                       |                               |
          ...Response
          |                        |                       |                               |
  for each enumerated device
          |ishtp_cl_send(
       HOSTIF_GET_REPORT_DESCRIPTOR|--------------fill ishtp_msg_hdr struct write to HW-- >|
          |                        |                       |                               |
          |                        |                       |                               |
   hid_allocate_device
          |                        |                       |                               |
   hid_add_device                  |                       |                               |
          |                        |                       |                               |

Lunar Lake 이후 host firmware loading

341-406

Lunar Lake generation부터 공간 최적화와 유연성을 높이기 위해 ISH firmware를 두 component로 나눴습니다. Bootloader는 BIOS에 통합되고 main firmware는 operating system file system에 저장됩니다.

먼저 ISHTP driver가 ISH bootloader에 `HOST_START_REQ_CMD`를 보냅니다. Bootloader의 `HOST_START_RES_CMD`에는 `ISHTP_SUPPORT_CAP_LOADER` bit가 들어 있습니다. Driver가 이 bit의 설정을 확인하면 host에서 firmware를 적재하는 절차를 시작합니다.

Driver는 먼저 `request_firmware()`를 호출하고 `LOADER_CMD_XFER_QUERY`를 보냅니다. Bootloader response를 받은 뒤 `LOADER_CMD_XFER_FRAGMENT`를 전송하고 다시 response를 기다립니다. 이어 `LOADER_CMD_START`를 보내고 응답을 받으면 bootloader가 main firmware로 jump합니다.

적재 절차가 끝나면 ISHTP driver는 `release_firmware()`를 호출합니다. `ISHTP_SUPPORT_CAP_LOADER` bit가 설정되지 않은 경우 이 host loading block 전체를 수행하지 않습니다.

Host firmware loading protocol
순서Driver 동작Bootloader 동작
1HOST_START_REQ_CMD 전송HOST_START_RES_CMD와 ISHTP_SUPPORT_CAP_LOADER bit 응답
2Capability bit 확인Host loading 지원 여부 제공
3request_firmware() 호출OS file system의 main firmware 수신 준비
4LOADER_CMD_XFER_QUERY 전송Query response
5LOADER_CMD_XFER_FRAGMENT 전송Fragment response
6LOADER_CMD_START 전송Response 후 main firmware로 jump
7release_firmware() 호출Main firmware 실행

Bootloader와 ISHTP driver가 교환하는 순서입니다.

Lunar Lake firmware 적재
HOST_START_REQ_CMD 전송HOST_START_RES_CMD의 ISHTP_SUPPORT_CAP_LOADER 확인request_firmware()로 image 확보LOADER_CMD_XFER_QUERY로 전송 조건 협상LOADER_CMD_XFER_FRAGMENT로 firmware 전달LOADER_CMD_START로 main firmware 시작release_firmware()로 image 해제

Capability가 있을 때만 점선 안의 적재 절차를 수행합니다.


ISH Firmware Loading from Host Flow
-----------------------------------

Starting from the Lunar Lake generation, the ISH firmware has been divided into two components for better space optimization and increased flexibility. These components include a bootloader that is integrated into the BIOS, and a main firmware that is stored within the operating system's file system.

The process works as follows:

- Initially, the ISHTP driver sends a command, HOST_START_REQ_CMD, to the ISH bootloader. In response, the bootloader sends back a HOST_START_RES_CMD. This response includes the ISHTP_SUPPORT_CAP_LOADER bit. Subsequently, the ISHTP driver checks if this bit is set. If it is, the firmware loading process from the host begins.

- During this process, the ISHTP driver first invokes the request_firmware() function, followed by sending a LOADER_CMD_XFER_QUERY command. Upon receiving a response from the bootloader, the ISHTP driver sends a LOADER_CMD_XFER_FRAGMENT command. After receiving another response, the ISHTP driver sends a LOADER_CMD_START command. The bootloader responds and then proceeds to the Main Firmware.

- After the process concludes, the ISHTP driver calls the release_firmware() function.

For more detailed information, please refer to the flow descriptions provided below:

::

  +---------------+                                                    +-----------------+
  | ISHTP Driver  |                                                    | ISH Bootloader  |
  +---------------+                                                    +-----------------+
          |                                                                     |
          |~~~Send HOST_START_REQ_CMD~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
          |                                                                     |
          |<--Send HOST_START_RES_CMD(Includes ISHTP_SUPPORT_CAP_LOADER bit)----|
          |                                                                     |
  ****************************************************************************************
  * if ISHTP_SUPPORT_CAP_LOADER bit is set                                               *
  ****************************************************************************************
          |                                                                     |
          |~~~start loading firmware from host process~~~+                      |
          |                                              |                      |
          |<---------------------------------------------+                      |
          |                                                                     |
  ---------------------------                                                   |
  | Call request_firmware() |                                                   |
  ---------------------------                                                   |
          |                                                                     |
          |~~~Send LOADER_CMD_XFER_QUERY~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
          |                                                                     |
          |<--Send response-----------------------------------------------------|
          |                                                                     |
          |~~~Send LOADER_CMD_XFER_FRAGMENT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
          |                                                                     |
          |<--Send response-----------------------------------------------------|
          |                                                                     |
          |~~~Send LOADER_CMD_START~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
          |                                                                     |
          |<--Send response-----------------------------------------------------|
          |                                                                     |
          |                                                                     |~~~Jump to Main Firmware~~~+
          |                                                                     |                           |
          |                                                                     |<--------------------------+
          |                                                                     |
  ---------------------------                                                   |
  | Call release_firmware() |                                                   |
  ---------------------------                                                   |
          |                                                                     |
  ****************************************************************************************
  * end if                                                                               *
  ****************************************************************************************
          |                                                                     |
  +---------------+                                                    +-----------------+
  | ISHTP Driver  |                                                    | ISH Bootloader  |
  +---------------+                                                    +-----------------+

Vendor custom firmware 이름과 검색 우선순위

407-435

ISH에서 실행되는 firmware는 Intel이 제공하거나 vendor가 Intel Firmware Development Kit(FDK)로 개발할 수 있습니다. Intel-built firmware는 `linux-firmware.git` repository의 `intel/ish/` 아래에 upstream됩니다. Lunar Lake용 Intel firmware 이름은 `ish_lnlm.bin`입니다.

Vendor custom firmware filename은 네 pattern 중 하나를 사용해야 합니다. 가장 구체적인 형식은 `ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin`입니다. 그 밖에 product SKU만 포함한 `ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin`, product name만 포함한 `ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.bin`, system vendor만 포함한 `ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}.bin`을 사용할 수 있습니다.

`${intel_plat_gen}`은 Intel platform generation을 뜻하며 Lunar Lake의 `lnlm`처럼 최대 8자입니다. `${SYS_VENDOR_CRC32}`는 DMI field `DMI_SYS_VENDOR`의 `sys_vendor`, `${PRODUCT_NAME_CRC32}`는 `DMI_PRODUCT_NAME`의 `product_name`, `${PRODUCT_SKU_CRC32}`는 `DMI_PRODUCT_SKU`의 `product_sku`에 대한 CRC32 checksum입니다.

Boot 중 driver는 가장 정밀한 custom match부터 차례로 검색합니다. 첫 일치 firmware를 적재하고 나머지는 건너뜁니다. 일치하지 않으면 다음 pattern으로 넘어가며 custom search가 모두 실패하면 마지막 기본 Intel firmware를 사용합니다.

Firmware 검색 순서
우선순위Filename일치 범위
1ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.binVendor + product name + SKU
2ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.binVendor + SKU
3ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.binVendor + product name
4ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}.binVendor
5ish_${intel_plat_gen}.bin기본 Intel platform firmware

경로는 모두 `intel/ish/` 아래이며 첫 일치 항목을 사용합니다.

Custom firmware 선택
Platform generation과 DMI field 수집sys_vendor·product_name·product_sku CRC32 계산Vendor + name + SKU filename 검색SKU 또는 name 조합으로 순차 완화Vendor-only filename 검색모두 실패하면 기본 intel/ish/ish_${intel_plat_gen}.bin 적재

구체적인 DMI match에서 기본 image 쪽으로 완화합니다.

Vendor Custom Firmware Loading
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The firmware running inside ISH can be provided by Intel or developed by vendors using the Firmware Development Kit (FDK) provided by Intel.
Intel will upstream the Intel-built firmware to the ``linux-firmware.git`` repository, located under the path ``intel/ish/``. For the Lunar Lake platform, the Intel-built ISH firmware will be named ``ish_lnlm.bin``.
Vendors who wish to upstream their custom firmware should follow these guidelines for naming their firmware files:

- The firmware filename should use one of the following patterns:

  - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin``
  - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin``
  - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.bin``
  - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}.bin``

- ``${intel_plat_gen}`` indicates the Intel platform generation (e.g., ``lnlm`` for Lunar Lake) and must not exceed 8 characters in length.
- ``${SYS_VENDOR_CRC32}`` is the CRC32 checksum of the ``sys_vendor`` value from the DMI field ``DMI_SYS_VENDOR``.
- ``${PRODUCT_NAME_CRC32}`` is the CRC32 checksum of the ``product_name`` value from the DMI field ``DMI_PRODUCT_NAME``.
- ``${PRODUCT_SKU_CRC32}`` is the CRC32 checksum of the ``product_sku`` value from the DMI field ``DMI_PRODUCT_SKU``.

During system boot, the ISH Linux driver will attempt to load the firmware in the following order, prioritizing custom firmware with more precise matching patterns:

1. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin``
2. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin``
3. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.bin``
4. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}.bin``
5. ``intel/ish/ish_${intel_plat_gen}.bin``

The driver will load the first matching firmware and skip the rest. If no matching firmware is found, it will proceed to the next pattern in the specified order. If all searches fail, the default Intel firmware, listed last in the order above, will be loaded.

ISH event tracing

436-443

ISH debugging에는 event tracing mechanism을 사용합니다. 먼저 `echo 1 > /sys/kernel/tracing/events/intel_ish/enable`로 `intel_ish` event를 활성화한 뒤 `cat /sys/kernel/tracing/trace`로 수집된 trace를 읽습니다.

ISH tracing 명령
명령목적
echo 1 > /sys/kernel/tracing/events/intel_ish/enableIntel ISH trace event 활성화
cat /sys/kernel/tracing/trace현재 kernel trace buffer 출력

Enable node와 trace buffer를 구분합니다.

Debug trace 확인
intel_ish event enable node에 1 기록문제가 발생하는 sensor·transport 동작 재현/sys/kernel/tracing/trace 읽기IPC·ISHTP event 순서 분석

Event를 켠 뒤 재현하여 trace를 수집합니다.

ISH Debugging
-------------

To debug ISH, event tracing mechanism is used. To enable debug logs::

  echo 1 > /sys/kernel/tracing/events/intel_ish/enable
  cat /sys/kernel/tracing/trace

Lenovo ThinkPad Yoga 260 IIO sysfs 예제

444-581

Lenovo ThinkPad Yoga 260의 예제는 `tree -l /sys/bus/iio/devices/` 출력으로 ISH sensor가 IIO device와 channel attribute로 노출되는 모습을 보여 줍니다. `iio:device0`은 `../../../devices/0044:8086:22D8.0001/HID-SENSOR-200073.9.auto/iio:device0`을 가리킵니다.

각 buffered IIO device에는 보통 `buffer/enable`, `buffer/length`, `buffer/watermark`가 있습니다. `scan_elements` 아래의 `_en`, `_index`, `_type` attribute는 channel을 scan에 포함할지, buffer에서의 index가 무엇인지, binary type과 layout이 무엇인지 나타냅니다. `trigger/current_trigger`는 현재 sample trigger를 가리킵니다.

Accelerometer는 `in_accel_hysteresis`, `in_accel_offset`, `in_accel_sampling_frequency`, `in_accel_scale`과 x·y·z의 `in_accel_*_raw`를 제공합니다. Scan element에도 x·y·z 각각의 enable, index, type이 있습니다.

Intensity sensor는 `in_intensity_both_raw`와 hysteresis, offset, sampling frequency, scale을 제공합니다. 단일 `both` channel에 대응하는 scan element의 enable, index, type과 current trigger도 함께 노출됩니다.

Magnetometer device는 `in_magn_x_raw`, `in_magn_y_raw`, `in_magn_z_raw`와 공통 hysteresis, offset, sampling frequency, scale을 제공합니다. 또한 tilt-compensated magnetic north rotation 값인 `in_rot_from_north_magnetic_tilt_comp_raw`와 rotation의 hysteresis, offset, sampling frequency, scale을 함께 제공합니다. Scan element에는 세 magnetic axis와 tilt-compensated rotation channel이 모두 들어갑니다.

Angular velocity device는 `in_anglvel_x_raw`, `in_anglvel_y_raw`, `in_anglvel_z_raw` 및 hysteresis, offset, sampling frequency, scale을 제공합니다. 원문 tree에는 같은 angular-velocity 형태의 device가 두 묶음 나타나며, 두 묶음 모두 x·y·z scan enable, index, type과 current trigger 구조를 가집니다.

예제 IIO channel 그룹
SensorRaw channel공통 attributeScan 구성
Accelerometerin_accel_x_raw · y_raw · z_rawhysteresis · offset · sampling_frequency · scalex·y·z의 en/index/type
Intensityin_intensity_both_rawhysteresis · offset · sampling_frequency · scaleboth의 en/index/type
Magnetometerin_magn_x_raw · y_raw · z_rawhysteresis · offset · sampling_frequency · scalex·y·z의 en/index/type
Tilt-comp rotationin_rot_from_north_magnetic_tilt_comp_rawrot hysteresis · offset · sampling_frequency · scalerotation의 en/index/type
Angular velocityin_anglvel_x_raw · y_raw · z_rawhysteresis · offset · sampling_frequency · scalex·y·z의 en/index/type

긴 tree 출력을 sensor별 interface로 정리했습니다.

Buffered IIO sample 설정
iio:deviceN의 name과 channel attribute 확인sampling_frequency·scale·offset 설정 또는 조회scan_elements의 필요한 channel _en 활성화buffer length와 watermark 구성current_trigger 선택buffer enable 후 binary sample 수집

예제 tree에서 반복되는 attribute의 일반적인 사용 흐름입니다.

ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
-------------------------------------------------

::

  root@otcpl-ThinkPad-Yoga-260:~# tree -l /sys/bus/iio/devices/
  /sys/bus/iio/devices/
  ├── iio:device0 -> ../../../devices/0044:8086:22D8.0001/HID-SENSOR-200073.9.auto/iio:device0
  │   ├── buffer
  │   │   ├── enable
  │   │   ├── length
  │   │   └── watermark
  ...
  │   ├── in_accel_hysteresis
  │   ├── in_accel_offset
  │   ├── in_accel_sampling_frequency
  │   ├── in_accel_scale
  │   ├── in_accel_x_raw
  │   ├── in_accel_y_raw
  │   ├── in_accel_z_raw
  │   ├── name
  │   ├── scan_elements
  │   │   ├── in_accel_x_en
  │   │   ├── in_accel_x_index
  │   │   ├── in_accel_x_type
  │   │   ├── in_accel_y_en
  │   │   ├── in_accel_y_index
  │   │   ├── in_accel_y_type
  │   │   ├── in_accel_z_en
  │   │   ├── in_accel_z_index
  │   │   └── in_accel_z_type
  ...
  │   │   ├── devices
  │   │   │   │   ├── buffer
  │   │   │   │   │   ├── enable
  │   │   │   │   │   ├── length
  │   │   │   │   │   └── watermark
  │   │   │   │   ├── dev
  │   │   │   │   ├── in_intensity_both_raw
  │   │   │   │   ├── in_intensity_hysteresis
  │   │   │   │   ├── in_intensity_offset
  │   │   │   │   ├── in_intensity_sampling_frequency
  │   │   │   │   ├── in_intensity_scale
  │   │   │   │   ├── name
  │   │   │   │   ├── scan_elements
  │   │   │   │   │   ├── in_intensity_both_en
  │   │   │   │   │   ├── in_intensity_both_index
  │   │   │   │   │   └── in_intensity_both_type
  │   │   │   │   ├── trigger
  │   │   │   │   │   └── current_trigger
  ...
  │   │   │   │   ├── buffer
  │   │   │   │   │   ├── enable
  │   │   │   │   │   ├── length
  │   │   │   │   │   └── watermark
  │   │   │   │   ├── dev
  │   │   │   │   ├── in_magn_hysteresis
  │   │   │   │   ├── in_magn_offset
  │   │   │   │   ├── in_magn_sampling_frequency
  │   │   │   │   ├── in_magn_scale
  │   │   │   │   ├── in_magn_x_raw
  │   │   │   │   ├── in_magn_y_raw
  │   │   │   │   ├── in_magn_z_raw
  │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_raw
  │   │   │   │   ├── in_rot_hysteresis
  │   │   │   │   ├── in_rot_offset
  │   │   │   │   ├── in_rot_sampling_frequency
  │   │   │   │   ├── in_rot_scale
  │   │   │   │   ├── name
  ...
  │   │   │   │   ├── scan_elements
  │   │   │   │   │   ├── in_magn_x_en
  │   │   │   │   │   ├── in_magn_x_index
  │   │   │   │   │   ├── in_magn_x_type
  │   │   │   │   │   ├── in_magn_y_en
  │   │   │   │   │   ├── in_magn_y_index
  │   │   │   │   │   ├── in_magn_y_type
  │   │   │   │   │   ├── in_magn_z_en
  │   │   │   │   │   ├── in_magn_z_index
  │   │   │   │   │   ├── in_magn_z_type
  │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_en
  │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_index
  │   │   │   │   │   └── in_rot_from_north_magnetic_tilt_comp_type
  │   │   │   │   ├── trigger
  │   │   │   │   │   └── current_trigger
  ...
  │   │   │   │   ├── buffer
  │   │   │   │   │   ├── enable
  │   │   │   │   │   ├── length
  │   │   │   │   │   └── watermark
  │   │   │   │   ├── dev
  │   │   │   │   ├── in_anglvel_hysteresis
  │   │   │   │   ├── in_anglvel_offset
  │   │   │   │   ├── in_anglvel_sampling_frequency
  │   │   │   │   ├── in_anglvel_scale
  │   │   │   │   ├── in_anglvel_x_raw
  │   │   │   │   ├── in_anglvel_y_raw
  │   │   │   │   ├── in_anglvel_z_raw
  │   │   │   │   ├── name
  │   │   │   │   ├── scan_elements
  │   │   │   │   │   ├── in_anglvel_x_en
  │   │   │   │   │   ├── in_anglvel_x_index
  │   │   │   │   │   ├── in_anglvel_x_type
  │   │   │   │   │   ├── in_anglvel_y_en
  │   │   │   │   │   ├── in_anglvel_y_index
  │   │   │   │   │   ├── in_anglvel_y_type
  │   │   │   │   │   ├── in_anglvel_z_en
  │   │   │   │   │   ├── in_anglvel_z_index
  │   │   │   │   │   └── in_anglvel_z_type
  │   │   │   │   ├── trigger
  │   │   │   │   │   └── current_trigger
  ...
  │   │   │   │   ├── buffer
  │   │   │   │   │   ├── enable
  │   │   │   │   │   ├── length
  │   │   │   │   │   └── watermark
  │   │   │   │   ├── dev
  │   │   │   │   ├── in_anglvel_hysteresis
  │   │   │   │   ├── in_anglvel_offset
  │   │   │   │   ├── in_anglvel_sampling_frequency
  │   │   │   │   ├── in_anglvel_scale
  │   │   │   │   ├── in_anglvel_x_raw
  │   │   │   │   ├── in_anglvel_y_raw
  │   │   │   │   ├── in_anglvel_z_raw
  │   │   │   │   ├── name
  │   │   │   │   ├── scan_elements
  │   │   │   │   │   ├── in_anglvel_x_en
  │   │   │   │   │   ├── in_anglvel_x_index
  │   │   │   │   │   ├── in_anglvel_x_type
  │   │   │   │   │   ├── in_anglvel_y_en
  │   │   │   │   │   ├── in_anglvel_y_index
  │   │   │   │   │   ├── in_anglvel_y_type
  │   │   │   │   │   ├── in_anglvel_z_en
  │   │   │   │   │   ├── in_anglvel_z_index
  │   │   │   │   │   └── in_anglvel_z_type
  │   │   │   │   ├── trigger
  │   │   │   │   │   └── current_trigger
  ...