|  | .. SPDX-License-Identifier: GPL-2.0-only | 
|  |  | 
|  | GPIO Aggregator | 
|  | =============== | 
|  |  | 
|  | The GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as | 
|  | a new gpio_chip.  This supports the following use cases. | 
|  |  | 
|  |  | 
|  | Aggregating GPIOs using Sysfs | 
|  | ----------------------------- | 
|  |  | 
|  | GPIO controllers are exported to userspace using /dev/gpiochip* character | 
|  | devices.  Access control to these devices is provided by standard UNIX file | 
|  | system permissions, on an all-or-nothing basis: either a GPIO controller is | 
|  | accessible for a user, or it is not. | 
|  |  | 
|  | The GPIO Aggregator provides access control for a set of one or more GPIOs, by | 
|  | aggregating them into a new gpio_chip, which can be assigned to a group or user | 
|  | using standard UNIX file ownership and permissions.  Furthermore, this | 
|  | simplifies and hardens exporting GPIOs to a virtual machine, as the VM can just | 
|  | grab the full GPIO controller, and no longer needs to care about which GPIOs to | 
|  | grab and which not, reducing the attack surface. | 
|  |  | 
|  | Aggregated GPIO controllers are instantiated and destroyed by writing to | 
|  | write-only attribute files in sysfs. | 
|  |  | 
|  | /sys/bus/platform/drivers/gpio-aggregator/ | 
|  |  | 
|  | "new_device" ... | 
|  | Userspace may ask the kernel to instantiate an aggregated GPIO | 
|  | controller by writing a string describing the GPIOs to | 
|  | aggregate to the "new_device" file, using the format | 
|  |  | 
|  | .. code-block:: none | 
|  |  | 
|  | [<gpioA>] [<gpiochipB> <offsets>] ... | 
|  |  | 
|  | Where: | 
|  |  | 
|  | "<gpioA>" ... | 
|  | is a GPIO line name, | 
|  |  | 
|  | "<gpiochipB>" ... | 
|  | is a GPIO chip label, and | 
|  |  | 
|  | "<offsets>" ... | 
|  | is a comma-separated list of GPIO offsets and/or | 
|  | GPIO offset ranges denoted by dashes. | 
|  |  | 
|  | Example: Instantiate a new GPIO aggregator by aggregating GPIO | 
|  | line 19 of "e6052000.gpio" and GPIO lines 20-21 of | 
|  | "e6050000.gpio" into a new gpio_chip: | 
|  |  | 
|  | .. code-block:: sh | 
|  |  | 
|  | $ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device | 
|  |  | 
|  | "delete_device" ... | 
|  | Userspace may ask the kernel to destroy an aggregated GPIO | 
|  | controller after use by writing its device name to the | 
|  | "delete_device" file. | 
|  |  | 
|  | Example: Destroy the previously-created aggregated GPIO | 
|  | controller, assumed to be "gpio-aggregator.0": | 
|  |  | 
|  | .. code-block:: sh | 
|  |  | 
|  | $ echo gpio-aggregator.0 > delete_device | 
|  |  | 
|  |  | 
|  | Generic GPIO Driver | 
|  | ------------------- | 
|  |  | 
|  | The GPIO Aggregator can also be used as a generic driver for a simple | 
|  | GPIO-operated device described in DT, without a dedicated in-kernel driver. | 
|  | This is useful in industrial control, and is not unlike e.g. spidev, which | 
|  | allows the user to communicate with an SPI device from userspace. | 
|  |  | 
|  | Binding a device to the GPIO Aggregator is performed either by modifying the | 
|  | gpio-aggregator driver, or by writing to the "driver_override" file in Sysfs. | 
|  |  | 
|  | Example: If "door" is a GPIO-operated device described in DT, using its own | 
|  | compatible value:: | 
|  |  | 
|  | door { | 
|  | compatible = "myvendor,mydoor"; | 
|  |  | 
|  | gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>, | 
|  | <&gpio2 20 GPIO_ACTIVE_LOW>; | 
|  | gpio-line-names = "open", "lock"; | 
|  | }; | 
|  |  | 
|  | it can be bound to the GPIO Aggregator by either: | 
|  |  | 
|  | 1. Adding its compatible value to ``gpio_aggregator_dt_ids[]``, | 
|  | 2. Binding manually using "driver_override": | 
|  |  | 
|  | .. code-block:: sh | 
|  |  | 
|  | $ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override | 
|  | $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind | 
|  |  | 
|  | After that, a new gpiochip "door" has been created: | 
|  |  | 
|  | .. code-block:: sh | 
|  |  | 
|  | $ gpioinfo door | 
|  | gpiochip12 - 2 lines: | 
|  | line   0:       "open"       unused   input  active-high | 
|  | line   1:       "lock"       unused   input  active-high |