GPIO setup is done for every board variant, but never for the baseboard, by configuring the file ./board/<board>/gpio.inc
. This file configures all the the pins on the EC chipset through the following macros.
GPIO(<name>, ...)
- Configures simple GPIO input and outputsGPIO_INT(<name>, ...)
- Configures GPIO inputs that connect to an interrupt service routine. Historically these entries are defined first, but this no longer required.ALTERNATE(...)
- Configures a pin for an alternate function (e.g I2C, ADC, SPI, etc)UNIMPLEMENTED(<name>, ...)
- Creates a fake GPIO entryThe GPIO()
, GPIO_INT()
, and UNIMPLEMENTED()
macros create a C enumeration of the form GPIO_<name>
that can be used in the code. As noted in GPIO Naming, the <name>
parameter should always match the schematic net name.
GPIO()
macroGPIO(name, pin, flags)
name
- Defines the schematic net name, which is expanded to the enumeration GPIO_name
by the macro.pin
- Use the PIN(group,pin)
macro to define the GPIO group and pin number. Note that on a few EC chipsets, the PIN macro is just PIN(pin)
.flags
- Define attributes of the pin (direction, pullup/pulldown, open drain, voltage level, etc). All supported flags are found following the GPIO_FLAG_NONE
definition in ./include/gpio.h.GPIO(EC_ENTERING_RW, PIN(E, 3), GPIO_OUT_LOW)
The EC common code requires the enum GPIO_ENTERING_RW
to be defined, so you should also map the net name to the EC name in the board.h
file.
#define GPIO_ENTERING_RW GPIO_EC_ENTERING_RW
GPIO_INT()
macroGPIO_INT(name, pin, flags, signal)
name
- Defines the schematic net name, which is expanded to the enumeration GPIO_name
by the macro.pin
- Same definition as GPIO()
macro.flags
- Same definition as GPIO()
macro. Should always have one of the GPIO_INT_*
flags set.signal
- Interrupt service routine called when the pin asserts according to the flags set.GPIO_INT(EC_LID_OPEN, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt)
The EC common code requires the enum GPIO_LID_OPEN
to be defined, so you als need to map the net name to the EC name in the board.h
file.
#define GPIO_LID_OPEN GPIO_EC_LID_OPEN
ALTERNATE()
macroALTERNATE(pinmask, function, module, flags)
pinmask
- Defines a set of pins in the same GPIO group to assign to a different function.function
- A chip-specific function number. Only used if the EC chipset provides multiple alternate functions in addition to GPIO (e.g. pin can be UART, I2C, SPI, or GPIO). The permitted values for this parameter vary based on the EC chipset type.module
- One of the enum module_id values defined in ./include/module_id.h.flags
- Same definition as GPIO()
macro.At runtime there are two mechanisms for switching a pin between GPIO mode and alternate function mode.
gpio_config_module(enum module_id id, int enable)
- Configures all pins matching the module enumeration id
.gpio_config_pin(enum module_id id, enum gpio_signal signal, int enable)
- Configures a single pin matching the GPIO enumeration signal
.For both routines, if enable
is 1, then the corresponding pins are configured for alternate mode operation. If enable
is 0, then the corresponding pins are configure for GPIO mode.
gpio_config_module()
is automatically called at runtime for all enabled interfaces (I2C, SPI, UART, etc). You can use gpio_config_pin()
to temporarily configure a pin for GPIO operation, and to restore the original alternate function. The I2C bus error recovery employs this mechanism to temporarily driver the I2C SCL and SDA signals to known states, without interference by the I2C controller in the EC chipset.
The general recipe for overriding alternate functions is shown below.
/* Disconnect I2C1_SDA pin from I2C controller */ gpio_config_pin(MODULE_I2C, GPIO_I2C1_SDA, 0); /* Setup I2C1_SDA as an GPIO open drain output and drive initial state low */ gpio_set_flags(GPIO_I2C1_SDA, GPIO_ODR_LOW); /* Set GPIO high (or low) as required */ gpio_set_level (GPIO_I2C1_SDA, 1); /* Restore I2C1_SDA pin to I2C function */' gpio_config_pin(MODULE_I2C, GPIO_I2C1_SDA, 1);
ALTERNATE(PIN_MASK(B, BIT(4) | BIT(5)), 0, MODULE_I2C, (GPIO_INPUT | GPIO_SEL_1P8V))