1 /*
2  * Copyright 2022 The Chromium OS Authors
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 /**
7  * @file
8  * @brief USBC Type-C Port Controller device APIs
9  *
10  * This file contains the USB Type-C Port Controller device APIs.
11  * All Type-C Port Controller device drivers should implement the
12  * APIs described in this file.
13  */
14 
15 #ifndef ZEPHYR_INCLUDE_DRIVERS_USBC_USBC_TCPC_H_
16 #define ZEPHYR_INCLUDE_DRIVERS_USBC_USBC_TCPC_H_
17 
18 /**
19  * @brief USB Type-C Port Controller API
20  * @defgroup usb_type_c_port_controller_api USB Type-C Port Controller API
21  * @since 3.1
22  * @version 0.1.0
23  * @ingroup io_interfaces
24  * @{
25  */
26 
27 #include <zephyr/types.h>
28 #include <zephyr/device.h>
29 #include <errno.h>
30 
31 #include "usbc_tc.h"
32 #include "usbc_pd.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /**
39  * @brief TCPC Alert bits
40  */
41 enum tcpc_alert {
42 	/** CC status changed */
43 	TCPC_ALERT_CC_STATUS,
44 	/** Power status changed */
45 	TCPC_ALERT_POWER_STATUS,
46 	/** Receive Buffer register changed */
47 	TCPC_ALERT_MSG_STATUS,
48 	/** Received Hard Reset message */
49 	TCPC_ALERT_HARD_RESET_RECEIVED,
50 	/** SOP* message transmission not successful */
51 	TCPC_ALERT_TRANSMIT_MSG_FAILED,
52 	/**
53 	 * Reset or SOP* message transmission not sent
54 	 * due to an incoming receive message
55 	 */
56 	TCPC_ALERT_TRANSMIT_MSG_DISCARDED,
57 	/** Reset or SOP* message transmission successful */
58 	TCPC_ALERT_TRANSMIT_MSG_SUCCESS,
59 	/** A high-voltage alarm has occurred */
60 	TCPC_ALERT_VBUS_ALARM_HI,
61 	/** A low-voltage alarm has occurred */
62 	TCPC_ALERT_VBUS_ALARM_LO,
63 	/** A fault has occurred. Read the FAULT_STATUS register */
64 	TCPC_ALERT_FAULT_STATUS,
65 	/** TCPC RX buffer has overflowed */
66 	TCPC_ALERT_RX_BUFFER_OVERFLOW,
67 	/** The TCPC in Attached.SNK state has detected a sink disconnect */
68 	TCPC_ALERT_VBUS_SNK_DISCONNECT,
69 	/** Receive buffer register changed */
70 	TCPC_ALERT_BEGINNING_MSG_STATUS,
71 	/** Extended status changed */
72 	TCPC_ALERT_EXTENDED_STATUS,
73 	/**
74 	 * An extended interrupt event has occurred. Read the alert_extended
75 	 * register
76 	 */
77 	TCPC_ALERT_EXTENDED,
78 	/** A vendor defined alert has been detected */
79 	TCPC_ALERT_VENDOR_DEFINED
80 };
81 
82 /**
83  * @brief TCPC Status register
84  */
85 enum tcpc_status_reg {
86 	/** The CC Status register */
87 	TCPC_CC_STATUS,
88 	/** The Power Status register */
89 	TCPC_POWER_STATUS,
90 	/** The Fault Status register */
91 	TCPC_FAULT_STATUS,
92 	/** The Extended Status register */
93 	TCPC_EXTENDED_STATUS,
94 	/** The Extended Alert Status register */
95 	TCPC_EXTENDED_ALERT_STATUS,
96 	/** The Vendor Defined Status register */
97 	TCPC_VENDOR_DEFINED_STATUS
98 };
99 
100 /**
101  * @brief TCPC Chip Information
102  */
103 struct tcpc_chip_info {
104 	/** Vendor Id */
105 	uint16_t vendor_id;
106 	/** Product Id */
107 	uint16_t product_id;
108 	/** Device Id */
109 	uint16_t device_id;
110 	/** Firmware version number */
111 	uint64_t fw_version_number;
112 
113 	union {
114 		/** Minimum Required firmware version string */
115 		uint8_t min_req_fw_version_string[8];
116 		/** Minimum Required firmware version number */
117 		uint64_t min_req_fw_version_number;
118 	};
119 };
120 
121 typedef	int (*tcpc_vconn_control_cb_t)(const struct device *dev,
122 		enum tc_cc_polarity pol, bool enable);
123 typedef	int (*tcpc_vconn_discharge_cb_t)(const struct device *dev,
124 		enum tc_cc_polarity pol, bool enable);
125 typedef void (*tcpc_alert_handler_cb_t)(const struct device *dev, void *data,
126 		enum tcpc_alert alert);
127 
128 __subsystem struct tcpc_driver_api {
129 	int (*init)(const struct device *dev);
130 	int (*get_cc)(const struct device *dev, enum tc_cc_voltage_state *cc1,
131 			enum tc_cc_voltage_state *cc2);
132 	int (*select_rp_value)(const struct device *dev, enum tc_rp_value rp);
133 	int (*get_rp_value)(const struct device *dev, enum tc_rp_value *rp);
134 	int (*set_cc)(const struct device *dev, enum tc_cc_pull pull);
135 	void (*set_vconn_discharge_cb)(const struct device *dev, tcpc_vconn_discharge_cb_t cb);
136 	void (*set_vconn_cb)(const struct device *dev, tcpc_vconn_control_cb_t vconn_cb);
137 	int (*vconn_discharge)(const struct device *dev, bool enable);
138 	int (*set_vconn)(const struct device *dev, bool enable);
139 	int (*set_roles)(const struct device *dev, enum tc_power_role power_role,
140 			enum tc_data_role data_role);
141 	int (*get_rx_pending_msg)(const struct device *dev, struct pd_msg *msg);
142 	int (*set_rx_enable)(const struct device *dev, bool enable);
143 	int (*set_cc_polarity)(const struct device *dev, enum tc_cc_polarity polarity);
144 	int (*transmit_data)(const struct device *dev, struct pd_msg *msg);
145 	int (*dump_std_reg)(const struct device *dev);
146 	void (*alert_handler_cb)(const struct device *dev, void *data, enum tcpc_alert alert);
147 	int (*get_status_register)(const struct device *dev, enum tcpc_status_reg reg,
148 			int32_t *status);
149 	int (*clear_status_register)(const struct device *dev, enum tcpc_status_reg reg,
150 			uint32_t mask);
151 	int (*mask_status_register)(const struct device *dev, enum tcpc_status_reg reg,
152 			uint32_t mask);
153 	int (*set_debug_accessory)(const struct device *dev, bool enable);
154 	int (*set_debug_detach)(const struct device *dev);
155 	int (*set_drp_toggle)(const struct device *dev, bool enable);
156 	int (*get_snk_ctrl)(const struct device *dev);
157 	int (*set_snk_ctrl)(const struct device *dev, bool enable);
158 	int (*get_src_ctrl)(const struct device *dev);
159 	int (*set_src_ctrl)(const struct device *dev, bool enable);
160 	int (*get_chip_info)(const struct device *dev, struct tcpc_chip_info *chip_info);
161 	int (*set_low_power_mode)(const struct device *dev, bool enable);
162 	int (*sop_prime_enable)(const struct device *dev, bool enable);
163 	int (*set_bist_test_mode)(const struct device *dev, bool enable);
164 	int (*set_alert_handler_cb)(const struct device *dev, tcpc_alert_handler_cb_t handler,
165 			void *data);
166 };
167 
168 /**
169  * @brief Returns whether the sink has detected a Rp resistor on the other side
170  */
tcpc_is_cc_rp(enum tc_cc_voltage_state cc)171 static inline int tcpc_is_cc_rp(enum tc_cc_voltage_state cc)
172 {
173 	return (cc == TC_CC_VOLT_RP_DEF) || (cc == TC_CC_VOLT_RP_1A5) ||
174 	       (cc == TC_CC_VOLT_RP_3A0);
175 }
176 
177 /**
178  * @brief Returns true if both CC lines are completely open
179  */
tcpc_is_cc_open(enum tc_cc_voltage_state cc1,enum tc_cc_voltage_state cc2)180 static inline int tcpc_is_cc_open(enum tc_cc_voltage_state cc1,
181 				  enum tc_cc_voltage_state cc2)
182 {
183 	return (cc1 < TC_CC_VOLT_RD) && (cc2 < TC_CC_VOLT_RD);
184 }
185 
186 /**
187  * @brief Returns true if we detect the port partner is a snk debug accessory
188  */
tcpc_is_cc_snk_dbg_acc(enum tc_cc_voltage_state cc1,enum tc_cc_voltage_state cc2)189 static inline int tcpc_is_cc_snk_dbg_acc(enum tc_cc_voltage_state cc1,
190 					 enum tc_cc_voltage_state cc2)
191 {
192 	return cc1 == TC_CC_VOLT_RD && cc2 == TC_CC_VOLT_RD;
193 }
194 
195 /**
196  * @brief Returns true if we detect the port partner is a src debug accessory
197  */
tcpc_is_cc_src_dbg_acc(enum tc_cc_voltage_state cc1,enum tc_cc_voltage_state cc2)198 static inline int tcpc_is_cc_src_dbg_acc(enum tc_cc_voltage_state cc1,
199 					 enum tc_cc_voltage_state cc2)
200 {
201 	return tcpc_is_cc_rp(cc1) && tcpc_is_cc_rp(cc2);
202 }
203 
204 /**
205  * @brief Returns true if the port partner is an audio accessory
206  */
tcpc_is_cc_audio_acc(enum tc_cc_voltage_state cc1,enum tc_cc_voltage_state cc2)207 static inline int tcpc_is_cc_audio_acc(enum tc_cc_voltage_state cc1,
208 				       enum tc_cc_voltage_state cc2)
209 {
210 	return cc1 == TC_CC_VOLT_RA && cc2 == TC_CC_VOLT_RA;
211 }
212 
213 /**
214  * @brief Returns true if the port partner is presenting at least one Rd
215  */
tcpc_is_cc_at_least_one_rd(enum tc_cc_voltage_state cc1,enum tc_cc_voltage_state cc2)216 static inline int tcpc_is_cc_at_least_one_rd(enum tc_cc_voltage_state cc1,
217 					     enum tc_cc_voltage_state cc2)
218 {
219 	return cc1 == TC_CC_VOLT_RD || cc2 == TC_CC_VOLT_RD;
220 }
221 
222 /**
223  * @brief Returns true if the port partner is presenting Rd on only one CC line
224  */
tcpc_is_cc_only_one_rd(enum tc_cc_voltage_state cc1,enum tc_cc_voltage_state cc2)225 static inline int tcpc_is_cc_only_one_rd(enum tc_cc_voltage_state cc1,
226 					 enum tc_cc_voltage_state cc2)
227 {
228 	return tcpc_is_cc_at_least_one_rd(cc1, cc2) && cc1 != cc2;
229 }
230 
231 /**
232  * @brief Initializes the TCPC
233  *
234  * @param dev Runtime device structure
235  *
236  * @retval 0 on success
237  * @retval -EIO on failure
238  * @retval -EAGAIN if initialization should be postponed
239  */
tcpc_init(const struct device * dev)240 static inline int tcpc_init(const struct device *dev)
241 {
242 	const struct tcpc_driver_api *api =
243 		(const struct tcpc_driver_api *)dev->api;
244 
245 	__ASSERT(api->init != NULL,
246 		 "Callback pointer should not be NULL");
247 
248 	return api->init(dev);
249 }
250 
251 /**
252  * @brief Reads the status of the CC lines
253  *
254  * @param dev  Runtime device structure
255  * @param cc1  A pointer where the CC1 status is written
256  * @param cc2  A pointer where the CC2 status is written
257  *
258  * @retval 0 on success
259  * @retval -EIO on failure
260  * @retval -ENOSYS if not implemented
261  */
tcpc_get_cc(const struct device * dev,enum tc_cc_voltage_state * cc1,enum tc_cc_voltage_state * cc2)262 static inline int tcpc_get_cc(const struct device *dev,
263 			      enum tc_cc_voltage_state *cc1,
264 			      enum tc_cc_voltage_state *cc2)
265 {
266 	const struct tcpc_driver_api *api =
267 		(const struct tcpc_driver_api *)dev->api;
268 
269 	if (api->get_cc == NULL) {
270 		return -ENOSYS;
271 	}
272 
273 	return api->get_cc(dev, cc1, cc2);
274 }
275 
276 /**
277  * @brief Sets the value of CC pull up resistor used when operating as a Source
278  *
279  * @param dev   Runtime device structure
280  * @param rp    Value of the Pull-Up Resistor.
281  *
282  * @retval 0 on success
283  * @retval -ENOSYS
284  * @retval -EIO on failure
285  */
tcpc_select_rp_value(const struct device * dev,enum tc_rp_value rp)286 static inline int tcpc_select_rp_value(const struct device *dev, enum tc_rp_value rp)
287 {
288 	const struct tcpc_driver_api *api =
289 	(const struct tcpc_driver_api *)dev->api;
290 
291 	if (api->select_rp_value == NULL) {
292 		return -ENOSYS;
293 	}
294 
295 	return api->select_rp_value(dev, rp);
296 }
297 
298 /**
299  * @brief Gets the value of the CC pull up resistor used when operating as a Source
300  *
301  * @param dev   Runtime device structure
302  * @param rp    pointer where the value of the Pull-Up Resistor is stored
303  *
304  * @retval 0 on success
305  * @retval -ENOSYS
306  * @retval -EIO on failure
307  */
tcpc_get_rp_value(const struct device * dev,enum tc_rp_value * rp)308 static inline int tcpc_get_rp_value(const struct device *dev, enum tc_rp_value *rp)
309 {
310 	const struct tcpc_driver_api *api =
311 	(const struct tcpc_driver_api *)dev->api;
312 
313 	if (api->get_rp_value == NULL) {
314 		return -ENOSYS;
315 	}
316 
317 	return api->get_rp_value(dev, rp);
318 }
319 
320 /**
321  * @brief Sets the CC pull resistor and sets the role as either Source or Sink
322  *
323  * @param dev   Runtime device structure
324  * @param pull  The pull resistor to set
325  *
326  * @retval 0 on success
327  * @retval -EIO on failure
328  */
tcpc_set_cc(const struct device * dev,enum tc_cc_pull pull)329 static inline int tcpc_set_cc(const struct device *dev, enum tc_cc_pull pull)
330 {
331 	const struct tcpc_driver_api *api =
332 		(const struct tcpc_driver_api *)dev->api;
333 
334 	__ASSERT(api->set_cc != NULL,
335 		 "Callback pointer should not be NULL");
336 
337 	return api->set_cc(dev, pull);
338 }
339 
340 /**
341  * @brief Sets a callback that can enable or disable VCONN if the TCPC is
342  *	  unable to or the system is configured in a way that does not use
343  *	  the VCONN control capabilities of the TCPC
344  *
345  * The callback is called in the tcpc_set_vconn function if vconn_cb isn't NULL
346  *
347  * @param dev       Runtime device structure
348  * @param vconn_cb  pointer to the callback function that controls vconn
349  */
tcpc_set_vconn_cb(const struct device * dev,tcpc_vconn_control_cb_t vconn_cb)350 static inline void tcpc_set_vconn_cb(const struct device *dev,
351 				     tcpc_vconn_control_cb_t vconn_cb)
352 {
353 	const struct tcpc_driver_api *api =
354 		(const struct tcpc_driver_api *)dev->api;
355 
356 	__ASSERT(api->set_vconn_cb != NULL,
357 		 "Callback pointer should not be NULL");
358 
359 	return api->set_vconn_cb(dev, vconn_cb);
360 }
361 
362 /**
363  * @brief Sets a callback that can enable or discharge VCONN if the TCPC is
364  *	  unable to or the system is configured in a way that does not use
365  *	  the VCONN control capabilities of the TCPC
366  *
367  * The callback is called in the tcpc_vconn_discharge function if cb isn't NULL
368  *
369  * @param dev       Runtime device structure
370  * @param cb  pointer to the callback function that discharges vconn
371  */
tcpc_set_vconn_discharge_cb(const struct device * dev,tcpc_vconn_discharge_cb_t cb)372 static inline void tcpc_set_vconn_discharge_cb(const struct device *dev,
373 				     tcpc_vconn_discharge_cb_t cb)
374 {
375 	const struct tcpc_driver_api *api =
376 		(const struct tcpc_driver_api *)dev->api;
377 
378 	__ASSERT(api->set_vconn_discharge_cb != NULL,
379 		 "Callback pointer should not be NULL");
380 
381 	return api->set_vconn_discharge_cb(dev, cb);
382 }
383 
384 /**
385  * @brief Discharges VCONN
386  *
387  * This function uses the TCPC to discharge VCONN if possible or calls the
388  * callback function set by tcpc_set_vconn_cb
389  *
390  * @param dev     Runtime device structure
391  * @param enable  VCONN discharge is enabled when true, it's disabled
392  *
393  * @retval 0 on success
394  * @retval -EIO on failure
395  * @retval -ENOSYS if not implemented
396  */
tcpc_vconn_discharge(const struct device * dev,bool enable)397 static inline int tcpc_vconn_discharge(const struct device *dev, bool enable)
398 {
399 	const struct tcpc_driver_api *api =
400 		(const struct tcpc_driver_api *)dev->api;
401 
402 	if (api->vconn_discharge == NULL) {
403 		return -ENOSYS;
404 	}
405 
406 	return api->vconn_discharge(dev, enable);
407 }
408 
409 /**
410  * @brief Enables or disables VCONN
411  *
412  * This function uses the TCPC to measure VCONN if possible or calls the
413  * callback function set by tcpc_set_vconn_cb
414  *
415  * @param dev     Runtime device structure
416  * @param enable  VCONN is enabled when true, it's disabled
417  *
418  * @retval 0 on success
419  * @retval -EIO on failure
420  * @retval -ENOSYS if not implemented
421  */
tcpc_set_vconn(const struct device * dev,bool enable)422 static inline int tcpc_set_vconn(const struct device *dev, bool enable)
423 {
424 	const struct tcpc_driver_api *api =
425 		(const struct tcpc_driver_api *)dev->api;
426 
427 	if (api->set_vconn == NULL) {
428 		return -ENOSYS;
429 	}
430 
431 	return api->set_vconn(dev, enable);
432 }
433 
434 /**
435  * @brief Sets the Power and Data Role of the PD message header
436  *
437  * This function only needs to be called once per data / power role change
438  *
439  * @param dev         Runtime device structure
440  * @param power_role  current power role
441  * @param data_role   current data role
442  *
443  * @retval 0 on success
444  * @retval -EIO on failure
445  * @retval -ENOSYS if not implemented
446  */
tcpc_set_roles(const struct device * dev,enum tc_power_role power_role,enum tc_data_role data_role)447 static inline int tcpc_set_roles(const struct device *dev,
448 				 enum tc_power_role power_role,
449 				 enum tc_data_role data_role)
450 {
451 	const struct tcpc_driver_api *api =
452 		(const struct tcpc_driver_api *)dev->api;
453 
454 	if (api->set_roles == NULL) {
455 		return -ENOSYS;
456 	}
457 
458 	return api->set_roles(dev, power_role, data_role);
459 }
460 
461 /**
462  * @brief Retrieves the Power Delivery message from the TCPC.
463  * If buf is NULL, then only the status is returned, where 0 means there is a message pending and
464  * -ENODATA means there is no pending message.
465  *
466  * @param dev Runtime device structure
467  * @param buf pointer where the pd_buf pointer is written, NULL if only checking the status
468  *
469  * @retval Greater or equal to 0 is the number of bytes received if buf parameter is provided
470  * @retval 0 if there is a message pending and buf parameter is NULL
471  * @retval -EIO on failure
472  * @retval -ENODATA if no message is pending
473  */
tcpc_get_rx_pending_msg(const struct device * dev,struct pd_msg * buf)474 static inline int tcpc_get_rx_pending_msg(const struct device *dev, struct pd_msg *buf)
475 {
476 	const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api;
477 
478 	__ASSERT(api->get_rx_pending_msg != NULL, "Callback pointer should not be NULL");
479 
480 	return api->get_rx_pending_msg(dev, buf);
481 }
482 
483 /**
484  * @brief Enables the reception of SOP* message types
485  *
486  * @param dev     Runtime device structure
487  * @param enable  Enable Power Delivery when true, else it's
488  *		  disabled
489  *
490  * @retval 0 on success
491  * @retval -EIO on failure
492  * @retval -ENOSYS if not implemented
493  */
tcpc_set_rx_enable(const struct device * dev,bool enable)494 static inline int tcpc_set_rx_enable(const struct device *dev, bool enable)
495 {
496 	const struct tcpc_driver_api *api =
497 		(const struct tcpc_driver_api *)dev->api;
498 
499 	if (api->set_rx_enable == NULL) {
500 		return -ENOSYS;
501 	}
502 
503 	return api->set_rx_enable(dev, enable);
504 }
505 
506 /**
507  * @brief Sets the polarity of the CC lines
508  *
509  * @param dev       Runtime device structure
510  * @param polarity  Polarity of the cc line
511  *
512  * @retval 0 on success
513  * @retval -EIO on failure
514  */
tcpc_set_cc_polarity(const struct device * dev,enum tc_cc_polarity polarity)515 static inline int tcpc_set_cc_polarity(const struct device *dev,
516 				       enum tc_cc_polarity polarity)
517 {
518 	const struct tcpc_driver_api *api =
519 		(const struct tcpc_driver_api *)dev->api;
520 
521 	__ASSERT(api->set_cc_polarity != NULL,
522 		 "Callback pointer should not be NULL");
523 
524 	return api->set_cc_polarity(dev, polarity);
525 }
526 
527 /**
528  * @brief Transmits a Power Delivery message
529  *
530  * @param dev     Runtime device structure
531  * @param msg     Power Delivery message to transmit
532  *
533  * @retval 0 on success
534  * @retval -EIO on failure
535  * @retval -ENOSYS if not implemented
536  */
tcpc_transmit_data(const struct device * dev,struct pd_msg * msg)537 static inline int tcpc_transmit_data(const struct device *dev,
538 				     struct pd_msg *msg)
539 {
540 	const struct tcpc_driver_api *api =
541 		(const struct tcpc_driver_api *)dev->api;
542 
543 	if (api->transmit_data == NULL) {
544 		return -ENOSYS;
545 	}
546 
547 	return api->transmit_data(dev, msg);
548 }
549 
550 /**
551  * @brief Dump a set of TCPC registers
552  *
553  * @param dev Runtime device structure
554  *
555  * @retval 0 on success
556  * @retval -EIO on failure
557  * @retval -ENOSYS if not implemented
558  */
tcpc_dump_std_reg(const struct device * dev)559 static inline int tcpc_dump_std_reg(const struct device *dev)
560 {
561 	const struct tcpc_driver_api *api =
562 		(const struct tcpc_driver_api *)dev->api;
563 
564 	if (api->dump_std_reg == NULL) {
565 		return -ENOSYS;
566 	}
567 
568 	return api->dump_std_reg(dev);
569 }
570 
571 /**
572  * @brief Sets the alert function that's called when an interrupt is triggered
573  *	  due to an alert bit
574  *
575  * Calling this function enables the particular alert bit
576  *
577  * @param dev      Runtime device structure
578  * @param handler  The callback function called when the bit is set
579  * @param data     user data passed to the callback
580  *
581  * @retval 0 on success
582  * @retval -EINVAL on failure
583  */
tcpc_set_alert_handler_cb(const struct device * dev,tcpc_alert_handler_cb_t handler,void * data)584 static inline int tcpc_set_alert_handler_cb(const struct device *dev,
585 					    tcpc_alert_handler_cb_t handler,
586 					    void *data)
587 {
588 	const struct tcpc_driver_api *api =
589 		(const struct tcpc_driver_api *)dev->api;
590 
591 	__ASSERT(api->set_alert_handler_cb != NULL,
592 		 "Callback pointer should not be NULL");
593 
594 	return api->set_alert_handler_cb(dev, handler, data);
595 }
596 
597 /**
598  * @brief Gets a status register
599  *
600  * @param dev     Runtime device structure
601  * @param reg     The status register to read
602  * @param status  Pointer where the status is stored
603  *
604  * @retval 0 on success
605  * @retval -EIO on failure
606  * @retval -ENOSYS if not implemented
607  */
tcpc_get_status_register(const struct device * dev,enum tcpc_status_reg reg,int32_t * status)608 static inline int tcpc_get_status_register(const struct device *dev,
609 					   enum tcpc_status_reg reg,
610 					   int32_t *status)
611 {
612 	const struct tcpc_driver_api *api =
613 		(const struct tcpc_driver_api *)dev->api;
614 
615 	if (api->get_status_register == NULL) {
616 		return -ENOSYS;
617 	}
618 
619 	return api->get_status_register(dev, reg, status);
620 }
621 
622 /**
623  * @brief Clears a TCPC status register
624  *
625  * @param dev   Runtime device structure
626  * @param reg   The status register to read
627  * @param mask  A bit mask of the status register to clear.
628  *		A status bit is cleared when it's set to 1.
629  *
630  * @retval 0 on success
631  * @retval -EIO on failure
632  * @retval -ENOSYS if not implemented
633  */
tcpc_clear_status_register(const struct device * dev,enum tcpc_status_reg reg,uint32_t mask)634 static inline int tcpc_clear_status_register(const struct device *dev,
635 					     enum tcpc_status_reg reg,
636 					     uint32_t mask)
637 {
638 	const struct tcpc_driver_api *api =
639 		(const struct tcpc_driver_api *)dev->api;
640 
641 	if (api->clear_status_register == NULL) {
642 		return -ENOSYS;
643 	}
644 
645 	return api->clear_status_register(dev, reg, mask);
646 }
647 
648 /**
649  * @brief Sets the mask of a TCPC status register
650  *
651  * @param dev   Runtime device structure
652  * @param reg   The status register to read
653  * @param mask  A bit mask of the status register to mask.
654  *		The status bit is masked if it's 0, else it's unmasked.
655  *
656  * @retval 0 on success
657  * @retval -EIO on failure
658  * @retval -ENOSYS if not implemented
659  */
tcpc_mask_status_register(const struct device * dev,enum tcpc_status_reg reg,uint32_t mask)660 static inline int tcpc_mask_status_register(const struct device *dev,
661 					    enum tcpc_status_reg reg,
662 					    uint32_t mask)
663 {
664 	const struct tcpc_driver_api *api =
665 		(const struct tcpc_driver_api *)dev->api;
666 
667 	if (api->mask_status_register == NULL) {
668 		return -ENOSYS;
669 	}
670 
671 	return api->mask_status_register(dev, reg, mask);
672 }
673 
674 /**
675  * @brief Manual control of TCPC DebugAccessory control
676  *
677  * @param dev     Runtime device structure
678  * @param enable  Enable Debug Accessory when true, else it's disabled
679  *
680  * @retval 0 on success
681  * @retval -EIO on failure
682  * @retval -ENOSYS if not implemented
683  */
tcpc_set_debug_accessory(const struct device * dev,bool enable)684 static inline int tcpc_set_debug_accessory(const struct device *dev,
685 					   bool enable)
686 {
687 	const struct tcpc_driver_api *api =
688 		(const struct tcpc_driver_api *)dev->api;
689 
690 	if (api->set_debug_accessory == NULL) {
691 		return -ENOSYS;
692 	}
693 
694 	return api->set_debug_accessory(dev, enable);
695 }
696 
697 /**
698  * @brief Detach from a debug connection
699  *
700  * @param dev Runtime device structure
701  *
702  * @retval 0 on success
703  * @retval -EIO on failure
704  * @retval -ENOSYS if not implemented
705  */
tcpc_set_debug_detach(const struct device * dev)706 static inline int tcpc_set_debug_detach(const struct device *dev)
707 {
708 	const struct tcpc_driver_api *api =
709 		(const struct tcpc_driver_api *)dev->api;
710 
711 	if (api->set_debug_detach == NULL) {
712 		return -ENOSYS;
713 	}
714 
715 	return api->set_debug_detach(dev);
716 }
717 
718 /**
719  * @brief Enable TCPC auto dual role toggle
720  *
721  * @param dev     Runtime device structure
722  * @param enable  Auto dual role toggle is active when true, else it's disabled
723  *
724  * @retval 0 on success
725  * @retval -EIO on failure
726  * @retval -ENOSYS if not implemented
727  */
tcpc_set_drp_toggle(const struct device * dev,bool enable)728 static inline int tcpc_set_drp_toggle(const struct device *dev, bool enable)
729 {
730 	const struct tcpc_driver_api *api =
731 		(const struct tcpc_driver_api *)dev->api;
732 
733 	if (api->set_drp_toggle == NULL) {
734 		return -ENOSYS;
735 	}
736 
737 	return api->set_drp_toggle(dev, enable);
738 }
739 
740 /**
741  * @brief Queries the current sinking state of the TCPC
742  *
743  * @param dev Runtime device structure
744  *
745  * @retval true if sinking power
746  * @retval false if not sinking power
747  * @retval -ENOSYS if not implemented
748  */
tcpc_get_snk_ctrl(const struct device * dev)749 static inline int tcpc_get_snk_ctrl(const struct device *dev)
750 {
751 	const struct tcpc_driver_api *api =
752 		(const struct tcpc_driver_api *)dev->api;
753 
754 	if (api->get_snk_ctrl == NULL) {
755 		return -ENOSYS;
756 	}
757 
758 	return api->get_snk_ctrl(dev);
759 }
760 
761 /**
762  * @brief Set the VBUS sinking state of the TCPC
763  *
764  * @param dev Runtime device structure
765  * @param enable True if sinking should be enabled, false if disabled
766  * @retval 0 on success
767  * @retval -ENOSYS if not implemented
768  */
tcpc_set_snk_ctrl(const struct device * dev,bool enable)769 static inline int tcpc_set_snk_ctrl(const struct device *dev, bool enable)
770 {
771 	const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api;
772 
773 	if (api->set_snk_ctrl == NULL) {
774 		return -ENOSYS;
775 	}
776 
777 	return api->set_snk_ctrl(dev, enable);
778 }
779 
780 /**
781  * @brief Queries the current sourcing state of the TCPC
782  *
783  * @param dev Runtime device structure
784  *
785  * @retval true if sourcing power
786  * @retval false if not sourcing power
787  * @retval -ENOSYS if not implemented
788  */
tcpc_get_src_ctrl(const struct device * dev)789 static inline int tcpc_get_src_ctrl(const struct device *dev)
790 {
791 	const struct tcpc_driver_api *api =
792 		(const struct tcpc_driver_api *)dev->api;
793 
794 	if (api->get_src_ctrl == NULL) {
795 		return -ENOSYS;
796 	}
797 
798 	return api->get_src_ctrl(dev);
799 }
800 
801 /**
802  * @brief Set the VBUS sourcing state of the TCPC
803  *
804  * @param dev Runtime device structure
805  * @param enable True if sourcing should be enabled, false if disabled
806  * @retval 0 on success
807  * @retval -ENOSYS if not implemented
808  */
tcpc_set_src_ctrl(const struct device * dev,bool enable)809 static inline int tcpc_set_src_ctrl(const struct device *dev, bool enable)
810 {
811 	const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api;
812 
813 	if (api->set_src_ctrl == NULL) {
814 		return -ENOSYS;
815 	}
816 
817 	return api->set_src_ctrl(dev, enable);
818 }
819 
820 /**
821  * @brief Controls the BIST Mode of the TCPC. It disables RX alerts while the
822  *	  mode is active.
823  *
824  * @param dev Runtime device structure
825  * @param enable The TCPC enters BIST TEST Mode when true
826  *
827  * @retval 0 on success
828  * @retval -EIO on failure
829  * @retval -ENOSYS if not implemented
830  */
tcpc_set_bist_test_mode(const struct device * dev,bool enable)831 static inline int tcpc_set_bist_test_mode(const struct device *dev,
832 					  bool enable)
833 {
834 	const struct tcpc_driver_api *api =
835 		(const struct tcpc_driver_api *)dev->api;
836 
837 	if (api->set_bist_test_mode == NULL) {
838 		return -ENOSYS;
839 	}
840 
841 	return api->set_bist_test_mode(dev, enable);
842 }
843 
844 /**
845  * @brief Gets the TCPC firmware version
846  *
847  * @param dev        Runtime device structure
848  * @param chip_info  Pointer to TCPC chip info where the version is stored
849  *
850  * @retval 0 on success
851  * @retval -EIO on failure
852  * @retval -ENOSYS if not implemented
853  */
tcpc_get_chip_info(const struct device * dev,struct tcpc_chip_info * chip_info)854 static inline int tcpc_get_chip_info(const struct device *dev,
855 				     struct tcpc_chip_info *chip_info)
856 {
857 	const struct tcpc_driver_api *api =
858 		(const struct tcpc_driver_api *)dev->api;
859 
860 	if (api->get_chip_info == NULL) {
861 		return -ENOSYS;
862 	}
863 
864 	return api->get_chip_info(dev, chip_info);
865 }
866 
867 /**
868  * @brief Instructs the TCPC to enter or exit low power mode
869  *
870  * @param dev     Runtime device structure
871  * @param enable  The TCPC enters low power mode when true, else it exits it
872  *
873  * @retval 0 on success
874  * @retval -EIO on failure
875  * @retval -ENOSYS if not implemented
876  */
tcpc_set_low_power_mode(const struct device * dev,bool enable)877 static inline int tcpc_set_low_power_mode(const struct device *dev,
878 					  bool enable)
879 {
880 	const struct tcpc_driver_api *api =
881 		(const struct tcpc_driver_api *)dev->api;
882 
883 	if (api->set_low_power_mode == NULL) {
884 		return -ENOSYS;
885 	}
886 
887 	return api->set_low_power_mode(dev, enable);
888 }
889 
890 /**
891  * @brief Enables the reception of SOP Prime messages
892  *
893  * @param dev     Runtime device structure
894  * @param enable  Can receive SOP Prime messages when true, else it can not
895  *
896  * @retval 0 on success
897  * @retval -EIO on failure
898  * @retval -ENOSYS if not implemented
899  */
tcpc_sop_prime_enable(const struct device * dev,bool enable)900 static inline int tcpc_sop_prime_enable(const struct device *dev,
901 					bool enable)
902 {
903 	const struct tcpc_driver_api *api =
904 		(const struct tcpc_driver_api *)dev->api;
905 
906 	if (api->sop_prime_enable == NULL) {
907 		return -ENOSYS;
908 	}
909 
910 	return api->sop_prime_enable(dev, enable);
911 }
912 
913 /**
914  * @}
915  */
916 
917 #ifdef __cplusplus
918 }
919 #endif
920 
921 #endif /* ZEPHYR_INCLUDE_DRIVERS_USBC_USBC_TCPC_H_ */
922