blob: a0338ead3b5ac8fe93b5012b4cebb21065583111 [file] [log] [blame]
Heiko Stuebnera9ca71e2020-07-01 11:28:42 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2019 Rockchip Electronics Co., Ltd
4 */
Chris Morgancb1a85e2023-05-10 10:55:50 -05005
6#include <linux/stddef.h>
7#include <adc.h>
8#include <asm/io.h>
9#include <dm.h>
10#include <env.h>
11#include <stdlib.h>
12
13#define DTB_DIR "rockchip/"
14
15struct oga_model {
16 const u16 adc_value;
17 const char *board;
18 const char *board_name;
19 const char *fdtfile;
20};
21
22enum oga_device_id {
23 OGA,
24 OGA_V11,
25 OGS,
26};
27
28/*
29 * All ADC values from schematic of Odroid Go Advance Black Edition.
30 * Value for OGS is inferred based on schematic and observed values.
31 */
32static const struct oga_model oga_model_details[] = {
33 [OGA] = {
34 856,
35 "rk3326-odroid-go2",
36 "ODROID-GO Advance",
37 DTB_DIR "rk3326-odroid-go2.dtb",
38 },
39 [OGA_V11] = {
40 677,
41 "rk3326-odroid-go2-v11",
42 "ODROID-GO Advance Black Edition",
43 DTB_DIR "rk3326-odroid-go2-v11.dtb",
44 },
45 [OGS] = {
46 85,
47 "rk3326-odroid-go3",
48 "ODROID-GO Super",
49 DTB_DIR "rk3326-odroid-go3.dtb",
50 },
51};
52
53/* Detect which Odroid Go Advance device we are using so as to load the
54 * correct devicetree for Linux. Set an environment variable once
55 * found. The detection depends on the value of ADC channel 0.
56 */
57int oga_detect_device(void)
58{
59 u32 adc_info;
60 int ret, i;
61 int board_id = -ENXIO;
62
63 ret = adc_channel_single_shot("saradc@ff288000", 0, &adc_info);
64 if (ret) {
65 printf("Read SARADC failed with error %d\n", ret);
66 return ret;
67 }
68
69 /*
70 * Get the correct device from the table. The ADC value is
71 * determined by a resistor on ADC channel 0. The manufacturer
72 * accounted for this with a 5% tolerance, so assume a +- value
73 * of 50 should be enough.
74 */
75 for (i = 0; i < ARRAY_SIZE(oga_model_details); i++) {
76 u32 adc_min = oga_model_details[i].adc_value - 50;
77 u32 adc_max = oga_model_details[i].adc_value + 50;
78
79 if (adc_min < adc_info && adc_max > adc_info) {
80 board_id = i;
81 break;
82 }
83 }
84
85 if (board_id < 0)
86 return board_id;
87
88 env_set("board", oga_model_details[board_id].board);
89 env_set("board_name",
90 oga_model_details[board_id].board_name);
91 env_set("fdtfile", oga_model_details[board_id].fdtfile);
92
93 return 0;
94}
95
96int rk_board_late_init(void)
97{
98 int ret;
99
100 ret = oga_detect_device();
101 if (ret) {
102 printf("Unable to detect device type: %d\n", ret);
103 return ret;
104 }
105
106 return 0;
107}