armbian_build/patch/kernel/archive/meson-6.9/0008-phy-amlogic-meson8b-usb2-Add-support-for-reading-the.patch
2024-06-06 13:32:13 +02:00

104 lines
3.3 KiB
Diff

From fa852523a5da72615695668ef4d354b6af2cae83 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sun, 3 May 2020 21:40:27 +0200
Subject: [PATCH 08/96] phy: amlogic: meson8b-usb2: Add support for reading the
"ID" signal
The first USB PHY on Amlogic Meson8/8b/8m2/GXBB SoCs is OTG capable.
This means that the USB "ID" signal is routed to the PHY. Add support
for the gpio-controller and #gpio-cells properties so the value of
the "ID" signal can be read as a GPIO (from the PHY) for example by
the usb-conn-gpio driver.
The registers also have a bit for the VBUS signal. That either is not
wired in hardware inside the SoC silicon or not wired on the boards
(e.g. Odroid-C1), which is why it's value is not exposed for now.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/phy/amlogic/phy-meson8b-usb2.c | 42 +++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
index d63147c41..d3d0bd367 100644
--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
+++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
@@ -7,6 +7,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
@@ -127,6 +128,7 @@ struct phy_meson8b_usb2_priv {
struct clk *clk_usb_general;
struct clk *clk_usb;
struct reset_control *reset;
+ struct gpio_chip gpiochip;
const struct phy_meson8b_usb2_match_data *match;
};
@@ -236,12 +238,44 @@ static const struct phy_ops phy_meson8b_usb2_ops = {
.owner = THIS_MODULE,
};
+static int phy_meson8b_usb2_id_gpio_get_direction(struct gpio_chip *gc,
+ unsigned int offset)
+{
+ return GPIO_LINE_DIRECTION_IN;
+}
+
+static int phy_meson8b_usb2_id_gpio_get_value(struct gpio_chip *gc,
+ unsigned int offset)
+{
+ struct phy_meson8b_usb2_priv *priv = gpiochip_get_data(gc);
+ unsigned int val;
+
+ regmap_read(priv->regmap, REG_ADP_BC, &val);
+
+ return (val & REG_ADP_BC_ID_DIG) ? 1 : 0;
+}
+
+static int phy_meson8b_usb2_id_gpiochip_add(struct device *dev,
+ struct phy_meson8b_usb2_priv *priv)
+{
+ priv->gpiochip.label = dev_name(dev);
+ priv->gpiochip.parent = dev;
+ priv->gpiochip.get_direction = phy_meson8b_usb2_id_gpio_get_direction;
+ priv->gpiochip.get = phy_meson8b_usb2_id_gpio_get_value;
+ priv->gpiochip.of_gpio_n_cells = 2;
+ priv->gpiochip.base = -1;
+ priv->gpiochip.ngpio = 1;
+
+ return devm_gpiochip_add_data(dev, &priv->gpiochip, priv);
+}
+
static int phy_meson8b_usb2_probe(struct platform_device *pdev)
{
struct phy_meson8b_usb2_priv *priv;
- struct phy *phy;
struct phy_provider *phy_provider;
void __iomem *base;
+ struct phy *phy;
+ int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -280,6 +314,12 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev)
return -EINVAL;
}
+ if (device_property_read_bool(&pdev->dev, "gpio-controller")) {
+ ret = phy_meson8b_usb2_id_gpiochip_add(&pdev->dev, priv);
+ if (ret)
+ return ret;
+ }
+
phy = devm_phy_create(&pdev->dev, NULL, &phy_meson8b_usb2_ops);
if (IS_ERR(phy)) {
return dev_err_probe(&pdev->dev, PTR_ERR(phy),
--
2.45.1