1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
/* 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 "adc.h"
#include "common.h"
#include "console.h"
#include "gpio.h"
#include "hooks.h"
#include "timer.h"
#include "util.h"
/**
* Conversion based on following table:
*
* ID | Rp | Rd | Voltage
* | kOhm | kOhm | mV
* ---+------+------+--------
* 0 | 51.1 | 2.2 | 136.2
* 1 | 51.1 | 6.81 | 388.1
* 2 | 51.1 | 11 | 584.5
* 3 | 57.6 | 18 | 785.7
* 4 | 51.1 | 22 | 993.2
* 5 | 51.1 | 30 | 1220.7
* 6 | 51.1 | 39.2 | 1432.6
* 7 | 56 | 56 | 1650.0
* 8 | 47 | 61.9 | 1875.8
* 9 | 47 | 80.6 | 2084.5
* 10 | 56 | 124 | 2273.3
* 11 | 51.1 | 150 | 2461.5
* 12 | 47 | 200 | 2672.1
* 13 | 47 | 330 | 2888.6
* 14 | 47 | 680 | 3086.7
*/
const static int voltage_map[] = {
136, 388, 584, 785, 993, 1220, 1432, 1650,
1875, 2084, 2273, 2461, 2672, 2888, 3086,
};
const int threshold_mv = 100;
/**
* Convert ADC value to board id using the voltage table above.
*
* @param ch ADC channel to read, usually ADC_BOARD_ID_0 or ADC_BOARD_ID_1.
*
* @return a non-negative board id, or negative value if error.
*/
static int adc_value_to_numeric_id(enum adc_channel ch)
{
int mv;
gpio_set_level(GPIO_EN_EC_ID_ODL, 0);
/* Wait to allow cap charge */
msleep(10);
mv = adc_read_channel(ch);
if (mv == ADC_READ_ERROR)
mv = adc_read_channel(ch);
gpio_set_level(GPIO_EN_EC_ID_ODL, 1);
if (mv == ADC_READ_ERROR)
return -EC_ERROR_UNKNOWN;
for (int i = 0; i < ARRAY_SIZE(voltage_map); i++) {
if (IN_RANGE(mv, voltage_map[i] - threshold_mv,
voltage_map[i] + threshold_mv - 1))
return i;
}
return -EC_ERROR_UNKNOWN;
}
static int version = -1;
/* b/163963220: Cache ADC value before board_hibernate_late() reads it */
static void board_version_init(void)
{
version = adc_value_to_numeric_id(ADC_BOARD_ID);
if (version < 0) {
ccprints("WARN:BOARD_ID_0");
ccprints("Assuming board id = 0");
version = 0;
}
}
DECLARE_HOOK(HOOK_INIT, board_version_init, HOOK_PRIO_INIT_ADC + 1);
int board_get_version(void)
{
return version;
}
|