요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
Device Tree와 debugfs 제어
gpio-virtuser.rst:101-177`gpio-virtuser` compatible 예와 values, direction, interrupt, debounce 등 시험용 debugfs interface를 설명합니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0-only
Virtual GPIO Consumer
=====================
The virtual GPIO Consumer module allows users to instantiate virtual devices
that request GPIOs and then control their behavior over debugfs. Virtual
consumer devices can be instantiated from device-tree or over configfs.
A virtual consumer uses the driver-facing GPIO APIs and allows to cover it with
automated tests driven by user-space. The GPIOs are requested using
``gpiod_get_array()`` and so we support multiple GPIOs per connector ID.
Creating GPIO consumers
-----------------------
The gpio-consumer module registers a configfs subsystem called
``'gpio-virtuser'``. For details of the configfs filesystem, please refer to
the configfs documentation.
The user can create a hierarchy of configfs groups and items as well as modify
values of exposed attributes. Once the consumer is instantiated, this hierarchy
will be translated to appropriate device properties. The general structure is:
**Group:** ``/config/gpio-virtuser``
This is the top directory of the gpio-consumer configfs tree.
**Group:** ``/config/gpio-consumer/example-name``
**Attribute:** ``/config/gpio-consumer/example-name/live``
**Attribute:** ``/config/gpio-consumer/example-name/dev_name``
This is a directory representing a GPIO consumer device.
The read-only ``dev_name`` attribute exposes the name of the device as it will
appear in the system on the platform bus. This is useful for locating the
associated debugfs directory under
``/sys/kernel/debug/gpio-virtuser/$dev_name``.
The ``'live'`` attribute allows to trigger the actual creation of the device
once it's fully configured. The accepted values are: ``'1'`` to enable the
virtual device and ``'0'`` to disable and tear it down.
Creating GPIO lookup tables
---------------------------
Users can create a number of configfs groups under the device group:
**Group:** ``/config/gpio-consumer/example-name/con_id``
The ``'con_id'`` directory represents a single GPIO lookup and its value maps
to the ``'con_id'`` argument of the ``gpiod_get()`` function. For example:
``con_id`` == ``'reset'`` maps to the ``reset-gpios`` device property.
Users can assign a number of GPIOs to each lookup. Each GPIO is a sub-directory
with a user-defined name under the ``'con_id'`` group.
**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/key``
**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/offset``
**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/drive``
**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/pull``
**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/active_low``
**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/transitory``
This is a group describing a single GPIO in the ``con_id-gpios`` property.
For virtual consumers created using configfs we use machine lookup tables so
this group can be considered as a mapping between the filesystem and the fields
of a single entry in ``'struct gpiod_lookup'``.
The ``'key'`` attribute represents either the name of the chip this GPIO
belongs to or the GPIO line name. This depends on the value of the ``'offset'``
attribute: if its value is >= 0, then ``'key'`` represents the label of the
chip to lookup while ``'offset'`` represents the offset of the line in that
chip. If ``'offset'`` is < 0, then ``'key'`` represents the name of the line.
The remaining attributes map to the ``'flags'`` field of the GPIO lookup
struct. The first two take string values as arguments:
**``'drive'``:** ``'push-pull'``, ``'open-drain'``, ``'open-source'``
**``'pull'``:** ``'pull-up'``, ``'pull-down'``, ``'pull-disabled'``, ``'as-is'``
``'active_low'`` and ``'transitory'`` are boolean attributes.
Activating GPIO consumers
-------------------------
Once the configuration is complete, the ``'live'`` attribute must be set to 1 in
order to instantiate the consumer. It can be set back to 0 to destroy the
virtual device. The module will synchronously wait for the new simulated device
to be successfully probed and if this doesn't happen, writing to ``'live'`` will
result in an error.
Device-tree
-----------
Virtual GPIO consumers can also be defined in device-tree. The compatible string
must be: ``"gpio-virtuser"`` with at least one property following the
standardized GPIO pattern.
An example device-tree code defining a virtual GPIO consumer:
.. code-block :: none
gpio-virt-consumer {
compatible = "gpio-virtuser";
foo-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>, <&gpio1 2 0>;
bar-gpios = <&gpio0 6 0>;
};
Controlling virtual GPIO consumers
----------------------------------
Once active, the device will export debugfs attributes for controlling GPIO
arrays as well as each requested GPIO line separately. Let's consider the
following device property: ``foo-gpios = <&gpio0 0 0>, <&gpio0 4 0>;``.
The following debugfs attribute groups will be created:
**Group:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/``
This is the group that will contain the attributes for the entire GPIO array.
**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values``
**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values_atomic``
Both attributes allow to read and set arrays of GPIO values. User must pass
exactly the number of values that the array contains in the form of a string
containing zeroes and ones representing inactive and active GPIO states
respectively. In this example: ``echo 11 > values``.
The ``values_atomic`` attribute works the same as ``values`` but the kernel
will execute the GPIO driver callbacks in interrupt context.
**Group:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/``
This is a group that represents a single GPIO with ``$index`` being its offset
in the array.
**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/consumer``
Allows to set and read the consumer label of the GPIO line.
**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/debounce``
Allows to set and read the debounce period of the GPIO line.
**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/direction``
**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/direction_atomic``
These two attributes allow to set the direction of the GPIO line. They accept
"input" and "output" as values. The atomic variant executes the driver callback
in interrupt context.
**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/interrupts``
If the line is requested in input mode, writing ``1`` to this attribute will
make the module listen for edge interrupts on the GPIO. Writing ``0`` disables
the monitoring. Reading this attribute returns the current number of registered
interrupts (both edges).
**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/value``
**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/value_atomic``
Both attributes allow to read and set values of individual requested GPIO lines.
They accept the following values: ``1`` and ``0``.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Virtual GPIO Consumer 개요
1-13Virtual GPIO Consumer 모듈은 GPIO를 요청하는 가상 장치를 만들고 debugfs에서 그 동작을 제어하게 합니다. 가상 consumer device는 device tree 또는 configfs로 만들 수 있습니다.
가상 consumer는 드라이버용 GPIO API를 사용하므로 사용자 공간이 구동하는 자동 시험으로 해당 API를 검증할 수 있습니다. GPIO는 `gpiod_get_array()`로 요청하므로 connector ID 하나에 GPIO 여러 개를 지원합니다.
Configfs에서 GPIO consumer 만들기
14-45`gpio-consumer` 모듈은 `gpio-virtuser`라는 configfs subsystem을 등록합니다. 사용자는 configfs group과 item 계층을 만들고 공개 attribute를 수정합니다. consumer가 만들어지면 이 계층은 알맞은 device property로 변환됩니다.
| 원문 configfs 경로 | 설명 |
|---|---|
| /config/gpio-virtuser | gpio-consumer configfs tree의 최상위 디렉터리입니다. |
| /config/gpio-consumer/example-name | GPIO consumer device를 나타내는 디렉터리입니다. 원문의 root와 device 경로 표기를 그대로 보존했습니다. |
| /config/gpio-consumer/example-name/live | 구성이 끝난 가상 장치를 만듭니다. 1은 활성화하고 0은 비활성화하며 제거합니다. |
| /config/gpio-consumer/example-name/dev_name | 읽기 전용. platform bus에 나타날 device name을 보여 줍니다. |
`dev_name`은 연관된 debugfs 디렉터리 `/sys/kernel/debug/gpio-virtuser/$dev_name`을 찾는 데 유용합니다.
GPIO lookup table 구성
46-91device group 아래에 configfs group을 여러 개 만들 수 있습니다. `/config/gpio-consumer/example-name/con_id`는 GPIO lookup 하나를 나타내며 디렉터리 값은 `gpiod_get()` 함수의 `con_id` 인자에 대응합니다. 예를 들어 `con_id`가 `reset`이면 `reset-gpios` device property에 대응합니다.
각 lookup에는 GPIO 여러 개를 지정할 수 있습니다. 각 GPIO는 `con_id` group 아래에서 사용자가 이름을 정한 하위 디렉터리입니다. configfs로 만든 가상 consumer는 machine lookup table을 사용하므로 이 group은 파일시스템 항목과 `struct gpiod_lookup` 한 항목의 필드 사이 매핑으로 볼 수 있습니다.
| attribute | 의미 |
|---|---|
| key | GPIO가 속한 chip name 또는 GPIO line name입니다. `offset >= 0`이면 chip label이고 `offset`은 chip 안의 line offset입니다. `offset < 0`이면 `key`는 line name입니다. |
| offset | `key`를 chip label로 해석할지 line name으로 해석할지 결정하고 chip 내부 line offset을 지정합니다. |
| drive | `struct gpiod_lookup.flags`에 대응하며 `push-pull`, `open-drain`, `open-source` 중 하나입니다. |
| pull | `struct gpiod_lookup.flags`에 대응하며 `pull-up`, `pull-down`, `pull-disabled`, `as-is` 중 하나입니다. |
| active_low | `flags` 필드에 대응하는 boolean attribute입니다. |
| transitory | `flags` 필드에 대응하는 boolean attribute입니다. |
원문 attribute 경로는 `/config/gpio-consumer/example-name/con_id/0/key`, `offset`, `drive`, `pull`, `active_low`, `transitory`입니다.
GPIO consumer 활성화
92-100구성이 끝나면 `live`를 1로 설정해 consumer를 만들고 0으로 되돌려 가상 장치를 제거합니다. 모듈은 새 가상 장치 probe가 성공할 때까지 동기적으로 기다리며 성공하지 않으면 `live` 쓰기가 오류를 반환합니다.
Device Tree 정의
101-118가상 GPIO consumer는 device tree에서도 정의할 수 있습니다. compatible 문자열은 `gpio-virtuser`여야 하고 표준 GPIO 패턴을 따르는 property가 하나 이상 있어야 합니다.
gpio-virt-consumer {
compatible = "gpio-virtuser";
foo-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>, <&gpio1 2 0>;
bar-gpios = <&gpio0 6 0>;
};
debugfs에서 가상 GPIO consumer 제어
119-177장치가 활성화되면 요청한 GPIO array 전체와 각 GPIO line을 따로 제어할 debugfs attribute가 생깁니다. 예시는 `foo-gpios = <&gpio0 0 0>, <&gpio0 4 0>;` property를 사용합니다.
| debugfs 경로 또는 attribute | 동작 |
|---|---|
| /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/ | GPIO array 전체의 attribute를 담는 group입니다. |
| values | GPIO 값 array를 읽고 설정합니다. array 원소 수와 정확히 같은 수의 0과 1 문자열을 전달해야 하며 각각 inactive와 active 상태입니다. 예: `echo 11 > values`. |
| values_atomic | `values`와 같지만 커널이 interrupt context에서 GPIO driver callback을 실행합니다. |
| /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/ | `$index`가 array offset인 단일 GPIO group입니다. |
| consumer | GPIO line의 consumer label을 읽고 설정합니다. |
| debounce | GPIO line의 debounce period를 읽고 설정합니다. |
| direction | GPIO line 방향을 `input` 또는 `output`으로 설정합니다. |
| direction_atomic | `direction`과 같지만 interrupt context에서 driver callback을 실행합니다. |
| interrupts | input mode line에서 1을 쓰면 양쪽 edge interrupt 감시를 시작하고 0은 감시를 끕니다. 읽으면 현재 등록한 interrupt의 누적 수를 반환합니다. |
| value | 요청한 개별 GPIO line 값을 1 또는 0으로 읽고 설정합니다. |
| value_atomic | 개별 GPIO line 값을 1 또는 0으로 읽고 설정하는 atomic 변형입니다. |
Consumer와 lookup 구성
gpio-virtuser.rst:1-100`gpiod_get_array()`를 사용하는 가상 consumer와 `struct gpiod_lookup`에 대응하는 configfs attribute를 정리합니다.