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