summaryrefslogtreecommitdiff
path: root/docs/configuration/gpio.md
blob: 4e13a7cb596eb11a93e4e63fa4b65654e77a3bc1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# GPIO Configuration

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 outputs
- `GPIO_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 entry

The `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](../new_board_checklist.md#GPIO-Naming), the `<name>` parameter should
always match the schematic net name.

## `GPIO()` macro

### Prototype

`GPIO(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](../../include/gpio.h).

### Example

![GPIO Example]

```c
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.

```c
#define GPIO_ENTERING_RW    GPIO_EC_ENTERING_RW
```

## `GPIO_INT()` macro

### Prototype
`GPIO_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.

### Example

![GPIO_INT Example]

```c
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.

```c
#define GPIO_LID_OPEN       GPIO_EC_LID_OPEN
```

## `ALTERNATE()` macro

### Prototype
`ALTERNATE(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.
  - STM32 - 0 to 7
  - Maxim - 1 to 3
  - Microchip - 0 to 3
  - MediaTek - 0 to 7
  - All others (Nuvton, ITE, TI Stellaris, ) only support one alternate
    function per pin, so this parameter should be set to 0.
- `module` - One of the enum module_id values defined in
  [./include/module_id.h](../../include/module_id.h).
- `flags` - Same definition as `GPIO()` macro.

### Notes

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.

```c
    /* 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);
```



### Example

![ALTERNATE Example]

```c
ALTERNATE(PIN_MASK(B, BIT(4) | BIT(5)), 0, MODULE_I2C, (GPIO_INPUT | GPIO_SEL_1P8V))
```

<!-- Images -->

<!-- If you make changes to the docs below make sure to regenerate the PNGs by
     appending "export/png" to the Google Drive link. -->

<!-- https://docs.google.com/drawings/d/18cWTYQRRCpypYDOLlvKQJTObwcj6wOjUga02B0oZXBg -->
[GPIO Example]: ../images/gpio_example.png
<!-- https://docs.google.com/drawings/d/1X6p5XfB6BBmUUKCrwOg56Bz6LZj9P_WPQXsOdk-OIiI -->
[GPIO_INT Example]: ../images/gpio_int_example.png
<!-- https://docs.google.com/drawings/d/1-kroVezQuA_KdQLzqYPs8u94EBg37z3k6lKzkSLRv-0 -->
[ALTERNATE Example]: ../images/alternate_example.png