1 /*
2  * Copyright (c) 2021 Google Inc
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_BBRAM_H
8 #define ZEPHYR_INCLUDE_DRIVERS_BBRAM_H
9 
10 #include <errno.h>
11 
12 #include <zephyr/device.h>
13 
14 /**
15  * @brief BBRAM Interface
16  * @defgroup bbram_interface BBRAM Interface
17  * @ingroup io_interfaces
18  * @{
19  */
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /**
26  * @typedef bbram_api_check_invalid_t
27  * @brief API template to check if the BBRAM is invalid.
28  *
29  * @see bbram_check_invalid
30  */
31 typedef int (*bbram_api_check_invalid_t)(const struct device *dev);
32 
33 /**
34  * @typedef bbram_api_check_standby_power_t
35  * @brief API template to check for standby power failure.
36  *
37  * @see bbram_check_standby_power
38  */
39 typedef int (*bbram_api_check_standby_power_t)(const struct device *dev);
40 
41 /**
42  * @typedef bbram_api_check_power_t
43  * @brief API template to check for V CC1 power failure.
44  *
45  * @see bbram_check_power
46  */
47 typedef int (*bbram_api_check_power_t)(const struct device *dev);
48 
49 /**
50  * @typedef bbram_api_get_size_t
51  * @brief API template to check the size of the BBRAM
52  *
53  * @see bbram_get_size
54  */
55 typedef int (*bbram_api_get_size_t)(const struct device *dev, size_t *size);
56 
57 /**
58  * @typedef bbram_api_read_t
59  * @brief API template to read from BBRAM.
60  *
61  * @see bbram_read
62  */
63 typedef int (*bbram_api_read_t)(const struct device *dev, size_t offset, size_t size,
64 			      uint8_t *data);
65 
66 /**
67  * @typedef bbram_api_write_t
68  * @brief API template to write to BBRAM.
69  *
70  * @see bbram_write
71  */
72 typedef int (*bbram_api_write_t)(const struct device *dev, size_t offset, size_t size,
73 			       const uint8_t *data);
74 
75 __subsystem struct bbram_driver_api {
76 	bbram_api_check_invalid_t check_invalid;
77 	bbram_api_check_standby_power_t check_standby_power;
78 	bbram_api_check_power_t check_power;
79 	bbram_api_get_size_t get_size;
80 	bbram_api_read_t read;
81 	bbram_api_write_t write;
82 };
83 
84 /**
85  * @brief Check if BBRAM is invalid
86  *
87  * Check if "Invalid Battery-Backed RAM" status is set then reset the status bit. This may occur as
88  * a result to low voltage at the VBAT pin.
89  *
90  * @param[in] dev BBRAM device pointer.
91  * @return 0 if the Battery-Backed RAM data is valid, -EFAULT otherwise.
92  */
93 __syscall int bbram_check_invalid(const struct device *dev);
94 
z_impl_bbram_check_invalid(const struct device * dev)95 static inline int z_impl_bbram_check_invalid(const struct device *dev)
96 {
97 	const struct bbram_driver_api *api =
98 		(const struct bbram_driver_api *)dev->api;
99 
100 	if (!api->check_invalid) {
101 		return -ENOTSUP;
102 	}
103 
104 	return api->check_invalid(dev);
105 }
106 
107 /**
108  * @brief Check for standby (Volt SBY) power failure.
109  *
110  * Check if the V standby power domain is turned on after it was off then reset the status bit.
111  *
112  * @param[in] dev BBRAM device pointer.
113  * @return 0 if V SBY power domain is in normal operation.
114  */
115 __syscall int bbram_check_standby_power(const struct device *dev);
116 
z_impl_bbram_check_standby_power(const struct device * dev)117 static inline int z_impl_bbram_check_standby_power(const struct device *dev)
118 {
119 	const struct bbram_driver_api *api =
120 		(const struct bbram_driver_api *)dev->api;
121 
122 	if (!api->check_standby_power) {
123 		return -ENOTSUP;
124 	}
125 
126 	return api->check_standby_power(dev);
127 }
128 
129 /**
130  * @brief Check for V CC1 power failure.
131  *
132  * This will return an error if the V CC1 power domain is turned on after it was off and reset the
133  * status bit.
134  *
135  * @param[in] dev BBRAM device pointer.
136  * @return 0 if the V CC1 power domain is in normal operation, -EFAULT otherwise.
137  */
138 __syscall int bbram_check_power(const struct device *dev);
139 
z_impl_bbram_check_power(const struct device * dev)140 static inline int z_impl_bbram_check_power(const struct device *dev)
141 {
142 	const struct bbram_driver_api *api =
143 		(const struct bbram_driver_api *)dev->api;
144 
145 	if (!api->check_power) {
146 		return -ENOTSUP;
147 	}
148 
149 	return api->check_power(dev);
150 }
151 
152 /**
153  * @brief Get the size of the BBRAM (in bytes).
154  *
155  * @param[in] dev BBRAM device pointer.
156  * @param[out] size Pointer to write the size to.
157  * @return 0 for success, -EFAULT otherwise.
158  */
159 __syscall int bbram_get_size(const struct device *dev, size_t *size);
160 
z_impl_bbram_get_size(const struct device * dev,size_t * size)161 static inline int z_impl_bbram_get_size(const struct device *dev, size_t *size)
162 {
163 	const struct bbram_driver_api *api =
164 		(const struct bbram_driver_api *)dev->api;
165 
166 	if (!api->get_size) {
167 		return -ENOTSUP;
168 	}
169 
170 	return api->get_size(dev, size);
171 }
172 
173 /**
174  * @brief Read bytes from BBRAM.
175  *
176  * @param[in]  dev The BBRAM device pointer to read from.
177  * @param[in]  offset The offset into the RAM address to start reading from.
178  * @param[in]  size The number of bytes to read.
179  * @param[out] data The buffer to load the data into.
180  * @return 0 on success, -EFAULT if the address range is out of bounds.
181  */
182 __syscall int bbram_read(const struct device *dev, size_t offset, size_t size,
183 			 uint8_t *data);
184 
z_impl_bbram_read(const struct device * dev,size_t offset,size_t size,uint8_t * data)185 static inline int z_impl_bbram_read(const struct device *dev, size_t offset,
186 				    size_t size, uint8_t *data)
187 {
188 	const struct bbram_driver_api *api =
189 		(const struct bbram_driver_api *)dev->api;
190 
191 	if (!api->read) {
192 		return -ENOTSUP;
193 	}
194 
195 	return api->read(dev, offset, size, data);
196 }
197 
198 /**
199  * @brief Write bytes to BBRAM.
200  *
201  * @param[in]  dev The BBRAM device pointer to write to.
202  * @param[in]  offset The offset into the RAM address to start writing to.
203  * @param[in]  size The number of bytes to write.
204  * @param[out] data Pointer to the start of data to write.
205  * @return 0 on success, -EFAULT if the address range is out of bounds.
206  */
207 __syscall int bbram_write(const struct device *dev, size_t offset, size_t size,
208 			  const uint8_t *data);
209 
z_impl_bbram_write(const struct device * dev,size_t offset,size_t size,const uint8_t * data)210 static inline int z_impl_bbram_write(const struct device *dev, size_t offset,
211 				     size_t size, const uint8_t *data)
212 {
213 	const struct bbram_driver_api *api =
214 		(const struct bbram_driver_api *)dev->api;
215 
216 	if (!api->write) {
217 		return -ENOTSUP;
218 	}
219 
220 	return api->write(dev, offset, size, data);
221 }
222 
223 /**
224  * @brief Set the emulated BBRAM driver's invalid state
225  *
226  * Calling this will affect the emulated behavior of bbram_check_invalid().
227  *
228  * @param[in] dev The emulated device to modify
229  * @param[in] is_invalid The new invalid state
230  * @return 0 on success, negative values on error.
231  */
232 int bbram_emul_set_invalid(const struct device *dev, bool is_invalid);
233 
234 /**
235  * @brief Set the emulated BBRAM driver's standby power state
236  *
237  * Calling this will affect the emulated behavior of bbram_check_standby_power().
238  *
239  * @param[in] dev The emulated device to modify
240  * @param[in] failure Whether or not standby power failure should be emulated
241  * @return 0 on success, negative values on error.
242  */
243 int bbram_emul_set_standby_power_state(const struct device *dev, bool failure);
244 
245 /**
246  * @brief Set the emulated BBRAM driver's  power state
247  *
248  * Calling this will affect the emulated behavior of bbram_check_power().
249  *
250  * @param[in] dev The emulated device to modify
251  * @param[in] failure Whether or not a power failure should be emulated
252  * @return 0 on success, negative values on error.
253  */
254 int bbram_emul_set_power_state(const struct device *dev, bool failure);
255 
256 #ifdef __cplusplus
257 }
258 #endif
259 
260 /**
261  * @}
262  */
263 
264 #include <zephyr/syscalls/bbram.h>
265 
266 #endif /* ZEPHYR_INCLUDE_DRIVERS_BBRAM_H */
267