xref: /OK3568_Linux_fs/kernel/Documentation/admin-guide/gpio/gpio-aggregator.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun
3*4882a593SmuzhiyunGPIO Aggregator
4*4882a593Smuzhiyun===============
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunThe GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as
7*4882a593Smuzhiyuna new gpio_chip.  This supports the following use cases.
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun
10*4882a593SmuzhiyunAggregating GPIOs using Sysfs
11*4882a593Smuzhiyun-----------------------------
12*4882a593Smuzhiyun
13*4882a593SmuzhiyunGPIO controllers are exported to userspace using /dev/gpiochip* character
14*4882a593Smuzhiyundevices.  Access control to these devices is provided by standard UNIX file
15*4882a593Smuzhiyunsystem permissions, on an all-or-nothing basis: either a GPIO controller is
16*4882a593Smuzhiyunaccessible for a user, or it is not.
17*4882a593Smuzhiyun
18*4882a593SmuzhiyunThe GPIO Aggregator provides access control for a set of one or more GPIOs, by
19*4882a593Smuzhiyunaggregating them into a new gpio_chip, which can be assigned to a group or user
20*4882a593Smuzhiyunusing standard UNIX file ownership and permissions.  Furthermore, this
21*4882a593Smuzhiyunsimplifies and hardens exporting GPIOs to a virtual machine, as the VM can just
22*4882a593Smuzhiyungrab the full GPIO controller, and no longer needs to care about which GPIOs to
23*4882a593Smuzhiyungrab and which not, reducing the attack surface.
24*4882a593Smuzhiyun
25*4882a593SmuzhiyunAggregated GPIO controllers are instantiated and destroyed by writing to
26*4882a593Smuzhiyunwrite-only attribute files in sysfs.
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun    /sys/bus/platform/drivers/gpio-aggregator/
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun	"new_device" ...
31*4882a593Smuzhiyun		Userspace may ask the kernel to instantiate an aggregated GPIO
32*4882a593Smuzhiyun		controller by writing a string describing the GPIOs to
33*4882a593Smuzhiyun		aggregate to the "new_device" file, using the format
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun		.. code-block:: none
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun		    [<gpioA>] [<gpiochipB> <offsets>] ...
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun		Where:
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun		    "<gpioA>" ...
42*4882a593Smuzhiyun			    is a GPIO line name,
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun		    "<gpiochipB>" ...
45*4882a593Smuzhiyun			    is a GPIO chip label, and
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun		    "<offsets>" ...
48*4882a593Smuzhiyun			    is a comma-separated list of GPIO offsets and/or
49*4882a593Smuzhiyun			    GPIO offset ranges denoted by dashes.
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun		Example: Instantiate a new GPIO aggregator by aggregating GPIO
52*4882a593Smuzhiyun		line 19 of "e6052000.gpio" and GPIO lines 20-21 of
53*4882a593Smuzhiyun		"e6050000.gpio" into a new gpio_chip:
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun		.. code-block:: sh
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun		    $ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun	"delete_device" ...
60*4882a593Smuzhiyun		Userspace may ask the kernel to destroy an aggregated GPIO
61*4882a593Smuzhiyun		controller after use by writing its device name to the
62*4882a593Smuzhiyun		"delete_device" file.
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun		Example: Destroy the previously-created aggregated GPIO
65*4882a593Smuzhiyun		controller, assumed to be "gpio-aggregator.0":
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun		.. code-block:: sh
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun		    $ echo gpio-aggregator.0 > delete_device
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun
72*4882a593SmuzhiyunGeneric GPIO Driver
73*4882a593Smuzhiyun-------------------
74*4882a593Smuzhiyun
75*4882a593SmuzhiyunThe GPIO Aggregator can also be used as a generic driver for a simple
76*4882a593SmuzhiyunGPIO-operated device described in DT, without a dedicated in-kernel driver.
77*4882a593SmuzhiyunThis is useful in industrial control, and is not unlike e.g. spidev, which
78*4882a593Smuzhiyunallows the user to communicate with an SPI device from userspace.
79*4882a593Smuzhiyun
80*4882a593SmuzhiyunBinding a device to the GPIO Aggregator is performed either by modifying the
81*4882a593Smuzhiyungpio-aggregator driver, or by writing to the "driver_override" file in Sysfs.
82*4882a593Smuzhiyun
83*4882a593SmuzhiyunExample: If "door" is a GPIO-operated device described in DT, using its own
84*4882a593Smuzhiyuncompatible value::
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun	door {
87*4882a593Smuzhiyun		compatible = "myvendor,mydoor";
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun		gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>,
90*4882a593Smuzhiyun			<&gpio2 20 GPIO_ACTIVE_LOW>;
91*4882a593Smuzhiyun		gpio-line-names = "open", "lock";
92*4882a593Smuzhiyun	};
93*4882a593Smuzhiyun
94*4882a593Smuzhiyunit can be bound to the GPIO Aggregator by either:
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun1. Adding its compatible value to ``gpio_aggregator_dt_ids[]``,
97*4882a593Smuzhiyun2. Binding manually using "driver_override":
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun.. code-block:: sh
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun    $ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override
102*4882a593Smuzhiyun    $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind
103*4882a593Smuzhiyun
104*4882a593SmuzhiyunAfter that, a new gpiochip "door" has been created:
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun.. code-block:: sh
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun    $ gpioinfo door
109*4882a593Smuzhiyun    gpiochip12 - 2 lines:
110*4882a593Smuzhiyun	    line   0:       "open"       unused   input  active-high
111*4882a593Smuzhiyun	    line   1:       "lock"       unused   input  active-high
112