1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
6 #include <linux/delay.h>
8 #include <linux/mod_devicetable.h>
9 #include <linux/module.h>
10 #include <linux/phy/phy.h>
11 #include <linux/platform_device.h>
13 #define HSIC_CTRL 0x08
14 #define HSIC_ENABLE BIT(7)
15 #define PLL_BYPASS BIT(4)
17 static int mmp3_hsic_phy_init(struct phy
*phy
)
19 void __iomem
*base
= (void __iomem
*)phy_get_drvdata(phy
);
22 hsic_ctrl
= readl_relaxed(base
+ HSIC_CTRL
);
23 hsic_ctrl
|= HSIC_ENABLE
;
24 hsic_ctrl
|= PLL_BYPASS
;
25 writel_relaxed(hsic_ctrl
, base
+ HSIC_CTRL
);
30 static const struct phy_ops mmp3_hsic_phy_ops
= {
31 .init
= mmp3_hsic_phy_init
,
35 static const struct of_device_id mmp3_hsic_phy_of_match
[] = {
36 { .compatible
= "marvell,mmp3-hsic-phy", },
39 MODULE_DEVICE_TABLE(of
, mmp3_hsic_phy_of_match
);
41 static int mmp3_hsic_phy_probe(struct platform_device
*pdev
)
43 struct device
*dev
= &pdev
->dev
;
44 struct phy_provider
*provider
;
48 base
= devm_platform_get_and_ioremap_resource(pdev
, 0, NULL
);
52 phy
= devm_phy_create(dev
, NULL
, &mmp3_hsic_phy_ops
);
54 dev_err(dev
, "failed to create PHY\n");
58 phy_set_drvdata(phy
, (void *)base
);
59 provider
= devm_of_phy_provider_register(dev
, of_phy_simple_xlate
);
60 if (IS_ERR(provider
)) {
61 dev_err(dev
, "failed to register PHY provider\n");
62 return PTR_ERR(provider
);
68 static struct platform_driver mmp3_hsic_phy_driver
= {
69 .probe
= mmp3_hsic_phy_probe
,
71 .name
= "mmp3-hsic-phy",
72 .of_match_table
= mmp3_hsic_phy_of_match
,
75 module_platform_driver(mmp3_hsic_phy_driver
);
77 MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
78 MODULE_DESCRIPTION("Marvell MMP3 USB HSIC PHY Driver");
79 MODULE_LICENSE("GPL");