/ src / lib / gpio.c
gpio.c
  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  
 41  uint32_t gpio_pulldown_base2_value(const gpio_t gpio[], int num_gpio)
 42  {
 43  	int i;
 44  
 45  	_check_num(__func__, num_gpio);
 46  	for (i = 0; i < num_gpio; i++)
 47  		gpio_input_pulldown(gpio[i]);
 48  
 49  	return _gpio_base2_value(gpio, num_gpio);
 50  }
 51  
 52  uint32_t gpio_pullup_base2_value(const gpio_t gpio[], int num_gpio)
 53  {
 54  	int i;
 55  
 56  	_check_num(__func__, num_gpio);
 57  	for (i = 0; i < num_gpio; i++)
 58  		gpio_input_pullup(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 */
172  __weak const char *gpio_acpi_path(gpio_t gpio)
173  {
174  	return NULL;
175  }
176  
177  /* Default handler returns 0 because type of gpio_t is unknown */
178  __weak uint16_t gpio_acpi_pin(gpio_t gpio)
179  {
180  	return 0;
181  }