diff options
-rw-r--r-- | common/util.c | 24 | ||||
-rw-r--r-- | include/util.h | 21 | ||||
-rw-r--r-- | zephyr/dts/bindings/gpio/gpio-id.yaml | 27 | ||||
-rw-r--r-- | zephyr/shim/src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | zephyr/shim/src/gpio_id.c | 75 | ||||
-rw-r--r-- | zephyr/shim/src/util.c | 24 |
6 files changed, 171 insertions, 1 deletions
diff --git a/common/util.c b/common/util.c index 7ed4c45c53..deaa62f37f 100644 --- a/common/util.c +++ b/common/util.c @@ -767,3 +767,27 @@ int binary_first_base3_from_bits(int *bits, int nbits) /* binary_below is normal binary system value if !has_z. */ return binary_below; } + +int binary_from_bits(int *bits, int nbits) +{ + int value = 0; + int i; + + /* Loop through every binary digit, from MSB to LSB. */ + for (i = nbits - 1; i >= 0; i--) + value = (value << 1) | bits[i]; + + return value; +} + +int ternary_from_bits(int *bits, int nbits) +{ + int value = 0; + int i; + + /* Loop through every ternary digit, from MSB to LSB. */ + for (i = nbits - 1; i >= 0; i--) + value = (value * 3) + bits[i]; + + return value; +} diff --git a/include/util.h b/include/util.h index 4ed352f0d7..1b077d0f55 100644 --- a/include/util.h +++ b/include/util.h @@ -342,7 +342,7 @@ void wait_for_ready(volatile uint32_t *reg, uint32_t enable, uint32_t ready); * the normal ternary system order (skipping the values that were already used * up). * - * This function is useful for converting BOARd ID, which is initially used a + * This function is useful for converting BOARD ID, which is initially used a * binary and later decided to switch to tri-state after some revisions have * already been built. * @@ -365,6 +365,25 @@ void wait_for_ready(volatile uint32_t *reg, uint32_t enable, uint32_t ready); */ int binary_first_base3_from_bits(int *bits, int nbits); +/** + * Convert the binary bit array to integer value. + * + * @param bits array of integers with values of 0 and 1 + * @param nbits number of bits to decode + * @return integer decoded from bits + */ +int binary_from_bits(int *bits, int nbits); + +/** + * Convert the ternary bit array to integer value. + * This function is used to handle 'Z' state of gpio as value of '2'. + * + * @param bits array of integers with values of 0, 1 or 2 + * @param nbits number of bits to decode + * @return integer decoded from bits + */ +int ternary_from_bits(int *bits, int nbits); + #ifdef __cplusplus } #endif diff --git a/zephyr/dts/bindings/gpio/gpio-id.yaml b/zephyr/dts/bindings/gpio/gpio-id.yaml new file mode 100644 index 0000000000..24322b3de8 --- /dev/null +++ b/zephyr/dts/bindings/gpio/gpio-id.yaml @@ -0,0 +1,27 @@ +description: Defines board version and sku id gpios + +compatible: cros-ec,gpio-id + +properties: + bits: + type: phandles + required: true + description: GPIO list to read, LSB to MSB + + system: + type: string + description: + Numeral system used to decode values + - binary - expects array with values of 0 and 1. + - binary_first_base3 - non-standard ternary number system + where the first 2^n natural numbers are represented as + they would be in a binary system (without any Z digits) + and the following 3^n-2^n numbers use the remaining + ternary representations in the normal ternary system order + - ternary - expects array with values of 0, 1 and 2. + It treats 'Z' state as digit '2'. + enum: + - binary + - binary_first_base3 + - ternary + diff --git a/zephyr/shim/src/CMakeLists.txt b/zephyr/shim/src/CMakeLists.txt index 5fee14dfbd..e9f6f55eab 100644 --- a/zephyr/shim/src/CMakeLists.txt +++ b/zephyr/shim/src/CMakeLists.txt @@ -5,6 +5,7 @@ zephyr_library_sources(console.c) zephyr_library_sources(crc.c) zephyr_library_sources(gpio.c) +zephyr_library_sources(gpio_id.c) zephyr_library_sources(util.c) if (DEFINED CONFIG_ARCH_POSIX) diff --git a/zephyr/shim/src/gpio_id.c b/zephyr/shim/src/gpio_id.c new file mode 100644 index 0000000000..f07ea8bd22 --- /dev/null +++ b/zephyr/shim/src/gpio_id.c @@ -0,0 +1,75 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <devicetree.h> +#include "gpio.h" +#include "util.h" + +#define IS_BOARD_COMPATIBLE \ + DT_NODE_HAS_COMPAT(DT_PATH(board), cros_ec_gpio_id) +#define IS_SKU_COMPATIBLE \ + DT_NODE_HAS_COMPAT(DT_PATH(sku), cros_ec_gpio_id) + +#define CONVERT_NUMERAL_SYSTEM_EVAL(system, bits, nbits) \ + system##_from_bits(bits, nbits) +#define CONVERT_NUMERAL_SYSTEM(system, bits, nbits) \ + CONVERT_NUMERAL_SYSTEM_EVAL(system, bits, nbits) + +#define READ_PIN_FROM_PHANDLE(node_id, prop, idx) \ + gpio_get_ternary(GPIO_SIGNAL(DT_PHANDLE_BY_IDX(node_id, prop, idx))), + +#if DT_NODE_EXISTS(DT_PATH(sku)) && IS_SKU_COMPATIBLE + +__override uint32_t board_get_sku_id(void) +{ + static uint32_t sku_id = (uint32_t)-1; + + if (sku_id == (uint32_t)-1) { + int bits[] = { + DT_FOREACH_PROP_ELEM(DT_PATH(sku), + bits, + READ_PIN_FROM_PHANDLE) + }; + + if (sizeof(bits) == 0) + return (uint32_t)-1; + + sku_id = CONVERT_NUMERAL_SYSTEM( + DT_ENUM_TOKEN(DT_PATH(sku), system), + bits, + ARRAY_SIZE(bits)); + } + + return sku_id; +} + +#endif + +#if DT_NODE_EXISTS(DT_PATH(board)) && IS_BOARD_COMPATIBLE + +__override int board_get_version(void) +{ + static int board_version = -1; + + if (board_version == -1) { + int bits[] = { + DT_FOREACH_PROP_ELEM(DT_PATH(board), + bits, + READ_PIN_FROM_PHANDLE) + }; + + if (sizeof(bits) == 0) + return -1; + + board_version = CONVERT_NUMERAL_SYSTEM( + DT_ENUM_TOKEN(DT_PATH(board), system), + bits, + ARRAY_SIZE(bits)); + } + + return board_version; +} + +#endif diff --git a/zephyr/shim/src/util.c b/zephyr/shim/src/util.c index 32f55e0581..af68838bec 100644 --- a/zephyr/shim/src/util.c +++ b/zephyr/shim/src/util.c @@ -329,3 +329,27 @@ int binary_first_base3_from_bits(int *bits, int nbits) /* binary_below is normal binary system value if !has_z. */ return binary_below; } + +int binary_from_bits(int *bits, int nbits) +{ + int value = 0; + int i; + + /* Loop through every binary digit, from MSB to LSB. */ + for (i = nbits - 1; i >= 0; i--) + value = (value << 1) | bits[i]; + + return value; +} + +int ternary_from_bits(int *bits, int nbits) +{ + int value = 0; + int i; + + /* Loop through every ternary digit, from MSB to LSB. */ + for (i = nbits - 1; i >= 0; i--) + value = (value * 3) + bits[i]; + + return value; +} |