coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
gpio.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <base3.h>
4 #include <console/console.h>
5 #include <delay.h>
6 #include <gpio.h>
7 
8 static void _check_num(const char *name, int num)
9 {
10  if ((num > 31) || (num < 1)) {
11  printk(BIOS_EMERG, "%s: %d ", name, num);
12  die("is an invalid number of GPIOs");
13  }
14 }
15 
16 static uint32_t _gpio_base2_value(const gpio_t gpio[], int num_gpio)
17 {
18  uint32_t result = 0;
19  int i;
20 
21  /* Wait until signals become stable */
22  udelay(10);
23 
24  for (i = 0; i < num_gpio; i++)
25  result |= gpio_get(gpio[i]) << i;
26 
27  return result;
28 }
29 
30 uint32_t gpio_base2_value(const gpio_t gpio[], int num_gpio)
31 {
32  int i;
33 
34  _check_num(__func__, num_gpio);
35  for (i = 0; i < num_gpio; i++)
36  gpio_input(gpio[i]);
37 
38  return _gpio_base2_value(gpio, num_gpio);
39 }
40 
42 {
43  int i;
44 
45  _check_num(__func__, num_gpio);
46  for (i = 0; i < num_gpio; i++)
48 
49  return _gpio_base2_value(gpio, num_gpio);
50 }
51 
53 {
54  int i;
55 
56  _check_num(__func__, num_gpio);
57  for (i = 0; i < num_gpio; i++)
59 
60  return _gpio_base2_value(gpio, num_gpio);
61 }
62 
63 uint32_t _gpio_base3_value(const gpio_t gpio[], int num_gpio, int binary_first)
64 {
65  /*
66  * GPIOs which are tied to stronger external pull up or pull down
67  * will stay there regardless of the internal pull up or pull
68  * down setting.
69  *
70  * GPIOs which are floating will go to whatever level they're
71  * internally pulled to.
72  */
73 
74  static const char tristate_char[] = {[0] = '0', [1] = '1', [Z] = 'Z'};
75  uint32_t result = 0;
76  int has_z = 0;
77  int binary_below = 0;
78  int index;
79  int temp;
80  char value[32];
81 
82  _check_num(__func__, num_gpio);
83 
84  /* Enable internal pull up */
85  for (index = 0; index < num_gpio; ++index)
86  gpio_input_pullup(gpio[index]);
87 
88  /* Wait until signals become stable */
89  udelay(10);
90 
91  /* Get gpio values at internal pull up */
92  for (index = 0; index < num_gpio; ++index)
93  value[index] = gpio_get(gpio[index]);
94 
95  /* Enable internal pull down */
96  for (index = 0; index < num_gpio; ++index)
97  gpio_input_pulldown(gpio[index]);
98 
99  /* Wait until signals become stable */
100  udelay(10);
101 
102  /*
103  * Get gpio values at internal pull down.
104  * Compare with gpio pull up value and then
105  * determine a gpio final value/state:
106  * 0: pull down
107  * 1: pull up
108  * 2: floating
109  */
110  printk(BIOS_DEBUG, "Reading tristate GPIOs: ");
111  for (index = num_gpio - 1; index >= 0; --index) {
112  temp = gpio_get(gpio[index]);
113  temp |= ((value[index] ^ temp) << 1);
114  printk(BIOS_DEBUG, "%c ", tristate_char[temp]);
115  result = (result * 3) + temp;
116 
117  /* Disable pull to avoid wasting power. For HiZ we leave the
118  pull-down enabled, since letting them float freely back and
119  forth may waste power in the SoC's GPIO input logic. */
120  if (temp != Z)
121  gpio_input(gpio[index]);
122 
123  /*
124  * For binary_first we keep track of the normal ternary result
125  * and whether we found any pin that was a Z. We also determine
126  * the amount of numbers that can be represented with only
127  * binary digits (no Z) whose value in the normal ternary system
128  * is lower than the one we are parsing. Counting from the left,
129  * we add 2^i for any '1' digit to account for the binary
130  * numbers whose values would be below it if all following
131  * digits we parsed would be '0'. As soon as we find a '2' digit
132  * we can total the remaining binary numbers below as 2^(i+1)
133  * because we know that all binary representations counting only
134  * this and following digits must have values below our number
135  * (since 1xxx is always smaller than 2xxx).
136  *
137  * Example: 1 0 2 1 (counting from the left / most significant)
138  * '1' at 3^3: Add 2^3 = 8 to account for binaries 0000-0111
139  * '0' at 3^2: Ignore (not all binaries 1000-1100 are below us)
140  * '2' at 3^1: Add 2^(1+1) = 4 to account for binaries 1000-1011
141  * Stop adding for lower digits (3^0), all already accounted
142  * now. We know that there can be no binary numbers 1020-102X.
143  */
144  if (binary_first && !has_z) {
145  switch (temp) {
146  case 0: /* Ignore '0' digits. */
147  break;
148  case 1: /* Account for binaries 0 to 2^index - 1. */
149  binary_below += 1 << index;
150  break;
151  case 2: /* Account for binaries 0 to 2^(index+1) - 1. */
152  binary_below += 1 << (index + 1);
153  has_z = 1;
154  }
155  }
156  }
157 
158  if (binary_first) {
159  if (has_z)
160  result = result + (1 << num_gpio) - binary_below;
161  else /* binary_below is normal binary system value if !has_z. */
162  result = binary_below;
163  }
164 
165  printk(BIOS_DEBUG, "= %d (%s base3 number system)\n", result,
166  binary_first ? "binary_first" : "standard");
167 
168  return result;
169 }
170 
171 /* Default handler for ACPI path is to return NULL */
173 {
174  return NULL;
175 }
176 
177 /* Default handler returns 0 because type of gpio_t is unknown */
179 {
180  return 0;
181 }
pte_t value
Definition: mmu.c:91
const char * name
Definition: mmu.c:92
#define Z
Definition: base3.h:7
#define printk(level,...)
Definition: stdlib.h:16
void __noreturn die(const char *fmt,...)
Definition: die.c:17
static uint32_t _gpio_base2_value(const gpio_t gpio[], int num_gpio)
Definition: gpio.c:16
uint32_t gpio_base2_value(const gpio_t gpio[], int num_gpio)
Definition: gpio.c:30
uint32_t gpio_pullup_base2_value(const gpio_t gpio[], int num_gpio)
Definition: gpio.c:52
uint32_t _gpio_base3_value(const gpio_t gpio[], int num_gpio, int binary_first)
Definition: gpio.c:63
uint32_t gpio_pulldown_base2_value(const gpio_t gpio[], int num_gpio)
Definition: gpio.c:41
__weak uint16_t gpio_acpi_pin(gpio_t gpio)
Definition: gpio.c:178
static void _check_num(const char *name, int num)
Definition: gpio.c:8
__weak const char * gpio_acpi_path(gpio_t gpio)
Definition: gpio.c:172
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_EMERG
BIOS_EMERG - Emergency / Fatal.
Definition: loglevel.h:25
result
Definition: mrc_cache.c:35
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
int gpio_get(gpio_t gpio_num)
Definition: gpio.c:166
void gpio_input_pullup(gpio_t gpio_num)
Definition: gpio.c:184
void gpio_input_pulldown(gpio_t gpio_num)
Definition: gpio.c:179
void gpio_input(gpio_t gpio_num)
Definition: gpio.c:189
#define NULL
Definition: stddef.h:19
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
Definition: pinmux.c:36
void udelay(uint32_t us)
Definition: udelay.c:15