€•aŒŒsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ2/translations/zh_CN/admin-guide/gpio/gpio-virtuser”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/zh_TW/admin-guide/gpio/gpio-virtuser”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/it_IT/admin-guide/gpio/gpio-virtuser”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/ja_JP/admin-guide/gpio/gpio-virtuser”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/ko_KR/admin-guide/gpio/gpio-virtuser”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/pt_BR/admin-guide/gpio/gpio-virtuser”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/sp_SP/admin-guide/gpio/gpio-virtuser”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)�”}”(hŒ%SPDX-License-Identifier: GPL-2.0-only”h]”hŒ%SPDX-License-Identifier: GPL-2.0-only”…”�”}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³ŒL/var/lib/git/docbuild/linux/Documentation/admin-guide/gpio/gpio-virtuser.rst”h´KubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒVirtual GPIO Consumer”h]”hŒVirtual GPIO Consumer”…”�”}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ paragraph”“”)�”}”(hŒÝ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.”h]”hŒÝ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.”…”�”}”(hhßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhÞ)�”}”(hŒÜ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.”h]”(hŒ”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 ”…”�”}”(hhíh²hh³Nh´NubhŒliteral”“”)�”}”(hŒ``gpiod_get_array()``”h]”hŒgpiod_get_array()”…”�”}”(hh÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhhíubhŒ3 and so we support multiple GPIOs per connector ID.”…”�”}”(hhíh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hhÊh²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒCreating GPIO consumers”h]”hŒCreating GPIO consumers”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´KubhÞ)�”}”(hŒ§The gpio-consumer module registers a configfs subsystem called ``'gpio-virtuser'``. For details of the configfs filesystem, please refer to the configfs documentation.”h]”(hŒ?The gpio-consumer module registers a configfs subsystem called ”…”�”}”(hj h²hh³Nh´Nubhö)�”}”(hŒ``'gpio-virtuser'``”h]”hŒ'gpio-virtuser'”…”�”}”(hj(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj ubhŒU. For details of the configfs filesystem, please refer to the configfs documentation.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubhÞ)�”}”(hŒí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:”h]”hŒí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:”…”�”}”(hj@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubhÞ)�”}”(hŒ$**Group:** ``/config/gpio-virtuser``”h]”(hŒstrong”“”)�”}”(hŒ **Group:**”h]”hŒGroup:”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjNubhŒ ”…”�”}”(hjNh²hh³Nh´Nubhö)�”}”(hŒ``/config/gpio-virtuser``”h]”hŒ/config/gpio-virtuser”…”�”}”(hjfh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjNubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubhÞ)�”}”(hŒ=This is the top directory of the gpio-consumer configfs tree.”h]”hŒ=This is the top directory of the gpio-consumer configfs tree.”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubhÞ)�”}”(hŒ1**Group:** ``/config/gpio-consumer/example-name``”h]”(jS)�”}”(hŒ **Group:**”h]”hŒGroup:”…”�”}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjˆubhŒ ”…”�”}”(hjˆh²hh³Nh´Nubhö)�”}”(hŒ&``/config/gpio-consumer/example-name``”h]”hŒ"/config/gpio-consumer/example-name”…”�”}”(hjžh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjˆubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubhÞ)�”}”(hŒ:**Attribute:** ``/config/gpio-consumer/example-name/live``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhj²ubhŒ ”…”�”}”(hj²h²hh³Nh´Nubhö)�”}”(hŒ+``/config/gpio-consumer/example-name/live``”h]”hŒ'/config/gpio-consumer/example-name/live”…”�”}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj²ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubhÞ)�”}”(hŒ>**Attribute:** ``/config/gpio-consumer/example-name/dev_name``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjÜubhŒ ”…”�”}”(hjÜh²hh³Nh´Nubhö)�”}”(hŒ/``/config/gpio-consumer/example-name/dev_name``”h]”hŒ+/config/gpio-consumer/example-name/dev_name”…”�”}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjÜubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K!hjh²hubhÞ)�”}”(hŒ8This is a directory representing a GPIO consumer device.”h]”hŒ8This is a directory representing a GPIO consumer device.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K#hjh²hubhÞ)�”}”(hŒê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``.”h]”(hŒThe read-only ”…”�”}”(hjh²hh³Nh´Nubhö)�”}”(hŒ ``dev_name``”h]”hŒdev_name”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjubhŒ¢ 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 ”…”�”}”(hjh²hh³Nh´Nubhö)�”}”(hŒ-``/sys/kernel/debug/gpio-virtuser/$dev_name``”h]”hŒ)/sys/kernel/debug/gpio-virtuser/$dev_name”…”�”}”(hj.h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjubhŒ.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K%hjh²hubhÞ)�”}”(hŒÏ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.”h]”(hŒThe ”…”�”}”(hjFh²hh³Nh´Nubhö)�”}”(hŒ ``'live'``”h]”hŒ'live'”…”�”}”(hjNh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjFubhŒv attribute allows to trigger the actual creation of the device once it’s fully configured. The accepted values are: ”…”�”}”(hjFh²hh³Nh´Nubhö)�”}”(hŒ``'1'``”h]”hŒ'1'”…”�”}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjFubhŒ" to enable the virtual device and ”…”�”}”(hjFh²hh³Nh´Nubhö)�”}”(hŒ``'0'``”h]”hŒ'0'”…”�”}”(hjrh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjFubhŒ to disable and tear it down.”…”�”}”(hjFh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K*hjh²hubeh}”(h]”Œcreating-gpio-consumers”ah ]”h"]”Œcreating gpio consumers”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒCreating GPIO lookup tables”h]”hŒCreating GPIO lookup tables”…”�”}”(hj•h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj’h²hh³hÇh´K/ubhÞ)�”}”(hŒDUsers can create a number of configfs groups under the device group:”h]”hŒDUsers can create a number of configfs groups under the device group:”…”�”}”(hj£h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K1hj’h²hubhÞ)�”}”(hŒ8**Group:** ``/config/gpio-consumer/example-name/con_id``”h]”(jS)�”}”(hŒ **Group:**”h]”hŒGroup:”…”�”}”(hjµh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhj±ubhŒ ”…”�”}”(hj±h²hh³Nh´Nubhö)�”}”(hŒ-``/config/gpio-consumer/example-name/con_id``”h]”hŒ)/config/gpio-consumer/example-name/con_id”…”�”}”(hjÇh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj±ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K3hj’h²hubhÞ)�”}”(hŒß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.”h]”(hŒThe ”…”�”}”(hjÛh²hh³Nh´Nubhö)�”}”(hŒ ``'con_id'``”h]”hŒ'con_id'”…”�”}”(hjãh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjÛubhŒE directory represents a single GPIO lookup and its value maps to the ”…”�”}”(hjÛh²hh³Nh´Nubhö)�”}”(hŒ ``'con_id'``”h]”hŒ'con_id'”…”�”}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjÛubhŒ argument of the ”…”�”}”(hjÛh²hh³Nh´Nubhö)�”}”(hŒ``gpiod_get()``”h]”hŒ gpiod_get()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjÛubhŒ function. For example: ”…”�”}”(hjÛh²hh³Nh´Nubhö)�”}”(hŒ ``con_id``”h]”hŒcon_id”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjÛubhŒ == ”…”�”}”(hjÛh²hh³Nh´Nubhö)�”}”(hŒ ``'reset'``”h]”hŒ'reset'”…”�”}”(hj+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjÛubhŒ maps to the ”…”�”}”(hjÛh²hh³Nh´Nubhö)�”}”(hŒ``reset-gpios``”h]”hŒ reset-gpios”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjÛubhŒ device property.”…”�”}”(hjÛh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K5hj’h²hubhÞ)�”}”(hŒ†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.”h]”(hŒsUsers can assign a number of GPIOs to each lookup. Each GPIO is a sub-directory with a user-defined name under the ”…”�”}”(hjUh²hh³Nh´Nubhö)�”}”(hŒ ``'con_id'``”h]”hŒ'con_id'”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjUubhŒ group.”…”�”}”(hjUh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K9hj’h²hubhÞ)�”}”(hŒB**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/key``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hjyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjuubhŒ ”…”�”}”(hjuh²hh³Nh´Nubhö)�”}”(hŒ3``/config/gpio-consumer/example-name/con_id/0/key``”h]”hŒ//config/gpio-consumer/example-name/con_id/0/key”…”�”}”(hj‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjuubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj’h²hubhÞ)�”}”(hŒD**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/drive``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjÉubhŒ ”…”�”}”(hjÉh²hh³Nh´Nubhö)�”}”(hŒ5``/config/gpio-consumer/example-name/con_id/0/drive``”h]”hŒ1/config/gpio-consumer/example-name/con_id/0/drive”…”�”}”(hjßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjÉubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K@hj’h²hubhÞ)�”}”(hŒC**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/pull``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjóubhŒ ”…”�”}”(hjóh²hh³Nh´Nubhö)�”}”(hŒ4``/config/gpio-consumer/example-name/con_id/0/pull``”h]”hŒ0/config/gpio-consumer/example-name/con_id/0/pull”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjóubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KBhj’h²hubhÞ)�”}”(hŒI**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/active_low``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hj!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjubhŒ ”…”�”}”(hjh²hh³Nh´Nubhö)�”}”(hŒ:``/config/gpio-consumer/example-name/con_id/0/active_low``”h]”hŒ6/config/gpio-consumer/example-name/con_id/0/active_low”…”�”}”(hj3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KDhj’h²hubhÞ)�”}”(hŒI**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/transitory``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hjKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjGubhŒ ”…”�”}”(hjGh²hh³Nh´Nubhö)�”}”(hŒ:``/config/gpio-consumer/example-name/con_id/0/transitory``”h]”hŒ6/config/gpio-consumer/example-name/con_id/0/transitory”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjGubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KFhj’h²hubhÞ)�”}”(hŒJThis is a group describing a single GPIO in the ``con_id-gpios`` property.”h]”(hŒ0This is a group describing a single GPIO in the ”…”�”}”(hjqh²hh³Nh´Nubhö)�”}”(hŒ``con_id-gpios``”h]”hŒ con_id-gpios”…”�”}”(hjyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjqubhŒ property.”…”�”}”(hjqh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KHhj’h²hubhÞ)�”}”(hŒÌ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'``.”h]”(hŒ²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 ”…”�”}”(hj‘h²hh³Nh´Nubhö)�”}”(hŒ``'struct gpiod_lookup'``”h]”hŒ'struct gpiod_lookup'”…”�”}”(hj™h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj‘ubhŒ.”…”�”}”(hj‘h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KJhj’h²hubhÞ)�”}”(hX~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.”h]”(hŒThe ”…”�”}”(hj±h²hh³Nh´Nubhö)�”}”(hŒ ``'key'``”h]”hŒ'key'”…”�”}”(hj¹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj±ubhŒ attribute represents either the name of the chip this GPIO belongs to or the GPIO line name. This depends on the value of the ”…”�”}”(hj±h²hh³Nh´Nubhö)�”}”(hŒ ``'offset'``”h]”hŒ'offset'”…”�”}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj±ubhŒ' attribute: if its value is >= 0, then ”…”�”}”(hj±h²hh³Nh´Nubhö)�”}”(hŒ ``'key'``”h]”hŒ'key'”…”�”}”(hjÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj±ubhŒ2 represents the label of the chip to lookup while ”…”�”}”(hj±h²hh³Nh´Nubhö)�”}”(hŒ ``'offset'``”h]”hŒ'offset'”…”�”}”(hjïh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj±ubhŒ4 represents the offset of the line in that chip. If ”…”�”}”(hj±h²hh³Nh´Nubhö)�”}”(hŒ ``'offset'``”h]”hŒ'offset'”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj±ubhŒ is < 0, then ”…”�”}”(hj±h²hh³Nh´Nubhö)�”}”(hŒ ``'key'``”h]”hŒ'key'”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj±ubhŒ! represents the name of the line.”…”�”}”(hj±h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KNhj’h²hubhÞ)�”}”(hŒThe remaining attributes map to the ``'flags'`` field of the GPIO lookup struct. The first two take string values as arguments:”h]”(hŒ$The remaining attributes map to the ”…”�”}”(hj+h²hh³Nh´Nubhö)�”}”(hŒ ``'flags'``”h]”hŒ'flags'”…”�”}”(hj3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj+ubhŒP field of the GPIO lookup struct. The first two take string values as arguments:”…”�”}”(hj+h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KThj’h²hubhÞ)�”}”(hŒ–**``'drive'``:** ``'push-pull'``, ``'open-drain'``, ``'open-source'`` **``'pull'``:** ``'pull-up'``, ``'pull-down'``, ``'pull-disabled'``, ``'as-is'``”h]”(jS)�”}”(hŒ**``'drive'``:**”h]”hŒ``’drive’``:”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjKubhŒ ”…”�”}”(hjKh²hh³Nh´Nubhö)�”}”(hŒ``'push-pull'``”h]”hŒ 'push-pull'”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjKubhŒ, ”…”�”}”(hjKh²hh³Nh´Nubhö)�”}”(hŒ``'open-drain'``”h]”hŒ 'open-drain'”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjKubhŒ, ”…”�”}”hjKsbhö)�”}”(hŒ``'open-source'``”h]”hŒ 'open-source'”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjKubhŒ ”…”�”}”(hjKh²hh³Nh´NubjS)�”}”(hŒ**``'pull'``:**”h]”hŒ``’pull’``:”…”�”}”(hj—h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjKubhŒ ”…”�”}”hjKsbhö)�”}”(hŒ ``'pull-up'``”h]”hŒ 'pull-up'”…”�”}”(hj©h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjKubhŒ, ”…”�”}”hjKsbhö)�”}”(hŒ``'pull-down'``”h]”hŒ 'pull-down'”…”�”}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjKubhŒ, ”…”�”}”hjKsbhö)�”}”(hŒ``'pull-disabled'``”h]”hŒ'pull-disabled'”…”�”}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjKubhŒ, ”…”�”}”hjKsbhö)�”}”(hŒ ``'as-is'``”h]”hŒ'as-is'”…”�”}”(hjßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjKubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KWhj’h²hubhÞ)�”}”(hŒ=``'active_low'`` and ``'transitory'`` are boolean attributes.”h]”(hö)�”}”(hŒ``'active_low'``”h]”hŒ 'active_low'”…”�”}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjóubhŒ and ”…”�”}”(hjóh²hh³Nh´Nubhö)�”}”(hŒ``'transitory'``”h]”hŒ 'transitory'”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjóubhŒ are boolean attributes.”…”�”}”(hjóh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KZhj’h²hubeh}”(h]”Œcreating-gpio-lookup-tables”ah ]”h"]”Œcreating gpio lookup tables”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K/ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒActivating GPIO consumers”h]”hŒActivating GPIO consumers”…”�”}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj)h²hh³hÇh´K]ubhÞ)�”}”(hXOOnce 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.”h]”(hŒ(Once the configuration is complete, the ”…”�”}”(hj:h²hh³Nh´Nubhö)�”}”(hŒ ``'live'``”h]”hŒ'live'”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj:ubhŒü 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 ”…”�”}”(hj:h²hh³Nh´Nubhö)�”}”(hŒ ``'live'``”h]”hŒ'live'”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj:ubhŒ will result in an error.”…”�”}”(hj:h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K_hj)h²hubeh}”(h]”Œactivating-gpio-consumers”ah ]”h"]”Œactivating gpio consumers”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K]ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ Device-tree”h]”hŒ Device-tree”…”�”}”(hjwh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjth²hh³hÇh´KfubhÞ)�”}”(hŒ±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.”h]”(hŒZVirtual GPIO consumers can also be defined in device-tree. The compatible string must be: ”…”�”}”(hj…h²hh³Nh´Nubhö)�”}”(hŒ``"gpio-virtuser"``”h]”hŒ"gpio-virtuser"”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj…ubhŒD with at least one property following the standardized GPIO pattern.”…”�”}”(hj…h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khhjth²hubhÞ)�”}”(hŒ=An example device-tree code defining a virtual GPIO consumer:”h]”hŒ=An example device-tree code defining a virtual GPIO consumer:”…”�”}”(hj¥h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Klhjth²hubhŒ literal_block”“”)�”}”(hŒ’gpio-virt-consumer { compatible = "gpio-virtuser"; foo-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>, <&gpio1 2 0>; bar-gpios = <&gpio0 6 0>; };”h]”hŒ’gpio-virt-consumer { compatible = "gpio-virtuser"; foo-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>, <&gpio1 2 0>; bar-gpios = <&gpio0 6 0>; };”…”�”}”hjµsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆŒforce”‰Œlanguage”Œnone”Œhighlight_args”}”uh1j³h³hÇh´Knhjth²hubeh}”(h]”Œ device-tree”ah ]”h"]”Œ device-tree”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KfubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ"Controlling virtual GPIO consumers”h]”hŒ"Controlling virtual GPIO consumers”…”�”}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjÐh²hh³hÇh´KxubhÞ)�”}”(hŒÝ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>;``.”h]”(hŒ³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: ”…”�”}”(hjáh²hh³Nh´Nubhö)�”}”(hŒ+``foo-gpios = <&gpio0 0 0>, <&gpio0 4 0>;``”h]”hŒ'foo-gpios = <&gpio0 0 0>, <&gpio0 4 0>;”…”�”}”(hjéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjáubhŒ.”…”�”}”(hjáh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KzhjÐh²hubhÞ)�”}”(hŒ7The following debugfs attribute groups will be created:”h]”hŒ7The following debugfs attribute groups will be created:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K~hjÐh²hubhÞ)�”}”(hŒC**Group:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/``”h]”(jS)�”}”(hŒ **Group:**”h]”hŒGroup:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjubhŒ ”…”�”}”(hjh²hh³Nh´Nubhö)�”}”(hŒ8``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/``”h]”hŒ4/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/”…”�”}”(hj%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K€hjÐh²hubhÞ)�”}”(hŒMThis is the group that will contain the attributes for the entire GPIO array.”h]”hŒMThis is the group that will contain the attributes for the entire GPIO array.”…”�”}”(hj9h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K‚hjÐh²hubhÞ)�”}”(hŒM**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hjKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjGubhŒ ”…”�”}”(hjGh²hh³Nh´Nubhö)�”}”(hŒ>``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values``”h]”hŒ:/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjGubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K„hjÐh²hubhÞ)�”}”(hŒT**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values_atomic``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hjuh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjqubhŒ ”…”�”}”(hjqh²hh³Nh´Nubhö)�”}”(hŒE``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values_atomic``”h]”hŒA/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values_atomic”…”�”}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjqubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K†hjÐh²hubhÞ)�”}”(hXBoth 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``.”h]”(hXBoth 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: ”…”�”}”(hj›h²hh³Nh´Nubhö)�”}”(hŒ``echo 11 > values``”h]”hŒecho 11 > values”…”�”}”(hj£h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj›ubhŒ.”…”�”}”(hj›h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KˆhjÐh²hubhÞ)�”}”(hŒˆThe ``values_atomic`` attribute works the same as ``values`` but the kernel will execute the GPIO driver callbacks in interrupt context.”h]”(hŒThe ”…”�”}”(hj»h²hh³Nh´Nubhö)�”}”(hŒ``values_atomic``”h]”hŒ values_atomic”…”�”}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj»ubhŒ attribute works the same as ”…”�”}”(hj»h²hh³Nh´Nubhö)�”}”(hŒ ``values``”h]”hŒvalues”…”�”}”(hjÕh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj»ubhŒL but the kernel will execute the GPIO driver callbacks in interrupt context.”…”�”}”(hj»h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K�hjÐh²hubhÞ)�”}”(hŒJ**Group:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/``”h]”(jS)�”}”(hŒ **Group:**”h]”hŒGroup:”…”�”}”(hjñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjíubhŒ ”…”�”}”(hjíh²hh³Nh´Nubhö)�”}”(hŒ?``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/``”h]”hŒ;/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjíubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K�hjÐh²hubhÞ)�”}”(hŒ\This is a group that represents a single GPIO with ``$index`` being its offset in the array.”h]”(hŒ3This is a group that represents a single GPIO with ”…”�”}”(hjh²hh³Nh´Nubhö)�”}”(hŒ ``$index``”h]”hŒ$index”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjubhŒ being its offset in the array.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K’hjÐh²hubhÞ)�”}”(hŒV**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/consumer``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hj;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhj7ubhŒ ”…”�”}”(hj7h²hh³Nh´Nubhö)�”}”(hŒG``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/consumer``”h]”hŒC/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/consumer”…”�”}”(hjMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhj7ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K•hjÐh²hubhÞ)�”}”(hŒ;Allows to set and read the consumer label of the GPIO line.”h]”hŒ;Allows to set and read the consumer label of the GPIO line.”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K—hjÐh²hubhÞ)�”}”(hŒV**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/debounce``”h]”(jS)�”}”(hŒ**Attribute:**”h]”hŒ Attribute:”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjoubhŒ ”…”�”}”(hjoh²hh³Nh´Nubhö)�”}”(hŒG``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/debounce``”h]”hŒC/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/debounce”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hõhjoubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K™hjÐh²hubhÞ)�”}”(hŒ