Lines Matching +full:usb2 +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Lantiq XWAY SoC RCU module based USB 1.1/2.0 PHY driver
6 * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de>
15 #include <linux/phy/phy.h>
21 /* Transmitter HS Pre-Emphasis Enable */
40 struct phy *phy; member
69 .compatible = "lantiq,ase-usb2-phy",
73 .compatible = "lantiq,danube-usb2-phy",
77 .compatible = "lantiq,xrx100-usb2-phy",
81 .compatible = "lantiq,xrx200-usb2-phy",
85 .compatible = "lantiq,xrx300-usb2-phy",
92 static int ltq_rcu_usb2_phy_init(struct phy *phy) in ltq_rcu_usb2_phy_init() argument
94 struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy); in ltq_rcu_usb2_phy_init()
96 if (priv->reg_bits->have_ana_cfg) { in ltq_rcu_usb2_phy_init()
97 regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset, in ltq_rcu_usb2_phy_init()
99 regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset, in ltq_rcu_usb2_phy_init()
104 regmap_update_bits(priv->regmap, priv->phy_reg_offset, in ltq_rcu_usb2_phy_init()
105 BIT(priv->reg_bits->hostmode), 0); in ltq_rcu_usb2_phy_init()
107 /* Select DMA endianness (Host-endian: big-endian) */ in ltq_rcu_usb2_phy_init()
108 regmap_update_bits(priv->regmap, priv->phy_reg_offset, in ltq_rcu_usb2_phy_init()
109 BIT(priv->reg_bits->slave_endianness), 0); in ltq_rcu_usb2_phy_init()
110 regmap_update_bits(priv->regmap, priv->phy_reg_offset, in ltq_rcu_usb2_phy_init()
111 BIT(priv->reg_bits->host_endianness), in ltq_rcu_usb2_phy_init()
112 BIT(priv->reg_bits->host_endianness)); in ltq_rcu_usb2_phy_init()
117 static int ltq_rcu_usb2_phy_power_on(struct phy *phy) in ltq_rcu_usb2_phy_power_on() argument
119 struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy); in ltq_rcu_usb2_phy_power_on()
120 struct device *dev = priv->dev; in ltq_rcu_usb2_phy_power_on()
123 reset_control_deassert(priv->phy_reset); in ltq_rcu_usb2_phy_power_on()
125 ret = clk_prepare_enable(priv->phy_gate_clk); in ltq_rcu_usb2_phy_power_on()
127 dev_err(dev, "failed to enable PHY gate\n"); in ltq_rcu_usb2_phy_power_on()
132 * at least the xrx200 usb2 phy requires some extra time to be in ltq_rcu_usb2_phy_power_on()
140 static int ltq_rcu_usb2_phy_power_off(struct phy *phy) in ltq_rcu_usb2_phy_power_off() argument
142 struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy); in ltq_rcu_usb2_phy_power_off()
144 reset_control_assert(priv->phy_reset); in ltq_rcu_usb2_phy_power_off()
146 clk_disable_unprepare(priv->phy_gate_clk); in ltq_rcu_usb2_phy_power_off()
161 struct device *dev = priv->dev; in ltq_rcu_usb2_of_parse()
164 priv->reg_bits = of_device_get_match_data(dev); in ltq_rcu_usb2_of_parse()
166 priv->regmap = syscon_node_to_regmap(dev->of_node->parent); in ltq_rcu_usb2_of_parse()
167 if (IS_ERR(priv->regmap)) { in ltq_rcu_usb2_of_parse()
169 return PTR_ERR(priv->regmap); in ltq_rcu_usb2_of_parse()
172 offset = of_get_address(dev->of_node, 0, NULL, NULL); in ltq_rcu_usb2_of_parse()
174 dev_err(dev, "Failed to get RCU PHY reg offset\n"); in ltq_rcu_usb2_of_parse()
175 return -ENOENT; in ltq_rcu_usb2_of_parse()
177 priv->phy_reg_offset = __be32_to_cpu(*offset); in ltq_rcu_usb2_of_parse()
179 if (priv->reg_bits->have_ana_cfg) { in ltq_rcu_usb2_of_parse()
180 offset = of_get_address(dev->of_node, 1, NULL, NULL); in ltq_rcu_usb2_of_parse()
183 return -ENOENT; in ltq_rcu_usb2_of_parse()
185 priv->ana_cfg1_reg_offset = __be32_to_cpu(*offset); in ltq_rcu_usb2_of_parse()
188 priv->phy_gate_clk = devm_clk_get(dev, "phy"); in ltq_rcu_usb2_of_parse()
189 if (IS_ERR(priv->phy_gate_clk)) { in ltq_rcu_usb2_of_parse()
190 dev_err(dev, "Unable to get USB phy gate clk\n"); in ltq_rcu_usb2_of_parse()
191 return PTR_ERR(priv->phy_gate_clk); in ltq_rcu_usb2_of_parse()
194 priv->ctrl_reset = devm_reset_control_get_shared(dev, "ctrl"); in ltq_rcu_usb2_of_parse()
195 if (IS_ERR(priv->ctrl_reset)) { in ltq_rcu_usb2_of_parse()
196 if (PTR_ERR(priv->ctrl_reset) != -EPROBE_DEFER) in ltq_rcu_usb2_of_parse()
198 return PTR_ERR(priv->ctrl_reset); in ltq_rcu_usb2_of_parse()
201 priv->phy_reset = devm_reset_control_get_optional(dev, "phy"); in ltq_rcu_usb2_of_parse()
203 return PTR_ERR_OR_ZERO(priv->phy_reset); in ltq_rcu_usb2_of_parse()
208 struct device *dev = &pdev->dev; in ltq_rcu_usb2_phy_probe()
215 return -ENOMEM; in ltq_rcu_usb2_phy_probe()
217 priv->dev = dev; in ltq_rcu_usb2_phy_probe()
224 reset_control_deassert(priv->ctrl_reset); in ltq_rcu_usb2_phy_probe()
226 reset_control_assert(priv->phy_reset); in ltq_rcu_usb2_phy_probe()
228 priv->phy = devm_phy_create(dev, dev->of_node, <q_rcu_usb2_phy_ops); in ltq_rcu_usb2_phy_probe()
229 if (IS_ERR(priv->phy)) { in ltq_rcu_usb2_phy_probe()
230 dev_err(dev, "failed to create PHY\n"); in ltq_rcu_usb2_phy_probe()
231 return PTR_ERR(priv->phy); in ltq_rcu_usb2_phy_probe()
234 phy_set_drvdata(priv->phy, priv); in ltq_rcu_usb2_phy_probe()
240 dev_set_drvdata(priv->dev, priv); in ltq_rcu_usb2_phy_probe()
247 .name = "lantiq-rcu-usb2-phy",
254 MODULE_DESCRIPTION("Lantiq XWAY USB2 PHY driver");