From 5b55048ef3f851564c8dc60d111ac55dd859a49c Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 16 Mar 2023 10:17:57 -0600 Subject: [PATCH] WIP: USB-PD current detection --- src/board/system76/common/common.mk | 4 + .../system76/common/include/board/usbpd.h | 9 +++ src/board/system76/common/main.c | 2 + src/board/system76/common/power.c | 2 + src/board/system76/common/usbpd/none.c | 7 ++ src/board/system76/common/usbpd/tps65987.c | 81 +++++++++++++++++++ src/board/system76/oryp11/board.mk | 6 ++ 7 files changed, 111 insertions(+) create mode 100644 src/board/system76/common/include/board/usbpd.h create mode 100644 src/board/system76/common/usbpd/none.c create mode 100644 src/board/system76/common/usbpd/tps65987.c diff --git a/src/board/system76/common/common.mk b/src/board/system76/common/common.mk index b4c76ba..7f34a4a 100644 --- a/src/board/system76/common/common.mk +++ b/src/board/system76/common/common.mk @@ -76,6 +76,10 @@ CFLAGS+=\ CHARGER?=bq24780s board-common-y += charger/$(CHARGER).c +# Add USB-PD +USBPD?=none +board-common-y += usbpd/$(USBPD).c + # Add keyboard ifndef KEYBOARD $(error KEYBOARD is not set by the board) diff --git a/src/board/system76/common/include/board/usbpd.h b/src/board/system76/common/include/board/usbpd.h new file mode 100644 index 0000000..aa47745 --- /dev/null +++ b/src/board/system76/common/include/board/usbpd.h @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0-only + +#ifndef _BOARD_USBPD_H +#define _BOARD_USBPD_H + +void usbpd_init(void); +void usbpd_event(void); + +#endif // _BOARD_USBPD_H diff --git a/src/board/system76/common/main.c b/src/board/system76/common/main.c index 2266b9e..7e82933 100644 --- a/src/board/system76/common/main.c +++ b/src/board/system76/common/main.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,7 @@ void init(void) { pwm_init(); smbus_init(); smfi_init(); + usbpd_init(); //TODO: INTC diff --git a/src/board/system76/common/power.c b/src/board/system76/common/power.c index c90a2b1..5a1eb8c 100644 --- a/src/board/system76/common/power.c +++ b/src/board/system76/common/power.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #if CONFIG_BUS_ESPI @@ -372,6 +373,7 @@ void power_event(void) { battery_charger_configure(); } battery_debug(); + usbpd_event(); // Reset main loop cycle to force reading PECI and battery main_cycle = 0; diff --git a/src/board/system76/common/usbpd/none.c b/src/board/system76/common/usbpd/none.c new file mode 100644 index 0000000..90a4993 --- /dev/null +++ b/src/board/system76/common/usbpd/none.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-3.0-only + +#include + +void usbpd_init(void) {} + +void usbpd_event(void) {} diff --git a/src/board/system76/common/usbpd/tps65987.c b/src/board/system76/common/usbpd/tps65987.c new file mode 100644 index 0000000..7087f78 --- /dev/null +++ b/src/board/system76/common/usbpd/tps65987.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-3.0-only + +// 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 +#include +#include + +#define USBPD_ADDRESS 0x20 + +#define REG_ACTIVE_CONTRACT_PDO 0x34 + +void usbpd_init(void) { + i2c_reset(&I2C_USBPD, true); +} + +void usbpd_event(void) { + /* Dump all registers for debugging + for(uint8_t reg = 0x00; reg < 0x80; reg+=1) { + uint8_t value[65] = { 0 }; + int16_t res = i2c_get(&I2C_DGPU, USBPD_ADDRESS, reg, value, 65); + if (res < 0) { + DEBUG("USBPD %02X ERROR %04X\n", reg, res); + } else { + DEBUG("USBPD %02X OK %04X %02X =", reg, res, value[0]); + for (int i = 0; i < (int)value[0]; i++) { + DEBUG(" %02X", value[i + 1]); + } + DEBUG("\n"); + } + } + */ + + uint8_t value[7] = { 0 }; + int16_t res = i2c_get(&I2C_USBPD, USBPD_ADDRESS, REG_ACTIVE_CONTRACT_PDO, value, 7); + if (res == 7) { + if (value[0] == 6) { + uint32_t pdo = + ((uint32_t)value[1]) | + (((uint32_t)value[2]) << 8) | + (((uint32_t)value[3]) << 16) | + (((uint32_t)value[4]) << 24); + DEBUG("USBPD PDO %08lX\n", pdo); + uint8_t kind = (uint8_t)((pdo >> 30) & 0b11); + if (kind == 0b00) { + DEBUG(" FIX"); + uint32_t current_ma = (pdo & 0x3FF) * 10; + DEBUG(" %ld.%03ld A", current_ma / 1000, current_ma % 1000); + uint32_t voltage_mv = ((pdo >> 10) & 0x3FF) * 50; + DEBUG(" %ld.%03ld V", voltage_mv / 1000, voltage_mv % 1000); + } else if (kind == 0b01) { + DEBUG(" BAT"); + uint32_t power_mw = (pdo & 0x3FF) * 250; + DEBUG(" %ld.%03ld W", power_mw / 1000, power_mw % 1000); + uint32_t min_voltage_mv = ((pdo >> 10) & 0x3FF) * 50; + DEBUG(" %ld.%03ld Vmin", min_voltage_mv / 1000, min_voltage_mv % 1000); + uint32_t max_voltage_mv = ((pdo >> 20) & 0x3FF) * 50; + DEBUG(" %ld.%03ld Vax", max_voltage_mv / 1000, max_voltage_mv % 1000); + } else if (kind == 0b10) { + DEBUG(" VAR"); + uint32_t current_ma = (pdo & 0x3FF) * 10; + DEBUG(" %ld.%03ld A", current_ma / 1000, current_ma % 1000); + uint32_t min_voltage_mv = ((pdo >> 10) & 0x3FF) * 50; + DEBUG(" %ld.%03ld Vmin", min_voltage_mv / 1000, min_voltage_mv % 1000); + uint32_t max_voltage_mv = ((pdo >> 20) & 0x3FF) * 50; + DEBUG(" %ld.%03ld Vax", max_voltage_mv / 1000, max_voltage_mv % 1000); + } else { + //TODO + DEBUG(" AUG"); + } + DEBUG("\n"); + } else { + DEBUG("USBPD PDO LEN %d\n", value[0]); + } + } else if (res < 0) { + DEBUG("USBPD ERR %04X\n", -res); + } else { + DEBUG("USBPD I2C LEN %d\n", res); + } +} diff --git a/src/board/system76/oryp11/board.mk b/src/board/system76/oryp11/board.mk index 371aca1..2ffe0cb 100644 --- a/src/board/system76/oryp11/board.mk +++ b/src/board/system76/oryp11/board.mk @@ -29,6 +29,9 @@ CFLAGS+=-DI2C_SMBUS=I2C_4 # Set touchpad PS2 bus CFLAGS+=-DPS2_TOUCHPAD=PS2_3 +# Set USB-PD I2C bus +CFLAGS+=-DI2C_USBPD=I2C_1 + # Set smart charger parameters # TODO: actually bq24800 CHARGER=bq24780s @@ -39,6 +42,9 @@ CFLAGS+=\ -DCHARGER_CHARGE_VOLTAGE=17600 \ -DCHARGER_INPUT_CURRENT=11500 +# Set USB-PD parameters +USBPD=tps65987 + # Set CPU power limits in watts CFLAGS+=\ -DPOWER_LIMIT_AC=230 \