summaryrefslogtreecommitdiffstats
path: root/src/mainboard/google/cherry/regulator.c
blob: 61f53d1eafbabb44c479eecbb1513e0a90d6f443 (plain)
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <ec/google/chromeec/ec.h>
#include <soc/mt6359p.h>
#include <soc/mt6360.h>
#include <soc/mt6691.h>
#include <soc/regulator.h>

#define MT6691_I2C_NUM	7

static int get_mt6360_regulator_id(enum mtk_regulator regulator)
{
	switch (regulator) {
	case MTK_REGULATOR_VDD2:
		return MT6360_BUCK1;
	case MTK_REGULATOR_VDDQ:
		return MT6360_BUCK2;
	case MTK_REGULATOR_VCC:
		return MT6360_LDO5;
	case MTK_REGULATOR_VCCQ:
		return MT6360_LDO3;
	default:
		break;
	}

	return -1;
}

static int get_mt6359p_regulator_id(enum mtk_regulator regulator)
{
	return regulator == MTK_REGULATOR_VCORE ? MT6359P_GPU11 : -1;
}

static int get_mt6691_regulator_id(enum mtk_regulator regulator)
{
	return regulator == MTK_REGULATOR_VMDDR ? MT6691_I2C_NUM : -1;
}

static int check_regulator_control(enum mtk_regulator regulator)
{
	/*
	 * MT6880 is not controlled by SW.
	 * No need to control it.
	 */
	if (regulator == MTK_REGULATOR_VDD1) {
		printk(BIOS_WARNING,
		       "[%d] MT6880 is not controlled by SW.\n", regulator);
		return -1;
	}
	return 0;
}

void mainboard_set_regulator_voltage(enum mtk_regulator regulator, uint32_t voltage_uv)
{
	if (check_regulator_control(regulator) < 0)
		return;

	int id;

	id = get_mt6360_regulator_id(regulator);
	if (id >= 0) {
		if (CONFIG(BOARD_GOOGLE_CHERRY)) {
			mt6360_set_voltage(id, voltage_uv);
		} else {
			uint32_t voltage_mv = voltage_uv / 1000;
			if (google_chromeec_regulator_set_voltage(id, voltage_mv,
								  voltage_mv) < 0) {
				printk(BIOS_WARNING,
				       "Failed to set voltage by ec: %d\n", regulator);
			}
		}
		return;
	}

	id = get_mt6359p_regulator_id(regulator);
	if (id >= 0) {
		mt6359p_buck_set_voltage(id, voltage_uv);
		return;
	}

	id = get_mt6691_regulator_id(regulator);
	if (id >= 0) {
		mt6691_set_voltage(id, voltage_uv);
		return;
	}

	printk(BIOS_ERR, "Invalid regulator ID: %d\n", regulator);
}

uint32_t mainboard_get_regulator_voltage(enum mtk_regulator regulator)
{
	if (check_regulator_control(regulator) < 0)
		return 0;

	int id;

	id = get_mt6360_regulator_id(regulator);
	if (id >= 0) {
		if (CONFIG(BOARD_GOOGLE_CHERRY)) {
			return mt6360_get_voltage(id);
		} else {
			uint32_t voltage_mv = 0;
			if (google_chromeec_regulator_get_voltage(id, &voltage_mv) < 0) {
				printk(BIOS_WARNING,
				       "Failed to get voltage by ec: %d\n", regulator);
				return 0;
			}
			return voltage_mv * 1000;
		}
	}

	id = get_mt6359p_regulator_id(regulator);
	if (id >= 0)
		return mt6359p_buck_get_voltage(id);

	id = get_mt6691_regulator_id(regulator);
	if (id >= 0)
		return mt6691_get_voltage(id);

	printk(BIOS_ERR, "Invalid regulator ID: %d\n", regulator);

	return 0;
}

int mainboard_enable_regulator(enum mtk_regulator regulator, bool enable)
{
	if (check_regulator_control(regulator) < 0)
		return 0;

	/* Return 0 if the regulator is already enabled or disabled. */
	if (mainboard_regulator_is_enabled(regulator) == enable)
		return 0;

	int id;

	id = get_mt6360_regulator_id(regulator);
	if (id >= 0) {
		if (CONFIG(BOARD_GOOGLE_CHERRY)) {
			mt6360_enable(id, enable);
			return 0;
		} else {
			if (google_chromeec_regulator_enable(id, enable) < 0) {
				printk(BIOS_WARNING,
				       "Failed to enable regulator by ec: %d\n", regulator);
				return -1;
			}
			return 0;
		}
	}

	printk(BIOS_ERR, "Invalid regulator ID: %d\n", regulator);

	return -1;
}

bool mainboard_regulator_is_enabled(enum mtk_regulator regulator)
{
	if (check_regulator_control(regulator) < 0)
		return false;

	int id;

	id = get_mt6360_regulator_id(regulator);
	if (id >= 0) {
		if (CONFIG(BOARD_GOOGLE_CHERRY)) {
			return !!mt6360_is_enabled(id);
		} else {
			uint8_t enabled;
			if (google_chromeec_regulator_is_enabled(id, &enabled) < 0) {
				printk(BIOS_WARNING,
				       "Failed to retrieve is_enabled by ec; assuming disabled\n");
				return 0;
			}
			return !!enabled;
		}

	}

	printk(BIOS_ERR, "Invalid regulator ID: %d\n; assuming disabled", regulator);

	return false;
}