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>
16 #include <linux/phy/phy.h>
22 /* Transmitter HS Pre-Emphasis Enable */
41 struct phy *phy; member
70 .compatible = "lantiq,ase-usb2-phy",
74 .compatible = "lantiq,danube-usb2-phy",
78 .compatible = "lantiq,xrx100-usb2-phy",
82 .compatible = "lantiq,xrx200-usb2-phy",
86 .compatible = "lantiq,xrx300-usb2-phy",
93 static int ltq_rcu_usb2_phy_init(struct phy *phy) in ltq_rcu_usb2_phy_init() argument
95 struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy); in ltq_rcu_usb2_phy_init()
97 if (priv->reg_bits->have_ana_cfg) { in ltq_rcu_usb2_phy_init()
98 regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset, in ltq_rcu_usb2_phy_init()
100 regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset, in ltq_rcu_usb2_phy_init()
105 regmap_update_bits(priv->regmap, priv->phy_reg_offset, in ltq_rcu_usb2_phy_init()
106 BIT(priv->reg_bits->hostmode), 0); in ltq_rcu_usb2_phy_init()
108 /* Select DMA endianness (Host-endian: big-endian) */ in ltq_rcu_usb2_phy_init()
109 regmap_update_bits(priv->regmap, priv->phy_reg_offset, in ltq_rcu_usb2_phy_init()
110 BIT(priv->reg_bits->slave_endianness), 0); in ltq_rcu_usb2_phy_init()
111 regmap_update_bits(priv->regmap, priv->phy_reg_offset, in ltq_rcu_usb2_phy_init()
112 BIT(priv->reg_bits->host_endianness), in ltq_rcu_usb2_phy_init()
113 BIT(priv->reg_bits->host_endianness)); in ltq_rcu_usb2_phy_init()
118 static int ltq_rcu_usb2_phy_power_on(struct phy *phy) in ltq_rcu_usb2_phy_power_on() argument
120 struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy); in ltq_rcu_usb2_phy_power_on()
121 struct device *dev = priv->dev; in ltq_rcu_usb2_phy_power_on()
124 reset_control_deassert(priv->phy_reset); in ltq_rcu_usb2_phy_power_on()
126 ret = clk_prepare_enable(priv->phy_gate_clk); in ltq_rcu_usb2_phy_power_on()
128 dev_err(dev, "failed to enable PHY gate\n"); in ltq_rcu_usb2_phy_power_on()
133 static int ltq_rcu_usb2_phy_power_off(struct phy *phy) in ltq_rcu_usb2_phy_power_off() argument
135 struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy); in ltq_rcu_usb2_phy_power_off()
137 reset_control_assert(priv->phy_reset); in ltq_rcu_usb2_phy_power_off()
139 clk_disable_unprepare(priv->phy_gate_clk); in ltq_rcu_usb2_phy_power_off()
154 struct device *dev = priv->dev; in ltq_rcu_usb2_of_parse()
157 priv->reg_bits = of_device_get_match_data(dev); in ltq_rcu_usb2_of_parse()
159 priv->regmap = syscon_node_to_regmap(dev->of_node->parent); in ltq_rcu_usb2_of_parse()
160 if (IS_ERR(priv->regmap)) { in ltq_rcu_usb2_of_parse()
162 return PTR_ERR(priv->regmap); in ltq_rcu_usb2_of_parse()
165 offset = of_get_address(dev->of_node, 0, NULL, NULL); in ltq_rcu_usb2_of_parse()
167 dev_err(dev, "Failed to get RCU PHY reg offset\n"); in ltq_rcu_usb2_of_parse()
168 return -ENOENT; in ltq_rcu_usb2_of_parse()
170 priv->phy_reg_offset = __be32_to_cpu(*offset); in ltq_rcu_usb2_of_parse()
172 if (priv->reg_bits->have_ana_cfg) { in ltq_rcu_usb2_of_parse()
173 offset = of_get_address(dev->of_node, 1, NULL, NULL); in ltq_rcu_usb2_of_parse()
176 return -ENOENT; in ltq_rcu_usb2_of_parse()
178 priv->ana_cfg1_reg_offset = __be32_to_cpu(*offset); in ltq_rcu_usb2_of_parse()
181 priv->phy_gate_clk = devm_clk_get(dev, "phy"); in ltq_rcu_usb2_of_parse()
182 if (IS_ERR(priv->phy_gate_clk)) { in ltq_rcu_usb2_of_parse()
183 dev_err(dev, "Unable to get USB phy gate clk\n"); in ltq_rcu_usb2_of_parse()
184 return PTR_ERR(priv->phy_gate_clk); in ltq_rcu_usb2_of_parse()
187 priv->ctrl_reset = devm_reset_control_get_shared(dev, "ctrl"); in ltq_rcu_usb2_of_parse()
188 if (IS_ERR(priv->ctrl_reset)) { in ltq_rcu_usb2_of_parse()
189 if (PTR_ERR(priv->ctrl_reset) != -EPROBE_DEFER) in ltq_rcu_usb2_of_parse()
191 return PTR_ERR(priv->ctrl_reset); in ltq_rcu_usb2_of_parse()
194 priv->phy_reset = devm_reset_control_get_optional(dev, "phy"); in ltq_rcu_usb2_of_parse()
196 return PTR_ERR_OR_ZERO(priv->phy_reset); in ltq_rcu_usb2_of_parse()
201 struct device *dev = &pdev->dev; in ltq_rcu_usb2_phy_probe()
208 return -ENOMEM; in ltq_rcu_usb2_phy_probe()
210 priv->dev = dev; in ltq_rcu_usb2_phy_probe()
217 reset_control_deassert(priv->ctrl_reset); in ltq_rcu_usb2_phy_probe()
219 reset_control_assert(priv->phy_reset); in ltq_rcu_usb2_phy_probe()
221 priv->phy = devm_phy_create(dev, dev->of_node, &ltq_rcu_usb2_phy_ops); in ltq_rcu_usb2_phy_probe()
222 if (IS_ERR(priv->phy)) { in ltq_rcu_usb2_phy_probe()
223 dev_err(dev, "failed to create PHY\n"); in ltq_rcu_usb2_phy_probe()
224 return PTR_ERR(priv->phy); in ltq_rcu_usb2_phy_probe()
227 phy_set_drvdata(priv->phy, priv); in ltq_rcu_usb2_phy_probe()
233 dev_set_drvdata(priv->dev, priv); in ltq_rcu_usb2_phy_probe()
240 .name = "lantiq-rcu-usb2-phy",
247 MODULE_DESCRIPTION("Lantiq XWAY USB2 PHY driver");