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