1 /*
2  * Copyright (c) 2022 Google LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Public APIs for the USB BC1.2 battery charging detect drivers.
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_DRIVERS_USB_USB_BC12_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_USB_USB_BC12_H_
14 
15 #include <zephyr/device.h>
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 /**
22  * @brief USB Battery Charging (BC1.2) driver APIs
23  * @defgroup b12_interface Battery Charging (BC1.2)
24  * @ingroup usb_interfaces
25  * @{
26  */
27 
28 /* FIXME - make these Kconfig options */
29 
30 /**
31  * @name BC1.2 constants
32  * @{
33  */
34 
35 /** BC1.2 USB charger voltage. */
36 #define BC12_CHARGER_VOLTAGE_UV	 5000 * 1000
37 /**
38  * BC1.2 USB charger minimum current. Set to match the Isusp of 2.5 mA parameter.
39  * This is returned by the driver when either BC1.2 detection fails, or the
40  * attached partner is a SDP (standard downstream port).
41  *
42  * The application may increase the current draw after determining the USB device
43  * state of suspended/unconfigured/configured.
44  *   Suspended: 2.5 mA
45  *   Unconfigured: 100 mA
46  *   Configured: 500 mA (USB 2.0)
47  */
48 #define BC12_CHARGER_MIN_CURR_UA 2500
49 /** BC1.2 USB charger maximum current. */
50 #define BC12_CHARGER_MAX_CURR_UA 1500 * 1000
51 
52 /** @} */
53 
54 /** @cond INTERNAL_HIDDEN
55  * @brief Helper macro for setting a BC1.2 current limit
56  *
57  * @param val Current limit value, in uA.
58  * @return A valid BC1.2 current limit, in uA, clamped between the BC1.2 minimum
59  * and maximum values.
60  */
61 #define BC12_CURR_UA(val) CLAMP(val, BC12_CHARGER_MIN_CURR_UA, BC12_CHARGER_MAX_CURR_UA)
62 /** @endcond  */
63 
64 /** @brief BC1.2 device role. */
65 enum bc12_role {
66 	BC12_DISCONNECTED,    /**< No BC1.2 device connected */
67 	BC12_PORTABLE_DEVICE, /**< BC1.2 device is a portable device */
68 	BC12_CHARGING_PORT,   /**< BC1.2 device is a charging port */
69 };
70 
71 /** @brief BC1.2 charging partner type. */
72 enum bc12_type {
73 	/**  No partner connected. */
74 	BC12_TYPE_NONE,
75 	/** Standard Downstream Port */
76 	BC12_TYPE_SDP,
77 	/** Dedicated Charging Port */
78 	BC12_TYPE_DCP,
79 	/** Charging Downstream Port */
80 	BC12_TYPE_CDP,
81 	/** Proprietary charging port */
82 	BC12_TYPE_PROPRIETARY,
83 	/** Unknown charging port, BC1.2 detection failed. */
84 	BC12_TYPE_UNKNOWN,
85 	/** Count of valid BC12 types. */
86 	BC12_TYPE_COUNT,
87 };
88 
89 /**
90  * @brief BC1.2 detected partner state.
91  */
92 struct bc12_partner_state {
93 	/** Current role of the BC1.2 device. */
94 	enum bc12_role bc12_role;
95 	union {
96 		struct {
97 			/**
98 			 * Charging partner type.
99 			 * Valid when @ref bc12_role is @ref BC12_PORTABLE_DEVICE.
100 			 */
101 			enum bc12_type type;
102 			/**
103 			 * Current, in uA, that the charging partner provides.
104 			 * Valid when @ref bc12_role is @ref BC12_PORTABLE_DEVICE.
105 			 */
106 			int current_ua;
107 			/**
108 			 * Voltage, in uV, that the charging partner provides.
109 			 * Valid when @ref bc12_role is @ref BC12_PORTABLE_DEVICE.
110 			 */
111 			int voltage_uv;
112 		};
113 		struct {
114 			/**
115 			 * True if a PD partner is currently connected.
116 			 * Valid when @ref bc12_role is @ref BC12_CHARGING_PORT.
117 			 */
118 			bool pd_partner_connected;
119 		};
120 	};
121 };
122 
123 /**
124  * @brief BC1.2 callback for charger configuration
125  *
126  * @param dev BC1.2 device which is notifying of the new charger state.
127  * @param state Current state of the BC1.2 client, including BC1.2 type
128  * detected, voltage, and current limits.
129  * If NULL, then the partner charger is disconnected or the BC1.2 device is
130  * operating in host mode.
131  * @param user_data Requester supplied data which is passed along to the callback.
132  */
133 typedef void (*bc12_callback_t)(const struct device *dev, struct bc12_partner_state *state,
134 				void *user_data);
135 
136 /**
137  * @cond INTERNAL_HIDDEN
138  *
139  * These are for internal use only, so skip these in public documentation.
140  */
141 __subsystem struct bc12_driver_api {
142 	int (*set_role)(const struct device *dev, enum bc12_role role);
143 	int (*set_result_cb)(const struct device *dev, bc12_callback_t cb, void *user_data);
144 };
145 /**
146  * @endcond
147  */
148 
149 /**
150  * @brief Set the BC1.2 role.
151  *
152  * @param dev Pointer to the device structure for the BC1.2 driver instance.
153  * @param role New role for the BC1.2 device.
154  *
155  * @retval 0 If successful.
156  * @retval -EIO general input/output error.
157  */
158 __syscall int bc12_set_role(const struct device *dev, enum bc12_role role);
159 
z_impl_bc12_set_role(const struct device * dev,enum bc12_role role)160 static inline int z_impl_bc12_set_role(const struct device *dev, enum bc12_role role)
161 {
162 	const struct bc12_driver_api *api = (const struct bc12_driver_api *)dev->api;
163 
164 	return api->set_role(dev, role);
165 }
166 
167 /**
168  * @brief Register a callback for BC1.2 results.
169  *
170  * @param dev Pointer to the device structure for the BC1.2 driver instance.
171  * @param cb Function pointer for the result callback.
172  * @param user_data Requester supplied data which is passed along to the callback.
173  *
174  * @retval 0 If successful.
175  * @retval -EIO general input/output error.
176  */
177 __syscall int bc12_set_result_cb(const struct device *dev, bc12_callback_t cb, void *user_data);
178 
z_impl_bc12_set_result_cb(const struct device * dev,bc12_callback_t cb,void * user_data)179 static inline int z_impl_bc12_set_result_cb(const struct device *dev, bc12_callback_t cb,
180 					    void *user_data)
181 {
182 	const struct bc12_driver_api *api = (const struct bc12_driver_api *)dev->api;
183 
184 	return api->set_result_cb(dev, cb, user_data);
185 }
186 
187 #ifdef __cplusplus
188 }
189 #endif
190 
191 /**
192  * @}
193  */
194 
195 #include <zephyr/syscalls/usb_bc12.h>
196 
197 #endif /* ZEPHYR_INCLUDE_DRIVERS_USB_USB_BC12_H_ */
198