Skip to contentSkip to conversation

Add Richtek RT1719 USBPD controller support

PATCH Superseded cy_huang 3 participants 6 messages Feb 7, 2022 – Feb 9, 2022

Subsystems (3)

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore

cy_huang

author
#0 lore raw

v3 cover Add Richtek RT1719 USBPD controller support

From: ChiYuan Huang <[email protected]>

Since v3:
1. Fix checkpatch.pl consistent space error in line 332.
2. Refine some error codes to more appropriate one.
3. In psy_set_property, except prop VOLTAGE_NOW, directly return -EINVAL.
4. Use devm_kasprintf to replace devm_kzalloc and snprintf in psy_register function.

Since v2:
1. Fix below kernel test robot build warning.

Quoted 1 line
Quoted 1 line

drivers/usb/typec/rt1719.c:492:65: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]

     492 |                                  RT1719_EVALMODE_MASK | src_sel + 1);
         |                                                         ~~~~~~~~^~~

ChiYuan Huang (2):
dt-bindings: usb: rt1719: Add binding for Richtek RT1719
usb: typec: rt1719: Add support for Richtek RT1719

 .../devicetree/bindings/usb/richtek,rt1719.yaml    |  85 ++
 drivers/usb/typec/Kconfig                          |  12 +
 drivers/usb/typec/Makefile                         |   1 +
 drivers/usb/typec/rt1719.c                         | 970 +++++++++++++++++++++
 4 files changed, 1068 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/richtek,rt1719.yaml
 create mode 100644 drivers/usb/typec/rt1719.c
Signature · 1 line
2.7.4
author
#1 lore raw

PATCH v3 1/2 dt-bindings: usb: rt1719: Add binding for Richtek RT1719

From: ChiYuan Huang <[email protected]>

Add binding for Richtek RT1719.

---
 .../devicetree/bindings/usb/richtek,rt1719.yaml    | 85 ++++++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/richtek,rt1719.yaml
Documentation/devicetree/bindings/usb/richtek,rt1719.yaml new file +85 -0
new file mode 100644
index 00000000..65a93f7
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/richtek,rt1719.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Richtek RT1719 sink-only Type-C PD controller bindings
+
+maintainers:
+  - ChiYuan Huang <[email protected]>
+
+description: |
+  The RT1719 is a sink-only USB Type-C contoller that complies with the latest
+  USB Type-C and PD standards. It does the USB Type-C detection including attach
+  and orientation. It integrates the physical layer of the USB BMC power
+  delivery protocol to allow up to 100W of power. The BMC PD block enables full
+  support for alternative interfaces of the Type-C specification.
+
+properties:
+  compatible:
+    enum:
+      - richtek,rt1719
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  wakeup-source:
+    description: enable IRQ remote wakeup, see power/wakeup-source.txt
+    type: boolean
+
+  connector:
+    type: object
+    $ref: ../connector/usb-connector.yaml#
+    description:
+      Properties for usb c connector.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - connector
+  - interrupts
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c0 {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      rt1719@43 {
+        compatible = "richtek,rt1719";
+        reg = <0x43>;
+        interrupts-extended = <&gpio26 2 IRQ_TYPE_LEVEL_LOW>;
+        wakeup-source;
+
+        connector {
+          compatible = "usb-c-connector";
+          label = "USB-C";
+
+          ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+              reg = <0>;
+              endpoint {
+                remote-endpoint = <&usb_hs>;
+              };
+            };
+            port@1 {
+              reg = <1>;
+              endpoint {
+                remote-endpoint = <&usb_ss>;
+              };
+            };
+          };
+        };
+      };
+    };
+...
Signature · 1 line
2.7.4
maintainer Reviewed-by on v3 1/2
#2 lore raw

Re: [PATCH v3 1/2] dt-bindings: usb: rt1719: Add binding for Richtek RT1719

Quoted 10 lines · cy_huang

From: ChiYuan Huang <[email protected]>

Add binding for Richtek RT1719.

---
 .../devicetree/bindings/usb/richtek,rt1719.yaml    | 85 ++++++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/richtek,rt1719.yaml
author
#3 lore raw

PATCH v3 2/2 usb: typec: rt1719: Add support for Richtek RT1719

In reply to cy_huang

From: ChiYuan Huang <[email protected]>

Richtek RT1719 is a sink-only Type-C PD controller it complies with latest USB Type-C and PD standards. It integrates the physical layer of USB power delivery protocol to allow up to 100W of power.

---
 drivers/usb/typec/Kconfig  |  12 +
 drivers/usb/typec/Makefile |   1 +
 drivers/usb/typec/rt1719.c | 970 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 983 insertions(+)
 create mode 100644 drivers/usb/typec/rt1719.c
drivers/usb/typec/Kconfig +12 -0
index ab480f3..bc918ca 100644
@@ -52,6 +52,18 @@ source "drivers/usb/typec/ucsi/Kconfig"
 
 source "drivers/usb/typec/tipd/Kconfig"
 
+config TYPEC_RT1719
+	tristate "Richtek RT1719 Sink Only Type-C controller driver"
+	depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  Say Y or M here if your system has Richtek RT1719 sink only
+	  Type-C port controller driver.
+
+	  If you choose to build this driver as a dynamically linked module, the
+	  module will be called rt1719.ko
+
 config TYPEC_HD3SS3220
 	tristate "TI HD3SS3220 Type-C DRP Port controller driver"
 	depends on I2C
drivers/usb/typec/Makefile +1 -0
index 57870a2..441dd6c 100644
@@ -9,4 +9,5 @@ obj-$(CONFIG_TYPEC_TPS6598X)	+= tipd/
 obj-$(CONFIG_TYPEC_HD3SS3220)	+= hd3ss3220.o
 obj-$(CONFIG_TYPEC_QCOM_PMIC)	+= qcom-pmic-typec.o
 obj-$(CONFIG_TYPEC_STUSB160X) 	+= stusb160x.o
+obj-$(CONFIG_TYPEC_RT1719)	+= rt1719.o
 obj-$(CONFIG_TYPEC)		+= mux/
drivers/usb/typec/rt1719.c new file +970 -0

970 lines not on this page · raw message

Signature · 1 line
2.7.4
maintainer
#4 lore raw

Re: [PATCH v3 2/2] usb: typec: rt1719: Add support for Richtek RT1719

Hi,

Sorry, there is still one more problem that I realised - not your problem, but a problem with fw_devlink_purge_absent_suppliers()...

Quoted 31 lines · cy_huang
drivers/usb/typec/rt1719.c new file +31 -0
+static int rt1719_probe(struct i2c_client *i2c)
+{
+	struct rt1719_data *data;
+	struct fwnode_handle *fwnode;
+	struct typec_capability typec_cap = { };
+	int ret;
+
+	data = devm_kzalloc(&i2c->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->dev = &i2c->dev;
+	init_completion(&data->req_completion);
+
+	data->regmap = devm_regmap_init_i2c(i2c, &rt1719_regmap_config);
+	if (IS_ERR(data->regmap)) {
+		ret = PTR_ERR(data->regmap);
+		dev_err(&i2c->dev, "Failed to init regmap (%d)\n", ret);
+		return ret;
+	}
+
+	ret = rt1719_check_exist(data);
+	if (ret)
+		return ret;
+
+	ret = rt1719_get_caps(data);
+	if (ret)
+		return ret;
+
+	/*
+	 * This fwnode has a "compatible" property, but is never populated as a

drivers/usb/typec/rt1719.c line 883

Quoted 10 lines
drivers/usb/typec/rt1719.c new file +10 -0
+	 * struct device. Instead we simply parse it to read the properties.
+	 * This it breaks fw_devlink=on. To maintain backward compatibility
+	 * with existing DT files, we work around this by deleting any
+	 * fwnode_links to/from this fwnode.
+	 */
+	fwnode = device_get_named_child_node(&i2c->dev, "connector");
+	if (!fwnode)
+		return -ENODEV;
+
+	fw_devlink_purge_absent_suppliers(fwnode);

So don't use that function unless you really see some issue that it's fixing yourself.

That function is broken. It breaks at least if the fwnode is shared - fwnodes can be, and are, shared - most likely it's broken in some other ways too. That function seems to be a hack for some individual problem that was caused by some deeper problem with the device links.

We really need to figure out a fix for the core problem now instead of trying to come up with these hacks for every single separate scenario that is breaking because of the core problem, what ever that core problem may be.

Quoted 76 lines
drivers/usb/typec/rt1719.c new file +76 -0
+	data->role_sw = fwnode_usb_role_switch_get(fwnode);
+	if (IS_ERR(data->role_sw)) {
+		ret = PTR_ERR(data->role_sw);
+		dev_err(&i2c->dev, "Failed to get usb role switch (%d)\n", ret);
+		goto err_fwnode_put;
+	}
+
+	ret = devm_rt1719_psy_register(data);
+	if (ret) {
+		dev_err(&i2c->dev, "Failed to register psy (%d)\n", ret);
+		goto err_role_put;
+	}
+
+	typec_cap.revision = USB_TYPEC_REV_1_2;
+	typec_cap.pd_revision = 0x300;	/* USB-PD spec release 3.0 */
+	typec_cap.type = TYPEC_PORT_SNK;
+	typec_cap.data = TYPEC_PORT_DRD;
+	typec_cap.ops = &rt1719_port_ops;
+	typec_cap.fwnode = fwnode;
+	typec_cap.driver_data = data;
+	typec_cap.accessory[0] = TYPEC_ACCESSORY_DEBUG;
+
+	data->partner_desc.identity = &data->partner_ident;
+
+	data->port = typec_register_port(&i2c->dev, &typec_cap);
+	if (IS_ERR(data->port)) {
+		ret = PTR_ERR(data->port);
+		dev_err(&i2c->dev, "Failed to register typec port (%d)\n", ret);
+		goto err_role_put;
+	}
+
+	ret = rt1719_init_attach_state(data);
+	if (ret) {
+		dev_err(&i2c->dev, "Failed to init attach state (%d)\n", ret);
+		goto err_role_put;
+	}
+
+	ret = rt1719_irq_init(data);
+	if (ret) {
+		dev_err(&i2c->dev, "Failed to init irq\n");
+		goto err_role_put;
+	}
+
+	fwnode_handle_put(fwnode);
+
+	i2c_set_clientdata(i2c, data);
+
+	return 0;
+
+err_role_put:
+	usb_role_switch_put(data->role_sw);
+err_fwnode_put:
+	fwnode_handle_put(fwnode);
+
+	return ret;
+}
+
+static int rt1719_remove(struct i2c_client *i2c)
+{
+	struct rt1719_data *data = i2c_get_clientdata(i2c);
+
+	typec_unregister_port(data->port);
+	usb_role_switch_put(data->role_sw);
+
+	return 0;
+}
+
+static const struct of_device_id __maybe_unused rt1719_device_table[] = {
+	{ .compatible = "richtek,rt1719", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, rt1719_device_table);
+
+static struct i2c_driver rt1719_driver = {
+	.driver = {
+		.name = "rt1719",

drivers/usb/typec/rt1719.c line 970

Quoted 10 lines
drivers/usb/typec/rt1719.c new file +10 -0
+		.of_match_table = rt1719_device_table,
+	},
+	.probe_new = rt1719_probe,
+	.remove = rt1719_remove,
+};
+module_i2c_driver(rt1719_driver);
+
+MODULE_AUTHOR("ChiYuan Huang <[email protected]>");
+MODULE_DESCRIPTION("Richtek RT1719 Sink Only USBPD Controller Driver");
+MODULE_LICENSE("GPL v2");

Oh, you probable want the make that "GPL" instead. See Documentation/process/license-rules.rst.

thanks,

Signature · 1 line
heikki
#5 lore raw

Re: [PATCH v3 2/2] usb: typec: rt1719: Add support for Richtek RT1719

Heikki Krogerus <[email protected]> 於 2022年2月9日 週三 下午8:52寫道:

Quoted 58 lines

Hi,

Sorry, there is still one more problem that I realised - not your problem, but a problem with fw_devlink_purge_absent_suppliers()...

Quoted 31 lines · cy_huang
drivers/usb/typec/rt1719.c new file +31 -0
+static int rt1719_probe(struct i2c_client *i2c)
+{
+     struct rt1719_data *data;
+     struct fwnode_handle *fwnode;
+     struct typec_capability typec_cap = { };
+     int ret;
+
+     data = devm_kzalloc(&i2c->dev, sizeof(*data), GFP_KERNEL);
+     if (!data)
+             return -ENOMEM;
+
+     data->dev = &i2c->dev;
+     init_completion(&data->req_completion);
+
+     data->regmap = devm_regmap_init_i2c(i2c, &rt1719_regmap_config);
+     if (IS_ERR(data->regmap)) {
+             ret = PTR_ERR(data->regmap);
+             dev_err(&i2c->dev, "Failed to init regmap (%d)\n", ret);
+             return ret;
+     }
+
+     ret = rt1719_check_exist(data);
+     if (ret)
+             return ret;
+
+     ret = rt1719_get_caps(data);
+     if (ret)
+             return ret;
+
+     /*
+      * This fwnode has a "compatible" property, but is never populated as a

drivers/usb/typec/rt1719.c line 883

Quoted 10 lines
drivers/usb/typec/rt1719.c new file +10 -0
+      * struct device. Instead we simply parse it to read the properties.
+      * This it breaks fw_devlink=on. To maintain backward compatibility
+      * with existing DT files, we work around this by deleting any
+      * fwnode_links to/from this fwnode.
+      */
+     fwnode = device_get_named_child_node(&i2c->dev, "connector");
+     if (!fwnode)
+             return -ENODEV;
+
+     fw_devlink_purge_absent_suppliers(fwnode);

So don't use that function unless you really see some issue that it's fixing yourself.

That function is broken. It breaks at least if the fwnode is shared - fwnodes can be, and are, shared - most likely it's broken in some other ways too. That function seems to be a hack for some individual problem that was caused by some deeper problem with the device links.

Quoted 5 lines

We really need to figure out a fix for the core problem now instead of trying to come up with these hacks for every single separate scenario that is breaking because of the core problem, what ever that core problem may be.

OK, I'll remove it.

Originally, I think the others use it to solve fwlink problem. But I didn't realize actually it's a workaround.

Quoted 81 lines
Quoted 81 lines
drivers/usb/typec/rt1719.c new file +81 -0
+     data->role_sw = fwnode_usb_role_switch_get(fwnode);
+     if (IS_ERR(data->role_sw)) {
+             ret = PTR_ERR(data->role_sw);
+             dev_err(&i2c->dev, "Failed to get usb role switch (%d)\n", ret);
+             goto err_fwnode_put;
+     }
+
+     ret = devm_rt1719_psy_register(data);
+     if (ret) {
+             dev_err(&i2c->dev, "Failed to register psy (%d)\n", ret);
+             goto err_role_put;
+     }
+
+     typec_cap.revision = USB_TYPEC_REV_1_2;
+     typec_cap.pd_revision = 0x300;  /* USB-PD spec release 3.0 */
+     typec_cap.type = TYPEC_PORT_SNK;
+     typec_cap.data = TYPEC_PORT_DRD;
+     typec_cap.ops = &rt1719_port_ops;
+     typec_cap.fwnode = fwnode;
+     typec_cap.driver_data = data;
+     typec_cap.accessory[0] = TYPEC_ACCESSORY_DEBUG;
+
+     data->partner_desc.identity = &data->partner_ident;
+
+     data->port = typec_register_port(&i2c->dev, &typec_cap);
+     if (IS_ERR(data->port)) {
+             ret = PTR_ERR(data->port);
+             dev_err(&i2c->dev, "Failed to register typec port (%d)\n", ret);
+             goto err_role_put;
+     }
+
+     ret = rt1719_init_attach_state(data);
+     if (ret) {
+             dev_err(&i2c->dev, "Failed to init attach state (%d)\n", ret);
+             goto err_role_put;
+     }
+
+     ret = rt1719_irq_init(data);
+     if (ret) {
+             dev_err(&i2c->dev, "Failed to init irq\n");
+             goto err_role_put;
+     }
+
+     fwnode_handle_put(fwnode);
+
+     i2c_set_clientdata(i2c, data);
+
+     return 0;
+
+err_role_put:
+     usb_role_switch_put(data->role_sw);
+err_fwnode_put:
+     fwnode_handle_put(fwnode);
+
+     return ret;
+}
+
+static int rt1719_remove(struct i2c_client *i2c)
+{
+     struct rt1719_data *data = i2c_get_clientdata(i2c);
+
+     typec_unregister_port(data->port);
+     usb_role_switch_put(data->role_sw);
+
+     return 0;
+}
+
+static const struct of_device_id __maybe_unused rt1719_device_table[] = {
+     { .compatible = "richtek,rt1719", },
+     { }
+};
+MODULE_DEVICE_TABLE(of, rt1719_device_table);
+
+static struct i2c_driver rt1719_driver = {
+     .driver = {
+             .name = "rt1719",
+             .of_match_table = rt1719_device_table,
+     },
+     .probe_new = rt1719_probe,
+     .remove = rt1719_remove,
+};
Quoted 9 lines

drivers/usb/typec/rt1719.c line 970

Quoted 5 lines
drivers/usb/typec/rt1719.c new file +5 -0
+module_i2c_driver(rt1719_driver);
+
+MODULE_AUTHOR("ChiYuan Huang <[email protected]>");
+MODULE_DESCRIPTION("Richtek RT1719 Sink Only USBPD Controller Driver");
+MODULE_LICENSE("GPL v2");

Oh, you probable want the make that "GPL" instead. See Documentation/process/license-rules.rst.

Ack in next.

Quoted 4 lines

thanks,

--
heikki