Lines Matching +full:usb2 +full:- +full:phy

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Samsung SoC USB 1.1/2.0 PHY driver
15 #include <linux/phy/phy.h>
18 #include "phy-samsung-usb2.h"
20 static int samsung_usb2_phy_power_on(struct phy *phy) in samsung_usb2_phy_power_on() argument
22 struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); in samsung_usb2_phy_power_on()
23 struct samsung_usb2_phy_driver *drv = inst->drv; in samsung_usb2_phy_power_on()
26 dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n", in samsung_usb2_phy_power_on()
27 inst->cfg->label); in samsung_usb2_phy_power_on()
29 if (drv->vbus) { in samsung_usb2_phy_power_on()
30 ret = regulator_enable(drv->vbus); in samsung_usb2_phy_power_on()
35 ret = clk_prepare_enable(drv->clk); in samsung_usb2_phy_power_on()
38 ret = clk_prepare_enable(drv->ref_clk); in samsung_usb2_phy_power_on()
41 if (inst->cfg->power_on) { in samsung_usb2_phy_power_on()
42 spin_lock(&drv->lock); in samsung_usb2_phy_power_on()
43 ret = inst->cfg->power_on(inst); in samsung_usb2_phy_power_on()
44 spin_unlock(&drv->lock); in samsung_usb2_phy_power_on()
52 clk_disable_unprepare(drv->ref_clk); in samsung_usb2_phy_power_on()
54 clk_disable_unprepare(drv->clk); in samsung_usb2_phy_power_on()
56 if (drv->vbus) in samsung_usb2_phy_power_on()
57 regulator_disable(drv->vbus); in samsung_usb2_phy_power_on()
62 static int samsung_usb2_phy_power_off(struct phy *phy) in samsung_usb2_phy_power_off() argument
64 struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); in samsung_usb2_phy_power_off()
65 struct samsung_usb2_phy_driver *drv = inst->drv; in samsung_usb2_phy_power_off()
68 dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n", in samsung_usb2_phy_power_off()
69 inst->cfg->label); in samsung_usb2_phy_power_off()
70 if (inst->cfg->power_off) { in samsung_usb2_phy_power_off()
71 spin_lock(&drv->lock); in samsung_usb2_phy_power_off()
72 ret = inst->cfg->power_off(inst); in samsung_usb2_phy_power_off()
73 spin_unlock(&drv->lock); in samsung_usb2_phy_power_off()
77 clk_disable_unprepare(drv->ref_clk); in samsung_usb2_phy_power_off()
78 clk_disable_unprepare(drv->clk); in samsung_usb2_phy_power_off()
79 if (drv->vbus) in samsung_usb2_phy_power_off()
80 ret = regulator_disable(drv->vbus); in samsung_usb2_phy_power_off()
91 static struct phy *samsung_usb2_phy_xlate(struct device *dev, in samsung_usb2_phy_xlate()
98 return ERR_PTR(-EINVAL); in samsung_usb2_phy_xlate()
100 if (WARN_ON(args->args[0] >= drv->cfg->num_phys)) in samsung_usb2_phy_xlate()
101 return ERR_PTR(-ENODEV); in samsung_usb2_phy_xlate()
103 return drv->instances[args->args[0]].phy; in samsung_usb2_phy_xlate()
109 .compatible = "samsung,exynos3250-usb2-phy",
115 .compatible = "samsung,exynos4210-usb2-phy",
121 .compatible = "samsung,exynos4x12-usb2-phy",
127 .compatible = "samsung,exynos5250-usb2-phy",
131 .compatible = "samsung,exynos5420-usb2-phy",
137 .compatible = "samsung,s5pv210-usb2-phy",
148 struct device *dev = &pdev->dev; in samsung_usb2_phy_probe()
153 if (!pdev->dev.of_node) { in samsung_usb2_phy_probe()
155 return -EINVAL; in samsung_usb2_phy_probe()
160 return -EINVAL; in samsung_usb2_phy_probe()
162 drv = devm_kzalloc(dev, struct_size(drv, instances, cfg->num_phys), in samsung_usb2_phy_probe()
165 return -ENOMEM; in samsung_usb2_phy_probe()
168 spin_lock_init(&drv->lock); in samsung_usb2_phy_probe()
170 drv->cfg = cfg; in samsung_usb2_phy_probe()
171 drv->dev = dev; in samsung_usb2_phy_probe()
173 drv->reg_phy = devm_platform_ioremap_resource(pdev, 0); in samsung_usb2_phy_probe()
174 if (IS_ERR(drv->reg_phy)) { in samsung_usb2_phy_probe()
175 dev_err(dev, "Failed to map register memory (phy)\n"); in samsung_usb2_phy_probe()
176 return PTR_ERR(drv->reg_phy); in samsung_usb2_phy_probe()
179 drv->reg_pmu = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, in samsung_usb2_phy_probe()
180 "samsung,pmureg-phandle"); in samsung_usb2_phy_probe()
181 if (IS_ERR(drv->reg_pmu)) { in samsung_usb2_phy_probe()
183 return PTR_ERR(drv->reg_pmu); in samsung_usb2_phy_probe()
186 if (drv->cfg->has_mode_switch) { in samsung_usb2_phy_probe()
187 drv->reg_sys = syscon_regmap_lookup_by_phandle( in samsung_usb2_phy_probe()
188 pdev->dev.of_node, "samsung,sysreg-phandle"); in samsung_usb2_phy_probe()
189 if (IS_ERR(drv->reg_sys)) { in samsung_usb2_phy_probe()
191 return PTR_ERR(drv->reg_sys); in samsung_usb2_phy_probe()
195 drv->clk = devm_clk_get(dev, "phy"); in samsung_usb2_phy_probe()
196 if (IS_ERR(drv->clk)) { in samsung_usb2_phy_probe()
197 dev_err(dev, "Failed to get clock of phy controller\n"); in samsung_usb2_phy_probe()
198 return PTR_ERR(drv->clk); in samsung_usb2_phy_probe()
201 drv->ref_clk = devm_clk_get(dev, "ref"); in samsung_usb2_phy_probe()
202 if (IS_ERR(drv->ref_clk)) { in samsung_usb2_phy_probe()
203 dev_err(dev, "Failed to get reference clock for the phy controller\n"); in samsung_usb2_phy_probe()
204 return PTR_ERR(drv->ref_clk); in samsung_usb2_phy_probe()
207 drv->ref_rate = clk_get_rate(drv->ref_clk); in samsung_usb2_phy_probe()
208 if (drv->cfg->rate_to_clk) { in samsung_usb2_phy_probe()
209 ret = drv->cfg->rate_to_clk(drv->ref_rate, &drv->ref_reg_val); in samsung_usb2_phy_probe()
214 drv->vbus = devm_regulator_get(dev, "vbus"); in samsung_usb2_phy_probe()
215 if (IS_ERR(drv->vbus)) { in samsung_usb2_phy_probe()
216 ret = PTR_ERR(drv->vbus); in samsung_usb2_phy_probe()
217 if (ret == -EPROBE_DEFER) in samsung_usb2_phy_probe()
219 drv->vbus = NULL; in samsung_usb2_phy_probe()
222 for (i = 0; i < drv->cfg->num_phys; i++) { in samsung_usb2_phy_probe()
223 char *label = drv->cfg->phys[i].label; in samsung_usb2_phy_probe()
224 struct samsung_usb2_phy_instance *p = &drv->instances[i]; in samsung_usb2_phy_probe()
226 dev_dbg(dev, "Creating phy \"%s\"\n", label); in samsung_usb2_phy_probe()
227 p->phy = devm_phy_create(dev, NULL, &samsung_usb2_phy_ops); in samsung_usb2_phy_probe()
228 if (IS_ERR(p->phy)) { in samsung_usb2_phy_probe()
229 dev_err(drv->dev, "Failed to create usb2_phy \"%s\"\n", in samsung_usb2_phy_probe()
231 return PTR_ERR(p->phy); in samsung_usb2_phy_probe()
234 p->cfg = &drv->cfg->phys[i]; in samsung_usb2_phy_probe()
235 p->drv = drv; in samsung_usb2_phy_probe()
236 phy_set_bus_width(p->phy, 8); in samsung_usb2_phy_probe()
237 phy_set_drvdata(p->phy, p); in samsung_usb2_phy_probe()
243 dev_err(drv->dev, "Failed to register phy provider\n"); in samsung_usb2_phy_probe()
254 .name = "samsung-usb2-phy",
260 MODULE_DESCRIPTION("Samsung S5P/Exynos SoC USB PHY driver");
263 MODULE_ALIAS("platform:samsung-usb2-phy");