77#include <board/gpio.h>
88#include <board/power.h>
99#include <board/usbpd.h>
10+ #include <common/command.h>
1011#include <common/debug.h>
1112#include <ec/i2c.h>
1213
1314#define USBPD_ADDRESS 0x20
1415
16+ #define REG_CMD_1 0x08
17+ #define REG_TX_SINK_CAPABILITIES 0x33
1518#define REG_ACTIVE_CONTRACT_PDO 0x34
19+ // clang-format off
20+ #define REG_DATA_STATUS 0x5F
21+ #define REG_DATA_STATUS_DATA_ORIENTATION BIT(1)
22+ #define REG_DATA_STATUS_ACTIVE_CABLE BIT(2)
23+ #define REG_DATA_STATUS_USB3_CONNECTION BIT(5)
24+ #define REG_DATA_STATUS_USB_DATA_ROLE BIT(7)
25+ #define REG_DATA_STATUS_DP_CONNECTION BIT(8)
26+ #define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_MASK (0b11 << 10)
27+ #define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_AB (0b10 << 10)
28+ #define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_CD (0b01 << 10)
29+ #define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_EF (0b00 << 10)
30+ #define REG_DATA_STATUS_DEBUG_ACCESSORY_MODE BIT(12)
31+ #define REG_DATA_STATUS_HPD_IRQ BIT(14)
32+ #define REG_DATA_STATUS_HPD_LEVEL BIT(15)
33+ // clang-format on
34+
35+ #ifndef HAVE_USBPD_CHARGING
36+ #define HAVE_USBPD_CHARGING 1
37+ #endif // HAVE_USBPD_CHARGING
1638
1739void usbpd_init (void ) {
1840 i2c_reset (& I2C_USBPD , true);
1941}
2042
43+ #if HAVE_USBPD_CHARGING
44+
2145static int16_t usbpd_current_limit (void ) {
2246 uint8_t value [7 ] = { 0 };
2347 int16_t res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , REG_ACTIVE_CONTRACT_PDO , value , sizeof (value ));
@@ -168,7 +192,7 @@ static int16_t usbpd_aneg(void) {
168192 int16_t res ;
169193
170194 uint8_t cmd [5 ] = { 4 , 'A' , 'N' , 'e' , 'g' };
171- res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , 0x08 , cmd , sizeof (cmd ));
195+ res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , REG_CMD_1 , cmd , sizeof (cmd ));
172196 if (res < 0 ) {
173197 return res ;
174198 }
@@ -185,7 +209,7 @@ void usbpd_disable_charging(void) {
185209
186210 // Read current value
187211 uint8_t value [2 ] = { 0 };
188- res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , 0x33 , value , sizeof (value ));
212+ res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , REG_TX_SINK_CAPABILITIES , value , sizeof (value ));
189213 if (res < 0 ) {
190214 DEBUG ("ERR %04X\n" , - res );
191215 return ;
@@ -200,7 +224,7 @@ void usbpd_disable_charging(void) {
200224 // Enable only the first TX sink PDO (5V)
201225 value [0 ] = 1 ;
202226 value [1 ] = 1 ;
203- res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , 0x33 , value , sizeof (value ));
227+ res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , REG_TX_SINK_CAPABILITIES , value , sizeof (value ));
204228 if (res < 0 ) {
205229 DEBUG ("ERR %04X\n" , - res );
206230 return ;
@@ -223,7 +247,7 @@ void usbpd_enable_charging(void) {
223247
224248 // Read current value
225249 uint8_t value [2 ] = { 0 };
226- res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , 0x33 , value , sizeof (value ));
250+ res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , REG_TX_SINK_CAPABILITIES , value , sizeof (value ));
227251 if (res < 0 ) {
228252 DEBUG ("ERR %04X\n" , - res );
229253 return ;
@@ -238,7 +262,7 @@ void usbpd_enable_charging(void) {
238262 // Enable the first two TX sink PDO (5V and 20V)
239263 value [0 ] = 1 ;
240264 value [1 ] = 2 ;
241- res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , 0x33 , value , sizeof (value ));
265+ res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , REG_TX_SINK_CAPABILITIES , value , sizeof (value ));
242266 if (res < 0 ) {
243267 DEBUG ("ERR %04X\n" , - res );
244268 return ;
@@ -253,3 +277,118 @@ void usbpd_enable_charging(void) {
253277
254278 DEBUG ("OK\n" );
255279}
280+
281+ #else // HAVE_USBPD_CHARGING
282+
283+ void usbpd_event (void ) {
284+ bool update = false;
285+
286+ static bool last_ac_in = false;
287+ bool ac_in = !gpio_get (& ACIN_N );
288+ if (ac_in != last_ac_in ) {
289+ last_ac_in = ac_in ;
290+ update = true;
291+
292+ DEBUG ("AC_IN %d\n" , ac_in );
293+ }
294+
295+ if (update ) {
296+ int16_t res ;
297+
298+ DEBUG ("USBPD DATA STATUS " );
299+
300+ // Read current value
301+ uint8_t value [6 ] = { 0 };
302+ res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , REG_DATA_STATUS , value , sizeof (value ));
303+ if (res < 0 ) {
304+ DEBUG ("ERR %04X\n" , - res );
305+ } else {
306+ DEBUG (
307+ "OK %02x = %02X, %02X%02X%02X%02X\n" ,
308+ value [0 ],
309+ value [5 ],
310+ value [4 ],
311+ value [3 ],
312+ value [2 ],
313+ value [1 ]
314+ );
315+ }
316+ }
317+ }
318+
319+ void usbpd_disable_charging (void ) {}
320+
321+ #endif // HAVE_USBPD_CHARGING
322+
323+ bool usbc_mux_info (uint8_t port , uint16_t * info ) {
324+ if (port != 0 ) {
325+ // Only port 0 is supported right now
326+ WARN ("usbc_mux_info does not support port %d\n" , port );
327+ return false;
328+ }
329+
330+ uint8_t value [6 ] = { 0 };
331+ int16_t res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , REG_DATA_STATUS , value , sizeof (value ));
332+ if (res < 0 ) {
333+ DEBUG ("ERR %04X\n" , - res );
334+ return false;
335+ }
336+
337+ uint32_t data_status = ((uint32_t )value [1 ]) | (((uint32_t )value [2 ]) << 8 ) |
338+ (((uint32_t )value [3 ]) << 16 ) | (((uint32_t )value [4 ]) << 24 );
339+
340+ DEBUG ("OK %02X, %02x = %02X, %08X\n" , res , value [0 ], value [5 ], data_status );
341+
342+ * info = 0 ;
343+ if (data_status & REG_DATA_STATUS_DP_CONNECTION ) {
344+ * info |= CMD_USBC_MUX_INFO_DP ;
345+ }
346+ if (data_status & REG_DATA_STATUS_USB3_CONNECTION ) {
347+ * info |= CMD_USBC_MUX_INFO_USB ;
348+ }
349+ if (data_status & REG_DATA_STATUS_ACTIVE_CABLE ) {
350+ * info |= CMD_USBC_MUX_INFO_CABLE ;
351+ }
352+ if (data_status & REG_DATA_STATUS_DATA_ORIENTATION ) {
353+ * info |= CMD_USBC_MUX_INFO_POLARITY ;
354+ }
355+ if (data_status & REG_DATA_STATUS_HPD_LEVEL ) {
356+ * info |= CMD_USBC_MUX_INFO_HPD_LVL ;
357+ }
358+ if (data_status & REG_DATA_STATUS_HPD_IRQ ) {
359+ * info |= CMD_USBC_MUX_INFO_HPD_IRQ ;
360+ }
361+ if (data_status & REG_DATA_STATUS_USB_DATA_ROLE ) {
362+ * info |= CMD_USBC_MUX_INFO_UFP ;
363+ }
364+ if (data_status & REG_DATA_STATUS_DEBUG_ACCESSORY_MODE ) {
365+ * info |= CMD_USBC_MUX_INFO_DBG_ACC ;
366+ }
367+
368+ switch (data_status & REG_DATA_STATUS_DP_PIN_ASSIGNMENT_MASK ) {
369+ case REG_DATA_STATUS_DP_PIN_ASSIGNMENT_AB :
370+ if (data_status & REG_DATA_STATUS_USB3_CONNECTION ) {
371+ * info |= CMD_USBC_MUX_INFO_DP_MODE_B ;
372+ } else {
373+ * info |= CMD_USBC_MUX_INFO_DP_MODE_A ;
374+ }
375+ break ;
376+ case REG_DATA_STATUS_DP_PIN_ASSIGNMENT_CD :
377+ if (data_status & REG_DATA_STATUS_USB3_CONNECTION ) {
378+ * info |= CMD_USBC_MUX_INFO_DP_MODE_D ;
379+ } else {
380+ * info |= CMD_USBC_MUX_INFO_DP_MODE_C ;
381+ }
382+ break ;
383+ case REG_DATA_STATUS_DP_PIN_ASSIGNMENT_EF :
384+ if (data_status & REG_DATA_STATUS_USB3_CONNECTION ) {
385+ * info |= CMD_USBC_MUX_INFO_DP_MODE_F ;
386+ } else {
387+ * info |= CMD_USBC_MUX_INFO_DP_MODE_E ;
388+ }
389+ break ;
390+ }
391+
392+ DEBUG ("USBC_MUX_INFO: %04X\n" , * info );
393+ return true;
394+ }
0 commit comments