2 * This file is part of the coreboot project.
4 * Copyright 2014 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
18 #include <console/console.h>
22 static int _gpio_base2_value(gpio_t gpio
[], int num_gpio
)
26 /* Wait until signals become stable */
29 for (i
= 0; i
< num_gpio
; i
++)
30 result
|= gpio_get(gpio
[i
]) << i
;
35 int gpio_base2_value(gpio_t gpio
[], int num_gpio
)
39 for (i
= 0; i
< num_gpio
; i
++)
42 return _gpio_base2_value(gpio
, num_gpio
);
45 int gpio_pulldown_base2_value(gpio_t gpio
[], int num_gpio
)
49 for (i
= 0; i
< num_gpio
; i
++)
50 gpio_input_pulldown(gpio
[i
]);
52 return _gpio_base2_value(gpio
, num_gpio
);
55 int gpio_pullup_base2_value(gpio_t gpio
[], int num_gpio
)
59 for (i
= 0; i
< num_gpio
; i
++)
60 gpio_input_pullup(gpio
[i
]);
62 return _gpio_base2_value(gpio
, num_gpio
);
65 int _gpio_base3_value(gpio_t gpio
[], int num_gpio
, int binary_first
)
68 * GPIOs which are tied to stronger external pull up or pull down
69 * will stay there regardless of the internal pull up or pull
72 * GPIOs which are floating will go to whatever level they're
73 * internally pulled to.
76 static const char tristate_char
[] = {[0] = '0', [1] = '1', [Z
] = 'Z'};
83 assert(num_gpio
<= 32);
85 /* Enable internal pull up */
86 for (index
= 0; index
< num_gpio
; ++index
)
87 gpio_input_pullup(gpio
[index
]);
89 /* Wait until signals become stable */
92 /* Get gpio values at internal pull up */
93 for (index
= 0; index
< num_gpio
; ++index
)
94 value
[index
] = gpio_get(gpio
[index
]);
96 /* Enable internal pull down */
97 for (index
= 0; index
< num_gpio
; ++index
)
98 gpio_input_pulldown(gpio
[index
]);
100 /* Wait until signals become stable */
104 * Get gpio values at internal pull down.
105 * Compare with gpio pull up value and then
106 * determine a gpio final value/state:
111 printk(BIOS_DEBUG
, "Reading tristate GPIOs: ");
112 for (index
= num_gpio
- 1; index
>= 0; --index
) {
113 temp
= gpio_get(gpio
[index
]);
114 temp
|= ((value
[index
] ^ temp
) << 1);
115 printk(BIOS_DEBUG
, "%c ", tristate_char
[temp
]);
116 result
= (result
* 3) + temp
;
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).
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.
139 if (binary_first
&& !has_z
) {
141 case 0: /* Ignore '0' digits. */
143 case 1: /* Account for binaries 0 to 2^index - 1. */
144 binary_below
+= 1 << index
;
146 case 2: /* Account for binaries 0 to 2^(index+1) - 1. */
147 binary_below
+= 1 << (index
+ 1);
155 result
= result
+ (1 << num_gpio
) - binary_below
;
156 else /* binary_below is normal binary system value if !has_z. */
157 result
= binary_below
;
160 printk(BIOS_DEBUG
, "= %d (%s base3 number system)\n", result
,
161 binary_first
? "binary_first" : "standard");
163 /* Disable pull up / pull down to conserve power */
164 for (index
= 0; index
< num_gpio
; ++index
)
165 gpio_input(gpio
[index
]);
170 /* Default handler for ACPI path is to return NULL */
171 __attribute__((weak
)) const char *gpio_acpi_path(gpio_t gpio
)
176 /* Default handler returns 0 because type of gpio_t is unknown */
177 __attribute__((weak
)) uint16_t gpio_acpi_pin(gpio_t gpio
)