diff --git a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts index 346ee4b928c4b3..adb3ec7f4e71e2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts +++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (c) 2022 Rockchip Electronics Co., Ltd. - * Copyright (c) 2022 Radxa Limited. + * Copyright (c) 2023 Radxa Limited. * */ @@ -649,7 +649,6 @@ status = "okay"; }; - &u2phy0_otg { status = "okay"; }; @@ -684,6 +683,21 @@ status = "okay"; }; +&i2c3 { + status = "okay"; + pinctrl-0 = <&i2c3m1_xfer>; + + usbc0: fusb302@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + interrupt-parent = <&gpio3>; + interrupts = ; + sel-gpios= <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usbc0_int>; + }; + }; + &reserved_memory { ramoops: ramoops@110000 { compatible = "ramoops"; @@ -942,4 +956,10 @@ rockchip,pins = <3 RK_PD3 RK_FUNC_GPIO &pcfg_pull_down>; }; }; + + usb-typec { + usbc0_int: usbc0-int { + rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; }; diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c index 99ea3b3f5a1c73..5ea7ec27ebedd9 100644 --- a/drivers/usb/typec/tcpm/fusb302.c +++ b/drivers/usb/typec/tcpm/fusb302.c @@ -84,6 +84,7 @@ struct fusb302_chip { bool irq_suspended; bool irq_while_suspended; struct gpio_desc *gpio_int_n; + struct gpio_desc *gpio_sel; int gpio_int_n_irq; struct extcon_dev *extcon; @@ -105,6 +106,7 @@ struct fusb302_chip { bool vbus_on; bool charge_on; bool vbus_present; + bool devices_reversal; enum typec_cc_polarity cc_polarity; enum typec_cc_status cc1; enum typec_cc_status cc2; @@ -708,6 +710,34 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc) return ret; } +/* For a single group of USB3.0, the signal direction + output of USB3.0 needs to be selected according to + the direction of TYPE C positive and negative insertion */ +static int fusb302_sel_gpio(struct fusb302_chip *chip){ + + if (chip->cc1 == TYPEC_CC_RD && + (chip->cc2 == TYPEC_CC_OPEN || chip->cc2 == TYPEC_CC_RA)) { + chip->devices_reversal = false; + } else if (chip->cc2 == TYPEC_CC_RD && + (chip->cc1 == TYPEC_CC_OPEN || chip->cc1 == TYPEC_CC_RA)) { + chip->devices_reversal = true; + } else if (chip->cc1 == TYPEC_CC_RA && chip->cc2 == TYPEC_CC_RD) { + chip->devices_reversal = true; + } else if (chip->cc1 == TYPEC_CC_RD && chip->cc2 == TYPEC_CC_RA) { + chip->devices_reversal = false; + } else { + return -1; + } + + if(chip->devices_reversal) { + gpiod_set_value(chip->gpio_sel, 1); + } else { + gpiod_set_value(chip->gpio_sel, 0); + }; + + return 0; +} + static int tcpm_get_cc(struct tcpc_dev *dev, enum typec_cc_status *cc1, enum typec_cc_status *cc2) { @@ -1628,6 +1658,12 @@ static void fusb302_irq_work(struct kthread_work *work) } } } + + ret = fusb302_sel_gpio(chip); + if (ret < 0) { + fusb302_log(chip, "fusb302 have no usb stroage devices"); + } + done: mutex_unlock(&chip->lock); enable_irq(chip->gpio_int_n_irq); @@ -1739,6 +1775,11 @@ static int fusb302_probe(struct i2c_client *client, init_tcpc_dev(&chip->tcpc_dev); fusb302_debugfs_init(chip); + chip->gpio_sel = devm_gpiod_get(dev, "sel", GPIOD_OUT_HIGH); + if (IS_ERR(chip->gpio_sel)) { + dev_err(dev, "failed to request gpio_sel\n"); + } + if (client->irq) { chip->gpio_int_n_irq = client->irq; } else {