From aa440b9533a436492d8fda3b8535f2b68e58fbab Mon Sep 17 00:00:00 2001 From: Wenting Zhang Date: Sat, 3 Feb 2024 23:32:43 -0500 Subject: [PATCH] Implement USB mux firmware support --- fw/CMakeLists.txt | 1 + fw/ptn3460.c | 19 ++++++------- fw/ptn3460.h | 1 + fw/usb_mux.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ fw/usb_mux.h | 48 +++++++++++++++++++++++++++++++++ fw/usb_pd_driver.c | 8 +++--- fw/usb_pd_driver.h | 5 +++- fw/usb_pd_protocol.c | 7 ++++- 8 files changed, 136 insertions(+), 16 deletions(-) create mode 100644 fw/usb_mux.c create mode 100644 fw/usb_mux.h diff --git a/fw/CMakeLists.txt b/fw/CMakeLists.txt index 6615d4e..153d023 100644 --- a/fw/CMakeLists.txt +++ b/fw/CMakeLists.txt @@ -35,6 +35,7 @@ add_executable(fw ptn3460.c tcpm_driver.c tps65185.c + usb_mux.c usb_pd_driver.c usb_pd_policy.c usb_pd_protocol.c diff --git a/fw/ptn3460.c b/fw/ptn3460.c index 1f8a10e..5054c49 100644 --- a/fw/ptn3460.c +++ b/fw/ptn3460.c @@ -23,6 +23,7 @@ #include #include "pico/stdlib.h" #include "hardware/i2c.h" +#include "config.h" #include "ptn3460.h" #include "utils.h" #include "edid.h" @@ -79,7 +80,7 @@ void ptn3460_init(void) { gpio_init(PTN3460_VALID_PIN); gpio_set_dir(PTN3460_VALID_PIN, GPIO_IN); gpio_pull_down(PTN3460_VALID_PIN); - sleep_ms(100); + sleep_ms(50); // wait for HPD to become high int ticks = 0; while (gpio_get(PTN3460_HPD_PIN) != true) { @@ -94,18 +95,14 @@ void ptn3460_init(void) { ptn3460_select_edid_emulation(0); ptn3460_load_edid(edid_get_raw()); - //ptn3460_write(0x80, 0x02); // Set AUX reverse ptn3460_write(0x81, 0x29); // 18bpp, clock on odd bus, dual channel +} - /*uint8_t buf[2]; - int result; - buf[0] = (uint8_t)0x80; - buf[1] = (uint8_t)0x02; - result = i2c_write_blocking(PTN3460_I2C, PTN3460_I2C_ADDRESS, - buf, 2, false); - if (result != 2) { - fatal("Failed writing data to PTN3460\n"); - }*/ +void ptn3460_set_aux_polarity(int reverse) { + if (reverse) + ptn3460_write(0x80, 0x02); // Enable AUX reverse + else + ptn3460_write(0x80, 0x00); // Disable AUX reverse } bool ptn3460_is_valid(void) { diff --git a/fw/ptn3460.h b/fw/ptn3460.h index 1ef101c..b305cdb 100644 --- a/fw/ptn3460.h +++ b/fw/ptn3460.h @@ -23,5 +23,6 @@ #ifdef INPUT_TYPEC void ptn3460_init(void); +void ptn3460_set_aux_polarity(int reverse); bool ptn3460_is_valid(void); #endif \ No newline at end of file diff --git a/fw/usb_mux.c b/fw/usb_mux.c new file mode 100644 index 0000000..68a5976 --- /dev/null +++ b/fw/usb_mux.c @@ -0,0 +1,63 @@ +// +// Copyright 2024 Wenting Zhang +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +#include +#include +#include "pico/stdlib.h" +#include "hardware/i2c.h" +#include "config.h" +#include "ptn3460.h" +#include "utils.h" +#include "usb_mux.h" + +#ifdef INPUT_TYPEC + +#define USBC_ORI_PIN 10 + +void usb_mux_init(int port) { + gpio_init(USBC_ORI_PIN); + gpio_set_dir(USBC_ORI_PIN, GPIO_OUT); + gpio_put(USBC_ORI_PIN, 0); +} + +void usb_mux_set(int port, enum typec_mux mux_mode, + enum usb_switch usb_config, int polarity) { + printf("USB MUX set %s, %d\n", + (usb_config == USB_SWITCH_CONNECT) ? "CONNECT" : + (usb_config == USB_SWITCH_DISCONNECT) ? "DISCONNECT" : "RESTORE", + polarity); + if (usb_config == USB_SWITCH_CONNECT) { + if (polarity == 0) { + // Not flipped + printf("Setting orientation to not flipped\n"); + gpio_put(USBC_ORI_PIN, 1); + ptn3460_set_aux_polarity(1); + } + else { + // Flipped + printf("Setting orientation to flipped\n"); + gpio_put(USBC_ORI_PIN, 0); + ptn3460_set_aux_polarity(0); + } + } +} + +#endif diff --git a/fw/usb_mux.h b/fw/usb_mux.h new file mode 100644 index 0000000..0f16e74 --- /dev/null +++ b/fw/usb_mux.h @@ -0,0 +1,48 @@ +// +// Copyright 2024 Wenting Zhang +// +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +/* USB mux driver */ +#ifndef __CROS_EC_USB_MUX_H +#define __CROS_EC_USB_MUX_H + +#include "usb_pd.h" + +/* USB-C mux state */ +typedef uint8_t mux_state_t; + +enum typec_mux { + TYPEC_MUX_NONE = 0, /* Open switch */ + TYPEC_MUX_USB, /* USB only */ + TYPEC_MUX_DP, /* DP only */ + TYPEC_MUX_DOCK /* Both USB and DP */ +}; + +enum usb_switch { + USB_SWITCH_CONNECT, + USB_SWITCH_DISCONNECT, + USB_SWITCH_RESTORE, +}; + +/** + * Initialize USB mux to its default state. + * + * @param port Port number. + */ +void usb_mux_init(int port); + +/** + * Configure superspeed muxes on type-C port. + * + * @param port port number. + * @param mux_mode mux selected function. + * @param usb_config usb2.0 selected function. + * @param polarity plug polarity (0=CC1, 1=CC2). + */ +void usb_mux_set(int port, enum typec_mux mux_mode, + enum usb_switch usb_config, int polarity); + +#endif \ No newline at end of file diff --git a/fw/usb_pd_driver.c b/fw/usb_pd_driver.c index 030cace..c9ed657 100644 --- a/fw/usb_pd_driver.c +++ b/fw/usb_pd_driver.c @@ -1,5 +1,5 @@ // -// Copyright 2022 Wenting Zhang +// Copyright 2024 Wenting Zhang // Copyright 2017 Jason Cerundolo // // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -21,6 +21,7 @@ // SOFTWARE. // #include "pico/stdlib.h" +#include #include "usb_pd_driver.h" #include "usb_pd.h" @@ -56,12 +57,13 @@ const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); void pd_set_input_current_limit(int port, uint32_t max_ma, uint32_t supply_voltage) { - + printf("Setting input current limit to %d V %d mA\n", supply_voltage, max_ma); } int pd_is_valid_input_voltage(int mv) { - return 1; + printf("Checking valid input voltage %d mV\n", mv); + return (mv < 5500); } int pd_snk_is_vbus_provided(int port) diff --git a/fw/usb_pd_driver.h b/fw/usb_pd_driver.h index d2add13..656df03 100644 --- a/fw/usb_pd_driver.h +++ b/fw/usb_pd_driver.h @@ -1,5 +1,5 @@ // -// Copyright 2022 Wenting Zhang +// Copyright 2024 Wenting Zhang // Copyright 2017 Jason Cerundolo // // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -59,6 +59,9 @@ extern "C" { #undef CONFIG_USB_PD_INITIAL_DRP_STATE #define CONFIG_USB_PD_INITIAL_DRP_STATE PD_DRP_FREEZE +/* Board has mux */ +#define CONFIG_USBC_SS_MUX + /* board specific type-C power constants */ /* * delay to turn on the power supply max is ~16ms. diff --git a/fw/usb_pd_protocol.c b/fw/usb_pd_protocol.c index a4e56ed..7a3eec3 100644 --- a/fw/usb_pd_protocol.c +++ b/fw/usb_pd_protocol.c @@ -1,3 +1,7 @@ +// +// Copyright 2024 Wenting Zhang +// Copyright 2017 Jason Cerundolo +// /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. @@ -9,6 +13,7 @@ #include "pico/stdlib.h" #include "usb_pd.h" #include "usb_pd_tcpm.h" +#include "usb_mux.h" #include "tcpm.h" #include "usb_pd_driver.h" @@ -846,7 +851,7 @@ static void handle_vdm_request(int port, int cnt, uint32_t *payload) int rlen = 0; uint32_t *rdata; - CPRINTF("VDM request"); + CPRINTF("VDM request\n"); if (pd[port].vdm_state == VDM_STATE_BUSY) { /* If UFP responded busy retry after timeout */ if (PD_VDO_CMDT(payload[0]) == CMDT_RSP_BUSY) {