Skip to content

Commit 85219ed

Browse files
barnas-michalcarlescufi
authored andcommitted
usbc: add API for the Power Path Controllers
This commit adds an API to the Power Path Controllers (PPC) that may be used with USB-C subsystem to control the current paths, enabling and disabling sourcing and sinking VBUS and protect against shorts, overvoltage and overcurrent. Signed-off-by: Michał Barnaś <[email protected]>
1 parent 08a2ca5 commit 85219ed

File tree

3 files changed

+301
-0
lines changed

3 files changed

+301
-0
lines changed

drivers/usb_c/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55

66
source "drivers/usb_c/tcpc/Kconfig"
77
source "drivers/usb_c/vbus/Kconfig"
8+
source "drivers/usb_c/ppc/Kconfig"

drivers/usb_c/ppc/Kconfig

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

0 commit comments

Comments
 (0)