1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk> |
4 | */ |
5 | |
6 | #include <linux/delay.h> |
7 | #include <linux/io.h> |
8 | #include <linux/mod_devicetable.h> |
9 | #include <linux/module.h> |
10 | #include <linux/phy/phy.h> |
11 | #include <linux/platform_device.h> |
12 | |
13 | #define HSIC_CTRL 0x08 |
14 | #define HSIC_ENABLE BIT(7) |
15 | #define PLL_BYPASS BIT(4) |
16 | |
17 | static int mmp3_hsic_phy_init(struct phy *phy) |
18 | { |
19 | void __iomem *base = (void __iomem *)phy_get_drvdata(phy); |
20 | u32 hsic_ctrl; |
21 | |
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); |
26 | |
27 | return 0; |
28 | } |
29 | |
30 | static const struct phy_ops mmp3_hsic_phy_ops = { |
31 | .init = mmp3_hsic_phy_init, |
32 | .owner = THIS_MODULE, |
33 | }; |
34 | |
35 | static const struct of_device_id mmp3_hsic_phy_of_match[] = { |
36 | { .compatible = "marvell,mmp3-hsic-phy" , }, |
37 | { }, |
38 | }; |
39 | MODULE_DEVICE_TABLE(of, mmp3_hsic_phy_of_match); |
40 | |
41 | static int mmp3_hsic_phy_probe(struct platform_device *pdev) |
42 | { |
43 | struct device *dev = &pdev->dev; |
44 | struct phy_provider *provider; |
45 | void __iomem *base; |
46 | struct phy *phy; |
47 | |
48 | base = devm_platform_get_and_ioremap_resource(pdev, index: 0, NULL); |
49 | if (IS_ERR(ptr: base)) |
50 | return PTR_ERR(ptr: base); |
51 | |
52 | phy = devm_phy_create(dev, NULL, ops: &mmp3_hsic_phy_ops); |
53 | if (IS_ERR(ptr: phy)) { |
54 | dev_err(dev, "failed to create PHY\n" ); |
55 | return PTR_ERR(ptr: phy); |
56 | } |
57 | |
58 | phy_set_drvdata(phy, data: (void *)base); |
59 | provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); |
60 | if (IS_ERR(ptr: provider)) { |
61 | dev_err(dev, "failed to register PHY provider\n" ); |
62 | return PTR_ERR(ptr: provider); |
63 | } |
64 | |
65 | return 0; |
66 | } |
67 | |
68 | static struct platform_driver mmp3_hsic_phy_driver = { |
69 | .probe = mmp3_hsic_phy_probe, |
70 | .driver = { |
71 | .name = "mmp3-hsic-phy" , |
72 | .of_match_table = mmp3_hsic_phy_of_match, |
73 | }, |
74 | }; |
75 | module_platform_driver(mmp3_hsic_phy_driver); |
76 | |
77 | MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>" ); |
78 | MODULE_DESCRIPTION("Marvell MMP3 USB HSIC PHY Driver" ); |
79 | MODULE_LICENSE("GPL" ); |
80 | |