Julius Werner 2b23948535 gpio: Add support for binary_first base3 number system
This patch adds support for an alternative ternary number system in
which group of GPIOs can be interpreted. In this system, the digit
combinations that would form a binary number (i.e. that contain no 'Z'
state) are used to represent the lower values in the way they're used in
the normal binary system, and all the combinations that do contain a 'Z'
are used to represent values above those. We can use this for boards
that originally get strapped with binary board IDs but eventually
require more revisions than that representation allows. We can switch
their code to binary_first base3 and all old revisions with already
produced boards will still get read as the correct numbers.

Credit for the algorithm idea goes to Haran Talmon.

BRANCH=None
BUG=None
TEST=Stubbed out the actual GPIO reading and simulated all combinations
of 4 ternary digits for both number systems.

Change-Id: Ib5127656455f97f890ce2999ba5ac5f58a20cf93
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/14116
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2016-03-22 21:18:30 +01:00

88 lines
3.3 KiB
C

/*
* This file is part of the coreboot project.
*
* Copyright 2014 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __SRC_INCLUDE_GPIO_H__
#define __SRC_INCLUDE_GPIO_H__
#include <soc/gpio.h>
#include <types.h>
/* <soc/gpio.h> must typedef a gpio_t that fits in 32 bits. */
_Static_assert(sizeof(gpio_t) <= sizeof(u32), "gpio_t doesn't fit in lb_gpio");
/* The following functions must be implemented by SoC/board code. */
int gpio_get(gpio_t gpio);
void gpio_set(gpio_t gpio, int value);
void gpio_input_pulldown(gpio_t gpio);
void gpio_input_pullup(gpio_t gpio);
void gpio_input(gpio_t gpio);
void gpio_output(gpio_t gpio, int value);
int _gpio_base3_value(gpio_t gpio[], int num_gpio, int binary_first);
/*
* Read the value presented by the set of GPIOs, when each pin is interpreted
* as a base-2 digit (LOW = 0, HIGH = 1).
*
* gpio[]: pin positions to read. gpio[0] is less significant than gpio[1].
* num_gpio: number of pins to read.
*/
int gpio_base2_value(gpio_t gpio[], int num_gpio);
/*
* Read the value presented by the set of GPIOs, when each pin is interpreted
* as a base-3 digit (LOW = 0, HIGH = 1, Z/floating = 2).
* Example: X1 = Z, X2 = 1 -> gpio_base3_value({GPIO(X1), GPIO(X2)}) = 5
* BASE3() from <base3.h> can generate numbers to compare the result to.
*
* gpio[]: pin positions to read. gpio[0] is less significant than gpio[1].
* num_gpio: number of pins to read.
*/
static inline int gpio_base3_value(gpio_t gpio[], int num_gpio)
{
return _gpio_base3_value(gpio, num_gpio, 0);
}
/*
* Read the value presented by the set of GPIOs, when each pin is interpreted
* as a base-3 digit (LOW = 0, HIGH = 1, Z/floating = 2) in a 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 (skipping the values that were already used up).
* This is useful for boards which initially used a binary board ID and later
* decided to switch to tri-state after some revisions have already been built.
* Example: For num_gpio = 2 we get the following representation:
*
* Number X1 X0
* 0 0 0
* 1 0 1
* 2 1 0
* 3 1 1 // Start counting ternaries back at 0 after this
* 4 0 2 // Skipping 00 and 01 which are already used up
* 5 1 2 // Skipping 10 and 11 which are already used up
* 6 2 0
* 7 2 1
* 8 2 2
*
* gpio[]: pin positions to read. gpio[0] is less significant than gpio[1].
* num_gpio: number of pins to read.
*/
static inline int gpio_binary_first_base3_value(gpio_t gpio[], int num_gpio)
{
return _gpio_base3_value(gpio, num_gpio, 1);
}
#endif /* __SRC_INCLUDE_GPIO_H__ */