Lines Matching +full:sm8750 +full:- +full:m31 +full:- +full:eusb2 +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
14 #include <linux/phy/phy.h>
114 struct phy *phy; member
123 struct phy *repeater;
143 return -EINVAL; in m31eusb2_phy_write_readback()
149 static int m31eusb2_phy_write_sequence(struct m31eusb2_phy *phy, in m31eusb2_phy_write_sequence() argument
157 dev_dbg(&phy->phy->dev, "Offset:%x BitMask:%x Value:%x", in m31eusb2_phy_write_sequence()
158 tbl->off, tbl->mask, tbl->val); in m31eusb2_phy_write_sequence()
160 ret = m31eusb2_phy_write_readback(phy->base, in m31eusb2_phy_write_sequence()
161 tbl->off, tbl->mask, in m31eusb2_phy_write_sequence()
162 tbl->val << __ffs(tbl->mask)); in m31eusb2_phy_write_sequence()
170 static int m31eusb2_phy_set_mode(struct phy *uphy, enum phy_mode mode, int submode) in m31eusb2_phy_set_mode()
172 struct m31eusb2_phy *phy = phy_get_drvdata(uphy); in m31eusb2_phy_set_mode() local
174 phy->mode = mode; in m31eusb2_phy_set_mode()
176 return phy_set_mode_ext(phy->repeater, mode, submode); in m31eusb2_phy_set_mode()
179 static int m31eusb2_phy_init(struct phy *uphy) in m31eusb2_phy_init()
181 struct m31eusb2_phy *phy = phy_get_drvdata(uphy); in m31eusb2_phy_init() local
182 const struct m31_eusb2_priv_data *data = phy->data; in m31eusb2_phy_init()
185 ret = regulator_bulk_enable(M31_EUSB_NUM_VREGS, phy->vregs); in m31eusb2_phy_init()
187 dev_err(&uphy->dev, "failed to enable regulator, %d\n", ret); in m31eusb2_phy_init()
191 ret = phy_init(phy->repeater); in m31eusb2_phy_init()
193 dev_err(&uphy->dev, "repeater init failed. %d\n", ret); in m31eusb2_phy_init()
197 ret = clk_prepare_enable(phy->clk); in m31eusb2_phy_init()
199 dev_err(&uphy->dev, "failed to enable cfg ahb clock, %d\n", ret); in m31eusb2_phy_init()
203 /* Perform phy reset */ in m31eusb2_phy_init()
204 reset_control_assert(phy->reset); in m31eusb2_phy_init()
206 reset_control_deassert(phy->reset); in m31eusb2_phy_init()
208 m31eusb2_phy_write_sequence(phy, data->setup_seq, data->setup_seq_nregs); in m31eusb2_phy_init()
209 m31eusb2_phy_write_readback(phy->base, in m31eusb2_phy_init()
211 FIELD_PREP(FSEL, data->fsel)); in m31eusb2_phy_init()
212 m31eusb2_phy_write_sequence(phy, data->override_seq, data->override_seq_nregs); in m31eusb2_phy_init()
213 m31eusb2_phy_write_sequence(phy, data->reset_seq, data->reset_seq_nregs); in m31eusb2_phy_init()
218 phy_exit(phy->repeater); in m31eusb2_phy_init()
220 regulator_bulk_disable(M31_EUSB_NUM_VREGS, phy->vregs); in m31eusb2_phy_init()
225 static int m31eusb2_phy_exit(struct phy *uphy) in m31eusb2_phy_exit()
227 struct m31eusb2_phy *phy = phy_get_drvdata(uphy); in m31eusb2_phy_exit() local
229 clk_disable_unprepare(phy->clk); in m31eusb2_phy_exit()
230 regulator_bulk_disable(M31_EUSB_NUM_VREGS, phy->vregs); in m31eusb2_phy_exit()
231 phy_exit(phy->repeater); in m31eusb2_phy_exit()
247 struct device *dev = &pdev->dev; in m31eusb2_phy_probe()
248 struct m31eusb2_phy *phy; in m31eusb2_phy_probe() local
251 phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); in m31eusb2_phy_probe()
252 if (!phy) in m31eusb2_phy_probe()
253 return -ENOMEM; in m31eusb2_phy_probe()
257 return -EINVAL; in m31eusb2_phy_probe()
258 phy->data = data; in m31eusb2_phy_probe()
260 phy->base = devm_platform_ioremap_resource(pdev, 0); in m31eusb2_phy_probe()
261 if (IS_ERR(phy->base)) in m31eusb2_phy_probe()
262 return PTR_ERR(phy->base); in m31eusb2_phy_probe()
264 phy->reset = devm_reset_control_get_exclusive(dev, NULL); in m31eusb2_phy_probe()
265 if (IS_ERR(phy->reset)) in m31eusb2_phy_probe()
266 return PTR_ERR(phy->reset); in m31eusb2_phy_probe()
268 phy->clk = devm_clk_get(dev, NULL); in m31eusb2_phy_probe()
269 if (IS_ERR(phy->clk)) in m31eusb2_phy_probe()
270 return dev_err_probe(dev, PTR_ERR(phy->clk), in m31eusb2_phy_probe()
273 phy->phy = devm_phy_create(dev, NULL, &m31eusb2_phy_gen_ops); in m31eusb2_phy_probe()
274 if (IS_ERR(phy->phy)) in m31eusb2_phy_probe()
275 return dev_err_probe(dev, PTR_ERR(phy->phy), in m31eusb2_phy_probe()
276 "failed to create phy\n"); in m31eusb2_phy_probe()
279 m31_eusb_phy_vregs, &phy->vregs); in m31eusb2_phy_probe()
284 phy_set_drvdata(phy->phy, phy); in m31eusb2_phy_probe()
286 phy->repeater = devm_of_phy_get_by_index(dev, dev->of_node, 0); in m31eusb2_phy_probe()
287 if (IS_ERR(phy->repeater)) in m31eusb2_phy_probe()
288 return dev_err_probe(dev, PTR_ERR(phy->repeater), in m31eusb2_phy_probe()
307 { .compatible = "qcom,sm8750-m31-eusb2-phy", .data = &m31_eusb_v1_data },
315 .name = "qcom-m31eusb2-phy",
323 MODULE_DESCRIPTION("eUSB2 Qualcomm M31 HSPHY driver");