summaryrefslogtreecommitdiff
path: root/include/charge_manager.h
blob: 2a3ca27d741400dd4752eb0d36a222f926a1a1e2 (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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/* Copyright 2014 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.
 */

#ifndef __CROS_EC_CHARGE_MANAGER_H
#define __CROS_EC_CHARGE_MANAGER_H

#include "common.h"
#include "ec_commands.h"

/* Charge port that indicates no active port */
#define CHARGE_PORT_NONE -1
#define CHARGE_CEIL_NONE -1

/* Initial charge state */
#define CHARGE_CURRENT_UNINITIALIZED -1
#define CHARGE_VOLTAGE_UNINITIALIZED -1

/* Only track BC1.2 charge current if we support BC1.2 charging */
#if defined(HAS_TASK_USB_CHG) || defined(HAS_TASK_USB_CHG_P0) || \
defined(TEST_BUILD)
#define CHARGE_MANAGER_BC12
#endif

/**
 * Time to delay for detecting the charger type (must be long enough for BC1.2
 * driver to get supplier information and notify charge manager).
 */
#define CHARGE_DETECT_DELAY (2*SECOND)

/* Commonly-used charge suppliers listed in no particular order */
enum charge_supplier {
	CHARGE_SUPPLIER_NONE = -1,
	CHARGE_SUPPLIER_PD,
	CHARGE_SUPPLIER_TYPEC,
	CHARGE_SUPPLIER_TYPEC_DTS,
#ifdef CHARGE_MANAGER_BC12
	CHARGE_SUPPLIER_BC12_DCP,
	CHARGE_SUPPLIER_BC12_CDP,
	CHARGE_SUPPLIER_BC12_SDP,
	CHARGE_SUPPLIER_PROPRIETARY,
	CHARGE_SUPPLIER_TYPEC_UNDER_1_5A,
	CHARGE_SUPPLIER_OTHER,
	CHARGE_SUPPLIER_VBUS,
#endif /* CHARGE_MANAGER_BC12 */
#if CONFIG_DEDICATED_CHARGE_PORT_COUNT > 0
	CHARGE_SUPPLIER_DEDICATED,
#endif
#ifdef CONFIG_WIRELESS_CHARGER_P9221_R7
	CHARGE_SUPPLIER_WPC_BPP,
	CHARGE_SUPPLIER_WPC_EPP,
	CHARGE_SUPPLIER_WPC_GPP,
#endif
	CHARGE_SUPPLIER_COUNT
};

/*
 * Charge supplier priority: lower number indicates higher priority.
 * Default priority is in charge_manager.c. It can be overridden by boards.
 */
extern const int supplier_priority[];

/* Charge tasks report available current and voltage */
struct charge_port_info {
	int current;
	int voltage;
};

/**
 * Called by charging tasks to update their available charge.
 *
 * @param supplier	Charge supplier to update.
 * @param port		Charge port to update.
 * @param charge	Charge port current / voltage. If NULL, current = 0
 * 			voltage = 0 will be used.
 */
void charge_manager_update_charge(int supplier,
				  int port,
				  const struct charge_port_info *charge);

/* Partner port dualrole capabilities */
enum dualrole_capabilities {
	CAP_UNKNOWN,
	CAP_DUALROLE,
	CAP_DEDICATED,
};

/**
 * Notify charge_manager of a partner dualrole capability change.
 *
 * @param port			Charge port which changed.
 * @param cap			New port capability.
 */
void charge_manager_update_dualrole(int port, enum dualrole_capabilities cap);

/**
 * Tell charge_manager to leave safe mode and switch to standard port / ILIM
 * selection logic.
 */
void charge_manager_leave_safe_mode(void);

/**
 * Charge ceiling can be set independently by different tasks / functions,
 * for different purposes.
 */
enum ceil_requestor {
	/* Set by PD task, during negotiation */
	CEIL_REQUESTOR_PD,
	/* Set by host commands */
	CEIL_REQUESTOR_HOST,
	/* Number of ceiling groups */
	CEIL_REQUESTOR_COUNT,
};

#define CHARGE_PORT_COUNT (CONFIG_USB_PD_PORT_MAX_COUNT + \
			   CONFIG_DEDICATED_CHARGE_PORT_COUNT)
#if (CONFIG_DEDICATED_CHARGE_PORT_COUNT > 0)

/**
 * By default, dedicated port has following properties:
 *
 * - dedicated port is sink only.
 * - dedicated port is always connected.
 * - dedicated port is given highest priority (supplier type is always
 *   CHARGE_SUPPLIER_DEDICATED).
 * - dualrole capability of dedicated port is always CAP_DEDICATED.
 * - there's only one dedicated port, its number is larger than PD port number.
 *
 * Sink property can be customized by implementing board_charge_port_is_sink()
 * and board_fill_source_power_info().
 * Connected can be customized by implementing board_charge_port_is_connected().
 */
#if !defined(DEDICATED_CHARGE_PORT)
#error "DEDICATED_CHARGE_PORT must be defined"
#elif DEDICATED_CHARGE_PORT < CONFIG_USB_PD_PORT_MAX_COUNT
#error "DEDICATED_CHARGE_PORT must larger than pd port numbers"
#endif /* !defined(DEDICATED_CHARGE_PORT) */

#endif /* CONFIG_DEDICATED_CHARGE_PORT_COUNT > 0 */

/**
 * Update charge ceiling for a given port. The ceiling can be set independently
 * for several requestors, and the min. ceil will be enforced.
 *
 * @param port			Charge port to update.
 * @param requestor		Charge ceiling requestor.
 * @param ceil			Charge ceiling (mA).
 */
void charge_manager_set_ceil(int port, enum ceil_requestor requestor, int ceil);

/*
 * Update PD charge ceiling for a given port. In the event that our ceiling
 * is currently above ceil, change the current limit before returning, without
 * waiting for a charge manager refresh. This function should only be used in
 * time-critical situations where we absolutely cannot proceed without limiting
 * our input current, and it should only be called from the PD tasks.
 * If you ever call this function then you are a terrible person.
 */
void charge_manager_force_ceil(int port, int ceil);

/**
 * Select an 'override port', a port which is always the preferred charge port.
 *
 * @param port			Charge port to select as override, or
 *				OVERRIDE_OFF to select no override port,
 *				or OVERRIDE_DONT_CHARGE to specific that no
 *				charge port should be selected.
 * @return			EC_SUCCESS on success,
 *				the other ec_error_list status on failure.
 */
int charge_manager_set_override(int port);

/**
 * Get the override port.
 *
 * @return	Port number or OVERRIDE_OFF or OVERRIDE_DONT_CHARGE.
 */
int charge_manager_get_override(void);

/**
 * Get the current active charge port, as determined by charge manager.
 *
 * @return	Current active charge port.
 */
int charge_manager_get_active_charge_port(void);

/**
 * Get the power limit set by charge manager.
 *
 * @return	Power limit (uW).
 */
int charge_manager_get_power_limit_uw(void);

/**
 * Get the charger current (mA) value.
 *
 * @return	Charger current (mA) or CHARGE_CURRENT_UNINITIALIZED.
 */
int charge_manager_get_charger_current(void);

/**
 * Get the charger voltage (mV) value.
 *
 * @return	Charger voltage (mV) or CHARGE_VOLTAGE_UNINITIALIZED.
 */
int charge_manager_get_charger_voltage(void);

#ifdef CONFIG_USB_PD_LOGGING
/* Save power state log entry for the given port */
void charge_manager_save_log(int port);
#endif

/**
 * Update whether a given port is sourcing current.
 *
 * @param port		Port number to be updated.
 * @param enable	0 if the source port is disabled;
 *			Otherwise the source port is enabled.
 */
void charge_manager_source_port(int port, int enable);

/**
 * Get PD source power data objects.
 *
 * @param src_pdo	Pointer to the data to return.
 * @param port		Current port to evaluate against.
 * @return number of PDOs returned.
 */
int charge_manager_get_source_pdo(const uint32_t **src_pdo, const int port);

/* Board-level callback functions */

/**
 * Set the passed charge port as active.`
 *
 * @param charge_port	Charge port to be enabled.
 * @return		EC_SUCCESS if the charge port is accepted,
 *			other ec_error_list status otherwise.
 */
int board_set_active_charge_port(int charge_port);

/**
 * Set the charge current limit.
 *
 * @param port PD port.
 * @param supplier Identified CHARGE_SUPPLIER_*.
 * @param charge_ma Desired charge current limit, <= max_ma.
 * @param max_ma Maximum charge current limit, >= charge_ma.
 * @param charge_mv Negotiated charge voltage (mV).
 */
void board_set_charge_limit(int port, int supplier, int charge_ma,
			    int max_ma, int charge_mv);

/**
 * Get whether the port is sourcing power on VBUS.
 *
 * @param port PD port.
 * @return VBUS power state.
 */
int board_vbus_source_enabled(int port);

#ifdef CONFIG_USB_PD_VBUS_MEASURE_ADC_EACH_PORT
/**
 * Gets the adc_channel for the specified port.
 *
 * @param port PD port.
 * @return adc_channel that measures the Vbus voltage.
 */
enum adc_channel board_get_vbus_adc(int port);
#endif /* CONFIG_USB_PD_VBUS_MEASURE_ADC_EACH_PORT */

/**
 * Board specific callback to check if the given port is sink.
 *
 * @param port	Dedicated charge port.
 * @return 1 if the port is sink.
 */
__override_proto int board_charge_port_is_sink(int port);

/**
 * Board specific callback to check if the given port is connected.
 *
 * @param port	Dedicated charge port.
 * @return 1 if the port is connected.
 */
__override_proto int board_charge_port_is_connected(int port);

/**
 * Board specific callback to fill passed power_info structure with current info
 * about the passed dedicate port.
 * This function is responsible for filling r->meas.* and r->max_power.
 *
 * @param port	Dedicated charge port.
 * @param r	USB PD power info to be updated.
 */
__override_proto
void board_fill_source_power_info(int port,
				  struct ec_response_usb_pd_power_info *r);

#endif /* __CROS_EC_CHARGE_MANAGER_H */