Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add usbc_mux_info command #422

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/board/system76/addw1/board.mk
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ CFLAGS+=\
-DCHARGER_CHARGE_VOLTAGE=12600 \
-DCHARGER_INPUT_CURRENT=11800

# Set USB-PD parameters
CONFIG_HAVE_USBPD = y
CONFIG_USBPD_TPS65987 = y
CFLAGS += -DI2C_USBPD=I2C_1

# Set CPU power limits in watts
CFLAGS+=\
-DPOWER_LIMIT_AC=180 \
Expand Down
5 changes: 5 additions & 0 deletions src/board/system76/addw2/board.mk
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ CFLAGS+=\
-DCHARGER_CHARGE_VOLTAGE=12600 \
-DCHARGER_INPUT_CURRENT=11800

# Set USB-PD parameters
CONFIG_HAVE_USBPD = y
CONFIG_USBPD_TPS65987 = y
CFLAGS += -DI2C_USBPD=I2C_1

# Set CPU power limits in watts
CFLAGS+=\
-DPOWER_LIMIT_AC=180 \
Expand Down
5 changes: 5 additions & 0 deletions src/board/system76/addw3/board.mk
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ CFLAGS+=\
-DCHARGER_CHARGE_VOLTAGE=17600 \
-DCHARGER_INPUT_CURRENT=14000

# Set USB-PD parameters
# XXX: Actually TPS65993
USBPD = tps65987
CFLAGS += -DI2C_USBPD=I2C_1

# Set CPU power limits in watts
CFLAGS+=\
-DPOWER_LIMIT_AC=280 \
Expand Down
5 changes: 5 additions & 0 deletions src/board/system76/addw4/board.mk
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ CFLAGS += \
-DCHARGER_CHARGE_VOLTAGE=17400 \
-DCHARGER_INPUT_CURRENT=11500

# Set USB-PD parameters
CONFIG_HAVE_USBPD = y
CONFIG_USBPD_TPS65987 = y
CFLAGS += -DI2C_USBPD=I2C_1

# Set CPU power limits in watts
CFLAGS += \
-DPOWER_LIMIT_AC=230 \
Expand Down
5 changes: 5 additions & 0 deletions src/board/system76/bonw14/board.mk
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ CFLAGS+=\
-DCHARGER_CHARGE_VOLTAGE=16800 \
-DCHARGER_INPUT_CURRENT=14000

# Set USB-PD parameters
CONFIG_HAVE_USBPD = y
CONFIG_USBPD_TPS65987 = y
CFLAGS += -DI2C_USBPD=I2C_1

# Set CPU power limits in watts
CFLAGS+=\
-DPOWER_LIMIT_AC=180 \
Expand Down
3 changes: 2 additions & 1 deletion src/board/system76/bonw15/board.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ CFLAGS+=-DI2C_SMBUS=I2C_4
# Set touchpad PS2 bus
CFLAGS+=-DPS2_TOUCHPAD=PS2_3


# Set smart charger parameters
# XXX: PRS1 and PRS2 are in parallel for adapter Rsense?
CHARGER=oz26786
Expand All @@ -38,9 +37,11 @@ CFLAGS+=\
-DCHARGER_INPUT_CURRENT=16920

# Set USB-PD parameters
# XXX: Actually TPS65994
CONFIG_HAVE_USBPD = y
CONFIG_USBPD_TPS65987 = y
CFLAGS += -DI2C_USBPD=I2C_1
CFLAGS += -DHAVE_USBPD_CHARGING=1

# Set CPU power limits in watts
CFLAGS+=\
Expand Down
10 changes: 10 additions & 0 deletions src/board/system76/common/include/board/usbpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
#ifndef _BOARD_USBPD_H
#define _BOARD_USBPD_H

#include <stdbool.h>
#include <stdint.h>

#if CONFIG_HAVE_USBPD

void usbpd_init(void);
void usbpd_event(void);
void usbpd_disable_charging(void);
void usbpd_enable_charging(void);
bool usbc_mux_info(uint8_t port, uint16_t *info);

#else

Expand All @@ -17,6 +21,12 @@ static inline void usbpd_event(void) {}
static inline void usbpd_disable_charging(void) {}
static inline void usbpd_enable_charging(void) {}

static inline bool usbc_mux_info(uint8_t port, uint16_t *info) {
(void)port;
(void)info;
return false;
}

#endif

#endif // _BOARD_USBPD_H
17 changes: 17 additions & 0 deletions src/board/system76/common/smfi.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <board/scratch.h>
#include <board/kbled.h>
#include <board/kbscan.h>
#include <board/usbpd.h>

#if CONFIG_SECURITY
#include <board/security.h>
Expand Down Expand Up @@ -264,6 +265,18 @@ static enum Result cmd_security_set(void) {
}
#endif // CONFIG_SECURITY

static enum Result cmd_usbc_mux_info(void) {
uint8_t port = smfi_cmd[SMFI_CMD_DATA];
uint16_t info = 0;
if (usbc_mux_info(port, &info)) {
smfi_cmd[SMFI_CMD_DATA + 1] = (uint8_t)info;
smfi_cmd[SMFI_CMD_DATA + 2] = (uint8_t)(info >> 8);
return RES_OK;
} else {
return RES_ERR;
}
}

#endif // !defined(__SCRATCH__)

#if defined(__SCRATCH__)
Expand Down Expand Up @@ -421,6 +434,10 @@ void smfi_event(void) {
break;
#endif // CONFIG_SECURITY

case CMD_USBC_MUX_INFO:
smfi_cmd[SMFI_CMD_RES] = cmd_usbc_mux_info();
break;

#endif // !defined(__SCRATCH__)
case CMD_SPI:
smfi_cmd[SMFI_CMD_RES] = cmd_spi();
Expand Down
149 changes: 143 additions & 6 deletions src/board/system76/common/usbpd/tps65987.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,43 @@
// USB-PD driver for TPS65987 and the mostly compatible TPS65993 and TPS65994.
// I2C register reference: https://www.ti.com/lit/ug/slvubh2b/slvubh2b.pdf

#include <board/usbpd.h>
#include <board/battery.h>
#include <board/gpio.h>
#include <board/power.h>
#include <board/usbpd.h>
#include <common/command.h>
#include <common/debug.h>
#include <ec/i2c.h>

#define USBPD_ADDRESS 0x20

#define REG_CMD_1 0x08
#define REG_TX_SINK_CAPABILITIES 0x33
#define REG_ACTIVE_CONTRACT_PDO 0x34
#define REG_DATA_STATUS 0x5F
#define REG_DATA_STATUS_DATA_ORIENTATION BIT(1)
#define REG_DATA_STATUS_ACTIVE_CABLE BIT(2)
#define REG_DATA_STATUS_USB3_CONNECTION BIT(5)
#define REG_DATA_STATUS_USB_DATA_ROLE BIT(7)
#define REG_DATA_STATUS_DP_CONNECTION BIT(8)
#define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_MASK (0b11 << 10)
#define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_AB (0b10 << 10)
#define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_CD (0b01 << 10)
#define REG_DATA_STATUS_DP_PIN_ASSIGNMENT_EF (0b00 << 10)
#define REG_DATA_STATUS_DEBUG_ACCESSORY_MODE BIT(12)
#define REG_DATA_STATUS_HPD_IRQ BIT(14)
#define REG_DATA_STATUS_HPD_LEVEL BIT(15)

#ifndef HAVE_USBPD_CHARGING
#define HAVE_USBPD_CHARGING 0
#endif // HAVE_USBPD_CHARGING

void usbpd_init(void) {
i2c_reset(&I2C_USBPD, true);
}

#if HAVE_USBPD_CHARGING

static int16_t usbpd_current_limit(void) {
uint8_t value[7] = { 0 };
int16_t res = i2c_get(&I2C_USBPD, USBPD_ADDRESS, REG_ACTIVE_CONTRACT_PDO, value, sizeof(value));
Expand Down Expand Up @@ -168,7 +190,7 @@ static int16_t usbpd_aneg(void) {
int16_t res;

uint8_t cmd[5] = { 4, 'A', 'N', 'e', 'g' };
res = i2c_set(&I2C_USBPD, USBPD_ADDRESS, 0x08, cmd, sizeof(cmd));
res = i2c_set(&I2C_USBPD, USBPD_ADDRESS, REG_CMD_1, cmd, sizeof(cmd));
if (res < 0) {
return res;
}
Expand All @@ -185,7 +207,7 @@ void usbpd_disable_charging(void) {

// Read current value
uint8_t value[2] = { 0 };
res = i2c_get(&I2C_USBPD, USBPD_ADDRESS, 0x33, value, sizeof(value));
res = i2c_get(&I2C_USBPD, USBPD_ADDRESS, REG_TX_SINK_CAPABILITIES, value, sizeof(value));
if (res < 0) {
DEBUG("ERR %04X\n", -res);
return;
Expand All @@ -200,7 +222,7 @@ void usbpd_disable_charging(void) {
// Enable only the first TX sink PDO (5V)
value[0] = 1;
value[1] = 1;
res = i2c_set(&I2C_USBPD, USBPD_ADDRESS, 0x33, value, sizeof(value));
res = i2c_set(&I2C_USBPD, USBPD_ADDRESS, REG_TX_SINK_CAPABILITIES, value, sizeof(value));
if (res < 0) {
DEBUG("ERR %04X\n", -res);
return;
Expand All @@ -223,7 +245,7 @@ void usbpd_enable_charging(void) {

// Read current value
uint8_t value[2] = { 0 };
res = i2c_get(&I2C_USBPD, USBPD_ADDRESS, 0x33, value, sizeof(value));
res = i2c_get(&I2C_USBPD, USBPD_ADDRESS, REG_TX_SINK_CAPABILITIES, value, sizeof(value));
if (res < 0) {
DEBUG("ERR %04X\n", -res);
return;
Expand All @@ -238,7 +260,7 @@ void usbpd_enable_charging(void) {
// Enable the first two TX sink PDO (5V and 20V)
value[0] = 1;
value[1] = 2;
res = i2c_set(&I2C_USBPD, USBPD_ADDRESS, 0x33, value, sizeof(value));
res = i2c_set(&I2C_USBPD, USBPD_ADDRESS, REG_TX_SINK_CAPABILITIES, value, sizeof(value));
if (res < 0) {
DEBUG("ERR %04X\n", -res);
return;
Expand All @@ -253,3 +275,118 @@ void usbpd_enable_charging(void) {

DEBUG("OK\n");
}

#else // HAVE_USBPD_CHARGING

void usbpd_event(void) {
bool update = false;

static bool last_ac_in = false;
bool ac_in = !gpio_get(&ACIN_N);
if (ac_in != last_ac_in) {
last_ac_in = ac_in;
update = true;

DEBUG("AC_IN %d\n", ac_in);
}

if (update) {
int16_t res;

DEBUG("USBPD DATA STATUS ");

// Read current value
uint8_t value[6] = { 0 };
res = i2c_get(&I2C_USBPD, USBPD_ADDRESS, REG_DATA_STATUS, value, sizeof(value));
if (res < 0) {
DEBUG("ERR %04X\n", -res);
} else {
DEBUG(
"OK %02x = %02X, %02X%02X%02X%02X\n",
value[0],
value[5],
value[4],
value[3],
value[2],
value[1]
);
}
}
}

void usbpd_disable_charging(void) {}

#endif // HAVE_USBPD_CHARGING

bool usbc_mux_info(uint8_t port, uint16_t *info) {
if (port != 0) {
// Only port 0 is supported right now
WARN("usbc_mux_info does not support port %d\n", port);
return false;
}

uint8_t value[6] = { 0 };
int16_t res = i2c_get(&I2C_USBPD, USBPD_ADDRESS, REG_DATA_STATUS, value, sizeof(value));
if (res < 0) {
DEBUG("ERR %04X\n", -res);
return false;
}

uint32_t data_status = ((uint32_t)value[1]) | (((uint32_t)value[2]) << 8) |
(((uint32_t)value[3]) << 16) | (((uint32_t)value[4]) << 24);

DEBUG("OK %02X, %02x = %02X, %08X\n", res, value[0], value[5], data_status);

*info = 0;
if (data_status & REG_DATA_STATUS_DP_CONNECTION) {
*info |= CMD_USBC_MUX_INFO_DP;
}
if (data_status & REG_DATA_STATUS_USB3_CONNECTION) {
*info |= CMD_USBC_MUX_INFO_USB;
}
if (data_status & REG_DATA_STATUS_ACTIVE_CABLE) {
*info |= CMD_USBC_MUX_INFO_CABLE;
}
if (data_status & REG_DATA_STATUS_DATA_ORIENTATION) {
*info |= CMD_USBC_MUX_INFO_POLARITY;
}
if (data_status & REG_DATA_STATUS_HPD_LEVEL) {
*info |= CMD_USBC_MUX_INFO_HPD_LVL;
}
if (data_status & REG_DATA_STATUS_HPD_IRQ) {
*info |= CMD_USBC_MUX_INFO_HPD_IRQ;
}
if (data_status & REG_DATA_STATUS_USB_DATA_ROLE) {
*info |= CMD_USBC_MUX_INFO_UFP;
}
if (data_status & REG_DATA_STATUS_DEBUG_ACCESSORY_MODE) {
*info |= CMD_USBC_MUX_INFO_DBG_ACC;
}

switch (data_status & REG_DATA_STATUS_DP_PIN_ASSIGNMENT_MASK) {
case REG_DATA_STATUS_DP_PIN_ASSIGNMENT_AB:
if (data_status & REG_DATA_STATUS_USB3_CONNECTION) {
*info |= CMD_USBC_MUX_INFO_DP_MODE_B;
} else {
*info |= CMD_USBC_MUX_INFO_DP_MODE_A;
}
break;
case REG_DATA_STATUS_DP_PIN_ASSIGNMENT_CD:
if (data_status & REG_DATA_STATUS_USB3_CONNECTION) {
*info |= CMD_USBC_MUX_INFO_DP_MODE_D;
} else {
*info |= CMD_USBC_MUX_INFO_DP_MODE_C;
}
break;
case REG_DATA_STATUS_DP_PIN_ASSIGNMENT_EF:
if (data_status & REG_DATA_STATUS_USB3_CONNECTION) {
*info |= CMD_USBC_MUX_INFO_DP_MODE_F;
} else {
*info |= CMD_USBC_MUX_INFO_DP_MODE_E;
}
break;
}

DEBUG("USBC_MUX_INFO: %04X\n", *info);
return true;
}
7 changes: 6 additions & 1 deletion src/board/system76/darp10-b/board.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ CONFIG_HAVE_KBLED = y
KBLED = white_dac
CFLAGS += -DKBLED_DAC=2


# Set battery I2C bus
CFLAGS += -DI2C_SMBUS=I2C_4

Expand All @@ -36,6 +35,12 @@ CFLAGS += \
-DCHARGER_CHARGE_VOLTAGE=17600 \
-DCHARGER_INPUT_CURRENT=4740

# Set USB-PD parameters
# XXX: Actually TPS65994BH
CONFIG_HAVE_USBPD = y
CONFIG_USBPD_TPS65987 = y
CFLAGS += -DI2C_USBPD=I2C_1

# Set CPU power limits in watts
CFLAGS += \
-DPOWER_LIMIT_AC=65 \
Expand Down
6 changes: 6 additions & 0 deletions src/board/system76/darp10/board.mk
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ CFLAGS += \
-DCHARGER_CHARGE_VOLTAGE=17600 \
-DCHARGER_INPUT_CURRENT=4740

# Set USB-PD parameters
# XXX: Actually TPS65994BH
CONFIG_HAVE_USBPD = y
CONFIG_USBPD_TPS65987 = y
CFLAGS += -DI2C_USBPD=I2C_1

# Set CPU power limits in watts
CFLAGS += \
-DPOWER_LIMIT_AC=65 \
Expand Down
Loading
Loading