Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
$id: http://devicetree.org/schemas/phy/spacemit,usb2-phy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: SpacemiT K1 SoC USB 2.0 PHY
title: SpacemiT K1/K3 SoC USB 2.0 PHY

maintainers:
- Ze Huang <huang.ze@linux.dev>

properties:
compatible:
const: spacemit,k1-usb2-phy
enum:
- spacemit,k1-usb2-phy
- spacemit,k3-usb2-phy

reg:
maxItems: 1
Expand Down
44 changes: 41 additions & 3 deletions drivers/phy/spacemit/phy-k1-usb2.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@
#define PHY_CLK_HSTXP_EN BIT(3) /* clock hstxp enable */
#define PHY_HSTXP_MODE BIT(4) /* 0: force en_txp to be 1; 1: no force */

#define PHY_K1_HS_HOST_DISC 0x40
#define PHY_K1_HS_HOST_DISC_CLR BIT(0)

#define PHY_K3_HS_HOST_DISC 0x20
#define PHY_K3_HS_HOST_DISC_CLR BIT(8)

#define PHY_PLL_DIV_CFG 0x98
#define PHY_FDIV_FRACT_8_15 GENMASK(7, 0)
#define PHY_FDIV_FRACT_16_19 GENMASK(11, 8)
Expand Down Expand Up @@ -142,9 +148,37 @@ static int spacemit_usb2phy_exit(struct phy *phy)
return 0;
}

static const struct phy_ops spacemit_usb2phy_ops = {
static int spacemit_k1_usb2phy_disconnect(struct phy *phy, int port)
{
struct spacemit_usb2phy *sphy = phy_get_drvdata(phy);

regmap_update_bits(sphy->regmap_base, PHY_K1_HS_HOST_DISC,
PHY_K1_HS_HOST_DISC_CLR, PHY_K1_HS_HOST_DISC_CLR);

return 0;
}

static int spacemit_k3_usb2phy_disconnect(struct phy *phy, int port)
{
struct spacemit_usb2phy *sphy = phy_get_drvdata(phy);

regmap_update_bits(sphy->regmap_base, PHY_K3_HS_HOST_DISC,
PHY_K3_HS_HOST_DISC_CLR, PHY_K3_HS_HOST_DISC_CLR);

return 0;
}

static const struct phy_ops spacemit_k1_usb2phy_ops = {
.init = spacemit_usb2phy_init,
.exit = spacemit_usb2phy_exit,
.disconnect = spacemit_k1_usb2phy_disconnect,
.owner = THIS_MODULE,
};

static const struct phy_ops spacemit_k3_usb2phy_ops = {
.init = spacemit_usb2phy_init,
.exit = spacemit_usb2phy_exit,
.disconnect = spacemit_k3_usb2phy_disconnect,
.owner = THIS_MODULE,
};

Expand All @@ -153,12 +187,15 @@ static int spacemit_usb2phy_probe(struct platform_device *pdev)
struct phy_provider *phy_provider;
struct device *dev = &pdev->dev;
struct spacemit_usb2phy *sphy;
const struct phy_ops *ops;
void __iomem *base;

sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
if (!sphy)
return -ENOMEM;

ops = device_get_match_data(dev);

sphy->clk = devm_clk_get_prepared(&pdev->dev, NULL);
if (IS_ERR(sphy->clk))
return dev_err_probe(dev, PTR_ERR(sphy->clk), "Failed to get clock\n");
Expand All @@ -171,7 +208,7 @@ static int spacemit_usb2phy_probe(struct platform_device *pdev)
if (IS_ERR(sphy->regmap_base))
return dev_err_probe(dev, PTR_ERR(sphy->regmap_base), "Failed to init regmap\n");

sphy->phy = devm_phy_create(dev, NULL, &spacemit_usb2phy_ops);
sphy->phy = devm_phy_create(dev, NULL, ops);
if (IS_ERR(sphy->phy))
return dev_err_probe(dev, PTR_ERR(sphy->phy), "Failed to create phy\n");

Expand All @@ -182,7 +219,8 @@ static int spacemit_usb2phy_probe(struct platform_device *pdev)
}

static const struct of_device_id spacemit_usb2phy_dt_match[] = {
{ .compatible = "spacemit,k1-usb2-phy", },
{ .compatible = "spacemit,k1-usb2-phy", .data = &spacemit_k1_usb2phy_ops },
{ .compatible = "spacemit,k3-usb2-phy", .data = &spacemit_k3_usb2phy_ops },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, spacemit_usb2phy_dt_match);
Expand Down
Loading