Skip to content

Commit

Permalink
dt-bindings: gpio: revise drive strength flags for generality
Browse files Browse the repository at this point in the history
The documentation and design for drive strength was based on Nordic GPIO
capabilities, and presumed that the default state was standard while the
alternate state was high.

The Semtech SX15088/SX1509B GPIO extender went the other way, with
default being high and alternate being low.

Rework the flags so that low and high are distinct from default.  Update
the two in-tree GPIO implementations that currently support drive
strength to make use of these flags.

Deprecate the ALT flag but define it to implement the documented
selection (high drive) in case it's being used by out-of-tree systems.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
  • Loading branch information
pabigot committed Feb 5, 2019
1 parent c3d8936 commit c85f776
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 42 deletions.
2 changes: 1 addition & 1 deletion drivers/gpio/gpio_cc2650.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ static int gpio_cc2650_config_pin(int pin, int flags)
if (flags & GPIO_DS_DISCONNECT_LOW) {
disconnect(pin, &gpio_doe31_0_config, &iocfg_config);
}
if (flags & GPIO_DS_ALT_LOW) {
if ((flags & GPIO_DS_LOW_MASK) == GPIO_DS_HI_LOW) {
iocfg_config |= CC2650_IOC_MAX_DRIVE_STRENGTH;
} else {
iocfg_config |= CC2650_IOC_MIN_DRIVE_STRENGTH;
Expand Down
24 changes: 16 additions & 8 deletions drivers/gpio/gpio_nrfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,31 +134,39 @@ static int gpio_nrfx_config(struct device *port, int access_op,
u8_t from_pin;
u8_t to_pin;

/* Map default selections to Nordic standard (low) */
if ((flags & GPIO_DS_LOW_MASK) == GPIO_DS_DFLT_LOW) {
flags |= GPIO_DS_LO_LOW;
}
if ((flags & GPIO_DS_HIGH_MASK) == GPIO_DS_DFLT_HIGH) {
flags |= GPIO_DS_LO_HIGH;
}

switch (flags & (GPIO_DS_LOW_MASK | GPIO_DS_HIGH_MASK)) {
case GPIO_DS_DFLT_LOW | GPIO_DS_DFLT_HIGH:
case GPIO_DS_LO_LOW | GPIO_DS_LO_HIGH:
drive = NRF_GPIO_PIN_S0S1;
break;
case GPIO_DS_DFLT_LOW | GPIO_DS_ALT_HIGH:
case GPIO_DS_LO_LOW | GPIO_DS_HI_HIGH:
drive = NRF_GPIO_PIN_S0H1;
break;
case GPIO_DS_DFLT_LOW | GPIO_DS_DISCONNECT_HIGH:
case GPIO_DS_LO_LOW | GPIO_DS_DISCONNECT_HIGH:
drive = NRF_GPIO_PIN_S0D1;
break;

case GPIO_DS_ALT_LOW | GPIO_DS_DFLT_HIGH:
case GPIO_DS_HI_LOW | GPIO_DS_LO_HIGH:
drive = NRF_GPIO_PIN_H0S1;
break;
case GPIO_DS_ALT_LOW | GPIO_DS_ALT_HIGH:
case GPIO_DS_HI_LOW | GPIO_DS_HI_HIGH:
drive = NRF_GPIO_PIN_H0H1;
break;
case GPIO_DS_ALT_LOW | GPIO_DS_DISCONNECT_HIGH:
case GPIO_DS_HI_LOW | GPIO_DS_DISCONNECT_HIGH:
drive = NRF_GPIO_PIN_H0D1;
break;

case GPIO_DS_DISCONNECT_LOW | GPIO_DS_DFLT_HIGH:
case GPIO_DS_DISCONNECT_LOW | GPIO_DS_LO_HIGH:
drive = NRF_GPIO_PIN_D0S1;
break;
case GPIO_DS_DISCONNECT_LOW | GPIO_DS_ALT_HIGH:
case GPIO_DS_DISCONNECT_LOW | GPIO_DS_HI_HIGH:
drive = NRF_GPIO_PIN_D0H1;
break;

Expand Down
105 changes: 72 additions & 33 deletions include/dt-bindings/gpio/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_GPIO_H_
#define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_GPIO_H_

/*
* Assigned Bit Positions
*
* @note: This table is intended as a convenience to summarize the bit
* assignments used in the fields defined below. The GPIO_foo_SHIFT
* macros are the canonical definition.
*
* Bit Prefix Variations
* ===== ============== =======================================================
* 0 GPIO_ACTIVE high or low
* 1 GPIO_SIGNALING single-ended or push-pull
* 2 GPIO_LINE source or drain
* 3-4 GPIO_PUD pull normal/up/down
* 5-8 GPIO_IO in, out, initialize, initial value
* 9-13 GPIO_INT enable, level/edge, low, high, double-edge
* 14 GPIO_POL polarity normal/invert
* 15 GPIO_DEBOUNCE disable/enable
* 16-17 GPIO_DS_LOW drive strength for output low: default/low/high/discon
* 18-19 GPIO_DS_HIGH drive strength for output high: default/low/high/discon
*/

/**
* @name GPIO active level indicator.
*
Expand Down Expand Up @@ -324,68 +345,72 @@
* The drive strength of individual pins can be configured
* independently for when the pin output is low and high.
*
* The `GPIO_DS_*_LOW` enumerations define the drive strength of a pin
* The `GPIO_DS_*_LOW` bits define the drive strength of a pin
* when output is low.
* The `GPIO_DS_*_HIGH` enumerations define the drive strength of a pin
*
* The `GPIO_DS_*_HIGH` bits define the drive strength of a pin
* when output is high.
*
* The `DISCONNECT` drive strength indicates that the pin is placed in a
* high impedance state and not driven, this option is used to
* configure hardware that supports a open collector drive mode.
* If the device does not distinguish drive strength by signal level,
* the drive strength configuration from `GPIO_DS_*_LOW` shall be
* used.
*
* The interface supports two different drive strengths:
* `DFLT` - The lowest drive strength supported by the HW
* `ALT` - The highest drive strength supported by the HW
* The interface supports several drive strengths:
* `LO` - The lowest drive strength supported by the HW
* `HI` - The highest drive strength supported by the HW
* `DISCONNECT` - The pin is placed in a high impedance state and not
* driven (open drain mode)
*
* On hardware that supports only one standard drive strength, both
* `DFLT` and `ALT` have the same behavior.
* In addition `DFLT` represents the default drive strength for a
* particular driver, and may be either `LO` or `HI`.
*
* On hardware that supports only one standard drive strength `LO` and
* `HI` have the same behavior.
*
* On hardware that does not support a disconnect mode, `DISCONNECT`
* will behave the same as `DFLT`.
*
* @{
*/
/** @cond INTERNAL_HIDDEN */
#define GPIO_DS_LOW_POS 16
#define GPIO_DS_LOW_MASK (3 << GPIO_DS_LOW_POS)
#define GPIO_DS_LOW_SHIFT 16
#define GPIO_DS_LOW_MASK (3 << GPIO_DS_LOW_SHIFT)
/** @endcond */

/** Default drive strength standard when GPIO pin output is low.
*/
#define GPIO_DS_DFLT_LOW (0 << GPIO_DS_LOW_POS)
/** Use default drive strength when GPIO pin output is low. */
#define GPIO_DS_DFLT_LOW (0 << GPIO_DS_LOW_SHIFT)

/** Alternative drive strength when GPIO pin output is low.
* For hardware that does not support configurable drive strength
* use the default drive strength.
*/
#define GPIO_DS_ALT_LOW (1 << GPIO_DS_LOW_POS)
/** Use low/reduced drive strength when GPIO pin output is low. */
#define GPIO_DS_LO_LOW (1 << GPIO_DS_LOW_SHIFT)

/** Use high/increased drive strength when GPIO pin output is low. */
#define GPIO_DS_HI_LOW (2 << GPIO_DS_LOW_SHIFT)

/** Disconnect pin when GPIO pin output is low.
* For hardware that does not support disconnect use the default
* drive strength.
*/
#define GPIO_DS_DISCONNECT_LOW (3 << GPIO_DS_LOW_POS)
#define GPIO_DS_DISCONNECT_LOW (3 << GPIO_DS_LOW_SHIFT)

/** @cond INTERNAL_HIDDEN */
#define GPIO_DS_HIGH_POS 18
#define GPIO_DS_HIGH_MASK (3 << GPIO_DS_HIGH_POS)
#define GPIO_DS_HIGH_SHIFT 18
#define GPIO_DS_HIGH_MASK (3 << GPIO_DS_HIGH_SHIFT)
/** @endcond */

/** Default drive strength when GPIO pin output is high. */
#define GPIO_DS_DFLT_HIGH (0 << GPIO_DS_HIGH_POS)
/** Use default drive strength when GPIO pin output is low. */
#define GPIO_DS_DFLT_HIGH (0 << GPIO_DS_HIGH_SHIFT)

/** Alternative drive strength when GPIO pin output is high.
* For hardware that does not support configurable drive strengths
* use the default drive strength.
*/
#define GPIO_DS_ALT_HIGH (1 << GPIO_DS_HIGH_POS)
/** Use low/reduced drive strength when GPIO pin output is low. */
#define GPIO_DS_LO_HIGH (1 << GPIO_DS_HIGH_SHIFT)

/** Use high/increased drive strength when GPIO pin output is low. */
#define GPIO_DS_HI_HIGH (2 << GPIO_DS_HIGH_SHIFT)

/** Disconnect pin when GPIO pin output is high.
/** Disconnect pin when GPIO pin output is low.
* For hardware that does not support disconnect use the default
* drive strength.
*/
#define GPIO_DS_DISCONNECT_HIGH (3 << GPIO_DS_HIGH_POS)
#define GPIO_DS_DISCONNECT_HIGH (3 << GPIO_DS_HIGH_SHIFT)

/** @} */

Expand Down Expand Up @@ -443,6 +468,20 @@
*/
#define GPIO_INT GPIO_INT_ENABLE

/** Legacy alias identifying high drive strength when GPIO output is
* low.
*
* @deprecated Replace with `GPIO_DS_HI_LOW`
*/
#define GPIO_DS_ALT_LOW GPIO_DS_HI_LOW

/** Legacy alias identifying high drive strength when GPIO output is
* high.
*
* @deprecated Replace with `GPIO_DS_HI_HIGH`
*/
#define GPIO_DS_ALT_HIGH GPIO_DS_HI_HIGH

/** @} */

#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_GPIO_H_ */

0 comments on commit c85f776

Please sign in to comment.