1 // SPDX-License-Identifier: GPL-2.0+
2 /* Copyright (C) 2019 Stephan Gerhold */
5 #include <generic-phy.h>
6 #include <dm/device_compat.h>
7 #include "musb_uboot.h"
9 static struct musb_hdrc_config ux500_musb_hdrc_config = {
17 struct musb_host_data mdata;
22 #define to_ux500_glue(d) container_of(d, struct ux500_glue, dev)
24 static int ux500_musb_enable(struct musb *musb)
26 struct ux500_glue *glue = to_ux500_glue(musb->controller);
32 ret = generic_phy_power_on(&glue->phy);
34 printf("%s: failed to power on USB PHY\n", __func__);
42 static void ux500_musb_disable(struct musb *musb)
44 struct ux500_glue *glue = to_ux500_glue(musb->controller);
50 ret = generic_phy_power_off(&glue->phy);
52 printf("%s: failed to power off USB PHY\n", __func__);
56 glue->enabled = false;
59 static int ux500_musb_init(struct musb *musb)
61 struct ux500_glue *glue = to_ux500_glue(musb->controller);
64 ret = generic_phy_init(&glue->phy);
66 printf("%s: failed to init USB PHY\n", __func__);
73 static int ux500_musb_exit(struct musb *musb)
75 struct ux500_glue *glue = to_ux500_glue(musb->controller);
78 ret = generic_phy_exit(&glue->phy);
80 printf("%s: failed to exit USB PHY\n", __func__);
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,
94 int dm_usb_gadget_handle_interrupts(struct udevice *dev)
96 struct ux500_glue *glue = dev_get_priv(dev);
98 glue->mdata.host->isr(0, glue->mdata.host);
102 static int ux500_musb_probe(struct udevice *dev)
104 #ifdef CONFIG_USB_MUSB_HOST
105 struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
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);
116 ret = generic_phy_get_by_name(dev, "usb", &glue->phy);
118 dev_err(dev, "failed to get USB PHY: %d\n", ret);
122 memset(&pdata, 0, sizeof(pdata));
123 pdata.platform_ops = &ux500_musb_ops;
124 pdata.config = &ux500_musb_hdrc_config;
126 #ifdef CONFIG_USB_MUSB_HOST
127 priv->desc_before_addr = true;
128 pdata.mode = MUSB_HOST;
130 host->host = musb_init_controller(&pdata, &glue->dev, base);
134 return musb_lowlevel_init(host);
136 pdata.mode = MUSB_PERIPHERAL;
137 host->host = musb_init_controller(&pdata, &glue->dev, base);
141 return usb_add_gadget_udc(&glue->dev, &host->host->g);
145 static int ux500_musb_remove(struct udevice *dev)
147 struct ux500_glue *glue = dev_get_priv(dev);
148 struct musb_host_data *host = &glue->mdata;
150 usb_del_gadget_udc(&host->host->g);
151 musb_stop(host->host);
158 static const struct udevice_id ux500_musb_ids[] = {
159 { .compatible = "stericsson,db8500-musb" },
163 U_BOOT_DRIVER(ux500_musb) = {
164 .name = "ux500-musb",
165 #ifdef CONFIG_USB_MUSB_HOST
168 .id = UCLASS_USB_GADGET_GENERIC,
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,
176 .plat_auto = sizeof(struct usb_plat),
177 .priv_auto = sizeof(struct ux500_glue),