summaryrefslogtreecommitdiff
path: root/zephyr/shim/src
diff options
context:
space:
mode:
authorPhilip Chen <philipchen@google.com>2021-07-08 12:57:28 -0700
committerCommit Bot <commit-bot@chromium.org>2021-07-09 05:09:27 +0000
commit002ccf3446a54813f249462064ed193e35435dcc (patch)
tree4299037b76c5cfbe4cc87a0acca00a4a584a0177 /zephyr/shim/src
parent4cf446bf5f122050f00376af66b9f5edcab26ba6 (diff)
downloadchrome-ec-002ccf3446a54813f249462064ed193e35435dcc.tar.gz
zephyr: shim: Support reading tri-state GPIO
Copy gpio_get_ternary() and binary_first_base3_from_bits() to zephyr. BRANCH=None BUG=b:186264627 TEST=zmake testall Change-Id: I7086668a33da095132dbccae0f41264b59b1b20e Signed-off-by: Philip Chen <philipchen@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3015243 Tested-by: Philip Chen <philipchen@chromium.org> Commit-Queue: Philip Chen <philipchen@chromium.org> Reviewed-by: Keith Short <keithshort@chromium.org>
Diffstat (limited to 'zephyr/shim/src')
-rw-r--r--zephyr/shim/src/gpio.c22
-rw-r--r--zephyr/shim/src/util.c53
2 files changed, 75 insertions, 0 deletions
diff --git a/zephyr/shim/src/gpio.c b/zephyr/shim/src/gpio.c
index 721791ab3d..aa04474f72 100644
--- a/zephyr/shim/src/gpio.c
+++ b/zephyr/shim/src/gpio.c
@@ -176,6 +176,28 @@ int gpio_get_level(enum gpio_signal signal)
return l;
}
+int gpio_get_ternary(enum gpio_signal signal)
+{
+ int pd, pu;
+ int flags = gpio_get_default_flags(signal);
+
+ /* Read GPIO with internal pull-down */
+ gpio_set_flags(signal, GPIO_INPUT | GPIO_PULL_DOWN);
+ pd = gpio_get_level(signal);
+ udelay(100);
+
+ /* Read GPIO with internal pull-up */
+ gpio_set_flags(signal, GPIO_INPUT | GPIO_PULL_UP);
+ pu = gpio_get_level(signal);
+ udelay(100);
+
+ /* Reset GPIO flags */
+ gpio_set_flags(signal, flags);
+
+ /* Check PU and PD readings to determine tristate */
+ return pu && !pd ? 2 : pd;
+}
+
const char *gpio_get_name(enum gpio_signal signal)
{
if (!gpio_is_implemented(signal))
diff --git a/zephyr/shim/src/util.c b/zephyr/shim/src/util.c
index ca45025cd7..32f55e0581 100644
--- a/zephyr/shim/src/util.c
+++ b/zephyr/shim/src/util.c
@@ -276,3 +276,56 @@ int cond_is(cond_t *c, int val)
else
return !(*c & COND_CURR_MASK);
}
+
+int binary_first_base3_from_bits(int *bits, int nbits)
+{
+ int binary_below = 0;
+ int has_z = 0;
+ int base3 = 0;
+ int i;
+
+ /* Loop through every ternary digit, from MSB to LSB. */
+ for (i = nbits - 1; i >= 0; i--) {
+ /*
+ * We keep track of the normal ternary result and whether
+ * we found any bit that was a Z. We also determine the
+ * amount of numbers that can be represented with only binary
+ * digits (no Z) whose value in the normal ternary system
+ * is lower than the one we are parsing. Counting from the left,
+ * we add 2^i for any '1' digit to account for the binary
+ * numbers whose values would be below it if all following
+ * digits we parsed would be '0'. As soon as we find a '2' digit
+ * we can total the remaining binary numbers below as 2^(i+1)
+ * because we know that all binary representations counting only
+ * this and following digits must have values below our number
+ * (since 1xxx is always smaller than 2xxx).
+ *
+ * Example: 1 0 2 1 (counting from the left / most significant)
+ * '1' at 3^3: Add 2^3 = 8 to account for binaries 0000-0111
+ * '0' at 3^2: Ignore (not all binaries 1000-1100 are below us)
+ * '2' at 3^1: Add 2^(1+1) = 4 to account for binaries 1000-1011
+ * Stop adding for lower digits (3^0), all already accounted
+ * now. We know that there can be no binary numbers 1020-102X.
+ */
+ base3 = (base3 * 3) + bits[i];
+
+ if (!has_z) {
+ switch (bits[i]) {
+ case 0: /* Ignore '0' digits. */
+ break;
+ case 1: /* Account for binaries 0 to 2^i - 1. */
+ binary_below += 1 << i;
+ break;
+ case 2: /* Account for binaries 0 to 2^(i+1) - 1. */
+ binary_below += 1 << (i + 1);
+ has_z = 1;
+ }
+ }
+ }
+
+ if (has_z)
+ return base3 + (1 << nbits) - binary_below;
+
+ /* binary_below is normal binary system value if !has_z. */
+ return binary_below;
+}