blob: c25b3f9f85e68d820e6da04071a70fd4268c9a05 [file] [log] [blame]
Angel Pons118a9c72020-04-02 23:48:34 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Vadim Bendebury9c9c3362014-07-23 09:40:02 -07003
Julius Werner886d29b2014-09-24 15:40:49 -07004#include <base3.h>
5#include <console/console.h>
Vadim Bendebury9c9c3362014-07-23 09:40:02 -07006#include <delay.h>
Julius Wernereaa9c452014-09-24 15:40:49 -07007#include <gpio.h>
Vadim Bendebury9c9c3362014-07-23 09:40:02 -07008
Richard Spiegel7160766e2018-09-03 08:55:51 -07009static void _check_num(const char *name, int num)
10{
11 if ((num > 31) || (num < 1)) {
12 printk(BIOS_EMERG, "%s: %d ", name, num);
13 die("is an invalid number of GPIOs");
14 }
15}
16
Julius Werner0a0340e2018-08-02 11:45:07 -070017static uint32_t _gpio_base2_value(const gpio_t gpio[], int num_gpio)
David Hendricks21db62e2014-11-06 15:05:35 -080018{
Julius Werner0a0340e2018-08-02 11:45:07 -070019 uint32_t result = 0;
20 int i;
David Hendricks21db62e2014-11-06 15:05:35 -080021
David Hendricksf9b49e82015-01-14 20:41:30 -080022 /* Wait until signals become stable */
23 udelay(10);
24
25 for (i = 0; i < num_gpio; i++)
David Hendricks21db62e2014-11-06 15:05:35 -080026 result |= gpio_get(gpio[i]) << i;
David Hendricks21db62e2014-11-06 15:05:35 -080027
28 return result;
29}
30
Julius Werner0a0340e2018-08-02 11:45:07 -070031uint32_t gpio_base2_value(const gpio_t gpio[], int num_gpio)
Aaron Durbinf41ac222016-07-06 22:37:10 -050032{
33 int i;
34
Richard Spiegel7160766e2018-09-03 08:55:51 -070035 _check_num(__func__, num_gpio);
Aaron Durbinf41ac222016-07-06 22:37:10 -050036 for (i = 0; i < num_gpio; i++)
37 gpio_input(gpio[i]);
38
39 return _gpio_base2_value(gpio, num_gpio);
40}
41
Julius Werner0a0340e2018-08-02 11:45:07 -070042uint32_t gpio_pulldown_base2_value(const gpio_t gpio[], int num_gpio)
Aaron Durbinf41ac222016-07-06 22:37:10 -050043{
44 int i;
45
Richard Spiegel7160766e2018-09-03 08:55:51 -070046 _check_num(__func__, num_gpio);
Aaron Durbinf41ac222016-07-06 22:37:10 -050047 for (i = 0; i < num_gpio; i++)
48 gpio_input_pulldown(gpio[i]);
49
50 return _gpio_base2_value(gpio, num_gpio);
51}
52
Julius Werner0a0340e2018-08-02 11:45:07 -070053uint32_t gpio_pullup_base2_value(const gpio_t gpio[], int num_gpio)
Aaron Durbinf41ac222016-07-06 22:37:10 -050054{
55 int i;
56
Richard Spiegel7160766e2018-09-03 08:55:51 -070057 _check_num(__func__, num_gpio);
Aaron Durbinf41ac222016-07-06 22:37:10 -050058 for (i = 0; i < num_gpio; i++)
59 gpio_input_pullup(gpio[i]);
60
61 return _gpio_base2_value(gpio, num_gpio);
62}
63
Julius Werner0a0340e2018-08-02 11:45:07 -070064uint32_t _gpio_base3_value(const gpio_t gpio[], int num_gpio, int binary_first)
Vadim Bendebury9c9c3362014-07-23 09:40:02 -070065{
66 /*
67 * GPIOs which are tied to stronger external pull up or pull down
68 * will stay there regardless of the internal pull up or pull
69 * down setting.
70 *
71 * GPIOs which are floating will go to whatever level they're
72 * internally pulled to.
73 */
74
Julius Werner886d29b2014-09-24 15:40:49 -070075 static const char tristate_char[] = {[0] = '0', [1] = '1', [Z] = 'Z'};
Julius Werner0a0340e2018-08-02 11:45:07 -070076 uint32_t result = 0;
Julius Werner2b239482016-03-16 17:11:55 -070077 int has_z = 0;
78 int binary_below = 0;
Julius Werner0a0340e2018-08-02 11:45:07 -070079 int index;
80 int temp;
Julius Werner8d8799a2014-12-19 16:11:14 -080081 char value[32];
Richard Spiegel7160766e2018-09-03 08:55:51 -070082
83 _check_num(__func__, num_gpio);
Vadim Bendebury9c9c3362014-07-23 09:40:02 -070084
85 /* Enable internal pull up */
86 for (index = 0; index < num_gpio; ++index)
87 gpio_input_pullup(gpio[index]);
88
89 /* Wait until signals become stable */
90 udelay(10);
91
92 /* Get gpio values at internal pull up */
93 for (index = 0; index < num_gpio; ++index)
Julius Wernereaa9c452014-09-24 15:40:49 -070094 value[index] = gpio_get(gpio[index]);
Vadim Bendebury9c9c3362014-07-23 09:40:02 -070095
96 /* Enable internal pull down */
97 for (index = 0; index < num_gpio; ++index)
98 gpio_input_pulldown(gpio[index]);
99
100 /* Wait until signals become stable */
101 udelay(10);
102
103 /*
104 * Get gpio values at internal pull down.
105 * Compare with gpio pull up value and then
106 * determine a gpio final value/state:
107 * 0: pull down
108 * 1: pull up
109 * 2: floating
110 */
Julius Werner886d29b2014-09-24 15:40:49 -0700111 printk(BIOS_DEBUG, "Reading tristate GPIOs: ");
Daisuke Nojiri573e2112014-08-08 15:38:52 -0700112 for (index = num_gpio - 1; index >= 0; --index) {
Julius Wernereaa9c452014-09-24 15:40:49 -0700113 temp = gpio_get(gpio[index]);
Julius Werner886d29b2014-09-24 15:40:49 -0700114 temp |= ((value[index] ^ temp) << 1);
115 printk(BIOS_DEBUG, "%c ", tristate_char[temp]);
David Hendricks3fc63682014-11-06 15:09:27 -0800116 result = (result * 3) + temp;
Julius Werner2b239482016-03-16 17:11:55 -0700117
118 /*
119 * For binary_first we keep track of the normal ternary result
120 * and whether we found any pin that was a Z. We also determine
121 * the amount of numbers that can be represented with only
122 * binary digits (no Z) whose value in the normal ternary system
123 * is lower than the one we are parsing. Counting from the left,
124 * we add 2^i for any '1' digit to account for the binary
125 * numbers whose values would be below it if all following
126 * digits we parsed would be '0'. As soon as we find a '2' digit
127 * we can total the remaining binary numbers below as 2^(i+1)
128 * because we know that all binary representations counting only
129 * this and following digits must have values below our number
130 * (since 1xxx is always smaller than 2xxx).
131 *
132 * Example: 1 0 2 1 (counting from the left / most significant)
133 * '1' at 3^3: Add 2^3 = 8 to account for binaries 0000-0111
134 * '0' at 3^2: Ignore (not all binaries 1000-1100 are below us)
135 * '2' at 3^1: Add 2^(1+1) = 4 to account for binaries 1000-1011
136 * Stop adding for lower digits (3^0), all already accounted
137 * now. We know that there can be no binary numbers 1020-102X.
138 */
139 if (binary_first && !has_z) {
Lee Leahy45fde702017-03-08 18:02:24 -0800140 switch (temp) {
Julius Werner2b239482016-03-16 17:11:55 -0700141 case 0: /* Ignore '0' digits. */
142 break;
143 case 1: /* Account for binaries 0 to 2^index - 1. */
144 binary_below += 1 << index;
145 break;
146 case 2: /* Account for binaries 0 to 2^(index+1) - 1. */
147 binary_below += 1 << (index + 1);
148 has_z = 1;
149 }
150 }
Vadim Bendebury9c9c3362014-07-23 09:40:02 -0700151 }
Julius Werner2b239482016-03-16 17:11:55 -0700152
153 if (binary_first) {
154 if (has_z)
155 result = result + (1 << num_gpio) - binary_below;
156 else /* binary_below is normal binary system value if !has_z. */
157 result = binary_below;
158 }
159
160 printk(BIOS_DEBUG, "= %d (%s base3 number system)\n", result,
161 binary_first ? "binary_first" : "standard");
Vadim Bendebury9c9c3362014-07-23 09:40:02 -0700162
163 /* Disable pull up / pull down to conserve power */
164 for (index = 0; index < num_gpio; ++index)
165 gpio_input(gpio[index]);
166
David Hendricks3fc63682014-11-06 15:09:27 -0800167 return result;
Vadim Bendebury9c9c3362014-07-23 09:40:02 -0700168}
Duncan Laurie3a39f442016-05-09 16:09:25 -0700169
170/* Default handler for ACPI path is to return NULL */
Aaron Durbin64031672018-04-21 14:45:32 -0600171__weak const char *gpio_acpi_path(gpio_t gpio)
Duncan Laurie3a39f442016-05-09 16:09:25 -0700172{
173 return NULL;
174}
Duncan Laurie5b6c28c2016-06-29 10:47:22 -0700175
176/* Default handler returns 0 because type of gpio_t is unknown */
Aaron Durbin64031672018-04-21 14:45:32 -0600177__weak uint16_t gpio_acpi_pin(gpio_t gpio)
Duncan Laurie5b6c28c2016-06-29 10:47:22 -0700178{
179 return 0;
180}