5 * Copyright (c) 2015 Stanislav Galabov. All rights reserved.
6 * Copyright (c) 2010,2011 Aleksandr Rybalko. All rights reserved.
7 * Copyright (c) 2007-2008 Hans Petter Selasky. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/stdint.h>
32 #include <sys/stddef.h>
33 #include <sys/param.h>
34 #include <sys/queue.h>
35 #include <sys/types.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
39 #include <sys/module.h>
41 #include <sys/mutex.h>
42 #include <sys/condvar.h>
43 #include <sys/sysctl.h>
45 #include <sys/unistd.h>
46 #include <sys/callout.h>
47 #include <sys/malloc.h>
51 #include <dev/usb/usb.h>
52 #include <dev/usb/usbdi.h>
54 #include <dev/usb/usb_core.h>
55 #include <dev/usb/usb_busdma.h>
56 #include <dev/usb/usb_process.h>
57 #include <dev/usb/usb_util.h>
59 #include <dev/usb/usb_controller.h>
60 #include <dev/usb/usb_bus.h>
62 #include <dev/usb/controller/dwc_otg.h>
63 #include <mips/rt305x/rt305xreg.h>
64 #include <mips/rt305x/rt305x_sysctlvar.h>
68 static device_probe_t dotg_obio_probe
;
69 static device_attach_t dotg_obio_attach
;
70 static device_detach_t dotg_obio_detach
;
73 dotg_obio_probe(device_t dev
)
75 device_set_desc(dev
, "DWC like USB OTG controller");
80 dotg_obio_attach(device_t dev
)
82 struct dwc_otg_softc
*sc
= device_get_softc(dev
);
86 /* setup controller interface softc */
88 /* initialise some bus fields */
89 sc
->sc_mode
= DWC_MODE_HOST
;
90 sc
->sc_bus
.parent
= dev
;
91 sc
->sc_bus
.devices
= sc
->sc_devices
;
92 sc
->sc_bus
.devices_max
= DWC_OTG_MAX_DEVICES
;
93 sc
->sc_bus
.dma_bits
= 32;
95 /* get all DMA memory */
96 if (usb_bus_mem_alloc_all(&sc
->sc_bus
,
97 USB_GET_DMA_TAG(dev
), NULL
)) {
103 bus_alloc_resource_any(dev
, SYS_RES_MEMORY
, &rid
, RF_ACTIVE
);
104 if (!(sc
->sc_io_res
)) {
105 printf("Can`t alloc MEM\n");
108 sc
->sc_io_tag
= rman_get_bustag(sc
->sc_io_res
);
109 sc
->sc_io_hdl
= rman_get_bushandle(sc
->sc_io_res
);
110 sc
->sc_io_size
= rman_get_size(sc
->sc_io_res
);
113 sc
->sc_irq_res
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
,
115 if (!(sc
->sc_irq_res
)) {
116 printf("Can`t alloc IRQ\n");
120 sc
->sc_bus
.bdev
= device_add_child(dev
, "usbus", -1);
121 if (!(sc
->sc_bus
.bdev
)) {
122 printf("Can`t add usbus\n");
125 device_set_ivars(sc
->sc_bus
.bdev
, &sc
->sc_bus
);
127 #if (__FreeBSD_version >= 700031)
128 err
= bus_setup_intr(dev
, sc
->sc_irq_res
,
129 INTR_TYPE_TTY
| INTR_MPSAFE
, dwc_otg_filter_interrupt
,
130 dwc_otg_interrupt
, sc
, &sc
->sc_intr_hdl
);
133 err
= bus_setup_intr(dev
, sc
->sc_irq_res
,
134 INTR_TYPE_BIO
| INTR_MPSAFE
,(driver_intr_t
*)dwc_otg_interrupt
,
135 sc
, &sc
->sc_intr_hdl
);
138 sc
->sc_intr_hdl
= NULL
;
139 printf("Can`t set IRQ handle\n");
143 /* Run clock for OTG core */
144 rt305x_sysctl_set(SYSCTL_CLKCFG1
, rt305x_sysctl_get(SYSCTL_CLKCFG1
) |
145 SYSCTL_CLKCFG1_OTG_CLK_EN
);
146 tmp
= rt305x_sysctl_get(SYSCTL_RSTCTRL
);
147 rt305x_sysctl_set(SYSCTL_RSTCTRL
, tmp
| SYSCTL_RSTCTRL_OTG
);
150 * Docs say that RSTCTRL bits for RT305x are W1C, so there should
151 * be no need for the below, but who really knows?
153 // rt305x_sysctl_set(SYSCTL_RSTCTRL, tmp & ~SYSCTL_RSTCTRL_OTG);
156 err
= dwc_otg_init(sc
);
157 if (err
) printf("dotg_init fail\n");
159 err
= device_probe_and_attach(sc
->sc_bus
.bdev
);
160 if (err
) printf("device_probe_and_attach fail %d\n", err
);
168 dotg_obio_detach(dev
);
173 dotg_obio_detach(device_t dev
)
175 struct dwc_otg_softc
*sc
= device_get_softc(dev
);
179 if (sc
->sc_bus
.bdev
) {
180 bdev
= sc
->sc_bus
.bdev
;
182 device_delete_child(dev
, bdev
);
184 /* during module unload there are lots of children leftover */
185 device_delete_children(dev
);
187 if (sc
->sc_irq_res
&& sc
->sc_intr_hdl
) {
189 * only call dotg_obio_uninit() after dotg_obio_init()
194 rt305x_sysctl_set(SYSCTL_CLKCFG1
,
195 rt305x_sysctl_get(SYSCTL_CLKCFG1
) &
196 ~SYSCTL_CLKCFG1_OTG_CLK_EN
);
198 err
= bus_teardown_intr(dev
, sc
->sc_irq_res
,
200 sc
->sc_intr_hdl
= NULL
;
202 if (sc
->sc_irq_res
) {
203 bus_release_resource(dev
, SYS_RES_IRQ
, 0,
205 sc
->sc_irq_res
= NULL
;
208 bus_release_resource(dev
, SYS_RES_MEMORY
, 0,
210 sc
->sc_io_res
= NULL
;
212 usb_bus_mem_free_all(&sc
->sc_bus
, NULL
);
217 static device_method_t dotg_obio_methods
[] = {
218 /* Device interface */
219 DEVMETHOD(device_probe
, dotg_obio_probe
),
220 DEVMETHOD(device_attach
, dotg_obio_attach
),
221 DEVMETHOD(device_detach
, dotg_obio_detach
),
222 DEVMETHOD(device_suspend
, bus_generic_suspend
),
223 DEVMETHOD(device_resume
, bus_generic_resume
),
224 DEVMETHOD(device_shutdown
, bus_generic_shutdown
),
229 static driver_t dotg_obio_driver
= {
231 .methods
= dotg_obio_methods
,
232 .size
= sizeof(struct dwc_otg_softc
),
235 static devclass_t dotg_obio_devclass
;
237 DRIVER_MODULE(dwcotg
, obio
, dotg_obio_driver
, dotg_obio_devclass
, 0, 0);