2020-07-01 09:28:42 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
|
|
|
/*
|
|
|
|
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
|
|
|
|
*/
|
2023-05-10 15:55:50 +00:00
|
|
|
|
|
|
|
#include <linux/stddef.h>
|
|
|
|
#include <adc.h>
|
|
|
|
#include <asm/io.h>
|
|
|
|
#include <dm.h>
|
|
|
|
#include <env.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#define DTB_DIR "rockchip/"
|
|
|
|
|
|
|
|
struct oga_model {
|
|
|
|
const u16 adc_value;
|
|
|
|
const char *board;
|
|
|
|
const char *board_name;
|
|
|
|
const char *fdtfile;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum oga_device_id {
|
|
|
|
OGA,
|
|
|
|
OGA_V11,
|
|
|
|
OGS,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All ADC values from schematic of Odroid Go Advance Black Edition.
|
|
|
|
* Value for OGS is inferred based on schematic and observed values.
|
|
|
|
*/
|
|
|
|
static const struct oga_model oga_model_details[] = {
|
|
|
|
[OGA] = {
|
|
|
|
856,
|
|
|
|
"rk3326-odroid-go2",
|
|
|
|
"ODROID-GO Advance",
|
|
|
|
DTB_DIR "rk3326-odroid-go2.dtb",
|
|
|
|
},
|
|
|
|
[OGA_V11] = {
|
|
|
|
677,
|
|
|
|
"rk3326-odroid-go2-v11",
|
|
|
|
"ODROID-GO Advance Black Edition",
|
|
|
|
DTB_DIR "rk3326-odroid-go2-v11.dtb",
|
|
|
|
},
|
|
|
|
[OGS] = {
|
|
|
|
85,
|
|
|
|
"rk3326-odroid-go3",
|
|
|
|
"ODROID-GO Super",
|
|
|
|
DTB_DIR "rk3326-odroid-go3.dtb",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Detect which Odroid Go Advance device we are using so as to load the
|
|
|
|
* correct devicetree for Linux. Set an environment variable once
|
|
|
|
* found. The detection depends on the value of ADC channel 0.
|
|
|
|
*/
|
|
|
|
int oga_detect_device(void)
|
|
|
|
{
|
|
|
|
u32 adc_info;
|
|
|
|
int ret, i;
|
|
|
|
int board_id = -ENXIO;
|
|
|
|
|
|
|
|
ret = adc_channel_single_shot("saradc@ff288000", 0, &adc_info);
|
|
|
|
if (ret) {
|
|
|
|
printf("Read SARADC failed with error %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the correct device from the table. The ADC value is
|
|
|
|
* determined by a resistor on ADC channel 0. The manufacturer
|
|
|
|
* accounted for this with a 5% tolerance, so assume a +- value
|
|
|
|
* of 50 should be enough.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < ARRAY_SIZE(oga_model_details); i++) {
|
|
|
|
u32 adc_min = oga_model_details[i].adc_value - 50;
|
|
|
|
u32 adc_max = oga_model_details[i].adc_value + 50;
|
|
|
|
|
|
|
|
if (adc_min < adc_info && adc_max > adc_info) {
|
|
|
|
board_id = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (board_id < 0)
|
|
|
|
return board_id;
|
|
|
|
|
|
|
|
env_set("board", oga_model_details[board_id].board);
|
|
|
|
env_set("board_name",
|
|
|
|
oga_model_details[board_id].board_name);
|
|
|
|
env_set("fdtfile", oga_model_details[board_id].fdtfile);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int rk_board_late_init(void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = oga_detect_device();
|
|
|
|
if (ret) {
|
|
|
|
printf("Unable to detect device type: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|