Add USB PHY support for CV18XX/SG200X series
Changed from v1:
1. remove dr_mode property and use default mode instead.
2. improve the description of `vbus_det-gpios` and `sophgo,switch-gpios`
Inochi Amaoto (2):
dt-bindings: phy: Add Sophgo CV1800 USB phy
phy: sophgo: Add USB 2.0 PHY driver for Sophgo CV18XX/SG200X
.../bindings/phy/sophgo,cv1800-usb-phy.yaml | 68 ++++
drivers/phy/Kconfig | 1 +
drivers/phy/Makefile | 1 +
drivers/phy/sophgo/Kconfig | 19 +
drivers/phy/sophgo/Makefile | 2 +
drivers/phy/sophgo/phy-cv1800-usb.c | 378 ++++++++++++++++++
6 files changed, 469 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
create mode 100644 drivers/phy/sophgo/Kconfig
create mode 100644 drivers/phy/sophgo/Makefile
create mode 100644 drivers/phy/sophgo/phy-cv1800-usb.c
--
2.44.0
Add USB 2.0 PHY driver for Sophgo CV18XX/SG200X.
Signed-off-by: Inochi Amaoto <[email protected]>
---
drivers/phy/Kconfig | 1 +
drivers/phy/Makefile | 1 +
drivers/phy/sophgo/Kconfig | 19 ++
drivers/phy/sophgo/Makefile | 2 +
drivers/phy/sophgo/phy-cv1800-usb.c | 378 ++++++++++++++++++++++++++++
5 files changed, 401 insertions(+)
create mode 100644 drivers/phy/sophgo/Kconfig
create mode 100644 drivers/phy/sophgo/Makefile
create mode 100644 drivers/phy/sophgo/phy-cv1800-usb.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 787354b849c7..596b37ab3191 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -92,6 +92,7 @@ source "drivers/phy/renesas/Kconfig"
source "drivers/phy/rockchip/Kconfig"
source "drivers/phy/samsung/Kconfig"
source "drivers/phy/socionext/Kconfig"
+source "drivers/phy/sophgo/Kconfig"
source "drivers/phy/st/Kconfig"
source "drivers/phy/starfive/Kconfig"
source "drivers/phy/sunplus/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 868a220ed0f6..7ff32f0ae08a 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -31,6 +31,7 @@ obj-y += allwinner/ \
rockchip/ \
samsung/ \
socionext/ \
+ sophgo/ \
st/ \
starfive/ \
sunplus/ \
diff --git a/drivers/phy/sophgo/Kconfig b/drivers/phy/sophgo/Kconfig
new file mode 100644
index 000000000000..b1c558de6616
--- /dev/null
+++ b/drivers/phy/sophgo/Kconfig
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Phy drivers for Sophgo platforms
+#
+
+if ARCH_SOPHGO || COMPILE_TEST
+
+config PHY_SOPHGO_CV1800_USB
+ tristate "Sophgo CV18XX/SG200X USB 2.0 PHY support"
+ depends on MFD_SYSCON
+ depends on USB_SUPPORT
+ select GENERIC_PHY
+ help
+ Enable this to support the USB 2.0 PHY used with
+ the DWC2 USB controller in Sophgo CV18XX/SG200X
+ series SoC.
+ If unsure, say N.
+
+endif # ARCH_SOPHGO || COMPILE_TEST
diff --git a/drivers/phy/sophgo/Makefile b/drivers/phy/sophgo/Makefile
new file mode 100644
index 000000000000..659537054cd4
--- /dev/null
+++ b/drivers/phy/sophgo/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PHY_SOPHGO_CV1800_USB) += phy-cv1800-usb.o
diff --git a/drivers/phy/sophgo/phy-cv1800-usb.c b/drivers/phy/sophgo/phy-cv1800-usb.c
new file mode 100644
index 000000000000..bf1b86f7aa1a
--- /dev/null
+++ b/drivers/phy/sophgo/phy-cv1800-usb.c
@@ -0,0 +1,378 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 Inochi Amaoto <[email protected]>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+#include <soc/sophgo/cv1800-sysctl.h>
+
+#define PHY_IDPAD_C_OW BIT(6)
+#define PHY_IDPAD_C_SW BIT(7)
+
+#define PHY_BASE_CLK_RATE 300000000
+#define PHY_APP_CLK_RATE 125000000
+#define PHY_LPM_CLK_RATE 12000000
+#define PHY_STB_CLK_RATE 333334
+
+#define PHY_VBUS_DET_DEBOUNCE_TIME usecs_to_jiffies(100)
+
+struct cv1800_usb_phy {
+ struct phy *phy;
+ struct regmap *syscon;
+ spinlock_t lock;
+ struct clk *usb_phy_clk;
+ struct clk *usb_app_clk;
+ struct clk *usb_lpm_clk;
+ struct clk *usb_stb_clk;
+ struct gpio_descs *switch_gpios;
+ struct gpio_desc *vbus_det_gpio;
+ int vbus_det_irq;
+ struct delayed_work vbus_work;
+ bool enable_otg;
+};
+
+static int cv1800_usb_phy_set_idpad(struct cv1800_usb_phy *phy,
+ bool is_host)
+{
+ unsigned long flags;
+ unsigned int regval = 0;
+ int ret;
+
+ if (is_host)
+ regval = PHY_IDPAD_C_OW;
+ else
+ regval = PHY_IDPAD_C_OW | PHY_IDPAD_C_SW;
+
+ spin_lock_irqsave(&phy->lock, flags);
+ ret = regmap_update_bits(phy->syscon, CV1800_USB_PHY_CTRL_REG,
+ PHY_IDPAD_C_OW | PHY_IDPAD_C_SW,
+ regval);
+ spin_unlock_irqrestore(&phy->lock, flags);
+
+ return ret;
+}
+
+static void cv1800_usb_phy_set_gpio(struct cv1800_usb_phy *phy,
+ bool is_host)
+{
+ unsigned int i, ndescs;
+ struct gpio_desc **gpios;
+
+ if (!phy->switch_gpios)
+ return;
+
+ ndescs = phy->switch_gpios->ndescs;
+ gpios = phy->switch_gpios->desc;
+
+ if (is_host) {
+ for (i = 0; i < ndescs; i++)
+ gpiod_set_value_cansleep(gpios[i], 0);
+ } else {
+ for (i = 0; i < ndescs; i++)
+ gpiod_set_value_cansleep(gpios[ndescs - 1 - i], 1);
+ }
+}
+
+static int cv1800_usb_phy_set_mode_internal(struct cv1800_usb_phy *phy,
+ bool is_host)
+{
+ int ret = cv1800_usb_phy_set_idpad(phy, is_host);
+
+ if (ret < 0)
+ return ret;
+
+ cv1800_usb_phy_set_gpio(phy, is_host);
+
+ return 0;
+}
+
+static ssize_t dr_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct cv1800_usb_phy *phy = dev_get_drvdata(dev);
+ bool is_host;
+
+ if (sysfs_streq(buf, "host")) {
+ phy->enable_otg = false;
+ is_host = true;
+ } else if (sysfs_streq(buf, "peripheral")) {
+ phy->enable_otg = false;
+ is_host = false;
+ } else if (sysfs_streq(buf, "otg") && phy->vbus_det_irq > 0) {
+ phy->enable_otg = true;
+ } else {
+ return -EINVAL;
+ }
+
+ if (phy->enable_otg)
+ queue_delayed_work(system_wq, &phy->vbus_work,
+ PHY_VBUS_DET_DEBOUNCE_TIME);
+ else
+ cv1800_usb_phy_set_mode_internal(phy, is_host);
+
+ return len;
+}
+
+static ssize_t dr_mode_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct cv1800_usb_phy *phy = dev_get_drvdata(dev);
+ unsigned long flags;
+ unsigned int regval;
+ bool is_host = true;
+ int ret;
+
+ spin_lock_irqsave(&phy->lock, flags);
+ ret = regmap_read(phy->syscon, CV1800_USB_PHY_CTRL_REG, ®val);
+ spin_unlock_irqrestore(&phy->lock, flags);
+
+ if (ret)
+ return ret;
+
+ if (regval & PHY_IDPAD_C_SW)
+ is_host = false;
+
+ return sprintf(buf, "%s%s\n",
+ phy->enable_otg ? "otg: " : "",
+ is_host ? "host" : "peripheral");
+}
+
+static DEVICE_ATTR_RW(dr_mode);
+
+static struct attribute *cv1800_usb_phy_attrs[] = {
+ &dev_attr_dr_mode.attr,
+ NULL
+};
+
+static const struct attribute_group cv1800_usb_phy_group = {
+ .attrs = cv1800_usb_phy_attrs,
+};
+
+static int cv1800_usb_phy_set_clock(struct cv1800_usb_phy *phy)
+{
+ int ret;
+
+ ret = clk_set_rate(phy->usb_phy_clk, PHY_BASE_CLK_RATE);
+ if (ret)
+ return ret;
+
+ ret = clk_set_rate(phy->usb_app_clk, PHY_APP_CLK_RATE);
+ if (ret)
+ return ret;
+
+ ret = clk_set_rate(phy->usb_lpm_clk, PHY_LPM_CLK_RATE);
+ if (ret)
+ return ret;
+
+ ret = clk_set_rate(phy->usb_stb_clk, PHY_STB_CLK_RATE);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int cv1800_usb_phy_set_mode(struct phy *_phy,
+ enum phy_mode mode, int submode)
+{
+ struct cv1800_usb_phy *phy = phy_get_drvdata(_phy);
+ bool is_host;
+
+ switch (mode) {
+ case PHY_MODE_USB_DEVICE:
+ is_host = false;
+ phy->enable_otg = false;
+ break;
+ case PHY_MODE_USB_HOST:
+ is_host = true;
+ phy->enable_otg = false;
+ break;
+ case PHY_MODE_USB_OTG:
+ /* phy only supports soft OTG when VBUS_DET pin is connected. */
+ if (phy->vbus_det_irq > 0) {
+ phy->enable_otg = true;
+ queue_delayed_work(system_wq, &phy->vbus_work,
+ PHY_VBUS_DET_DEBOUNCE_TIME);
+ }
+ return 0;
+ default:
+ return -EINVAL;
+ }
+
+ return cv1800_usb_phy_set_mode_internal(phy, is_host);
+}
+
+static const struct phy_ops cv1800_usb_phy_ops = {
+ .set_mode = cv1800_usb_phy_set_mode,
+ .owner = THIS_MODULE,
+};
+
+static void cv1800_usb_phy_vbus_switch(struct work_struct *work)
+{
+ struct cv1800_usb_phy *phy =
+ container_of(work, struct cv1800_usb_phy, vbus_work.work);
+ int state = gpiod_get_value_cansleep(phy->vbus_det_gpio);
+
+ cv1800_usb_phy_set_mode_internal(phy, state == 0);
+}
+
+static irqreturn_t cv1800_usb_phy_vbus_det_irq(int irq, void *dev_id)
+{
+ struct cv1800_usb_phy *phy = dev_id;
+
+ if (phy->enable_otg)
+ queue_delayed_work(system_wq, &phy->vbus_work,
+ PHY_VBUS_DET_DEBOUNCE_TIME);
+ return IRQ_HANDLED;
+}
+
+static void cv1800_usb_phy_init_mode(struct device *dev,
+ struct cv1800_usb_phy *phy)
+{
+ phy->enable_otg = false;
+
+ if (phy->vbus_det_irq > 0)
+ phy->enable_otg = true;
+
+ if (phy->enable_otg)
+ queue_delayed_work(system_wq, &phy->vbus_work, 0);
+ else
+ cv1800_usb_phy_set_mode_internal(phy, true);
+}
+
+static int cv1800_usb_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device *parent = dev->parent;
+ struct cv1800_usb_phy *phy;
+ struct phy_provider *phy_provider;
+ int ret;
+
+ if (!parent)
+ return -ENODEV;
+
+ phy = devm_kmalloc(dev, sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return -ENOMEM;
+
+ phy->syscon = syscon_node_to_regmap(parent->of_node);
+ if (IS_ERR_OR_NULL(phy->syscon))
+ return -ENODEV;
+
+ spin_lock_init(&phy->lock);
+
+ phy->usb_phy_clk = devm_clk_get_enabled(dev, "phy");
+ if (IS_ERR(phy->usb_phy_clk))
+ return dev_err_probe(dev, PTR_ERR(phy->usb_phy_clk),
+ "Failed to get phy clock\n");
+
+ phy->usb_app_clk = devm_clk_get_enabled(dev, "app");
+ if (IS_ERR(phy->usb_app_clk))
+ return dev_err_probe(dev, PTR_ERR(phy->usb_app_clk),
+ "Failed to get app clock\n");
+
+ phy->usb_lpm_clk = devm_clk_get_enabled(dev, "lpm");
+ if (IS_ERR(phy->usb_lpm_clk))
+ return dev_err_probe(dev, PTR_ERR(phy->usb_lpm_clk),
+ "Failed to get lpm clock\n");
+
+ phy->usb_stb_clk = devm_clk_get_enabled(dev, "stb");
+ if (IS_ERR(phy->usb_stb_clk))
+ return dev_err_probe(dev, PTR_ERR(phy->usb_stb_clk),
+ "Failed to get stb clock\n");
+
+ phy->phy = devm_phy_create(dev, NULL, &cv1800_usb_phy_ops);
+ if (IS_ERR(phy->phy))
+ return dev_err_probe(dev, PTR_ERR(phy->phy),
+ "Failed to create phy\n");
+
+ ret = cv1800_usb_phy_set_clock(phy);
+ if (ret)
+ return ret;
+
+ phy->switch_gpios = devm_gpiod_get_array_optional(dev, "sophgo,switch",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(phy->switch_gpios))
+ return dev_err_probe(dev, PTR_ERR(phy->switch_gpios),
+ "Failed to get switch pin\n");
+
+ phy->vbus_det_gpio = devm_gpiod_get_optional(dev, "vbus_det", GPIOD_IN);
+ if (IS_ERR(phy->vbus_det_gpio))
+ return dev_err_probe(dev, PTR_ERR(phy->vbus_det_gpio),
+ "Failed to process vbus pin\n");
+
+ phy->vbus_det_irq = gpiod_to_irq(phy->vbus_det_gpio);
+ if (phy->vbus_det_irq > 0) {
+ ret = devm_request_irq(dev, phy->vbus_det_irq,
+ cv1800_usb_phy_vbus_det_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "usb-vbus-det", phy);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to request vbus irq\n");
+ }
+
+ INIT_DELAYED_WORK(&phy->vbus_work, cv1800_usb_phy_vbus_switch);
+
+ ret = sysfs_create_group(&dev->kobj, &cv1800_usb_phy_group);
+ if (ret)
+ dev_warn(dev, "failed to create sysfs attributes\n");
+
+ phy_set_drvdata(phy->phy, phy);
+ platform_set_drvdata(pdev, phy);
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ /*
+ * phy needs to change mode twice after initialization,
+ * otherwise the controller can not found devices attached
+ * to the phy.
+ */
+ cv1800_usb_phy_set_idpad(phy, false);
+ cv1800_usb_phy_set_idpad(phy, true);
+ cv1800_usb_phy_init_mode(dev, phy);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static void cv1800_usb_phy_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct cv1800_usb_phy *phy = platform_get_drvdata(pdev);
+
+ if (phy->vbus_det_irq > 0)
+ devm_free_irq(dev, phy->vbus_det_irq, phy);
+
+ cancel_delayed_work_sync(&phy->vbus_work);
+}
+
+static const struct of_device_id cv1800_usb_phy_ids[] = {
+ { .compatible = "sophgo,cv1800-usb-phy" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, cv1800_usb_phy_ids);
+
+static struct platform_driver cv1800_usb_phy_driver = {
+ .probe = cv1800_usb_phy_probe,
+ .remove_new = cv1800_usb_phy_remove,
+ .driver = {
+ .name = "cv1800-usb-phy",
+ .of_match_table = cv1800_usb_phy_ids,
+ },
+};
+module_platform_driver(cv1800_usb_phy_driver);
+MODULE_DESCRIPTION("CV1800/SG2000 SoC USB 2.0 PHY driver");
+MODULE_LICENSE("GPL");
--
2.44.0
The USB phy of Sophgo CV18XX series SoC needs to sense a pin called
"VBUS_DET" to get the right operation mode. If this pin is not
connected, it only supports setting the mode manually.
Add USB phy bindings for Sophgo CV18XX/SG200X series SoC.
Signed-off-by: Inochi Amaoto <[email protected]>
---
.../bindings/phy/sophgo,cv1800-usb-phy.yaml | 68 +++++++++++++++++++
1 file changed, 68 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
diff --git a/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml b/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
new file mode 100644
index 000000000000..7e3382c18d44
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/sophgo,cv1800-usb-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sophgo CV18XX/SG200X USB 2.0 PHY
+
+maintainers:
+ - Inochi Amaoto <[email protected]>
+
+properties:
+ compatible:
+ const: sophgo,cv1800-usb-phy
+
+ reg:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+ clocks:
+ items:
+ - description: PHY clock
+ - description: PHY app clock
+ - description: PHY stb clock
+ - description: PHY lpm clock
+
+ clock-names:
+ items:
+ - const: phy
+ - const: app
+ - const: stb
+ - const: lpm
+
+ vbus_det-gpios:
+ description: GPIO to the USB OTG VBUS detect pin. This should not be
+ defined if vbus_det pin and switch pin are connected, which may
+ break the VBUS detection.
+ maxItems: 1
+
+ sophgo,switch-gpios:
+ description: GPIO array for the phy to control connected switch. For
+ host mode, the driver will set these GPIOs to low one by one. For
+ device mode, the driver will set these GPIOs to high in reverse
+ order.
+ maxItems: 2
+
+required:
+ - compatible
+ - "#phy-cells"
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ phy@48 {
+ compatible = "sophgo,cv1800-usb-phy";
+ reg = <0x48 0x4>;
+ #phy-cells = <0>;
+ clocks = <&clk 92>, <&clk 93>,
+ <&clk 94>, <&clk 95>;
+ clock-names = "phy", "app", "stb", "lpm";
+ };
+
+...
--
2.44.0
On Mon, Apr 29, 2024 at 08:30:23AM GMT, Inochi Amaoto wrote:
> Add USB PHY support for CV18XX/SG200X series
>
> Changed from v1:
> 1. remove dr_mode property and use default mode instead.
> 2. improve the description of `vbus_det-gpios` and `sophgo,switch-gpios`
>
> Inochi Amaoto (2):
> dt-bindings: phy: Add Sophgo CV1800 USB phy
> phy: sophgo: Add USB 2.0 PHY driver for Sophgo CV18XX/SG200X
>
> .../bindings/phy/sophgo,cv1800-usb-phy.yaml | 68 ++++
> drivers/phy/Kconfig | 1 +
> drivers/phy/Makefile | 1 +
> drivers/phy/sophgo/Kconfig | 19 +
> drivers/phy/sophgo/Makefile | 2 +
> drivers/phy/sophgo/phy-cv1800-usb.c | 378 ++++++++++++++++++
> 6 files changed, 469 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> create mode 100644 drivers/phy/sophgo/Kconfig
> create mode 100644 drivers/phy/sophgo/Makefile
> create mode 100644 drivers/phy/sophgo/phy-cv1800-usb.c
>
> --
> 2.44.0
>
On Fri, Apr 12, 2024 at 03:21:26PM +0800, Inochi Amaoto wrote:
> Add USB PHY support for CV18XX/SG200X series
>
> Inochi Amaoto (2):
> dt-bindings: phy: Add Sophgo CV1800 USB phy
> phy: sophgo: Add USB 2.0 PHY driver for Sophgo CV18XX/SG200X
>
Sorry for forgetting to mention the depends patch again:
https://lore.kernel.org/all/IA1PR20MB4953BAA0F8E06CB202C5C2FBBB062@IA1PR20MB4953.namprd20.prod.outlook.com/
On Mon, Apr 29, 2024 at 08:31:11AM +0800, Inochi Amaoto wrote:
> The USB phy of Sophgo CV18XX series SoC needs to sense a pin called
> "VBUS_DET" to get the right operation mode. If this pin is not
> connected, it only supports setting the mode manually.
>
> Add USB phy bindings for Sophgo CV18XX/SG200X series SoC.
>
> Signed-off-by: Inochi Amaoto <[email protected]>
> ---
> .../bindings/phy/sophgo,cv1800-usb-phy.yaml | 68 +++++++++++++++++++
> 1 file changed, 68 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
>
> diff --git a/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml b/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> new file mode 100644
> index 000000000000..7e3382c18d44
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> @@ -0,0 +1,68 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/sophgo,cv1800-usb-phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Sophgo CV18XX/SG200X USB 2.0 PHY
> +
> +maintainers:
> + - Inochi Amaoto <[email protected]>
> +
> +properties:
> + compatible:
> + const: sophgo,cv1800-usb-phy
> +
> + reg:
> + maxItems: 1
> +
> + "#phy-cells":
> + const: 0
> +
> + clocks:
> + items:
> + - description: PHY clock
> + - description: PHY app clock
> + - description: PHY stb clock
> + - description: PHY lpm clock
> +
> + clock-names:
> + items:
> + - const: phy
> + - const: app
> + - const: stb
> + - const: lpm
> +
> + vbus_det-gpios:
"vbus_det-gpios" isn't a common property AFAICT, why does it not get a
vendor prefix when the other gpios property does?
> + description: GPIO to the USB OTG VBUS detect pin. This should not be
> + defined if vbus_det pin and switch pin are connected, which may
> + break the VBUS detection.
> + maxItems: 1
> +
> + sophgo,switch-gpios:
> + description: GPIO array for the phy to control connected switch. For
> + host mode, the driver will set these GPIOs to low one by one. For
> + device mode, the driver will set these GPIOs to high in reverse
> + order.
> + maxItems: 2
You're still missing the itemised description of what each of the gpios
here are - how would I know which order to put the GPIOs in?
Cheers,
Conor.
> +
> +required:
> + - compatible
> + - "#phy-cells"
> + - clocks
> + - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + phy@48 {
> + compatible = "sophgo,cv1800-usb-phy";
> + reg = <0x48 0x4>;
> + #phy-cells = <0>;
> + clocks = <&clk 92>, <&clk 93>,
> + <&clk 94>, <&clk 95>;
> + clock-names = "phy", "app", "stb", "lpm";
> + };
> +
> +...
> --
> 2.44.0
>
On Tue, Apr 30, 2024 at 06:09:20PM GMT, Conor Dooley wrote:
> On Mon, Apr 29, 2024 at 08:31:11AM +0800, Inochi Amaoto wrote:
> > The USB phy of Sophgo CV18XX series SoC needs to sense a pin called
> > "VBUS_DET" to get the right operation mode. If this pin is not
> > connected, it only supports setting the mode manually.
> >
> > Add USB phy bindings for Sophgo CV18XX/SG200X series SoC.
> >
> > Signed-off-by: Inochi Amaoto <[email protected]>
> > ---
> > .../bindings/phy/sophgo,cv1800-usb-phy.yaml | 68 +++++++++++++++++++
> > 1 file changed, 68 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml b/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> > new file mode 100644
> > index 000000000000..7e3382c18d44
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> > @@ -0,0 +1,68 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/phy/sophgo,cv1800-usb-phy.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Sophgo CV18XX/SG200X USB 2.0 PHY
> > +
> > +maintainers:
> > + - Inochi Amaoto <[email protected]>
> > +
> > +properties:
> > + compatible:
> > + const: sophgo,cv1800-usb-phy
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + "#phy-cells":
> > + const: 0
> > +
> > + clocks:
> > + items:
> > + - description: PHY clock
> > + - description: PHY app clock
> > + - description: PHY stb clock
> > + - description: PHY lpm clock
> > +
> > + clock-names:
> > + items:
> > + - const: phy
> > + - const: app
> > + - const: stb
> > + - const: lpm
> > +
> > + vbus_det-gpios:
>
> "vbus_det-gpios" isn't a common property AFAICT, why does it not get a
> vendor prefix when the other gpios property does?
>
I have seen other binding (such as sunxi phy) uses this property without
vendor prefix. So I think it is a common property and don't add perfix
for it. But it is OK for me add the vendor prefix, thanks.
> > + description: GPIO to the USB OTG VBUS detect pin. This should not be
> > + defined if vbus_det pin and switch pin are connected, which may
> > + break the VBUS detection.
> > + maxItems: 1
> > +
> > + sophgo,switch-gpios:
> > + description: GPIO array for the phy to control connected switch. For
> > + host mode, the driver will set these GPIOs to low one by one. For
> > + device mode, the driver will set these GPIOs to high in reverse
> > + order.
> > + maxItems: 2
>
> You're still missing the itemised description of what each of the gpios
> here are - how would I know which order to put the GPIOs in?
>
> Cheers,
> Conor.
In most case, the order depends on hardware design. But following the
guide sophgo provides, it does have an common order. Is it good to add
this description as a reference guide? If so, I will add it.
Regards,
Inochi
>
> > +
> > +required:
> > + - compatible
> > + - "#phy-cells"
> > + - clocks
> > + - clock-names
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > + - |
> > + phy@48 {
> > + compatible = "sophgo,cv1800-usb-phy";
> > + reg = <0x48 0x4>;
> > + #phy-cells = <0>;
> > + clocks = <&clk 92>, <&clk 93>,
> > + <&clk 94>, <&clk 95>;
> > + clock-names = "phy", "app", "stb", "lpm";
> > + };
> > +
> > +...
> > --
> > 2.44.0
> >
On Wed, May 01, 2024 at 08:28:47AM +0800, Inochi Amaoto wrote:
> On Tue, Apr 30, 2024 at 06:09:20PM GMT, Conor Dooley wrote:
> > On Mon, Apr 29, 2024 at 08:31:11AM +0800, Inochi Amaoto wrote:
> > > The USB phy of Sophgo CV18XX series SoC needs to sense a pin called
> > > "VBUS_DET" to get the right operation mode. If this pin is not
> > > connected, it only supports setting the mode manually.
> > >
> > > Add USB phy bindings for Sophgo CV18XX/SG200X series SoC.
> > >
> > > Signed-off-by: Inochi Amaoto <[email protected]>
> > > ---
> > > .../bindings/phy/sophgo,cv1800-usb-phy.yaml | 68 +++++++++++++++++++
> > > 1 file changed, 68 insertions(+)
> > > create mode 100644 Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> > >
> > > diff --git a/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml b/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> > > new file mode 100644
> > > index 000000000000..7e3382c18d44
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> > > @@ -0,0 +1,68 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/phy/sophgo,cv1800-usb-phy.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Sophgo CV18XX/SG200X USB 2.0 PHY
> > > +
> > > +maintainers:
> > > + - Inochi Amaoto <[email protected]>
> > > +
> > > +properties:
> > > + compatible:
> > > + const: sophgo,cv1800-usb-phy
> > > +
> > > + reg:
> > > + maxItems: 1
> > > +
> > > + "#phy-cells":
> > > + const: 0
> > > +
> > > + clocks:
> > > + items:
> > > + - description: PHY clock
> > > + - description: PHY app clock
> > > + - description: PHY stb clock
> > > + - description: PHY lpm clock
> > > +
> > > + clock-names:
> > > + items:
> > > + - const: phy
> > > + - const: app
> > > + - const: stb
> > > + - const: lpm
> > > +
> > > + vbus_det-gpios:
> >
> > "vbus_det-gpios" isn't a common property AFAICT, why does it not get a
> > vendor prefix when the other gpios property does?
> >
>
> I have seen other binding (such as sunxi phy) uses this property without
> vendor prefix. So I think it is a common property and don't add perfix
> for it. But it is OK for me add the vendor prefix, thanks.
I asked yesterday and Krzysztof said:
"gpios just like supplies - no prefixes, I think."
The other phy used a different property (they're not identical), I did
check that yesterday.
>
> > > + description: GPIO to the USB OTG VBUS detect pin. This should not be
> > > + defined if vbus_det pin and switch pin are connected, which may
> > > + break the VBUS detection.
> > > + maxItems: 1
> > > +
> > > + sophgo,switch-gpios:
> > > + description: GPIO array for the phy to control connected switch. For
> > > + host mode, the driver will set these GPIOs to low one by one. For
> > > + device mode, the driver will set these GPIOs to high in reverse
> > > + order.
> > > + maxItems: 2
> >
> > You're still missing the itemised description of what each of the gpios
> > here are - how would I know which order to put the GPIOs in?
> >
> > Cheers,
> > Conor.
>
> In most case, the order depends on hardware design. But following the
> guide sophgo provides, it does have an common order. Is it good to add
> this description as a reference guide? If so, I will add it.
If we can say "gpio 1 connects to xyz on the switch" & "gpio 2 connects
to tuv" then it'll be easier to understand how to write the node.
>
> Regards,
> Inochi
>
> >
> > > +
> > > +required:
> > > + - compatible
> > > + - "#phy-cells"
> > > + - clocks
> > > + - clock-names
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > + - |
> > > + phy@48 {
> > > + compatible = "sophgo,cv1800-usb-phy";
> > > + reg = <0x48 0x4>;
> > > + #phy-cells = <0>;
> > > + clocks = <&clk 92>, <&clk 93>,
> > > + <&clk 94>, <&clk 95>;
> > > + clock-names = "phy", "app", "stb", "lpm";
> > > + };
> > > +
> > > +...
> > > --
> > > 2.44.0
> > >
>
>
On Wed, May 01, 2024 at 06:05:28PM GMT, Conor Dooley wrote:
> On Wed, May 01, 2024 at 08:28:47AM +0800, Inochi Amaoto wrote:
> > On Tue, Apr 30, 2024 at 06:09:20PM GMT, Conor Dooley wrote:
> > > On Mon, Apr 29, 2024 at 08:31:11AM +0800, Inochi Amaoto wrote:
> > > > The USB phy of Sophgo CV18XX series SoC needs to sense a pin called
> > > > "VBUS_DET" to get the right operation mode. If this pin is not
> > > > connected, it only supports setting the mode manually.
> > > >
> > > > Add USB phy bindings for Sophgo CV18XX/SG200X series SoC.
> > > >
> > > > Signed-off-by: Inochi Amaoto <[email protected]>
> > > > ---
> > > > .../bindings/phy/sophgo,cv1800-usb-phy.yaml | 68 +++++++++++++++++++
> > > > 1 file changed, 68 insertions(+)
> > > > create mode 100644 Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml b/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> > > > new file mode 100644
> > > > index 000000000000..7e3382c18d44
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> > > > @@ -0,0 +1,68 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/phy/sophgo,cv1800-usb-phy.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Sophgo CV18XX/SG200X USB 2.0 PHY
> > > > +
> > > > +maintainers:
> > > > + - Inochi Amaoto <[email protected]>
> > > > +
> > > > +properties:
> > > > + compatible:
> > > > + const: sophgo,cv1800-usb-phy
> > > > +
> > > > + reg:
> > > > + maxItems: 1
> > > > +
> > > > + "#phy-cells":
> > > > + const: 0
> > > > +
> > > > + clocks:
> > > > + items:
> > > > + - description: PHY clock
> > > > + - description: PHY app clock
> > > > + - description: PHY stb clock
> > > > + - description: PHY lpm clock
> > > > +
> > > > + clock-names:
> > > > + items:
> > > > + - const: phy
> > > > + - const: app
> > > > + - const: stb
> > > > + - const: lpm
> > > > +
> > > > + vbus_det-gpios:
> > >
> > > "vbus_det-gpios" isn't a common property AFAICT, why does it not get a
> > > vendor prefix when the other gpios property does?
> > >
> >
> > I have seen other binding (such as sunxi phy) uses this property without
> > vendor prefix. So I think it is a common property and don't add perfix
> > for it. But it is OK for me add the vendor prefix, thanks.
>
> I asked yesterday and Krzysztof said:
> "gpios just like supplies - no prefixes, I think."
Thanks for your explanation. If I do not understand wrong, you mean
it does not need to add vender prefix?
> The other phy used a different property (they're not identical), I did
> check that yesterday.
>
Yes, it is not total identical. But they do look similar.
> >
> > > > + description: GPIO to the USB OTG VBUS detect pin. This should not be
> > > > + defined if vbus_det pin and switch pin are connected, which may
> > > > + break the VBUS detection.
> > > > + maxItems: 1
> > > > +
> > > > + sophgo,switch-gpios:
> > > > + description: GPIO array for the phy to control connected switch. For
> > > > + host mode, the driver will set these GPIOs to low one by one. For
> > > > + device mode, the driver will set these GPIOs to high in reverse
> > > > + order.
> > > > + maxItems: 2
> > >
> > > You're still missing the itemised description of what each of the gpios
> > > here are - how would I know which order to put the GPIOs in?
> > >
> > > Cheers,
> > > Conor.
> >
> > In most case, the order depends on hardware design. But following the
> > guide sophgo provides, it does have an common order. Is it good to add
> > this description as a reference guide? If so, I will add it.
>
> If we can say "gpio 1 connects to xyz on the switch" & "gpio 2 connects
> to tuv" then it'll be easier to understand how to write the node.
>
Good, I will add description of reference design for these gpios.
> >
> > Regards,
> > Inochi
> >
> > >
> > > > +
> > > > +required:
> > > > + - compatible
> > > > + - "#phy-cells"
> > > > + - clocks
> > > > + - clock-names
> > > > +
> > > > +additionalProperties: false
> > > > +
> > > > +examples:
> > > > + - |
> > > > + phy@48 {
> > > > + compatible = "sophgo,cv1800-usb-phy";
> > > > + reg = <0x48 0x4>;
> > > > + #phy-cells = <0>;
> > > > + clocks = <&clk 92>, <&clk 93>,
> > > > + <&clk 94>, <&clk 95>;
> > > > + clock-names = "phy", "app", "stb", "lpm";
> > > > + };
> > > > +
> > > > +...
> > > > --
> > > > 2.44.0
> > > >
> >
> >
Inochi,
Please also send this patchset to the linux-riscv mailinglist next time.
Thanks,
Chen
On 2024/4/29 8:30, Inochi Amaoto wrote:
> Add USB PHY support for CV18XX/SG200X series
>
> Changed from v1:
> 1. remove dr_mode property and use default mode instead.
> 2. improve the description of `vbus_det-gpios` and `sophgo,switch-gpios`
>
> Inochi Amaoto (2):
> dt-bindings: phy: Add Sophgo CV1800 USB phy
> phy: sophgo: Add USB 2.0 PHY driver for Sophgo CV18XX/SG200X
>
> .../bindings/phy/sophgo,cv1800-usb-phy.yaml | 68 ++++
> drivers/phy/Kconfig | 1 +
> drivers/phy/Makefile | 1 +
> drivers/phy/sophgo/Kconfig | 19 +
> drivers/phy/sophgo/Makefile | 2 +
> drivers/phy/sophgo/phy-cv1800-usb.c | 378 ++++++++++++++++++
> 6 files changed, 469 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/sophgo,cv1800-usb-phy.yaml
> create mode 100644 drivers/phy/sophgo/Kconfig
> create mode 100644 drivers/phy/sophgo/Makefile
> create mode 100644 drivers/phy/sophgo/phy-cv1800-usb.c
>
> --
> 2.44.0
>
On Fri, May 03, 2024 at 08:36:47AM +0800, Inochi Amaoto wrote:
> On Wed, May 01, 2024 at 06:05:28PM GMT, Conor Dooley wrote:
> > On Wed, May 01, 2024 at 08:28:47AM +0800, Inochi Amaoto wrote:
> > > On Tue, Apr 30, 2024 at 06:09:20PM GMT, Conor Dooley wrote:
> > > > On Mon, Apr 29, 2024 at 08:31:11AM +0800, Inochi Amaoto wrote:
> > > > > + vbus_det-gpios:
> > > >
> > > > "vbus_det-gpios" isn't a common property AFAICT, why does it not get a
> > > > vendor prefix when the other gpios property does?
> > > >
> > >
> > > I have seen other binding (such as sunxi phy) uses this property without
> > > vendor prefix. So I think it is a common property and don't add perfix
> > > for it. But it is OK for me add the vendor prefix, thanks.
> >
> > I asked yesterday and Krzysztof said:
> > "gpios just like supplies - no prefixes, I think."
>
> Thanks for your explanation. If I do not understand wrong, you mean
> it does not need to add vender prefix?
Yeah, I think you're okay.