178 lines · plain
1.. SPDX-License-Identifier: GPL-2.0-only2 3Virtual GPIO Consumer4=====================5 6The virtual GPIO Consumer module allows users to instantiate virtual devices7that request GPIOs and then control their behavior over debugfs. Virtual8consumer devices can be instantiated from device-tree or over configfs.9 10A virtual consumer uses the driver-facing GPIO APIs and allows to cover it with11automated tests driven by user-space. The GPIOs are requested using12``gpiod_get_array()`` and so we support multiple GPIOs per connector ID.13 14Creating GPIO consumers15-----------------------16 17The gpio-consumer module registers a configfs subsystem called18``'gpio-virtuser'``. For details of the configfs filesystem, please refer to19the configfs documentation.20 21The user can create a hierarchy of configfs groups and items as well as modify22values of exposed attributes. Once the consumer is instantiated, this hierarchy23will be translated to appropriate device properties. The general structure is:24 25**Group:** ``/config/gpio-virtuser``26 27This is the top directory of the gpio-consumer configfs tree.28 29**Group:** ``/config/gpio-consumer/example-name``30 31**Attribute:** ``/config/gpio-consumer/example-name/live``32 33**Attribute:** ``/config/gpio-consumer/example-name/dev_name``34 35This is a directory representing a GPIO consumer device.36 37The read-only ``dev_name`` attribute exposes the name of the device as it will38appear in the system on the platform bus. This is useful for locating the39associated debugfs directory under40``/sys/kernel/debug/gpio-virtuser/$dev_name``.41 42The ``'live'`` attribute allows to trigger the actual creation of the device43once it's fully configured. The accepted values are: ``'1'`` to enable the44virtual device and ``'0'`` to disable and tear it down.45 46Creating GPIO lookup tables47---------------------------48 49Users can create a number of configfs groups under the device group:50 51**Group:** ``/config/gpio-consumer/example-name/con_id``52 53The ``'con_id'`` directory represents a single GPIO lookup and its value maps54to the ``'con_id'`` argument of the ``gpiod_get()`` function. For example:55``con_id`` == ``'reset'`` maps to the ``reset-gpios`` device property.56 57Users can assign a number of GPIOs to each lookup. Each GPIO is a sub-directory58with a user-defined name under the ``'con_id'`` group.59 60**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/key``61 62**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/offset``63 64**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/drive``65 66**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/pull``67 68**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/active_low``69 70**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/transitory``71 72This is a group describing a single GPIO in the ``con_id-gpios`` property.73 74For virtual consumers created using configfs we use machine lookup tables so75this group can be considered as a mapping between the filesystem and the fields76of a single entry in ``'struct gpiod_lookup'``.77 78The ``'key'`` attribute represents either the name of the chip this GPIO79belongs to or the GPIO line name. This depends on the value of the ``'offset'``80attribute: if its value is >= 0, then ``'key'`` represents the label of the81chip to lookup while ``'offset'`` represents the offset of the line in that82chip. If ``'offset'`` is < 0, then ``'key'`` represents the name of the line.83 84The remaining attributes map to the ``'flags'`` field of the GPIO lookup85struct. The first two take string values as arguments:86 87**``'drive'``:** ``'push-pull'``, ``'open-drain'``, ``'open-source'``88**``'pull'``:** ``'pull-up'``, ``'pull-down'``, ``'pull-disabled'``, ``'as-is'``89 90``'active_low'`` and ``'transitory'`` are boolean attributes.91 92Activating GPIO consumers93-------------------------94 95Once the confiuration is complete, the ``'live'`` attribute must be set to 1 in96order to instantiate the consumer. It can be set back to 0 to destroy the97virtual device. The module will synchronously wait for the new simulated device98to be successfully probed and if this doesn't happen, writing to ``'live'`` will99result in an error.100 101Device-tree102-----------103 104Virtual GPIO consumers can also be defined in device-tree. The compatible string105must be: ``"gpio-virtuser"`` with at least one property following the106standardized GPIO pattern.107 108An example device-tree code defining a virtual GPIO consumer:109 110.. code-block :: none111 112 gpio-virt-consumer {113 compatible = "gpio-virtuser";114 115 foo-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>, <&gpio1 2 0>;116 bar-gpios = <&gpio0 6 0>;117 };118 119Controlling virtual GPIO consumers120----------------------------------121 122Once active, the device will export debugfs attributes for controlling GPIO123arrays as well as each requested GPIO line separately. Let's consider the124following device property: ``foo-gpios = <&gpio0 0 0>, <&gpio0 4 0>;``.125 126The following debugfs attribute groups will be created:127 128**Group:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/``129 130This is the group that will contain the attributes for the entire GPIO array.131 132**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values``133 134**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values_atomic``135 136Both attributes allow to read and set arrays of GPIO values. User must pass137exactly the number of values that the array contains in the form of a string138containing zeroes and ones representing inactive and active GPIO states139respectively. In this example: ``echo 11 > values``.140 141The ``values_atomic`` attribute works the same as ``values`` but the kernel142will execute the GPIO driver callbacks in interrupt context.143 144**Group:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/``145 146This is a group that represents a single GPIO with ``$index`` being its offset147in the array.148 149**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/consumer``150 151Allows to set and read the consumer label of the GPIO line.152 153**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/debounce``154 155Allows to set and read the debounce period of the GPIO line.156 157**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/direction``158 159**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/direction_atomic``160 161These two attributes allow to set the direction of the GPIO line. They accept162"input" and "output" as values. The atomic variant executes the driver callback163in interrupt context.164 165**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/interrupts``166 167If the line is requested in input mode, writing ``1`` to this attribute will168make the module listen for edge interrupts on the GPIO. Writing ``0`` disables169the monitoring. Reading this attribute returns the current number of registered170interrupts (both edges).171 172**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/value``173 174**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/value_atomic``175 176Both attributes allow to read and set values of individual requested GPIO lines.177They accept the following values: ``1`` and ``0``.178