summaryrefslogtreecommitdiff
path: root/src/mainboard/google/gru/boardid.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainboard/google/gru/boardid.c')
-rw-r--r--src/mainboard/google/gru/boardid.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/mainboard/google/gru/boardid.c b/src/mainboard/google/gru/boardid.c
index f62fe97226..5f030adf01 100644
--- a/src/mainboard/google/gru/boardid.c
+++ b/src/mainboard/google/gru/boardid.c
@@ -16,9 +16,46 @@
#include <boardid.h>
#include <console/console.h>
#include <stdlib.h>
+#include <soc/saradc.h>
+
+/*
+ * This matches two Kevin prototypes, needs to be sorted out with HW engs to
+ * have more regular mapping between the voltage and board ID.
+ */
+static const int board_id_readings[] = { 42, 120 };
+
+/*
+ * The ADC produces a 10 bit value, the resistor accuracy is 1%, let's leave
+ * 2% room for error on both sides, total variation would be 4%, which is
+ * approximately 40 points with a 10 bit ADC. The hardware specification
+ * guarantees valid readings to be at least 64 bits (2^6) apart.
+ */
+#define ACCEPTABLE_DELTA (int)(1024 * .02)
uint8_t board_id(void)
{
+ static int cached_board_id = -1;
+ int i;
+ int adc_reading;
+
+ if (cached_board_id != -1)
+ return cached_board_id;
+
+ adc_reading = get_saradc_value(1);
+ for (i = 0; i < ARRAY_SIZE(board_id_readings); i++) {
+ int delta = board_id_readings[i] - adc_reading;
+
+ if ((delta < ACCEPTABLE_DELTA) && (delta > -ACCEPTABLE_DELTA)) {
+ printk(BIOS_DEBUG, "ADC reading %d, "
+ "expected value %d board ID %d\n",
+ adc_reading, delta + adc_reading, i);
+ cached_board_id = i;
+ return i;
+ }
+ }
+
+ printk(BIOS_ERR, "Unmatched ADC reading of %d, using Board ID of 0\n",
+ adc_reading);
return 0;
}