1 /*
2 * Copyright 2023 Cirrus Logic, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Charger APIs
10 */
11
12 #ifndef ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_
14
15 /**
16 * @brief Charger Interface
17 * @defgroup charger_interface Charger Interface
18 * @ingroup io_interfaces
19 * @{
20 */
21
22 #include <stdbool.h>
23 #include <stddef.h>
24 #include <stdint.h>
25
26 #include <zephyr/device.h>
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif /* __cplusplus */
31
32 /**
33 * @brief Runtime Dynamic Battery Parameters
34 */
35 enum charger_property {
36 /** Indicates if external supply is present for the charger. */
37 /** Value should be of type enum charger_online */
38 CHARGER_PROP_ONLINE = 0,
39 /** Reports whether or not a battery is present. */
40 /** Value should be of type bool*/
41 CHARGER_PROP_PRESENT,
42 /** Represents the charging status of the charger. */
43 /** Value should be of type enum charger_status */
44 CHARGER_PROP_STATUS,
45 /** Represents the charging algo type of the charger. */
46 /** Value should be of type enum charger_charge_type */
47 CHARGER_PROP_CHARGE_TYPE,
48 /** Represents the health of the charger. */
49 /** Value should be of type enum charger_health */
50 CHARGER_PROP_HEALTH,
51 /** Configuration of current sink used for charging in µA */
52 CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA,
53 /** Configuration of current sink used for conditioning in µA */
54 CHARGER_PROP_PRECHARGE_CURRENT_UA,
55 /** Configuration of charge termination target in µA */
56 CHARGER_PROP_CHARGE_TERM_CURRENT_UA,
57 /** Configuration of charge voltage regulation target in µV */
58 CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV,
59 /**
60 * Configuration of the input current regulation target in µA
61 *
62 * This value is a rising current threshold that is regulated by reducing the charge
63 * current output
64 */
65 CHARGER_PROP_INPUT_REGULATION_CURRENT_UA,
66 /**
67 * Configuration of the input voltage regulation target in µV
68 *
69 * This value is a falling voltage threshold that is regulated by reducing the charge
70 * current output
71 */
72 CHARGER_PROP_INPUT_REGULATION_VOLTAGE_UV,
73 /**
74 * Configuration to issue a notification to the system based on the input current
75 * level and timing
76 *
77 * Value should be of type struct charger_current_notifier
78 */
79 CHARGER_PROP_INPUT_CURRENT_NOTIFICATION,
80 /**
81 * Configuration to issue a notification to the system based on the battery discharge
82 * current level and timing
83 *
84 * Value should be of type struct charger_current_notifier
85 */
86 CHARGER_PROP_DISCHARGE_CURRENT_NOTIFICATION,
87 /**
88 * Configuration of the falling system voltage threshold where a notification
89 * is issued to the system, measured in µV
90 */
91 CHARGER_PROP_SYSTEM_VOLTAGE_NOTIFICATION_UV,
92 /**
93 * Configuration to issue a notification to the system based on the charger status change
94 *
95 * Value should be of type charger_status_notifier_t
96 */
97 CHARGER_PROP_STATUS_NOTIFICATION,
98 /**
99 * Configuration to issue a notification to the system based on the charger online change
100 *
101 * Value should be of type charger_online_notifier_t
102 */
103 CHARGER_PROP_ONLINE_NOTIFICATION,
104 /** Reserved to demark end of common charger properties */
105 CHARGER_PROP_COMMON_COUNT,
106 /**
107 * Reserved to demark downstream custom properties - use this value as the actual value may
108 * change over future versions of this API
109 */
110 CHARGER_PROP_CUSTOM_BEGIN = CHARGER_PROP_COMMON_COUNT + 1,
111 /** Reserved to demark end of valid enum properties */
112 CHARGER_PROP_MAX = UINT16_MAX,
113 };
114
115 /**
116 * @typedef charger_prop_t
117 * @brief A charger property's identifier
118 *
119 * See charger_property for a list of identifiers
120 */
121 typedef uint16_t charger_prop_t;
122
123 /**
124 * @brief External supply states
125 */
126 enum charger_online {
127 /** External supply not present */
128 CHARGER_ONLINE_OFFLINE = 0,
129 /** External supply is present and of fixed output */
130 CHARGER_ONLINE_FIXED,
131 /** External supply is present and of programmable output*/
132 CHARGER_ONLINE_PROGRAMMABLE,
133 };
134
135 /**
136 * @brief Charging states
137 */
138 enum charger_status {
139 /** Charging device state is unknown */
140 CHARGER_STATUS_UNKNOWN = 0,
141 /** Charging device is charging a battery */
142 CHARGER_STATUS_CHARGING,
143 /** Charging device is not able to charge a battery */
144 CHARGER_STATUS_DISCHARGING,
145 /** Charging device is not charging a battery */
146 CHARGER_STATUS_NOT_CHARGING,
147 /** The battery is full and the charging device will not attempt charging */
148 CHARGER_STATUS_FULL,
149 };
150
151 /**
152 * @brief Charge algorithm types
153 */
154 enum charger_charge_type {
155 /** Charge type is unknown */
156 CHARGER_CHARGE_TYPE_UNKNOWN = 0,
157 /** Charging is not occurring */
158 CHARGER_CHARGE_TYPE_NONE,
159 /**
160 * Charging is occurring at the slowest desired charge rate,
161 * typically for battery detection or preconditioning
162 */
163 CHARGER_CHARGE_TYPE_TRICKLE,
164 /** Charging is occurring at the fastest desired charge rate */
165 CHARGER_CHARGE_TYPE_FAST,
166 /** Charging is occurring at a moderate charge rate */
167 CHARGER_CHARGE_TYPE_STANDARD,
168 /*
169 * Charging is being dynamically adjusted by the charger device
170 */
171 CHARGER_CHARGE_TYPE_ADAPTIVE,
172 /*
173 * Charging is occurring at a reduced charge rate to preserve
174 * battery health
175 */
176 CHARGER_CHARGE_TYPE_LONGLIFE,
177 /*
178 * The charger device is being bypassed and the power conversion
179 * is being handled externally, typically by a "smart" wall adaptor
180 */
181 CHARGER_CHARGE_TYPE_BYPASS,
182 };
183
184 /**
185 * @brief Charger health conditions
186 *
187 * These conditions determine the ability to, or the rate of, charge
188 */
189 enum charger_health {
190 /** Charger health condition is unknown */
191 CHARGER_HEALTH_UNKNOWN = 0,
192 /** Charger health condition is good */
193 CHARGER_HEALTH_GOOD,
194 /** The charger device is overheated */
195 CHARGER_HEALTH_OVERHEAT,
196 /** The battery voltage has exceeded its overvoltage threshold */
197 CHARGER_HEALTH_OVERVOLTAGE,
198 /**
199 * The battery or charger device is experiencing an unspecified
200 * failure.
201 */
202 CHARGER_HEALTH_UNSPEC_FAILURE,
203 /** The battery temperature is below the "cold" threshold */
204 CHARGER_HEALTH_COLD,
205 /** The charger device's watchdog timer has expired */
206 CHARGER_HEALTH_WATCHDOG_TIMER_EXPIRE,
207 /** The charger device's safety timer has expired */
208 CHARGER_HEALTH_SAFETY_TIMER_EXPIRE,
209 /** The charger device requires calibration */
210 CHARGER_HEALTH_CALIBRATION_REQUIRED,
211 /** The battery temperature is in the "warm" range */
212 CHARGER_HEALTH_WARM,
213 /** The battery temperature is in the "cool" range */
214 CHARGER_HEALTH_COOL,
215 /** The battery temperature is below the "hot" threshold */
216 CHARGER_HEALTH_HOT,
217 /** The charger device does not detect a battery */
218 CHARGER_HEALTH_NO_BATTERY,
219 };
220
221 /**
222 * @brief Charger severity levels for system notifications
223 */
224 enum charger_notification_severity {
225 /** Most severe level, typically triggered instantaneously */
226 CHARGER_SEVERITY_PEAK = 0,
227 /** More severe than the warning level, less severe than peak */
228 CHARGER_SEVERITY_CRITICAL,
229 /** Base severity level */
230 CHARGER_SEVERITY_WARNING,
231 };
232
233 /**
234 * @brief The input current thresholds for the charger to notify the system
235 */
236 struct charger_current_notifier {
237 /** The severity of the notification where CHARGER_SEVERITY_PEAK is the most severe */
238 uint8_t severity;
239 /** The current threshold to be exceeded */
240 uint32_t current_ua;
241 /** The duration of excess current before notifying the system */
242 uint32_t duration_us;
243 };
244
245 /**
246 * @brief The charger status change callback to notify the system
247 *
248 * @param status Current charging state
249 */
250 typedef void (*charger_status_notifier_t)(enum charger_status status);
251
252 /**
253 * @brief The charger online change callback to notify the system
254 *
255 * @param online Current external supply state
256 */
257 typedef void (*charger_online_notifier_t)(enum charger_online online);
258
259 /**
260 * @brief container for a charger_property value
261 *
262 */
263 union charger_propval {
264 /* Fields have the format: */
265 /* CHARGER_PROPERTY_FIELD */
266 /* type property_field; */
267
268 /** CHARGER_PROP_ONLINE */
269 enum charger_online online;
270 /** CHARGER_PROP_PRESENT */
271 bool present;
272 /** CHARGER_PROP_STATUS */
273 enum charger_status status;
274 /** CHARGER_PROP_CHARGE_TYPE */
275 enum charger_charge_type charge_type;
276 /** CHARGER_PROP_HEALTH */
277 enum charger_health health;
278 /** CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA */
279 uint32_t const_charge_current_ua;
280 /** CHARGER_PROP_PRECHARGE_CURRENT_UA */
281 uint32_t precharge_current_ua;
282 /** CHARGER_PROP_CHARGE_TERM_CURRENT_UA */
283 uint32_t charge_term_current_ua;
284 /** CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV */
285 uint32_t const_charge_voltage_uv;
286 /** CHARGER_PROP_INPUT_REGULATION_CURRENT_UA */
287 uint32_t input_current_regulation_current_ua;
288 /** CHARGER_PROP_INPUT_REGULATION_VOLTAGE_UV */
289 uint32_t input_voltage_regulation_voltage_uv;
290 /** CHARGER_PROP_INPUT_CURRENT_NOTIFICATION */
291 struct charger_current_notifier input_current_notification;
292 /** CHARGER_PROP_DISCHARGE_CURRENT_NOTIFICATION */
293 struct charger_current_notifier discharge_current_notification;
294 /** CHARGER_PROP_SYSTEM_VOLTAGE_NOTIFICATION_UV */
295 uint32_t system_voltage_notification;
296 /** CHARGER_PROP_STATUS_NOTIFICATION */
297 charger_status_notifier_t status_notification;
298 /** CHARGER_PROP_ONLINE_NOTIFICATION */
299 charger_online_notifier_t online_notification;
300 };
301
302 /**
303 * @typedef charger_get_property_t
304 * @brief Callback API for getting a charger property.
305 *
306 * See charger_get_property() for argument description
307 */
308 typedef int (*charger_get_property_t)(const struct device *dev, const charger_prop_t prop,
309 union charger_propval *val);
310
311 /**
312 * @typedef charger_set_property_t
313 * @brief Callback API for setting a charger property.
314 *
315 * See charger_set_property() for argument description
316 */
317 typedef int (*charger_set_property_t)(const struct device *dev, const charger_prop_t prop,
318 const union charger_propval *val);
319
320 /**
321 * @typedef charger_charge_enable_t
322 * @brief Callback API enabling or disabling a charge cycle.
323 *
324 * See charger_charge_enable() for argument description
325 */
326 typedef int (*charger_charge_enable_t)(const struct device *dev, const bool enable);
327
328 /**
329 * @brief Charging device API
330 *
331 * Caching is entirely on the onus of the client
332 */
333 __subsystem struct charger_driver_api {
334 charger_get_property_t get_property;
335 charger_set_property_t set_property;
336 charger_charge_enable_t charge_enable;
337 };
338
339 /**
340 * @brief Fetch a battery charger property
341 *
342 * @param dev Pointer to the battery charger device
343 * @param prop Charger property to get
344 * @param val Pointer to charger_propval union
345 *
346 * @retval 0 if successful
347 * @retval < 0 if getting property failed
348 */
349 __syscall int charger_get_prop(const struct device *dev, const charger_prop_t prop,
350 union charger_propval *val);
351
z_impl_charger_get_prop(const struct device * dev,const charger_prop_t prop,union charger_propval * val)352 static inline int z_impl_charger_get_prop(const struct device *dev, const charger_prop_t prop,
353 union charger_propval *val)
354 {
355 const struct charger_driver_api *api = (const struct charger_driver_api *)dev->api;
356
357 return api->get_property(dev, prop, val);
358 }
359
360 /**
361 * @brief Set a battery charger property
362 *
363 * @param dev Pointer to the battery charger device
364 * @param prop Charger property to set
365 * @param val Pointer to charger_propval union
366 *
367 * @retval 0 if successful
368 * @retval < 0 if setting property failed
369 */
370 __syscall int charger_set_prop(const struct device *dev, const charger_prop_t prop,
371 const union charger_propval *val);
372
z_impl_charger_set_prop(const struct device * dev,const charger_prop_t prop,const union charger_propval * val)373 static inline int z_impl_charger_set_prop(const struct device *dev, const charger_prop_t prop,
374 const union charger_propval *val)
375 {
376 const struct charger_driver_api *api = (const struct charger_driver_api *)dev->api;
377
378 return api->set_property(dev, prop, val);
379 }
380
381 /**
382 * @brief Enable or disable a charge cycle
383 *
384 * @param dev Pointer to the battery charger device
385 * @param enable true enables a charge cycle, false disables a charge cycle
386 *
387 * @retval 0 if successful
388 * @retval -EIO if communication with the charger failed
389 * @retval -EINVAL if the conditions for initiating charging are invalid
390 */
391 __syscall int charger_charge_enable(const struct device *dev, const bool enable);
392
z_impl_charger_charge_enable(const struct device * dev,const bool enable)393 static inline int z_impl_charger_charge_enable(const struct device *dev, const bool enable)
394 {
395 const struct charger_driver_api *api = (const struct charger_driver_api *)dev->api;
396
397 return api->charge_enable(dev, enable);
398 }
399
400 /**
401 * @}
402 */
403
404 #ifdef __cplusplus
405 }
406 #endif /* __cplusplus */
407
408 #include <zephyr/syscalls/charger.h>
409
410 #endif /* ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_ */
411