1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2020, The Linux Foundation. All rights reserved. 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/delay.h> 8 #include <linux/err.h> 9 #include <linux/io.h> 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/phy/phy.h> 14 #include <linux/platform_device.h> 15 #include <linux/regmap.h> 16 #include <linux/regulator/consumer.h> 17 #include <linux/reset.h> 18 #include <linux/slab.h> 19 20 #define USB2_PHY_USB_PHY_UTMI_CTRL0 (0x3c) 21 #define SLEEPM BIT(0) 22 #define OPMODE_MASK GENMASK(4, 3) 23 #define OPMODE_NORMAL (0x00) 24 #define OPMODE_NONDRIVING BIT(3) 25 #define TERMSEL BIT(5) 26 27 #define USB2_PHY_USB_PHY_UTMI_CTRL1 (0x40) 28 #define XCVRSEL BIT(0) 29 30 #define USB2_PHY_USB_PHY_UTMI_CTRL5 (0x50) 31 #define POR BIT(1) 32 33 #define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0 (0x54) 34 #define SIDDQ BIT(2) 35 #define RETENABLEN BIT(3) 36 #define FSEL_MASK GENMASK(6, 4) 37 #define FSEL_DEFAULT (0x3 << 4) 38 39 #define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1 (0x58) 40 #define VBUSVLDEXTSEL0 BIT(4) 41 #define PLLBTUNE BIT(5) 42 43 #define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2 (0x5c) 44 #define VREGBYPASS BIT(0) 45 46 #define USB2_PHY_USB_PHY_HS_PHY_CTRL1 (0x60) 47 #define VBUSVLDEXT0 BIT(0) 48 49 #define USB2_PHY_USB_PHY_HS_PHY_CTRL2 (0x64) 50 #define USB2_AUTO_RESUME BIT(0) 51 #define USB2_SUSPEND_N BIT(2) 52 #define USB2_SUSPEND_N_SEL BIT(3) 53 54 #define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X0 (0x6c) 55 #define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X1 (0x70) 56 #define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X2 (0x74) 57 #define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X3 (0x78) 58 #define PARAM_OVRD_MASK 0xFF 59 60 #define USB2_PHY_USB_PHY_CFG0 (0x94) 61 #define UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN BIT(0) 62 #define UTMI_PHY_CMN_CTRL_OVERRIDE_EN BIT(1) 63 64 #define USB2_PHY_USB_PHY_REFCLK_CTRL (0xa0) 65 #define REFCLK_SEL_MASK GENMASK(1, 0) 66 #define REFCLK_SEL_DEFAULT (0x2 << 0) 67 68 #define HS_DISCONNECT_MASK GENMASK(2, 0) 69 #define SQUELCH_DETECTOR_MASK GENMASK(7, 5) 70 71 #define HS_AMPLITUDE_MASK GENMASK(3, 0) 72 #define PREEMPHASIS_DURATION_MASK BIT(5) 73 #define PREEMPHASIS_AMPLITUDE_MASK GENMASK(7, 6) 74 75 #define HS_RISE_FALL_MASK GENMASK(1, 0) 76 #define HS_CROSSOVER_VOLTAGE_MASK GENMASK(3, 2) 77 #define HS_OUTPUT_IMPEDANCE_MASK GENMASK(5, 4) 78 79 #define LS_FS_OUTPUT_IMPEDANCE_MASK GENMASK(3, 0) 80 81 static const char * const qcom_snps_hsphy_vreg_names[] = { 82 "vdda-pll", "vdda33", "vdda18", 83 }; 84 85 #define SNPS_HS_NUM_VREGS ARRAY_SIZE(qcom_snps_hsphy_vreg_names) 86 87 struct override_param { 88 s32 value; 89 u8 reg_val; 90 }; 91 92 struct override_param_map { 93 const char *prop_name; 94 const struct override_param *param_table; 95 u8 table_size; 96 u8 reg_offset; 97 u8 param_mask; 98 }; 99 100 struct phy_override_seq { 101 bool need_update; 102 u8 offset; 103 u8 value; 104 u8 mask; 105 }; 106 107 #define NUM_HSPHY_TUNING_PARAMS (9) 108 109 /** 110 * struct qcom_snps_hsphy - snps hs phy attributes 111 * 112 * @dev: device structure 113 * 114 * @phy: generic phy 115 * @base: iomapped memory space for snps hs phy 116 * 117 * @num_clks: number of clocks 118 * @clks: array of clocks 119 * @phy_reset: phy reset control 120 * @vregs: regulator supplies bulk data 121 * @phy_initialized: if PHY has been initialized correctly 122 * @mode: contains the current mode the PHY is in 123 * @update_seq_cfg: tuning parameters for phy init 124 */ 125 struct qcom_snps_hsphy { 126 struct device *dev; 127 128 struct phy *phy; 129 void __iomem *base; 130 131 int num_clks; 132 struct clk_bulk_data *clks; 133 struct reset_control *phy_reset; 134 struct regulator_bulk_data vregs[SNPS_HS_NUM_VREGS]; 135 136 bool phy_initialized; 137 enum phy_mode mode; 138 struct phy_override_seq update_seq_cfg[NUM_HSPHY_TUNING_PARAMS]; 139 }; 140 141 static int qcom_snps_hsphy_clk_init(struct qcom_snps_hsphy *hsphy) 142 { 143 struct device *dev = hsphy->dev; 144 145 hsphy->num_clks = 2; 146 hsphy->clks = devm_kcalloc(dev, hsphy->num_clks, sizeof(*hsphy->clks), GFP_KERNEL); 147 if (!hsphy->clks) 148 return -ENOMEM; 149 150 /* 151 * TODO: Currently no device tree instantiation of the PHY is using the clock. 152 * This needs to be fixed in order for this code to be able to use devm_clk_bulk_get(). 153 */ 154 hsphy->clks[0].id = "cfg_ahb"; 155 hsphy->clks[0].clk = devm_clk_get_optional(dev, "cfg_ahb"); 156 if (IS_ERR(hsphy->clks[0].clk)) 157 return dev_err_probe(dev, PTR_ERR(hsphy->clks[0].clk), 158 "failed to get cfg_ahb clk\n"); 159 160 hsphy->clks[1].id = "ref"; 161 hsphy->clks[1].clk = devm_clk_get(dev, "ref"); 162 if (IS_ERR(hsphy->clks[1].clk)) 163 return dev_err_probe(dev, PTR_ERR(hsphy->clks[1].clk), 164 "failed to get ref clk\n"); 165 166 return 0; 167 } 168 169 static inline void qcom_snps_hsphy_write_mask(void __iomem *base, u32 offset, 170 u32 mask, u32 val) 171 { 172 u32 reg; 173 174 reg = readl_relaxed(base + offset); 175 reg &= ~mask; 176 reg |= val & mask; 177 writel_relaxed(reg, base + offset); 178 179 /* Ensure above write is completed */ 180 readl_relaxed(base + offset); 181 } 182 183 static int qcom_snps_hsphy_suspend(struct qcom_snps_hsphy *hsphy) 184 { 185 dev_dbg(&hsphy->phy->dev, "Suspend QCOM SNPS PHY\n"); 186 187 if (hsphy->mode == PHY_MODE_USB_HOST) { 188 /* Enable auto-resume to meet remote wakeup timing */ 189 qcom_snps_hsphy_write_mask(hsphy->base, 190 USB2_PHY_USB_PHY_HS_PHY_CTRL2, 191 USB2_AUTO_RESUME, 192 USB2_AUTO_RESUME); 193 usleep_range(500, 1000); 194 qcom_snps_hsphy_write_mask(hsphy->base, 195 USB2_PHY_USB_PHY_HS_PHY_CTRL2, 196 0, USB2_AUTO_RESUME); 197 } 198 199 return 0; 200 } 201 202 static int qcom_snps_hsphy_resume(struct qcom_snps_hsphy *hsphy) 203 { 204 dev_dbg(&hsphy->phy->dev, "Resume QCOM SNPS PHY, mode\n"); 205 206 return 0; 207 } 208 209 static int __maybe_unused qcom_snps_hsphy_runtime_suspend(struct device *dev) 210 { 211 struct qcom_snps_hsphy *hsphy = dev_get_drvdata(dev); 212 213 if (!hsphy->phy_initialized) 214 return 0; 215 216 return qcom_snps_hsphy_suspend(hsphy); 217 } 218 219 static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) 220 { 221 struct qcom_snps_hsphy *hsphy = dev_get_drvdata(dev); 222 223 if (!hsphy->phy_initialized) 224 return 0; 225 226 return qcom_snps_hsphy_resume(hsphy); 227 } 228 229 static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode, 230 int submode) 231 { 232 struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy); 233 234 hsphy->mode = mode; 235 return 0; 236 } 237 238 static const struct override_param hs_disconnect_sc7280[] = { 239 { -272, 0 }, 240 { 0, 1 }, 241 { 317, 2 }, 242 { 630, 3 }, 243 { 973, 4 }, 244 { 1332, 5 }, 245 { 1743, 6 }, 246 { 2156, 7 }, 247 }; 248 249 static const struct override_param squelch_det_threshold_sc7280[] = { 250 { -2090, 7 }, 251 { -1560, 6 }, 252 { -1030, 5 }, 253 { -530, 4 }, 254 { 0, 3 }, 255 { 530, 2 }, 256 { 1060, 1 }, 257 { 1590, 0 }, 258 }; 259 260 static const struct override_param hs_amplitude_sc7280[] = { 261 { -660, 0 }, 262 { -440, 1 }, 263 { -220, 2 }, 264 { 0, 3 }, 265 { 230, 4 }, 266 { 440, 5 }, 267 { 650, 6 }, 268 { 890, 7 }, 269 { 1110, 8 }, 270 { 1330, 9 }, 271 { 1560, 10 }, 272 { 1780, 11 }, 273 { 2000, 12 }, 274 { 2220, 13 }, 275 { 2430, 14 }, 276 { 2670, 15 }, 277 }; 278 279 static const struct override_param preemphasis_duration_sc7280[] = { 280 { 10000, 1 }, 281 { 20000, 0 }, 282 }; 283 284 static const struct override_param preemphasis_amplitude_sc7280[] = { 285 { 10000, 1 }, 286 { 20000, 2 }, 287 { 30000, 3 }, 288 { 40000, 0 }, 289 }; 290 291 static const struct override_param hs_rise_fall_time_sc7280[] = { 292 { -4100, 3 }, 293 { 0, 2 }, 294 { 2810, 1 }, 295 { 5430, 0 }, 296 }; 297 298 static const struct override_param hs_crossover_voltage_sc7280[] = { 299 { -31000, 1 }, 300 { 0, 3 }, 301 { 28000, 2 }, 302 }; 303 304 static const struct override_param hs_output_impedance_sc7280[] = { 305 { -2300000, 3 }, 306 { 0, 2 }, 307 { 2600000, 1 }, 308 { 6100000, 0 }, 309 }; 310 311 static const struct override_param ls_fs_output_impedance_sc7280[] = { 312 { -1053, 15 }, 313 { -557, 7 }, 314 { 0, 3 }, 315 { 612, 1 }, 316 { 1310, 0 }, 317 }; 318 319 static const struct override_param_map sc7280_snps_7nm_phy[] = { 320 { 321 "qcom,hs-disconnect-bp", 322 hs_disconnect_sc7280, 323 ARRAY_SIZE(hs_disconnect_sc7280), 324 USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X0, 325 HS_DISCONNECT_MASK 326 }, 327 { 328 "qcom,squelch-detector-bp", 329 squelch_det_threshold_sc7280, 330 ARRAY_SIZE(squelch_det_threshold_sc7280), 331 USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X0, 332 SQUELCH_DETECTOR_MASK 333 }, 334 { 335 "qcom,hs-amplitude-bp", 336 hs_amplitude_sc7280, 337 ARRAY_SIZE(hs_amplitude_sc7280), 338 USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X1, 339 HS_AMPLITUDE_MASK 340 }, 341 { 342 "qcom,pre-emphasis-duration-bp", 343 preemphasis_duration_sc7280, 344 ARRAY_SIZE(preemphasis_duration_sc7280), 345 USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X1, 346 PREEMPHASIS_DURATION_MASK, 347 }, 348 { 349 "qcom,pre-emphasis-amplitude-bp", 350 preemphasis_amplitude_sc7280, 351 ARRAY_SIZE(preemphasis_amplitude_sc7280), 352 USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X1, 353 PREEMPHASIS_AMPLITUDE_MASK, 354 }, 355 { 356 "qcom,hs-rise-fall-time-bp", 357 hs_rise_fall_time_sc7280, 358 ARRAY_SIZE(hs_rise_fall_time_sc7280), 359 USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X2, 360 HS_RISE_FALL_MASK 361 }, 362 { 363 "qcom,hs-crossover-voltage-microvolt", 364 hs_crossover_voltage_sc7280, 365 ARRAY_SIZE(hs_crossover_voltage_sc7280), 366 USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X2, 367 HS_CROSSOVER_VOLTAGE_MASK 368 }, 369 { 370 "qcom,hs-output-impedance-micro-ohms", 371 hs_output_impedance_sc7280, 372 ARRAY_SIZE(hs_output_impedance_sc7280), 373 USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X2, 374 HS_OUTPUT_IMPEDANCE_MASK, 375 }, 376 { 377 "qcom,ls-fs-output-impedance-bp", 378 ls_fs_output_impedance_sc7280, 379 ARRAY_SIZE(ls_fs_output_impedance_sc7280), 380 USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X3, 381 LS_FS_OUTPUT_IMPEDANCE_MASK, 382 }, 383 {}, 384 }; 385 386 static int qcom_snps_hsphy_init(struct phy *phy) 387 { 388 struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy); 389 int ret, i; 390 391 dev_vdbg(&phy->dev, "%s(): Initializing SNPS HS phy\n", __func__); 392 393 ret = regulator_bulk_enable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); 394 if (ret) 395 return ret; 396 397 ret = clk_bulk_prepare_enable(hsphy->num_clks, hsphy->clks); 398 if (ret) { 399 dev_err(&phy->dev, "failed to enable clocks, %d\n", ret); 400 goto poweroff_phy; 401 } 402 403 ret = reset_control_assert(hsphy->phy_reset); 404 if (ret) { 405 dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret); 406 goto disable_clks; 407 } 408 409 usleep_range(100, 150); 410 411 ret = reset_control_deassert(hsphy->phy_reset); 412 if (ret) { 413 dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret); 414 goto disable_clks; 415 } 416 417 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0, 418 UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 419 UTMI_PHY_CMN_CTRL_OVERRIDE_EN); 420 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_UTMI_CTRL5, 421 POR, POR); 422 qcom_snps_hsphy_write_mask(hsphy->base, 423 USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0, 424 FSEL_MASK, 0); 425 qcom_snps_hsphy_write_mask(hsphy->base, 426 USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, 427 PLLBTUNE, PLLBTUNE); 428 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_REFCLK_CTRL, 429 REFCLK_SEL_DEFAULT, REFCLK_SEL_MASK); 430 qcom_snps_hsphy_write_mask(hsphy->base, 431 USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, 432 VBUSVLDEXTSEL0, VBUSVLDEXTSEL0); 433 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL1, 434 VBUSVLDEXT0, VBUSVLDEXT0); 435 436 for (i = 0; i < ARRAY_SIZE(hsphy->update_seq_cfg); i++) { 437 if (hsphy->update_seq_cfg[i].need_update) 438 qcom_snps_hsphy_write_mask(hsphy->base, 439 hsphy->update_seq_cfg[i].offset, 440 hsphy->update_seq_cfg[i].mask, 441 hsphy->update_seq_cfg[i].value); 442 } 443 444 qcom_snps_hsphy_write_mask(hsphy->base, 445 USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2, 446 VREGBYPASS, VREGBYPASS); 447 448 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2, 449 USB2_SUSPEND_N_SEL | USB2_SUSPEND_N, 450 USB2_SUSPEND_N_SEL | USB2_SUSPEND_N); 451 452 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_UTMI_CTRL0, 453 SLEEPM, SLEEPM); 454 455 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0, 456 SIDDQ, 0); 457 458 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_UTMI_CTRL5, 459 POR, 0); 460 461 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2, 462 USB2_SUSPEND_N_SEL, 0); 463 464 qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0, 465 UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 0); 466 467 hsphy->phy_initialized = true; 468 469 return 0; 470 471 disable_clks: 472 clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks); 473 poweroff_phy: 474 regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); 475 476 return ret; 477 } 478 479 static int qcom_snps_hsphy_exit(struct phy *phy) 480 { 481 struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy); 482 483 reset_control_assert(hsphy->phy_reset); 484 clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks); 485 regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); 486 hsphy->phy_initialized = false; 487 488 return 0; 489 } 490 491 static const struct phy_ops qcom_snps_hsphy_gen_ops = { 492 .init = qcom_snps_hsphy_init, 493 .exit = qcom_snps_hsphy_exit, 494 .set_mode = qcom_snps_hsphy_set_mode, 495 .owner = THIS_MODULE, 496 }; 497 498 static const struct of_device_id qcom_snps_hsphy_of_match_table[] = { 499 { .compatible = "qcom,sm8150-usb-hs-phy", }, 500 { .compatible = "qcom,usb-snps-hs-5nm-phy", }, 501 { 502 .compatible = "qcom,usb-snps-hs-7nm-phy", 503 .data = &sc7280_snps_7nm_phy, 504 }, 505 { .compatible = "qcom,usb-snps-femto-v2-phy", }, 506 { } 507 }; 508 MODULE_DEVICE_TABLE(of, qcom_snps_hsphy_of_match_table); 509 510 static const struct dev_pm_ops qcom_snps_hsphy_pm_ops = { 511 SET_RUNTIME_PM_OPS(qcom_snps_hsphy_runtime_suspend, 512 qcom_snps_hsphy_runtime_resume, NULL) 513 }; 514 515 static void qcom_snps_hsphy_override_param_update_val( 516 const struct override_param_map map, 517 s32 dt_val, struct phy_override_seq *seq_entry) 518 { 519 int i; 520 521 /* 522 * Param table for each param is in increasing order 523 * of dt values. We need to iterate over the list to 524 * select the entry that matches the dt value and pick 525 * up the corresponding register value. 526 */ 527 for (i = 0; i < map.table_size - 1; i++) { 528 if (map.param_table[i].value == dt_val) 529 break; 530 } 531 532 seq_entry->need_update = true; 533 seq_entry->offset = map.reg_offset; 534 seq_entry->mask = map.param_mask; 535 seq_entry->value = map.param_table[i].reg_val << __ffs(map.param_mask); 536 } 537 538 static void qcom_snps_hsphy_read_override_param_seq(struct device *dev) 539 { 540 struct device_node *node = dev->of_node; 541 s32 val; 542 int ret, i; 543 struct qcom_snps_hsphy *hsphy; 544 const struct override_param_map *cfg = of_device_get_match_data(dev); 545 546 if (!cfg) 547 return; 548 549 hsphy = dev_get_drvdata(dev); 550 551 for (i = 0; cfg[i].prop_name != NULL; i++) { 552 ret = of_property_read_s32(node, cfg[i].prop_name, &val); 553 if (ret) 554 continue; 555 556 qcom_snps_hsphy_override_param_update_val(cfg[i], val, 557 &hsphy->update_seq_cfg[i]); 558 dev_dbg(&hsphy->phy->dev, "Read param: %s dt_val: %d reg_val: 0x%x\n", 559 cfg[i].prop_name, val, hsphy->update_seq_cfg[i].value); 560 561 } 562 } 563 564 static int qcom_snps_hsphy_probe(struct platform_device *pdev) 565 { 566 struct device *dev = &pdev->dev; 567 struct qcom_snps_hsphy *hsphy; 568 struct phy_provider *phy_provider; 569 struct phy *generic_phy; 570 int ret, i; 571 int num; 572 573 hsphy = devm_kzalloc(dev, sizeof(*hsphy), GFP_KERNEL); 574 if (!hsphy) 575 return -ENOMEM; 576 577 hsphy->dev = dev; 578 579 hsphy->base = devm_platform_ioremap_resource(pdev, 0); 580 if (IS_ERR(hsphy->base)) 581 return PTR_ERR(hsphy->base); 582 583 ret = qcom_snps_hsphy_clk_init(hsphy); 584 if (ret) 585 return dev_err_probe(dev, ret, "failed to initialize clocks\n"); 586 587 hsphy->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); 588 if (IS_ERR(hsphy->phy_reset)) { 589 dev_err(dev, "failed to get phy core reset\n"); 590 return PTR_ERR(hsphy->phy_reset); 591 } 592 593 num = ARRAY_SIZE(hsphy->vregs); 594 for (i = 0; i < num; i++) 595 hsphy->vregs[i].supply = qcom_snps_hsphy_vreg_names[i]; 596 597 ret = devm_regulator_bulk_get(dev, num, hsphy->vregs); 598 if (ret) 599 return dev_err_probe(dev, ret, 600 "failed to get regulator supplies\n"); 601 602 pm_runtime_set_active(dev); 603 pm_runtime_enable(dev); 604 /* 605 * Prevent runtime pm from being ON by default. Users can enable 606 * it using power/control in sysfs. 607 */ 608 pm_runtime_forbid(dev); 609 610 generic_phy = devm_phy_create(dev, NULL, &qcom_snps_hsphy_gen_ops); 611 if (IS_ERR(generic_phy)) { 612 ret = PTR_ERR(generic_phy); 613 dev_err(dev, "failed to create phy, %d\n", ret); 614 return ret; 615 } 616 hsphy->phy = generic_phy; 617 618 dev_set_drvdata(dev, hsphy); 619 phy_set_drvdata(generic_phy, hsphy); 620 qcom_snps_hsphy_read_override_param_seq(dev); 621 622 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 623 if (!IS_ERR(phy_provider)) 624 dev_dbg(dev, "Registered Qcom-SNPS HS phy\n"); 625 else 626 pm_runtime_disable(dev); 627 628 return PTR_ERR_OR_ZERO(phy_provider); 629 } 630 631 static struct platform_driver qcom_snps_hsphy_driver = { 632 .probe = qcom_snps_hsphy_probe, 633 .driver = { 634 .name = "qcom-snps-hs-femto-v2-phy", 635 .pm = &qcom_snps_hsphy_pm_ops, 636 .of_match_table = qcom_snps_hsphy_of_match_table, 637 }, 638 }; 639 640 module_platform_driver(qcom_snps_hsphy_driver); 641 642 MODULE_DESCRIPTION("Qualcomm SNPS FEMTO USB HS PHY V2 driver"); 643 MODULE_LICENSE("GPL v2"); 644