phy-hi3670-usb3.c (15693B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform 4 * 5 * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd. 6 * http://www.huawei.com 7 * 8 * Authors: Yu Chen <chenyu56@huawei.com> 9 */ 10 11#include <linux/bitfield.h> 12#include <linux/clk.h> 13#include <linux/kernel.h> 14#include <linux/mfd/syscon.h> 15#include <linux/module.h> 16#include <linux/phy/phy.h> 17#include <linux/platform_device.h> 18#include <linux/regmap.h> 19 20#define SCTRL_SCDEEPSLEEPED (0x0) 21#define USB_CLK_SELECTED BIT(20) 22 23#define PERI_CRG_PEREN0 (0x00) 24#define PERI_CRG_PERDIS0 (0x04) 25#define PERI_CRG_PEREN4 (0x40) 26#define PERI_CRG_PERDIS4 (0x44) 27#define PERI_CRG_PERRSTEN4 (0x90) 28#define PERI_CRG_PERRSTDIS4 (0x94) 29#define PERI_CRG_ISODIS (0x148) 30#define PERI_CRG_PEREN6 (0x410) 31#define PERI_CRG_PERDIS6 (0x414) 32 33#define USB_REFCLK_ISO_EN BIT(25) 34 35#define GT_CLK_USB2PHY_REF BIT(19) 36 37#define PCTRL_PERI_CTRL3 (0x10) 38#define PCTRL_PERI_CTRL3_MSK_START (16) 39#define USB_TCXO_EN BIT(1) 40 41#define PCTRL_PERI_CTRL24 (0x64) 42#define SC_CLK_USB3PHY_3MUX1_SEL BIT(25) 43 44#define USB3OTG_CTRL0 (0x00) 45#define USB3OTG_CTRL3 (0x0c) 46#define USB3OTG_CTRL4 (0x10) 47#define USB3OTG_CTRL5 (0x14) 48#define USB3OTG_CTRL7 (0x1c) 49#define USB_MISC_CFG50 (0x50) 50#define USB_MISC_CFG54 (0x54) 51#define USB_MISC_CFG58 (0x58) 52#define USB_MISC_CFG5C (0x5c) 53#define USB_MISC_CFGA0 (0xa0) 54#define TCA_CLK_RST (0x200) 55#define TCA_INTR_EN (0x204) 56#define TCA_INTR_STS (0x208) 57#define TCA_GCFG (0x210) 58#define TCA_TCPC (0x214) 59#define TCA_SYSMODE_CFG (0x218) 60#define TCA_VBUS_CTRL (0x240) 61 62#define CTRL0_USB3_VBUSVLD BIT(7) 63#define CTRL0_USB3_VBUSVLD_SEL BIT(6) 64 65#define CTRL3_USB2_VBUSVLDEXT0 BIT(6) 66#define CTRL3_USB2_VBUSVLDEXTSEL0 BIT(5) 67 68#define CTRL5_USB2_SIDDQ BIT(0) 69 70#define CTRL7_USB2_REFCLKSEL_MASK GENMASK(4, 3) 71#define CTRL7_USB2_REFCLKSEL_ABB (BIT(4) | BIT(3)) 72#define CTRL7_USB2_REFCLKSEL_PAD BIT(4) 73 74#define CFG50_USB3_PHY_TEST_POWERDOWN BIT(23) 75 76#define CFG54_USB31PHY_CR_ADDR_MASK GENMASK(31, 16) 77 78#define CFG54_USB3PHY_REF_USE_PAD BIT(12) 79#define CFG54_PHY0_PMA_PWR_STABLE BIT(11) 80#define CFG54_PHY0_PCS_PWR_STABLE BIT(9) 81#define CFG54_USB31PHY_CR_ACK BIT(7) 82#define CFG54_USB31PHY_CR_WR_EN BIT(5) 83#define CFG54_USB31PHY_CR_SEL BIT(4) 84#define CFG54_USB31PHY_CR_RD_EN BIT(3) 85#define CFG54_USB31PHY_CR_CLK BIT(2) 86#define CFG54_USB3_PHY0_ANA_PWR_EN BIT(1) 87 88#define CFG58_USB31PHY_CR_DATA_MASK GENMASK(31, 16) 89 90#define CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN BIT(1) 91 92#define CFGA0_VAUX_RESET BIT(9) 93#define CFGA0_USB31C_RESET BIT(8) 94#define CFGA0_USB2PHY_REFCLK_SELECT BIT(4) 95#define CFGA0_USB3PHY_RESET BIT(1) 96#define CFGA0_USB2PHY_POR BIT(0) 97 98#define INTR_EN_XA_TIMEOUT_EVT_EN BIT(1) 99#define INTR_EN_XA_ACK_EVT_EN BIT(0) 100 101#define CLK_RST_TCA_REF_CLK_EN BIT(1) 102#define CLK_RST_SUSPEND_CLK_EN BIT(0) 103 104#define GCFG_ROLE_HSTDEV BIT(4) 105#define GCFG_OP_MODE GENMASK(1, 0) 106#define GCFG_OP_MODE_CTRL_SYNC_MODE BIT(0) 107 108#define TCPC_VALID BIT(4) 109#define TCPC_LOW_POWER_EN BIT(3) 110#define TCPC_MUX_CONTROL_MASK GENMASK(1, 0) 111#define TCPC_MUX_CONTROL_USB31 BIT(0) 112 113#define SYSMODE_CFG_TYPEC_DISABLE BIT(3) 114 115#define VBUS_CTRL_POWERPRESENT_OVERRD GENMASK(3, 2) 116#define VBUS_CTRL_VBUSVALID_OVERRD GENMASK(1, 0) 117 118#define KIRIN970_USB_DEFAULT_PHY_PARAM (0xfdfee4) 119#define KIRIN970_USB_DEFAULT_PHY_VBOOST (0x5) 120 121#define TX_VBOOST_LVL_REG (0xf) 122#define TX_VBOOST_LVL_START (6) 123#define TX_VBOOST_LVL_ENABLE BIT(9) 124 125struct hi3670_priv { 126 struct device *dev; 127 struct regmap *peri_crg; 128 struct regmap *pctrl; 129 struct regmap *sctrl; 130 struct regmap *usb31misc; 131 132 u32 eye_diagram_param; 133 u32 tx_vboost_lvl; 134 135 u32 peri_crg_offset; 136 u32 pctrl_offset; 137 u32 usb31misc_offset; 138}; 139 140static int hi3670_phy_cr_clk(struct regmap *usb31misc) 141{ 142 int ret; 143 144 /* Clock up */ 145 ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, 146 CFG54_USB31PHY_CR_CLK, CFG54_USB31PHY_CR_CLK); 147 if (ret) 148 return ret; 149 150 /* Clock down */ 151 return regmap_update_bits(usb31misc, USB_MISC_CFG54, 152 CFG54_USB31PHY_CR_CLK, 0); 153} 154 155static int hi3670_phy_cr_set_sel(struct regmap *usb31misc) 156{ 157 return regmap_update_bits(usb31misc, USB_MISC_CFG54, 158 CFG54_USB31PHY_CR_SEL, CFG54_USB31PHY_CR_SEL); 159} 160 161static int hi3670_phy_cr_start(struct regmap *usb31misc, int direction) 162{ 163 int ret, reg; 164 165 if (direction) 166 reg = CFG54_USB31PHY_CR_WR_EN; 167 else 168 reg = CFG54_USB31PHY_CR_RD_EN; 169 170 ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, reg, reg); 171 172 if (ret) 173 return ret; 174 175 ret = hi3670_phy_cr_clk(usb31misc); 176 if (ret) 177 return ret; 178 179 return regmap_update_bits(usb31misc, USB_MISC_CFG54, 180 CFG54_USB31PHY_CR_RD_EN | CFG54_USB31PHY_CR_WR_EN, 0); 181} 182 183static int hi3670_phy_cr_wait_ack(struct regmap *usb31misc) 184{ 185 u32 reg; 186 int retry = 10; 187 int ret; 188 189 while (retry-- > 0) { 190 ret = regmap_read(usb31misc, USB_MISC_CFG54, ®); 191 if (ret) 192 return ret; 193 if ((reg & CFG54_USB31PHY_CR_ACK) == CFG54_USB31PHY_CR_ACK) 194 return 0; 195 196 ret = hi3670_phy_cr_clk(usb31misc); 197 if (ret) 198 return ret; 199 200 usleep_range(10, 20); 201 } 202 203 return -ETIMEDOUT; 204} 205 206static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr) 207{ 208 u32 reg; 209 int ret; 210 211 ret = regmap_read(usb31misc, USB_MISC_CFG54, ®); 212 if (ret) 213 return ret; 214 215 reg = FIELD_PREP(CFG54_USB31PHY_CR_ADDR_MASK, addr); 216 217 return regmap_update_bits(usb31misc, USB_MISC_CFG54, 218 CFG54_USB31PHY_CR_ADDR_MASK, reg); 219} 220 221static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val) 222{ 223 int reg, i, ret; 224 225 for (i = 0; i < 100; i++) { 226 ret = hi3670_phy_cr_clk(usb31misc); 227 if (ret) 228 return ret; 229 } 230 231 ret = hi3670_phy_cr_set_sel(usb31misc); 232 if (ret) 233 return ret; 234 235 ret = hi3670_phy_cr_set_addr(usb31misc, addr); 236 if (ret) 237 return ret; 238 239 ret = hi3670_phy_cr_start(usb31misc, 0); 240 if (ret) 241 return ret; 242 243 ret = hi3670_phy_cr_wait_ack(usb31misc); 244 if (ret) 245 return ret; 246 247 ret = regmap_read(usb31misc, USB_MISC_CFG58, ®); 248 if (ret) 249 return ret; 250 251 *val = FIELD_GET(CFG58_USB31PHY_CR_DATA_MASK, reg); 252 253 return 0; 254} 255 256static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val) 257{ 258 int i; 259 int ret; 260 261 for (i = 0; i < 100; i++) { 262 ret = hi3670_phy_cr_clk(usb31misc); 263 if (ret) 264 return ret; 265 } 266 267 ret = hi3670_phy_cr_set_sel(usb31misc); 268 if (ret) 269 return ret; 270 271 ret = hi3670_phy_cr_set_addr(usb31misc, addr); 272 if (ret) 273 return ret; 274 275 ret = regmap_write(usb31misc, USB_MISC_CFG58, 276 FIELD_PREP(CFG58_USB31PHY_CR_DATA_MASK, val)); 277 if (ret) 278 return ret; 279 280 ret = hi3670_phy_cr_start(usb31misc, 1); 281 if (ret) 282 return ret; 283 284 return hi3670_phy_cr_wait_ack(usb31misc); 285} 286 287static int hi3670_phy_set_params(struct hi3670_priv *priv) 288{ 289 u32 reg; 290 int ret; 291 int retry = 3; 292 293 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4, 294 priv->eye_diagram_param); 295 if (ret) { 296 dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n"); 297 return ret; 298 } 299 300 while (retry-- > 0) { 301 ret = hi3670_phy_cr_read(priv->usb31misc, 302 TX_VBOOST_LVL_REG, ®); 303 if (!ret) 304 break; 305 306 if (ret != -ETIMEDOUT) { 307 dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n"); 308 return ret; 309 } 310 } 311 if (ret) 312 return ret; 313 314 reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START)); 315 ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg); 316 if (ret) 317 dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n"); 318 319 return ret; 320} 321 322static bool hi3670_is_abbclk_selected(struct hi3670_priv *priv) 323{ 324 u32 reg; 325 326 if (!priv->sctrl) { 327 dev_err(priv->dev, "priv->sctrl is null!\n"); 328 return false; 329 } 330 331 if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, ®)) { 332 dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n"); 333 return false; 334 } 335 336 if ((reg & USB_CLK_SELECTED) == 0) 337 return false; 338 339 return true; 340} 341 342static int hi3670_config_phy_clock(struct hi3670_priv *priv) 343{ 344 u32 val, mask; 345 int ret; 346 347 if (!hi3670_is_abbclk_selected(priv)) { 348 /* usb refclk iso disable */ 349 ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS, 350 USB_REFCLK_ISO_EN); 351 if (ret) 352 goto out; 353 354 /* enable usb_tcxo_en */ 355 ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3, 356 USB_TCXO_EN | 357 (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START)); 358 359 /* select usbphy clk from abb */ 360 mask = SC_CLK_USB3PHY_3MUX1_SEL; 361 ret = regmap_update_bits(priv->pctrl, 362 PCTRL_PERI_CTRL24, mask, 0); 363 if (ret) 364 goto out; 365 366 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, 367 CFGA0_USB2PHY_REFCLK_SELECT, 0); 368 if (ret) 369 goto out; 370 371 ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val); 372 if (ret) 373 goto out; 374 val &= ~CTRL7_USB2_REFCLKSEL_MASK; 375 val |= CTRL7_USB2_REFCLKSEL_ABB; 376 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val); 377 if (ret) 378 goto out; 379 380 return 0; 381 } 382 383 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54, 384 CFG54_USB3PHY_REF_USE_PAD, 385 CFG54_USB3PHY_REF_USE_PAD); 386 if (ret) 387 goto out; 388 389 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, 390 CFGA0_USB2PHY_REFCLK_SELECT, 391 CFGA0_USB2PHY_REFCLK_SELECT); 392 if (ret) 393 goto out; 394 395 ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val); 396 if (ret) 397 goto out; 398 val &= ~CTRL7_USB2_REFCLKSEL_MASK; 399 val |= CTRL7_USB2_REFCLKSEL_PAD; 400 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val); 401 if (ret) 402 goto out; 403 404 ret = regmap_write(priv->peri_crg, 405 PERI_CRG_PEREN6, GT_CLK_USB2PHY_REF); 406 if (ret) 407 goto out; 408 409 return 0; 410out: 411 dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret); 412 return ret; 413} 414 415static int hi3670_config_tca(struct hi3670_priv *priv) 416{ 417 u32 val, mask; 418 int ret; 419 420 ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff); 421 if (ret) 422 goto out; 423 424 ret = regmap_write(priv->usb31misc, TCA_INTR_EN, 425 INTR_EN_XA_TIMEOUT_EVT_EN | INTR_EN_XA_ACK_EVT_EN); 426 if (ret) 427 goto out; 428 429 mask = CLK_RST_TCA_REF_CLK_EN | CLK_RST_SUSPEND_CLK_EN; 430 ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0); 431 if (ret) 432 goto out; 433 434 ret = regmap_update_bits(priv->usb31misc, TCA_GCFG, 435 GCFG_ROLE_HSTDEV | GCFG_OP_MODE, 436 GCFG_ROLE_HSTDEV | GCFG_OP_MODE_CTRL_SYNC_MODE); 437 if (ret) 438 goto out; 439 440 ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG, 441 SYSMODE_CFG_TYPEC_DISABLE, 0); 442 if (ret) 443 goto out; 444 445 ret = regmap_read(priv->usb31misc, TCA_TCPC, &val); 446 if (ret) 447 goto out; 448 val &= ~(TCPC_VALID | TCPC_LOW_POWER_EN | TCPC_MUX_CONTROL_MASK); 449 val |= (TCPC_VALID | TCPC_MUX_CONTROL_USB31); 450 ret = regmap_write(priv->usb31misc, TCA_TCPC, val); 451 if (ret) 452 goto out; 453 454 ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL, 455 VBUS_CTRL_POWERPRESENT_OVERRD | VBUS_CTRL_VBUSVALID_OVERRD); 456 if (ret) 457 goto out; 458 459 return 0; 460out: 461 dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret); 462 return ret; 463} 464 465static int hi3670_phy_init(struct phy *phy) 466{ 467 struct hi3670_priv *priv = phy_get_drvdata(phy); 468 u32 val; 469 int ret; 470 471 /* assert controller */ 472 val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET | 473 CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR; 474 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0); 475 if (ret) 476 goto out; 477 478 ret = hi3670_config_phy_clock(priv); 479 if (ret) 480 goto out; 481 482 /* Exit from IDDQ mode */ 483 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5, 484 CTRL5_USB2_SIDDQ, 0); 485 if (ret) 486 goto out; 487 488 /* Release USB31 PHY out of TestPowerDown mode */ 489 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50, 490 CFG50_USB3_PHY_TEST_POWERDOWN, 0); 491 if (ret) 492 goto out; 493 494 /* Deassert phy */ 495 val = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR; 496 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val); 497 if (ret) 498 goto out; 499 500 usleep_range(100, 120); 501 502 /* Tell the PHY power is stable */ 503 val = CFG54_USB3_PHY0_ANA_PWR_EN | CFG54_PHY0_PCS_PWR_STABLE | 504 CFG54_PHY0_PMA_PWR_STABLE; 505 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54, 506 val, val); 507 if (ret) 508 goto out; 509 510 ret = hi3670_config_tca(priv); 511 if (ret) 512 goto out; 513 514 /* Enable SSC */ 515 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C, 516 CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN, 517 CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN); 518 if (ret) 519 goto out; 520 521 /* Deassert controller */ 522 val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET; 523 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val); 524 if (ret) 525 goto out; 526 527 usleep_range(100, 120); 528 529 /* Set fake vbus valid signal */ 530 val = CTRL0_USB3_VBUSVLD | CTRL0_USB3_VBUSVLD_SEL; 531 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val); 532 if (ret) 533 goto out; 534 535 val = CTRL3_USB2_VBUSVLDEXT0 | CTRL3_USB2_VBUSVLDEXTSEL0; 536 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val); 537 if (ret) 538 goto out; 539 540 usleep_range(100, 120); 541 542 ret = hi3670_phy_set_params(priv); 543 if (ret) 544 goto out; 545 546 return 0; 547out: 548 dev_err(priv->dev, "failed to init phy ret: %d\n", ret); 549 return ret; 550} 551 552static int hi3670_phy_exit(struct phy *phy) 553{ 554 struct hi3670_priv *priv = phy_get_drvdata(phy); 555 u32 mask; 556 int ret; 557 558 /* Assert phy */ 559 mask = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR; 560 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0); 561 if (ret) 562 goto out; 563 564 if (!hi3670_is_abbclk_selected(priv)) { 565 /* disable usb_tcxo_en */ 566 ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3, 567 USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START); 568 } else { 569 ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6, 570 GT_CLK_USB2PHY_REF); 571 if (ret) 572 goto out; 573 } 574 575 return 0; 576out: 577 dev_err(priv->dev, "failed to exit phy ret: %d\n", ret); 578 return ret; 579} 580 581static const struct phy_ops hi3670_phy_ops = { 582 .init = hi3670_phy_init, 583 .exit = hi3670_phy_exit, 584 .owner = THIS_MODULE, 585}; 586 587static int hi3670_phy_probe(struct platform_device *pdev) 588{ 589 struct phy_provider *phy_provider; 590 struct device *dev = &pdev->dev; 591 struct phy *phy; 592 struct hi3670_priv *priv; 593 594 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 595 if (!priv) 596 return -ENOMEM; 597 598 priv->dev = dev; 599 priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node, 600 "hisilicon,pericrg-syscon"); 601 if (IS_ERR(priv->peri_crg)) { 602 dev_err(dev, "no hisilicon,pericrg-syscon\n"); 603 return PTR_ERR(priv->peri_crg); 604 } 605 606 priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node, 607 "hisilicon,pctrl-syscon"); 608 if (IS_ERR(priv->pctrl)) { 609 dev_err(dev, "no hisilicon,pctrl-syscon\n"); 610 return PTR_ERR(priv->pctrl); 611 } 612 613 priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node, 614 "hisilicon,sctrl-syscon"); 615 if (IS_ERR(priv->sctrl)) { 616 dev_err(dev, "no hisilicon,sctrl-syscon\n"); 617 return PTR_ERR(priv->sctrl); 618 } 619 620 /* node of hi3670 phy is a sub-node of usb3_otg_bc */ 621 priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node); 622 if (IS_ERR(priv->usb31misc)) { 623 dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n"); 624 return PTR_ERR(priv->usb31misc); 625 } 626 627 if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param", 628 &priv->eye_diagram_param)) 629 priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM; 630 631 if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl", 632 &priv->tx_vboost_lvl)) 633 priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST; 634 635 phy = devm_phy_create(dev, NULL, &hi3670_phy_ops); 636 if (IS_ERR(phy)) 637 return PTR_ERR(phy); 638 639 phy_set_drvdata(phy, priv); 640 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 641 return PTR_ERR_OR_ZERO(phy_provider); 642} 643 644static const struct of_device_id hi3670_phy_of_match[] = { 645 { .compatible = "hisilicon,hi3670-usb-phy" }, 646 { }, 647}; 648MODULE_DEVICE_TABLE(of, hi3670_phy_of_match); 649 650static struct platform_driver hi3670_phy_driver = { 651 .probe = hi3670_phy_probe, 652 .driver = { 653 .name = "hi3670-usb-phy", 654 .of_match_table = hi3670_phy_of_match, 655 } 656}; 657module_platform_driver(hi3670_phy_driver); 658 659MODULE_AUTHOR("Yu Chen <chenyu56@huawei.com>"); 660MODULE_LICENSE("GPL v2"); 661MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver");