33// USB-PD driver for TPS65987 and the mostly compatible TPS65993 and TPS65994.
44// I2C register reference: https://www.ti.com/lit/ug/slvubh2b/slvubh2b.pdf
55
6+ #include <board/usbpd.h>
67#include <board/battery.h>
78#include <board/gpio.h>
89#include <board/power.h>
9- #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+ #define REG_DATA_STATUS 0x5F
20+ #define REG_DATA_STATUS_DATA_ORIENTATION BIT(1)
21+ #define REG_DATA_STATUS_ACTIVE_CABLE BIT(2)
22+ #define REG_DATA_STATUS_USB3_CONNECTION BIT(5)
23+ #define REG_DATA_STATUS_USB_DATA_ROLE BIT(7)
24+ #define REG_DATA_STATUS_DP_CONNECTION BIT(8)
25+ #define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_MASK (0b11 << 10)
26+ #define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_AB (0b10 << 10)
27+ #define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_CD (0b01 << 10)
28+ #define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_EF (0b00 << 10)
29+ #define REG_DATA_STATUS_DEBUG_ACCESSORY_MODE BIT(12)
30+ #define REG_DATA_STATUS_HPD_IRQ BIT(14)
31+ #define REG_DATA_STATUS_HPD_LEVEL BIT(15)
32+
33+ #ifndef HAVE_USBPD_CHARGING
34+ #define HAVE_USBPD_CHARGING 0
35+ #endif // HAVE_USBPD_CHARGING
1636
1737void usbpd_init (void ) {
1838 i2c_reset (& I2C_USBPD , true);
1939}
2040
41+ #if HAVE_USBPD_CHARGING
42+
2143static int16_t usbpd_current_limit (void ) {
2244 uint8_t value [7 ] = { 0 };
2345 int16_t res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , REG_ACTIVE_CONTRACT_PDO , value , sizeof (value ));
@@ -168,7 +190,7 @@ static int16_t usbpd_aneg(void) {
168190 int16_t res ;
169191
170192 uint8_t cmd [5 ] = { 4 , 'A' , 'N' , 'e' , 'g' };
171- res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , 0x08 , cmd , sizeof (cmd ));
193+ res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , REG_CMD_1 , cmd , sizeof (cmd ));
172194 if (res < 0 ) {
173195 return res ;
174196 }
@@ -185,7 +207,7 @@ void usbpd_disable_charging(void) {
185207
186208 // Read current value
187209 uint8_t value [2 ] = { 0 };
188- res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , 0x33 , value , sizeof (value ));
210+ res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , REG_TX_SINK_CAPABILITIES , value , sizeof (value ));
189211 if (res < 0 ) {
190212 DEBUG ("ERR %04X\n" , - res );
191213 return ;
@@ -200,7 +222,7 @@ void usbpd_disable_charging(void) {
200222 // Enable only the first TX sink PDO (5V)
201223 value [0 ] = 1 ;
202224 value [1 ] = 1 ;
203- res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , 0x33 , value , sizeof (value ));
225+ res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , REG_TX_SINK_CAPABILITIES , value , sizeof (value ));
204226 if (res < 0 ) {
205227 DEBUG ("ERR %04X\n" , - res );
206228 return ;
@@ -223,7 +245,7 @@ void usbpd_enable_charging(void) {
223245
224246 // Read current value
225247 uint8_t value [2 ] = { 0 };
226- res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , 0x33 , value , sizeof (value ));
248+ res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , REG_TX_SINK_CAPABILITIES , value , sizeof (value ));
227249 if (res < 0 ) {
228250 DEBUG ("ERR %04X\n" , - res );
229251 return ;
@@ -238,7 +260,7 @@ void usbpd_enable_charging(void) {
238260 // Enable the first two TX sink PDO (5V and 20V)
239261 value [0 ] = 1 ;
240262 value [1 ] = 2 ;
241- res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , 0x33 , value , sizeof (value ));
263+ res = i2c_set (& I2C_USBPD , USBPD_ADDRESS , REG_TX_SINK_CAPABILITIES , value , sizeof (value ));
242264 if (res < 0 ) {
243265 DEBUG ("ERR %04X\n" , - res );
244266 return ;
@@ -253,3 +275,118 @@ void usbpd_enable_charging(void) {
253275
254276 DEBUG ("OK\n" );
255277}
278+
279+ #else // HAVE_USBPD_CHARGING
280+
281+ void usbpd_event (void ) {
282+ bool update = false;
283+
284+ static bool last_ac_in = false;
285+ bool ac_in = !gpio_get (& ACIN_N );
286+ if (ac_in != last_ac_in ) {
287+ last_ac_in = ac_in ;
288+ update = true;
289+
290+ DEBUG ("AC_IN %d\n" , ac_in );
291+ }
292+
293+ if (update ) {
294+ int16_t res ;
295+
296+ DEBUG ("USBPD DATA STATUS " );
297+
298+ // Read current value
299+ uint8_t value [6 ] = { 0 };
300+ res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , REG_DATA_STATUS , value , sizeof (value ));
301+ if (res < 0 ) {
302+ DEBUG ("ERR %04X\n" , - res );
303+ } else {
304+ DEBUG (
305+ "OK %02x = %02X, %02X%02X%02X%02X\n" ,
306+ value [0 ],
307+ value [5 ],
308+ value [4 ],
309+ value [3 ],
310+ value [2 ],
311+ value [1 ]
312+ );
313+ }
314+ }
315+ }
316+
317+ void usbpd_disable_charging (void ) {}
318+
319+ #endif // HAVE_USBPD_CHARGING
320+
321+ bool usbc_mux_info (uint8_t port , uint16_t * info ) {
322+ if (port != 0 ) {
323+ // Only port 0 is supported right now
324+ WARN ("usbc_mux_info does not support port %d\n" , port );
325+ return false;
326+ }
327+
328+ uint8_t value [6 ] = { 0 };
329+ int16_t res = i2c_get (& I2C_USBPD , USBPD_ADDRESS , REG_DATA_STATUS , value , sizeof (value ));
330+ if (res < 0 ) {
331+ DEBUG ("ERR %04X\n" , - res );
332+ return false;
333+ }
334+
335+ uint32_t data_status = ((uint32_t )value [1 ]) | (((uint32_t )value [2 ]) << 8 ) |
336+ (((uint32_t )value [3 ]) << 16 ) | (((uint32_t )value [4 ]) << 24 );
337+
338+ DEBUG ("OK %02X, %02x = %02X, %08X\n" , res , value [0 ], value [5 ], data_status );
339+
340+ * info = 0 ;
341+ if (data_status & REG_DATA_STATUS_DP_CONNECTION ) {
342+ * info |= CMD_USBC_MUX_INFO_DP ;
343+ }
344+ if (data_status & REG_DATA_STATUS_USB3_CONNECTION ) {
345+ * info |= CMD_USBC_MUX_INFO_USB ;
346+ }
347+ if (data_status & REG_DATA_STATUS_ACTIVE_CABLE ) {
348+ * info |= CMD_USBC_MUX_INFO_CABLE ;
349+ }
350+ if (data_status & REG_DATA_STATUS_DATA_ORIENTATION ) {
351+ * info |= CMD_USBC_MUX_INFO_POLARITY ;
352+ }
353+ if (data_status & REG_DATA_STATUS_HPD_LEVEL ) {
354+ * info |= CMD_USBC_MUX_INFO_HPD_LVL ;
355+ }
356+ if (data_status & REG_DATA_STATUS_HPD_IRQ ) {
357+ * info |= CMD_USBC_MUX_INFO_HPD_IRQ ;
358+ }
359+ if (data_status & REG_DATA_STATUS_USB_DATA_ROLE ) {
360+ * info |= CMD_USBC_MUX_INFO_UFP ;
361+ }
362+ if (data_status & REG_DATA_STATUS_DEBUG_ACCESSORY_MODE ) {
363+ * info |= CMD_USBC_MUX_INFO_DBG_ACC ;
364+ }
365+
366+ switch (data_status & REG_DATA_STATUS_DP_PIN_ASSIGNMENT_MASK ) {
367+ case REG_DATA_STATUS_DP_PIN_ASSIGNMENT_AB :
368+ if (data_status & REG_DATA_STATUS_USB3_CONNECTION ) {
369+ * info |= CMD_USBC_MUX_INFO_DP_MODE_B ;
370+ } else {
371+ * info |= CMD_USBC_MUX_INFO_DP_MODE_A ;
372+ }
373+ break ;
374+ case REG_DATA_STATUS_DP_PIN_ASSIGNMENT_CD :
375+ if (data_status & REG_DATA_STATUS_USB3_CONNECTION ) {
376+ * info |= CMD_USBC_MUX_INFO_DP_MODE_D ;
377+ } else {
378+ * info |= CMD_USBC_MUX_INFO_DP_MODE_C ;
379+ }
380+ break ;
381+ case REG_DATA_STATUS_DP_PIN_ASSIGNMENT_EF :
382+ if (data_status & REG_DATA_STATUS_USB3_CONNECTION ) {
383+ * info |= CMD_USBC_MUX_INFO_DP_MODE_F ;
384+ } else {
385+ * info |= CMD_USBC_MUX_INFO_DP_MODE_E ;
386+ }
387+ break ;
388+ }
389+
390+ DEBUG ("USBC_MUX_INFO: %04X\n" , * info );
391+ return true;
392+ }
0 commit comments