WIP FPC-III support
[linux/fpc-iii.git] / drivers / staging / hikey9xx / phy-hi3670-usb3.c
blob4fc013911a7874d7a33cded94564af737c2c236f
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform
5 * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd.
6 * http://www.huawei.com
8 * Authors: Yu Chen <chenyu56@huawei.com>
9 */
11 #include <linux/clk.h>
12 #include <linux/kernel.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
15 #include <linux/phy/phy.h>
16 #include <linux/platform_device.h>
17 #include <linux/regmap.h>
19 #define SCTRL_SCDEEPSLEEPED (0x0)
20 #define USB_CLK_SELECTED BIT(20)
22 #define PERI_CRG_PEREN0 (0x00)
23 #define PERI_CRG_PERDIS0 (0x04)
24 #define PERI_CRG_PEREN4 (0x40)
25 #define PERI_CRG_PERDIS4 (0x44)
26 #define PERI_CRG_PERRSTEN4 (0x90)
27 #define PERI_CRG_PERRSTDIS4 (0x94)
28 #define PERI_CRG_ISODIS (0x148)
29 #define PERI_CRG_PEREN6 (0x410)
30 #define PERI_CRG_PERDIS6 (0x414)
32 #define USB_REFCLK_ISO_EN BIT(25)
34 #define GT_CLK_USB2PHY_REF BIT(19)
36 #define PCTRL_PERI_CTRL3 (0x10)
37 #define PCTRL_PERI_CTRL3_MSK_START (16)
38 #define USB_TCXO_EN BIT(1)
40 #define PCTRL_PERI_CTRL24 (0x64)
41 #define SC_CLK_USB3PHY_3MUX1_SEL BIT(25)
43 #define USB3OTG_CTRL0 (0x00)
44 #define USB3OTG_CTRL3 (0x0C)
45 #define USB3OTG_CTRL4 (0x10)
46 #define USB3OTG_CTRL5 (0x14)
47 #define USB3OTG_CTRL7 (0x1C)
48 #define USB_MISC_CFG50 (0x50)
49 #define USB_MISC_CFG54 (0x54)
50 #define USB_MISC_CFG58 (0x58)
51 #define USB_MISC_CFG5C (0x5C)
52 #define USB_MISC_CFGA0 (0xA0)
53 #define TCA_CLK_RST (0x200)
54 #define TCA_INTR_EN (0x204)
55 #define TCA_INTR_STS (0x208)
56 #define TCA_GCFG (0x210)
57 #define TCA_TCPC (0x214)
58 #define TCA_SYSMODE_CFG (0x218)
59 #define TCA_VBUS_CTRL (0x240)
61 #define CTRL0_USB3_VBUSVLD BIT(7)
62 #define CTRL0_USB3_VBUSVLD_SEL BIT(6)
64 #define CTRL3_USB2_VBUSVLDEXT0 BIT(6)
65 #define CTRL3_USB2_VBUSVLDEXTSEL0 BIT(5)
67 #define CTRL5_USB2_SIDDQ BIT(0)
69 #define CTRL7_USB2_REFCLKSEL_MASK (3 << 3)
70 #define CTRL7_USB2_REFCLKSEL_ABB (3 << 3)
71 #define CTRL7_USB2_REFCLKSEL_PAD (2 << 3)
73 #define CFG50_USB3_PHY_TEST_POWERDOWN BIT(23)
75 #define CFG54_USB31PHY_CR_ADDR_MASK (0xFFFF)
76 #define CFG54_USB31PHY_CR_ADDR_SHIFT (16)
77 #define CFG54_USB3PHY_REF_USE_PAD BIT(12)
78 #define CFG54_PHY0_PMA_PWR_STABLE BIT(11)
79 #define CFG54_PHY0_PCS_PWR_STABLE BIT(9)
80 #define CFG54_USB31PHY_CR_ACK BIT(7)
81 #define CFG54_USB31PHY_CR_WR_EN BIT(5)
82 #define CFG54_USB31PHY_CR_SEL BIT(4)
83 #define CFG54_USB31PHY_CR_RD_EN BIT(3)
84 #define CFG54_USB31PHY_CR_CLK BIT(2)
85 #define CFG54_USB3_PHY0_ANA_PWR_EN BIT(1)
87 #define CFG58_USB31PHY_CR_DATA_MASK (0xFFFF)
88 #define CFG58_USB31PHY_CR_DATA_RD_START (16)
90 #define CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN BIT(1)
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)
98 #define INTR_EN_XA_TIMEOUT_EVT_EN BIT(1)
99 #define INTR_EN_XA_ACK_EVT_EN BIT(0)
101 #define CLK_RST_TCA_REF_CLK_EN BIT(1)
102 #define CLK_RST_SUSPEND_CLK_EN BIT(0)
104 #define GCFG_ROLE_HSTDEV BIT(4)
105 #define GCFG_OP_MODE (3 << 0)
106 #define GCFG_OP_MODE_CTRL_SYNC_MODE BIT(0)
108 #define TCPC_VALID BIT(4)
109 #define TCPC_LOW_POWER_EN BIT(3)
110 #define TCPC_MUX_CONTROL_MASK (3 << 0)
111 #define TCPC_MUX_CONTROL_USB31 BIT(0)
113 #define SYSMODE_CFG_TYPEC_DISABLE BIT(3)
115 #define VBUS_CTRL_POWERPRESENT_OVERRD (3 << 2)
116 #define VBUS_CTRL_VBUSVALID_OVERRD (3 << 0)
118 #define KIRIN970_USB_DEFAULT_PHY_PARAM (0xFDFEE4)
119 #define KIRIN970_USB_DEFAULT_PHY_VBOOST (0x5)
121 #define TX_VBOOST_LVL_REG (0xf)
122 #define TX_VBOOST_LVL_START (6)
123 #define TX_VBOOST_LVL_ENABLE BIT(9)
125 struct hi3670_priv {
126 struct device *dev;
127 struct regmap *peri_crg;
128 struct regmap *pctrl;
129 struct regmap *sctrl;
130 struct regmap *usb31misc;
132 u32 eye_diagram_param;
133 u32 tx_vboost_lvl;
135 u32 peri_crg_offset;
136 u32 pctrl_offset;
137 u32 usb31misc_offset;
140 static int hi3670_phy_cr_clk(struct regmap *usb31misc)
142 int ret;
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;
150 /* Clock down */
151 ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
152 CFG54_USB31PHY_CR_CLK, 0);
154 return ret;
157 static int hi3670_phy_cr_set_sel(struct regmap *usb31misc)
159 return regmap_update_bits(usb31misc, USB_MISC_CFG54,
160 CFG54_USB31PHY_CR_SEL, CFG54_USB31PHY_CR_SEL);
163 static int hi3670_phy_cr_start(struct regmap *usb31misc, int direction)
165 int ret;
167 if (direction)
168 ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
169 CFG54_USB31PHY_CR_WR_EN,
170 CFG54_USB31PHY_CR_WR_EN);
171 else
172 ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
173 CFG54_USB31PHY_CR_RD_EN,
174 CFG54_USB31PHY_CR_RD_EN);
176 if (ret)
177 return ret;
179 ret = hi3670_phy_cr_clk(usb31misc);
180 if (ret)
181 return ret;
183 ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
184 CFG54_USB31PHY_CR_RD_EN | CFG54_USB31PHY_CR_WR_EN, 0);
186 return ret;
189 static int hi3670_phy_cr_wait_ack(struct regmap *usb31misc)
191 u32 reg;
192 int retry = 100000;
193 int ret;
195 while (retry-- > 0) {
196 ret = regmap_read(usb31misc, USB_MISC_CFG54, &reg);
197 if (ret)
198 return ret;
199 if ((reg & CFG54_USB31PHY_CR_ACK) == CFG54_USB31PHY_CR_ACK)
200 return 0;
202 ret = hi3670_phy_cr_clk(usb31misc);
203 if (ret)
204 return ret;
207 return -ETIMEDOUT;
210 static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr)
212 u32 reg;
213 int ret;
215 ret = regmap_read(usb31misc, USB_MISC_CFG54, &reg);
216 if (ret)
217 return ret;
219 reg &= ~(CFG54_USB31PHY_CR_ADDR_MASK << CFG54_USB31PHY_CR_ADDR_SHIFT);
220 reg |= ((addr & CFG54_USB31PHY_CR_ADDR_MASK) << CFG54_USB31PHY_CR_ADDR_SHIFT);
221 ret = regmap_write(usb31misc, USB_MISC_CFG54, reg);
223 return ret;
226 static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val)
228 int reg;
229 int i;
230 int ret;
232 for (i = 0; i < 100; i++) {
233 ret = hi3670_phy_cr_clk(usb31misc);
234 if (ret)
235 return ret;
238 ret = hi3670_phy_cr_set_sel(usb31misc);
239 if (ret)
240 return ret;
242 ret = hi3670_phy_cr_set_addr(usb31misc, addr);
243 if (ret)
244 return ret;
246 ret = hi3670_phy_cr_start(usb31misc, 0);
247 if (ret)
248 return ret;
250 ret = hi3670_phy_cr_wait_ack(usb31misc);
251 if (ret)
252 return ret;
254 ret = regmap_read(usb31misc, USB_MISC_CFG58, &reg);
255 if (ret)
256 return ret;
258 *val = (reg >> CFG58_USB31PHY_CR_DATA_RD_START) &
259 CFG58_USB31PHY_CR_DATA_MASK;
261 return 0;
264 static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val)
266 int i;
267 int ret;
269 for (i = 0; i < 100; i++) {
270 ret = hi3670_phy_cr_clk(usb31misc);
271 if (ret)
272 return ret;
275 ret = hi3670_phy_cr_set_sel(usb31misc);
276 if (ret)
277 return ret;
279 ret = hi3670_phy_cr_set_addr(usb31misc, addr);
280 if (ret)
281 return ret;
283 ret = regmap_write(usb31misc, USB_MISC_CFG58,
284 val & CFG58_USB31PHY_CR_DATA_MASK);
285 if (ret)
286 return ret;
288 ret = hi3670_phy_cr_start(usb31misc, 1);
289 if (ret)
290 return ret;
292 ret = hi3670_phy_cr_wait_ack(usb31misc);
294 return ret;
297 static int hi3670_phy_set_params(struct hi3670_priv *priv)
299 u32 reg;
300 int ret;
301 int retry = 3;
303 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4,
304 priv->eye_diagram_param);
305 if (ret) {
306 dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n");
307 return ret;
310 while (retry-- > 0) {
311 ret = hi3670_phy_cr_read(priv->usb31misc,
312 TX_VBOOST_LVL_REG, &reg);
313 if (!ret)
314 break;
316 if (ret != -ETIMEDOUT) {
317 dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n");
318 return ret;
321 if (ret)
322 return ret;
324 reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START));
325 ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg);
326 if (ret)
327 dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n");
329 return ret;
332 static int hi3670_is_abbclk_seleted(struct hi3670_priv *priv)
334 u32 reg;
336 if (!priv->sctrl) {
337 dev_err(priv->dev, "priv->sctrl is null!\n");
338 return 1;
341 if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, &reg)) {
342 dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n");
343 return 1;
346 if ((reg & USB_CLK_SELECTED) == 0)
347 return 1;
349 return 0;
352 static int hi3670_config_phy_clock(struct hi3670_priv *priv)
354 u32 val, mask;
355 int ret;
357 if (hi3670_is_abbclk_seleted(priv)) {
358 /* usb refclk iso disable */
359 ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS,
360 USB_REFCLK_ISO_EN);
361 if (ret)
362 goto out;
364 /* enable usb_tcxo_en */
365 ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
366 USB_TCXO_EN |
367 (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START));
369 /* select usbphy clk from abb */
370 mask = SC_CLK_USB3PHY_3MUX1_SEL;
371 ret = regmap_update_bits(priv->pctrl,
372 PCTRL_PERI_CTRL24, mask, 0);
373 if (ret)
374 goto out;
376 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
377 CFGA0_USB2PHY_REFCLK_SELECT, 0);
378 if (ret)
379 goto out;
381 ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
382 if (ret)
383 goto out;
384 val &= ~CTRL7_USB2_REFCLKSEL_MASK;
385 val |= CTRL7_USB2_REFCLKSEL_ABB;
386 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
387 if (ret)
388 goto out;
390 return 0;
393 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
394 CFG54_USB3PHY_REF_USE_PAD,
395 CFG54_USB3PHY_REF_USE_PAD);
396 if (ret)
397 goto out;
399 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
400 CFGA0_USB2PHY_REFCLK_SELECT,
401 CFGA0_USB2PHY_REFCLK_SELECT);
402 if (ret)
403 goto out;
405 ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
406 if (ret)
407 goto out;
408 val &= ~CTRL7_USB2_REFCLKSEL_MASK;
409 val |= CTRL7_USB2_REFCLKSEL_PAD;
410 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
411 if (ret)
412 goto out;
414 ret = regmap_write(priv->peri_crg,
415 PERI_CRG_PEREN6, GT_CLK_USB2PHY_REF);
416 if (ret)
417 goto out;
419 return 0;
420 out:
421 dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
422 return ret;
425 static int hi3670_config_tca(struct hi3670_priv *priv)
427 u32 val, mask;
428 int ret;
430 ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff);
431 if (ret)
432 goto out;
434 ret = regmap_write(priv->usb31misc, TCA_INTR_EN,
435 INTR_EN_XA_TIMEOUT_EVT_EN | INTR_EN_XA_ACK_EVT_EN);
436 if (ret)
437 goto out;
439 mask = CLK_RST_TCA_REF_CLK_EN | CLK_RST_SUSPEND_CLK_EN;
440 ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0);
441 if (ret)
442 goto out;
444 ret = regmap_update_bits(priv->usb31misc, TCA_GCFG,
445 GCFG_ROLE_HSTDEV | GCFG_OP_MODE,
446 GCFG_ROLE_HSTDEV | GCFG_OP_MODE_CTRL_SYNC_MODE);
447 if (ret)
448 goto out;
450 ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG,
451 SYSMODE_CFG_TYPEC_DISABLE, 0);
452 if (ret)
453 goto out;
455 ret = regmap_read(priv->usb31misc, TCA_TCPC, &val);
456 if (ret)
457 goto out;
458 val &= ~(TCPC_VALID | TCPC_LOW_POWER_EN | TCPC_MUX_CONTROL_MASK);
459 val |= (TCPC_VALID | TCPC_MUX_CONTROL_USB31);
460 ret = regmap_write(priv->usb31misc, TCA_TCPC, val);
461 if (ret)
462 goto out;
464 ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL,
465 VBUS_CTRL_POWERPRESENT_OVERRD | VBUS_CTRL_VBUSVALID_OVERRD);
466 if (ret)
467 goto out;
469 return 0;
470 out:
471 dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
472 return ret;
475 static int hi3670_phy_init(struct phy *phy)
477 struct hi3670_priv *priv = phy_get_drvdata(phy);
478 u32 val;
479 int ret;
481 /* assert controller */
482 val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET |
483 CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
484 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0);
485 if (ret)
486 goto out;
488 ret = hi3670_config_phy_clock(priv);
489 if (ret)
490 goto out;
492 /* Exit from IDDQ mode */
493 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5,
494 CTRL5_USB2_SIDDQ, 0);
495 if (ret)
496 goto out;
498 /* Release USB31 PHY out of TestPowerDown mode */
499 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50,
500 CFG50_USB3_PHY_TEST_POWERDOWN, 0);
501 if (ret)
502 goto out;
504 /* Deassert phy */
505 val = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
506 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
507 if (ret)
508 goto out;
510 usleep_range(100, 120);
512 /* Tell the PHY power is stable */
513 val = CFG54_USB3_PHY0_ANA_PWR_EN | CFG54_PHY0_PCS_PWR_STABLE |
514 CFG54_PHY0_PMA_PWR_STABLE;
515 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
516 val, val);
517 if (ret)
518 goto out;
520 ret = hi3670_config_tca(priv);
521 if (ret)
522 goto out;
524 /* Enable SSC */
525 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C,
526 CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN,
527 CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN);
528 if (ret)
529 goto out;
531 /* Deassert controller */
532 val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET;
533 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
534 if (ret)
535 goto out;
537 usleep_range(100, 120);
539 /* Set fake vbus valid signal */
540 val = CTRL0_USB3_VBUSVLD | CTRL0_USB3_VBUSVLD_SEL;
541 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val);
542 if (ret)
543 goto out;
545 val = CTRL3_USB2_VBUSVLDEXT0 | CTRL3_USB2_VBUSVLDEXTSEL0;
546 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val);
547 if (ret)
548 goto out;
550 usleep_range(100, 120);
552 ret = hi3670_phy_set_params(priv);
553 if (ret)
554 goto out;
556 return 0;
557 out:
558 dev_err(priv->dev, "failed to init phy ret: %d\n", ret);
559 return ret;
562 static int hi3670_phy_exit(struct phy *phy)
564 struct hi3670_priv *priv = phy_get_drvdata(phy);
565 u32 mask;
566 int ret;
568 /* Assert phy */
569 mask = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
570 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0);
571 if (ret)
572 goto out;
574 if (hi3670_is_abbclk_seleted(priv)) {
575 /* disable usb_tcxo_en */
576 ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
577 USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START);
578 } else {
579 ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6,
580 GT_CLK_USB2PHY_REF);
581 if (ret)
582 goto out;
585 return 0;
586 out:
587 dev_err(priv->dev, "failed to exit phy ret: %d\n", ret);
588 return ret;
591 static struct phy_ops hi3670_phy_ops = {
592 .init = hi3670_phy_init,
593 .exit = hi3670_phy_exit,
594 .owner = THIS_MODULE,
597 static int hi3670_phy_probe(struct platform_device *pdev)
599 struct phy_provider *phy_provider;
600 struct device *dev = &pdev->dev;
601 struct phy *phy;
602 struct hi3670_priv *priv;
604 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
605 if (!priv)
606 return -ENOMEM;
608 priv->dev = dev;
609 priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node,
610 "hisilicon,pericrg-syscon");
611 if (IS_ERR(priv->peri_crg)) {
612 dev_err(dev, "no hisilicon,pericrg-syscon\n");
613 return PTR_ERR(priv->peri_crg);
616 priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
617 "hisilicon,pctrl-syscon");
618 if (IS_ERR(priv->pctrl)) {
619 dev_err(dev, "no hisilicon,pctrl-syscon\n");
620 return PTR_ERR(priv->pctrl);
623 priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
624 "hisilicon,sctrl-syscon");
625 if (IS_ERR(priv->sctrl)) {
626 dev_err(dev, "no hisilicon,sctrl-syscon\n");
627 return PTR_ERR(priv->sctrl);
630 /* node of hi3670 phy is a sub-node of usb3_otg_bc */
631 priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node);
632 if (IS_ERR(priv->usb31misc)) {
633 dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n");
634 return PTR_ERR(priv->usb31misc);
637 if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param",
638 &priv->eye_diagram_param))
639 priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM;
641 if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl",
642 &priv->tx_vboost_lvl))
643 priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST;
645 phy = devm_phy_create(dev, NULL, &hi3670_phy_ops);
646 if (IS_ERR(phy))
647 return PTR_ERR(phy);
649 phy_set_drvdata(phy, priv);
650 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
651 return PTR_ERR_OR_ZERO(phy_provider);
654 static const struct of_device_id hi3670_phy_of_match[] = {
655 { .compatible = "hisilicon,hi3670-usb-phy" },
656 { },
658 MODULE_DEVICE_TABLE(of, hi3670_phy_of_match);
660 static struct platform_driver hi3670_phy_driver = {
661 .probe = hi3670_phy_probe,
662 .driver = {
663 .name = "hi3670-usb-phy",
664 .of_match_table = hi3670_phy_of_match,
667 module_platform_driver(hi3670_phy_driver);
669 MODULE_AUTHOR("Yu Chen <chenyu56@huawei.com>");
670 MODULE_LICENSE("GPL v2");
671 MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver");