Line data Source code
1 1 : /*
2 : * Copyright 2023 Google LLC
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : /**
7 : * @file
8 : * @brief USB Type-C Power Path Controller device API
9 : *
10 : */
11 :
12 : #ifndef ZEPHYR_INCLUDE_DRIVERS_USBC_USBC_PPC_H_
13 : #define ZEPHYR_INCLUDE_DRIVERS_USBC_USBC_PPC_H_
14 :
15 : /**
16 : * @brief USB Type-C Power Path Controller
17 : * @defgroup usb_type_c_power_path_controller USB Type-C Power Path Controller
18 : * @ingroup usb_type_c
19 : * @{
20 : */
21 :
22 : #include <zephyr/types.h>
23 : #include <zephyr/device.h>
24 : #include <errno.h>
25 :
26 : #ifdef __cplusplus
27 : extern "C" {
28 : #endif
29 :
30 : /** Type of event being notified by Power Path Controller */
31 1 : enum usbc_ppc_event {
32 : /** Exit from dead-battery mode failed */
33 : USBC_PPC_EVENT_DEAD_BATTERY_ERROR = 0,
34 :
35 : /** Overvoltage detected while being in a source role */
36 : USBC_PPC_EVENT_SRC_OVERVOLTAGE,
37 : /** Reverse current detected while being in a source role */
38 : USBC_PPC_EVENT_SRC_REVERSE_CURRENT,
39 : /** Overcurrent detected while being in a source role */
40 : USBC_PPC_EVENT_SRC_OVERCURRENT,
41 : /** VBUS short detected while being in a source role */
42 : USBC_PPC_EVENT_SRC_SHORT,
43 :
44 : /** Chip over temperature detected */
45 : USBC_PPC_EVENT_OVER_TEMPERATURE,
46 : /** Sink and source paths enabled simultaneously */
47 : USBC_PPC_EVENT_BOTH_SNKSRC_ENABLED,
48 :
49 : /** Reverse current detected while being in a sink role */
50 : USBC_PPC_EVENT_SNK_REVERSE_CURRENT,
51 : /** VBUS short detected while being in a sink role */
52 : USBC_PPC_EVENT_SNK_SHORT,
53 : /** Overvoltage detected while being in a sink role */
54 : USBC_PPC_EVENT_SNK_OVERVOLTAGE,
55 : };
56 :
57 0 : typedef void (*usbc_ppc_event_cb_t)(const struct device *dev, void *data, enum usbc_ppc_event ev);
58 :
59 : /** Structure with pointers to the functions implemented by driver */
60 1 : __subsystem struct usbc_ppc_driver_api {
61 0 : int (*is_dead_battery_mode)(const struct device *dev);
62 0 : int (*exit_dead_battery_mode)(const struct device *dev);
63 0 : int (*is_vbus_source)(const struct device *dev);
64 0 : int (*is_vbus_sink)(const struct device *dev);
65 0 : int (*set_snk_ctrl)(const struct device *dev, bool enable);
66 0 : int (*set_src_ctrl)(const struct device *dev, bool enable);
67 0 : int (*set_vbus_discharge)(const struct device *dev, bool enable);
68 0 : int (*is_vbus_present)(const struct device *dev);
69 0 : int (*set_event_handler)(const struct device *dev, usbc_ppc_event_cb_t handler, void *data);
70 0 : int (*dump_regs)(const struct device *dev);
71 : };
72 :
73 : /*
74 : * API functions
75 : */
76 :
77 : /**
78 : * @brief Check if PPC is in the dead battery mode
79 : *
80 : * @param dev PPC device structure
81 : * @retval 1 if PPC is in the dead battery mode
82 : * @retval 0 if PPC is not in the dead battery mode
83 : * @retval -EIO if I2C communication failed
84 : * @retval -ENOSYS if this function is not supported by the driver
85 : */
86 1 : static inline int ppc_is_dead_battery_mode(const struct device *dev)
87 : {
88 : const struct usbc_ppc_driver_api *api = (const struct usbc_ppc_driver_api *)dev->api;
89 :
90 : if (api->is_dead_battery_mode == NULL) {
91 : return -ENOSYS;
92 : }
93 :
94 : return api->is_dead_battery_mode(dev);
95 : }
96 :
97 : /**
98 : * @brief Request the PPC to exit from the dead battery mode
99 : * Return from this call doesn't mean that the PPC is not in the dead battery anymore.
100 : * In the case of error, the driver should execute the callback with
101 : * USBC_PPC_EVENT_DEAD_BATTERY_ERROR enum. To check if the PPC disabled the dead battery mode,
102 : * the call to ppc_is_dead_battery_mode should be done.
103 : *
104 : * @param dev PPC device structure
105 : * @retval 0 if request was successfully sent
106 : * @retval -EIO if I2C communication failed
107 : * @retval -ENOSYS if this function is not supported by the driver
108 : */
109 1 : static inline int ppc_exit_dead_battery_mode(const struct device *dev)
110 : {
111 : const struct usbc_ppc_driver_api *api = (const struct usbc_ppc_driver_api *)dev->api;
112 :
113 : if (api->exit_dead_battery_mode == NULL) {
114 : return -ENOSYS;
115 : }
116 :
117 : return api->exit_dead_battery_mode(dev);
118 : }
119 :
120 : /**
121 : * @brief Check if the PPC is sourcing the VBUS
122 : *
123 : * @param dev PPC device structure
124 : * @retval 1 if the PPC is sourcing the VBUS
125 : * @retval 0 if the PPC is not sourcing the VBUS
126 : * @retval -EIO if I2C communication failed
127 : * @retval -ENOSYS if this function is not supported by the driver
128 : */
129 1 : static inline int ppc_is_vbus_source(const struct device *dev)
130 : {
131 : const struct usbc_ppc_driver_api *api = (const struct usbc_ppc_driver_api *)dev->api;
132 :
133 : if (api->is_vbus_source == NULL) {
134 : return -ENOSYS;
135 : }
136 :
137 : return api->is_vbus_source(dev);
138 : }
139 :
140 : /**
141 : * @brief Check if the PPC is sinking the VBUS
142 : *
143 : * @param dev PPC device structure
144 : * @retval 1 if the PPC is sinking the VBUS
145 : * @retval 0 if the PPC is not sinking the VBUS
146 : * @retval -EIO if I2C communication failed
147 : * @retval -ENOSYS if this function is not supported by the driver
148 : */
149 1 : static inline int ppc_is_vbus_sink(const struct device *dev)
150 : {
151 : const struct usbc_ppc_driver_api *api = (const struct usbc_ppc_driver_api *)dev->api;
152 :
153 : if (api->is_vbus_sink == NULL) {
154 : return -ENOSYS;
155 : }
156 :
157 : return api->is_vbus_sink(dev);
158 : }
159 :
160 : /**
161 : * @brief Set the state of VBUS sinking
162 : *
163 : * @param dev PPC device structure
164 : * @param enable True if sinking VBUS should be enabled, false if should be disabled
165 : * @retval 0 if success
166 : * @retval -EIO if I2C communication failed
167 : * @retval -ENOSYS if this function is not supported by the driver
168 : */
169 1 : static inline int ppc_set_snk_ctrl(const struct device *dev, bool enable)
170 : {
171 : const struct usbc_ppc_driver_api *api = (const struct usbc_ppc_driver_api *)dev->api;
172 :
173 : if (api->set_snk_ctrl == NULL) {
174 : return -ENOSYS;
175 : }
176 :
177 : return api->set_snk_ctrl(dev, enable);
178 : }
179 :
180 : /**
181 : * @brief Set the state of VBUS sourcing
182 : *
183 : * @param dev PPC device structure
184 : * @param enable True if sourcing VBUS should be enabled, false if should be disabled
185 : * @retval 0 if success
186 : * @retval -EIO if I2C communication failed
187 : * @retval -ENOSYS if this function is not supported by the driver
188 : */
189 1 : static inline int ppc_set_src_ctrl(const struct device *dev, bool enable)
190 : {
191 : const struct usbc_ppc_driver_api *api = (const struct usbc_ppc_driver_api *)dev->api;
192 :
193 : if (api->set_src_ctrl == NULL) {
194 : return -ENOSYS;
195 : }
196 :
197 : return api->set_src_ctrl(dev, enable);
198 : }
199 :
200 : /**
201 : * @brief Set the state of VBUS discharging
202 : *
203 : * @param dev PPC device structure
204 : * @param enable True if VBUS discharging should be enabled, false if should be disabled
205 : * @retval 0 if success
206 : * @retval -EIO if I2C communication failed
207 : * @retval -ENOSYS if this function is not supported by the driver
208 : */
209 1 : static inline int ppc_set_vbus_discharge(const struct device *dev, bool enable)
210 : {
211 : const struct usbc_ppc_driver_api *api = (const struct usbc_ppc_driver_api *)dev->api;
212 :
213 : if (api->set_vbus_discharge == NULL) {
214 : return -ENOSYS;
215 : }
216 :
217 : return api->set_vbus_discharge(dev, enable);
218 : }
219 :
220 : /**
221 : * @brief Check if VBUS is present
222 : *
223 : * @param dev PPC device structure
224 : * @retval 1 if VBUS voltage is present
225 : * @retval 0 if no VBUS voltage is detected
226 : * @retval -EIO if I2C communication failed
227 : * @retval -ENOSYS if this function is not supported by the driver
228 : */
229 1 : static inline int ppc_is_vbus_present(const struct device *dev)
230 : {
231 : const struct usbc_ppc_driver_api *api = (const struct usbc_ppc_driver_api *)dev->api;
232 :
233 : if (api->is_vbus_present == NULL) {
234 : return -ENOSYS;
235 : }
236 :
237 : return api->is_vbus_present(dev);
238 : }
239 :
240 : /**
241 : * @brief Set the callback used to notify about PPC events
242 : *
243 : * @param dev PPC device structure
244 : * @param handler Handler that will be called with events notifications
245 : * @param data Pointer used as an argument to the callback
246 : * @retval 0 if success
247 : * @retval -ENOSYS if this function is not supported by the driver
248 : */
249 1 : static inline int ppc_set_event_handler(const struct device *dev,
250 : usbc_ppc_event_cb_t handler, void *data)
251 : {
252 : const struct usbc_ppc_driver_api *api = (const struct usbc_ppc_driver_api *)dev->api;
253 :
254 : if (api->set_event_handler == NULL) {
255 : return -ENOSYS;
256 : }
257 :
258 : return api->set_event_handler(dev, handler, data);
259 : }
260 :
261 : /**
262 : * @brief Print the values or PPC registers
263 : *
264 : * @param dev PPC device structure
265 : * @retval 0 if success
266 : * @retval -EIO if I2C communication failed
267 : * @retval -ENOSYS if this function is not supported by the driver
268 : */
269 1 : static inline int ppc_dump_regs(const struct device *dev)
270 : {
271 : const struct usbc_ppc_driver_api *api = (const struct usbc_ppc_driver_api *)dev->api;
272 :
273 : if (api->dump_regs == NULL) {
274 : return -ENOSYS;
275 : }
276 :
277 : return api->dump_regs(dev);
278 : }
279 :
280 : #ifdef __cplusplus
281 : }
282 : #endif
283 :
284 : /**
285 : * @}
286 : */
287 :
288 : #endif /* ZEPHYR_INCLUDE_DRIVERS_USBC_USBC_PPC_H_ */
|