
This just has a few starting points. Work remaining:
- Get GPIOs from the device tree correctly, and claim them - Perhaps create a USB phy class and driver for sunxi - Perhaps allow USB ports to be specified by some sort of peripherals ID instead of an index?
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/usb/host/ehci-sunxi.c | 71 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+)
diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c index eda9f69..5b92edf 100644 --- a/drivers/usb/host/ehci-sunxi.c +++ b/drivers/usb/host/ehci-sunxi.c @@ -11,8 +11,15 @@
#include <asm/arch/usbc.h> #include <common.h> +#include <asm/gpio.h> #include "ehci.h"
+struct ehci_sunxi_priv { + struct gpio_desc vbus_gpio; +}; + +#ifndef CONFIG_DM_USB + int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { @@ -44,3 +51,67 @@ int ehci_hcd_stop(int index)
return sunxi_usbc_free_resources(index + 1); } +#endif + +#ifdef CONFIG_DM_USB +static int ehci_usb_ofdata_to_platdata(struct udevice *dev) +{ + return 0; +} + +static int ehci_usb_probe(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + struct ehci_sunxi_priv *priv = dev_get_priv(dev); + struct ehci_hccr *hccr; + struct ehci_hcor *hcor; + static bool clk_done; + int ret; + + /* TODO: Need to get this from the correct node */ + ret = gpio_request_by_name(dev, "gpio", &priv->vbus_gpio, GPIOD_IS_OUT); + if (ret) + return ret; + + hccr = (struct ehci_hccr *)&priv->reg->cap_length; + hcor = (struct ehci_hcor *)&priv->reg->usb_cmd; + if (!clk_done) { + config_clock(get_pll_timing(&fdt_usb_controllers[priv->type])); + clk_done = true; + } + + return ehci_register(dev, hccr, hcor, &tegra_ehci_ops, 0, + plat->init_type); +} + +static int ehci_usb_remove(struct udevice *dev) +{ + int ret; + + ret = ehci_deregister(dev); + if (ret) + return ret; + + /* TODO: free GPIOs */ + + return 0; +} + +static const struct udevice_id ehci_usb_ids[] = { + { .compatible = "allwinner,sun7i-a20-ehci", }, + { } +}; + +U_BOOT_DRIVER(usb_ehci) = { + .name = "ehci_sunxi", + .id = UCLASS_USB, + .of_match = ehci_usb_ids, + .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, + .probe = ehci_usb_probe, + .remove = ehci_usb_remove, + .ops = &ehci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct ehci_sunxi_priv), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif