1#include <sys/cdefs.h>
| 1#include <sys/cdefs.h>
|
2__FBSDID("$FreeBSD: head/sys/dev/usb/controller/atmegadci_atmelarm.c 192984 2009-05-28 17:36:36Z thompsa $");
| 2__FBSDID("$FreeBSD: head/sys/dev/usb/controller/atmegadci_atmelarm.c 194228 2009-06-15 01:02:43Z thompsa $");
|
3 4/*- 5 * Copyright (c) 2009 Hans Petter Selasky. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <dev/usb/usb.h> 30 31#include <dev/usb/usb_core.h> 32#include <dev/usb/usb_busdma.h> 33#include <dev/usb/usb_process.h> 34#include <dev/usb/usb_util.h> 35 36#include <dev/usb/usb_controller.h> 37#include <dev/usb/usb_bus.h> 38#include <dev/usb/controller/atmegadci.h> 39 40#include <sys/rman.h> 41 42static device_probe_t atmegadci_probe; 43static device_attach_t atmegadci_attach; 44static device_detach_t atmegadci_detach; 45static device_shutdown_t atmegadci_shutdown; 46 47struct atmegadci_super_softc { 48 struct atmegadci_softc sc_otg; /* must be first */ 49}; 50 51static void 52atmegadci_clocks_on(struct usb_bus *bus) 53{ 54 /* TODO */ 55} 56 57static void 58atmegadci_clocks_off(struct usb_bus *bus) 59{ 60 /* TODO */ 61} 62 63static int 64atmegadci_probe(device_t dev) 65{ 66 device_set_desc(dev, "ATMEL OTG integrated USB controller"); 67 return (0); 68} 69 70static int 71atmegadci_attach(device_t dev) 72{ 73 struct atmegadci_super_softc *sc = device_get_softc(dev); 74 int err; 75 int rid; 76 77 /* setup MUSB OTG USB controller interface softc */ 78 sc->sc_otg.sc_clocks_on = &atmegadci_clocks_on; 79 sc->sc_otg.sc_clocks_off = &atmegadci_clocks_off; 80 81 /* initialise some bus fields */ 82 sc->sc_otg.sc_bus.parent = dev; 83 sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices; 84 sc->sc_otg.sc_bus.devices_max = ATMEGA_MAX_DEVICES; 85 86 /* get all DMA memory */
| 3 4/*- 5 * Copyright (c) 2009 Hans Petter Selasky. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <dev/usb/usb.h> 30 31#include <dev/usb/usb_core.h> 32#include <dev/usb/usb_busdma.h> 33#include <dev/usb/usb_process.h> 34#include <dev/usb/usb_util.h> 35 36#include <dev/usb/usb_controller.h> 37#include <dev/usb/usb_bus.h> 38#include <dev/usb/controller/atmegadci.h> 39 40#include <sys/rman.h> 41 42static device_probe_t atmegadci_probe; 43static device_attach_t atmegadci_attach; 44static device_detach_t atmegadci_detach; 45static device_shutdown_t atmegadci_shutdown; 46 47struct atmegadci_super_softc { 48 struct atmegadci_softc sc_otg; /* must be first */ 49}; 50 51static void 52atmegadci_clocks_on(struct usb_bus *bus) 53{ 54 /* TODO */ 55} 56 57static void 58atmegadci_clocks_off(struct usb_bus *bus) 59{ 60 /* TODO */ 61} 62 63static int 64atmegadci_probe(device_t dev) 65{ 66 device_set_desc(dev, "ATMEL OTG integrated USB controller"); 67 return (0); 68} 69 70static int 71atmegadci_attach(device_t dev) 72{ 73 struct atmegadci_super_softc *sc = device_get_softc(dev); 74 int err; 75 int rid; 76 77 /* setup MUSB OTG USB controller interface softc */ 78 sc->sc_otg.sc_clocks_on = &atmegadci_clocks_on; 79 sc->sc_otg.sc_clocks_off = &atmegadci_clocks_off; 80 81 /* initialise some bus fields */ 82 sc->sc_otg.sc_bus.parent = dev; 83 sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices; 84 sc->sc_otg.sc_bus.devices_max = ATMEGA_MAX_DEVICES; 85 86 /* get all DMA memory */
|
87 if (usb2_bus_mem_alloc_all(&sc->sc_otg.sc_bus,
| 87 if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus,
|
88 USB_GET_DMA_TAG(dev), NULL)) { 89 return (ENOMEM); 90 } 91 rid = 0; 92 sc->sc_otg.sc_io_res = 93 bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 94 95 if (!(sc->sc_otg.sc_io_res)) { 96 err = ENOMEM; 97 goto error; 98 } 99 sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res); 100 sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res); 101 102 rid = 0; 103 sc->sc_otg.sc_irq_res = 104 bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); 105 if (!(sc->sc_otg.sc_irq_res)) { 106 goto error; 107 } 108 sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1); 109 if (!(sc->sc_otg.sc_bus.bdev)) { 110 goto error; 111 } 112 device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus); 113 114 err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, 115 NULL, (driver_intr_t *)atmegadci_interrupt, sc, &sc->sc_otg.sc_intr_hdl); 116 if (err) { 117 sc->sc_otg.sc_intr_hdl = NULL; 118 goto error; 119 } 120 err = atmegadci_init(&sc->sc_otg); 121 if (!err) { 122 err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev); 123 } 124 if (err) { 125 goto error; 126 } 127 return (0); 128 129error: 130 atmegadci_detach(dev); 131 return (ENXIO); 132} 133 134static int 135atmegadci_detach(device_t dev) 136{ 137 struct atmegadci_super_softc *sc = device_get_softc(dev); 138 device_t bdev; 139 int err; 140 141 if (sc->sc_otg.sc_bus.bdev) { 142 bdev = sc->sc_otg.sc_bus.bdev; 143 device_detach(bdev); 144 device_delete_child(dev, bdev); 145 } 146 /* during module unload there are lots of children leftover */ 147 device_delete_all_children(dev); 148 149 if (sc->sc_otg.sc_irq_res && sc->sc_otg.sc_intr_hdl) { 150 /* 151 * only call atmegadci_uninit() after atmegadci_init() 152 */ 153 atmegadci_uninit(&sc->sc_otg); 154 155 err = bus_teardown_intr(dev, sc->sc_otg.sc_irq_res, 156 sc->sc_otg.sc_intr_hdl); 157 sc->sc_otg.sc_intr_hdl = NULL; 158 } 159 /* free IRQ channel, if any */ 160 if (sc->sc_otg.sc_irq_res) { 161 bus_release_resource(dev, SYS_RES_IRQ, 0, 162 sc->sc_otg.sc_irq_res); 163 sc->sc_otg.sc_irq_res = NULL; 164 } 165 /* free memory resource, if any */ 166 if (sc->sc_otg.sc_io_res) { 167 bus_release_resource(dev, SYS_RES_MEMORY, 0, 168 sc->sc_otg.sc_io_res); 169 sc->sc_otg.sc_io_res = NULL; 170 }
| 88 USB_GET_DMA_TAG(dev), NULL)) { 89 return (ENOMEM); 90 } 91 rid = 0; 92 sc->sc_otg.sc_io_res = 93 bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 94 95 if (!(sc->sc_otg.sc_io_res)) { 96 err = ENOMEM; 97 goto error; 98 } 99 sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res); 100 sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res); 101 102 rid = 0; 103 sc->sc_otg.sc_irq_res = 104 bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); 105 if (!(sc->sc_otg.sc_irq_res)) { 106 goto error; 107 } 108 sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1); 109 if (!(sc->sc_otg.sc_bus.bdev)) { 110 goto error; 111 } 112 device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus); 113 114 err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, 115 NULL, (driver_intr_t *)atmegadci_interrupt, sc, &sc->sc_otg.sc_intr_hdl); 116 if (err) { 117 sc->sc_otg.sc_intr_hdl = NULL; 118 goto error; 119 } 120 err = atmegadci_init(&sc->sc_otg); 121 if (!err) { 122 err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev); 123 } 124 if (err) { 125 goto error; 126 } 127 return (0); 128 129error: 130 atmegadci_detach(dev); 131 return (ENXIO); 132} 133 134static int 135atmegadci_detach(device_t dev) 136{ 137 struct atmegadci_super_softc *sc = device_get_softc(dev); 138 device_t bdev; 139 int err; 140 141 if (sc->sc_otg.sc_bus.bdev) { 142 bdev = sc->sc_otg.sc_bus.bdev; 143 device_detach(bdev); 144 device_delete_child(dev, bdev); 145 } 146 /* during module unload there are lots of children leftover */ 147 device_delete_all_children(dev); 148 149 if (sc->sc_otg.sc_irq_res && sc->sc_otg.sc_intr_hdl) { 150 /* 151 * only call atmegadci_uninit() after atmegadci_init() 152 */ 153 atmegadci_uninit(&sc->sc_otg); 154 155 err = bus_teardown_intr(dev, sc->sc_otg.sc_irq_res, 156 sc->sc_otg.sc_intr_hdl); 157 sc->sc_otg.sc_intr_hdl = NULL; 158 } 159 /* free IRQ channel, if any */ 160 if (sc->sc_otg.sc_irq_res) { 161 bus_release_resource(dev, SYS_RES_IRQ, 0, 162 sc->sc_otg.sc_irq_res); 163 sc->sc_otg.sc_irq_res = NULL; 164 } 165 /* free memory resource, if any */ 166 if (sc->sc_otg.sc_io_res) { 167 bus_release_resource(dev, SYS_RES_MEMORY, 0, 168 sc->sc_otg.sc_io_res); 169 sc->sc_otg.sc_io_res = NULL; 170 }
|
171 usb2_bus_mem_free_all(&sc->sc_otg.sc_bus, NULL);
| 171 usb_bus_mem_free_all(&sc->sc_otg.sc_bus, NULL);
|
172 173 return (0); 174} 175 176static int 177atmegadci_shutdown(device_t dev) 178{ 179 struct atmegadci_super_softc *sc = device_get_softc(dev); 180 int err; 181 182 err = bus_generic_shutdown(dev); 183 if (err) 184 return (err); 185 186 atmegadci_uninit(&sc->sc_otg); 187 188 return (0); 189} 190 191static device_method_t atmegadci_methods[] = { 192 /* Device interface */ 193 DEVMETHOD(device_probe, atmegadci_probe), 194 DEVMETHOD(device_attach, atmegadci_attach), 195 DEVMETHOD(device_detach, atmegadci_detach), 196 DEVMETHOD(device_shutdown, atmegadci_shutdown), 197 198 /* Bus interface */ 199 DEVMETHOD(bus_print_child, bus_generic_print_child), 200 201 {0, 0} 202}; 203 204static driver_t atmegadci_driver = { 205 "atmegadci", 206 atmegadci_methods, 207 sizeof(struct atmegadci_super_softc), 208}; 209 210static devclass_t atmegadci_devclass; 211 212DRIVER_MODULE(atmegadci, atmelarm, atmegadci_driver, atmegadci_devclass, 0, 0); 213MODULE_DEPEND(atmegadci, usb, 1, 1, 1);
| 172 173 return (0); 174} 175 176static int 177atmegadci_shutdown(device_t dev) 178{ 179 struct atmegadci_super_softc *sc = device_get_softc(dev); 180 int err; 181 182 err = bus_generic_shutdown(dev); 183 if (err) 184 return (err); 185 186 atmegadci_uninit(&sc->sc_otg); 187 188 return (0); 189} 190 191static device_method_t atmegadci_methods[] = { 192 /* Device interface */ 193 DEVMETHOD(device_probe, atmegadci_probe), 194 DEVMETHOD(device_attach, atmegadci_attach), 195 DEVMETHOD(device_detach, atmegadci_detach), 196 DEVMETHOD(device_shutdown, atmegadci_shutdown), 197 198 /* Bus interface */ 199 DEVMETHOD(bus_print_child, bus_generic_print_child), 200 201 {0, 0} 202}; 203 204static driver_t atmegadci_driver = { 205 "atmegadci", 206 atmegadci_methods, 207 sizeof(struct atmegadci_super_softc), 208}; 209 210static devclass_t atmegadci_devclass; 211 212DRIVER_MODULE(atmegadci, atmelarm, atmegadci_driver, atmegadci_devclass, 0, 0); 213MODULE_DEPEND(atmegadci, usb, 1, 1, 1);
|