gpio: document open drain/source behaviour
This has been a totally undocumented feature for years so add some generic concepts and documentation about open drain/source, include some facts on how we now support for hardware. Cc: Michael Hennerich <michael.hennerich@analog.com> Cc: Nicolas Saenz Julienne <nicolassaenzj@gmail.com> Cc: H. Nikolaus Schaller <hns@goldelico.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
a0e637387a
commit
6b5029d3ec
|
@ -68,6 +68,95 @@ control callbacks) if it is expected to call GPIO APIs from atomic context
|
|||
on -RT (inside hard IRQ handlers and similar contexts). Normally this should
|
||||
not be required.
|
||||
|
||||
|
||||
GPIOs with open drain/source support
|
||||
------------------------------------
|
||||
|
||||
Open drain (CMOS) or open collector (TTL) means the line is not actively driven
|
||||
high: instead you provide the drain/collector as output, so when the transistor
|
||||
is not open, it will present a high-impedance (tristate) to the external rail.
|
||||
|
||||
|
||||
CMOS CONFIGURATION TTL CONFIGURATION
|
||||
|
||||
||--- out +--- out
|
||||
in ----|| |/
|
||||
||--+ in ----|
|
||||
| |\
|
||||
GND GND
|
||||
|
||||
This configuration is normally used as a way to achieve one of two things:
|
||||
|
||||
- Level-shifting: to reach a logical level higher than that of the silicon
|
||||
where the output resides.
|
||||
|
||||
- inverse wire-OR on an I/O line, for example a GPIO line, making it possible
|
||||
for any driving stage on the line to drive it low even if any other output
|
||||
to the same line is simultaneously driving it high. A special case of this
|
||||
is driving the SCL and SCA lines of an I2C bus, which is by definition a
|
||||
wire-OR bus.
|
||||
|
||||
Both usecases require that the line be equipped with a pull-up resistor. This
|
||||
resistor will make the line tend to high level unless one of the transistors on
|
||||
the rail actively pulls it down.
|
||||
|
||||
Integrated electronics often have an output driver stage in the form of a CMOS
|
||||
"totem-pole" with one N-MOS and one P-MOS transistor where one of them drives
|
||||
the line high and one of them drives the line low. This is called a push-pull
|
||||
output. The "totem-pole" looks like so:
|
||||
|
||||
VDD
|
||||
|
|
||||
OD ||--+
|
||||
+--/ ---o|| P-MOS-FET
|
||||
| ||--+
|
||||
in --+ +----- out
|
||||
| ||--+
|
||||
+--/ ----|| N-MOS-FET
|
||||
OS ||--+
|
||||
|
|
||||
GND
|
||||
|
||||
You see the little "switches" named "OD" and "OS" that enable/disable the
|
||||
P-MOS or N-MOS transistor right after the split of the input. As you can see,
|
||||
either transistor will go totally numb if this switch is open. The totem-pole
|
||||
is then halved and give high impedance instead of actively driving the line
|
||||
high or low respectively. That is usually how software-controlled open
|
||||
drain/source works.
|
||||
|
||||
Some GPIO hardware come in open drain / open source configuration. Some are
|
||||
hard-wired lines that will only support open drain or open source no matter
|
||||
what: there is only one transistor there. Some are software-configurable:
|
||||
by flipping a bit in a register the output can be configured as open drain
|
||||
or open source, by flicking open the switches labeled "OD" and "OS" in the
|
||||
drawing above.
|
||||
|
||||
By disabling the P-MOS transistor, the output can be driven between GND and
|
||||
high impedance (open drain), and by disabling the N-MOS transistor, the output
|
||||
can be driven between VDD and high impedance (open source). In the first case,
|
||||
a pull-up resistor is needed on the outgoing rail to complete the circuit, and
|
||||
in the second case, a pull-down resistor is needed on the rail.
|
||||
|
||||
Hardware that supports open drain or open source or both, can implement a
|
||||
special callback in the gpio_chip: .set_single_ended() that takes an enum flag
|
||||
telling whether to configure the line as open drain, open source or push-pull.
|
||||
This will happen in response to the GPIO_OPEN_DRAIN or GPIO_OPEN_SOURCE flag
|
||||
set in the machine file, or coming from other hardware descriptions.
|
||||
|
||||
If this state can not be configured in hardware, i.e. if the GPIO hardware does
|
||||
not support open drain/open source in hardware, the GPIO library will instead
|
||||
use a trick: when a line is set as output, if the line is flagged as open
|
||||
drain, and the output value is negative, it will be driven low as usual. But
|
||||
if the output value is set to positive, it will instead *NOT* be driven high,
|
||||
instead it will be switched to input, as input mode is high impedance, thus
|
||||
achieveing an "open drain emulation" of sorts: electrically the behaviour will
|
||||
be identical, with the exception of possible hardware glitches when switching
|
||||
the mode of the line.
|
||||
|
||||
For open source configuration the same principle is used, just that instead
|
||||
of actively driving the line low, it is set to input.
|
||||
|
||||
|
||||
GPIO drivers providing IRQs
|
||||
---------------------------
|
||||
It is custom that GPIO drivers (GPIO chips) are also providing interrupts,
|
||||
|
|
Loading…
Reference in a new issue