static int musbotg_attach(device_t dev) { struct musbotg_super_softc *sc = device_get_softc(dev); int err; int i; uint32_t rev, reg; /* Request the memory resources */ err = bus_alloc_resources(dev, am335x_musbotg_mem_spec, sc->sc_mem_res); if (err) { device_printf(dev, "Error: could not allocate mem resources\n"); return (ENXIO); } /* Request the IRQ resources */ err = bus_alloc_resources(dev, am335x_musbotg_irq_spec, sc->sc_irq_res); if (err) { device_printf(dev, "Error: could not allocate irq resources\n"); return (ENXIO); } /* * Reset USBSS, USB0 and USB1 */ rev = USBSS_READ4(sc, USBSS_REVREG); device_printf(dev, "TI AM335X USBSS v%d.%d.%d\n", (rev >> 8) & 7, (rev >> 6) & 3, rev & 63); ti_prcm_clk_enable(MUSB0_CLK); USBSS_WRITE4(sc, USBSS_SYSCONFIG, USBSS_SYSCONFIG_SRESET); while (USBSS_READ4(sc, USBSS_SYSCONFIG) & USBSS_SYSCONFIG_SRESET) ; err = bus_setup_intr(dev, sc->sc_irq_res[0], INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)musbotg_usbss_interrupt, sc, &sc->sc_intr_hdl); if (err) { sc->sc_intr_hdl = NULL; device_printf(dev, "Failed to setup USBSS interrupt\n"); goto error; } for (i = 0; i < AM335X_USB_PORTS; i++) { /* setup MUSB OTG USB controller interface softc */ sc->sc_otg[i].sc_clocks_on = &musbotg_clocks_on; sc->sc_otg[i].sc_clocks_off = &musbotg_clocks_off; sc->sc_otg[i].sc_clocks_arg = &USB_CTRL[i]; sc->sc_otg[i].sc_ep_int_set = musbotg_ep_int_set; /* initialise some bus fields */ sc->sc_otg[i].sc_bus.parent = dev; sc->sc_otg[i].sc_bus.devices = sc->sc_otg[i].sc_devices; sc->sc_otg[i].sc_bus.devices_max = MUSB2_MAX_DEVICES; /* get all DMA memory */ if (usb_bus_mem_alloc_all(&sc->sc_otg[i].sc_bus, USB_GET_DMA_TAG(dev), NULL)) { device_printf(dev, "Failed allocate bus mem for musb%d\n", i); return (ENOMEM); } sc->sc_otg[i].sc_io_res = sc->sc_mem_res[RES_USBCORE(i)]; sc->sc_otg[i].sc_io_tag = rman_get_bustag(sc->sc_otg[i].sc_io_res); sc->sc_otg[i].sc_io_hdl = rman_get_bushandle(sc->sc_otg[i].sc_io_res); sc->sc_otg[i].sc_io_size = rman_get_size(sc->sc_otg[i].sc_io_res); sc->sc_otg[i].sc_irq_res = sc->sc_irq_res[i+1]; sc->sc_otg[i].sc_bus.bdev = device_add_child(dev, "usbus", -1); if (!(sc->sc_otg[i].sc_bus.bdev)) { device_printf(dev, "No busdev for musb%d\n", i); goto error; } device_set_ivars(sc->sc_otg[i].sc_bus.bdev, &sc->sc_otg[i].sc_bus); err = bus_setup_intr(dev, sc->sc_otg[i].sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)musbotg_wrapper_interrupt, &sc->sc_otg[i], &sc->sc_otg[i].sc_intr_hdl); if (err) { sc->sc_otg[i].sc_intr_hdl = NULL; device_printf(dev, "Failed to setup interrupt for musb%d\n", i); goto error; } sc->sc_otg[i].sc_id = i; sc->sc_otg[i].sc_platform_data = sc; if (i == 0) sc->sc_otg[i].sc_mode = MUSB2_DEVICE_MODE; else sc->sc_otg[i].sc_mode = MUSB2_HOST_MODE; /* * software-controlled function */ if (sc->sc_otg[i].sc_mode == MUSB2_HOST_MODE) { reg = USBCTRL_READ4(sc, i, USBCTRL_MODE); reg |= USBCTRL_MODE_IDDIGMUX; reg &= ~USBCTRL_MODE_IDDIG; USBCTRL_WRITE4(sc, i, USBCTRL_MODE, reg); USBCTRL_WRITE4(sc, i, USBCTRL_UTMI, USBCTRL_UTMI_FSDATAEXT); } else { reg = USBCTRL_READ4(sc, i, USBCTRL_MODE); reg |= USBCTRL_MODE_IDDIGMUX; reg |= USBCTRL_MODE_IDDIG; USBCTRL_WRITE4(sc, i, USBCTRL_MODE, reg); } reg = USBCTRL_INTEN_USB_ALL & ~USBCTRL_INTEN_USB_SOF; USBCTRL_WRITE4(sc, i, USBCTRL_INTEN_SET1, reg); USBCTRL_WRITE4(sc, i, USBCTRL_INTEN_CLR0, 0xffffffff); err = musbotg_init(&sc->sc_otg[i]); if (!err) err = device_probe_and_attach(sc->sc_otg[i].sc_bus.bdev); if (err) goto error; /* poll VBUS one time */ musbotg_vbus_poll(sc, i); } return (0); error: musbotg_detach(dev); return (ENXIO); }
static int musbotg_attach(device_t dev) { struct musbotg_super_softc *sc = device_get_softc(dev); int err; int rid; /* setup MUSB OTG USB controller interface softc */ sc->sc_otg.sc_clocks_on = &musbotg_clocks_on; sc->sc_otg.sc_clocks_off = &musbotg_clocks_off; sc->sc_otg.sc_clocks_arg = sc; /* initialise some bus fields */ sc->sc_otg.sc_bus.parent = dev; sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices; sc->sc_otg.sc_bus.devices_max = MUSB2_MAX_DEVICES; /* get all DMA memory */ if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus, USB_GET_DMA_TAG(dev), NULL)) { return (ENOMEM); } rid = 0; sc->sc_otg.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!(sc->sc_otg.sc_io_res)) { err = ENOMEM; goto error; } sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res); sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res); sc->sc_otg.sc_io_size = rman_get_size(sc->sc_otg.sc_io_res); rid = 0; sc->sc_otg.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (!(sc->sc_otg.sc_irq_res)) { goto error; } sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1); if (!(sc->sc_otg.sc_bus.bdev)) { goto error; } device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus); #if (__FreeBSD_version >= 700031) err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)musbotg_interrupt, sc, &sc->sc_otg.sc_intr_hdl); #else err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, (driver_intr_t *)musbotg_interrupt, sc, &sc->sc_otg.sc_intr_hdl); #endif if (err) { sc->sc_otg.sc_intr_hdl = NULL; goto error; } err = musbotg_init(&sc->sc_otg); if (!err) { err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev); } if (err) { goto error; } else { /* poll VBUS one time */ musbotg_vbus_poll(sc); } return (0); error: musbotg_detach(dev); return (ENXIO); }
static int musbotg_attach(device_t dev) { struct musbotg_super_softc *sc = device_get_softc(dev); char mode[16]; int err; uint32_t reg; sc->sc_otg.sc_id = device_get_unit(dev); /* Request the memory resources */ err = bus_alloc_resources(dev, am335x_musbotg_mem_spec, sc->sc_mem_res); if (err) { device_printf(dev, "Error: could not allocate mem resources\n"); return (ENXIO); } /* Request the IRQ resources */ sc->sc_otg.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irq_rid, RF_ACTIVE); if (sc->sc_otg.sc_irq_res == NULL) { device_printf(dev, "Error: could not allocate irq resources\n"); return (ENXIO); } /* setup MUSB OTG USB controller interface softc */ sc->sc_otg.sc_clocks_on = &musbotg_clocks_on; sc->sc_otg.sc_clocks_off = &musbotg_clocks_off; sc->sc_otg.sc_clocks_arg = &sc->sc_otg; sc->sc_otg.sc_ep_int_set = musbotg_ep_int_set; /* initialise some bus fields */ sc->sc_otg.sc_bus.parent = dev; sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices; sc->sc_otg.sc_bus.devices_max = MUSB2_MAX_DEVICES; sc->sc_otg.sc_bus.dma_bits = 32; /* get all DMA memory */ if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus, USB_GET_DMA_TAG(dev), NULL)) { device_printf(dev, "Failed allocate bus mem for musb\n"); return (ENOMEM); } sc->sc_otg.sc_io_res = sc->sc_mem_res[RES_USBCORE]; sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res); sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res); sc->sc_otg.sc_io_size = rman_get_size(sc->sc_otg.sc_io_res); sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1); if (!(sc->sc_otg.sc_bus.bdev)) { device_printf(dev, "No busdev for musb\n"); goto error; } device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus); err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)musbotg_wrapper_interrupt, &sc->sc_otg, &sc->sc_otg.sc_intr_hdl); if (err) { sc->sc_otg.sc_intr_hdl = NULL; device_printf(dev, "Failed to setup interrupt for musb\n"); goto error; } sc->sc_otg.sc_platform_data = sc; if (OF_getprop(ofw_bus_get_node(dev), "dr_mode", mode, sizeof(mode)) > 0) { if (strcasecmp(mode, "host") == 0) sc->sc_otg.sc_mode = MUSB2_HOST_MODE; else sc->sc_otg.sc_mode = MUSB2_DEVICE_MODE; } else { /* Beaglebone defaults: USB0 device, USB1 HOST. */ if (sc->sc_otg.sc_id == 0) sc->sc_otg.sc_mode = MUSB2_DEVICE_MODE; else sc->sc_otg.sc_mode = MUSB2_HOST_MODE; } /* * software-controlled function */ if (sc->sc_otg.sc_mode == MUSB2_HOST_MODE) { reg = USBCTRL_READ4(sc, USBCTRL_MODE); reg |= USBCTRL_MODE_IDDIGMUX; reg &= ~USBCTRL_MODE_IDDIG; USBCTRL_WRITE4(sc, USBCTRL_MODE, reg); USBCTRL_WRITE4(sc, USBCTRL_UTMI, USBCTRL_UTMI_FSDATAEXT); } else { reg = USBCTRL_READ4(sc, USBCTRL_MODE); reg |= USBCTRL_MODE_IDDIGMUX; reg |= USBCTRL_MODE_IDDIG; USBCTRL_WRITE4(sc, USBCTRL_MODE, reg); } reg = USBCTRL_INTEN_USB_ALL & ~USBCTRL_INTEN_USB_SOF; USBCTRL_WRITE4(sc, USBCTRL_INTEN_SET1, reg); USBCTRL_WRITE4(sc, USBCTRL_INTEN_CLR0, 0xffffffff); err = musbotg_init(&sc->sc_otg); if (!err) err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev); if (err) goto error; /* poll VBUS one time */ musbotg_vbus_poll(sc); return (0); error: musbotg_detach(dev); return (ENXIO); }