blob: ffeb6bc206a895d58ece3b99aba57b0324b116cd [file] [log] [blame]
Jim Liu1fd3b3d2022-06-21 17:09:02 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2021 Nuvoton Technology Corp.
4 */
5
Jim Liu1fd3b3d2022-06-21 17:09:02 +08006#include <dm.h>
7#include <generic-phy.h>
8#include <reset.h>
9#include <asm/io.h>
10#include <dm/device_compat.h>
11#include <linux/delay.h>
12#include "ohci.h"
13
14struct npcm_ohci_priv {
15 ohci_t ohci;
16 struct phy phy;
17};
18
19static int npcm_ohci_setup_phy(struct udevice *dev, struct phy *phy)
20{
21 int ret;
22
23 if (!phy)
24 return 0;
25
26 ret = generic_phy_get_by_index(dev, 0, phy);
27 if (ret) {
28 if (ret != -ENOENT) {
29 dev_err(dev, "failed to get usb phy\n");
30 return ret;
31 }
32 } else {
33 ret = generic_phy_init(phy);
34 if (ret) {
35 dev_err(dev, "failed to init usb phy\n");
36 return ret;
37 }
38 }
39
40 return 0;
41}
42
43static int npcm_ohci_init(struct udevice *dev)
44{
45 struct npcm_ohci_priv *priv = dev_get_priv(dev);
46 struct reset_ctl reset;
47 int ret;
48
49 ret = reset_get_by_index(dev, 0, &reset);
50 if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
51 dev_err(dev, "failed to get reset\n");
52 return ret;
53 }
54
55 /* reset controller */
56 if (reset_valid(&reset))
57 reset_assert(&reset);
58
59 /* setup phy */
60 ret = npcm_ohci_setup_phy(dev, &priv->phy);
61 if (ret)
62 return ret;
63
64 /* release controller from reset */
65 if (reset_valid(&reset))
66 reset_deassert(&reset);
67
68 return 0;
69}
70
71static int npcm_ohci_probe(struct udevice *dev)
72{
73 struct ohci_regs *regs = dev_read_addr_ptr(dev);
74 int ret;
75
76 ret = npcm_ohci_init(dev);
77 if (ret)
78 return ret;
79
80 return ohci_register(dev, regs);
81}
82
83static int npcm_ohci_remove(struct udevice *dev)
84{
85 struct npcm_ohci_priv *priv = dev_get_priv(dev);
86
87 generic_phy_exit(&priv->phy);
88
89 return ohci_deregister(dev);
90}
91
92static const struct udevice_id npcm_ohci_ids[] = {
93 { .compatible = "nuvoton,npcm845-ohci" },
94 { .compatible = "nuvoton,npcm750-ohci" },
95 { }
96};
97
98U_BOOT_DRIVER(ohci_npcm) = {
99 .name = "ohci_npcm",
100 .id = UCLASS_USB,
101 .of_match = npcm_ohci_ids,
102 .probe = npcm_ohci_probe,
103 .remove = npcm_ohci_remove,
104 .ops = &ohci_usb_ops,
105 .priv_auto = sizeof(struct npcm_ohci_priv),
106 .flags = DM_FLAG_ALLOC_PRIV_DMA,
107};