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