Skip to content

Commit 289fc64

Browse files
jackpot51crawfxrd
authored andcommitted
Add usbc_mux_info command
1 parent 51d35cb commit 289fc64

4 files changed

Lines changed: 203 additions & 6 deletions

File tree

src/board/system76/common/include/board/usbpd.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
#ifndef _BOARD_USBPD_H
44
#define _BOARD_USBPD_H
55

6+
#include <stdbool.h>
7+
#include <stdint.h>
8+
69
#if CONFIG_HAVE_USBPD
710

811
void usbpd_init(void);
912
void usbpd_event(void);
1013
void usbpd_disable_charging(void);
1114
void usbpd_enable_charging(void);
15+
bool usbc_mux_info(uint8_t port, uint16_t *info);
1216

1317
#else
1418

@@ -17,6 +21,12 @@ static inline void usbpd_event(void) {}
1721
static inline void usbpd_disable_charging(void) {}
1822
static inline void usbpd_enable_charging(void) {}
1923

24+
static inline bool usbc_mux_info(uint8_t port, uint16_t *info) {
25+
(void)port;
26+
(void)info;
27+
return false;
28+
}
29+
2030
#endif
2131

2232
#endif // _BOARD_USBPD_H

src/board/system76/common/smfi.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <board/scratch.h>
2222
#include <board/kbled.h>
2323
#include <board/kbscan.h>
24+
#include <board/usbpd.h>
2425

2526
#if CONFIG_SECURITY
2627
#include <board/security.h>
@@ -264,6 +265,18 @@ static enum Result cmd_security_set(void) {
264265
}
265266
#endif // CONFIG_SECURITY
266267

268+
static enum Result cmd_usbc_mux_info(void) {
269+
uint8_t port = smfi_cmd[SMFI_CMD_DATA];
270+
uint16_t info = 0;
271+
if (usbc_mux_info(port, &info)) {
272+
smfi_cmd[SMFI_CMD_DATA + 1] = (uint8_t)info;
273+
smfi_cmd[SMFI_CMD_DATA + 2] = (uint8_t)(info >> 8);
274+
return RES_OK;
275+
} else {
276+
return RES_ERR;
277+
}
278+
}
279+
267280
#endif // !defined(__SCRATCH__)
268281

269282
#if defined(__SCRATCH__)
@@ -421,6 +434,10 @@ void smfi_event(void) {
421434
break;
422435
#endif // CONFIG_SECURITY
423436

437+
case CMD_USBC_MUX_INFO:
438+
smfi_cmd[SMFI_CMD_RES] = cmd_usbc_mux_info();
439+
break;
440+
424441
#endif // !defined(__SCRATCH__)
425442
case CMD_SPI:
426443
smfi_cmd[SMFI_CMD_RES] = cmd_spi();

src/board/system76/common/usbpd/tps65987.c

Lines changed: 143 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,43 @@
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

1737
void usbpd_init(void) {
1838
i2c_reset(&I2C_USBPD, true);
1939
}
2040

41+
#if HAVE_USBPD_CHARGING
42+
2143
static 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+
}

src/common/include/common/command.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ enum Command {
5050
CMD_SECURITY_GET = 20,
5151
// Set security state
5252
CMD_SECURITY_SET = 21,
53+
// Get USB-C mux info (for coreboot)
54+
CMD_USBC_MUX_INFO = 22,
5355
//TODO
5456
};
5557

@@ -85,4 +87,35 @@ enum SecurityState {
8587
SECURITY_STATE_PREPARE_UNLOCK = 3,
8688
};
8789

90+
enum UsbcMuxInfoFlags {
91+
// DisplayPort connected if set
92+
CMD_USBC_MUX_INFO_DP = BIT(0),
93+
// USB connected if set
94+
CMD_USBC_MUX_INFO_USB = BIT(1),
95+
// Active cable if set, passive if not set
96+
CMD_USBC_MUX_INFO_CABLE = BIT(2),
97+
// Polarity of device, flipped if set, normal if not set
98+
CMD_USBC_MUX_INFO_POLARITY = BIT(3),
99+
// HPD level assert
100+
CMD_USBC_MUX_INFO_HPD_LVL = BIT(4),
101+
// HPD IRQ assert
102+
CMD_USBC_MUX_INFO_HPD_IRQ = BIT(5),
103+
// UFP if set, DFP if not set
104+
CMD_USBC_MUX_INFO_UFP = BIT(6),
105+
// Debug accessory if set
106+
CMD_USBC_MUX_INFO_DBG_ACC = BIT(7),
107+
// DP pin mode A
108+
CMD_USBC_MUX_INFO_DP_MODE_A = BIT(8),
109+
// DP pin mode B
110+
CMD_USBC_MUX_INFO_DP_MODE_B = BIT(9),
111+
// DP pin mode C
112+
CMD_USBC_MUX_INFO_DP_MODE_C = BIT(10),
113+
// DP pin mode D
114+
CMD_USBC_MUX_INFO_DP_MODE_D = BIT(11),
115+
// DP pin mode E
116+
CMD_USBC_MUX_INFO_DP_MODE_E = BIT(12),
117+
// DP pin mode F
118+
CMD_USBC_MUX_INFO_DP_MODE_F = BIT(13),
119+
};
120+
88121
#endif // _COMMON_COMMAND_H

0 commit comments

Comments
 (0)