This adds the missing bits to support the USB-C Altmode
support on SM8550.
These are the following changes since the previous SM8450 SoC:
- No more GLINK altmode events for USB only changes, only DP
- Type-C orientation is available on a PMIC signal connected
to a GPIO line
- When altmode is disconnected, an 0xff mode event is sent.
In order to handle those changes, a new orientation-gpios property
is added to the usb-c connector bindings.
The 0xff altomode is translated as a SAFE type-c mux mode.
And in order to handle such info, we tie this to the UCSI connector
events to propagate the orientation to Type-C switches.
Signed-off-by: Neil Armstrong <[email protected]>
---
Neil Armstrong (7):
dt-bindings: connector: usb-connector: add a gpio used to determine the Type-C port plug orientation
soc: qcom: pmic_glink_altmode: handle safe mode when disconnect
usb: ucsi: glink: use the connector orientation GPIO to provide switch events
qcom: pmic_glink: enable altmode for SM8550
arm64: dts: qcom: sm8550: add ports subnodes in usb/dp qmpphy node
arm64: dts: qcom: sm8550-mtp: add pmic glink port/endpoints
arm64: dts: qcom: sm8550-qrd: add pmic glink port/endpoints
.../bindings/connector/usb-connector.yaml | 5 ++
arch/arm64/boot/dts/qcom/sm8550-mtp.dts | 67 ++++++++++++++-
arch/arm64/boot/dts/qcom/sm8550-qrd.dts | 99 +++++++++++++++++++++-
arch/arm64/boot/dts/qcom/sm8550.dtsi | 26 ++++++
drivers/soc/qcom/pmic_glink.c | 6 +-
drivers/soc/qcom/pmic_glink_altmode.c | 18 +++-
drivers/usb/typec/ucsi/ucsi_glink.c | 52 +++++++++++-
7 files changed, 262 insertions(+), 11 deletions(-)
---
base-commit: f339b18115200db76b42475e44e3bc926e3ecab0
change-id: 20230601-topic-sm8550-upstream-type-c-e85b4d971450
Best regards,
--
Neil Armstrong <[email protected]>
On some platforms, the Type-C plug orientation is given on a GPIO line.
Document this optional Type-C connector property, and take the
assumption an active level represents an inverted/flipped orientation.
Signed-off-by: Neil Armstrong <[email protected]>
---
Documentation/devicetree/bindings/connector/usb-connector.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml
index ae515651fc6b..c3884eed6ba4 100644
--- a/Documentation/devicetree/bindings/connector/usb-connector.yaml
+++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml
@@ -114,6 +114,11 @@ properties:
description: Set this property if the Type-C connector has no power delivery support.
type: boolean
+ orientation-gpios:
+ description: An input gpio for Type-C connector orientation, used to detect orientation
+ of the Type-C connector. GPIO active level means "CC2" or Reversed/Flipped orientation.
+ maxItems: 1
+
# The following are optional properties for "usb-c-connector" with power
# delivery support.
source-pdos:
--
2.34.1
Altmode is also supported for SM8550, allow it.
Signed-off-by: Neil Armstrong <[email protected]>
---
drivers/soc/qcom/pmic_glink.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c
index c87056769ebd..8af06bdc6f5a 100644
--- a/drivers/soc/qcom/pmic_glink.c
+++ b/drivers/soc/qcom/pmic_glink.c
@@ -342,13 +342,9 @@ static const unsigned long pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT
BIT(PMIC_GLINK_CLIENT_ALTMODE) |
BIT(PMIC_GLINK_CLIENT_UCSI);
-/* Do not handle altmode for now on those platforms */
-static const unsigned long pmic_glink_sm8550_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) |
- BIT(PMIC_GLINK_CLIENT_UCSI);
-
static const struct of_device_id pmic_glink_of_match[] = {
{ .compatible = "qcom,sm8450-pmic-glink", .data = &pmic_glink_sm8450_client_mask },
- { .compatible = "qcom,sm8550-pmic-glink", .data = &pmic_glink_sm8550_client_mask },
+ { .compatible = "qcom,sm8550-pmic-glink", .data = &pmic_glink_sm8450_client_mask },
{ .compatible = "qcom,pmic-glink" },
{}
};
--
2.34.1
Add the USB3+DP Combo QMP PHY port subnodes in the SM8550 SoC DTSI
to avoid duplication in the devices DTs.
Signed-off-by: Neil Armstrong <[email protected]>
---
arch/arm64/boot/dts/qcom/sm8550.dtsi | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
index b41b3981b3ce..ca2280041f83 100644
--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
@@ -2838,6 +2838,32 @@ usb_dp_qmpphy: phy@88e8000 {
#phy-cells = <1>;
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_dp_qmpphy_out: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_dp_qmpphy_usb_ss_in: endpoint {
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ usb_dp_qmpphy_dp_in: endpoint {
+ };
+ };
+ };
};
usb_1: usb@a6f8800 {
--
2.34.1
On some Qcom SoCs, the Altmode event mode is set to 0xff when
the Type-C port is disconnected.
Handle this specific mode and translate it as the SAFE mode.
Signed-off-by: Neil Armstrong <[email protected]>
---
drivers/soc/qcom/pmic_glink_altmode.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c
index df48fbea4b68..007d308e2f15 100644
--- a/drivers/soc/qcom/pmic_glink_altmode.c
+++ b/drivers/soc/qcom/pmic_glink_altmode.c
@@ -173,6 +173,20 @@ static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode,
dev_err(altmode->dev, "failed to switch mux to USB\n");
}
+static void pmic_glink_altmode_safe(struct pmic_glink_altmode *altmode,
+ struct pmic_glink_altmode_port *port)
+{
+ int ret;
+
+ port->state.alt = NULL;
+ port->state.data = NULL;
+ port->state.mode = TYPEC_STATE_SAFE;
+
+ ret = typec_mux_set(port->typec_mux, &port->state);
+ if (ret)
+ dev_err(altmode->dev, "failed to switch mux to safe mode\n");
+}
+
static void pmic_glink_altmode_worker(struct work_struct *work)
{
struct pmic_glink_altmode_port *alt_port = work_to_altmode_port(work);
@@ -180,7 +194,9 @@ static void pmic_glink_altmode_worker(struct work_struct *work)
typec_switch_set(alt_port->typec_switch, alt_port->orientation);
- if (alt_port->svid == USB_TYPEC_DP_SID)
+ if (alt_port->svid == USB_TYPEC_DP_SID && alt_port->mode == 0xff)
+ pmic_glink_altmode_safe(altmode, alt_port);
+ else if (alt_port->svid == USB_TYPEC_DP_SID)
pmic_glink_altmode_enable_dp(altmode, alt_port, alt_port->mode,
alt_port->hpd_state, alt_port->hpd_irq);
else
--
2.34.1
On SM8550, the non-altmode orientation is not given anymore within
altmode events, even with USB SVIDs events.
On the other side, the Type-C connector orientation is correctly
reported by a signal from the PMIC.
Take this gpio signal when we detect some Type-C port activity
to notify any Type-C switches tied to the Type-C port connectors.
Signed-off-by: Neil Armstrong <[email protected]>
---
drivers/usb/typec/ucsi/ucsi_glink.c | 52 ++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
index 1fe9cb5b6bd9..88491dbff7e3 100644
--- a/drivers/usb/typec/ucsi/ucsi_glink.c
+++ b/drivers/usb/typec/ucsi/ucsi_glink.c
@@ -9,9 +9,13 @@
#include <linux/mutex.h>
#include <linux/property.h>
#include <linux/soc/qcom/pdr.h>
+#include <linux/usb/typec_mux.h>
+#include <linux/gpio/consumer.h>
#include <linux/soc/qcom/pmic_glink.h>
#include "ucsi.h"
+#define PMIC_GLINK_MAX_PORTS 2
+
#define UCSI_BUF_SIZE 48
#define MSG_TYPE_REQ_RESP 1
@@ -53,6 +57,9 @@ struct ucsi_notify_ind_msg {
struct pmic_glink_ucsi {
struct device *dev;
+ struct gpio_desc *port_orientation[PMIC_GLINK_MAX_PORTS];
+ struct typec_switch *port_switch[PMIC_GLINK_MAX_PORTS];
+
struct pmic_glink_client *client;
struct ucsi *ucsi;
@@ -221,8 +228,20 @@ static void pmic_glink_ucsi_notify(struct work_struct *work)
}
con_num = UCSI_CCI_CONNECTOR(cci);
- if (con_num)
+ if (con_num) {
+ if (con_num < PMIC_GLINK_MAX_PORTS &&
+ ucsi->port_orientation[con_num - 1]) {
+ int orientation = gpiod_get_value(ucsi->port_orientation[con_num - 1]);
+
+ if (orientation >= 0) {
+ typec_switch_set(ucsi->port_switch[con_num - 1],
+ orientation ? TYPEC_ORIENTATION_REVERSE
+ : TYPEC_ORIENTATION_NORMAL);
+ }
+ }
+
ucsi_connector_change(ucsi->ucsi, con_num);
+ }
if (ucsi->sync_pending && cci & UCSI_CCI_BUSY) {
ucsi->sync_val = -EBUSY;
@@ -283,6 +302,7 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev,
{
struct pmic_glink_ucsi *ucsi;
struct device *dev = &adev->dev;
+ struct fwnode_handle *fwnode;
int ret;
ucsi = devm_kzalloc(dev, sizeof(*ucsi), GFP_KERNEL);
@@ -310,6 +330,36 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev,
ucsi_set_drvdata(ucsi->ucsi, ucsi);
+ device_for_each_child_node(dev, fwnode) {
+ u32 port;
+
+ ret = fwnode_property_read_u32(fwnode, "reg", &port);
+ if (ret < 0) {
+ dev_err(dev, "missing reg property of %pOFn\n", fwnode);
+ return ret;
+ }
+
+ if (port >= PMIC_GLINK_MAX_PORTS) {
+ dev_warn(dev, "invalid connector number, ignoring\n");
+ continue;
+ }
+
+ ucsi->port_orientation[port] = devm_fwnode_gpiod_get(&adev->dev, fwnode,
+ "orientation",
+ GPIOD_IN, NULL);
+ if (IS_ERR(ucsi->port_orientation[port]))
+ return dev_err_probe(dev, PTR_ERR(ucsi->port_orientation[port]),
+ "unable to acquire orientation gpio\n");
+
+ if (!ucsi->port_orientation[port])
+ continue;
+
+ ucsi->port_switch[port] = fwnode_typec_switch_get(fwnode);
+ if (IS_ERR(ucsi->port_switch[port]))
+ return dev_err_probe(dev, PTR_ERR(ucsi->port_switch[port]),
+ "failed to acquire orientation-switch\n");
+ }
+
ucsi->client = devm_pmic_glink_register_client(dev,
PMIC_GLINK_OWNER_USBC,
pmic_glink_ucsi_callback,
--
2.34.1
Add nodes to support Type-C USB/DP functionality.
On this platform, a Type-C redriver is added to the
SuperSpeed graph.
Signed-off-by: Neil Armstrong <[email protected]>
---
arch/arm64/boot/dts/qcom/sm8550-qrd.dts | 99 ++++++++++++++++++++++++++++++++-
1 file changed, 97 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
index 8669d29144bb..edb31efa563a 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
@@ -64,6 +64,7 @@ connector@0 {
reg = <0>;
power-role = "dual";
data-role = "dual";
+ orientation-gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>;
ports {
#address-cells = <1>;
@@ -81,7 +82,15 @@ port@1 {
reg = <1>;
pmic_glink_ss_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_ss>;
+ remote-endpoint = <&redriver_ss_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_sbu: endpoint {
+ remote-endpoint = <&fsa4480_sbu_mux>;
};
};
};
@@ -420,6 +429,69 @@ vreg_l3g_1p2: ldo3 {
};
};
+&i2c_master_hub_0 {
+ status = "okay";
+};
+
+&i2c_hub_2 {
+ status = "okay";
+
+ typec-mux@1c {
+ compatible = "onnn,nb7vpq904m";
+ reg = <0x1c>;
+
+ vcc-supply = <&vreg_l15b_1p8>;
+
+ mode-switch;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ redriver_ss_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ redriver_ss_in: endpoint {
+ data-lanes = <2 3 0 1>;
+ remote-endpoint = <&usb_dp_qmpphy_out>;
+ };
+ };
+ };
+ };
+
+ fsa4480@42 {
+ compatible = "fcs,fsa4480";
+ reg = <0x42>;
+
+ vcc-supply = <&vreg_bob1>;
+
+ mode-switch;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ fsa4480_sbu_mux: endpoint {
+ remote-endpoint = <&pmic_glink_sbu>;
+ };
+ };
+ };
+ };
+};
+
&gcc {
clocks = <&bi_tcxo_div2>, <&sleep_clk>,
<&pcie0_phy>,
@@ -471,6 +543,15 @@ &mdss_dsi0_phy {
status = "okay";
};
+&mdss_dp0 {
+ status = "okay";
+};
+
+&mdss_dp0_out {
+ data-lanes = <0 1>;
+ remote-endpoint = <&usb_dp_qmpphy_dp_in>;
+};
+
&pcie_1_phy_aux_clk {
status = "disabled";
};
@@ -650,7 +731,7 @@ &usb_1_dwc3_hs {
};
&usb_1_dwc3_ss {
- remote-endpoint = <&pmic_glink_ss_in>;
+ remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
};
&usb_1_hsphy {
@@ -666,9 +747,23 @@ &usb_dp_qmpphy {
vdda-phy-supply = <&vreg_l3e_1p2>;
vdda-pll-supply = <&vreg_l3f_0p88>;
+ orientation-switch;
+
status = "okay";
};
+&usb_dp_qmpphy_dp_in {
+ remote-endpoint = <&mdss_dp0_out>;
+};
+
+&usb_dp_qmpphy_out {
+ remote-endpoint = <&redriver_ss_in>;
+};
+
+&usb_dp_qmpphy_usb_ss_in {
+ remote-endpoint = <&usb_1_dwc3_ss>;
+};
+
&xo_board {
clock-frequency = <76800000>;
};
--
2.34.1
Add nodes to support Type-C USB/DP functionality.
Signed-off-by: Neil Armstrong <[email protected]>
---
arch/arm64/boot/dts/qcom/sm8550-mtp.dts | 67 ++++++++++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
index 579f65f52370..8d4741404f2d 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
@@ -80,7 +80,15 @@ port@1 {
reg = <1>;
pmic_glink_ss_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_ss>;
+ remote-endpoint = <&usb_dp_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_sbu: endpoint {
+ remote-endpoint = <&fsa4480_sbu_mux>;
};
};
};
@@ -419,6 +427,38 @@ vreg_l3g_1p2: ldo3 {
};
};
+&i2c_master_hub_0 {
+ status = "okay";
+};
+
+&i2c_hub_2 {
+ status = "okay";
+
+ fsa4480@42 {
+ compatible = "fcs,fsa4480";
+ reg = <0x42>;
+
+ vcc-supply = <&vreg_bob1>;
+
+ mode-switch;
+ orientation-switch;
+ svid = /bits/ 16 <0xff01>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ fsa4480_sbu_mux: endpoint {
+ remote-endpoint = <&pmic_glink_sbu>;
+ };
+ };
+ };
+ };
+};
+
&mdss {
status = "okay";
};
@@ -459,6 +499,15 @@ &mdss_dsi0_phy {
status = "okay";
};
+&mdss_dp0 {
+ status = "okay";
+};
+
+&mdss_dp0_out {
+ data-lanes = <0 1>;
+ remote-endpoint = <&usb_dp_qmpphy_dp_in>;
+};
+
&pcie_1_phy_aux_clk {
clock-frequency = <1000>;
};
@@ -652,7 +701,7 @@ &usb_1_dwc3_hs {
};
&usb_1_dwc3_ss {
- remote-endpoint = <&pmic_glink_ss_in>;
+ remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
};
&usb_1_hsphy {
@@ -668,9 +717,23 @@ &usb_dp_qmpphy {
vdda-phy-supply = <&vreg_l3e_1p2>;
vdda-pll-supply = <&vreg_l3f_0p91>;
+ orientation-switch;
+
status = "okay";
};
+&usb_dp_qmpphy_dp_in {
+ remote-endpoint = <&mdss_dp0_out>;
+};
+
+&usb_dp_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss_in>;
+};
+
+&usb_dp_qmpphy_usb_ss_in {
+ remote-endpoint = <&usb_1_dwc3_ss>;
+};
+
&xo_board {
clock-frequency = <76800000>;
};
--
2.34.1
On 1.06.2023 16:07, Neil Armstrong wrote:
> Add the USB3+DP Combo QMP PHY port subnodes in the SM8550 SoC DTSI
> to avoid duplication in the devices DTs.
>
> Signed-off-by: Neil Armstrong <[email protected]>
> ---
Reviewed-by: Konrad Dybcio <[email protected]>
Konrad
> arch/arm64/boot/dts/qcom/sm8550.dtsi | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
> index b41b3981b3ce..ca2280041f83 100644
> --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
> @@ -2838,6 +2838,32 @@ usb_dp_qmpphy: phy@88e8000 {
> #phy-cells = <1>;
>
> status = "disabled";
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> +
> + usb_dp_qmpphy_out: endpoint {
> + };
> + };
> +
> + port@1 {
> + reg = <1>;
> +
> + usb_dp_qmpphy_usb_ss_in: endpoint {
> + };
> + };
> +
> + port@2 {
> + reg = <2>;
> +
> + usb_dp_qmpphy_dp_in: endpoint {
> + };
> + };
> + };
> };
>
> usb_1: usb@a6f8800 {
>
On 01/06/2023 16:07, Neil Armstrong wrote:
> On some platforms, the Type-C plug orientation is given on a GPIO line.
>
Acked-by: Krzysztof Kozlowski <[email protected]>
Best regards,
Krzysztof
On 01/06/2023 17:07, Neil Armstrong wrote:
> On some platforms, the Type-C plug orientation is given on a GPIO line.
>
> Document this optional Type-C connector property, and take the
> assumption an active level represents an inverted/flipped orientation.
>
> Signed-off-by: Neil Armstrong <[email protected]>
> ---
> Documentation/devicetree/bindings/connector/usb-connector.yaml | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml
> index ae515651fc6b..c3884eed6ba4 100644
> --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml
> +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml
> @@ -114,6 +114,11 @@ properties:
> description: Set this property if the Type-C connector has no power delivery support.
> type: boolean
>
> + orientation-gpios:
> + description: An input gpio for Type-C connector orientation, used to detect orientation
> + of the Type-C connector. GPIO active level means "CC2" or Reversed/Flipped orientation.
> + maxItems: 1
Should this be a property of the connector or of the parent device node?
I mean, unlike usb-b-connector (where ID and Vbus can be simple GPIOs
nearly directly connected to the pins of the connector) for the USB-C
the orientation is not a connector's GPIO, but rather some additional
not elementary logic.
> +
> # The following are optional properties for "usb-c-connector" with power
> # delivery support.
> source-pdos:
>
--
With best wishes
Dmitry
On 03/06/2023 22:22, Dmitry Baryshkov wrote:
> On 01/06/2023 17:07, Neil Armstrong wrote:
>> On some platforms, the Type-C plug orientation is given on a GPIO line.
>>
>> Document this optional Type-C connector property, and take the
>> assumption an active level represents an inverted/flipped orientation.
>>
>> Signed-off-by: Neil Armstrong <[email protected]>
>> ---
>> Documentation/devicetree/bindings/connector/usb-connector.yaml | 5 +++++
>> 1 file changed, 5 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml
>> index ae515651fc6b..c3884eed6ba4 100644
>> --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml
>> +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml
>> @@ -114,6 +114,11 @@ properties:
>> description: Set this property if the Type-C connector has no power delivery support.
>> type: boolean
>> + orientation-gpios:
>> + description: An input gpio for Type-C connector orientation, used to detect orientation
>> + of the Type-C connector. GPIO active level means "CC2" or Reversed/Flipped orientation.
>> + maxItems: 1
>
> Should this be a property of the connector or of the parent device node? I mean, unlike usb-b-connector (where ID and Vbus can be simple GPIOs nearly directly connected to the pins of the connector) for the USB-C the orientation is not a connector's GPIO, but rather some additional not elementary logic.
I don't see the issue, orientation is a property of the connector itself,
even if it's provided by another ic.
Neil
>
>> +
>> # The following are optional properties for "usb-c-connector" with power
>> # delivery support.
>> source-pdos:
>>
>
On 05/06/2023 10:30, Neil Armstrong wrote:
> On 03/06/2023 22:22, Dmitry Baryshkov wrote:
>> On 01/06/2023 17:07, Neil Armstrong wrote:
>>> On some platforms, the Type-C plug orientation is given on a GPIO line.
>>>
>>> Document this optional Type-C connector property, and take the
>>> assumption an active level represents an inverted/flipped orientation.
>>>
>>> Signed-off-by: Neil Armstrong <[email protected]>
>>> ---
>>> Documentation/devicetree/bindings/connector/usb-connector.yaml | 5
>>> +++++
>>> 1 file changed, 5 insertions(+)
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/connector/usb-connector.yaml
>>> b/Documentation/devicetree/bindings/connector/usb-connector.yaml
>>> index ae515651fc6b..c3884eed6ba4 100644
>>> --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml
>>> +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml
>>> @@ -114,6 +114,11 @@ properties:
>>> description: Set this property if the Type-C connector has no
>>> power delivery support.
>>> type: boolean
>>> + orientation-gpios:
>>> + description: An input gpio for Type-C connector orientation,
>>> used to detect orientation
>>> + of the Type-C connector. GPIO active level means "CC2" or
>>> Reversed/Flipped orientation.
>>> + maxItems: 1
>>
>> Should this be a property of the connector or of the parent device
>> node? I mean, unlike usb-b-connector (where ID and Vbus can be simple
>> GPIOs nearly directly connected to the pins of the connector) for the
>> USB-C the orientation is not a connector's GPIO, but rather some
>> additional not elementary logic.
>
> I don't see the issue, orientation is a property of the connector itself,
> even if it's provided by another ic.
I'd argue that the _gpio_ is not a property of the connector itself.
Generic USB-C connector will not have such orientation GPIO. But
probably it is a minor issue.
>>
>>> +
>>> # The following are optional properties for "usb-c-connector"
>>> with power
>>> # delivery support.
>>> source-pdos:
>>>
>>
>
--
With best wishes
Dmitry
On Thu, Jun 01, 2023 at 04:07:03PM +0200, Neil Armstrong wrote:
> On SM8550, the non-altmode orientation is not given anymore within
> altmode events, even with USB SVIDs events.
>
> On the other side, the Type-C connector orientation is correctly
> reported by a signal from the PMIC.
>
> Take this gpio signal when we detect some Type-C port activity
> to notify any Type-C switches tied to the Type-C port connectors.
>
> Signed-off-by: Neil Armstrong <[email protected]>
Acked-by: Heikki Krogerus <[email protected]>
> ---
> drivers/usb/typec/ucsi/ucsi_glink.c | 52 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
> index 1fe9cb5b6bd9..88491dbff7e3 100644
> --- a/drivers/usb/typec/ucsi/ucsi_glink.c
> +++ b/drivers/usb/typec/ucsi/ucsi_glink.c
> @@ -9,9 +9,13 @@
> #include <linux/mutex.h>
> #include <linux/property.h>
> #include <linux/soc/qcom/pdr.h>
> +#include <linux/usb/typec_mux.h>
> +#include <linux/gpio/consumer.h>
> #include <linux/soc/qcom/pmic_glink.h>
> #include "ucsi.h"
>
> +#define PMIC_GLINK_MAX_PORTS 2
> +
> #define UCSI_BUF_SIZE 48
>
> #define MSG_TYPE_REQ_RESP 1
> @@ -53,6 +57,9 @@ struct ucsi_notify_ind_msg {
> struct pmic_glink_ucsi {
> struct device *dev;
>
> + struct gpio_desc *port_orientation[PMIC_GLINK_MAX_PORTS];
> + struct typec_switch *port_switch[PMIC_GLINK_MAX_PORTS];
> +
> struct pmic_glink_client *client;
>
> struct ucsi *ucsi;
> @@ -221,8 +228,20 @@ static void pmic_glink_ucsi_notify(struct work_struct *work)
> }
>
> con_num = UCSI_CCI_CONNECTOR(cci);
> - if (con_num)
> + if (con_num) {
> + if (con_num < PMIC_GLINK_MAX_PORTS &&
> + ucsi->port_orientation[con_num - 1]) {
> + int orientation = gpiod_get_value(ucsi->port_orientation[con_num - 1]);
> +
> + if (orientation >= 0) {
> + typec_switch_set(ucsi->port_switch[con_num - 1],
> + orientation ? TYPEC_ORIENTATION_REVERSE
> + : TYPEC_ORIENTATION_NORMAL);
> + }
> + }
> +
> ucsi_connector_change(ucsi->ucsi, con_num);
> + }
>
> if (ucsi->sync_pending && cci & UCSI_CCI_BUSY) {
> ucsi->sync_val = -EBUSY;
> @@ -283,6 +302,7 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev,
> {
> struct pmic_glink_ucsi *ucsi;
> struct device *dev = &adev->dev;
> + struct fwnode_handle *fwnode;
> int ret;
>
> ucsi = devm_kzalloc(dev, sizeof(*ucsi), GFP_KERNEL);
> @@ -310,6 +330,36 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev,
>
> ucsi_set_drvdata(ucsi->ucsi, ucsi);
>
> + device_for_each_child_node(dev, fwnode) {
> + u32 port;
> +
> + ret = fwnode_property_read_u32(fwnode, "reg", &port);
> + if (ret < 0) {
> + dev_err(dev, "missing reg property of %pOFn\n", fwnode);
> + return ret;
> + }
> +
> + if (port >= PMIC_GLINK_MAX_PORTS) {
> + dev_warn(dev, "invalid connector number, ignoring\n");
> + continue;
> + }
> +
> + ucsi->port_orientation[port] = devm_fwnode_gpiod_get(&adev->dev, fwnode,
> + "orientation",
> + GPIOD_IN, NULL);
> + if (IS_ERR(ucsi->port_orientation[port]))
> + return dev_err_probe(dev, PTR_ERR(ucsi->port_orientation[port]),
> + "unable to acquire orientation gpio\n");
> +
> + if (!ucsi->port_orientation[port])
> + continue;
> +
> + ucsi->port_switch[port] = fwnode_typec_switch_get(fwnode);
> + if (IS_ERR(ucsi->port_switch[port]))
> + return dev_err_probe(dev, PTR_ERR(ucsi->port_switch[port]),
> + "failed to acquire orientation-switch\n");
> + }
> +
> ucsi->client = devm_pmic_glink_register_client(dev,
> PMIC_GLINK_OWNER_USBC,
> pmic_glink_ucsi_callback,
>
> --
> 2.34.1
--
heikki