Line data Source code
1 0 : /*
2 : * Copyright 2022 Google LLC
3 : * Copyright 2023 Microsoft Corporation
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 :
8 : #ifndef ZEPHYR_INCLUDE_DRIVERS_BATTERY_H_
9 : #define ZEPHYR_INCLUDE_DRIVERS_BATTERY_H_
10 :
11 : /**
12 : * @brief Fuel Gauge Interface
13 : * @defgroup fuel_gauge_interface Fuel Gauge Interface
14 : * @since 3.3
15 : * @version 0.1.0
16 : * @ingroup io_interfaces
17 : * @{
18 : */
19 :
20 : #ifdef __cplusplus
21 : extern "C" {
22 : #endif /* __cplusplus */
23 :
24 : #include <errno.h>
25 : #include <stdbool.h>
26 : #include <stddef.h>
27 : #include <stdint.h>
28 :
29 : #include <zephyr/device.h>
30 :
31 0 : enum fuel_gauge_prop_type {
32 : /** Runtime Dynamic Battery Parameters */
33 : /**
34 : * Provide a 1 minute average of the current on the battery.
35 : * Does not check for flags or whether those values are bad readings.
36 : * See driver instance header for details on implementation and
37 : * how the average is calculated. Units in uA negative=discharging
38 : */
39 : FUEL_GAUGE_AVG_CURRENT = 0,
40 :
41 : /** Used to cutoff the battery from the system - useful for storage/shipping of devices */
42 : FUEL_GAUGE_BATTERY_CUTOFF,
43 : /** Battery current (uA); negative=discharging */
44 : FUEL_GAUGE_CURRENT,
45 : /** Whether the battery underlying the fuel-gauge is cut off from charge */
46 : FUEL_GAUGE_CHARGE_CUTOFF,
47 : /** Cycle count in 1/100ths (number of charge/discharge cycles) */
48 : FUEL_GAUGE_CYCLE_COUNT,
49 : /** Connect state of battery */
50 : FUEL_GAUGE_CONNECT_STATE,
51 : /** General Error/Runtime Flags */
52 : FUEL_GAUGE_FLAGS,
53 : /** Full Charge Capacity in uAh (might change in some implementations to determine wear) */
54 : FUEL_GAUGE_FULL_CHARGE_CAPACITY,
55 : /** Is the battery physically present */
56 : FUEL_GAUGE_PRESENT_STATE,
57 : /** Remaining capacity in uAh */
58 : FUEL_GAUGE_REMAINING_CAPACITY,
59 : /** Remaining battery life time in minutes */
60 : FUEL_GAUGE_RUNTIME_TO_EMPTY,
61 : /** Remaining time in minutes until battery reaches full charge */
62 : FUEL_GAUGE_RUNTIME_TO_FULL,
63 : /** Retrieve word from SBS1.1 ManufactuerAccess */
64 : FUEL_GAUGE_SBS_MFR_ACCESS,
65 : /** Absolute state of charge (percent, 0-100) - expressed as % of design capacity */
66 : FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE,
67 : /** Relative state of charge (percent, 0-100) - expressed as % of full charge capacity */
68 : FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
69 : /** Temperature in 0.1 K */
70 : FUEL_GAUGE_TEMPERATURE,
71 : /** Battery voltage (uV) */
72 : FUEL_GAUGE_VOLTAGE,
73 : /** Battery Mode (flags) */
74 : FUEL_GAUGE_SBS_MODE,
75 : /** Battery desired Max Charging Current (uA) */
76 : FUEL_GAUGE_CHARGE_CURRENT,
77 : /** Battery desired Max Charging Voltage (uV) */
78 : FUEL_GAUGE_CHARGE_VOLTAGE,
79 : /** Alarm, Status and Error codes (flags) */
80 : FUEL_GAUGE_STATUS,
81 : /** Design Capacity (mAh or 10mWh) */
82 : FUEL_GAUGE_DESIGN_CAPACITY,
83 : /** Design Voltage (mV) */
84 : FUEL_GAUGE_DESIGN_VOLTAGE,
85 : /** AtRate (mA or 10 mW) */
86 : FUEL_GAUGE_SBS_ATRATE,
87 : /** AtRateTimeToFull (minutes) */
88 : FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL,
89 : /** AtRateTimeToEmpty (minutes) */
90 : FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY,
91 : /** AtRateOK (boolean) */
92 : FUEL_GAUGE_SBS_ATRATE_OK,
93 : /** Remaining Capacity Alarm (mAh or 10mWh) */
94 : FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM,
95 : /** Remaining Time Alarm (minutes) */
96 : FUEL_GAUGE_SBS_REMAINING_TIME_ALARM,
97 : /** Manufacturer of pack (1 byte length + 20 bytes data) */
98 : FUEL_GAUGE_MANUFACTURER_NAME,
99 : /** Name of pack (1 byte length + 20 bytes data) */
100 : FUEL_GAUGE_DEVICE_NAME,
101 : /** Chemistry (1 byte length + 4 bytes data) */
102 : FUEL_GAUGE_DEVICE_CHEMISTRY,
103 :
104 : /** Reserved to demark end of common fuel gauge properties */
105 : FUEL_GAUGE_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 : FUEL_GAUGE_CUSTOM_BEGIN,
111 :
112 : /** Reserved to demark end of valid enum properties */
113 : FUEL_GAUGE_PROP_MAX = UINT16_MAX,
114 : };
115 :
116 0 : typedef uint16_t fuel_gauge_prop_t;
117 :
118 : /** Property field to value/type union */
119 1 : union fuel_gauge_prop_val {
120 : /* Fields have the format: */
121 : /* FUEL_GAUGE_PROPERTY_FIELD */
122 : /* type property_field; */
123 :
124 : /* Dynamic Battery Info */
125 : /** FUEL_GAUGE_AVG_CURRENT */
126 1 : int avg_current;
127 : /** FUEL_GAUGE_CHARGE_CUTOFF */
128 1 : bool cutoff;
129 : /** FUEL_GAUGE_CURRENT */
130 1 : int current;
131 : /** FUEL_GAUGE_CYCLE_COUNT */
132 1 : uint32_t cycle_count;
133 : /** FUEL_GAUGE_FLAGS */
134 1 : uint32_t flags;
135 : /** FUEL_GAUGE_FULL_CHARGE_CAPACITY */
136 1 : uint32_t full_charge_capacity;
137 : /** FUEL_GAUGE_REMAINING_CAPACITY */
138 1 : uint32_t remaining_capacity;
139 : /** FUEL_GAUGE_RUNTIME_TO_EMPTY */
140 1 : uint32_t runtime_to_empty;
141 : /** FUEL_GAUGE_RUNTIME_TO_FULL */
142 1 : uint32_t runtime_to_full;
143 : /** FUEL_GAUGE_SBS_MFR_ACCESS */
144 1 : uint16_t sbs_mfr_access_word;
145 : /** FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE */
146 1 : uint8_t absolute_state_of_charge;
147 : /** FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE */
148 1 : uint8_t relative_state_of_charge;
149 : /** FUEL_GAUGE_TEMPERATURE */
150 1 : uint16_t temperature;
151 : /** FUEL_GAUGE_VOLTAGE */
152 1 : int voltage;
153 : /** FUEL_GAUGE_SBS_MODE */
154 1 : uint16_t sbs_mode;
155 : /** FUEL_GAUGE_CHARGE_CURRENT */
156 1 : uint32_t chg_current;
157 : /** FUEL_GAUGE_CHARGE_VOLTAGE */
158 1 : uint32_t chg_voltage;
159 : /** FUEL_GAUGE_STATUS */
160 1 : uint16_t fg_status;
161 : /** FUEL_GAUGE_DESIGN_CAPACITY */
162 1 : uint16_t design_cap;
163 : /** FUEL_GAUGE_DESIGN_VOLTAGE */
164 1 : uint16_t design_volt;
165 : /** FUEL_GAUGE_SBS_ATRATE */
166 1 : int16_t sbs_at_rate;
167 : /** FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL */
168 1 : uint16_t sbs_at_rate_time_to_full;
169 : /** FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY */
170 1 : uint16_t sbs_at_rate_time_to_empty;
171 : /** FUEL_GAUGE_SBS_ATRATE_OK */
172 1 : bool sbs_at_rate_ok;
173 : /** FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM */
174 1 : uint16_t sbs_remaining_capacity_alarm;
175 : /** FUEL_GAUGE_SBS_REMAINING_TIME_ALARM */
176 1 : uint16_t sbs_remaining_time_alarm;
177 : };
178 :
179 : /**
180 : * Data structures for reading SBS buffer properties
181 : */
182 1 : #define SBS_GAUGE_MANUFACTURER_NAME_MAX_SIZE 20
183 0 : #define SBS_GAUGE_DEVICE_NAME_MAX_SIZE 20
184 0 : #define SBS_GAUGE_DEVICE_CHEMISTRY_MAX_SIZE 4
185 :
186 0 : struct sbs_gauge_manufacturer_name {
187 0 : uint8_t manufacturer_name_length;
188 0 : char manufacturer_name[SBS_GAUGE_MANUFACTURER_NAME_MAX_SIZE];
189 : } __packed;
190 :
191 0 : struct sbs_gauge_device_name {
192 0 : uint8_t device_name_length;
193 0 : char device_name[SBS_GAUGE_DEVICE_NAME_MAX_SIZE];
194 : } __packed;
195 :
196 0 : struct sbs_gauge_device_chemistry {
197 0 : uint8_t device_chemistry_length;
198 0 : char device_chemistry[SBS_GAUGE_DEVICE_CHEMISTRY_MAX_SIZE];
199 : } __packed;
200 :
201 : /**
202 : * @typedef fuel_gauge_get_property_t
203 : * @brief Callback API for getting a fuel_gauge property.
204 : *
205 : * See fuel_gauge_get_property() for argument description
206 : */
207 1 : typedef int (*fuel_gauge_get_property_t)(const struct device *dev, fuel_gauge_prop_t prop,
208 : union fuel_gauge_prop_val *val);
209 :
210 : /**
211 : * @typedef fuel_gauge_set_property_t
212 : * @brief Callback API for setting a fuel_gauge property.
213 : *
214 : * See fuel_gauge_set_property() for argument description
215 : */
216 1 : typedef int (*fuel_gauge_set_property_t)(const struct device *dev, fuel_gauge_prop_t prop,
217 : union fuel_gauge_prop_val val);
218 :
219 : /**
220 : * @typedef fuel_gauge_get_buffer_property_t
221 : * @brief Callback API for getting a fuel_gauge buffer property.
222 : *
223 : * See fuel_gauge_get_buffer_property() for argument description
224 : */
225 1 : typedef int (*fuel_gauge_get_buffer_property_t)(const struct device *dev,
226 : fuel_gauge_prop_t prop_type,
227 : void *dst, size_t dst_len);
228 :
229 : /**
230 : * @typedef fuel_gauge_battery_cutoff_t
231 : * @brief Callback API for doing a battery cutoff.
232 : *
233 : * See fuel_gauge_battery_cutoff() for argument description
234 : */
235 1 : typedef int (*fuel_gauge_battery_cutoff_t)(const struct device *dev);
236 :
237 : /* Caching is entirely on the onus of the client */
238 :
239 0 : __subsystem struct fuel_gauge_driver_api {
240 : /**
241 : * Note: Historically this API allowed drivers to implement a custom multi-get/set property
242 : * function, this was added so drivers could potentially optimize batch read with their
243 : * specific chip. However, it was removed because of no existing concrete case upstream.
244 : * If this need is demonstrated, we can add this back in as an API field.
245 : */
246 1 : fuel_gauge_get_property_t get_property;
247 0 : fuel_gauge_set_property_t set_property;
248 0 : fuel_gauge_get_buffer_property_t get_buffer_property;
249 0 : fuel_gauge_battery_cutoff_t battery_cutoff;
250 : };
251 :
252 : /**
253 : * @brief Fetch a battery fuel-gauge property
254 : *
255 : * @param dev Pointer to the battery fuel-gauge device
256 : * @param prop Type of property to be fetched from device
257 : * @param val pointer to a union fuel_gauge_prop_val where the property is read into from the
258 : * fuel gauge device.
259 : * @return 0 if successful, negative errno code if failure.
260 : */
261 1 : __syscall int fuel_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
262 : union fuel_gauge_prop_val *val);
263 :
264 : static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
265 : union fuel_gauge_prop_val *val)
266 : {
267 : const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api;
268 :
269 : if (api->get_property == NULL) {
270 : return -ENOSYS;
271 : }
272 :
273 : return api->get_property(dev, prop, val);
274 : }
275 :
276 : /**
277 : * @brief Fetch multiple battery fuel-gauge properties. The default implementation is the same as
278 : * calling fuel_gauge_get_prop() multiple times. A driver may implement the `get_properties` field
279 : * of the fuel gauge driver APIs struct to override this implementation.
280 : *
281 : * @param dev Pointer to the battery fuel-gauge device
282 : * @param props Array of the type of property to be fetched from device, each index corresponds
283 : * to the same index of the vals input array.
284 : * @param vals Pointer to array of union fuel_gauge_prop_val where the property is read into from
285 : * the fuel gauge device. The vals array is not permuted.
286 : * @param len number of properties in props & vals array
287 : *
288 : * @return 0 if successful, negative errno code of first failing property
289 : */
290 :
291 1 : __syscall int fuel_gauge_get_props(const struct device *dev, fuel_gauge_prop_t *props,
292 : union fuel_gauge_prop_val *vals, size_t len);
293 : static inline int z_impl_fuel_gauge_get_props(const struct device *dev,
294 : fuel_gauge_prop_t *props,
295 : union fuel_gauge_prop_val *vals, size_t len)
296 : {
297 : const struct fuel_gauge_driver_api *api = dev->api;
298 :
299 : for (int i = 0; i < len; i++) {
300 : int ret = api->get_property(dev, props[i], vals + i);
301 :
302 : if (ret) {
303 : return ret;
304 : }
305 : }
306 :
307 : return 0;
308 : }
309 :
310 : /**
311 : * @brief Set a battery fuel-gauge property
312 : *
313 : * @param dev Pointer to the battery fuel-gauge device
314 : * @param prop Type of property that's being set
315 : * @param val Value to set associated prop property.
316 : *
317 : * @return 0 if successful, negative errno code of first failing property
318 : */
319 1 : __syscall int fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop,
320 : union fuel_gauge_prop_val val);
321 :
322 : static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop,
323 : union fuel_gauge_prop_val val)
324 : {
325 : const struct fuel_gauge_driver_api *api = dev->api;
326 :
327 : if (api->set_property == NULL) {
328 : return -ENOSYS;
329 : }
330 :
331 : return api->set_property(dev, prop, val);
332 : }
333 : /**
334 : * @brief Set a battery fuel-gauge property
335 : *
336 : * @param dev Pointer to the battery fuel-gauge device
337 : * @param props Array of the type of property to be set, each index corresponds
338 : * to the same index of the vals input array.
339 : * @param vals Pointer to array of union fuel_gauge_prop_val where the property is written
340 : * the fuel gauge device. The vals array is not permuted.
341 : * @param len number of properties in props array
342 : *
343 : * @return return=0 if successful. Otherwise, return array index of failing property.
344 : */
345 1 : __syscall int fuel_gauge_set_props(const struct device *dev, fuel_gauge_prop_t *props,
346 : union fuel_gauge_prop_val *vals, size_t len);
347 :
348 : static inline int z_impl_fuel_gauge_set_props(const struct device *dev,
349 : fuel_gauge_prop_t *props,
350 : union fuel_gauge_prop_val *vals, size_t len)
351 : {
352 : for (int i = 0; i < len; i++) {
353 : int ret = fuel_gauge_set_prop(dev, props[i], vals[i]);
354 :
355 : if (ret) {
356 : return ret;
357 : }
358 : }
359 :
360 : return 0;
361 : }
362 :
363 : /**
364 : * @brief Fetch a battery fuel-gauge buffer property
365 : *
366 : * @param dev Pointer to the battery fuel-gauge device
367 : * @param prop_type Type of property to be fetched from device
368 : * @param dst byte array or struct that will hold the buffer data that is read from the fuel gauge
369 : * @param dst_len the length of the destination array in bytes
370 : *
371 : * @return return=0 if successful, return < 0 if getting property failed, return 0 on success
372 : */
373 :
374 1 : __syscall int fuel_gauge_get_buffer_prop(const struct device *dev, fuel_gauge_prop_t prop_type,
375 : void *dst, size_t dst_len);
376 :
377 : static inline int z_impl_fuel_gauge_get_buffer_prop(const struct device *dev,
378 : fuel_gauge_prop_t prop_type,
379 : void *dst, size_t dst_len)
380 : {
381 : const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api;
382 :
383 : if (api->get_buffer_property == NULL) {
384 : return -ENOSYS;
385 : }
386 :
387 : return api->get_buffer_property(dev, prop_type, dst, dst_len);
388 : }
389 :
390 : /**
391 : * @brief Have fuel gauge cutoff its associated battery.
392 : *
393 : * @param dev Pointer to the battery fuel-gauge device
394 : *
395 : * @return return=0 if successful and battery cutoff is now in process, return < 0 if failed to do
396 : * battery cutoff.
397 : */
398 1 : __syscall int fuel_gauge_battery_cutoff(const struct device *dev);
399 :
400 : static inline int z_impl_fuel_gauge_battery_cutoff(const struct device *dev)
401 : {
402 : const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api;
403 :
404 : if (api->battery_cutoff == NULL) {
405 : return -ENOSYS;
406 : }
407 :
408 : return api->battery_cutoff(dev);
409 : }
410 :
411 : /**
412 : * @}
413 : */
414 :
415 : #ifdef __cplusplus
416 : }
417 : #endif /* __cplusplus */
418 :
419 : #include <zephyr/syscalls/fuel_gauge.h>
420 :
421 : #endif /* ZEPHYR_INCLUDE_DRIVERS_BATTERY_H_ */
|