blob: 2e345956f8e187b9f912a95043940e647ac244a6 [file] [log] [blame]
Vadim Bendebury9c9c3362014-07-23 09:40:02 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2014 Google Inc.
5 *
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.
9 *
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.
Vadim Bendebury9c9c3362014-07-23 09:40:02 -070014 */
15
Julius Werner8d8799a2014-12-19 16:11:14 -080016#include <assert.h>
Julius Werner886d29b2014-09-24 15:40:49 -070017#include <base3.h>
18#include <console/console.h>
Vadim Bendebury9c9c3362014-07-23 09:40:02 -070019#include <delay.h>
Julius Wernereaa9c452014-09-24 15:40:49 -070020#include <gpio.h>
Vadim Bendebury9c9c3362014-07-23 09:40:02 -070021
David Hendricks21db62e2014-11-06 15:05:35 -080022int gpio_base2_value(gpio_t gpio[], int num_gpio)
23{
24 int i, result = 0;
25
David Hendricksf9b49e82015-01-14 20:41:30 -080026 for (i = 0; i < num_gpio; i++)
David Hendricks21db62e2014-11-06 15:05:35 -080027 gpio_input(gpio[i]);
David Hendricksf9b49e82015-01-14 20:41:30 -080028
29 /* Wait until signals become stable */
30 udelay(10);
31
32 for (i = 0; i < num_gpio; i++)
David Hendricks21db62e2014-11-06 15:05:35 -080033 result |= gpio_get(gpio[i]) << i;
David Hendricks21db62e2014-11-06 15:05:35 -080034
35 return result;
36}
37
Julius Werner2b239482016-03-16 17:11:55 -070038int _gpio_base3_value(gpio_t gpio[], int num_gpio, int binary_first)
Vadim Bendebury9c9c3362014-07-23 09:40:02 -070039{
40 /*
41 * GPIOs which are tied to stronger external pull up or pull down
42 * will stay there regardless of the internal pull up or pull
43 * down setting.
44 *
45 * GPIOs which are floating will go to whatever level they're
46 * internally pulled to.
47 */
48
Julius Werner886d29b2014-09-24 15:40:49 -070049 static const char tristate_char[] = {[0] = '0', [1] = '1', [Z] = 'Z'};
Vadim Bendebury9c9c3362014-07-23 09:40:02 -070050 int temp;
51 int index;
David Hendricks3fc63682014-11-06 15:09:27 -080052 int result = 0;
Julius Werner2b239482016-03-16 17:11:55 -070053 int has_z = 0;
54 int binary_below = 0;
Julius Werner8d8799a2014-12-19 16:11:14 -080055 char value[32];
56 assert(num_gpio <= 32);
Vadim Bendebury9c9c3362014-07-23 09:40:02 -070057
58 /* Enable internal pull up */
59 for (index = 0; index < num_gpio; ++index)
60 gpio_input_pullup(gpio[index]);
61
62 /* Wait until signals become stable */
63 udelay(10);
64
65 /* Get gpio values at internal pull up */
66 for (index = 0; index < num_gpio; ++index)
Julius Wernereaa9c452014-09-24 15:40:49 -070067 value[index] = gpio_get(gpio[index]);
Vadim Bendebury9c9c3362014-07-23 09:40:02 -070068
69 /* Enable internal pull down */
70 for (index = 0; index < num_gpio; ++index)
71 gpio_input_pulldown(gpio[index]);
72
73 /* Wait until signals become stable */
74 udelay(10);
75
76 /*
77 * Get gpio values at internal pull down.
78 * Compare with gpio pull up value and then
79 * determine a gpio final value/state:
80 * 0: pull down
81 * 1: pull up
82 * 2: floating
83 */
Julius Werner886d29b2014-09-24 15:40:49 -070084 printk(BIOS_DEBUG, "Reading tristate GPIOs: ");
Daisuke Nojiri573e2112014-08-08 15:38:52 -070085 for (index = num_gpio - 1; index >= 0; --index) {
Julius Wernereaa9c452014-09-24 15:40:49 -070086 temp = gpio_get(gpio[index]);
Julius Werner886d29b2014-09-24 15:40:49 -070087 temp |= ((value[index] ^ temp) << 1);
88 printk(BIOS_DEBUG, "%c ", tristate_char[temp]);
David Hendricks3fc63682014-11-06 15:09:27 -080089 result = (result * 3) + temp;
Julius Werner2b239482016-03-16 17:11:55 -070090
91 /*
92 * For binary_first we keep track of the normal ternary result
93 * and whether we found any pin that was a Z. We also determine
94 * the amount of numbers that can be represented with only
95 * binary digits (no Z) whose value in the normal ternary system
96 * is lower than the one we are parsing. Counting from the left,
97 * we add 2^i for any '1' digit to account for the binary
98 * numbers whose values would be below it if all following
99 * digits we parsed would be '0'. As soon as we find a '2' digit
100 * we can total the remaining binary numbers below as 2^(i+1)
101 * because we know that all binary representations counting only
102 * this and following digits must have values below our number
103 * (since 1xxx is always smaller than 2xxx).
104 *
105 * Example: 1 0 2 1 (counting from the left / most significant)
106 * '1' at 3^3: Add 2^3 = 8 to account for binaries 0000-0111
107 * '0' at 3^2: Ignore (not all binaries 1000-1100 are below us)
108 * '2' at 3^1: Add 2^(1+1) = 4 to account for binaries 1000-1011
109 * Stop adding for lower digits (3^0), all already accounted
110 * now. We know that there can be no binary numbers 1020-102X.
111 */
112 if (binary_first && !has_z) {
113 switch(temp) {
114 case 0: /* Ignore '0' digits. */
115 break;
116 case 1: /* Account for binaries 0 to 2^index - 1. */
117 binary_below += 1 << index;
118 break;
119 case 2: /* Account for binaries 0 to 2^(index+1) - 1. */
120 binary_below += 1 << (index + 1);
121 has_z = 1;
122 }
123 }
Vadim Bendebury9c9c3362014-07-23 09:40:02 -0700124 }
Julius Werner2b239482016-03-16 17:11:55 -0700125
126 if (binary_first) {
127 if (has_z)
128 result = result + (1 << num_gpio) - binary_below;
129 else /* binary_below is normal binary system value if !has_z. */
130 result = binary_below;
131 }
132
133 printk(BIOS_DEBUG, "= %d (%s base3 number system)\n", result,
134 binary_first ? "binary_first" : "standard");
Vadim Bendebury9c9c3362014-07-23 09:40:02 -0700135
136 /* Disable pull up / pull down to conserve power */
137 for (index = 0; index < num_gpio; ++index)
138 gpio_input(gpio[index]);
139
David Hendricks3fc63682014-11-06 15:09:27 -0800140 return result;
Vadim Bendebury9c9c3362014-07-23 09:40:02 -0700141}