]> Git Repo - u-boot.git/blob - drivers/usb/musb-new/ux500.c
Restore patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"
[u-boot.git] / drivers / usb / musb-new / ux500.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /* Copyright (C) 2019 Stephan Gerhold */
3
4 #include <dm.h>
5 #include <generic-phy.h>
6 #include <dm/device_compat.h>
7 #include "musb_uboot.h"
8
9 static struct musb_hdrc_config ux500_musb_hdrc_config = {
10         .multipoint     = true,
11         .dyn_fifo       = true,
12         .num_eps        = 16,
13         .ram_bits       = 16,
14 };
15
16 struct ux500_glue {
17         struct musb_host_data mdata;
18         struct device dev;
19         struct phy phy;
20         bool enabled;
21 };
22 #define to_ux500_glue(d)        container_of(d, struct ux500_glue, dev)
23
24 static int ux500_musb_enable(struct musb *musb)
25 {
26         struct ux500_glue *glue = to_ux500_glue(musb->controller);
27         int ret;
28
29         if (glue->enabled)
30                 return 0;
31
32         ret = generic_phy_power_on(&glue->phy);
33         if (ret) {
34                 printf("%s: failed to power on USB PHY\n", __func__);
35                 return ret;
36         }
37
38         glue->enabled = true;
39         return 0;
40 }
41
42 static void ux500_musb_disable(struct musb *musb)
43 {
44         struct ux500_glue *glue = to_ux500_glue(musb->controller);
45         int ret;
46
47         if (!glue->enabled)
48                 return;
49
50         ret = generic_phy_power_off(&glue->phy);
51         if (ret) {
52                 printf("%s: failed to power off USB PHY\n", __func__);
53                 return;
54         }
55
56         glue->enabled = false;
57 }
58
59 static int ux500_musb_init(struct musb *musb)
60 {
61         struct ux500_glue *glue = to_ux500_glue(musb->controller);
62         int ret;
63
64         ret = generic_phy_init(&glue->phy);
65         if (ret) {
66                 printf("%s: failed to init USB PHY\n", __func__);
67                 return ret;
68         }
69
70         return 0;
71 }
72
73 static int ux500_musb_exit(struct musb *musb)
74 {
75         struct ux500_glue *glue = to_ux500_glue(musb->controller);
76         int ret;
77
78         ret = generic_phy_exit(&glue->phy);
79         if (ret) {
80                 printf("%s: failed to exit USB PHY\n", __func__);
81                 return ret;
82         }
83
84         return 0;
85 }
86
87 static const struct musb_platform_ops ux500_musb_ops = {
88         .init           = ux500_musb_init,
89         .exit           = ux500_musb_exit,
90         .enable         = ux500_musb_enable,
91         .disable        = ux500_musb_disable,
92 };
93
94 int dm_usb_gadget_handle_interrupts(struct udevice *dev)
95 {
96         struct ux500_glue *glue = dev_get_priv(dev);
97
98         glue->mdata.host->isr(0, glue->mdata.host);
99         return 0;
100 }
101
102 static int ux500_musb_probe(struct udevice *dev)
103 {
104 #ifdef CONFIG_USB_MUSB_HOST
105         struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
106 #endif
107         struct ux500_glue *glue = dev_get_priv(dev);
108         struct musb_host_data *host = &glue->mdata;
109         struct musb_hdrc_platform_data pdata;
110         void *base = dev_read_addr_ptr(dev);
111         int ret;
112
113         if (!base)
114                 return -EINVAL;
115
116         ret = generic_phy_get_by_name(dev, "usb", &glue->phy);
117         if (ret) {
118                 dev_err(dev, "failed to get USB PHY: %d\n", ret);
119                 return ret;
120         }
121
122         memset(&pdata, 0, sizeof(pdata));
123         pdata.platform_ops = &ux500_musb_ops;
124         pdata.config = &ux500_musb_hdrc_config;
125
126 #ifdef CONFIG_USB_MUSB_HOST
127         priv->desc_before_addr = true;
128         pdata.mode = MUSB_HOST;
129
130         host->host = musb_init_controller(&pdata, &glue->dev, base);
131         if (!host->host)
132                 return -EIO;
133
134         return musb_lowlevel_init(host);
135 #else
136         pdata.mode = MUSB_PERIPHERAL;
137         host->host = musb_init_controller(&pdata, &glue->dev, base);
138         if (!host->host)
139                 return -EIO;
140
141         return usb_add_gadget_udc(&glue->dev, &host->host->g);
142 #endif
143 }
144
145 static int ux500_musb_remove(struct udevice *dev)
146 {
147         struct ux500_glue *glue = dev_get_priv(dev);
148         struct musb_host_data *host = &glue->mdata;
149
150         usb_del_gadget_udc(&host->host->g);
151         musb_stop(host->host);
152         free(host->host);
153         host->host = NULL;
154
155         return 0;
156 }
157
158 static const struct udevice_id ux500_musb_ids[] = {
159         { .compatible = "stericsson,db8500-musb" },
160         { }
161 };
162
163 U_BOOT_DRIVER(ux500_musb) = {
164         .name           = "ux500-musb",
165 #ifdef CONFIG_USB_MUSB_HOST
166         .id             = UCLASS_USB,
167 #else
168         .id             = UCLASS_USB_GADGET_GENERIC,
169 #endif
170         .of_match       = ux500_musb_ids,
171         .probe          = ux500_musb_probe,
172         .remove         = ux500_musb_remove,
173 #ifdef CONFIG_USB_MUSB_HOST
174         .ops            = &musb_usb_ops,
175 #endif
176         .plat_auto      = sizeof(struct usb_plat),
177         .priv_auto      = sizeof(struct ux500_glue),
178 };
This page took 0.035819 seconds and 4 git commands to generate.